summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-17 00:20:36 +0200
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-17 00:20:36 +0200
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /scripts
downloadlinux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.xz
linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
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 @@
+#!/bin/sh
+indent -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 @@
+###
+# scripts contains sources for various helper programs used throughout
+# the kernel for the build process.
+# ---------------------------------------------------------------------------
+# kallsyms: Find all symbols in vmlinux
+# pnmttologo: Convert pnm files to logo files
+# conmakehash: Create chartable
+# conmakehash: Create arrays for initializing the kernel console tables
+
+hostprogs-$(CONFIG_KALLSYMS) += kallsyms
+hostprogs-$(CONFIG_LOGO) += pnmtologo
+hostprogs-$(CONFIG_VT) += conmakehash
+hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
+hostprogs-$(CONFIG_IKCONFIG) += bin2c
+
+always := $(hostprogs-y)
+
+subdir-$(CONFIG_MODVERSIONS) += genksyms
+subdir-$(CONFIG_MODULES) += mod
+
+# Let clean descend into subdirs
+subdir- += 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 @@
+# ==========================================================================
+# Building
+# ==========================================================================
+
+src := $(obj)
+
+.PHONY: __build
+__build:
+
+# Read .config if it exist, otherwise ignore
+-include .config
+
+include $(if $(wildcard $(obj)/Kbuild), $(obj)/Kbuild, $(obj)/Makefile)
+
+include scripts/Makefile.lib
+
+ifdef host-progs
+ifneq ($(hostprogs-y),$(host-progs))
+$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!)
+hostprogs-y += $(host-progs)
+endif
+endif
+
+# Do not include host rules unles needed
+ifneq ($(hostprogs-y)$(hostprogs-m),)
+include scripts/Makefile.host
+endif
+
+ifneq ($(KBUILD_SRC),)
+# Create output directory if not already present
+_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
+
+# Create directories for object files if directory does not exist
+# Needed when obj-y := dir/file.o syntax is used
+_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
+endif
+
+
+ifdef EXTRA_TARGETS
+$(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.6. Please fix!)
+endif
+
+ifdef build-targets
+$(warning kbuild: $(obj)/Makefile - Usage of build-targets is obsolete in 2.6. Please fix!)
+endif
+
+ifdef export-objs
+$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.6. Please fix!)
+endif
+
+ifdef O_TARGET
+$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.6. Please fix!)
+endif
+
+ifdef L_TARGET
+$(error kbuild: $(obj)/Makefile - Use of L_TARGET is replaced by lib-y in 2.6. Please fix!)
+endif
+
+ifdef list-multi
+$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.6. Please fix!)
+endif
+
+ifndef obj
+$(warning kbuild: Makefile.build is included improperly)
+endif
+
+# ===========================================================================
+
+ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
+lib-target := $(obj)/lib.a
+endif
+
+ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
+builtin-target := $(obj)/built-in.o
+endif
+
+# We keep a list of all modules in $(MODVERDIR)
+
+__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
+ $(if $(KBUILD_MODULES),$(obj-m)) \
+ $(subdir-ym) $(always)
+ @:
+
+# Linus' kernel sanity checking tool
+ifneq ($(KBUILD_CHECKSRC),0)
+ ifeq ($(KBUILD_CHECKSRC),2)
+ quiet_cmd_force_checksrc = CHECK $<
+ cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
+ else
+ quiet_cmd_checksrc = CHECK $<
+ cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
+ endif
+endif
+
+
+# Compile C sources (.c)
+# ---------------------------------------------------------------------------
+
+# Default is built-in, unless we know otherwise
+modkern_cflags := $(CFLAGS_KERNEL)
+quiet_modtag := $(empty) $(empty)
+
+$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
+
+$(real-objs-m) : quiet_modtag := [M]
+$(real-objs-m:.o=.i) : quiet_modtag := [M]
+$(real-objs-m:.o=.s) : quiet_modtag := [M]
+$(real-objs-m:.o=.lst): quiet_modtag := [M]
+
+$(obj-m) : quiet_modtag := [M]
+
+# Default for not multi-part modules
+modname = $(*F)
+
+$(multi-objs-m) : modname = $(modname-multi)
+$(multi-objs-m:.o=.i) : modname = $(modname-multi)
+$(multi-objs-m:.o=.s) : modname = $(modname-multi)
+$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
+$(multi-objs-y) : modname = $(modname-multi)
+$(multi-objs-y:.o=.i) : modname = $(modname-multi)
+$(multi-objs-y:.o=.s) : modname = $(modname-multi)
+$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
+
+quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
+cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
+
+%.s: %.c FORCE
+ $(call if_changed_dep,cc_s_c)
+
+quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
+cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
+
+%.i: %.c FORCE
+ $(call if_changed_dep,cc_i_c)
+
+# C (.c) files
+# The C file is compiled and updated dependency information is generated.
+# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
+
+quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
+
+ifndef CONFIG_MODVERSIONS
+cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
+
+else
+# When module versioning is enabled the following steps are executed:
+# o compile a .tmp_<file>.o from <file>.c
+# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
+# not export symbols, we just rename .tmp_<file>.o to <file>.o and
+# are done.
+# o otherwise, we calculate symbol versions using the good old
+# genksyms on the preprocessed source and postprocess them in a way
+# that they are usable as a linker script
+# o generate <file>.o from .tmp_<file>.o using the linker to
+# replace the unresolved symbols __crc_exported_symbol with
+# the actual value of the checksum generated by genksyms
+
+cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
+cmd_modversions = \
+ if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
+ $(CPP) -D__GENKSYMS__ $(c_flags) $< \
+ | $(GENKSYMS) \
+ > $(@D)/.tmp_$(@F:.o=.ver); \
+ \
+ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
+ -T $(@D)/.tmp_$(@F:.o=.ver); \
+ rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
+ else \
+ mv $(@D)/.tmp_$(@F) $@; \
+ fi;
+endif
+
+define rule_cc_o_c
+ $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \
+ $(cmd_checksrc) \
+ $(if $($(quiet)cmd_cc_o_c),echo ' $($(quiet)cmd_cc_o_c)';) \
+ $(cmd_cc_o_c); \
+ $(cmd_modversions) \
+ scripts/basic/fixdep $(depfile) $@ '$(cmd_cc_o_c)' > $(@D)/.$(@F).tmp; \
+ rm -f $(depfile); \
+ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
+endef
+
+# Built-in and composite module parts
+
+%.o: %.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,cc_o_c)
+
+# Single-part modules are special since we need to mark them in $(MODVERDIR)
+
+$(single-used-m): %.o: %.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,cc_o_c)
+ @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
+
+quiet_cmd_cc_lst_c = MKLST $@
+ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
+ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
+ System.map $(OBJDUMP) > $@
+
+%.lst: %.c FORCE
+ $(call if_changed_dep,cc_lst_c)
+
+# Compile assembler sources (.S)
+# ---------------------------------------------------------------------------
+
+modkern_aflags := $(AFLAGS_KERNEL)
+
+$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE)
+$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
+
+quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
+cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
+
+%.s: %.S FORCE
+ $(call if_changed_dep,as_s_S)
+
+quiet_cmd_as_o_S = AS $(quiet_modtag) $@
+cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+
+%.o: %.S FORCE
+ $(call if_changed_dep,as_o_S)
+
+targets += $(real-objs-y) $(real-objs-m) $(lib-y)
+targets += $(extra-y) $(MAKECMDGOALS) $(always)
+
+# Linker scripts preprocessor (.lds.S -> .lds)
+# ---------------------------------------------------------------------------
+quiet_cmd_cpp_lds_S = LDS $@
+ cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
+
+%.lds: %.lds.S FORCE
+ $(call if_changed_dep,cpp_lds_S)
+
+# Build the compiled-in targets
+# ---------------------------------------------------------------------------
+
+# To build objects in subdirs, we need to descend into the directories
+$(sort $(subdir-obj-y)): $(subdir-ym) ;
+
+#
+# Rule to compile a set of .o files into one .o file
+#
+ifdef builtin-target
+quiet_cmd_link_o_target = LD $@
+# If the list of objects to link is empty, just create an empty built-in.o
+cmd_link_o_target = $(if $(strip $(obj-y)),\
+ $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
+ rm -f $@; $(AR) rcs $@)
+
+$(builtin-target): $(obj-y) FORCE
+ $(call if_changed,link_o_target)
+
+targets += $(builtin-target)
+endif # builtin-target
+
+#
+# Rule to compile a set of .o files into one .a file
+#
+ifdef lib-target
+quiet_cmd_link_l_target = AR $@
+cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y)
+
+$(lib-target): $(lib-y) FORCE
+ $(call if_changed,link_l_target)
+
+targets += $(lib-target)
+endif
+
+#
+# Rule to link composite objects
+#
+# Composite objects are specified in kbuild makefile as follows:
+# <composite-object>-objs := <list of .o files>
+# or
+# <composite-object>-y := <list of .o files>
+link_multi_deps = \
+$(filter $(addprefix $(obj)/, \
+$($(subst $(obj)/,,$(@:.o=-objs))) \
+$($(subst $(obj)/,,$(@:.o=-y)))), $^)
+
+quiet_cmd_link_multi-y = LD $@
+cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
+
+quiet_cmd_link_multi-m = LD [M] $@
+cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)
+
+# We would rather have a list of rules like
+# foo.o: $(foo-objs)
+# but that's not so easy, so we rather make all composite objects depend
+# on the set of all their parts
+$(multi-used-y) : %.o: $(multi-objs-y) FORCE
+ $(call if_changed,link_multi-y)
+
+$(multi-used-m) : %.o: $(multi-objs-m) FORCE
+ $(call if_changed,link_multi-m)
+ @{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
+
+targets += $(multi-used-y) $(multi-used-m)
+
+
+# Descending
+# ---------------------------------------------------------------------------
+
+.PHONY: $(subdir-ym)
+$(subdir-ym):
+ $(Q)$(MAKE) $(build)=$@
+
+# Add FORCE to the prequisites of a target to force it to be always rebuilt.
+# ---------------------------------------------------------------------------
+
+.PHONY: FORCE
+
+FORCE:
+
+# Read all saved command lines and dependencies for the $(targets) we
+# may be building above, using $(if_changed{,_dep}). As an
+# optimization, we don't need to read them if the target does not
+# exist, we will rebuild anyway in that case.
+
+targets := $(wildcard $(sort $(targets)))
+cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+
+ifneq ($(cmd_files),)
+ include $(cmd_files)
+endif
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 @@
+# ==========================================================================
+# Cleaning up
+# ==========================================================================
+
+src := $(obj)
+
+.PHONY: __clean
+__clean:
+
+include $(if $(wildcard $(obj)/Kbuild), $(obj)/Kbuild, $(obj)/Makefile)
+
+# Figure out what we need to build from the various variables
+# ==========================================================================
+
+__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
+subdir-y += $(__subdir-y)
+__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
+subdir-m += $(__subdir-m)
+__subdir-n := $(patsubst %/,%,$(filter %/, $(obj-n)))
+subdir-n += $(__subdir-n)
+__subdir- := $(patsubst %/,%,$(filter %/, $(obj-)))
+subdir- += $(__subdir-)
+
+# Subdirectories we need to descend into
+
+subdir-ym := $(sort $(subdir-y) $(subdir-m))
+subdir-ymn := $(sort $(subdir-ym) $(subdir-n) $(subdir-))
+
+# Add subdir path
+
+subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
+
+# build a list of files to remove, usually releative to the current
+# directory
+
+__clean-files := $(extra-y) $(EXTRA_TARGETS) $(always) \
+ $(targets) $(clean-files) \
+ $(host-progs) \
+ $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
+
+# as clean-files is given relative to the current directory, this adds
+# a $(obj) prefix, except for absolute paths
+
+__clean-files := $(wildcard \
+ $(addprefix $(obj)/, $(filter-out /%, $(__clean-files))) \
+ $(filter /%, $(__clean-files)))
+
+# as clean-dirs is given relative to the current directory, this adds
+# a $(obj) prefix, except for absolute paths
+
+__clean-dirs := $(wildcard \
+ $(addprefix $(obj)/, $(filter-out /%, $(clean-dirs))) \
+ $(filter /%, $(clean-dirs)))
+
+# ==========================================================================
+
+quiet_cmd_clean = CLEAN $(obj)
+ cmd_clean = rm -f $(__clean-files)
+quiet_cmd_cleandir = CLEAN $(__clean-dirs)
+ cmd_cleandir = rm -rf $(__clean-dirs)
+
+
+__clean: $(subdir-ymn)
+ifneq ($(strip $(__clean-files)),)
+ +$(call cmd,clean)
+endif
+ifneq ($(strip $(__clean-dirs)),)
+ +$(call cmd,cleandir)
+endif
+ifneq ($(strip $(clean-rule)),)
+ +$(clean-rule)
+endif
+ @:
+
+
+# ===========================================================================
+# Generic stuff
+# ===========================================================================
+
+# Descending
+# ---------------------------------------------------------------------------
+
+.PHONY: $(subdir-ymn)
+$(subdir-ymn):
+ $(Q)$(MAKE) $(clean)=$@
+
+# If quiet is set, only print short version of command
+
+cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
+
+# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
+# Usage:
+# $(Q)$(MAKE) $(clean)=dir
+clean := -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 @@
+# ==========================================================================
+# Building binaries on the host system
+# Binaries are used during the compilation of the kernel, for example
+# to preprocess a data file.
+#
+# Both C and C++ is supported, but preferred language is C for such utilities.
+#
+# Samle syntax (see Documentation/kbuild/makefile.txt for reference)
+# hostprogs-y := bin2hex
+# Will compile bin2hex.c and create an executable named bin2hex
+#
+# hostprogs-y := lxdialog
+# lxdialog-objs := checklist.o lxdialog.o
+# Will compile lxdialog.c and checklist.c, and then link the executable
+# lxdialog, based on checklist.o and lxdialog.o
+#
+# hostprogs-y := qconf
+# qconf-cxxobjs := qconf.o
+# qconf-objs := menu.o
+# Will compile qconf as a C++ program, and menu as a C program.
+# They are linked as C++ code to the executable qconf
+
+# hostprogs-y := conf
+# conf-objs := conf.o libkconfig.so
+# libkconfig-objs := expr.o type.o
+# Will create a shared library named libkconfig.so that consist of
+# expr.o and type.o (they are both compiled as C code and the object file
+# are made as position independent code).
+# conf.c is compiled as a c program, and conf.o is linked together with
+# libkconfig.so as the executable conf.
+# Note: Shared libraries consisting of C++ files are not supported
+
+__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m))
+
+# hostprogs-y := tools/build may have been specified. Retreive directory
+obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
+obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
+
+
+# C code
+# Executables compiled from a single .c file
+host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
+
+# C executables linked based on several .o files
+host-cmulti := $(foreach m,$(__hostprogs),\
+ $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
+
+# Object (.o) files compiled from .c files
+host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
+
+# C++ code
+# C++ executables compiled from at least on .cc file
+# and zero or more .c files
+host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
+
+# C++ Object (.o) files compiled from .cc files
+host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
+
+# Shared libaries (only .c supported)
+# Shared libraries (.so) - all .so files referenced in "xxx-objs"
+host-cshlib := $(sort $(filter %.so, $(host-cobjs)))
+# Remove .so files from "xxx-objs"
+host-cobjs := $(filter-out %.so,$(host-cobjs))
+
+#Object (.o) files used by the shared libaries
+host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
+
+__hostprogs := $(addprefix $(obj)/,$(__hostprogs))
+host-csingle := $(addprefix $(obj)/,$(host-csingle))
+host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
+host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
+host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
+host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
+host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
+host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs))
+obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
+
+#####
+# Handle options to gcc. Support building with separate output directory
+
+_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o)
+_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
+
+ifeq ($(KBUILD_SRC),)
+__hostc_flags = $(_hostc_flags)
+__hostcxx_flags = $(_hostcxx_flags)
+else
+__hostc_flags = -I$(obj) $(call flags,_hostc_flags)
+__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags)
+endif
+
+hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags)
+hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags)
+
+#####
+# Compile programs on the host
+
+# Create executable from a single .c file
+# host-csingle -> Executable
+quiet_cmd_host-csingle = HOSTCC $@
+ cmd_host-csingle = $(HOSTCC) $(hostc_flags) $(HOST_LOADLIBES) -o $@ $<
+$(host-csingle): %: %.c FORCE
+ $(call if_changed_dep,host-csingle)
+
+# Link an executable based on list of .o files, all plain c
+# host-cmulti -> executable
+quiet_cmd_host-cmulti = HOSTLD $@
+ cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
+ $(addprefix $(obj)/,$($(@F)-objs)) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE
+ $(call if_changed,host-cmulti)
+
+# Create .o file from a single .c file
+# host-cobjs -> .o
+quiet_cmd_host-cobjs = HOSTCC $@
+ cmd_host-cobjs = $(HOSTCC) $(hostc_flags) -c -o $@ $<
+$(host-cobjs): %.o: %.c FORCE
+ $(call if_changed_dep,host-cobjs)
+
+# Link an executable based on list of .o files, a mixture of .c and .cc
+# host-cxxmulti -> executable
+quiet_cmd_host-cxxmulti = HOSTLD $@
+ cmd_host-cxxmulti = $(HOSTCXX) $(HOSTLDFLAGS) -o $@ \
+ $(foreach o,objs cxxobjs,\
+ $(addprefix $(obj)/,$($(@F)-$(o)))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cxxmulti): %: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE
+ $(call if_changed,host-cxxmulti)
+
+# Create .o file from a single .cc (C++) file
+quiet_cmd_host-cxxobjs = HOSTCXX $@
+ cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
+$(host-cxxobjs): %.o: %.cc FORCE
+ $(call if_changed_dep,host-cxxobjs)
+
+# Compile .c file, create position independent .o file
+# host-cshobjs -> .o
+quiet_cmd_host-cshobjs = HOSTCC -fPIC $@
+ cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
+$(host-cshobjs): %.o: %.c FORCE
+ $(call if_changed_dep,host-cshobjs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cshlib)
+quiet_cmd_host-cshlib = HOSTLLD -shared $@
+ cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cshlib): %: $(host-cshobjs) FORCE
+ $(call if_changed,host-cshlib)
+
+targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
+ $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs)
+
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 @@
+# ===========================================================================
+# kbuild: Generic definitions
+# ===========================================================================
+
+# Standard vars
+
+comma := ,
+empty :=
+space := $(empty) $(empty)
+
+# Backward compatibility - to be removed...
+extra-y += $(EXTRA_TARGETS)
+# Figure out what we need to build from the various variables
+# ===========================================================================
+
+# When an object is listed to be built compiled-in and modular,
+# only build the compiled-in version
+
+obj-m := $(filter-out $(obj-y),$(obj-m))
+
+# Libraries are always collected in one lib file.
+# Filter out objects already built-in
+
+lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
+
+
+# Handle objects in subdirs
+# ---------------------------------------------------------------------------
+# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o
+# and add the directory to the list of dirs to descend into: $(subdir-y)
+# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
+# and add the directory to the list of dirs to descend into: $(subdir-m)
+
+__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
+subdir-y += $(__subdir-y)
+__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
+subdir-m += $(__subdir-m)
+obj-y := $(patsubst %/, %/built-in.o, $(obj-y))
+obj-m := $(filter-out %/, $(obj-m))
+
+# Subdirectories we need to descend into
+
+subdir-ym := $(sort $(subdir-y) $(subdir-m))
+
+# if $(foo-objs) exists, foo.o is a composite object
+multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
+multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
+multi-used := $(multi-used-y) $(multi-used-m)
+single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
+
+# Build list of the parts of our composite objects, our composite
+# objects depend on those (obviously)
+multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
+multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
+multi-objs := $(multi-objs-y) $(multi-objs-m)
+
+# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live
+# in the local directory
+subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
+
+# $(obj-dirs) is a list of directories that contain object files
+obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
+
+# Replace multi-part objects by their individual parts, look at local dir only
+real-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)
+real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
+
+# Add subdir path
+
+extra-y := $(addprefix $(obj)/,$(extra-y))
+always := $(addprefix $(obj)/,$(always))
+targets := $(addprefix $(obj)/,$(targets))
+obj-y := $(addprefix $(obj)/,$(obj-y))
+obj-m := $(addprefix $(obj)/,$(obj-m))
+lib-y := $(addprefix $(obj)/,$(lib-y))
+subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
+real-objs-y := $(addprefix $(obj)/,$(real-objs-y))
+real-objs-m := $(addprefix $(obj)/,$(real-objs-m))
+single-used-m := $(addprefix $(obj)/,$(single-used-m))
+multi-used-y := $(addprefix $(obj)/,$(multi-used-y))
+multi-used-m := $(addprefix $(obj)/,$(multi-used-m))
+multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y))
+multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m))
+subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
+obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
+
+# The temporary file to save gcc -MD generated dependencies must not
+# contain a comma
+depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
+
+# These flags are needed for modversions and compiling, so we define them here
+# already
+# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
+# end up in (or would, if it gets compiled in)
+# Note: It's possible that one object gets potentially linked into more
+# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
+# where foo and bar are the name of the modules.
+basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
+modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
+
+_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
+_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
+
+# If building the kernel in a separate objtree expand all occurrences
+# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
+
+ifeq ($(KBUILD_SRC),)
+__c_flags = $(_c_flags)
+__a_flags = $(_a_flags)
+__cpp_flags = $(_cpp_flags)
+else
+
+# Prefix -I with $(srctree) if it is not an absolute path
+addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)
+# Find all -I options and call addtree
+flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
+
+# -I$(obj) locates generated .h files
+# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
+# and locates generated .h files
+# FIXME: Replace both with specific CFLAGS* statements in the makefiles
+__c_flags = $(call addtree,-I$(obj)) $(call flags,_c_flags)
+__a_flags = $(call flags,_a_flags)
+__cpp_flags = $(call flags,_cpp_flags)
+endif
+
+c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+ $(__c_flags) $(modkern_cflags) \
+ $(basename_flags) $(modname_flags)
+
+a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+ $(__a_flags) $(modkern_aflags)
+
+cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
+
+ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS)
+
+# Finds the multi-part object the current object will be linked into
+modname-multi = $(sort $(foreach m,$(multi-used),\
+ $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
+
+# Shipped files
+# ===========================================================================
+
+quiet_cmd_shipped = SHIPPED $@
+cmd_shipped = cat $< > $@
+
+$(obj)/%:: $(src)/%_shipped
+ $(call cmd,shipped)
+
+# Commands useful for building a boot image
+# ===========================================================================
+#
+# Use as following:
+#
+# target: source(s) FORCE
+# $(if_changed,ld/objcopy/gzip)
+#
+# and add target to EXTRA_TARGETS so that we know we have to
+# read in the saved command line
+
+# Linking
+# ---------------------------------------------------------------------------
+
+quiet_cmd_ld = LD $@
+cmd_ld = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) \
+ $(filter-out FORCE,$^) -o $@
+
+# Objcopy
+# ---------------------------------------------------------------------------
+
+quiet_cmd_objcopy = OBJCOPY $@
+cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
+
+# Gzip
+# ---------------------------------------------------------------------------
+
+quiet_cmd_gzip = GZIP $@
+cmd_gzip = gzip -f -9 < $< > $@
+
+# ===========================================================================
+# Generic stuff
+# ===========================================================================
+
+ifneq ($(KBUILD_NOCMDDEP),1)
+# Check if both arguments has same arguments. Result in empty string if equal
+# User may override this check using make KBUILD_NOCMDDEP=1
+arg-check = $(strip $(filter-out $(1), $(2)) $(filter-out $(2), $(1)) )
+
+endif
+
+# echo command. Short version is $(quiet) equals quiet, otherwise full command
+echo-cmd = $(if $($(quiet)cmd_$(1)), \
+ echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';)
+
+# function to only execute the passed command if necessary
+# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file
+# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars
+#
+if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
+ @set -e; \
+ $(echo-cmd) \
+ $(cmd_$(1)); \
+ echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
+
+
+# execute the command and also postprocess generated .d dependencies
+# file
+
+if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
+ $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
+ @set -e; \
+ $(echo-cmd) \
+ $(cmd_$(1)); \
+ scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
+ rm -f $(depfile); \
+ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
+
+# Usage: $(call if_changed_rule,foo)
+# will check if $(cmd_foo) changed, or any of the prequisites changed,
+# and if so will execute $(rule_foo)
+
+if_changed_rule = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\
+ @set -e; \
+ $(rule_$(1)))
+
+# If quiet is set, only print short version of command
+
+cmd = @$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))' &&) $(cmd_$(1))
+
+# $(call descend,<dir>,<target>)
+# Recursively call a sub-make in <dir> with target <target>
+# Usage is deprecated, because make do not see this as an invocation of make.
+descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
+
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
+# Usage:
+# $(Q)$(MAKE) $(build)=dir
+build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
+
+# filechk is used to check if the content of a generated file is updated.
+# Sample usage:
+# define filechk_sample
+# echo $KERNELRELEASE
+# endef
+# version.h : Makefile
+# $(call filechk,sample)
+# The rule defined shall write to stdout the content of the new file.
+# The existing file will be compared with the new one.
+# - If no file exist it is created
+# - If the content differ the new file is used
+# - If they are equal no change, and no timestamp update
+
+define filechk
+ $(Q)set -e; \
+ echo ' CHK $@'; \
+ mkdir -p $(dir $@); \
+ $(filechk_$(1)) $(2) > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then \
+ rm -f $@.tmp; \
+ else \
+ echo ' UPD $@'; \
+ mv -f $@.tmp $@; \
+ fi
+endef
+
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 @@
+# ==========================================================================
+# Installing modules
+# ==========================================================================
+
+.PHONY: __modinst
+__modinst:
+
+include scripts/Makefile.lib
+
+#
+
+__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
+
+.PHONY: $(modules)
+__modinst: $(modules)
+ @:
+
+quiet_cmd_modules_install = INSTALL $@
+ cmd_modules_install = mkdir -p $(2); cp $@ $(2)
+
+# Modules built outside the kernel source tree go into extra by default
+INSTALL_MOD_DIR ?= extra
+ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(KBUILD_EXTMOD),,$(@D))
+
+modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
+
+$(modules):
+ $(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 @@
+# ===========================================================================
+# Module versions
+# ===========================================================================
+#
+# Stage one of module building created the following:
+# a) The individual .o files used for the module
+# b) A <module>.o file wich is the .o files above linked together
+# c) A <module>.mod file in $(MODVERDIR)/, listing the name of the
+# the preliminary <module>.o file, plus all .o files
+
+# Stage 2 is handled by this file and does the following
+# 1) Find all modules from the files listed in $(MODVERDIR)/
+# 2) modpost is then used to
+# 3) create one <module>.mod.c file pr. module
+# 4) create one Module.symvers file with CRC for all exported symbols
+# 5) compile all <module>.mod.c files
+# 6) final link of the module to a <module.ko> file
+
+# Step 3 is used to place certain information in the module's ELF
+# section, including information such as:
+# Version magic (see include/vermagic.h for full details)
+# - Kernel release
+# - SMP is CONFIG_SMP
+# - PREEMPT is CONFIG_PREEMPT
+# - GCC Version
+# Module info
+# - Module version (MODULE_VERSION)
+# - Module alias'es (MODULE_ALIAS)
+# - Module license (MODULE_LICENSE)
+# - See include/linux/module.h for more details
+
+# Step 4 is solely used to allow module versioning in external modules,
+# where the CRC of each module is retreived from the Module.symers file.
+
+.PHONY: _modpost
+_modpost: __modpost
+
+include .config
+include scripts/Makefile.lib
+
+symverfile := $(objtree)/Module.symvers
+
+# Step 1), find all modules listed in $(MODVERDIR)/
+__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
+
+_modpost: $(modules)
+
+
+# Step 2), invoke modpost
+# Includes step 3,4
+quiet_cmd_modpost = MODPOST
+ cmd_modpost = scripts/mod/modpost \
+ $(if $(CONFIG_MODVERSIONS),-m) \
+ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \
+ $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \
+ $(filter-out FORCE,$^)
+
+.PHONY: __modpost
+__modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE
+ $(call cmd,modpost)
+
+# Declare generated files as targets for modpost
+$(symverfile): __modpost ;
+$(modules:.ko=.mod.c): __modpost ;
+
+
+# Step 5), compile all *.mod.c files
+
+# modname is set to make c_flags define KBUILD_MODNAME
+modname = $(*F)
+
+quiet_cmd_cc_o_c = CC $@
+ cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
+ -c -o $@ $<
+
+$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
+ $(call if_changed_dep,cc_o_c)
+
+targets += $(modules:.ko=.mod.o)
+
+# Step 6), final link of the modules
+quiet_cmd_ld_ko_o = LD [M] $@
+ cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
+ $(filter-out FORCE,$^)
+
+$(modules): %.ko :%.o %.mod.o FORCE
+ $(call if_changed,ld_ko_o)
+
+targets += $(modules)
+
+
+# Add FORCE to the prequisites of a target to force it to be always rebuilt.
+# ---------------------------------------------------------------------------
+
+.PHONY: FORCE
+
+FORCE:
+
+# Read all saved command lines and dependencies for the $(targets) we
+# may be building above, using $(if_changed{,_dep}). As an
+# optimization, we don't need to read them if the target does not
+# exist, we will rebuild anyway in that case.
+
+targets := $(wildcard $(sort $(targets)))
+cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+
+ifneq ($(cmd_files),)
+ include $(cmd_files)
+endif
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 @@
+###
+# Makefile.basic list the most basic programs used during the build process.
+# The programs listed herein is what is needed to do the basic stuff,
+# such as splitting .config and fix dependency file.
+# This initial step is needed to avoid files to be recompiled
+# when kernel configuration changes (which is what happens when
+# .config is included by main Makefile.
+# ---------------------------------------------------------------------------
+# fixdep: Used to generate dependency information during build process
+# split-include: Divide all config symbols up in a number of files in
+# include/config/...
+# docproc: Used in Documentation/docbook
+
+hostprogs-y := fixdep split-include docproc
+always := $(hostprogs-y)
+
+# fixdep is needed to compile other host programs
+$(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 @@
+/*
+ * docproc is a simple preprocessor for the template files
+ * used as placeholders for the kernel internal documentation.
+ * docproc is used for documentation-frontend and
+ * dependency-generator.
+ * The two usages have in common that they require
+ * some knowledge of the .tmpl syntax, therefore they
+ * are kept together.
+ *
+ * documentation-frontend
+ * Scans the template file and call kernel-doc for
+ * all occurrences of ![EIF]file
+ * Beforehand each referenced file are scanned for
+ * any exported sympols "EXPORT_SYMBOL()" statements.
+ * This is used to create proper -function and
+ * -nofunction arguments in calls to kernel-doc.
+ * Usage: docproc doc file.tmpl
+ *
+ * dependency-generator:
+ * Scans the template file and list all files
+ * referenced in a format recognized by make.
+ * Usage: docproc depend file.tmpl
+ * Writes dependency information to stdout
+ * in the following format:
+ * file.tmpl src.c src2.c
+ * The filenames are obtained from the following constructs:
+ * !Efilename
+ * !Ifilename
+ * !Dfilename
+ * !Ffilename
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/* exitstatus is used to keep track of any failing calls to kernel-doc,
+ * but execution continues. */
+int exitstatus = 0;
+
+typedef void DFL(char *);
+DFL *defaultline;
+
+typedef void FILEONLY(char * file);
+FILEONLY *internalfunctions;
+FILEONLY *externalfunctions;
+FILEONLY *symbolsonly;
+
+typedef void FILELINE(char * file, signed char * line);
+FILELINE * singlefunctions;
+FILELINE * entity_system;
+
+#define MAXLINESZ 2048
+#define MAXFILES 250
+#define KERNELDOCPATH "scripts/"
+#define KERNELDOC "kernel-doc"
+#define DOCBOOK "-docbook"
+#define FUNCTION "-function"
+#define NOFUNCTION "-nofunction"
+
+void usage (void)
+{
+ fprintf(stderr, "Usage: docproc {doc|depend} file\n");
+ fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
+ fprintf(stderr, "doc: frontend when generating kernel documentation\n");
+ fprintf(stderr, "depend: generate list of files referenced within file\n");
+}
+
+/*
+ * Execute kernel-doc with parameters givin in svec
+ */
+void exec_kernel_doc(char **svec)
+{
+ pid_t pid;
+ int ret;
+ char real_filename[PATH_MAX + 1];
+ /* Make sure output generated so far are flushed */
+ fflush(stdout);
+ switch(pid=fork()) {
+ case -1:
+ perror("fork");
+ exit(1);
+ case 0:
+ memset(real_filename, 0, sizeof(real_filename));
+ strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+ strncat(real_filename, KERNELDOCPATH KERNELDOC,
+ PATH_MAX - strlen(real_filename));
+ execvp(real_filename, svec);
+ fprintf(stderr, "exec ");
+ perror(real_filename);
+ exit(1);
+ default:
+ waitpid(pid, &ret ,0);
+ }
+ if (WIFEXITED(ret))
+ exitstatus |= WEXITSTATUS(ret);
+ else
+ exitstatus = 0xff;
+}
+
+/* Types used to create list of all exported symbols in a number of files */
+struct symbols
+{
+ char *name;
+};
+
+struct symfile
+{
+ char *filename;
+ struct symbols *symbollist;
+ int symbolcnt;
+};
+
+struct symfile symfilelist[MAXFILES];
+int symfilecnt = 0;
+
+void add_new_symbol(struct symfile *sym, char * symname)
+{
+ sym->symbollist =
+ realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+ sym->symbollist[sym->symbolcnt++].name = strdup(symname);
+}
+
+/* Add a filename to the list */
+struct symfile * add_new_file(char * filename)
+{
+ symfilelist[symfilecnt++].filename = strdup(filename);
+ return &symfilelist[symfilecnt - 1];
+}
+/* Check if file already are present in the list */
+struct symfile * filename_exist(char * filename)
+{
+ int i;
+ for (i=0; i < symfilecnt; i++)
+ if (strcmp(symfilelist[i].filename, filename) == 0)
+ return &symfilelist[i];
+ return NULL;
+}
+
+/*
+ * List all files referenced within the template file.
+ * Files are separated by tabs.
+ */
+void adddep(char * file) { printf("\t%s", file); }
+void adddep2(char * file, signed char * line) { line = line; adddep(file); }
+void noaction(char * line) { line = line; }
+void noaction2(char * file, signed char * line) { file = file; line = line; }
+
+/* Echo the line without further action */
+void printline(char * line) { printf("%s", line); }
+
+/*
+ * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
+ * in filename.
+ * All symbols located are stored in symfilelist.
+ */
+void find_export_symbols(char * filename)
+{
+ FILE * fp;
+ struct symfile *sym;
+ char line[MAXLINESZ];
+ if (filename_exist(filename) == NULL) {
+ char real_filename[PATH_MAX + 1];
+ memset(real_filename, 0, sizeof(real_filename));
+ strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+ strncat(real_filename, filename,
+ PATH_MAX - strlen(real_filename));
+ sym = add_new_file(filename);
+ fp = fopen(real_filename, "r");
+ if (fp == NULL)
+ {
+ fprintf(stderr, "docproc: ");
+ perror(real_filename);
+ }
+ while(fgets(line, MAXLINESZ, fp)) {
+ signed char *p;
+ signed char *e;
+ if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
+ ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
+ /* Skip EXPORT_SYMBOL{_GPL} */
+ while (isalnum(*p) || *p == '_')
+ p++;
+ /* Remove paranteses and additional ws */
+ while (isspace(*p))
+ p++;
+ if (*p != '(')
+ continue; /* Syntax error? */
+ else
+ p++;
+ while (isspace(*p))
+ p++;
+ e = p;
+ while (isalnum(*e) || *e == '_')
+ e++;
+ *e = '\0';
+ add_new_symbol(sym, p);
+ }
+ }
+ fclose(fp);
+ }
+}
+
+/*
+ * Document all external or internal functions in a file.
+ * Call kernel-doc with following parameters:
+ * kernel-doc -docbook -nofunction function_name1 filename
+ * function names are obtained from all the the src files
+ * by find_export_symbols.
+ * intfunc uses -nofunction
+ * extfunc uses -function
+ */
+void docfunctions(char * filename, char * type)
+{
+ int i,j;
+ int symcnt = 0;
+ int idx = 0;
+ char **vec;
+
+ for (i=0; i <= symfilecnt; i++)
+ symcnt += symfilelist[i].symbolcnt;
+ vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
+ if (vec == NULL) {
+ perror("docproc: ");
+ exit(1);
+ }
+ vec[idx++] = KERNELDOC;
+ vec[idx++] = DOCBOOK;
+ for (i=0; i < symfilecnt; i++) {
+ struct symfile * sym = &symfilelist[i];
+ for (j=0; j < sym->symbolcnt; j++) {
+ vec[idx++] = type;
+ vec[idx++] = sym->symbollist[j].name;
+ }
+ }
+ vec[idx++] = filename;
+ vec[idx] = NULL;
+ printf("<!-- %s -->\n", filename);
+ exec_kernel_doc(vec);
+ fflush(stdout);
+ free(vec);
+}
+void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
+void extfunc(char * filename) { docfunctions(filename, FUNCTION); }
+
+/*
+ * Document sp�ecific function(s) in a file.
+ * Call kernel-doc with the following parameters:
+ * kernel-doc -docbook -function function1 [-function function2]
+ */
+void singfunc(char * filename, signed char * line)
+{
+ char *vec[200]; /* Enough for specific functions */
+ int i, idx = 0;
+ int startofsym = 1;
+ vec[idx++] = KERNELDOC;
+ vec[idx++] = DOCBOOK;
+
+ /* Split line up in individual parameters preceeded by FUNCTION */
+ for (i=0; line[i]; i++) {
+ if (isspace(line[i])) {
+ line[i] = '\0';
+ startofsym = 1;
+ continue;
+ }
+ if (startofsym) {
+ startofsym = 0;
+ vec[idx++] = FUNCTION;
+ vec[idx++] = &line[i];
+ }
+ }
+ vec[idx++] = filename;
+ vec[idx] = NULL;
+ exec_kernel_doc(vec);
+}
+
+/*
+ * Parse file, calling action specific functions for:
+ * 1) Lines containing !E
+ * 2) Lines containing !I
+ * 3) Lines containing !D
+ * 4) Lines containing !F
+ * 5) Default lines - lines not matching the above
+ */
+void parse_file(FILE *infile)
+{
+ char line[MAXLINESZ];
+ signed char * s;
+ while(fgets(line, MAXLINESZ, infile)) {
+ if (line[0] == '!') {
+ s = line + 2;
+ switch (line[1]) {
+ case 'E':
+ while (*s && !isspace(*s)) s++;
+ *s = '\0';
+ externalfunctions(line+2);
+ break;
+ case 'I':
+ while (*s && !isspace(*s)) s++;
+ *s = '\0';
+ internalfunctions(line+2);
+ break;
+ case 'D':
+ while (*s && !isspace(*s)) s++;
+ *s = '\0';
+ symbolsonly(line+2);
+ break;
+ case 'F':
+ /* filename */
+ while (*s && !isspace(*s)) s++;
+ *s++ = '\0';
+ /* function names */
+ while (isspace(*s))
+ s++;
+ singlefunctions(line +2, s);
+ break;
+ default:
+ defaultline(line);
+ }
+ }
+ else {
+ defaultline(line);
+ }
+ }
+ fflush(stdout);
+}
+
+
+int main(int argc, char *argv[])
+{
+ FILE * infile;
+ if (argc != 3) {
+ usage();
+ exit(1);
+ }
+ /* Open file, exit on error */
+ infile = fopen(argv[2], "r");
+ if (infile == NULL) {
+ fprintf(stderr, "docproc: ");
+ perror(argv[2]);
+ exit(2);
+ }
+
+ if (strcmp("doc", argv[1]) == 0)
+ {
+ /* Need to do this in two passes.
+ * First pass is used to collect all symbols exported
+ * in the various files.
+ * Second pass generate the documentation.
+ * This is required because function are declared
+ * and exported in different files :-((
+ */
+ /* Collect symbols */
+ defaultline = noaction;
+ internalfunctions = find_export_symbols;
+ externalfunctions = find_export_symbols;
+ symbolsonly = find_export_symbols;
+ singlefunctions = noaction2;
+ parse_file(infile);
+
+ /* Rewind to start from beginning of file again */
+ fseek(infile, 0, SEEK_SET);
+ defaultline = printline;
+ internalfunctions = intfunc;
+ externalfunctions = extfunc;
+ symbolsonly = printline;
+ singlefunctions = singfunc;
+
+ parse_file(infile);
+ }
+ else if (strcmp("depend", argv[1]) == 0)
+ {
+ /* Create first part of dependency chain
+ * file.tmpl */
+ printf("%s\t", argv[2]);
+ defaultline = noaction;
+ internalfunctions = adddep;
+ externalfunctions = adddep;
+ symbolsonly = adddep;
+ singlefunctions = adddep2;
+ parse_file(infile);
+ printf("\n");
+ }
+ else
+ {
+ fprintf(stderr, "Unknown option: %s\n", argv[1]);
+ exit(1);
+ }
+ fclose(infile);
+ fflush(stdout);
+ return exitstatus;
+}
+
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 @@
+/*
+ * "Optimize" a list of dependencies as spit out by gcc -MD
+ * for the kernel build
+ * ===========================================================================
+ *
+ * Author Kai Germaschewski
+ * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ *
+ * Introduction:
+ *
+ * gcc produces a very nice and correct list of dependencies which
+ * tells make when to remake a file.
+ *
+ * To use this list as-is however has the drawback that virtually
+ * every file in the kernel includes <linux/config.h> which then again
+ * includes <linux/autoconf.h>
+ *
+ * If the user re-runs make *config, linux/autoconf.h will be
+ * regenerated. make notices that and will rebuild every file which
+ * includes autoconf.h, i.e. basically all files. This is extremely
+ * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
+ *
+ * So we play the same trick that "mkdep" played before. We replace
+ * the dependency on linux/autoconf.h by a dependency on every config
+ * option which is mentioned in any of the listed prequisites.
+ *
+ * To be exact, split-include populates a tree in include/config/,
+ * e.g. include/config/his/driver.h, which contains the #define/#undef
+ * for the CONFIG_HIS_DRIVER option.
+ *
+ * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
+ * which depend on "include/linux/config/his/driver.h" will be rebuilt,
+ * so most likely only his driver ;-)
+ *
+ * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
+ *
+ * So to get dependencies right, there are two issues:
+ * o if any of the files the compiler read changed, we need to rebuild
+ * o if the command line given to the compile the file changed, we
+ * better rebuild as well.
+ *
+ * The former is handled by using the -MD output, the later by saving
+ * the command line used to compile the old object and comparing it
+ * to the one we would now use.
+ *
+ * Again, also this idea is pretty old and has been discussed on
+ * kbuild-devel a long time ago. I don't have a sensibly working
+ * internet connection right now, so I rather don't mention names
+ * without double checking.
+ *
+ * This code here has been based partially based on mkdep.c, which
+ * says the following about its history:
+ *
+ * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
+ * This is a C version of syncdep.pl by Werner Almesberger.
+ *
+ *
+ * It is invoked as
+ *
+ * fixdep <depfile> <target> <cmdline>
+ *
+ * and will read the dependency file <depfile>
+ *
+ * The transformed dependency snipped is written to stdout.
+ *
+ * It first generates a line
+ *
+ * cmd_<target> = <cmdline>
+ *
+ * and then basically copies the .<target>.d file to stdout, in the
+ * process filtering out the dependency on linux/autoconf.h and adding
+ * dependencies on include/config/my/option.h for every
+ * CONFIG_MY_OPTION encountered in any of the prequisites.
+ *
+ * It will also filter out all the dependencies on *.ver. We need
+ * to make sure that the generated version checksum are globally up
+ * to date before even starting the recursive build, so it's too late
+ * at this point anyway.
+ *
+ * The algorithm to grep for "CONFIG_..." is bit unusual, but should
+ * be fast ;-) We don't even try to really parse the header files, but
+ * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
+ * be picked up as well. It's not a problem with respect to
+ * correctness, since that can only give too many dependencies, thus
+ * we cannot miss a rebuild. Since people tend to not mention totally
+ * unrelated CONFIG_ options all over the place, it's not an
+ * efficiency problem either.
+ *
+ * (Note: it'd be easy to port over the complete mkdep state machine,
+ * but I don't think the added complexity is worth it)
+ */
+/*
+ * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
+ * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
+ * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
+ * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
+ * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
+ * those files will have correct dependencies.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <ctype.h>
+#include <arpa/inet.h>
+
+#define INT_CONF ntohl(0x434f4e46)
+#define INT_ONFI ntohl(0x4f4e4649)
+#define INT_NFIG ntohl(0x4e464947)
+#define INT_FIG_ ntohl(0x4649475f)
+
+char *target;
+char *depfile;
+char *cmdline;
+
+void usage(void)
+
+{
+ fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
+ exit(1);
+}
+
+void print_cmdline(void)
+{
+ printf("cmd_%s := %s\n\n", target, cmdline);
+}
+
+char * str_config = NULL;
+int size_config = 0;
+int len_config = 0;
+
+/*
+ * Grow the configuration string to a desired length.
+ * Usually the first growth is plenty.
+ */
+void grow_config(int len)
+{
+ while (len_config + len > size_config) {
+ if (size_config == 0)
+ size_config = 2048;
+ str_config = realloc(str_config, size_config *= 2);
+ if (str_config == NULL)
+ { perror("fixdep:malloc"); exit(1); }
+ }
+}
+
+
+
+/*
+ * Lookup a value in the configuration string.
+ */
+int is_defined_config(const char * name, int len)
+{
+ const char * pconfig;
+ const char * plast = str_config + len_config - len;
+ for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
+ if (pconfig[ -1] == '\n'
+ && pconfig[len] == '\n'
+ && !memcmp(pconfig, name, len))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Add a new value to the configuration string.
+ */
+void define_config(const char * name, int len)
+{
+ grow_config(len + 1);
+
+ memcpy(str_config+len_config, name, len);
+ len_config += len;
+ str_config[len_config++] = '\n';
+}
+
+/*
+ * Clear the set of configuration strings.
+ */
+void clear_config(void)
+{
+ len_config = 0;
+ define_config("", 0);
+}
+
+/*
+ * Record the use of a CONFIG_* word.
+ */
+void use_config(char *m, int slen)
+{
+ char s[PATH_MAX];
+ char *p;
+
+ if (is_defined_config(m, slen))
+ return;
+
+ define_config(m, slen);
+
+ memcpy(s, m, slen); s[slen] = 0;
+
+ for (p = s; p < s + slen; p++) {
+ if (*p == '_')
+ *p = '/';
+ else
+ *p = tolower((unsigned char)*p);
+ }
+ printf(" $(wildcard include/config/%s.h) \\\n", s);
+}
+
+void parse_config_file(signed char *map, size_t len)
+{
+ int *end = (int *) (map + len);
+ /* start at +1, so that p can never be < map */
+ int *m = (int *) map + 1;
+ signed char *p, *q;
+
+ for (; m < end; m++) {
+ if (*m == INT_CONF) { p = (signed char *) m ; goto conf; }
+ if (*m == INT_ONFI) { p = (signed char *) m-1; goto conf; }
+ if (*m == INT_NFIG) { p = (signed char *) m-2; goto conf; }
+ if (*m == INT_FIG_) { p = (signed char *) m-3; goto conf; }
+ continue;
+ conf:
+ if (p > map + len - 7)
+ continue;
+ if (memcmp(p, "CONFIG_", 7))
+ continue;
+ for (q = p + 7; q < map + len; q++) {
+ if (!(isalnum(*q) || *q == '_'))
+ goto found;
+ }
+ continue;
+
+ found:
+ use_config(p+7, q-p-7);
+ }
+}
+
+/* test is s ends in sub */
+int strrcmp(char *s, char *sub)
+{
+ int slen = strlen(s);
+ int sublen = strlen(sub);
+
+ if (sublen > slen)
+ return 1;
+
+ return memcmp(s + slen - sublen, sub, sublen);
+}
+
+void do_config_file(char *filename)
+{
+ struct stat st;
+ int fd;
+ void *map;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "fixdep: ");
+ perror(filename);
+ exit(2);
+ }
+ fstat(fd, &st);
+ if (st.st_size == 0) {
+ close(fd);
+ return;
+ }
+ map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if ((long) map == -1) {
+ perror("fixdep: mmap");
+ close(fd);
+ return;
+ }
+
+ parse_config_file(map, st.st_size);
+
+ munmap(map, st.st_size);
+
+ close(fd);
+}
+
+void parse_dep_file(void *map, size_t len)
+{
+ signed char *m = map;
+ signed char *end = m + len;
+ signed char *p;
+ char s[PATH_MAX];
+
+ p = strchr(m, ':');
+ if (!p) {
+ fprintf(stderr, "fixdep: parse error\n");
+ exit(1);
+ }
+ memcpy(s, m, p-m); s[p-m] = 0;
+ printf("deps_%s := \\\n", target);
+ m = p+1;
+
+ clear_config();
+
+ while (m < end) {
+ while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
+ m++;
+ p = m;
+ while (p < end && *p != ' ') p++;
+ if (p == end) {
+ do p--; while (!isalnum(*p));
+ p++;
+ }
+ memcpy(s, m, p-m); s[p-m] = 0;
+ if (strrcmp(s, "include/linux/autoconf.h") &&
+ strrcmp(s, "arch/um/include/uml-config.h") &&
+ strrcmp(s, ".ver")) {
+ printf(" %s \\\n", s);
+ do_config_file(s);
+ }
+ m = p + 1;
+ }
+ printf("\n%s: $(deps_%s)\n\n", target, target);
+ printf("$(deps_%s):\n", target);
+}
+
+void print_deps(void)
+{
+ struct stat st;
+ int fd;
+ void *map;
+
+ fd = open(depfile, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "fixdep: ");
+ perror(depfile);
+ exit(2);
+ }
+ fstat(fd, &st);
+ if (st.st_size == 0) {
+ fprintf(stderr,"fixdep: %s is empty\n",depfile);
+ close(fd);
+ return;
+ }
+ map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if ((long) map == -1) {
+ perror("fixdep: mmap");
+ close(fd);
+ return;
+ }
+
+ parse_dep_file(map, st.st_size);
+
+ munmap(map, st.st_size);
+
+ close(fd);
+}
+
+void traps(void)
+{
+ static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
+
+ if (*(int *)test != INT_CONF) {
+ fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
+ *(int *)test);
+ exit(2);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ traps();
+
+ if (argc != 4)
+ usage();
+
+ depfile = argv[1];
+ target = argv[2];
+ cmdline = argv[3];
+
+ print_cmdline();
+ print_deps();
+
+ return 0;
+}
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 @@
+/*
+ * split-include.c
+ *
+ * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
+ * This is a C version of syncdep.pl by Werner Almesberger.
+ *
+ * This program takes autoconf.h as input and outputs a directory full
+ * of one-line include files, merging onto the old values.
+ *
+ * Think of the configuration options as key-value pairs. Then there
+ * are five cases:
+ *
+ * key old value new value action
+ *
+ * KEY-1 VALUE-1 VALUE-1 leave file alone
+ * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file
+ * KEY-3 - VALUE-3 write VALUE-3 into file
+ * KEY-4 VALUE-4 - write an empty file
+ * KEY-5 (empty) - leave old empty file alone
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define ERROR_EXIT(strExit) \
+ { \
+ const int errnoSave = errno; \
+ fprintf(stderr, "%s: ", str_my_name); \
+ errno = errnoSave; \
+ perror((strExit)); \
+ exit(1); \
+ }
+
+
+
+int main(int argc, const char * argv [])
+{
+ const char * str_my_name;
+ const char * str_file_autoconf;
+ const char * str_dir_config;
+
+ FILE * fp_config;
+ FILE * fp_target;
+ FILE * fp_find;
+
+ int buffer_size;
+
+ char * line;
+ char * old_line;
+ char * list_target;
+ char * ptarget;
+
+ struct stat stat_buf;
+
+ /* Check arg count. */
+ if (argc != 3)
+ {
+ fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]);
+ exit(1);
+ }
+
+ str_my_name = argv[0];
+ str_file_autoconf = argv[1];
+ str_dir_config = argv[2];
+
+ /* Find a buffer size. */
+ if (stat(str_file_autoconf, &stat_buf) != 0)
+ ERROR_EXIT(str_file_autoconf);
+ buffer_size = 2 * stat_buf.st_size + 4096;
+
+ /* Allocate buffers. */
+ if ( (line = malloc(buffer_size)) == NULL
+ || (old_line = malloc(buffer_size)) == NULL
+ || (list_target = malloc(buffer_size)) == NULL )
+ ERROR_EXIT(str_file_autoconf);
+
+ /* Open autoconfig file. */
+ if ((fp_config = fopen(str_file_autoconf, "r")) == NULL)
+ ERROR_EXIT(str_file_autoconf);
+
+ /* Make output directory if needed. */
+ if (stat(str_dir_config, &stat_buf) != 0)
+ {
+ if (mkdir(str_dir_config, 0755) != 0)
+ ERROR_EXIT(str_dir_config);
+ }
+
+ /* Change to output directory. */
+ if (chdir(str_dir_config) != 0)
+ ERROR_EXIT(str_dir_config);
+
+ /* Put initial separator into target list. */
+ ptarget = list_target;
+ *ptarget++ = '\n';
+
+ /* Read config lines. */
+ while (fgets(line, buffer_size, fp_config))
+ {
+ const signed char * str_config;
+ int is_same;
+ int itarget;
+
+ if (line[0] != '#')
+ continue;
+ if ((str_config = strstr(line, "CONFIG_")) == NULL)
+ continue;
+
+ /* Make the output file name. */
+ str_config += sizeof("CONFIG_") - 1;
+ for (itarget = 0; !isspace(str_config[itarget]); itarget++)
+ {
+ int c = (unsigned char) str_config[itarget];
+ if (isupper(c)) c = tolower(c);
+ if (c == '_') c = '/';
+ ptarget[itarget] = c;
+ }
+ ptarget[itarget++] = '.';
+ ptarget[itarget++] = 'h';
+ ptarget[itarget++] = '\0';
+
+ /* Check for existing file. */
+ is_same = 0;
+ if ((fp_target = fopen(ptarget, "r")) != NULL)
+ {
+ fgets(old_line, buffer_size, fp_target);
+ if (fclose(fp_target) != 0)
+ ERROR_EXIT(ptarget);
+ if (!strcmp(line, old_line))
+ is_same = 1;
+ }
+
+ if (!is_same)
+ {
+ /* Auto-create directories. */
+ int islash;
+ for (islash = 0; islash < itarget; islash++)
+ {
+ if (ptarget[islash] == '/')
+ {
+ ptarget[islash] = '\0';
+ if (stat(ptarget, &stat_buf) != 0
+ && mkdir(ptarget, 0755) != 0)
+ ERROR_EXIT( ptarget );
+ ptarget[islash] = '/';
+ }
+ }
+
+ /* Write the file. */
+ if ((fp_target = fopen(ptarget, "w" )) == NULL)
+ ERROR_EXIT(ptarget);
+ fputs(line, fp_target);
+ if (ferror(fp_target) || fclose(fp_target) != 0)
+ ERROR_EXIT(ptarget);
+ }
+
+ /* Update target list */
+ ptarget += itarget;
+ *(ptarget-1) = '\n';
+ }
+
+ /*
+ * Close autoconfig file.
+ * Terminate the target list.
+ */
+ if (fclose(fp_config) != 0)
+ ERROR_EXIT(str_file_autoconf);
+ *ptarget = '\0';
+
+ /*
+ * Fix up existing files which have no new value.
+ * This is Case 4 and Case 5.
+ *
+ * I re-read the tree and filter it against list_target.
+ * This is crude. But it avoids data copies. Also, list_target
+ * is compact and contiguous, so it easily fits into cache.
+ *
+ * Notice that list_target contains strings separated by \n,
+ * with a \n before the first string and after the last.
+ * fgets gives the incoming names a terminating \n.
+ * So by having an initial \n, strstr will find exact matches.
+ */
+
+ fp_find = popen("find * -type f -name \"*.h\" -print", "r");
+ if (fp_find == 0)
+ ERROR_EXIT( "find" );
+
+ line[0] = '\n';
+ while (fgets(line+1, buffer_size, fp_find))
+ {
+ if (strstr(list_target, line) == NULL)
+ {
+ /*
+ * This is an old file with no CONFIG_* flag in autoconf.h.
+ */
+
+ /* First strip the \n. */
+ line[strlen(line)-1] = '\0';
+
+ /* Grab size. */
+ if (stat(line+1, &stat_buf) != 0)
+ ERROR_EXIT(line);
+
+ /* If file is not empty, make it empty and give it a fresh date. */
+ if (stat_buf.st_size != 0)
+ {
+ if ((fp_target = fopen(line+1, "w")) == NULL)
+ ERROR_EXIT(line);
+ if (fclose(fp_target) != 0)
+ ERROR_EXIT(line);
+ }
+ }
+ }
+
+ if (pclose(fp_find) != 0)
+ ERROR_EXIT("find");
+
+ return 0;
+}
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 @@
+/*
+ * Unloved program to convert a binary on stdin to a C include on stdout
+ *
+ * Jan 1999 Matt Mackall <mpm@selenic.com>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ int ch, total=0;
+
+ if (argc > 1)
+ printf("const char %s[] %s=\n",
+ argv[1], argc > 2 ? argv[2] : "");
+
+ do {
+ printf("\t\"");
+ while ((ch = getchar()) != EOF)
+ {
+ total++;
+ printf("\\x%02x",ch);
+ if (total % 16 == 0)
+ break;
+ }
+ printf("\"\n");
+ } while (ch != EOF);
+
+ if (argc > 1)
+ printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
+
+ return 0;
+}
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 @@
+/***************************************************************************
+ * binoffset.c
+ * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# binoffset.c:
+# - searches a (binary) file for a specified (binary) pattern
+# - returns the offset of the located pattern or ~0 if not found
+# - exits with exit status 0 normally or non-0 if pattern is not found
+# or any other error occurs.
+
+****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#define VERSION "0.1"
+#define BUF_SIZE (16 * 1024)
+#define PAT_SIZE 100
+
+char *progname;
+char *inputname;
+int inputfd;
+unsigned int bix; /* buf index */
+unsigned char patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */
+int pat_len; /* actual number of pattern bytes */
+unsigned char *madr; /* mmap address */
+size_t filesize;
+int num_matches = 0;
+off_t firstloc = 0;
+
+void usage (void)
+{
+ fprintf (stderr, "%s ver. %s\n", progname, VERSION);
+ fprintf (stderr, "usage: %s filename pattern_bytes\n",
+ progname);
+ fprintf (stderr, " [prints location of pattern_bytes in file]\n");
+ exit (1);
+}
+
+void get_pattern (int pat_count, char *pats [])
+{
+ int ix, err, tmp;
+
+#ifdef DEBUG
+ fprintf (stderr,"get_pattern: count = %d\n", pat_count);
+ for (ix = 0; ix < pat_count; ix++)
+ fprintf (stderr, " pat # %d: [%s]\n", ix, pats[ix]);
+#endif
+
+ for (ix = 0; ix < pat_count; ix++) {
+ tmp = 0;
+ err = sscanf (pats[ix], "%5i", &tmp);
+ if (err != 1 || tmp > 0xff) {
+ fprintf (stderr, "pattern or value error in pattern # %d [%s]\n",
+ ix, pats[ix]);
+ usage ();
+ }
+ patterns [ix] = tmp;
+ }
+ pat_len = pat_count;
+}
+
+void search_pattern (void)
+{
+ for (bix = 0; bix < filesize; bix++) {
+ if (madr[bix] == patterns[0]) {
+ if (memcmp (&madr[bix], patterns, pat_len) == 0) {
+ if (num_matches == 0)
+ firstloc = bix;
+ num_matches++;
+ }
+ }
+ }
+}
+
+#ifdef NOTDEF
+size_t get_filesize (int fd)
+{
+ off_t end_off = lseek (fd, 0, SEEK_END);
+ lseek (fd, 0, SEEK_SET);
+ return (size_t) end_off;
+}
+#endif
+
+size_t get_filesize (int fd)
+{
+ int err;
+ struct stat stat;
+
+ err = fstat (fd, &stat);
+ fprintf (stderr, "filesize: %ld\n", err < 0 ? (long)err : stat.st_size);
+ if (err < 0)
+ return err;
+ return (size_t) stat.st_size;
+}
+
+int main (int argc, char *argv [])
+{
+ progname = argv[0];
+
+ if (argc < 3)
+ usage ();
+
+ get_pattern (argc - 2, argv + 2);
+
+ inputname = argv[1];
+
+ inputfd = open (inputname, O_RDONLY);
+ if (inputfd == -1) {
+ fprintf (stderr, "%s: cannot open '%s'\n",
+ progname, inputname);
+ exit (3);
+ }
+
+ filesize = get_filesize (inputfd);
+
+ madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0);
+ if (madr == MAP_FAILED) {
+ fprintf (stderr, "mmap error = %d\n", errno);
+ close (inputfd);
+ exit (4);
+ }
+
+ search_pattern ();
+
+ if (munmap (madr, filesize))
+ fprintf (stderr, "munmap error = %d\n", errno);
+
+ if (close (inputfd))
+ fprintf (stderr, "%s: error %d closing '%s'\n",
+ progname, errno, inputname);
+
+ fprintf (stderr, "number of pattern matches = %d\n", num_matches);
+ if (num_matches == 0)
+ firstloc = ~0;
+ printf ("%ld\n", firstloc);
+ fprintf (stderr, "%ld\n", firstloc);
+
+ exit (num_matches ? 0 : 2);
+}
+
+/* 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 @@
+#! /usr/bin/perl
+#
+# checkconfig: find uses of CONFIG_* names without matching definitions.
+# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>.
+
+use integer;
+
+$| = 1;
+
+foreach $file (@ARGV)
+{
+ # Open this file.
+ open(FILE, $file) || die "Can't open $file: $!\n";
+
+ # Initialize variables.
+ my $fInComment = 0;
+ my $fInString = 0;
+ my $fUseConfig = 0;
+ my $iLinuxConfig = 0;
+ my %configList = ();
+
+ LINE: while ( <FILE> )
+ {
+ # Strip comments.
+ $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
+ m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
+
+ # Pick up definitions.
+ if ( m/^\s*#/o )
+ {
+ $iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o;
+ $configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o;
+ }
+
+ # Strip strings.
+ $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next);
+ m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1)));
+
+ # Pick up definitions.
+ if ( m/^\s*#/o )
+ {
+ $iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o;
+ $configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o;
+ $configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o;
+ $configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o;
+ }
+
+ # Look for usages.
+ next unless m/CONFIG_/o;
+ WORD: while ( m/\bCONFIG_(\w+)/og )
+ {
+ $fUseConfig = 1;
+ last LINE if $iLinuxConfig;
+ next WORD if exists $configList{$1};
+ print "$file: $.: need CONFIG_$1.\n";
+ $configList{$1} = 0;
+ }
+ }
+
+ # Report superfluous includes.
+ if ( $iLinuxConfig && ! $fUseConfig )
+ { print "$file: $iLinuxConfig: linux/config.h not needed.\n"; }
+
+ close(FILE);
+}
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 @@
+#!/usr/bin/perl
+#
+# checkincludes: Find files included more than once in (other) files.
+# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>.
+
+foreach $file (@ARGV) {
+ open(FILE, $file) or die "Cannot open $file: $!.\n";
+
+ my %includedfiles = ();
+
+ while (<FILE>) {
+ if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
+ ++$includedfiles{$1};
+ }
+ }
+
+ foreach $filename (keys %includedfiles) {
+ if ($includedfiles{$filename} > 1) {
+ print "$file: $filename is included more than once.\n";
+ }
+ }
+
+ close(FILE);
+}
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 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <joern@wh.fh-wedel.de>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+# s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
+# Mips port by Juan Quintela <quintela@mandrakesoft.com>
+# IA64 port via Andreas Dilger
+# Arm port by Holger Schurig
+# sh64 port by Paul Mundt
+# Random bits by Matt Mackall <mpm@selenic.com>
+# M68k port by Geert Uytterhoeven and Andreas Schwab
+#
+# Usage:
+# objdump -d vmlinux | stackcheck.pl [arch]
+#
+# TODO : Port to all architectures (one regex per arch)
+
+# check for arch
+#
+# $re is used for two matches:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the size of the stack growth
+#
+# use anything else and feel the pain ;)
+my (@stack, $re, $x, $xs);
+{
+ my $arch = shift;
+ if ($arch eq "") {
+ $arch = `uname -m`;
+ }
+
+ $x = "[0-9a-f]"; # hex character
+ $xs = "[0-9a-f ]"; # hex character or space
+ if ($arch eq 'arm') {
+ #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
+ $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch =~ /^i[3456]86$/) {
+ #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+ $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o;
+ } elsif ($arch eq 'x86_64') {
+ # 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp
+ $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%rsp$/o;
+ } elsif ($arch eq 'ia64') {
+ #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12
+ $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
+ } elsif ($arch eq 'm68k') {
+ # 2b6c: 4e56 fb70 linkw %fp,#-1168
+ # 1df770: defc ffe4 addaw #-28,%sp
+ $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
+ } elsif ($arch eq 'mips64') {
+ #8800402c: 67bdfff0 daddiu sp,sp,-16
+ $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch eq 'mips') {
+ #88003254: 27bdffe0 addiu sp,sp,-32
+ $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch eq 'ppc') {
+ #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+ $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
+ } elsif ($arch eq 'ppc64') {
+ #XXX
+ $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
+ } elsif ($arch =~ /^s390x?$/) {
+ # 11160: a7 fb ff 60 aghi %r15,-160
+ $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch =~ /^sh64$/) {
+ #XXX: we only check for the immediate case presently,
+ # though we will want to check for the movi/sub
+ # pair for larger users. -- PFM.
+ #a00048e0: d4fc40f0 addi.l r15,-240,r15
+ $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
+ } else {
+ print("wrong or unknown architecture\n");
+ exit
+ }
+}
+
+sub bysize($) {
+ my ($asize, $bsize);
+ ($asize = $a) =~ s/.*: *(.*)$/$1/;
+ ($bsize = $b) =~ s/.*: *(.*)$/$1/;
+ $bsize <=> $asize
+}
+
+#
+# main()
+#
+my $funcre = qr/^$x* <(.*)>:$/;
+my $func;
+while (my $line = <STDIN>) {
+ if ($line =~ m/$funcre/) {
+ $func = $1;
+ }
+ if ($line =~ m/$re/) {
+ my $size = $1;
+ $size = hex($size) if ($size =~ /^0x/);
+
+ if ($size > 0xf0000000) {
+ $size = - $size;
+ $size += 0x80000000;
+ $size += 0x80000000;
+ }
+ next if ($size > 0x10000000);
+
+ next if $line !~ m/^($xs*)/;
+ my $addr = $1;
+ $addr =~ s/ /0/g;
+ $addr = "0x$addr";
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ next if ($size < 100);
+ push @stack, "$intro$size\n";
+ }
+}
+
+print 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 @@
+#! /usr/bin/perl
+#
+# checkversion find uses of LINUX_VERSION_CODE, KERNEL_VERSION, or
+# UTS_RELEASE without including <linux/version.h>, or cases of
+# including <linux/version.h> that don't need it.
+# Copyright (C) 2003, Randy Dunlap <rddunlap@osdl.org>
+
+$| = 1;
+
+my $debugging = 0;
+
+foreach $file (@ARGV)
+{
+ # Open this file.
+ open(FILE, $file) || die "Can't open $file: $!\n";
+
+ # Initialize variables.
+ my $fInComment = 0;
+ my $fInString = 0;
+ my $fUseVersion = 0;
+ my $iLinuxVersion = 0;
+
+ LINE: while ( <FILE> )
+ {
+ # Strip comments.
+ $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
+ m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
+
+ # Pick up definitions.
+ if ( m/^\s*#/o ) {
+ $iLinuxVersion = $. if m/^\s*#\s*include\s*"linux\/version\.h"/o;
+ }
+
+ # Strip strings.
+ $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next);
+ m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1)));
+
+ # Pick up definitions.
+ if ( m/^\s*#/o ) {
+ $iLinuxVersion = $. if m/^\s*#\s*include\s*<linux\/version\.h>/o;
+ }
+
+ # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
+ if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/) ||
+ ($_ =~ /UTS_RELEASE/)) {
+ $fUseVersion = 1;
+ last LINE if $iLinuxVersion;
+ }
+ }
+
+ # Report used version IDs without include?
+ if ($fUseVersion && ! $iLinuxVersion) {
+ print "$file: $.: need linux/version.h\n";
+ }
+
+ # Report superfluous includes.
+ if ($iLinuxVersion && ! $fUseVersion) {
+ print "$file: $iLinuxVersion linux/version.h not needed.\n";
+ }
+
+ # debug: report OK results:
+ if ($debugging) {
+ if ($iLinuxVersion && $fUseVersion) {
+ print "$file: version use is OK ($iLinuxVersion)\n";
+ }
+ if (! $iLinuxVersion && ! $fUseVersion) {
+ print "$file: version use is OK (none)\n";
+ }
+ }
+
+ close(FILE);
+}
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 @@
+/*
+ * conmakehash.c
+ *
+ * Create arrays for initializing the kernel folded tables (using a hash
+ * table turned out to be to limiting...) Unfortunately we can't simply
+ * preinitialize the tables at compile time since kfree() cannot accept
+ * memory not allocated by kmalloc(), and doing our own memory management
+ * just for this seems like massive overkill.
+ *
+ * Copyright (C) 1995-1997 H. Peter Anvin
+ *
+ * This program is a part of the Linux kernel, and may be freely
+ * copied under the terms of the GNU General Public License (GPL),
+ * version 2, or at your option any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <string.h>
+#include <ctype.h>
+
+#define MAX_FONTLEN 256
+
+typedef unsigned short unicode;
+
+void usage(char *argv0)
+{
+ fprintf(stderr, "Usage: \n"
+ " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
+ exit(EX_USAGE);
+}
+
+int getunicode(char **p0)
+{
+ unsigned char *p = *p0;
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p != 'U' || p[1] != '+' ||
+ !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
+ !isxdigit(p[5]) || isxdigit(p[6]))
+ return -1;
+ *p0 = p+6;
+ return strtol(p+2,0,16);
+}
+
+unicode unitable[MAX_FONTLEN][255];
+ /* Massive overkill, but who cares? */
+int unicount[MAX_FONTLEN];
+
+void addpair(int fp, int un)
+{
+ int i;
+
+ if ( un <= 0xfffe )
+ {
+ /* Check it isn't a duplicate */
+
+ for ( i = 0 ; i < unicount[fp] ; i++ )
+ if ( unitable[fp][i] == un )
+ return;
+
+ /* Add to list */
+
+ if ( unicount[fp] > 254 )
+ {
+ fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
+ exit(EX_DATAERR);
+ }
+
+ unitable[fp][unicount[fp]] = un;
+ unicount[fp]++;
+ }
+
+ /* otherwise: ignore */
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *ctbl;
+ char *tblname;
+ char buffer[65536];
+ int fontlen;
+ int i, nuni, nent;
+ int fp0, fp1, un0, un1;
+ char *p, *p1;
+
+ if ( argc < 2 || argc > 5 )
+ usage(argv[0]);
+
+ if ( !strcmp(argv[1],"-") )
+ {
+ ctbl = stdin;
+ tblname = "stdin";
+ }
+ else
+ {
+ ctbl = fopen(tblname = argv[1], "r");
+ if ( !ctbl )
+ {
+ perror(tblname);
+ exit(EX_NOINPUT);
+ }
+ }
+
+ /* For now we assume the default font is always 256 characters. */
+ fontlen = 256;
+
+ /* Initialize table */
+
+ for ( i = 0 ; i < fontlen ; i++ )
+ unicount[i] = 0;
+
+ /* Now we come to the tricky part. Parse the input table. */
+
+ while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
+ {
+ if ( (p = strchr(buffer, '\n')) != NULL )
+ *p = '\0';
+ else
+ fprintf(stderr, "%s: Warning: line too long\n", tblname);
+
+ p = buffer;
+
+/*
+ * Syntax accepted:
+ * <fontpos> <unicode> <unicode> ...
+ * <range> idem
+ * <range> <unicode range>
+ *
+ * where <range> ::= <fontpos>-<fontpos>
+ * and <unicode> ::= U+<h><h><h><h>
+ * and <h> ::= <hexadecimal digit>
+ */
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (!*p || *p == '#')
+ continue; /* skip comment or blank line */
+
+ fp0 = strtol(p, &p1, 0);
+ if (p1 == p)
+ {
+ fprintf(stderr, "Bad input line: %s\n", buffer);
+ exit(EX_DATAERR);
+ }
+ p = p1;
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '-')
+ {
+ p++;
+ fp1 = strtol(p, &p1, 0);
+ if (p1 == p)
+ {
+ fprintf(stderr, "Bad input line: %s\n", buffer);
+ exit(EX_DATAERR);
+ }
+ p = p1;
+ }
+ else
+ fp1 = 0;
+
+ if ( fp0 < 0 || fp0 >= fontlen )
+ {
+ fprintf(stderr,
+ "%s: Glyph number (0x%x) larger than font length\n",
+ tblname, fp0);
+ exit(EX_DATAERR);
+ }
+ if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
+ {
+ fprintf(stderr,
+ "%s: Bad end of range (0x%x)\n",
+ tblname, fp1);
+ exit(EX_DATAERR);
+ }
+
+ if (fp1)
+ {
+ /* we have a range; expect the word "idem" or a Unicode range of the
+ same length */
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (!strncmp(p, "idem", 4))
+ {
+ for (i=fp0; i<=fp1; i++)
+ addpair(i,i);
+ p += 4;
+ }
+ else
+ {
+ un0 = getunicode(&p);
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p != '-')
+ {
+ fprintf(stderr,
+"%s: Corresponding to a range of font positions, there should be a Unicode range\n",
+ tblname);
+ exit(EX_DATAERR);
+ }
+ p++;
+ un1 = getunicode(&p);
+ if (un0 < 0 || un1 < 0)
+ {
+ fprintf(stderr,
+"%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
+ tblname, fp0, fp1);
+ exit(EX_DATAERR);
+ }
+ if (un1 - un0 != fp1 - fp0)
+ {
+ fprintf(stderr,
+"%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
+ tblname, un0, un1, fp0, fp1);
+ exit(EX_DATAERR);
+ }
+ for(i=fp0; i<=fp1; i++)
+ addpair(i,un0-fp0+i);
+ }
+ }
+ else
+ {
+ /* no range; expect a list of unicode values for a single font position */
+
+ while ( (un0 = getunicode(&p)) >= 0 )
+ addpair(fp0, un0);
+ }
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p && *p != '#')
+ fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
+ }
+
+ /* Okay, we hit EOF, now output hash table */
+
+ fclose(ctbl);
+
+
+ /* Compute total size of Unicode list */
+ nuni = 0;
+ for ( i = 0 ; i < fontlen ; i++ )
+ nuni += unicount[i];
+
+ printf("\
+/*\n\
+ * Do not edit this file; it was automatically generated by\n\
+ *\n\
+ * conmakehash %s > [this file]\n\
+ *\n\
+ */\n\
+\n\
+#include <linux/types.h>\n\
+\n\
+u8 dfont_unicount[%d] = \n\
+{\n\t", argv[1], fontlen);
+
+ for ( i = 0 ; i < fontlen ; i++ )
+ {
+ printf("%3d", unicount[i]);
+ if ( i == fontlen-1 )
+ printf("\n};\n");
+ else if ( i % 8 == 7 )
+ printf(",\n\t");
+ else
+ printf(", ");
+ }
+
+ printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
+
+ fp0 = 0;
+ nent = 0;
+ for ( i = 0 ; i < nuni ; i++ )
+ {
+ while ( nent >= unicount[fp0] )
+ {
+ fp0++;
+ nent = 0;
+ }
+ printf("0x%04x", unitable[fp0][nent++]);
+ if ( i == nuni-1 )
+ printf("\n};\n");
+ else if ( i % 8 == 7 )
+ printf(",\n\t");
+ else
+ printf(", ");
+ }
+
+ exit(EX_OK);
+}
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 @@
+#!/bin/sh
+# extracts .config info from a [b]zImage file
+# uses: binoffset (new), dd, zcat, strings, grep
+# $arg1 is [b]zImage filename
+
+binoffset="./scripts/binoffset"
+
+IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
+IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
+function dump_config {
+ typeset file="$1"
+
+ start=`$binoffset $file $IKCFG_ST 2>/dev/null`
+ [ "$?" != "0" ] && start="-1"
+ if [ "$start" -eq "-1" ]; then
+ return
+ fi
+ end=`$binoffset $file $IKCFG_ED 2>/dev/null`
+
+ let start="$start + 8"
+ let size="$end - $start"
+
+ head --bytes="$end" "$file" | tail --bytes="$size" | zcat
+
+ clean_up
+ exit 0
+}
+
+
+usage()
+{
+ echo " usage: extract-ikconfig [b]zImage_filename"
+}
+
+clean_up()
+{
+ if [ "$TMPFILE" != "" ]; then
+ rm -f $TMPFILE
+ fi
+}
+
+if [ $# -lt 1 ]
+then
+ usage
+ exit 1
+fi
+
+TMPFILE="/tmp/ikconfig-$$"
+image="$1"
+
+# vmlinux: Attempt to dump the configuration from the file directly
+dump_config "$image"
+
+GZHDR1="0x1f 0x8b 0x08 0x00"
+GZHDR2="0x1f 0x8b 0x08 0x08"
+
+# vmlinux.gz: Check for a compressed images
+off=`$binoffset "$image" $GZHDR1 2>/dev/null`
+[ "$?" != "0" ] && off="-1"
+if [ "$off" -eq "-1" ]; then
+ off=`$binoffset "$image" $GZHDR2 2>/dev/null`
+ [ "$?" != "0" ] && off="-1"
+fi
+if [ "$off" -eq "0" ]; then
+ zcat <"$image" >"$TMPFILE"
+ dump_config "$TMPFILE"
+elif [ "$off" -ne "-1" ]; then
+ (dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \
+ zcat >"$TMPFILE"
+ dump_config "$TMPFILE"
+fi
+
+echo "ERROR: Unable to extract kernel configuration information."
+echo " This kernel image may not have the config info."
+
+clean_up
+exit 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 @@
+#!/bin/sh
+#
+# gcc-version gcc-command
+#
+# Prints the gcc version of `gcc-command' in a canonical 4-digit form
+# such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc.
+#
+
+compiler="$*"
+
+MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
+MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
+printf "%02d%02d\\n" $MAJOR $MINOR
+
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 @@
+#!/bin/bash
+# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
+# Released under the terms of the GNU GPL
+#
+# Generate a newline separated list of entries from the file/directory
+# supplied as an argument.
+#
+# If a file/directory is not supplied then generate a small dummy file.
+#
+# The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c.
+#
+
+default_initramfs() {
+ cat <<-EOF
+ # This is a very simple, default initramfs
+
+ dir /dev 0755 0 0
+ nod /dev/console 0600 0 0 c 5 1
+ dir /root 0700 0 0
+ EOF
+}
+
+filetype() {
+ local argv1="$1"
+
+ # symlink test must come before file test
+ if [ -L "${argv1}" ]; then
+ echo "slink"
+ elif [ -f "${argv1}" ]; then
+ echo "file"
+ elif [ -d "${argv1}" ]; then
+ echo "dir"
+ elif [ -b "${argv1}" -o -c "${argv1}" ]; then
+ echo "nod"
+ elif [ -p "${argv1}" ]; then
+ echo "pipe"
+ elif [ -S "${argv1}" ]; then
+ echo "sock"
+ else
+ echo "invalid"
+ fi
+ return 0
+}
+
+print_mtime() {
+ local argv1="$1"
+ local my_mtime="0"
+
+ if [ -e "${argv1}" ]; then
+ my_mtime=$(find "${argv1}" -printf "%T@\n" | sort -r | head -n 1)
+ fi
+
+ echo "# Last modified: ${my_mtime}"
+ echo
+}
+
+parse() {
+ local location="$1"
+ local name="${location/${srcdir}//}"
+ # change '//' into '/'
+ name="${name//\/\///}"
+ local mode="$2"
+ local uid="$3"
+ local gid="$4"
+ local ftype=$(filetype "${location}")
+ # remap uid/gid to 0 if necessary
+ [ "$uid" -eq "$root_uid" ] && uid=0
+ [ "$gid" -eq "$root_gid" ] && gid=0
+ local str="${mode} ${uid} ${gid}"
+
+ [ "${ftype}" == "invalid" ] && return 0
+ [ "${location}" == "${srcdir}" ] && return 0
+
+ case "${ftype}" in
+ "file")
+ str="${ftype} ${name} ${location} ${str}"
+ ;;
+ "nod")
+ local dev_type=
+ local maj=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{sub(/,/, "", $5); print $5}')
+ local min=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{print $6}')
+
+ if [ -b "${location}" ]; then
+ dev_type="b"
+ else
+ dev_type="c"
+ fi
+ str="${ftype} ${name} ${str} ${dev_type} ${maj} ${min}"
+ ;;
+ "slink")
+ local target=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{print $11}')
+ str="${ftype} ${name} ${target} ${str}"
+ ;;
+ *)
+ str="${ftype} ${name} ${str}"
+ ;;
+ esac
+
+ echo "${str}"
+
+ return 0
+}
+
+usage() {
+ printf "Usage:\n"
+ printf "$0 [ [-u <root_uid>] [-g <root_gid>] [-d | <cpio_source>] ] . . .\n"
+ printf "\n"
+ printf -- "-u <root_uid> User ID to map to user ID 0 (root).\n"
+ printf " <root_uid> is only meaningful if <cpio_source>\n"
+ printf " is a directory.\n"
+ printf -- "-g <root_gid> Group ID to map to group ID 0 (root).\n"
+ printf " <root_gid> is only meaningful if <cpio_source>\n"
+ printf " is a directory.\n"
+ printf "<cpio_source> File list or directory for cpio archive.\n"
+ printf " If <cpio_source> is not provided then a\n"
+ printf " a default list will be output.\n"
+ printf -- "-d Output the default cpio list. If no <cpio_source>\n"
+ printf " is given then the default cpio list will be output.\n"
+ printf "\n"
+ printf "All options may be repeated and are interpreted sequentially\n"
+ printf "and immediately. -u and -g states are preserved across\n"
+ printf "<cpio_source> options so an explicit \"-u 0 -g 0\" is required\n"
+ printf "to reset the root/group mapping.\n"
+}
+
+build_list() {
+ printf "\n#####################\n# $cpio_source\n"
+
+ if [ -f "$cpio_source" ]; then
+ print_mtime "$cpio_source"
+ cat "$cpio_source"
+ elif [ -d "$cpio_source" ]; then
+ srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g')
+ dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null)
+
+ # If $dirlist is only one line, then the directory is empty
+ if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
+ print_mtime "$cpio_source"
+
+ echo "${dirlist}" | \
+ while read x; do
+ parse ${x}
+ done
+ else
+ # Failsafe in case directory is empty
+ default_initramfs
+ fi
+ else
+ echo " $0: Cannot open '$cpio_source'" >&2
+ exit 1
+ fi
+}
+
+
+root_uid=0
+root_gid=0
+
+while [ $# -gt 0 ]; do
+ arg="$1"
+ shift
+ case "$arg" in
+ "-u")
+ root_uid="$1"
+ shift
+ ;;
+ "-g")
+ root_gid="$1"
+ shift
+ ;;
+ "-d")
+ default_list="$arg"
+ default_initramfs
+ ;;
+ "-h")
+ usage
+ exit 0
+ ;;
+ *)
+ case "$arg" in
+ "-"*)
+ printf "ERROR: unknown option \"$arg\"\n" >&2
+ printf "If the filename validly begins with '-', then it must be prefixed\n" >&2
+ printf "by './' so that it won't be interpreted as an option." >&2
+ printf "\n" >&2
+ usage >&2
+ exit 1
+ ;;
+ *)
+ cpio_source="$arg"
+ build_list
+ ;;
+ esac
+ ;;
+ esac
+done
+
+# spit out the default cpio list if a source hasn't been specified
+[ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs
+
+exit 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 @@
+
+hostprogs-y := genksyms
+always := $(hostprogs-y)
+
+genksyms-objs := genksyms.o parse.o lex.o
+
+# -I needed for generated C source (shipped source)
+HOSTCFLAGS_parse.o := -Wno-uninitialized -I$(src)
+
+# dependencies on generated files need to be listed explicitly
+$(obj)/lex.o: $(obj)/parse.h $(obj)/keywords.c
+
+# -I needed for generated C source (shipped source)
+HOSTCFLAGS_lex.o := -I$(src)
+
+ifdef GENERATE_PARSER
+
+# gperf
+
+quiet_cmd_keywords.c = GPERF $@
+ cmd_keywords.c = gperf -L ANSI-C -a -C -E -g -H is_reserved_hash \
+ -k 1,3,$$ -N is_reserved_word -p -t $< > $@
+
+$(obj)/keywords.c: $(obj)/keywords.gperf FORCE
+ $(call if_changed,keywords.c)
+
+# flex
+
+quiet_cmd_lex.c = FLEX $@
+ cmd_lex.c = flex -o$@ -d $(filter-out FORCE,$^)
+
+$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h FORCE
+ $(call if_changed,lex.c)
+
+# bison
+
+quiet_cmd_parse.c = BISON $@
+ cmd_parse.c = bison -o$@ -dtv $(filter-out FORCE,$^)
+
+$(obj)/parse.c: $(obj)/parse.y FORCE
+ $(call if_changed,parse.c)
+
+$(obj)/parse.h: $(obj)/parse.c ;
+
+clean-files += parse.output
+
+endif
+
+targets += 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 @@
+/* Generate kernel symbol version hashes.
+ Copyright 1996, 1997 Linux International.
+
+ New implementation contributed by Richard Henderson <rth@tamu.edu>
+ Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+ This file was part of the Linux modutils 2.4.22: moved back into the
+ kernel sources by Rusty Russell/Kai Germaschewski.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdarg.h>
+#ifdef __GNU_LIBRARY__
+#include <getopt.h>
+#endif /* __GNU_LIBRARY__ */
+
+#include "genksyms.h"
+
+/*----------------------------------------------------------------------*/
+
+#define HASH_BUCKETS 4096
+
+static struct symbol *symtab[HASH_BUCKETS];
+FILE *debugfile;
+
+int cur_line = 1;
+char *cur_filename, *output_directory;
+
+int flag_debug, flag_dump_defs, flag_warnings;
+
+static int errors;
+static int nsyms;
+
+static struct symbol *expansion_trail;
+
+static const char * const symbol_type_name[] = {
+ "normal", "typedef", "enum", "struct", "union"
+};
+
+/*----------------------------------------------------------------------*/
+
+static const unsigned int crctab32[] =
+{
+ 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
+ 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
+ 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
+ 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
+ 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
+ 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
+ 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
+ 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
+ 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
+ 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
+ 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
+ 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
+ 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
+ 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
+ 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
+ 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
+ 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
+ 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
+ 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
+ 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
+ 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
+ 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
+ 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
+ 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
+ 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
+ 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
+ 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
+ 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
+ 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
+ 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
+ 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
+ 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
+ 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
+ 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
+ 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
+ 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
+ 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
+ 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
+ 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
+ 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
+ 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
+ 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
+ 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
+ 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
+ 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
+ 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
+ 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
+ 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
+ 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
+ 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
+ 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
+ 0x2d02ef8dU
+};
+
+static inline unsigned long
+partial_crc32_one(unsigned char c, unsigned long crc)
+{
+ return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
+}
+
+static inline unsigned long
+partial_crc32(const char *s, unsigned long crc)
+{
+ while (*s)
+ crc = partial_crc32_one(*s++, crc);
+ return crc;
+}
+
+static inline unsigned long
+crc32(const char *s)
+{
+ return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
+}
+
+
+/*----------------------------------------------------------------------*/
+
+static inline enum symbol_type
+map_to_ns(enum symbol_type t)
+{
+ if (t == SYM_TYPEDEF)
+ t = SYM_NORMAL;
+ else if (t == SYM_UNION)
+ t = SYM_STRUCT;
+ return t;
+}
+
+struct symbol *
+find_symbol(const char *name, enum symbol_type ns)
+{
+ unsigned long h = crc32(name) % HASH_BUCKETS;
+ struct symbol *sym;
+
+ for (sym = symtab[h]; sym ; sym = sym->hash_next)
+ if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0)
+ break;
+
+ return sym;
+}
+
+struct symbol *
+add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern)
+{
+ unsigned long h = crc32(name) % HASH_BUCKETS;
+ struct symbol *sym;
+
+ for (sym = symtab[h]; sym ; sym = sym->hash_next)
+ if (map_to_ns(sym->type) == map_to_ns(type)
+ && strcmp(name, sym->name) == 0)
+ {
+ if (!equal_list(sym->defn, defn))
+ error_with_pos("redefinition of %s", name);
+ return sym;
+ }
+
+ sym = xmalloc(sizeof(*sym));
+ sym->name = name;
+ sym->type = type;
+ sym->defn = defn;
+ sym->expansion_trail = NULL;
+ sym->is_extern = is_extern;
+
+ sym->hash_next = symtab[h];
+ symtab[h] = sym;
+
+ if (flag_debug)
+ {
+ fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name);
+ if (is_extern)
+ fputs("extern ", debugfile);
+ print_list(debugfile, defn);
+ fputs(">\n", debugfile);
+ }
+
+ ++nsyms;
+ return sym;
+}
+
+
+/*----------------------------------------------------------------------*/
+
+inline void
+free_node(struct string_list *node)
+{
+ free(node->string);
+ free(node);
+}
+
+void
+free_list(struct string_list *s, struct string_list *e)
+{
+ while (s != e)
+ {
+ struct string_list *next = s->next;
+ free_node(s);
+ s = next;
+ }
+}
+
+inline struct string_list *
+copy_node(struct string_list *node)
+{
+ struct string_list *newnode;
+
+ newnode = xmalloc(sizeof(*newnode));
+ newnode->string = xstrdup(node->string);
+ newnode->tag = node->tag;
+
+ return newnode;
+}
+
+struct string_list *
+copy_list(struct string_list *s, struct string_list *e)
+{
+ struct string_list *h, *p;
+
+ if (s == e)
+ return NULL;
+
+ p = h = copy_node(s);
+ while ((s = s->next) != e)
+ p = p->next = copy_node(s);
+ p->next = NULL;
+
+ return h;
+}
+
+int
+equal_list(struct string_list *a, struct string_list *b)
+{
+ while (a && b)
+ {
+ if (a->tag != b->tag || strcmp(a->string, b->string))
+ return 0;
+ a = a->next;
+ b = b->next;
+ }
+
+ return !a && !b;
+}
+
+static inline void
+print_node(FILE *f, struct string_list *list)
+{
+ switch (list->tag)
+ {
+ case SYM_STRUCT:
+ putc('s', f);
+ goto printit;
+ case SYM_UNION:
+ putc('u', f);
+ goto printit;
+ case SYM_ENUM:
+ putc('e', f);
+ goto printit;
+ case SYM_TYPEDEF:
+ putc('t', f);
+ goto printit;
+
+ printit:
+ putc('#', f);
+ case SYM_NORMAL:
+ fputs(list->string, f);
+ break;
+ }
+}
+
+void
+print_list(FILE *f, struct string_list *list)
+{
+ struct string_list **e, **b;
+ struct string_list *tmp, **tmp2;
+ int elem = 1;
+
+ if (list == NULL)
+ {
+ fputs("(nil)", f);
+ return;
+ }
+
+ tmp = list;
+ while((tmp = tmp->next) != NULL)
+ elem++;
+
+ b = alloca(elem * sizeof(*e));
+ e = b + elem;
+ tmp2 = e - 1;
+
+ (*tmp2--) = list;
+ while((list = list->next) != NULL)
+ *(tmp2--) = list;
+
+ while (b != e)
+ {
+ print_node(f, *b++);
+ putc(' ', f);
+ }
+}
+
+static unsigned long
+expand_and_crc_list(struct string_list *list, unsigned long crc)
+{
+ struct string_list **e, **b;
+ struct string_list *tmp, **tmp2;
+ int elem = 1;
+
+ if (!list)
+ return crc;
+
+ tmp = list;
+ while((tmp = tmp->next) != NULL)
+ elem++;
+
+ b = alloca(elem * sizeof(*e));
+ e = b + elem;
+ tmp2 = e - 1;
+
+ *(tmp2--) = list;
+ while ((list = list->next) != NULL)
+ *(tmp2--) = list;
+
+ while (b != e)
+ {
+ struct string_list *cur;
+ struct symbol *subsym;
+
+ cur = *(b++);
+ switch (cur->tag)
+ {
+ case SYM_NORMAL:
+ if (flag_dump_defs)
+ fprintf(debugfile, "%s ", cur->string);
+ crc = partial_crc32(cur->string, crc);
+ crc = partial_crc32_one(' ', crc);
+ break;
+
+ case SYM_TYPEDEF:
+ subsym = find_symbol(cur->string, cur->tag);
+ if (subsym->expansion_trail)
+ {
+ if (flag_dump_defs)
+ fprintf(debugfile, "%s ", cur->string);
+ crc = partial_crc32(cur->string, crc);
+ crc = partial_crc32_one(' ', crc);
+ }
+ else
+ {
+ subsym->expansion_trail = expansion_trail;
+ expansion_trail = subsym;
+ crc = expand_and_crc_list(subsym->defn, crc);
+ }
+ break;
+
+ case SYM_STRUCT:
+ case SYM_UNION:
+ case SYM_ENUM:
+ subsym = find_symbol(cur->string, cur->tag);
+ if (!subsym)
+ {
+ struct string_list *n, *t = NULL;
+
+ error_with_pos("expand undefined %s %s",
+ symbol_type_name[cur->tag], cur->string);
+
+ n = xmalloc(sizeof(*n));
+ n->string = xstrdup(symbol_type_name[cur->tag]);
+ n->tag = SYM_NORMAL;
+ n->next = t;
+ t = n;
+
+ n = xmalloc(sizeof(*n));
+ n->string = xstrdup(cur->string);
+ n->tag = SYM_NORMAL;
+ n->next = t;
+ t = n;
+
+ n = xmalloc(sizeof(*n));
+ n->string = xstrdup("{ UNKNOWN }");
+ n->tag = SYM_NORMAL;
+ n->next = t;
+
+ subsym = add_symbol(cur->string, cur->tag, n, 0);
+ }
+ if (subsym->expansion_trail)
+ {
+ if (flag_dump_defs)
+ {
+ fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag],
+ cur->string);
+ }
+
+ crc = partial_crc32(symbol_type_name[cur->tag], crc);
+ crc = partial_crc32_one(' ', crc);
+ crc = partial_crc32(cur->string, crc);
+ crc = partial_crc32_one(' ', crc);
+ }
+ else
+ {
+ subsym->expansion_trail = expansion_trail;
+ expansion_trail = subsym;
+ crc = expand_and_crc_list(subsym->defn, crc);
+ }
+ break;
+ }
+ }
+
+ return crc;
+}
+
+void
+export_symbol(const char *name)
+{
+ struct symbol *sym;
+
+ sym = find_symbol(name, SYM_NORMAL);
+ if (!sym)
+ error_with_pos("export undefined symbol %s", name);
+ else
+ {
+ unsigned long crc;
+
+ if (flag_dump_defs)
+ fprintf(debugfile, "Export %s == <", name);
+
+ expansion_trail = (struct symbol *)-1L;
+
+ crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
+
+ sym = expansion_trail;
+ while (sym != (struct symbol *)-1L)
+ {
+ struct symbol *n = sym->expansion_trail;
+ sym->expansion_trail = 0;
+ sym = n;
+ }
+
+ if (flag_dump_defs)
+ fputs(">\n", debugfile);
+
+ /* Used as a linker script. */
+ printf("__crc_%s = 0x%08lx ;\n", name, crc);
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
+void
+error(const char *fmt, ...)
+{
+ va_list args;
+
+ if (flag_warnings)
+ {
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ putc('\n', stderr);
+
+ errors++;
+ }
+}
+
+void
+error_with_pos(const char *fmt, ...)
+{
+ va_list args;
+
+ if (flag_warnings)
+ {
+ fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ putc('\n', stderr);
+
+ errors++;
+ }
+}
+
+
+void genksyms_usage(void)
+{
+ fputs("Usage:\n"
+ "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n"
+ "\n"
+#ifdef __GNU_LIBRARY__
+ " -d, --debug Increment the debug level (repeatable)\n"
+ " -D, --dump Dump expanded symbol defs (for debugging only)\n"
+ " -w, --warnings Enable warnings\n"
+ " -q, --quiet Disable warnings (default)\n"
+ " -h, --help Print this message\n"
+ " -V, --version Print the release version\n"
+#else /* __GNU_LIBRARY__ */
+ " -d Increment the debug level (repeatable)\n"
+ " -D Dump expanded symbol defs (for debugging only)\n"
+ " -w Enable warnings\n"
+ " -q Disable warnings (default)\n"
+ " -h Print this message\n"
+ " -V Print the release version\n"
+#endif /* __GNU_LIBRARY__ */
+ , stderr);
+}
+
+int
+main(int argc, char **argv)
+{
+ int o;
+
+#ifdef __GNU_LIBRARY__
+ struct option long_opts[] = {
+ {"debug", 0, 0, 'd'},
+ {"warnings", 0, 0, 'w'},
+ {"quiet", 0, 0, 'q'},
+ {"dump", 0, 0, 'D'},
+ {"version", 0, 0, 'V'},
+ {"help", 0, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+
+ while ((o = getopt_long(argc, argv, "dwqVDk:p:",
+ &long_opts[0], NULL)) != EOF)
+#else /* __GNU_LIBRARY__ */
+ while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF)
+#endif /* __GNU_LIBRARY__ */
+ switch (o)
+ {
+ case 'd':
+ flag_debug++;
+ break;
+ case 'w':
+ flag_warnings = 1;
+ break;
+ case 'q':
+ flag_warnings = 0;
+ break;
+ case 'V':
+ fputs("genksyms version 2.5.60\n", stderr);
+ break;
+ case 'D':
+ flag_dump_defs = 1;
+ break;
+ case 'h':
+ genksyms_usage();
+ return 0;
+ default:
+ genksyms_usage();
+ return 1;
+ }
+
+ {
+ extern int yydebug;
+ extern int yy_flex_debug;
+
+ yydebug = (flag_debug > 1);
+ yy_flex_debug = (flag_debug > 2);
+
+ debugfile = stderr;
+ /* setlinebuf(debugfile); */
+ }
+
+ yyparse();
+
+ if (flag_debug)
+ {
+ fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
+ nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS);
+ }
+
+ return errors != 0;
+}
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 @@
+/* Generate kernel symbol version hashes.
+ Copyright 1996, 1997 Linux International.
+
+ New implementation contributed by Richard Henderson <rth@tamu.edu>
+ Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+ This file is part of the Linux modutils.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#ifndef MODUTILS_GENKSYMS_H
+#define MODUTILS_GENKSYMS_H 1
+
+#include <stdio.h>
+
+
+enum symbol_type
+{
+ SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
+};
+
+struct string_list
+{
+ struct string_list *next;
+ enum symbol_type tag;
+ char *string;
+};
+
+struct symbol
+{
+ struct symbol *hash_next;
+ const char *name;
+ enum symbol_type type;
+ struct string_list *defn;
+ struct symbol *expansion_trail;
+ int is_extern;
+};
+
+typedef struct string_list **yystype;
+#define YYSTYPE yystype
+
+extern FILE *outfile, *debugfile;
+
+extern int cur_line;
+extern char *cur_filename, *output_directory;
+
+extern int flag_debug, flag_dump_defs, flag_warnings;
+extern int checksum_version, kernel_version;
+
+extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents;
+extern struct string_list *current_list, *next_list;
+
+
+struct symbol *find_symbol(const char *name, enum symbol_type ns);
+struct symbol *add_symbol(const char *name, enum symbol_type type,
+ struct string_list *defn, int is_extern);
+void export_symbol(const char *);
+
+struct string_list *reset_list(void);
+void free_list(struct string_list *s, struct string_list *e);
+void free_node(struct string_list *list);
+struct string_list *copy_node(struct string_list *);
+struct string_list *copy_list(struct string_list *s, struct string_list *e);
+int equal_list(struct string_list *a, struct string_list *b);
+void print_list(FILE *, struct string_list *list);
+
+int yylex(void);
+int yyparse(void);
+
+void error_with_pos(const char *, ...);
+
+#define version(a,b,c) ((a << 16) | (b << 8) | (c))
+
+/*----------------------------------------------------------------------*/
+
+#define MODUTILS_VERSION "<in-kernel>"
+
+#define xmalloc(size) ({ void *__ptr = malloc(size); \
+ if(!__ptr && size != 0) { \
+ fprintf(stderr, "out of memory\n"); \
+ exit(1); \
+ } \
+ __ptr; })
+#define xstrdup(str) ({ char *__str = strdup(str); \
+ if (!__str) { \
+ fprintf(stderr, "out of memory\n"); \
+ exit(1); \
+ } \
+ __str; })
+
+#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 @@
+/* ANSI-C code produced by gperf version 2.7.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 */
+struct resword { const char *name; int token; };
+/* maximum key range = 109, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+is_reserved_hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 5,
+ 113, 113, 113, 113, 113, 113, 0, 113, 113, 113,
+ 0, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 0, 113, 0, 113, 20,
+ 25, 0, 35, 30, 113, 20, 113, 113, 40, 30,
+ 30, 0, 0, 113, 0, 51, 0, 15, 5, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113
+ };
+ return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
+}
+
+#ifdef __GNUC__
+__inline
+#endif
+const struct resword *
+is_reserved_word (register const char *str, register unsigned int len)
+{
+ enum
+ {
+ TOTAL_KEYWORDS = 41,
+ MIN_WORD_LENGTH = 3,
+ MAX_WORD_LENGTH = 17,
+ MIN_HASH_VALUE = 4,
+ MAX_HASH_VALUE = 112
+ };
+
+ static const struct resword wordlist[] =
+ {
+ {""}, {""}, {""}, {""},
+ {"auto", AUTO_KEYW},
+ {""}, {""},
+ {"__asm__", ASM_KEYW},
+ {""},
+ {"_restrict", RESTRICT_KEYW},
+ {"__typeof__", TYPEOF_KEYW},
+ {"__attribute", ATTRIBUTE_KEYW},
+ {"__restrict__", RESTRICT_KEYW},
+ {"__attribute__", ATTRIBUTE_KEYW},
+ {""},
+ {"__volatile", VOLATILE_KEYW},
+ {""},
+ {"__volatile__", VOLATILE_KEYW},
+ {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
+ {""}, {""}, {""},
+ {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
+ {"int", INT_KEYW},
+ {"char", CHAR_KEYW},
+ {""}, {""},
+ {"__const", CONST_KEYW},
+ {"__inline", INLINE_KEYW},
+ {"__const__", CONST_KEYW},
+ {"__inline__", INLINE_KEYW},
+ {""}, {""}, {""}, {""},
+ {"__asm", ASM_KEYW},
+ {"extern", EXTERN_KEYW},
+ {""},
+ {"register", REGISTER_KEYW},
+ {""},
+ {"float", FLOAT_KEYW},
+ {"typeof", TYPEOF_KEYW},
+ {"typedef", TYPEDEF_KEYW},
+ {""}, {""},
+ {"_Bool", BOOL_KEYW},
+ {"double", DOUBLE_KEYW},
+ {""}, {""},
+ {"enum", ENUM_KEYW},
+ {""}, {""}, {""},
+ {"volatile", VOLATILE_KEYW},
+ {"void", VOID_KEYW},
+ {"const", CONST_KEYW},
+ {"short", SHORT_KEYW},
+ {"struct", STRUCT_KEYW},
+ {""},
+ {"restrict", RESTRICT_KEYW},
+ {""},
+ {"__signed__", SIGNED_KEYW},
+ {""},
+ {"asm", ASM_KEYW},
+ {""}, {""},
+ {"inline", INLINE_KEYW},
+ {""}, {""}, {""},
+ {"union", UNION_KEYW},
+ {""}, {""}, {""}, {""}, {""}, {""},
+ {"static", STATIC_KEYW},
+ {""}, {""}, {""}, {""}, {""}, {""},
+ {"__signed", SIGNED_KEYW},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""},
+ {"unsigned", UNSIGNED_KEYW},
+ {""}, {""}, {""}, {""},
+ {"long", LONG_KEYW},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {"signed", SIGNED_KEYW}
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = is_reserved_hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register const char *s = wordlist[key].name;
+
+ if (*str == *s && !strcmp (str + 1, s + 1))
+ return &wordlist[key];
+ }
+ }
+ return 0;
+}
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 @@
+%{
+%}
+struct resword { const char *name; int token; }
+%%
+EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
+EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
+__asm, ASM_KEYW
+__asm__, ASM_KEYW
+__attribute, ATTRIBUTE_KEYW
+__attribute__, ATTRIBUTE_KEYW
+__const, CONST_KEYW
+__const__, CONST_KEYW
+__inline, INLINE_KEYW
+__inline__, INLINE_KEYW
+__signed, SIGNED_KEYW
+__signed__, SIGNED_KEYW
+__volatile, VOLATILE_KEYW
+__volatile__, VOLATILE_KEYW
+# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict. KAO
+_Bool, BOOL_KEYW
+_restrict, RESTRICT_KEYW
+__restrict__, RESTRICT_KEYW
+restrict, RESTRICT_KEYW
+asm, ASM_KEYW
+# attribute commented out in modutils 2.4.2. People are using 'attribute' as a
+# field name which breaks the genksyms parser. It is not a gcc keyword anyway.
+# KAO.
+# attribute, ATTRIBUTE_KEYW
+auto, AUTO_KEYW
+char, CHAR_KEYW
+const, CONST_KEYW
+double, DOUBLE_KEYW
+enum, ENUM_KEYW
+extern, EXTERN_KEYW
+float, FLOAT_KEYW
+inline, INLINE_KEYW
+int, INT_KEYW
+long, LONG_KEYW
+register, REGISTER_KEYW
+short, SHORT_KEYW
+signed, SIGNED_KEYW
+static, STATIC_KEYW
+struct, STRUCT_KEYW
+typedef, TYPEDEF_KEYW
+union, UNION_KEYW
+unsigned, UNSIGNED_KEYW
+void, VOID_KEYW
+volatile, VOLATILE_KEYW
+typeof, TYPEOF_KEYW
+__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 @@
+#line 2 "scripts/genksyms/lex.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+
+#define FLEX_DEBUG
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+
+#define FLEX_DEBUG
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 13
+#define YY_END_OF_BUFFER 14
+static yyconst short int yy_accept[76] =
+ { 0,
+ 0, 0, 0, 0, 14, 12, 4, 3, 12, 7,
+ 12, 12, 7, 12, 12, 12, 12, 12, 9, 9,
+ 12, 12, 12, 4, 0, 5, 0, 7, 0, 6,
+ 0, 0, 0, 0, 0, 0, 2, 8, 10, 10,
+ 9, 0, 0, 9, 9, 0, 9, 0, 0, 11,
+ 0, 0, 0, 10, 0, 10, 9, 9, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 0, 0, 0,
+ 0, 0, 0, 1, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 5, 6, 7, 8, 9, 10, 1,
+ 1, 8, 11, 1, 12, 13, 8, 14, 15, 15,
+ 15, 15, 15, 15, 15, 16, 16, 1, 1, 17,
+ 18, 19, 1, 1, 20, 20, 20, 20, 21, 22,
+ 7, 7, 7, 7, 7, 23, 7, 7, 7, 7,
+ 7, 7, 7, 7, 24, 7, 7, 25, 7, 7,
+ 1, 26, 1, 8, 7, 1, 20, 20, 20, 20,
+
+ 21, 22, 7, 7, 7, 7, 7, 27, 7, 7,
+ 7, 7, 7, 7, 7, 7, 24, 7, 7, 25,
+ 7, 7, 1, 28, 1, 8, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[29] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 3, 1, 1, 1,
+ 4, 4, 5, 6, 6, 6, 1, 1, 1, 7,
+ 8, 7, 3, 3, 3, 1, 3, 1
+ } ;
+
+static yyconst short int yy_base[88] =
+ { 0,
+ 0, 147, 21, 140, 145, 284, 39, 284, 26, 0,
+ 32, 126, 40, 44, 115, 35, 36, 46, 50, 53,
+ 39, 61, 54, 79, 65, 284, 0, 0, 66, 284,
+ 0, 119, 79, 75, 123, 104, 284, 284, 107, 0,
+ 79, 73, 76, 76, 66, 0, 0, 85, 86, 284,
+ 133, 83, 91, 284, 99, 147, 284, 114, 122, 70,
+ 107, 141, 172, 151, 135, 181, 284, 137, 114, 157,
+ 149, 48, 45, 284, 284, 208, 214, 222, 230, 238,
+ 246, 250, 255, 256, 261, 267, 275
+ } ;
+
+static yyconst short int yy_def[88] =
+ { 0,
+ 75, 1, 1, 3, 75, 75, 75, 75, 76, 77,
+ 78, 75, 77, 79, 75, 75, 75, 75, 75, 19,
+ 75, 75, 75, 75, 76, 75, 80, 77, 78, 75,
+ 81, 75, 76, 78, 79, 79, 75, 75, 75, 39,
+ 19, 82, 83, 75, 75, 84, 20, 76, 78, 75,
+ 79, 51, 85, 75, 75, 75, 75, 84, 79, 51,
+ 79, 79, 79, 51, 75, 75, 75, 86, 79, 63,
+ 86, 87, 87, 75, 0, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75
+ } ;
+
+static yyconst short int yy_nxt[313] =
+ { 0,
+ 6, 7, 8, 7, 9, 6, 10, 6, 6, 11,
+ 6, 6, 12, 6, 6, 6, 6, 6, 6, 10,
+ 10, 10, 13, 10, 10, 6, 10, 6, 15, 16,
+ 26, 15, 17, 18, 19, 20, 20, 21, 15, 22,
+ 24, 30, 24, 38, 33, 36, 37, 74, 23, 34,
+ 74, 27, 38, 38, 38, 38, 38, 31, 32, 39,
+ 39, 39, 40, 41, 41, 42, 47, 47, 47, 26,
+ 43, 38, 44, 45, 46, 30, 44, 75, 38, 38,
+ 24, 38, 24, 26, 30, 40, 55, 55, 57, 26,
+ 27, 31, 57, 43, 35, 30, 64, 64, 64, 57,
+
+ 31, 65, 65, 75, 27, 36, 37, 35, 59, 37,
+ 27, 31, 56, 56, 56, 59, 37, 51, 52, 52,
+ 39, 39, 39, 59, 37, 37, 68, 53, 54, 54,
+ 69, 50, 38, 54, 59, 37, 44, 45, 32, 37,
+ 44, 35, 59, 37, 75, 14, 60, 60, 66, 66,
+ 66, 37, 14, 72, 75, 61, 62, 63, 59, 61,
+ 56, 56, 56, 69, 64, 64, 64, 69, 67, 67,
+ 75, 75, 75, 67, 37, 35, 75, 75, 75, 61,
+ 62, 75, 75, 61, 75, 70, 70, 70, 75, 75,
+ 75, 70, 70, 70, 66, 66, 66, 75, 75, 75,
+
+ 75, 75, 54, 54, 75, 75, 75, 54, 25, 25,
+ 25, 25, 25, 25, 25, 25, 28, 75, 75, 28,
+ 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
+ 35, 35, 35, 35, 35, 35, 35, 35, 48, 75,
+ 48, 48, 48, 48, 48, 48, 49, 75, 49, 49,
+ 49, 49, 49, 49, 42, 42, 75, 42, 56, 75,
+ 56, 58, 58, 58, 66, 75, 66, 71, 71, 71,
+ 71, 71, 71, 71, 71, 73, 73, 73, 73, 73,
+ 73, 73, 73, 5, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75
+ } ;
+
+static yyconst short int yy_chk[313] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 9, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 7, 11, 7, 16, 13, 14, 14, 73, 3, 13,
+ 72, 9, 16, 17, 17, 21, 21, 11, 18, 18,
+ 18, 18, 19, 19, 19, 19, 20, 20, 20, 25,
+ 19, 23, 19, 19, 19, 29, 19, 20, 22, 22,
+ 24, 23, 24, 33, 34, 42, 43, 43, 45, 48,
+ 25, 29, 45, 42, 60, 49, 52, 52, 52, 44,
+
+ 34, 53, 53, 41, 33, 36, 36, 52, 61, 61,
+ 48, 49, 55, 55, 55, 69, 69, 36, 36, 36,
+ 39, 39, 39, 59, 59, 35, 59, 39, 39, 39,
+ 61, 32, 15, 39, 51, 51, 58, 58, 12, 68,
+ 58, 68, 62, 62, 5, 4, 51, 51, 65, 65,
+ 65, 71, 2, 71, 0, 51, 51, 51, 70, 51,
+ 56, 56, 56, 62, 64, 64, 64, 62, 56, 56,
+ 0, 0, 0, 56, 63, 64, 0, 0, 0, 70,
+ 70, 0, 0, 70, 0, 63, 63, 63, 0, 0,
+ 0, 63, 63, 63, 66, 66, 66, 0, 0, 0,
+
+ 0, 0, 66, 66, 0, 0, 0, 66, 76, 76,
+ 76, 76, 76, 76, 76, 76, 77, 0, 0, 77,
+ 77, 77, 78, 78, 78, 78, 78, 78, 78, 78,
+ 79, 79, 79, 79, 79, 79, 79, 79, 80, 0,
+ 80, 80, 80, 80, 80, 80, 81, 0, 81, 81,
+ 81, 81, 81, 81, 82, 82, 0, 82, 83, 0,
+ 83, 84, 84, 84, 85, 0, 85, 86, 86, 86,
+ 86, 86, 86, 86, 86, 87, 87, 87, 87, 87,
+ 87, 87, 87, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 1;
+
+static yyconst short int yy_rule_linenum[13] =
+ { 0,
+ 69, 70, 71, 74, 77, 78, 79, 85, 86, 87,
+ 89, 92
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "scripts/genksyms/lex.l"
+#define INITIAL 0
+/* Lexical analysis for genksyms.
+ Copyright 1996, 1997 Linux International.
+
+ New implementation contributed by Richard Henderson <rth@tamu.edu>
+ Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+ Taken from Linux modutils 2.4.22.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#line 25 "scripts/genksyms/lex.l"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "genksyms.h"
+#include "parse.h"
+
+/* We've got a two-level lexer here. We let flex do basic tokenization
+ and then we categorize those basic tokens in the second stage. */
+#define YY_DECL static int yylex1(void)
+
+/* Version 2 checksumming does proper tokenization; version 1 wasn't
+ quite so pedantic. */
+#define V2_TOKENS 1
+
+/* We don't do multiple input files. */
+#line 513 "scripts/genksyms/lex.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ yy_current_buffer->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp = NULL, *yy_bp = NULL;
+ register int yy_act;
+
+#line 65 "scripts/genksyms/lex.l"
+
+
+
+ /* Keep track of our location in the original source files. */
+#line 672 "scripts/genksyms/lex.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 76 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 284 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+ if ( yy_flex_debug )
+ {
+ if ( yy_act == 0 )
+ fprintf( stderr, "--scanner backing up\n" );
+ else if ( yy_act < 13 )
+ fprintf( stderr, "--accepting rule at line %d (\"%s\")\n",
+ yy_rule_linenum[yy_act], yytext );
+ else if ( yy_act == 13 )
+ fprintf( stderr, "--accepting default rule (\"%s\")\n",
+ yytext );
+ else if ( yy_act == 14 )
+ fprintf( stderr, "--(end of buffer or a NUL)\n" );
+ else
+ fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
+ }
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 69 "scripts/genksyms/lex.l"
+return FILENAME;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 70 "scripts/genksyms/lex.l"
+cur_line++;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 71 "scripts/genksyms/lex.l"
+cur_line++;
+ YY_BREAK
+/* Ignore all other whitespace. */
+case 4:
+YY_RULE_SETUP
+#line 74 "scripts/genksyms/lex.l"
+;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 77 "scripts/genksyms/lex.l"
+return STRING;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 78 "scripts/genksyms/lex.l"
+return CHAR;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 79 "scripts/genksyms/lex.l"
+return IDENT;
+ YY_BREAK
+/* The Pedant requires that the other C multi-character tokens be
+ recognized as tokens. We don't actually use them since we don't
+ parse expressions, but we do want whitespace to be arranged
+ around them properly. */
+case 8:
+YY_RULE_SETUP
+#line 85 "scripts/genksyms/lex.l"
+return OTHER;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 86 "scripts/genksyms/lex.l"
+return INT;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 87 "scripts/genksyms/lex.l"
+return REAL;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 89 "scripts/genksyms/lex.l"
+return DOTS;
+ YY_BREAK
+/* All other tokens are single characters. */
+case 12:
+YY_RULE_SETUP
+#line 92 "scripts/genksyms/lex.l"
+return yytext[0];
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 95 "scripts/genksyms/lex.l"
+ECHO;
+ YY_BREAK
+#line 842 "scripts/genksyms/lex.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(V2_TOKENS):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 76 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 76 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 75);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ yy_current_buffer->yy_at_bol = (c == '\n');
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 95 "scripts/genksyms/lex.l"
+
+
+/* Bring in the keyword recognizer. */
+
+#include "keywords.c"
+
+
+/* Macros to append to our phrase collection list. */
+
+#define _APP(T,L) do { \
+ cur_node = next_node; \
+ next_node = xmalloc(sizeof(*next_node)); \
+ next_node->next = cur_node; \
+ cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
+ cur_node->tag = SYM_NORMAL; \
+ } while (0)
+
+#define APP _APP(yytext, yyleng)
+
+
+/* The second stage lexer. Here we incorporate knowledge of the state
+ of the parser to tailor the tokens that are returned. */
+
+int
+yylex(void)
+{
+ static enum {
+ ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
+ ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
+ ST_TABLE_5, ST_TABLE_6
+ } lexstate = ST_NOTSTARTED;
+
+ static int suppress_type_lookup, dont_want_brace_phrase;
+ static struct string_list *next_node;
+
+ int token, count = 0;
+ struct string_list *cur_node;
+
+ if (lexstate == ST_NOTSTARTED)
+ {
+ BEGIN(V2_TOKENS);
+ next_node = xmalloc(sizeof(*next_node));
+ next_node->next = NULL;
+ lexstate = ST_NORMAL;
+ }
+
+repeat:
+ token = yylex1();
+
+ if (token == 0)
+ return 0;
+ else if (token == FILENAME)
+ {
+ char *file, *e;
+
+ /* Save the filename and line number for later error messages. */
+
+ if (cur_filename)
+ free(cur_filename);
+
+ file = strchr(yytext, '\"')+1;
+ e = strchr(file, '\"');
+ *e = '\0';
+ cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
+ cur_line = atoi(yytext+2);
+
+ goto repeat;
+ }
+
+ switch (lexstate)
+ {
+ case ST_NORMAL:
+ switch (token)
+ {
+ case IDENT:
+ APP;
+ {
+ const struct resword *r = is_reserved_word(yytext, yyleng);
+ if (r)
+ {
+ switch (token = r->token)
+ {
+ case ATTRIBUTE_KEYW:
+ lexstate = ST_ATTRIBUTE;
+ count = 0;
+ goto repeat;
+ case ASM_KEYW:
+ lexstate = ST_ASM;
+ count = 0;
+ goto repeat;
+
+ case STRUCT_KEYW:
+ case UNION_KEYW:
+ dont_want_brace_phrase = 3;
+ case ENUM_KEYW:
+ suppress_type_lookup = 2;
+ goto fini;
+
+ case EXPORT_SYMBOL_KEYW:
+ goto fini;
+ }
+ }
+ if (!suppress_type_lookup)
+ {
+ struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
+ if (sym && sym->type == SYM_TYPEDEF)
+ token = TYPE;
+ }
+ }
+ break;
+
+ case '[':
+ APP;
+ lexstate = ST_BRACKET;
+ count = 1;
+ goto repeat;
+
+ case '{':
+ APP;
+ if (dont_want_brace_phrase)
+ break;
+ lexstate = ST_BRACE;
+ count = 1;
+ goto repeat;
+
+ case '=': case ':':
+ APP;
+ lexstate = ST_EXPRESSION;
+ break;
+
+ case DOTS:
+ default:
+ APP;
+ break;
+ }
+ break;
+
+ case ST_ATTRIBUTE:
+ APP;
+ switch (token)
+ {
+ case '(':
+ ++count;
+ goto repeat;
+ case ')':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = ATTRIBUTE_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_ASM:
+ APP;
+ switch (token)
+ {
+ case '(':
+ ++count;
+ goto repeat;
+ case ')':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = ASM_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_BRACKET:
+ APP;
+ switch (token)
+ {
+ case '[':
+ ++count;
+ goto repeat;
+ case ']':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = BRACKET_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_BRACE:
+ APP;
+ switch (token)
+ {
+ case '{':
+ ++count;
+ goto repeat;
+ case '}':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = BRACE_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_EXPRESSION:
+ switch (token)
+ {
+ case '(': case '[': case '{':
+ ++count;
+ APP;
+ goto repeat;
+ case ')': case ']': case '}':
+ --count;
+ APP;
+ goto repeat;
+ case ',': case ';':
+ if (count == 0)
+ {
+ /* Put back the token we just read so's we can find it again
+ after registering the expression. */
+ unput(token);
+
+ lexstate = ST_NORMAL;
+ token = EXPRESSION_PHRASE;
+ break;
+ }
+ APP;
+ goto repeat;
+ default:
+ APP;
+ goto repeat;
+ }
+ break;
+
+ case ST_TABLE_1:
+ goto repeat;
+
+ case ST_TABLE_2:
+ if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
+ {
+ token = EXPORT_SYMBOL_KEYW;
+ lexstate = ST_TABLE_5;
+ APP;
+ break;
+ }
+ lexstate = ST_TABLE_6;
+ /* FALLTHRU */
+
+ case ST_TABLE_6:
+ switch (token)
+ {
+ case '{': case '[': case '(':
+ ++count;
+ break;
+ case '}': case ']': case ')':
+ --count;
+ break;
+ case ',':
+ if (count == 0)
+ lexstate = ST_TABLE_2;
+ break;
+ };
+ goto repeat;
+
+ case ST_TABLE_3:
+ goto repeat;
+
+ case ST_TABLE_4:
+ if (token == ';')
+ lexstate = ST_NORMAL;
+ goto repeat;
+
+ case ST_TABLE_5:
+ switch (token)
+ {
+ case ',':
+ token = ';';
+ lexstate = ST_TABLE_2;
+ APP;
+ break;
+ default:
+ APP;
+ break;
+ }
+ break;
+
+ default:
+ abort();
+ }
+fini:
+
+ if (suppress_type_lookup > 0)
+ --suppress_type_lookup;
+ if (dont_want_brace_phrase > 0)
+ --dont_want_brace_phrase;
+
+ yylval = &next_node->next;
+
+ return token;
+}
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define ASM_KEYW 257
+#define ATTRIBUTE_KEYW 258
+#define AUTO_KEYW 259
+#define BOOL_KEYW 260
+#define CHAR_KEYW 261
+#define CONST_KEYW 262
+#define DOUBLE_KEYW 263
+#define ENUM_KEYW 264
+#define EXTERN_KEYW 265
+#define FLOAT_KEYW 266
+#define INLINE_KEYW 267
+#define INT_KEYW 268
+#define LONG_KEYW 269
+#define REGISTER_KEYW 270
+#define RESTRICT_KEYW 271
+#define SHORT_KEYW 272
+#define SIGNED_KEYW 273
+#define STATIC_KEYW 274
+#define STRUCT_KEYW 275
+#define TYPEDEF_KEYW 276
+#define UNION_KEYW 277
+#define UNSIGNED_KEYW 278
+#define VOID_KEYW 279
+#define VOLATILE_KEYW 280
+#define TYPEOF_KEYW 281
+#define EXPORT_SYMBOL_KEYW 282
+#define ASM_PHRASE 283
+#define ATTRIBUTE_PHRASE 284
+#define BRACE_PHRASE 285
+#define BRACKET_PHRASE 286
+#define EXPRESSION_PHRASE 287
+#define CHAR 288
+#define DOTS 289
+#define IDENT 290
+#define INT 291
+#define REAL 292
+#define STRING 293
+#define TYPE 294
+#define OTHER 295
+#define FILENAME 296
+
+
+extern 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 @@
+/* Lexical analysis for genksyms.
+ Copyright 1996, 1997 Linux International.
+
+ New implementation contributed by Richard Henderson <rth@tamu.edu>
+ Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+ Taken from Linux modutils 2.4.22.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+%{
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "genksyms.h"
+#include "parse.h"
+
+/* We've got a two-level lexer here. We let flex do basic tokenization
+ and then we categorize those basic tokens in the second stage. */
+#define YY_DECL static int yylex1(void)
+
+%}
+
+IDENT [A-Za-z_\$][A-Za-z0-9_\$]*
+
+O_INT 0[0-7]*
+D_INT [1-9][0-9]*
+X_INT 0[Xx][0-9A-Fa-f]+
+I_SUF [Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]
+INT ({O_INT}|{D_INT}|{X_INT}){I_SUF}?
+
+FRAC ([0-9]*\.[0-9]+)|([0-9]+\.)
+EXP [Ee][+-]?[0-9]+
+F_SUF [FfLl]
+REAL ({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)
+
+STRING L?\"([^\\\"]*\\.)*[^\\\"]*\"
+CHAR L?\'([^\\\']*\\.)*[^\\\']*\'
+
+MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
+
+/* Version 2 checksumming does proper tokenization; version 1 wasn't
+ quite so pedantic. */
+%s V2_TOKENS
+
+/* We don't do multiple input files. */
+%option noyywrap
+
+%%
+
+
+ /* Keep track of our location in the original source files. */
+^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n return FILENAME;
+^#.*\n cur_line++;
+\n cur_line++;
+
+ /* Ignore all other whitespace. */
+[ \t\f\v\r]+ ;
+
+
+{STRING} return STRING;
+{CHAR} return CHAR;
+{IDENT} return IDENT;
+
+ /* The Pedant requires that the other C multi-character tokens be
+ recognized as tokens. We don't actually use them since we don't
+ parse expressions, but we do want whitespace to be arranged
+ around them properly. */
+<V2_TOKENS>{MC_TOKEN} return OTHER;
+<V2_TOKENS>{INT} return INT;
+<V2_TOKENS>{REAL} return REAL;
+
+"..." return DOTS;
+
+ /* All other tokens are single characters. */
+. return yytext[0];
+
+
+%%
+
+/* Bring in the keyword recognizer. */
+
+#include "keywords.c"
+
+
+/* Macros to append to our phrase collection list. */
+
+#define _APP(T,L) do { \
+ cur_node = next_node; \
+ next_node = xmalloc(sizeof(*next_node)); \
+ next_node->next = cur_node; \
+ cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
+ cur_node->tag = SYM_NORMAL; \
+ } while (0)
+
+#define APP _APP(yytext, yyleng)
+
+
+/* The second stage lexer. Here we incorporate knowledge of the state
+ of the parser to tailor the tokens that are returned. */
+
+int
+yylex(void)
+{
+ static enum {
+ ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
+ ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
+ ST_TABLE_5, ST_TABLE_6
+ } lexstate = ST_NOTSTARTED;
+
+ static int suppress_type_lookup, dont_want_brace_phrase;
+ static struct string_list *next_node;
+
+ int token, count = 0;
+ struct string_list *cur_node;
+
+ if (lexstate == ST_NOTSTARTED)
+ {
+ BEGIN(V2_TOKENS);
+ next_node = xmalloc(sizeof(*next_node));
+ next_node->next = NULL;
+ lexstate = ST_NORMAL;
+ }
+
+repeat:
+ token = yylex1();
+
+ if (token == 0)
+ return 0;
+ else if (token == FILENAME)
+ {
+ char *file, *e;
+
+ /* Save the filename and line number for later error messages. */
+
+ if (cur_filename)
+ free(cur_filename);
+
+ file = strchr(yytext, '\"')+1;
+ e = strchr(file, '\"');
+ *e = '\0';
+ cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
+ cur_line = atoi(yytext+2);
+
+ goto repeat;
+ }
+
+ switch (lexstate)
+ {
+ case ST_NORMAL:
+ switch (token)
+ {
+ case IDENT:
+ APP;
+ {
+ const struct resword *r = is_reserved_word(yytext, yyleng);
+ if (r)
+ {
+ switch (token = r->token)
+ {
+ case ATTRIBUTE_KEYW:
+ lexstate = ST_ATTRIBUTE;
+ count = 0;
+ goto repeat;
+ case ASM_KEYW:
+ lexstate = ST_ASM;
+ count = 0;
+ goto repeat;
+
+ case STRUCT_KEYW:
+ case UNION_KEYW:
+ dont_want_brace_phrase = 3;
+ case ENUM_KEYW:
+ suppress_type_lookup = 2;
+ goto fini;
+
+ case EXPORT_SYMBOL_KEYW:
+ goto fini;
+ }
+ }
+ if (!suppress_type_lookup)
+ {
+ struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
+ if (sym && sym->type == SYM_TYPEDEF)
+ token = TYPE;
+ }
+ }
+ break;
+
+ case '[':
+ APP;
+ lexstate = ST_BRACKET;
+ count = 1;
+ goto repeat;
+
+ case '{':
+ APP;
+ if (dont_want_brace_phrase)
+ break;
+ lexstate = ST_BRACE;
+ count = 1;
+ goto repeat;
+
+ case '=': case ':':
+ APP;
+ lexstate = ST_EXPRESSION;
+ break;
+
+ case DOTS:
+ default:
+ APP;
+ break;
+ }
+ break;
+
+ case ST_ATTRIBUTE:
+ APP;
+ switch (token)
+ {
+ case '(':
+ ++count;
+ goto repeat;
+ case ')':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = ATTRIBUTE_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_ASM:
+ APP;
+ switch (token)
+ {
+ case '(':
+ ++count;
+ goto repeat;
+ case ')':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = ASM_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_BRACKET:
+ APP;
+ switch (token)
+ {
+ case '[':
+ ++count;
+ goto repeat;
+ case ']':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = BRACKET_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_BRACE:
+ APP;
+ switch (token)
+ {
+ case '{':
+ ++count;
+ goto repeat;
+ case '}':
+ if (--count == 0)
+ {
+ lexstate = ST_NORMAL;
+ token = BRACE_PHRASE;
+ break;
+ }
+ goto repeat;
+ default:
+ goto repeat;
+ }
+ break;
+
+ case ST_EXPRESSION:
+ switch (token)
+ {
+ case '(': case '[': case '{':
+ ++count;
+ APP;
+ goto repeat;
+ case ')': case ']': case '}':
+ --count;
+ APP;
+ goto repeat;
+ case ',': case ';':
+ if (count == 0)
+ {
+ /* Put back the token we just read so's we can find it again
+ after registering the expression. */
+ unput(token);
+
+ lexstate = ST_NORMAL;
+ token = EXPRESSION_PHRASE;
+ break;
+ }
+ APP;
+ goto repeat;
+ default:
+ APP;
+ goto repeat;
+ }
+ break;
+
+ case ST_TABLE_1:
+ goto repeat;
+
+ case ST_TABLE_2:
+ if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
+ {
+ token = EXPORT_SYMBOL_KEYW;
+ lexstate = ST_TABLE_5;
+ APP;
+ break;
+ }
+ lexstate = ST_TABLE_6;
+ /* FALLTHRU */
+
+ case ST_TABLE_6:
+ switch (token)
+ {
+ case '{': case '[': case '(':
+ ++count;
+ break;
+ case '}': case ']': case ')':
+ --count;
+ break;
+ case ',':
+ if (count == 0)
+ lexstate = ST_TABLE_2;
+ break;
+ };
+ goto repeat;
+
+ case ST_TABLE_3:
+ goto repeat;
+
+ case ST_TABLE_4:
+ if (token == ';')
+ lexstate = ST_NORMAL;
+ goto repeat;
+
+ case ST_TABLE_5:
+ switch (token)
+ {
+ case ',':
+ token = ';';
+ lexstate = ST_TABLE_2;
+ APP;
+ break;
+ default:
+ APP;
+ break;
+ }
+ break;
+
+ default:
+ abort();
+ }
+fini:
+
+ if (suppress_type_lookup > 0)
+ --suppress_type_lookup;
+ if (dont_want_brace_phrase > 0)
+ --dont_want_brace_phrase;
+
+ yylval = &next_node->next;
+
+ return token;
+}
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 @@
+
+/* A Bison parser, made from scripts/genksyms/parse.y
+ by GNU Bison version 1.28 */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define ASM_KEYW 257
+#define ATTRIBUTE_KEYW 258
+#define AUTO_KEYW 259
+#define BOOL_KEYW 260
+#define CHAR_KEYW 261
+#define CONST_KEYW 262
+#define DOUBLE_KEYW 263
+#define ENUM_KEYW 264
+#define EXTERN_KEYW 265
+#define FLOAT_KEYW 266
+#define INLINE_KEYW 267
+#define INT_KEYW 268
+#define LONG_KEYW 269
+#define REGISTER_KEYW 270
+#define RESTRICT_KEYW 271
+#define SHORT_KEYW 272
+#define SIGNED_KEYW 273
+#define STATIC_KEYW 274
+#define STRUCT_KEYW 275
+#define TYPEDEF_KEYW 276
+#define UNION_KEYW 277
+#define UNSIGNED_KEYW 278
+#define VOID_KEYW 279
+#define VOLATILE_KEYW 280
+#define TYPEOF_KEYW 281
+#define EXPORT_SYMBOL_KEYW 282
+#define ASM_PHRASE 283
+#define ATTRIBUTE_PHRASE 284
+#define BRACE_PHRASE 285
+#define BRACKET_PHRASE 286
+#define EXPRESSION_PHRASE 287
+#define CHAR 288
+#define DOTS 289
+#define IDENT 290
+#define INT 291
+#define REAL 292
+#define STRING 293
+#define TYPE 294
+#define OTHER 295
+#define FILENAME 296
+
+#line 24 "scripts/genksyms/parse.y"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include "genksyms.h"
+
+static int is_typedef;
+static int is_extern;
+static char *current_name;
+static struct string_list *decl_spec;
+
+static void yyerror(const char *);
+
+static inline void
+remove_node(struct string_list **p)
+{
+ struct string_list *node = *p;
+ *p = node->next;
+ free_node(node);
+}
+
+static inline void
+remove_list(struct string_list **pb, struct string_list **pe)
+{
+ struct string_list *b = *pb, *e = *pe;
+ *pb = e;
+ free_list(b, e);
+}
+
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#ifndef YYDEBUG
+#define YYDEBUG 1
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 172
+#define YYFLAG -32768
+#define YYNTBASE 52
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 96)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 46,
+ 47, 48, 2, 45, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 51, 43, 2,
+ 49, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 50, 2, 44, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 2, 5, 6, 9, 10, 14, 16, 18, 20,
+ 22, 25, 28, 32, 33, 35, 37, 41, 46, 47,
+ 49, 51, 54, 56, 58, 60, 62, 64, 66, 68,
+ 70, 72, 77, 80, 83, 86, 90, 94, 98, 101,
+ 104, 107, 109, 111, 113, 115, 117, 119, 121, 123,
+ 125, 127, 129, 132, 133, 135, 137, 140, 142, 144,
+ 146, 148, 151, 153, 155, 160, 165, 168, 172, 176,
+ 179, 181, 183, 185, 190, 195, 198, 202, 206, 209,
+ 211, 215, 216, 218, 220, 224, 227, 230, 232, 233,
+ 235, 237, 242, 247, 250, 254, 258, 262, 263, 265,
+ 268, 272, 276, 277, 279, 281, 284, 288, 291, 292,
+ 294, 296, 300, 303, 306, 308, 311, 312, 314, 317,
+ 318, 320
+};
+
+static const short yyrhs[] = { 53,
+ 0, 52, 53, 0, 0, 54, 55, 0, 0, 22,
+ 56, 57, 0, 57, 0, 81, 0, 93, 0, 95,
+ 0, 1, 43, 0, 1, 44, 0, 61, 58, 43,
+ 0, 0, 59, 0, 60, 0, 59, 45, 60, 0,
+ 71, 94, 92, 82, 0, 0, 62, 0, 63, 0,
+ 62, 63, 0, 64, 0, 65, 0, 5, 0, 16,
+ 0, 20, 0, 11, 0, 13, 0, 66, 0, 70,
+ 0, 27, 46, 62, 47, 0, 21, 36, 0, 23,
+ 36, 0, 10, 36, 0, 21, 36, 84, 0, 23,
+ 36, 84, 0, 10, 36, 31, 0, 10, 31, 0,
+ 21, 84, 0, 23, 84, 0, 7, 0, 18, 0,
+ 14, 0, 15, 0, 19, 0, 24, 0, 12, 0,
+ 9, 0, 25, 0, 6, 0, 40, 0, 48, 68,
+ 0, 0, 69, 0, 70, 0, 69, 70, 0, 8,
+ 0, 26, 0, 30, 0, 17, 0, 67, 71, 0,
+ 72, 0, 36, 0, 72, 46, 75, 47, 0, 72,
+ 46, 1, 47, 0, 72, 32, 0, 46, 71, 47,
+ 0, 46, 1, 47, 0, 67, 73, 0, 74, 0,
+ 36, 0, 40, 0, 74, 46, 75, 47, 0, 74,
+ 46, 1, 47, 0, 74, 32, 0, 46, 73, 47,
+ 0, 46, 1, 47, 0, 76, 35, 0, 76, 0,
+ 77, 45, 35, 0, 0, 77, 0, 78, 0, 77,
+ 45, 78, 0, 62, 79, 0, 67, 79, 0, 80,
+ 0, 0, 36, 0, 40, 0, 80, 46, 75, 47,
+ 0, 80, 46, 1, 47, 0, 80, 32, 0, 46,
+ 79, 47, 0, 46, 1, 47, 0, 61, 71, 31,
+ 0, 0, 83, 0, 49, 33, 0, 50, 85, 44,
+ 0, 50, 1, 44, 0, 0, 86, 0, 87, 0,
+ 86, 87, 0, 61, 88, 43, 0, 1, 43, 0,
+ 0, 89, 0, 90, 0, 89, 45, 90, 0, 73,
+ 92, 0, 36, 91, 0, 91, 0, 51, 33, 0,
+ 0, 30, 0, 29, 43, 0, 0, 29, 0, 28,
+ 46, 36, 47, 43, 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 101, 103, 106, 109, 112, 114, 115, 116, 117, 118,
+ 119, 120, 123, 137, 139, 142, 151, 163, 169, 171,
+ 174, 176, 179, 186, 189, 191, 192, 193, 194, 197,
+ 199, 200, 204, 206, 208, 212, 219, 226, 235, 236,
+ 237, 240, 242, 243, 244, 245, 246, 247, 248, 249,
+ 250, 251, 254, 259, 261, 264, 266, 269, 270, 270,
+ 271, 278, 280, 283, 293, 295, 297, 299, 301, 307,
+ 309, 312, 314, 315, 317, 319, 321, 323, 327, 329,
+ 330, 333, 335, 338, 340, 344, 349, 352, 355, 357,
+ 365, 369, 371, 373, 375, 377, 381, 390, 392, 396,
+ 401, 403, 406, 408, 411, 413, 416, 419, 423, 425,
+ 428, 430, 433, 435, 436, 439, 443, 445, 448, 452,
+ 454, 457
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = { "$","error","$undefined.","ASM_KEYW",
+"ATTRIBUTE_KEYW","AUTO_KEYW","BOOL_KEYW","CHAR_KEYW","CONST_KEYW","DOUBLE_KEYW",
+"ENUM_KEYW","EXTERN_KEYW","FLOAT_KEYW","INLINE_KEYW","INT_KEYW","LONG_KEYW",
+"REGISTER_KEYW","RESTRICT_KEYW","SHORT_KEYW","SIGNED_KEYW","STATIC_KEYW","STRUCT_KEYW",
+"TYPEDEF_KEYW","UNION_KEYW","UNSIGNED_KEYW","VOID_KEYW","VOLATILE_KEYW","TYPEOF_KEYW",
+"EXPORT_SYMBOL_KEYW","ASM_PHRASE","ATTRIBUTE_PHRASE","BRACE_PHRASE","BRACKET_PHRASE",
+"EXPRESSION_PHRASE","CHAR","DOTS","IDENT","INT","REAL","STRING","TYPE","OTHER",
+"FILENAME","';'","'}'","','","'('","')'","'*'","'='","'{'","':'","declaration_seq",
+"declaration","@1","declaration1","@2","simple_declaration","init_declarator_list_opt",
+"init_declarator_list","init_declarator","decl_specifier_seq_opt","decl_specifier_seq",
+"decl_specifier","storage_class_specifier","type_specifier","simple_type_specifier",
+"ptr_operator","cvar_qualifier_seq_opt","cvar_qualifier_seq","cvar_qualifier",
+"declarator","direct_declarator","nested_declarator","direct_nested_declarator",
+"parameter_declaration_clause","parameter_declaration_list_opt","parameter_declaration_list",
+"parameter_declaration","m_abstract_declarator","direct_m_abstract_declarator",
+"function_definition","initializer_opt","initializer","class_body","member_specification_opt",
+"member_specification","member_declaration","member_declarator_list_opt","member_declarator_list",
+"member_declarator","member_bitfield_declarator","attribute_opt","asm_definition",
+"asm_phrase_opt","export_definition", NULL
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 52, 52, 54, 53, 56, 55, 55, 55, 55, 55,
+ 55, 55, 57, 58, 58, 59, 59, 60, 61, 61,
+ 62, 62, 63, 63, 64, 64, 64, 64, 64, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 67, 68, 68, 69, 69, 70, 70, 70,
+ 70, 71, 71, 72, 72, 72, 72, 72, 72, 73,
+ 73, 74, 74, 74, 74, 74, 74, 74, 75, 75,
+ 75, 76, 76, 77, 77, 78, 79, 79, 80, 80,
+ 80, 80, 80, 80, 80, 80, 81, 82, 82, 83,
+ 84, 84, 85, 85, 86, 86, 87, 87, 88, 88,
+ 89, 89, 90, 90, 90, 91, 92, 92, 93, 94,
+ 94, 95
+};
+
+static const short yyr2[] = { 0,
+ 1, 2, 0, 2, 0, 3, 1, 1, 1, 1,
+ 2, 2, 3, 0, 1, 1, 3, 4, 0, 1,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 2, 2, 2, 3, 3, 3, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 0, 1, 1, 2, 1, 1, 1,
+ 1, 2, 1, 1, 4, 4, 2, 3, 3, 2,
+ 1, 1, 1, 4, 4, 2, 3, 3, 2, 1,
+ 3, 0, 1, 1, 3, 2, 2, 1, 0, 1,
+ 1, 4, 4, 2, 3, 3, 3, 0, 1, 2,
+ 3, 3, 0, 1, 1, 2, 3, 2, 0, 1,
+ 1, 3, 2, 2, 1, 2, 0, 1, 2, 0,
+ 1, 5
+};
+
+static const short yydefact[] = { 3,
+ 3, 1, 0, 2, 0, 25, 51, 42, 58, 49,
+ 0, 28, 48, 29, 44, 45, 26, 61, 43, 46,
+ 27, 0, 5, 0, 47, 50, 59, 0, 0, 0,
+ 60, 52, 4, 7, 14, 20, 21, 23, 24, 30,
+ 31, 8, 9, 10, 11, 12, 39, 35, 33, 0,
+ 40, 19, 34, 41, 0, 0, 119, 64, 0, 54,
+ 0, 15, 16, 0, 120, 63, 22, 38, 36, 0,
+ 109, 0, 0, 105, 6, 14, 37, 0, 0, 0,
+ 0, 53, 55, 56, 13, 0, 62, 121, 97, 117,
+ 67, 0, 108, 102, 72, 73, 0, 0, 0, 117,
+ 71, 0, 110, 111, 115, 101, 0, 106, 120, 32,
+ 0, 69, 68, 57, 17, 118, 98, 0, 89, 0,
+ 80, 83, 84, 114, 0, 72, 0, 116, 70, 113,
+ 76, 0, 107, 0, 122, 0, 18, 99, 66, 90,
+ 52, 0, 89, 86, 88, 65, 79, 0, 78, 77,
+ 0, 0, 112, 100, 0, 91, 0, 87, 94, 0,
+ 81, 85, 75, 74, 96, 95, 0, 0, 93, 92,
+ 0, 0
+};
+
+static const short yydefgoto[] = { 1,
+ 2, 3, 33, 52, 34, 61, 62, 63, 71, 36,
+ 37, 38, 39, 40, 64, 82, 83, 41, 109, 66,
+ 100, 101, 120, 121, 122, 123, 144, 145, 42, 137,
+ 138, 51, 72, 73, 74, 102, 103, 104, 105, 117,
+ 43, 90, 44
+};
+
+static const short yypact[] = {-32768,
+ 15,-32768, 197,-32768, 23,-32768,-32768,-32768,-32768,-32768,
+ -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, -28,-32768, -25,-32768,-32768,-32768, -26, -22, -12,
+-32768,-32768,-32768,-32768, 49, 493,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 27, -8, 101,
+-32768, 493, -8,-32768, 493, 10,-32768,-32768, 11, 9,
+ 18, 26,-32768, 49, -15, -13,-32768,-32768,-32768, 25,
+ 24, 48, 149,-32768,-32768, 49,-32768, 414, 39, 40,
+ 47,-32768, 9,-32768,-32768, 49,-32768,-32768,-32768, 66,
+-32768, 241,-32768,-32768, 50,-32768, 5, 65, 42, 66,
+ 17, 56, 55,-32768,-32768,-32768, 60,-32768, 75,-32768,
+ 80,-32768,-32768,-32768,-32768,-32768, 81, 82, 370, 85,
+ 98, 89,-32768,-32768, 88,-32768, 91,-32768,-32768,-32768,
+-32768, 284,-32768, 24,-32768, 103,-32768,-32768,-32768,-32768,
+-32768, 8, 43,-32768, 30,-32768,-32768, 457,-32768,-32768,
+ 92, 93,-32768,-32768, 95,-32768, 96,-32768,-32768, 327,
+-32768,-32768,-32768,-32768,-32768,-32768, 99, 104,-32768,-32768,
+ 148,-32768
+};
+
+static const short yypgoto[] = {-32768,
+ 152,-32768,-32768,-32768, 119,-32768,-32768, 94, 0, -55,
+ -35,-32768,-32768,-32768, -69,-32768,-32768, -56, -30,-32768,
+ -76,-32768, -122,-32768,-32768, 29, -62,-32768,-32768,-32768,
+-32768, -17,-32768,-32768, 105,-32768,-32768, 52, 86, 83,
+-32768,-32768,-32768
+};
+
+
+#define YYLAST 533
+
+
+static const short yytable[] = { 78,
+ 67, 99, 35, 84, 65, 125, 54, 49, 155, 152,
+ 53, 80, 47, 88, 171, 89, 9, 48, 91, 55,
+ 127, 50, 129, 56, 50, 18, 114, 99, 81, 99,
+ 57, 69, 92, 87, 27, 77, 119, 168, 31, -89,
+ 126, 50, 67, 140, 96, 79, 58, 156, 131, 143,
+ 97, 76, 60, 142, -89, 60, 59, 68, 60, 95,
+ 85, 159, 132, 96, 99, 45, 46, 93, 94, 97,
+ 86, 60, 143, 143, 98, 160, 119, 126, 140, 157,
+ 158, 96, 156, 67, 58, 111, 112, 97, 142, 60,
+ 60, 106, 119, 113, 59, 116, 60, 128, 133, 134,
+ 98, 70, 93, 88, 119, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 135, 24, 25, 26, 27, 28, 139, 136,
+ 31, 146, 147, 148, 149, 154, -19, 150, 163, 164,
+ 32, 165, 166, -19, -103, 169, -19, 172, -19, 107,
+ 170, -19, 4, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 75, 24, 25, 26, 27, 28, 162, 108, 31, 115,
+ 124, 0, 130, 0, -19, 153, 0, 0, 32, 0,
+ 0, -19, -104, 0, -19, 0, -19, 5, 0, -19,
+ 0, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 0, 0, 0,
+ 0, 0, -19, 0, 0, 0, 32, 0, 0, -19,
+ 0, 118, -19, 0, -19, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 0, 24, 25, 26, 27, 28, 0, 0,
+ 31, 0, 0, 0, 0, -82, 0, 0, 0, 0,
+ 32, 0, 0, 0, 151, 0, 0, -82, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 0, 24, 25, 26, 27,
+ 28, 0, 0, 31, 0, 0, 0, 0, -82, 0,
+ 0, 0, 0, 32, 0, 0, 0, 167, 0, 0,
+ -82, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 0, 24,
+ 25, 26, 27, 28, 0, 0, 31, 0, 0, 0,
+ 0, -82, 0, 0, 0, 0, 32, 0, 0, 0,
+ 0, 0, 0, -82, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 0, 24, 25, 26, 27, 28, 0, 0, 31,
+ 0, 0, 0, 0, 0, 140, 0, 0, 0, 141,
+ 0, 0, 0, 0, 0, 142, 0, 60, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 0, 24, 25, 26, 27,
+ 28, 0, 0, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 32, 0, 0, 0, 0, 0, 0,
+ 110, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 0, 24,
+ 25, 26, 27, 28, 0, 0, 31, 0, 0, 0,
+ 0, 161, 0, 0, 0, 0, 32, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 0, 24, 25, 26, 27, 28,
+ 0, 0, 31, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 32
+};
+
+static const short yycheck[] = { 55,
+ 36, 71, 3, 60, 35, 1, 24, 36, 1, 132,
+ 36, 1, 31, 29, 0, 31, 8, 36, 32, 46,
+ 97, 50, 99, 46, 50, 17, 83, 97, 59, 99,
+ 43, 49, 46, 64, 26, 53, 92, 160, 30, 32,
+ 36, 50, 78, 36, 40, 36, 36, 40, 32, 119,
+ 46, 52, 48, 46, 47, 48, 46, 31, 48, 36,
+ 43, 32, 46, 40, 134, 43, 44, 43, 44, 46,
+ 45, 48, 142, 143, 51, 46, 132, 36, 36, 142,
+ 143, 40, 40, 119, 36, 47, 47, 46, 46, 48,
+ 48, 44, 148, 47, 46, 30, 48, 33, 43, 45,
+ 51, 1, 43, 29, 160, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 43, 23, 24, 25, 26, 27, 47, 49,
+ 30, 47, 35, 45, 47, 33, 36, 47, 47, 47,
+ 40, 47, 47, 43, 44, 47, 46, 0, 48, 1,
+ 47, 51, 1, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 52, 23, 24, 25, 26, 27, 148, 73, 30, 86,
+ 95, -1, 100, -1, 36, 134, -1, -1, 40, -1,
+ -1, 43, 44, -1, 46, -1, 48, 1, -1, 51,
+ -1, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, -1, -1, -1,
+ -1, -1, 36, -1, -1, -1, 40, -1, -1, 43,
+ -1, 1, 46, -1, 48, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, -1, 23, 24, 25, 26, 27, -1, -1,
+ 30, -1, -1, -1, -1, 35, -1, -1, -1, -1,
+ 40, -1, -1, -1, 1, -1, -1, 47, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, -1, 23, 24, 25, 26,
+ 27, -1, -1, 30, -1, -1, -1, -1, 35, -1,
+ -1, -1, -1, 40, -1, -1, -1, 1, -1, -1,
+ 47, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, -1, 23,
+ 24, 25, 26, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, -1, -1, -1, -1, 40, -1, -1, -1,
+ -1, -1, -1, 47, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, -1, 23, 24, 25, 26, 27, -1, -1, 30,
+ -1, -1, -1, -1, -1, 36, -1, -1, -1, 40,
+ -1, -1, -1, -1, -1, 46, -1, 48, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, -1, 23, 24, 25, 26,
+ 27, -1, -1, 30, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 40, -1, -1, -1, -1, -1, -1,
+ 47, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, -1, 23,
+ 24, 25, 26, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, -1, -1, -1, -1, 40, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, -1, 23, 24, 25, 26, 27,
+ -1, -1, 30, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 40
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/lib/bison.simple"
+/* This file comes from bison-1.28. */
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C. */
+/* This used to test MSDOS, but that is a bad idea
+ since that symbol is in the user namespace. */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+ instead, just don't use alloca. */
+#include <malloc.h>
+#endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+ So I turned it off. rms, 2 May 1997. */
+/* #include <malloc.h> */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
+ and on HPUX 10. Eventually we can turn this on. */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
+#endif
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Define __yy_memcpy. Note that the size argument
+ should be passed with type unsigned int, because that is what the non-GCC
+ definitions require. With GCC, __builtin_memcpy takes an arg
+ of type size_t, but it can handle unsigned int. */
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (to, from, count)
+ char *to;
+ char *from;
+ unsigned int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (char *to, char *from, unsigned int count)
+{
+ register char *t = to;
+ register char *f = from;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 217 "/usr/lib/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int yyparse (void *);
+#else
+int yyparse (void);
+#endif
+#endif
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+ int yyfree_stacks = 0;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ if (yyfree_stacks)
+ {
+ free (yyss);
+ free (yyvs);
+#ifdef YYLSP_NEEDED
+ free (yyls);
+#endif
+ }
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+#ifndef YYSTACK_USE_ALLOCA
+ yyfree_stacks = 1;
+#endif
+ yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1,
+ size * (unsigned int) sizeof (*yyssp));
+ yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+ size * (unsigned int) sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1,
+ size * (unsigned int) sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 3:
+#line 107 "scripts/genksyms/parse.y"
+{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;
+ break;}
+case 4:
+#line 109 "scripts/genksyms/parse.y"
+{ free_list(*yyvsp[0], NULL); *yyvsp[0] = NULL; ;
+ break;}
+case 5:
+#line 113 "scripts/genksyms/parse.y"
+{ is_typedef = 1; ;
+ break;}
+case 6:
+#line 114 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 11:
+#line 119 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 12:
+#line 120 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 13:
+#line 125 "scripts/genksyms/parse.y"
+{ if (current_name) {
+ struct string_list *decl = (*yyvsp[0])->next;
+ (*yyvsp[0])->next = NULL;
+ add_symbol(current_name,
+ is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
+ decl, is_extern);
+ current_name = NULL;
+ }
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 14:
+#line 138 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 16:
+#line 144 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[0];
+ *yyvsp[0] = NULL;
+ add_symbol(current_name,
+ is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+ current_name = NULL;
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 17:
+#line 152 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[0];
+ *yyvsp[0] = NULL;
+ free_list(*yyvsp[-1], NULL);
+ *yyvsp[-1] = decl_spec;
+ add_symbol(current_name,
+ is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+ current_name = NULL;
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 18:
+#line 165 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1] ? yyvsp[-1] : yyvsp[-2] ? yyvsp[-2] : yyvsp[-3]; ;
+ break;}
+case 19:
+#line 170 "scripts/genksyms/parse.y"
+{ decl_spec = NULL; ;
+ break;}
+case 21:
+#line 175 "scripts/genksyms/parse.y"
+{ decl_spec = *yyvsp[0]; ;
+ break;}
+case 22:
+#line 176 "scripts/genksyms/parse.y"
+{ decl_spec = *yyvsp[0]; ;
+ break;}
+case 23:
+#line 181 "scripts/genksyms/parse.y"
+{ /* Version 2 checksumming ignores storage class, as that
+ is really irrelevant to the linkage. */
+ remove_node(yyvsp[0]);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 28:
+#line 193 "scripts/genksyms/parse.y"
+{ is_extern = 1; yyval = yyvsp[0]; ;
+ break;}
+case 29:
+#line 194 "scripts/genksyms/parse.y"
+{ is_extern = 0; yyval = yyvsp[0]; ;
+ break;}
+case 33:
+#line 205 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_STRUCT; yyval = yyvsp[0]; ;
+ break;}
+case 34:
+#line 207 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_UNION; yyval = yyvsp[0]; ;
+ break;}
+case 35:
+#line 209 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_ENUM; yyval = yyvsp[0]; ;
+ break;}
+case 36:
+#line 213 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+ r = copy_node(i); r->tag = SYM_STRUCT;
+ r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+ add_symbol(i->string, SYM_STRUCT, s, is_extern);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 37:
+#line 220 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+ r = copy_node(i); r->tag = SYM_UNION;
+ r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+ add_symbol(i->string, SYM_UNION, s, is_extern);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 38:
+#line 227 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+ r = copy_node(i); r->tag = SYM_ENUM;
+ r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+ add_symbol(i->string, SYM_ENUM, s, is_extern);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 39:
+#line 235 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 40:
+#line 236 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 41:
+#line 237 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 52:
+#line 251 "scripts/genksyms/parse.y"
+{ (*yyvsp[0])->tag = SYM_TYPEDEF; yyval = yyvsp[0]; ;
+ break;}
+case 53:
+#line 256 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+ break;}
+case 54:
+#line 260 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 57:
+#line 266 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 61:
+#line 272 "scripts/genksyms/parse.y"
+{ /* restrict has no effect in prototypes so ignore it */
+ remove_node(yyvsp[0]);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 62:
+#line 279 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 64:
+#line 285 "scripts/genksyms/parse.y"
+{ if (current_name != NULL) {
+ error_with_pos("unexpected second declaration name");
+ YYERROR;
+ } else {
+ current_name = (*yyvsp[0])->string;
+ yyval = yyvsp[0];
+ }
+ ;
+ break;}
+case 65:
+#line 294 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 66:
+#line 296 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 67:
+#line 298 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 68:
+#line 300 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 69:
+#line 302 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 70:
+#line 308 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 74:
+#line 316 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 75:
+#line 318 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 76:
+#line 320 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 77:
+#line 322 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 78:
+#line 324 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 79:
+#line 328 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 81:
+#line 330 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 82:
+#line 334 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 85:
+#line 341 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 86:
+#line 346 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+ break;}
+case 87:
+#line 351 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+ break;}
+case 89:
+#line 356 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 90:
+#line 358 "scripts/genksyms/parse.y"
+{ /* For version 2 checksums, we don't want to remember
+ private parameter names. */
+ remove_node(yyvsp[0]);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 91:
+#line 366 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[0]);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 92:
+#line 370 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 93:
+#line 372 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 94:
+#line 374 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 95:
+#line 376 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 96:
+#line 378 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 97:
+#line 383 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[-1];
+ *yyvsp[-1] = NULL;
+ add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+ yyval = yyvsp[0];
+ ;
+ break;}
+case 98:
+#line 391 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 100:
+#line 398 "scripts/genksyms/parse.y"
+{ remove_list(yyvsp[0], &(*yyvsp[-1])->next); yyval = yyvsp[0]; ;
+ break;}
+case 101:
+#line 402 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 102:
+#line 403 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 103:
+#line 407 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 106:
+#line 413 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 107:
+#line 418 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 108:
+#line 420 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 109:
+#line 424 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 112:
+#line 430 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 113:
+#line 434 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+ break;}
+case 114:
+#line 435 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 116:
+#line 440 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 117:
+#line 444 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 119:
+#line 449 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 120:
+#line 453 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+ break;}
+case 122:
+#line 459 "scripts/genksyms/parse.y"
+{ export_symbol((*yyvsp[-2])->string); yyval = yyvsp[0]; ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/lib/bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+ goto yyerrlab1;
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+
+ yyacceptlab:
+ /* YYACCEPT comes here. */
+ if (yyfree_stacks)
+ {
+ free (yyss);
+ free (yyvs);
+#ifdef YYLSP_NEEDED
+ free (yyls);
+#endif
+ }
+ return 0;
+
+ yyabortlab:
+ /* YYABORT comes here. */
+ if (yyfree_stacks)
+ {
+ free (yyss);
+ free (yyvs);
+#ifdef YYLSP_NEEDED
+ free (yyls);
+#endif
+ }
+ return 1;
+}
+#line 463 "scripts/genksyms/parse.y"
+
+
+static void
+yyerror(const char *e)
+{
+ error_with_pos("%s", e);
+}
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 @@
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define ASM_KEYW 257
+#define ATTRIBUTE_KEYW 258
+#define AUTO_KEYW 259
+#define BOOL_KEYW 260
+#define CHAR_KEYW 261
+#define CONST_KEYW 262
+#define DOUBLE_KEYW 263
+#define ENUM_KEYW 264
+#define EXTERN_KEYW 265
+#define FLOAT_KEYW 266
+#define INLINE_KEYW 267
+#define INT_KEYW 268
+#define LONG_KEYW 269
+#define REGISTER_KEYW 270
+#define RESTRICT_KEYW 271
+#define SHORT_KEYW 272
+#define SIGNED_KEYW 273
+#define STATIC_KEYW 274
+#define STRUCT_KEYW 275
+#define TYPEDEF_KEYW 276
+#define UNION_KEYW 277
+#define UNSIGNED_KEYW 278
+#define VOID_KEYW 279
+#define VOLATILE_KEYW 280
+#define TYPEOF_KEYW 281
+#define EXPORT_SYMBOL_KEYW 282
+#define ASM_PHRASE 283
+#define ATTRIBUTE_PHRASE 284
+#define BRACE_PHRASE 285
+#define BRACKET_PHRASE 286
+#define EXPRESSION_PHRASE 287
+#define CHAR 288
+#define DOTS 289
+#define IDENT 290
+#define INT 291
+#define REAL 292
+#define STRING 293
+#define TYPE 294
+#define OTHER 295
+#define FILENAME 296
+
+
+extern 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 @@
+/* C global declaration parser for genksyms.
+ Copyright 1996, 1997 Linux International.
+
+ New implementation contributed by Richard Henderson <rth@tamu.edu>
+ Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+ This file is part of the Linux modutils.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+%{
+
+#include <assert.h>
+#include <malloc.h>
+#include "genksyms.h"
+
+static int is_typedef;
+static int is_extern;
+static char *current_name;
+static struct string_list *decl_spec;
+
+static void yyerror(const char *);
+
+static inline void
+remove_node(struct string_list **p)
+{
+ struct string_list *node = *p;
+ *p = node->next;
+ free_node(node);
+}
+
+static inline void
+remove_list(struct string_list **pb, struct string_list **pe)
+{
+ struct string_list *b = *pb, *e = *pe;
+ *pb = e;
+ free_list(b, e);
+}
+
+%}
+
+%token ASM_KEYW
+%token ATTRIBUTE_KEYW
+%token AUTO_KEYW
+%token BOOL_KEYW
+%token CHAR_KEYW
+%token CONST_KEYW
+%token DOUBLE_KEYW
+%token ENUM_KEYW
+%token EXTERN_KEYW
+%token FLOAT_KEYW
+%token INLINE_KEYW
+%token INT_KEYW
+%token LONG_KEYW
+%token REGISTER_KEYW
+%token RESTRICT_KEYW
+%token SHORT_KEYW
+%token SIGNED_KEYW
+%token STATIC_KEYW
+%token STRUCT_KEYW
+%token TYPEDEF_KEYW
+%token UNION_KEYW
+%token UNSIGNED_KEYW
+%token VOID_KEYW
+%token VOLATILE_KEYW
+%token TYPEOF_KEYW
+
+%token EXPORT_SYMBOL_KEYW
+
+%token ASM_PHRASE
+%token ATTRIBUTE_PHRASE
+%token BRACE_PHRASE
+%token BRACKET_PHRASE
+%token EXPRESSION_PHRASE
+
+%token CHAR
+%token DOTS
+%token IDENT
+%token INT
+%token REAL
+%token STRING
+%token TYPE
+%token OTHER
+%token FILENAME
+
+%%
+
+declaration_seq:
+ declaration
+ | declaration_seq declaration
+ ;
+
+declaration:
+ { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
+ declaration1
+ { free_list(*$2, NULL); *$2 = NULL; }
+ ;
+
+declaration1:
+ TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
+ { $$ = $3; }
+ | simple_declaration
+ | function_definition
+ | asm_definition
+ | export_definition
+ | error ';' { $$ = $2; }
+ | error '}' { $$ = $2; }
+ ;
+
+simple_declaration:
+ decl_specifier_seq_opt init_declarator_list_opt ';'
+ { if (current_name) {
+ struct string_list *decl = (*$3)->next;
+ (*$3)->next = NULL;
+ add_symbol(current_name,
+ is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
+ decl, is_extern);
+ current_name = NULL;
+ }
+ $$ = $3;
+ }
+ ;
+
+init_declarator_list_opt:
+ /* empty */ { $$ = NULL; }
+ | init_declarator_list
+ ;
+
+init_declarator_list:
+ init_declarator
+ { struct string_list *decl = *$1;
+ *$1 = NULL;
+ add_symbol(current_name,
+ is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+ current_name = NULL;
+ $$ = $1;
+ }
+ | init_declarator_list ',' init_declarator
+ { struct string_list *decl = *$3;
+ *$3 = NULL;
+ free_list(*$2, NULL);
+ *$2 = decl_spec;
+ add_symbol(current_name,
+ is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+ current_name = NULL;
+ $$ = $3;
+ }
+ ;
+
+init_declarator:
+ declarator asm_phrase_opt attribute_opt initializer_opt
+ { $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
+ ;
+
+/* Hang on to the specifiers so that we can reuse them. */
+decl_specifier_seq_opt:
+ /* empty */ { decl_spec = NULL; }
+ | decl_specifier_seq
+ ;
+
+decl_specifier_seq:
+ decl_specifier { decl_spec = *$1; }
+ | decl_specifier_seq decl_specifier { decl_spec = *$2; }
+ ;
+
+decl_specifier:
+ storage_class_specifier
+ { /* Version 2 checksumming ignores storage class, as that
+ is really irrelevant to the linkage. */
+ remove_node($1);
+ $$ = $1;
+ }
+ | type_specifier
+ ;
+
+storage_class_specifier:
+ AUTO_KEYW
+ | REGISTER_KEYW
+ | STATIC_KEYW
+ | EXTERN_KEYW { is_extern = 1; $$ = $1; }
+ | INLINE_KEYW { is_extern = 0; $$ = $1; }
+ ;
+
+type_specifier:
+ simple_type_specifier
+ | cvar_qualifier
+ | TYPEOF_KEYW '(' decl_specifier_seq ')'
+
+ /* References to s/u/e's defined elsewhere. Rearrange things
+ so that it is easier to expand the definition fully later. */
+ | STRUCT_KEYW IDENT
+ { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
+ | UNION_KEYW IDENT
+ { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
+ | ENUM_KEYW IDENT
+ { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
+
+ /* Full definitions of an s/u/e. Record it. */
+ | STRUCT_KEYW IDENT class_body
+ { struct string_list *s = *$3, *i = *$2, *r;
+ r = copy_node(i); r->tag = SYM_STRUCT;
+ r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+ add_symbol(i->string, SYM_STRUCT, s, is_extern);
+ $$ = $3;
+ }
+ | UNION_KEYW IDENT class_body
+ { struct string_list *s = *$3, *i = *$2, *r;
+ r = copy_node(i); r->tag = SYM_UNION;
+ r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+ add_symbol(i->string, SYM_UNION, s, is_extern);
+ $$ = $3;
+ }
+ | ENUM_KEYW IDENT BRACE_PHRASE
+ { struct string_list *s = *$3, *i = *$2, *r;
+ r = copy_node(i); r->tag = SYM_ENUM;
+ r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+ add_symbol(i->string, SYM_ENUM, s, is_extern);
+ $$ = $3;
+ }
+
+ /* Anonymous s/u/e definitions. Nothing needs doing. */
+ | ENUM_KEYW BRACE_PHRASE { $$ = $2; }
+ | STRUCT_KEYW class_body { $$ = $2; }
+ | UNION_KEYW class_body { $$ = $2; }
+ ;
+
+simple_type_specifier:
+ CHAR_KEYW
+ | SHORT_KEYW
+ | INT_KEYW
+ | LONG_KEYW
+ | SIGNED_KEYW
+ | UNSIGNED_KEYW
+ | FLOAT_KEYW
+ | DOUBLE_KEYW
+ | VOID_KEYW
+ | BOOL_KEYW
+ | TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
+ ;
+
+ptr_operator:
+ '*' cvar_qualifier_seq_opt
+ { $$ = $2 ? $2 : $1; }
+ ;
+
+cvar_qualifier_seq_opt:
+ /* empty */ { $$ = NULL; }
+ | cvar_qualifier_seq
+ ;
+
+cvar_qualifier_seq:
+ cvar_qualifier
+ | cvar_qualifier_seq cvar_qualifier { $$ = $2; }
+ ;
+
+cvar_qualifier:
+ CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
+ | RESTRICT_KEYW
+ { /* restrict has no effect in prototypes so ignore it */
+ remove_node($1);
+ $$ = $1;
+ }
+ ;
+
+declarator:
+ ptr_operator declarator { $$ = $2; }
+ | direct_declarator
+ ;
+
+direct_declarator:
+ IDENT
+ { if (current_name != NULL) {
+ error_with_pos("unexpected second declaration name");
+ YYERROR;
+ } else {
+ current_name = (*$1)->string;
+ $$ = $1;
+ }
+ }
+ | direct_declarator '(' parameter_declaration_clause ')'
+ { $$ = $4; }
+ | direct_declarator '(' error ')'
+ { $$ = $4; }
+ | direct_declarator BRACKET_PHRASE
+ { $$ = $2; }
+ | '(' declarator ')'
+ { $$ = $3; }
+ | '(' error ')'
+ { $$ = $3; }
+ ;
+
+/* Nested declarators differ from regular declarators in that they do
+ not record the symbols they find in the global symbol table. */
+nested_declarator:
+ ptr_operator nested_declarator { $$ = $2; }
+ | direct_nested_declarator
+ ;
+
+direct_nested_declarator:
+ IDENT
+ | TYPE
+ | direct_nested_declarator '(' parameter_declaration_clause ')'
+ { $$ = $4; }
+ | direct_nested_declarator '(' error ')'
+ { $$ = $4; }
+ | direct_nested_declarator BRACKET_PHRASE
+ { $$ = $2; }
+ | '(' nested_declarator ')'
+ { $$ = $3; }
+ | '(' error ')'
+ { $$ = $3; }
+ ;
+
+parameter_declaration_clause:
+ parameter_declaration_list_opt DOTS { $$ = $2; }
+ | parameter_declaration_list_opt
+ | parameter_declaration_list ',' DOTS { $$ = $3; }
+ ;
+
+parameter_declaration_list_opt:
+ /* empty */ { $$ = NULL; }
+ | parameter_declaration_list
+ ;
+
+parameter_declaration_list:
+ parameter_declaration
+ | parameter_declaration_list ',' parameter_declaration
+ { $$ = $3; }
+ ;
+
+parameter_declaration:
+ decl_specifier_seq m_abstract_declarator
+ { $$ = $2 ? $2 : $1; }
+ ;
+
+m_abstract_declarator:
+ ptr_operator m_abstract_declarator
+ { $$ = $2 ? $2 : $1; }
+ | direct_m_abstract_declarator
+ ;
+
+direct_m_abstract_declarator:
+ /* empty */ { $$ = NULL; }
+ | IDENT
+ { /* For version 2 checksums, we don't want to remember
+ private parameter names. */
+ remove_node($1);
+ $$ = $1;
+ }
+ /* This wasn't really a typedef name but an identifier that
+ shadows one. */
+ | TYPE
+ { remove_node($1);
+ $$ = $1;
+ }
+ | direct_m_abstract_declarator '(' parameter_declaration_clause ')'
+ { $$ = $4; }
+ | direct_m_abstract_declarator '(' error ')'
+ { $$ = $4; }
+ | direct_m_abstract_declarator BRACKET_PHRASE
+ { $$ = $2; }
+ | '(' m_abstract_declarator ')'
+ { $$ = $3; }
+ | '(' error ')'
+ { $$ = $3; }
+ ;
+
+function_definition:
+ decl_specifier_seq_opt declarator BRACE_PHRASE
+ { struct string_list *decl = *$2;
+ *$2 = NULL;
+ add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+ $$ = $3;
+ }
+ ;
+
+initializer_opt:
+ /* empty */ { $$ = NULL; }
+ | initializer
+ ;
+
+/* We never care about the contents of an initializer. */
+initializer:
+ '=' EXPRESSION_PHRASE
+ { remove_list($2, &(*$1)->next); $$ = $2; }
+ ;
+
+class_body:
+ '{' member_specification_opt '}' { $$ = $3; }
+ | '{' error '}' { $$ = $3; }
+ ;
+
+member_specification_opt:
+ /* empty */ { $$ = NULL; }
+ | member_specification
+ ;
+
+member_specification:
+ member_declaration
+ | member_specification member_declaration { $$ = $2; }
+ ;
+
+member_declaration:
+ decl_specifier_seq_opt member_declarator_list_opt ';'
+ { $$ = $3; }
+ | error ';'
+ { $$ = $2; }
+ ;
+
+member_declarator_list_opt:
+ /* empty */ { $$ = NULL; }
+ | member_declarator_list
+ ;
+
+member_declarator_list:
+ member_declarator
+ | member_declarator_list ',' member_declarator { $$ = $3; }
+ ;
+
+member_declarator:
+ nested_declarator attribute_opt { $$ = $2 ? $2 : $1; }
+ | IDENT member_bitfield_declarator { $$ = $2; }
+ | member_bitfield_declarator
+ ;
+
+member_bitfield_declarator:
+ ':' EXPRESSION_PHRASE { $$ = $2; }
+ ;
+
+attribute_opt:
+ /* empty */ { $$ = NULL; }
+ | ATTRIBUTE_PHRASE
+ ;
+
+asm_definition:
+ ASM_PHRASE ';' { $$ = $2; }
+ ;
+
+asm_phrase_opt:
+ /* empty */ { $$ = NULL; }
+ | ASM_PHRASE
+ ;
+
+export_definition:
+ EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
+ { export_symbol((*$3)->string); $$ = $5; }
+ ;
+
+
+%%
+
+static void
+yyerror(const char *e)
+{
+ error_with_pos("%s", e);
+}
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 @@
+/* Generate assembler source containing symbol information
+ *
+ * Copyright 2002 by Kai Germaschewski
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Usage: nm -n vmlinux | scripts/kallsyms [--all-symbols] > symbols.S
+ *
+ * ChangeLog:
+ *
+ * (25/Aug/2004) Paulo Marques <pmarques@grupopie.com>
+ * Changed the compression method from stem compression to "table lookup"
+ * compression
+ *
+ * Table compression uses all the unused char codes on the symbols and
+ * maps these to the most used substrings (tokens). For instance, it might
+ * map char code 0xF7 to represent "write_" and then in every symbol where
+ * "write_" appears it can be replaced by 0xF7, saving 5 bytes.
+ * The used codes themselves are also placed in the table so that the
+ * decompresion can work without "special cases".
+ * Applied to kernel symbols, this usually produces a compression ratio
+ * of about 50%.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/* maximum token length used. It doesn't pay to increase it a lot, because
+ * very long substrings probably don't repeat themselves too often. */
+#define MAX_TOK_SIZE 11
+#define KSYM_NAME_LEN 127
+
+/* we use only a subset of the complete symbol table to gather the token count,
+ * to speed up compression, at the expense of a little compression ratio */
+#define WORKING_SET 1024
+
+/* first find the best token only on the list of tokens that would profit more
+ * than GOOD_BAD_THRESHOLD. Only if this list is empty go to the "bad" list.
+ * Increasing this value will put less tokens on the "good" list, so the search
+ * is faster. However, if the good list runs out of tokens, we must painfully
+ * search the bad list. */
+#define GOOD_BAD_THRESHOLD 10
+
+/* token hash parameters */
+#define HASH_BITS 18
+#define HASH_TABLE_SIZE (1 << HASH_BITS)
+#define HASH_MASK (HASH_TABLE_SIZE - 1)
+#define HASH_BASE_OFFSET 2166136261U
+#define HASH_FOLD(a) ((a)&(HASH_MASK))
+
+/* flags to mark symbols */
+#define SYM_FLAG_VALID 1
+#define SYM_FLAG_SAMPLED 2
+
+struct sym_entry {
+ unsigned long long addr;
+ char type;
+ unsigned char flags;
+ unsigned char len;
+ unsigned char *sym;
+};
+
+
+static struct sym_entry *table;
+static int size, cnt;
+static unsigned long long _stext, _etext, _sinittext, _einittext;
+static int all_symbols = 0;
+
+struct token {
+ unsigned char data[MAX_TOK_SIZE];
+ unsigned char len;
+ /* profit: the number of bytes that could be saved by inserting this
+ * token into the table */
+ int profit;
+ struct token *next; /* next token on the hash list */
+ struct token *right; /* next token on the good/bad list */
+ struct token *left; /* previous token on the good/bad list */
+ struct token *smaller; /* token that is less one letter than this one */
+ };
+
+struct token bad_head, good_head;
+struct token *hash_table[HASH_TABLE_SIZE];
+
+/* the table that holds the result of the compression */
+unsigned char best_table[256][MAX_TOK_SIZE+1];
+unsigned char best_table_len[256];
+
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n");
+ exit(1);
+}
+
+/*
+ * This ignores the intensely annoying "mapping symbols" found
+ * in ARM ELF files: $a, $t and $d.
+ */
+static inline int
+is_arm_mapping_symbol(const char *str)
+{
+ return str[0] == '$' && strchr("atd", str[1])
+ && (str[2] == '\0' || str[2] == '.');
+}
+
+static int
+read_symbol(FILE *in, struct sym_entry *s)
+{
+ char str[500];
+ int rc;
+
+ rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
+ if (rc != 3) {
+ if (rc != EOF) {
+ /* skip line */
+ fgets(str, 500, in);
+ }
+ return -1;
+ }
+
+ /* Ignore most absolute/undefined (?) symbols. */
+ if (strcmp(str, "_stext") == 0)
+ _stext = s->addr;
+ else if (strcmp(str, "_etext") == 0)
+ _etext = s->addr;
+ else if (strcmp(str, "_sinittext") == 0)
+ _sinittext = s->addr;
+ else if (strcmp(str, "_einittext") == 0)
+ _einittext = s->addr;
+ else if (toupper(s->type) == 'A')
+ {
+ /* Keep these useful absolute symbols */
+ if (strcmp(str, "__kernel_syscall_via_break") &&
+ strcmp(str, "__kernel_syscall_via_epc") &&
+ strcmp(str, "__kernel_sigtramp") &&
+ strcmp(str, "__gp"))
+ return -1;
+
+ }
+ else if (toupper(s->type) == 'U' ||
+ is_arm_mapping_symbol(str))
+ return -1;
+
+ /* include the type field in the symbol name, so that it gets
+ * compressed together */
+ s->len = strlen(str) + 1;
+ s->sym = (char *) malloc(s->len + 1);
+ strcpy(s->sym + 1, str);
+ s->sym[0] = s->type;
+
+ return 0;
+}
+
+static int
+symbol_valid(struct sym_entry *s)
+{
+ /* Symbols which vary between passes. Passes 1 and 2 must have
+ * identical symbol lists. The kallsyms_* symbols below are only added
+ * after pass 1, they would be included in pass 2 when --all-symbols is
+ * specified so exclude them to get a stable symbol list.
+ */
+ static char *special_symbols[] = {
+ "kallsyms_addresses",
+ "kallsyms_num_syms",
+ "kallsyms_names",
+ "kallsyms_markers",
+ "kallsyms_token_table",
+ "kallsyms_token_index",
+
+ /* Exclude linker generated symbols which vary between passes */
+ "_SDA_BASE_", /* ppc */
+ "_SDA2_BASE_", /* ppc */
+ NULL };
+ int i;
+
+ /* if --all-symbols is not specified, then symbols outside the text
+ * and inittext sections are discarded */
+ if (!all_symbols) {
+ if ((s->addr < _stext || s->addr > _etext)
+ && (s->addr < _sinittext || s->addr > _einittext))
+ return 0;
+ /* Corner case. Discard any symbols with the same value as
+ * _etext or _einittext, they can move between pass 1 and 2
+ * when the kallsyms data is added. If these symbols move then
+ * they may get dropped in pass 2, which breaks the kallsyms
+ * rules.
+ */
+ if ((s->addr == _etext && strcmp(s->sym + 1, "_etext")) ||
+ (s->addr == _einittext && strcmp(s->sym + 1, "_einittext")))
+ return 0;
+ }
+
+ /* Exclude symbols which vary between passes. */
+ if (strstr(s->sym + 1, "_compiled."))
+ return 0;
+
+ for (i = 0; special_symbols[i]; i++)
+ if( strcmp(s->sym + 1, special_symbols[i]) == 0 )
+ return 0;
+
+ return 1;
+}
+
+static void
+read_map(FILE *in)
+{
+ while (!feof(in)) {
+ if (cnt >= size) {
+ size += 10000;
+ table = realloc(table, sizeof(*table) * size);
+ if (!table) {
+ fprintf(stderr, "out of memory\n");
+ exit (1);
+ }
+ }
+ if (read_symbol(in, &table[cnt]) == 0)
+ cnt++;
+ }
+}
+
+static void output_label(char *label)
+{
+ printf(".globl %s\n",label);
+ printf("\tALGN\n");
+ printf("%s:\n",label);
+}
+
+/* uncompress a compressed symbol. When this function is called, the best table
+ * might still be compressed itself, so the function needs to be recursive */
+static int expand_symbol(unsigned char *data, int len, char *result)
+{
+ int c, rlen, total=0;
+
+ while (len) {
+ c = *data;
+ /* if the table holds a single char that is the same as the one
+ * we are looking for, then end the search */
+ if (best_table[c][0]==c && best_table_len[c]==1) {
+ *result++ = c;
+ total++;
+ } else {
+ /* if not, recurse and expand */
+ rlen = expand_symbol(best_table[c], best_table_len[c], result);
+ total += rlen;
+ result += rlen;
+ }
+ data++;
+ len--;
+ }
+ *result=0;
+
+ return total;
+}
+
+static void
+write_src(void)
+{
+ int i, k, off, valid;
+ unsigned int best_idx[256];
+ unsigned int *markers;
+ char buf[KSYM_NAME_LEN+1];
+
+ printf("#include <asm/types.h>\n");
+ printf("#if BITS_PER_LONG == 64\n");
+ printf("#define PTR .quad\n");
+ printf("#define ALGN .align 8\n");
+ printf("#else\n");
+ printf("#define PTR .long\n");
+ printf("#define ALGN .align 4\n");
+ printf("#endif\n");
+
+ printf(".data\n");
+
+ output_label("kallsyms_addresses");
+ valid = 0;
+ for (i = 0; i < cnt; i++) {
+ if (table[i].flags & SYM_FLAG_VALID) {
+ printf("\tPTR\t%#llx\n", table[i].addr);
+ valid++;
+ }
+ }
+ printf("\n");
+
+ output_label("kallsyms_num_syms");
+ printf("\tPTR\t%d\n", valid);
+ printf("\n");
+
+ /* table of offset markers, that give the offset in the compressed stream
+ * every 256 symbols */
+ markers = (unsigned int *) malloc(sizeof(unsigned int)*((valid + 255) / 256));
+
+ output_label("kallsyms_names");
+ valid = 0;
+ off = 0;
+ for (i = 0; i < cnt; i++) {
+
+ if (!table[i].flags & SYM_FLAG_VALID)
+ continue;
+
+ if ((valid & 0xFF) == 0)
+ markers[valid >> 8] = off;
+
+ printf("\t.byte 0x%02x", table[i].len);
+ for (k = 0; k < table[i].len; k++)
+ printf(", 0x%02x", table[i].sym[k]);
+ printf("\n");
+
+ off += table[i].len + 1;
+ valid++;
+ }
+ printf("\n");
+
+ output_label("kallsyms_markers");
+ for (i = 0; i < ((valid + 255) >> 8); i++)
+ printf("\tPTR\t%d\n", markers[i]);
+ printf("\n");
+
+ free(markers);
+
+ output_label("kallsyms_token_table");
+ off = 0;
+ for (i = 0; i < 256; i++) {
+ best_idx[i] = off;
+ expand_symbol(best_table[i],best_table_len[i],buf);
+ printf("\t.asciz\t\"%s\"\n", buf);
+ off += strlen(buf) + 1;
+ }
+ printf("\n");
+
+ output_label("kallsyms_token_index");
+ for (i = 0; i < 256; i++)
+ printf("\t.short\t%d\n", best_idx[i]);
+ printf("\n");
+}
+
+
+/* table lookup compression functions */
+
+static inline unsigned int rehash_token(unsigned int hash, unsigned char data)
+{
+ return ((hash * 16777619) ^ data);
+}
+
+static unsigned int hash_token(unsigned char *data, int len)
+{
+ unsigned int hash=HASH_BASE_OFFSET;
+ int i;
+
+ for (i = 0; i < len; i++)
+ hash = rehash_token(hash, data[i]);
+
+ return HASH_FOLD(hash);
+}
+
+/* find a token given its data and hash value */
+static struct token *find_token_hash(unsigned char *data, int len, unsigned int hash)
+{
+ struct token *ptr;
+
+ ptr = hash_table[hash];
+
+ while (ptr) {
+ if ((ptr->len == len) && (memcmp(ptr->data, data, len) == 0))
+ return ptr;
+ ptr=ptr->next;
+ }
+
+ return NULL;
+}
+
+static inline void insert_token_in_group(struct token *head, struct token *ptr)
+{
+ ptr->right = head->right;
+ ptr->right->left = ptr;
+ head->right = ptr;
+ ptr->left = head;
+}
+
+static inline void remove_token_from_group(struct token *ptr)
+{
+ ptr->left->right = ptr->right;
+ ptr->right->left = ptr->left;
+}
+
+
+/* build the counts for all the tokens that start with "data", and have lenghts
+ * from 2 to "len" */
+static void learn_token(unsigned char *data, int len)
+{
+ struct token *ptr,*last_ptr;
+ int i, newprofit;
+ unsigned int hash = HASH_BASE_OFFSET;
+ unsigned int hashes[MAX_TOK_SIZE + 1];
+
+ if (len > MAX_TOK_SIZE)
+ len = MAX_TOK_SIZE;
+
+ /* calculate and store the hash values for all the sub-tokens */
+ hash = rehash_token(hash, data[0]);
+ for (i = 2; i <= len; i++) {
+ hash = rehash_token(hash, data[i-1]);
+ hashes[i] = HASH_FOLD(hash);
+ }
+
+ last_ptr = NULL;
+ ptr = NULL;
+
+ for (i = len; i >= 2; i--) {
+ hash = hashes[i];
+
+ if (!ptr) ptr = find_token_hash(data, i, hash);
+
+ if (!ptr) {
+ /* create a new token entry */
+ ptr = (struct token *) malloc(sizeof(*ptr));
+
+ memcpy(ptr->data, data, i);
+ ptr->len = i;
+
+ /* when we create an entry, it's profit is 0 because
+ * we also take into account the size of the token on
+ * the compressed table. We then subtract GOOD_BAD_THRESHOLD
+ * so that the test to see if this token belongs to
+ * the good or bad list, is a comparison to zero */
+ ptr->profit = -GOOD_BAD_THRESHOLD;
+
+ ptr->next = hash_table[hash];
+ hash_table[hash] = ptr;
+
+ insert_token_in_group(&bad_head, ptr);
+
+ ptr->smaller = NULL;
+ } else {
+ newprofit = ptr->profit + (ptr->len - 1);
+ /* check to see if this token needs to be moved to a
+ * different list */
+ if((ptr->profit < 0) && (newprofit >= 0)) {
+ remove_token_from_group(ptr);
+ insert_token_in_group(&good_head,ptr);
+ }
+ ptr->profit = newprofit;
+ }
+
+ if (last_ptr) last_ptr->smaller = ptr;
+ last_ptr = ptr;
+
+ ptr = ptr->smaller;
+ }
+}
+
+/* decrease the counts for all the tokens that start with "data", and have lenghts
+ * from 2 to "len". This function is much simpler than learn_token because we have
+ * more guarantees (tho tokens exist, the ->smaller pointer is set, etc.)
+ * The two separate functions exist only because of compression performance */
+static void forget_token(unsigned char *data, int len)
+{
+ struct token *ptr;
+ int i, newprofit;
+ unsigned int hash=0;
+
+ if (len > MAX_TOK_SIZE) len = MAX_TOK_SIZE;
+
+ hash = hash_token(data, len);
+ ptr = find_token_hash(data, len, hash);
+
+ for (i = len; i >= 2; i--) {
+
+ newprofit = ptr->profit - (ptr->len - 1);
+ if ((ptr->profit >= 0) && (newprofit < 0)) {
+ remove_token_from_group(ptr);
+ insert_token_in_group(&bad_head, ptr);
+ }
+ ptr->profit=newprofit;
+
+ ptr=ptr->smaller;
+ }
+}
+
+/* count all the possible tokens in a symbol */
+static void learn_symbol(unsigned char *symbol, int len)
+{
+ int i;
+
+ for (i = 0; i < len - 1; i++)
+ learn_token(symbol + i, len - i);
+}
+
+/* decrease the count for all the possible tokens in a symbol */
+static void forget_symbol(unsigned char *symbol, int len)
+{
+ int i;
+
+ for (i = 0; i < len - 1; i++)
+ forget_token(symbol + i, len - i);
+}
+
+/* set all the symbol flags and do the initial token count */
+static void build_initial_tok_table(void)
+{
+ int i, use_it, valid;
+
+ valid = 0;
+ for (i = 0; i < cnt; i++) {
+ table[i].flags = 0;
+ if ( symbol_valid(&table[i]) ) {
+ table[i].flags |= SYM_FLAG_VALID;
+ valid++;
+ }
+ }
+
+ use_it = 0;
+ for (i = 0; i < cnt; i++) {
+
+ /* subsample the available symbols. This method is almost like
+ * a Bresenham's algorithm to get uniformly distributed samples
+ * across the symbol table */
+ if (table[i].flags & SYM_FLAG_VALID) {
+
+ use_it += WORKING_SET;
+
+ if (use_it >= valid) {
+ table[i].flags |= SYM_FLAG_SAMPLED;
+ use_it -= valid;
+ }
+ }
+ if (table[i].flags & SYM_FLAG_SAMPLED)
+ learn_symbol(table[i].sym, table[i].len);
+ }
+}
+
+/* replace a given token in all the valid symbols. Use the sampled symbols
+ * to update the counts */
+static void compress_symbols(unsigned char *str, int tlen, int idx)
+{
+ int i, len, learn, size;
+ unsigned char *p;
+
+ for (i = 0; i < cnt; i++) {
+
+ if (!(table[i].flags & SYM_FLAG_VALID)) continue;
+
+ len = table[i].len;
+ learn = 0;
+ p = table[i].sym;
+
+ do {
+ /* find the token on the symbol */
+ p = (unsigned char *) strstr((char *) p, (char *) str);
+ if (!p) break;
+
+ if (!learn) {
+ /* if this symbol was used to count, decrease it */
+ if (table[i].flags & SYM_FLAG_SAMPLED)
+ forget_symbol(table[i].sym, len);
+ learn = 1;
+ }
+
+ *p = idx;
+ size = (len - (p - table[i].sym)) - tlen + 1;
+ memmove(p + 1, p + tlen, size);
+ p++;
+ len -= tlen - 1;
+
+ } while (size >= tlen);
+
+ if(learn) {
+ table[i].len = len;
+ /* if this symbol was used to count, learn it again */
+ if(table[i].flags & SYM_FLAG_SAMPLED)
+ learn_symbol(table[i].sym, len);
+ }
+ }
+}
+
+/* search the token with the maximum profit */
+static struct token *find_best_token(void)
+{
+ struct token *ptr,*best,*head;
+ int bestprofit;
+
+ bestprofit=-10000;
+
+ /* failsafe: if the "good" list is empty search from the "bad" list */
+ if(good_head.right == &good_head) head = &bad_head;
+ else head = &good_head;
+
+ ptr = head->right;
+ best = NULL;
+ while (ptr != head) {
+ if (ptr->profit > bestprofit) {
+ bestprofit = ptr->profit;
+ best = ptr;
+ }
+ ptr = ptr->right;
+ }
+
+ return best;
+}
+
+/* this is the core of the algorithm: calculate the "best" table */
+static void optimize_result(void)
+{
+ struct token *best;
+ int i;
+
+ /* using the '\0' symbol last allows compress_symbols to use standard
+ * fast string functions */
+ for (i = 255; i >= 0; i--) {
+
+ /* if this table slot is empty (it is not used by an actual
+ * original char code */
+ if (!best_table_len[i]) {
+
+ /* find the token with the breates profit value */
+ best = find_best_token();
+
+ /* place it in the "best" table */
+ best_table_len[i] = best->len;
+ memcpy(best_table[i], best->data, best_table_len[i]);
+ /* zero terminate the token so that we can use strstr
+ in compress_symbols */
+ best_table[i][best_table_len[i]]='\0';
+
+ /* replace this token in all the valid symbols */
+ compress_symbols(best_table[i], best_table_len[i], i);
+ }
+ }
+}
+
+/* start by placing the symbols that are actually used on the table */
+static void insert_real_symbols_in_table(void)
+{
+ int i, j, c;
+
+ memset(best_table, 0, sizeof(best_table));
+ memset(best_table_len, 0, sizeof(best_table_len));
+
+ for (i = 0; i < cnt; i++) {
+ if (table[i].flags & SYM_FLAG_VALID) {
+ for (j = 0; j < table[i].len; j++) {
+ c = table[i].sym[j];
+ best_table[c][0]=c;
+ best_table_len[c]=1;
+ }
+ }
+ }
+}
+
+static void optimize_token_table(void)
+{
+ memset(hash_table, 0, sizeof(hash_table));
+
+ good_head.left = &good_head;
+ good_head.right = &good_head;
+
+ bad_head.left = &bad_head;
+ bad_head.right = &bad_head;
+
+ build_initial_tok_table();
+
+ insert_real_symbols_in_table();
+
+ optimize_result();
+}
+
+
+int
+main(int argc, char **argv)
+{
+ if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0)
+ all_symbols = 1;
+ else if (argc != 1)
+ usage();
+
+ read_map(stdin);
+ optimize_token_table();
+ write_src();
+
+ return 0;
+}
+
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 @@
+# ===========================================================================
+# Kernel configuration targets
+# These targets are used from top-level makefile
+
+.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig
+
+xconfig: $(obj)/qconf
+ $< arch/$(ARCH)/Kconfig
+
+gconfig: $(obj)/gconf
+ $< arch/$(ARCH)/Kconfig
+
+menuconfig: $(obj)/mconf
+ $(Q)$(MAKE) $(build)=scripts/lxdialog
+ $< arch/$(ARCH)/Kconfig
+
+config: $(obj)/conf
+ $< arch/$(ARCH)/Kconfig
+
+oldconfig: $(obj)/conf
+ $< -o arch/$(ARCH)/Kconfig
+
+silentoldconfig: $(obj)/conf
+ $< -s arch/$(ARCH)/Kconfig
+
+.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig
+
+randconfig: $(obj)/conf
+ $< -r arch/$(ARCH)/Kconfig
+
+allyesconfig: $(obj)/conf
+ $< -y arch/$(ARCH)/Kconfig
+
+allnoconfig: $(obj)/conf
+ $< -n arch/$(ARCH)/Kconfig
+
+allmodconfig: $(obj)/conf
+ $< -m arch/$(ARCH)/Kconfig
+
+defconfig: $(obj)/conf
+ifeq ($(KBUILD_DEFCONFIG),)
+ $< -d arch/$(ARCH)/Kconfig
+else
+ @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)'
+ $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig
+endif
+
+%_defconfig: $(obj)/conf
+ $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig
+
+# Help text used by make help
+help:
+ @echo ' config - Update current config utilising a line-oriented program'
+ @echo ' menuconfig - Update current config utilising a menu based program'
+ @echo ' xconfig - Update current config utilising a QT based front-end'
+ @echo ' gconfig - Update current config utilising a GTK based front-end'
+ @echo ' oldconfig - Update current config utilising a provided .config as base'
+ @echo ' randconfig - New config with random answer to all options'
+ @echo ' defconfig - New config with default answer to all options'
+ @echo ' allmodconfig - New config selecting modules when possible'
+ @echo ' allyesconfig - New config where all options are accepted with yes'
+ @echo ' allnoconfig - New minimal config'
+
+# ===========================================================================
+# Shared Makefile for the various kconfig executables:
+# conf: Used for defconfig, oldconfig and related targets
+# mconf: Used for the mconfig target.
+# Utilizes the lxdialog package
+# qconf: Used for the xconfig target
+# Based on QT which needs to be installed to compile it
+# gconf: Used for the gconfig target
+# Based on GTK which needs to be installed to compile it
+# object files used by all kconfig flavours
+
+hostprogs-y := conf mconf qconf gconf
+conf-objs := conf.o zconf.tab.o
+mconf-objs := mconf.o zconf.tab.o
+
+ifeq ($(MAKECMDGOALS),xconfig)
+ qconf-target := 1
+endif
+ifeq ($(MAKECMDGOALS),gconfig)
+ gconf-target := 1
+endif
+
+
+ifeq ($(qconf-target),1)
+qconf-cxxobjs := qconf.o
+qconf-objs := kconfig_load.o zconf.tab.o
+endif
+
+ifeq ($(gconf-target),1)
+gconf-objs := gconf.o kconfig_load.o zconf.tab.o
+endif
+
+clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
+ .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
+
+# generated files seem to need this to find local include files
+HOSTCFLAGS_lex.zconf.o := -I$(src)
+HOSTCFLAGS_zconf.tab.o := -I$(src)
+
+HOSTLOADLIBES_qconf = -L$(QTLIBPATH) -Wl,-rpath,$(QTLIBPATH) -l$(QTLIB) -ldl
+HOSTCXXFLAGS_qconf.o = -I$(QTDIR)/include -D LKC_DIRECT_LINK
+
+HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
+HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
+ -D LKC_DIRECT_LINK
+
+$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h
+
+$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
+$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
+$(obj)/lex.zconf.c: $(src)/lex.zconf.c_shipped
+
+$(obj)/qconf.o: $(obj)/.tmp_qtcheck
+
+ifeq ($(qconf-target),1)
+MOC = $(QTDIR)/bin/moc
+QTLIBPATH = $(QTDIR)/lib
+-include $(obj)/.tmp_qtcheck
+
+# QT needs some extra effort...
+$(obj)/.tmp_qtcheck:
+ @set -e; for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
+ if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \
+ done; \
+ if [ -z "$$DIR" ]; then \
+ echo "*"; \
+ echo "* Unable to find the QT installation. Please make sure that the"; \
+ echo "* QT development package is correctly installed and the QTDIR"; \
+ echo "* environment variable is set to the correct location."; \
+ echo "*"; \
+ false; \
+ fi; \
+ LIBPATH=$$DIR/lib; LIB=qt; \
+ $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
+ LIBPATH=$$DIR/lib/$$($(HOSTCXX) -print-multi-os-directory); \
+ if [ -f $$LIBPATH/libqt-mt.so ]; then LIB=qt-mt; fi; \
+ echo "QTDIR=$$DIR" > $@; echo "QTLIBPATH=$$LIBPATH" >> $@; \
+ echo "QTLIB=$$LIB" >> $@; \
+ if [ ! -x $$DIR/bin/moc -a -x /usr/bin/moc ]; then \
+ echo "*"; \
+ echo "* Unable to find $$DIR/bin/moc, using /usr/bin/moc instead."; \
+ echo "*"; \
+ echo "MOC=/usr/bin/moc" >> $@; \
+ fi
+endif
+
+$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
+
+ifeq ($(gconf-target),1)
+-include $(obj)/.tmp_gtkcheck
+
+# GTK needs some extra effort, too...
+$(obj)/.tmp_gtkcheck:
+ @if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then \
+ if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then \
+ touch $@; \
+ else \
+ echo "*"; \
+ echo "* GTK+ is present but version >= 2.0.0 is required."; \
+ echo "*"; \
+ false; \
+ fi \
+ else \
+ echo "*"; \
+ echo "* Unable to find the GTK+ installation. Please make sure that"; \
+ echo "* the GTK+ 2.0 development package is correctly installed..."; \
+ echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \
+ echo "*"; \
+ false; \
+ fi
+endif
+
+$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
+
+$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
+
+$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
+
+$(obj)/gconf.o: $(obj)/lkc_defs.h
+
+$(obj)/%.moc: $(src)/%.h
+ $(MOC) -i $< -o $@
+
+$(obj)/lkc_defs.h: $(src)/lkc_proto.h
+ sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
+
+
+###
+# The following requires flex/bison
+# By default we use the _shipped versions, uncomment the following line if
+# you are modifying the flex/bison src.
+# LKC_GENPARSER := 1
+
+ifdef LKC_GENPARSER
+
+$(obj)/zconf.tab.c: $(obj)/zconf.y
+$(obj)/zconf.tab.h: $(obj)/zconf.tab.c
+
+%.tab.c: %.y
+ bison -t -d -v -b $* -p $(notdir $*) $<
+
+lex.%.c: %.l
+ flex -P$(notdir $*) -o$@ $<
+
+endif
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static void conf(struct menu *menu);
+static void check_conf(struct menu *menu);
+
+enum {
+ ask_all,
+ ask_new,
+ ask_silent,
+ set_default,
+ set_yes,
+ set_mod,
+ set_no,
+ set_random
+} input_mode = ask_all;
+char *defconfig_file;
+
+static int indent = 1;
+static int valid_stdin = 1;
+static int conf_cnt;
+static signed char line[128];
+static struct menu *rootEntry;
+
+static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
+
+static void strip(signed char *str)
+{
+ signed char *p = str;
+ int l;
+
+ while ((isspace(*p)))
+ p++;
+ l = strlen(p);
+ if (p != str)
+ memmove(str, p, l + 1);
+ if (!l)
+ return;
+ p = str + l - 1;
+ while ((isspace(*p)))
+ *p-- = 0;
+}
+
+static void check_stdin(void)
+{
+ if (!valid_stdin && input_mode == ask_silent) {
+ printf("aborted!\n\n");
+ printf("Console input/output is redirected. ");
+ printf("Run 'make oldconfig' to update configuration.\n\n");
+ exit(1);
+ }
+}
+
+static void conf_askvalue(struct symbol *sym, const char *def)
+{
+ enum symbol_type type = sym_get_type(sym);
+ tristate val;
+
+ if (!sym_has_value(sym))
+ printf("(NEW) ");
+
+ line[0] = '\n';
+ line[1] = 0;
+
+ if (!sym_is_changable(sym)) {
+ printf("%s\n", def);
+ line[0] = '\n';
+ line[1] = 0;
+ return;
+ }
+
+ switch (input_mode) {
+ case ask_new:
+ case ask_silent:
+ if (sym_has_value(sym)) {
+ printf("%s\n", def);
+ return;
+ }
+ check_stdin();
+ case ask_all:
+ fflush(stdout);
+ fgets(line, 128, stdin);
+ return;
+ case set_default:
+ printf("%s\n", def);
+ return;
+ default:
+ break;
+ }
+
+ switch (type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ printf("%s\n", def);
+ return;
+ default:
+ ;
+ }
+ switch (input_mode) {
+ case set_yes:
+ if (sym_tristate_within_range(sym, yes)) {
+ line[0] = 'y';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ case set_mod:
+ if (type == S_TRISTATE) {
+ if (sym_tristate_within_range(sym, mod)) {
+ line[0] = 'm';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ } else {
+ if (sym_tristate_within_range(sym, yes)) {
+ line[0] = 'y';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ }
+ case set_no:
+ if (sym_tristate_within_range(sym, no)) {
+ line[0] = 'n';
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ }
+ case set_random:
+ do {
+ val = (tristate)(random() % 3);
+ } while (!sym_tristate_within_range(sym, val));
+ switch (val) {
+ case no: line[0] = 'n'; break;
+ case mod: line[0] = 'm'; break;
+ case yes: line[0] = 'y'; break;
+ }
+ line[1] = '\n';
+ line[2] = 0;
+ break;
+ default:
+ break;
+ }
+ printf("%s", line);
+}
+
+int conf_string(struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ const char *def, *help;
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ printf("(%s) ", sym->name);
+ def = sym_get_string_value(sym);
+ if (sym_get_string_value(sym))
+ printf("[%s] ", def);
+ conf_askvalue(sym, def);
+ switch (line[0]) {
+ case '\n':
+ break;
+ case '?':
+ /* print help */
+ if (line[1] == '\n') {
+ help = nohelp_text;
+ if (menu->sym->help)
+ help = menu->sym->help;
+ printf("\n%s\n", menu->sym->help);
+ def = NULL;
+ break;
+ }
+ default:
+ line[strlen(line)-1] = 0;
+ def = line;
+ }
+ if (def && sym_set_string_value(sym, def))
+ return 0;
+ }
+}
+
+static int conf_sym(struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ int type;
+ tristate oldval, newval;
+ const char *help;
+
+ while (1) {
+ printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ if (sym->name)
+ printf("(%s) ", sym->name);
+ type = sym_get_type(sym);
+ putchar('[');
+ oldval = sym_get_tristate_value(sym);
+ switch (oldval) {
+ case no:
+ putchar('N');
+ break;
+ case mod:
+ putchar('M');
+ break;
+ case yes:
+ putchar('Y');
+ break;
+ }
+ if (oldval != no && sym_tristate_within_range(sym, no))
+ printf("/n");
+ if (oldval != mod && sym_tristate_within_range(sym, mod))
+ printf("/m");
+ if (oldval != yes && sym_tristate_within_range(sym, yes))
+ printf("/y");
+ if (sym->help)
+ printf("/?");
+ printf("] ");
+ conf_askvalue(sym, sym_get_string_value(sym));
+ strip(line);
+
+ switch (line[0]) {
+ case 'n':
+ case 'N':
+ newval = no;
+ if (!line[1] || !strcmp(&line[1], "o"))
+ break;
+ continue;
+ case 'm':
+ case 'M':
+ newval = mod;
+ if (!line[1])
+ break;
+ continue;
+ case 'y':
+ case 'Y':
+ newval = yes;
+ if (!line[1] || !strcmp(&line[1], "es"))
+ break;
+ continue;
+ case 0:
+ newval = oldval;
+ break;
+ case '?':
+ goto help;
+ default:
+ continue;
+ }
+ if (sym_set_tristate_value(sym, newval))
+ return 0;
+help:
+ help = nohelp_text;
+ if (sym->help)
+ help = sym->help;
+ printf("\n%s\n", help);
+ }
+}
+
+static int conf_choice(struct menu *menu)
+{
+ struct symbol *sym, *def_sym;
+ struct menu *child;
+ int type;
+ bool is_new;
+
+ sym = menu->sym;
+ type = sym_get_type(sym);
+ is_new = !sym_has_value(sym);
+ if (sym_is_changable(sym)) {
+ conf_sym(menu);
+ sym_calc_value(sym);
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ return 1;
+ case mod:
+ return 0;
+ case yes:
+ break;
+ }
+ } else {
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ return 1;
+ case mod:
+ printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ return 0;
+ case yes:
+ break;
+ }
+ }
+
+ while (1) {
+ int cnt, def;
+
+ printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ def_sym = sym_get_choice_value(sym);
+ cnt = def = 0;
+ line[0] = '0';
+ line[1] = 0;
+ for (child = menu->list; child; child = child->next) {
+ if (!menu_is_visible(child))
+ continue;
+ if (!child->sym) {
+ printf("%*c %s\n", indent, '*', menu_get_prompt(child));
+ continue;
+ }
+ cnt++;
+ if (child->sym == def_sym) {
+ def = cnt;
+ printf("%*c", indent, '>');
+ } else
+ printf("%*c", indent, ' ');
+ printf(" %d. %s", cnt, menu_get_prompt(child));
+ if (child->sym->name)
+ printf(" (%s)", child->sym->name);
+ if (!sym_has_value(child->sym))
+ printf(" (NEW)");
+ printf("\n");
+ }
+ printf("%*schoice", indent - 1, "");
+ if (cnt == 1) {
+ printf("[1]: 1\n");
+ goto conf_childs;
+ }
+ printf("[1-%d", cnt);
+ if (sym->help)
+ printf("?");
+ printf("]: ");
+ switch (input_mode) {
+ case ask_new:
+ case ask_silent:
+ if (!is_new) {
+ cnt = def;
+ printf("%d\n", cnt);
+ break;
+ }
+ check_stdin();
+ case ask_all:
+ fflush(stdout);
+ fgets(line, 128, stdin);
+ strip(line);
+ if (line[0] == '?') {
+ printf("\n%s\n", menu->sym->help ?
+ menu->sym->help : nohelp_text);
+ continue;
+ }
+ if (!line[0])
+ cnt = def;
+ else if (isdigit(line[0]))
+ cnt = atoi(line);
+ else
+ continue;
+ break;
+ case set_random:
+ def = (random() % cnt) + 1;
+ case set_default:
+ case set_yes:
+ case set_mod:
+ case set_no:
+ cnt = def;
+ printf("%d\n", cnt);
+ break;
+ }
+
+ conf_childs:
+ for (child = menu->list; child; child = child->next) {
+ if (!child->sym || !menu_is_visible(child))
+ continue;
+ if (!--cnt)
+ break;
+ }
+ if (!child)
+ continue;
+ if (line[strlen(line) - 1] == '?') {
+ printf("\n%s\n", child->sym->help ?
+ child->sym->help : nohelp_text);
+ continue;
+ }
+ sym_set_choice_value(sym, child->sym);
+ if (child->list) {
+ indent += 2;
+ conf(child->list);
+ indent -= 2;
+ }
+ return 1;
+ }
+}
+
+static void conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ if (prop) {
+ const char *prompt;
+
+ switch (prop->type) {
+ case P_MENU:
+ if (input_mode == ask_silent && rootEntry != menu) {
+ check_conf(menu);
+ return;
+ }
+ case P_COMMENT:
+ prompt = menu_get_prompt(menu);
+ if (prompt)
+ printf("%*c\n%*c %s\n%*c\n",
+ indent, '*',
+ indent, '*', prompt,
+ indent, '*');
+ default:
+ ;
+ }
+ }
+
+ if (!sym)
+ goto conf_childs;
+
+ if (sym_is_choice(sym)) {
+ conf_choice(menu);
+ if (sym->curr.tri != mod)
+ return;
+ goto conf_childs;
+ }
+
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ conf_string(menu);
+ break;
+ default:
+ conf_sym(menu);
+ break;
+ }
+
+conf_childs:
+ if (sym)
+ indent += 2;
+ for (child = menu->list; child; child = child->next)
+ conf(child);
+ if (sym)
+ indent -= 2;
+}
+
+static void check_conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct menu *child;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ if (sym) {
+ if (sym_is_changable(sym) && !sym_has_value(sym)) {
+ if (!conf_cnt++)
+ printf("*\n* Restart config...\n*\n");
+ rootEntry = menu_get_parent_menu(menu);
+ conf(rootEntry);
+ }
+ if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
+ return;
+ }
+
+ for (child = menu->list; child; child = child->next)
+ check_conf(child);
+}
+
+int main(int ac, char **av)
+{
+ int i = 1;
+ const char *name;
+ struct stat tmpstat;
+
+ if (ac > i && av[i][0] == '-') {
+ switch (av[i++][1]) {
+ case 'o':
+ input_mode = ask_new;
+ break;
+ case 's':
+ input_mode = ask_silent;
+ valid_stdin = isatty(0) && isatty(1) && isatty(2);
+ break;
+ case 'd':
+ input_mode = set_default;
+ break;
+ case 'D':
+ input_mode = set_default;
+ defconfig_file = av[i++];
+ if (!defconfig_file) {
+ printf("%s: No default config file specified\n",
+ av[0]);
+ exit(1);
+ }
+ break;
+ case 'n':
+ input_mode = set_no;
+ break;
+ case 'm':
+ input_mode = set_mod;
+ break;
+ case 'y':
+ input_mode = set_yes;
+ break;
+ case 'r':
+ input_mode = set_random;
+ srandom(time(NULL));
+ break;
+ case 'h':
+ case '?':
+ printf("%s [-o|-s] config\n", av[0]);
+ exit(0);
+ }
+ }
+ name = av[i];
+ if (!name) {
+ printf("%s: Kconfig file missing\n", av[0]);
+ }
+ conf_parse(name);
+ //zconfdump(stdout);
+ switch (input_mode) {
+ case set_default:
+ if (!defconfig_file)
+ defconfig_file = conf_get_default_confname();
+ if (conf_read(defconfig_file)) {
+ printf("***\n"
+ "*** Can't find default configuration \"%s\"!\n"
+ "***\n", defconfig_file);
+ exit(1);
+ }
+ break;
+ case ask_silent:
+ if (stat(".config", &tmpstat)) {
+ printf("***\n"
+ "*** You have not yet configured your kernel!\n"
+ "***\n"
+ "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
+ "*** \"make menuconfig\" or \"make xconfig\").\n"
+ "***\n");
+ exit(1);
+ }
+ case ask_all:
+ case ask_new:
+ conf_read(NULL);
+ break;
+ default:
+ break;
+ }
+
+ if (input_mode != ask_silent) {
+ rootEntry = &rootmenu;
+ conf(&rootmenu);
+ if (input_mode == ask_all) {
+ input_mode = ask_silent;
+ valid_stdin = 1;
+ }
+ }
+ do {
+ conf_cnt = 0;
+ check_conf(&rootmenu);
+ } while (conf_cnt);
+ if (conf_write(NULL)) {
+ fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n");
+ return 1;
+ }
+ return 0;
+}
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+const char conf_def_filename[] = ".config";
+
+const char conf_defname[] = "arch/$ARCH/defconfig";
+
+const char *conf_confnames[] = {
+ ".config",
+ "/lib/modules/$UNAME_RELEASE/.config",
+ "/etc/kernel-config",
+ "/boot/config-$UNAME_RELEASE",
+ conf_defname,
+ NULL,
+};
+
+static char *conf_expand_value(const signed char *in)
+{
+ struct symbol *sym;
+ const signed char *src;
+ static char res_value[SYMBOL_MAXLENGTH];
+ char *dst, name[SYMBOL_MAXLENGTH];
+
+ res_value[0] = 0;
+ dst = name;
+ while ((src = strchr(in, '$'))) {
+ strncat(res_value, in, src - in);
+ src++;
+ dst = name;
+ while (isalnum(*src) || *src == '_')
+ *dst++ = *src++;
+ *dst = 0;
+ sym = sym_lookup(name, 0);
+ sym_calc_value(sym);
+ strcat(res_value, sym_get_string_value(sym));
+ in = src;
+ }
+ strcat(res_value, in);
+
+ return res_value;
+}
+
+char *conf_get_default_confname(void)
+{
+ struct stat buf;
+ static char fullname[PATH_MAX+1];
+ char *env, *name;
+
+ name = conf_expand_value(conf_defname);
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ if (!stat(fullname, &buf))
+ return fullname;
+ }
+ return name;
+}
+
+int conf_read(const char *name)
+{
+ FILE *in = NULL;
+ char line[1024];
+ char *p, *p2;
+ int lineno = 0;
+ struct symbol *sym;
+ struct property *prop;
+ struct expr *e;
+ int i;
+
+ if (name) {
+ in = zconf_fopen(name);
+ } else {
+ const char **names = conf_confnames;
+ while ((name = *names++)) {
+ name = conf_expand_value(name);
+ in = zconf_fopen(name);
+ if (in) {
+ printf("#\n"
+ "# using defaults found in %s\n"
+ "#\n", name);
+ break;
+ }
+ }
+ }
+
+ if (!in)
+ return 1;
+
+ for_all_symbols(i, sym) {
+ sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
+ sym->flags &= ~SYMBOL_VALID;
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ if (sym->user.val)
+ free(sym->user.val);
+ default:
+ sym->user.val = NULL;
+ sym->user.tri = no;
+ }
+ }
+
+ while (fgets(line, sizeof(line), in)) {
+ lineno++;
+ sym = NULL;
+ switch (line[0]) {
+ case '#':
+ if (memcmp(line + 2, "CONFIG_", 7))
+ continue;
+ p = strchr(line + 9, ' ');
+ if (!p)
+ continue;
+ *p++ = 0;
+ if (strncmp(p, "is not set", 10))
+ continue;
+ sym = sym_find(line + 9);
+ if (!sym) {
+ fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
+ break;
+ }
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ sym->user.tri = no;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ default:
+ ;
+ }
+ break;
+ case 'C':
+ if (memcmp(line, "CONFIG_", 7))
+ continue;
+ p = strchr(line + 7, '=');
+ if (!p)
+ continue;
+ *p++ = 0;
+ p2 = strchr(p, '\n');
+ if (p2)
+ *p2 = 0;
+ sym = sym_find(line + 7);
+ if (!sym) {
+ fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
+ break;
+ }
+ switch (sym->type) {
+ case S_TRISTATE:
+ if (p[0] == 'm') {
+ sym->user.tri = mod;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ }
+ case S_BOOLEAN:
+ if (p[0] == 'y') {
+ sym->user.tri = yes;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ }
+ if (p[0] == 'n') {
+ sym->user.tri = no;
+ sym->flags &= ~SYMBOL_NEW;
+ break;
+ }
+ break;
+ case S_STRING:
+ if (*p++ != '"')
+ break;
+ for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+ if (*p2 == '"') {
+ *p2 = 0;
+ break;
+ }
+ memmove(p2, p2 + 1, strlen(p2));
+ }
+ if (!p2) {
+ fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
+ exit(1);
+ }
+ case S_INT:
+ case S_HEX:
+ if (sym_string_valid(sym, p)) {
+ sym->user.val = strdup(p);
+ sym->flags &= ~SYMBOL_NEW;
+ } else {
+ fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
+ exit(1);
+ }
+ break;
+ default:
+ ;
+ }
+ break;
+ case '\n':
+ break;
+ default:
+ continue;
+ }
+ if (sym && sym_is_choice_value(sym)) {
+ struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+ switch (sym->user.tri) {
+ case no:
+ break;
+ case mod:
+ if (cs->user.tri == yes)
+ /* warn? */;
+ break;
+ case yes:
+ if (cs->user.tri != no)
+ /* warn? */;
+ cs->user.val = sym;
+ break;
+ }
+ cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
+ cs->flags &= ~SYMBOL_NEW;
+ }
+ }
+ fclose(in);
+
+ if (modules_sym)
+ sym_calc_value(modules_sym);
+ for_all_symbols(i, sym) {
+ sym_calc_value(sym);
+ if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
+ if (sym->visible == no)
+ sym->flags |= SYMBOL_NEW;
+ switch (sym->type) {
+ case S_STRING:
+ case S_INT:
+ case S_HEX:
+ if (!sym_string_within_range(sym, sym->user.val))
+ sym->flags |= SYMBOL_NEW;
+ default:
+ break;
+ }
+ }
+ if (!sym_is_choice(sym))
+ continue;
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr)
+ if (e->right.sym->visible != no)
+ sym->flags |= e->right.sym->flags & SYMBOL_NEW;
+ }
+
+ sym_change_count = 1;
+
+ return 0;
+}
+
+int conf_write(const char *name)
+{
+ FILE *out, *out_h;
+ struct symbol *sym;
+ struct menu *menu;
+ const char *basename;
+ char dirname[128], tmpname[128], newname[128];
+ int type, l;
+ const char *str;
+ time_t now;
+ int use_timestamp = 1;
+ char *env;
+
+ dirname[0] = 0;
+ if (name && name[0]) {
+ struct stat st;
+ char *slash;
+
+ if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
+ strcpy(dirname, name);
+ strcat(dirname, "/");
+ basename = conf_def_filename;
+ } else if ((slash = strrchr(name, '/'))) {
+ int size = slash - name + 1;
+ memcpy(dirname, name, size);
+ dirname[size] = 0;
+ if (slash[1])
+ basename = slash + 1;
+ else
+ basename = conf_def_filename;
+ } else
+ basename = name;
+ } else
+ basename = conf_def_filename;
+
+ sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
+ out = fopen(newname, "w");
+ if (!out)
+ return 1;
+ out_h = NULL;
+ if (!name) {
+ out_h = fopen(".tmpconfig.h", "w");
+ if (!out_h)
+ return 1;
+ }
+ sym = sym_lookup("KERNELRELEASE", 0);
+ sym_calc_value(sym);
+ time(&now);
+ env = getenv("KCONFIG_NOTIMESTAMP");
+ if (env && *env)
+ use_timestamp = 0;
+
+ fprintf(out, "#\n"
+ "# Automatically generated make config: don't edit\n"
+ "# Linux kernel version: %s\n"
+ "%s%s"
+ "#\n",
+ sym_get_string_value(sym),
+ use_timestamp ? "# " : "",
+ use_timestamp ? ctime(&now) : "");
+ if (out_h)
+ fprintf(out_h, "/*\n"
+ " * Automatically generated C config: don't edit\n"
+ " * Linux kernel version: %s\n"
+ "%s%s"
+ " */\n"
+ "#define AUTOCONF_INCLUDED\n",
+ sym_get_string_value(sym),
+ use_timestamp ? " * " : "",
+ use_timestamp ? ctime(&now) : "");
+
+ if (!sym_change_count)
+ sym_clear_all_valid();
+
+ menu = rootmenu.list;
+ while (menu) {
+ sym = menu->sym;
+ if (!sym) {
+ if (!menu_is_visible(menu))
+ goto next;
+ str = menu_get_prompt(menu);
+ fprintf(out, "\n"
+ "#\n"
+ "# %s\n"
+ "#\n", str);
+ if (out_h)
+ fprintf(out_h, "\n"
+ "/*\n"
+ " * %s\n"
+ " */\n", str);
+ } else if (!(sym->flags & SYMBOL_CHOICE)) {
+ sym_calc_value(sym);
+ if (!(sym->flags & SYMBOL_WRITE))
+ goto next;
+ sym->flags &= ~SYMBOL_WRITE;
+ type = sym->type;
+ if (type == S_TRISTATE) {
+ sym_calc_value(modules_sym);
+ if (modules_sym->curr.tri == no)
+ type = S_BOOLEAN;
+ }
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (sym_get_tristate_value(sym)) {
+ case no:
+ fprintf(out, "# CONFIG_%s is not set\n", sym->name);
+ if (out_h)
+ fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
+ break;
+ case mod:
+ fprintf(out, "CONFIG_%s=m\n", sym->name);
+ if (out_h)
+ fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
+ break;
+ case yes:
+ fprintf(out, "CONFIG_%s=y\n", sym->name);
+ if (out_h)
+ fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
+ break;
+ }
+ break;
+ case S_STRING:
+ // fix me
+ str = sym_get_string_value(sym);
+ fprintf(out, "CONFIG_%s=\"", sym->name);
+ if (out_h)
+ fprintf(out_h, "#define CONFIG_%s \"", sym->name);
+ do {
+ l = strcspn(str, "\"\\");
+ if (l) {
+ fwrite(str, l, 1, out);
+ if (out_h)
+ fwrite(str, l, 1, out_h);
+ }
+ str += l;
+ while (*str == '\\' || *str == '"') {
+ fprintf(out, "\\%c", *str);
+ if (out_h)
+ fprintf(out_h, "\\%c", *str);
+ str++;
+ }
+ } while (*str);
+ fputs("\"\n", out);
+ if (out_h)
+ fputs("\"\n", out_h);
+ break;
+ case S_HEX:
+ str = sym_get_string_value(sym);
+ if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
+ fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+ if (out_h)
+ fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
+ break;
+ }
+ case S_INT:
+ str = sym_get_string_value(sym);
+ fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+ if (out_h)
+ fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
+ break;
+ }
+ }
+
+ next:
+ if (menu->list) {
+ menu = menu->list;
+ continue;
+ }
+ if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+ fclose(out);
+ if (out_h) {
+ fclose(out_h);
+ rename(".tmpconfig.h", "include/linux/autoconf.h");
+ file_write_dep(NULL);
+ }
+ if (!name || basename != conf_def_filename) {
+ if (!name)
+ name = conf_def_filename;
+ sprintf(tmpname, "%s.old", name);
+ rename(name, tmpname);
+ }
+ sprintf(tmpname, "%s%s", dirname, basename);
+ if (rename(newname, tmpname))
+ return 1;
+
+ sym_change_count = 0;
+
+ return 0;
+}
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define DEBUG_EXPR 0
+
+struct expr *expr_alloc_symbol(struct symbol *sym)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = E_SYMBOL;
+ e->left.sym = sym;
+ return e;
+}
+
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = type;
+ e->left.expr = ce;
+ return e;
+}
+
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = type;
+ e->left.expr = e1;
+ e->right.expr = e2;
+ return e;
+}
+
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
+{
+ struct expr *e = malloc(sizeof(*e));
+ memset(e, 0, sizeof(*e));
+ e->type = type;
+ e->left.sym = s1;
+ e->right.sym = s2;
+ return e;
+}
+
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
+{
+ if (!e1)
+ return e2;
+ return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
+}
+
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
+{
+ if (!e1)
+ return e2;
+ return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
+}
+
+struct expr *expr_copy(struct expr *org)
+{
+ struct expr *e;
+
+ if (!org)
+ return NULL;
+
+ e = malloc(sizeof(*org));
+ memcpy(e, org, sizeof(*org));
+ switch (org->type) {
+ case E_SYMBOL:
+ e->left = org->left;
+ break;
+ case E_NOT:
+ e->left.expr = expr_copy(org->left.expr);
+ break;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ e->left.sym = org->left.sym;
+ e->right.sym = org->right.sym;
+ break;
+ case E_AND:
+ case E_OR:
+ case E_CHOICE:
+ e->left.expr = expr_copy(org->left.expr);
+ e->right.expr = expr_copy(org->right.expr);
+ break;
+ default:
+ printf("can't copy type %d\n", e->type);
+ free(e);
+ e = NULL;
+ break;
+ }
+
+ return e;
+}
+
+void expr_free(struct expr *e)
+{
+ if (!e)
+ return;
+
+ switch (e->type) {
+ case E_SYMBOL:
+ break;
+ case E_NOT:
+ expr_free(e->left.expr);
+ return;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ break;
+ case E_OR:
+ case E_AND:
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ break;
+ default:
+ printf("how to free type %d?\n", e->type);
+ break;
+ }
+ free(e);
+}
+
+static int trans_count;
+
+#define e1 (*ep1)
+#define e2 (*ep2)
+
+static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+ if (e1->type == type) {
+ __expr_eliminate_eq(type, &e1->left.expr, &e2);
+ __expr_eliminate_eq(type, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ __expr_eliminate_eq(type, &e1, &e2->left.expr);
+ __expr_eliminate_eq(type, &e1, &e2->right.expr);
+ return;
+ }
+ if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+ e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
+ return;
+ if (!expr_eq(e1, e2))
+ return;
+ trans_count++;
+ expr_free(e1); expr_free(e2);
+ switch (type) {
+ case E_OR:
+ e1 = expr_alloc_symbol(&symbol_no);
+ e2 = expr_alloc_symbol(&symbol_no);
+ break;
+ case E_AND:
+ e1 = expr_alloc_symbol(&symbol_yes);
+ e2 = expr_alloc_symbol(&symbol_yes);
+ break;
+ default:
+ ;
+ }
+}
+
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
+{
+ if (!e1 || !e2)
+ return;
+ switch (e1->type) {
+ case E_OR:
+ case E_AND:
+ __expr_eliminate_eq(e1->type, ep1, ep2);
+ default:
+ ;
+ }
+ if (e1->type != e2->type) switch (e2->type) {
+ case E_OR:
+ case E_AND:
+ __expr_eliminate_eq(e2->type, ep1, ep2);
+ default:
+ ;
+ }
+ e1 = expr_eliminate_yn(e1);
+ e2 = expr_eliminate_yn(e2);
+}
+
+#undef e1
+#undef e2
+
+int expr_eq(struct expr *e1, struct expr *e2)
+{
+ int res, old_count;
+
+ if (e1->type != e2->type)
+ return 0;
+ switch (e1->type) {
+ case E_EQUAL:
+ case E_UNEQUAL:
+ return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
+ case E_SYMBOL:
+ return e1->left.sym == e2->left.sym;
+ case E_NOT:
+ return expr_eq(e1->left.expr, e2->left.expr);
+ case E_AND:
+ case E_OR:
+ e1 = expr_copy(e1);
+ e2 = expr_copy(e2);
+ old_count = trans_count;
+ expr_eliminate_eq(&e1, &e2);
+ res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+ e1->left.sym == e2->left.sym);
+ expr_free(e1);
+ expr_free(e2);
+ trans_count = old_count;
+ return res;
+ case E_CHOICE:
+ case E_RANGE:
+ case E_NONE:
+ /* panic */;
+ }
+
+ if (DEBUG_EXPR) {
+ expr_fprint(e1, stdout);
+ printf(" = ");
+ expr_fprint(e2, stdout);
+ printf(" ?\n");
+ }
+
+ return 0;
+}
+
+struct expr *expr_eliminate_yn(struct expr *e)
+{
+ struct expr *tmp;
+
+ if (e) switch (e->type) {
+ case E_AND:
+ e->left.expr = expr_eliminate_yn(e->left.expr);
+ e->right.expr = expr_eliminate_yn(e->right.expr);
+ if (e->left.expr->type == E_SYMBOL) {
+ if (e->left.expr->left.sym == &symbol_no) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ e->right.expr = NULL;
+ return e;
+ } else if (e->left.expr->left.sym == &symbol_yes) {
+ free(e->left.expr);
+ tmp = e->right.expr;
+ *e = *(e->right.expr);
+ free(tmp);
+ return e;
+ }
+ }
+ if (e->right.expr->type == E_SYMBOL) {
+ if (e->right.expr->left.sym == &symbol_no) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ e->right.expr = NULL;
+ return e;
+ } else if (e->right.expr->left.sym == &symbol_yes) {
+ free(e->right.expr);
+ tmp = e->left.expr;
+ *e = *(e->left.expr);
+ free(tmp);
+ return e;
+ }
+ }
+ break;
+ case E_OR:
+ e->left.expr = expr_eliminate_yn(e->left.expr);
+ e->right.expr = expr_eliminate_yn(e->right.expr);
+ if (e->left.expr->type == E_SYMBOL) {
+ if (e->left.expr->left.sym == &symbol_no) {
+ free(e->left.expr);
+ tmp = e->right.expr;
+ *e = *(e->right.expr);
+ free(tmp);
+ return e;
+ } else if (e->left.expr->left.sym == &symbol_yes) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ e->right.expr = NULL;
+ return e;
+ }
+ }
+ if (e->right.expr->type == E_SYMBOL) {
+ if (e->right.expr->left.sym == &symbol_no) {
+ free(e->right.expr);
+ tmp = e->left.expr;
+ *e = *(e->left.expr);
+ free(tmp);
+ return e;
+ } else if (e->right.expr->left.sym == &symbol_yes) {
+ expr_free(e->left.expr);
+ expr_free(e->right.expr);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ e->right.expr = NULL;
+ return e;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ return e;
+}
+
+/*
+ * bool FOO!=n => FOO
+ */
+struct expr *expr_trans_bool(struct expr *e)
+{
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_AND:
+ case E_OR:
+ case E_NOT:
+ e->left.expr = expr_trans_bool(e->left.expr);
+ e->right.expr = expr_trans_bool(e->right.expr);
+ break;
+ case E_UNEQUAL:
+ // FOO!=n -> FOO
+ if (e->left.sym->type == S_TRISTATE) {
+ if (e->right.sym == &symbol_no) {
+ e->type = E_SYMBOL;
+ e->right.sym = NULL;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ return e;
+}
+
+/*
+ * e1 || e2 -> ?
+ */
+struct expr *expr_join_or(struct expr *e1, struct expr *e2)
+{
+ struct expr *tmp;
+ struct symbol *sym1, *sym2;
+
+ if (expr_eq(e1, e2))
+ return expr_copy(e1);
+ if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+ return NULL;
+ if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+ return NULL;
+ if (e1->type == E_NOT) {
+ tmp = e1->left.expr;
+ if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+ return NULL;
+ sym1 = tmp->left.sym;
+ } else
+ sym1 = e1->left.sym;
+ if (e2->type == E_NOT) {
+ if (e2->left.expr->type != E_SYMBOL)
+ return NULL;
+ sym2 = e2->left.expr->left.sym;
+ } else
+ sym2 = e2->left.sym;
+ if (sym1 != sym2)
+ return NULL;
+ if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+ return NULL;
+ if (sym1->type == S_TRISTATE) {
+ if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+ (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
+ // (a='y') || (a='m') -> (a!='n')
+ return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
+ }
+ if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
+ // (a='y') || (a='n') -> (a!='m')
+ return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
+ }
+ if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+ ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
+ // (a='m') || (a='n') -> (a!='y')
+ return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
+ }
+ }
+ if (sym1->type == S_BOOLEAN && sym1 == sym2) {
+ if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
+ (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
+ return expr_alloc_symbol(&symbol_yes);
+ }
+
+ if (DEBUG_EXPR) {
+ printf("optimize (");
+ expr_fprint(e1, stdout);
+ printf(") || (");
+ expr_fprint(e2, stdout);
+ printf(")?\n");
+ }
+ return NULL;
+}
+
+struct expr *expr_join_and(struct expr *e1, struct expr *e2)
+{
+ struct expr *tmp;
+ struct symbol *sym1, *sym2;
+
+ if (expr_eq(e1, e2))
+ return expr_copy(e1);
+ if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+ return NULL;
+ if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+ return NULL;
+ if (e1->type == E_NOT) {
+ tmp = e1->left.expr;
+ if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+ return NULL;
+ sym1 = tmp->left.sym;
+ } else
+ sym1 = e1->left.sym;
+ if (e2->type == E_NOT) {
+ if (e2->left.expr->type != E_SYMBOL)
+ return NULL;
+ sym2 = e2->left.expr->left.sym;
+ } else
+ sym2 = e2->left.sym;
+ if (sym1 != sym2)
+ return NULL;
+ if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+ return NULL;
+
+ if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
+ (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
+ // (a) && (a='y') -> (a='y')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+ if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
+ (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
+ // (a) && (a!='n') -> (a)
+ return expr_alloc_symbol(sym1);
+
+ if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
+ (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
+ // (a) && (a!='m') -> (a='y')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+ if (sym1->type == S_TRISTATE) {
+ if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
+ // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+ sym2 = e1->right.sym;
+ if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+ return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+ : expr_alloc_symbol(&symbol_no);
+ }
+ if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
+ // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+ sym2 = e2->right.sym;
+ if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+ return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+ : expr_alloc_symbol(&symbol_no);
+ }
+ if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
+ // (a!='y') && (a!='n') -> (a='m')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
+
+ if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+ ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+ (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
+ // (a!='y') && (a!='m') -> (a='n')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
+
+ if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+ ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+ (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
+ // (a!='m') && (a!='n') -> (a='m')
+ return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+ if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
+ (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
+ (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
+ (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
+ return NULL;
+ }
+
+ if (DEBUG_EXPR) {
+ printf("optimize (");
+ expr_fprint(e1, stdout);
+ printf(") && (");
+ expr_fprint(e2, stdout);
+ printf(")?\n");
+ }
+ return NULL;
+}
+
+static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+ struct expr *tmp;
+
+ if (e1->type == type) {
+ expr_eliminate_dups1(type, &e1->left.expr, &e2);
+ expr_eliminate_dups1(type, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ expr_eliminate_dups1(type, &e1, &e2->left.expr);
+ expr_eliminate_dups1(type, &e1, &e2->right.expr);
+ return;
+ }
+ if (e1 == e2)
+ return;
+
+ switch (e1->type) {
+ case E_OR: case E_AND:
+ expr_eliminate_dups1(e1->type, &e1, &e1);
+ default:
+ ;
+ }
+
+ switch (type) {
+ case E_OR:
+ tmp = expr_join_or(e1, e2);
+ if (tmp) {
+ expr_free(e1); expr_free(e2);
+ e1 = expr_alloc_symbol(&symbol_no);
+ e2 = tmp;
+ trans_count++;
+ }
+ break;
+ case E_AND:
+ tmp = expr_join_and(e1, e2);
+ if (tmp) {
+ expr_free(e1); expr_free(e2);
+ e1 = expr_alloc_symbol(&symbol_yes);
+ e2 = tmp;
+ trans_count++;
+ }
+ break;
+ default:
+ ;
+ }
+#undef e1
+#undef e2
+}
+
+static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+ struct expr *tmp, *tmp1, *tmp2;
+
+ if (e1->type == type) {
+ expr_eliminate_dups2(type, &e1->left.expr, &e2);
+ expr_eliminate_dups2(type, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ expr_eliminate_dups2(type, &e1, &e2->left.expr);
+ expr_eliminate_dups2(type, &e1, &e2->right.expr);
+ }
+ if (e1 == e2)
+ return;
+
+ switch (e1->type) {
+ case E_OR:
+ expr_eliminate_dups2(e1->type, &e1, &e1);
+ // (FOO || BAR) && (!FOO && !BAR) -> n
+ tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+ tmp2 = expr_copy(e2);
+ tmp = expr_extract_eq_and(&tmp1, &tmp2);
+ if (expr_is_yes(tmp1)) {
+ expr_free(e1);
+ e1 = expr_alloc_symbol(&symbol_no);
+ trans_count++;
+ }
+ expr_free(tmp2);
+ expr_free(tmp1);
+ expr_free(tmp);
+ break;
+ case E_AND:
+ expr_eliminate_dups2(e1->type, &e1, &e1);
+ // (FOO && BAR) || (!FOO || !BAR) -> y
+ tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+ tmp2 = expr_copy(e2);
+ tmp = expr_extract_eq_or(&tmp1, &tmp2);
+ if (expr_is_no(tmp1)) {
+ expr_free(e1);
+ e1 = expr_alloc_symbol(&symbol_yes);
+ trans_count++;
+ }
+ expr_free(tmp2);
+ expr_free(tmp1);
+ expr_free(tmp);
+ break;
+ default:
+ ;
+ }
+#undef e1
+#undef e2
+}
+
+struct expr *expr_eliminate_dups(struct expr *e)
+{
+ int oldcount;
+ if (!e)
+ return e;
+
+ oldcount = trans_count;
+ while (1) {
+ trans_count = 0;
+ switch (e->type) {
+ case E_OR: case E_AND:
+ expr_eliminate_dups1(e->type, &e, &e);
+ expr_eliminate_dups2(e->type, &e, &e);
+ default:
+ ;
+ }
+ if (!trans_count)
+ break;
+ e = expr_eliminate_yn(e);
+ }
+ trans_count = oldcount;
+ return e;
+}
+
+struct expr *expr_transform(struct expr *e)
+{
+ struct expr *tmp;
+
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_EQUAL:
+ case E_UNEQUAL:
+ case E_SYMBOL:
+ case E_CHOICE:
+ break;
+ default:
+ e->left.expr = expr_transform(e->left.expr);
+ e->right.expr = expr_transform(e->right.expr);
+ }
+
+ switch (e->type) {
+ case E_EQUAL:
+ if (e->left.sym->type != S_BOOLEAN)
+ break;
+ if (e->right.sym == &symbol_no) {
+ e->type = E_NOT;
+ e->left.expr = expr_alloc_symbol(e->left.sym);
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_mod) {
+ printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_yes) {
+ e->type = E_SYMBOL;
+ e->right.sym = NULL;
+ break;
+ }
+ break;
+ case E_UNEQUAL:
+ if (e->left.sym->type != S_BOOLEAN)
+ break;
+ if (e->right.sym == &symbol_no) {
+ e->type = E_SYMBOL;
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_mod) {
+ printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ e->right.sym = NULL;
+ break;
+ }
+ if (e->right.sym == &symbol_yes) {
+ e->type = E_NOT;
+ e->left.expr = expr_alloc_symbol(e->left.sym);
+ e->right.sym = NULL;
+ break;
+ }
+ break;
+ case E_NOT:
+ switch (e->left.expr->type) {
+ case E_NOT:
+ // !!a -> a
+ tmp = e->left.expr->left.expr;
+ free(e->left.expr);
+ free(e);
+ e = tmp;
+ e = expr_transform(e);
+ break;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ // !a='x' -> a!='x'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
+ break;
+ case E_OR:
+ // !(a || b) -> !a && !b
+ tmp = e->left.expr;
+ e->type = E_AND;
+ e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+ tmp->type = E_NOT;
+ tmp->right.expr = NULL;
+ e = expr_transform(e);
+ break;
+ case E_AND:
+ // !(a && b) -> !a || !b
+ tmp = e->left.expr;
+ e->type = E_OR;
+ e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+ tmp->type = E_NOT;
+ tmp->right.expr = NULL;
+ e = expr_transform(e);
+ break;
+ case E_SYMBOL:
+ if (e->left.expr->left.sym == &symbol_yes) {
+ // !'y' -> 'n'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_no;
+ break;
+ }
+ if (e->left.expr->left.sym == &symbol_mod) {
+ // !'m' -> 'm'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_mod;
+ break;
+ }
+ if (e->left.expr->left.sym == &symbol_no) {
+ // !'n' -> 'y'
+ tmp = e->left.expr;
+ free(e);
+ e = tmp;
+ e->type = E_SYMBOL;
+ e->left.sym = &symbol_yes;
+ break;
+ }
+ break;
+ default:
+ ;
+ }
+ break;
+ default:
+ ;
+ }
+ return e;
+}
+
+int expr_contains_symbol(struct expr *dep, struct symbol *sym)
+{
+ if (!dep)
+ return 0;
+
+ switch (dep->type) {
+ case E_AND:
+ case E_OR:
+ return expr_contains_symbol(dep->left.expr, sym) ||
+ expr_contains_symbol(dep->right.expr, sym);
+ case E_SYMBOL:
+ return dep->left.sym == sym;
+ case E_EQUAL:
+ case E_UNEQUAL:
+ return dep->left.sym == sym ||
+ dep->right.sym == sym;
+ case E_NOT:
+ return expr_contains_symbol(dep->left.expr, sym);
+ default:
+ ;
+ }
+ return 0;
+}
+
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
+{
+ if (!dep)
+ return false;
+
+ switch (dep->type) {
+ case E_AND:
+ return expr_depends_symbol(dep->left.expr, sym) ||
+ expr_depends_symbol(dep->right.expr, sym);
+ case E_SYMBOL:
+ return dep->left.sym == sym;
+ case E_EQUAL:
+ if (dep->left.sym == sym) {
+ if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
+ return true;
+ }
+ break;
+ case E_UNEQUAL:
+ if (dep->left.sym == sym) {
+ if (dep->right.sym == &symbol_no)
+ return true;
+ }
+ break;
+ default:
+ ;
+ }
+ return false;
+}
+
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
+{
+ struct expr *tmp = NULL;
+ expr_extract_eq(E_AND, &tmp, ep1, ep2);
+ if (tmp) {
+ *ep1 = expr_eliminate_yn(*ep1);
+ *ep2 = expr_eliminate_yn(*ep2);
+ }
+ return tmp;
+}
+
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
+{
+ struct expr *tmp = NULL;
+ expr_extract_eq(E_OR, &tmp, ep1, ep2);
+ if (tmp) {
+ *ep1 = expr_eliminate_yn(*ep1);
+ *ep2 = expr_eliminate_yn(*ep2);
+ }
+ return tmp;
+}
+
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+ if (e1->type == type) {
+ expr_extract_eq(type, ep, &e1->left.expr, &e2);
+ expr_extract_eq(type, ep, &e1->right.expr, &e2);
+ return;
+ }
+ if (e2->type == type) {
+ expr_extract_eq(type, ep, ep1, &e2->left.expr);
+ expr_extract_eq(type, ep, ep1, &e2->right.expr);
+ return;
+ }
+ if (expr_eq(e1, e2)) {
+ *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
+ expr_free(e2);
+ if (type == E_AND) {
+ e1 = expr_alloc_symbol(&symbol_yes);
+ e2 = expr_alloc_symbol(&symbol_yes);
+ } else if (type == E_OR) {
+ e1 = expr_alloc_symbol(&symbol_no);
+ e2 = expr_alloc_symbol(&symbol_no);
+ }
+ }
+#undef e1
+#undef e2
+}
+
+struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
+{
+ struct expr *e1, *e2;
+
+ if (!e) {
+ e = expr_alloc_symbol(sym);
+ if (type == E_UNEQUAL)
+ e = expr_alloc_one(E_NOT, e);
+ return e;
+ }
+ switch (e->type) {
+ case E_AND:
+ e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+ e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+ if (sym == &symbol_yes)
+ e = expr_alloc_two(E_AND, e1, e2);
+ if (sym == &symbol_no)
+ e = expr_alloc_two(E_OR, e1, e2);
+ if (type == E_UNEQUAL)
+ e = expr_alloc_one(E_NOT, e);
+ return e;
+ case E_OR:
+ e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+ e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+ if (sym == &symbol_yes)
+ e = expr_alloc_two(E_OR, e1, e2);
+ if (sym == &symbol_no)
+ e = expr_alloc_two(E_AND, e1, e2);
+ if (type == E_UNEQUAL)
+ e = expr_alloc_one(E_NOT, e);
+ return e;
+ case E_NOT:
+ return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
+ case E_UNEQUAL:
+ case E_EQUAL:
+ if (type == E_EQUAL) {
+ if (sym == &symbol_yes)
+ return expr_copy(e);
+ if (sym == &symbol_mod)
+ return expr_alloc_symbol(&symbol_no);
+ if (sym == &symbol_no)
+ return expr_alloc_one(E_NOT, expr_copy(e));
+ } else {
+ if (sym == &symbol_yes)
+ return expr_alloc_one(E_NOT, expr_copy(e));
+ if (sym == &symbol_mod)
+ return expr_alloc_symbol(&symbol_yes);
+ if (sym == &symbol_no)
+ return expr_copy(e);
+ }
+ break;
+ case E_SYMBOL:
+ return expr_alloc_comp(type, e->left.sym, sym);
+ case E_CHOICE:
+ case E_RANGE:
+ case E_NONE:
+ /* panic */;
+ }
+ return NULL;
+}
+
+tristate expr_calc_value(struct expr *e)
+{
+ tristate val1, val2;
+ const char *str1, *str2;
+
+ if (!e)
+ return yes;
+
+ switch (e->type) {
+ case E_SYMBOL:
+ sym_calc_value(e->left.sym);
+ return e->left.sym->curr.tri;
+ case E_AND:
+ val1 = expr_calc_value(e->left.expr);
+ val2 = expr_calc_value(e->right.expr);
+ return E_AND(val1, val2);
+ case E_OR:
+ val1 = expr_calc_value(e->left.expr);
+ val2 = expr_calc_value(e->right.expr);
+ return E_OR(val1, val2);
+ case E_NOT:
+ val1 = expr_calc_value(e->left.expr);
+ return E_NOT(val1);
+ case E_EQUAL:
+ sym_calc_value(e->left.sym);
+ sym_calc_value(e->right.sym);
+ str1 = sym_get_string_value(e->left.sym);
+ str2 = sym_get_string_value(e->right.sym);
+ return !strcmp(str1, str2) ? yes : no;
+ case E_UNEQUAL:
+ sym_calc_value(e->left.sym);
+ sym_calc_value(e->right.sym);
+ str1 = sym_get_string_value(e->left.sym);
+ str2 = sym_get_string_value(e->right.sym);
+ return !strcmp(str1, str2) ? no : yes;
+ default:
+ printf("expr_calc_value: %d?\n", e->type);
+ return no;
+ }
+}
+
+int expr_compare_type(enum expr_type t1, enum expr_type t2)
+{
+#if 0
+ return 1;
+#else
+ if (t1 == t2)
+ return 0;
+ switch (t1) {
+ case E_EQUAL:
+ case E_UNEQUAL:
+ if (t2 == E_NOT)
+ return 1;
+ case E_NOT:
+ if (t2 == E_AND)
+ return 1;
+ case E_AND:
+ if (t2 == E_OR)
+ return 1;
+ case E_OR:
+ if (t2 == E_CHOICE)
+ return 1;
+ case E_CHOICE:
+ if (t2 == 0)
+ return 1;
+ default:
+ return -1;
+ }
+ printf("[%dgt%d?]", t1, t2);
+ return 0;
+#endif
+}
+
+void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
+{
+ if (!e) {
+ fn(data, "y");
+ return;
+ }
+
+ if (expr_compare_type(prevtoken, e->type) > 0)
+ fn(data, "(");
+ switch (e->type) {
+ case E_SYMBOL:
+ if (e->left.sym->name)
+ fn(data, e->left.sym->name);
+ else
+ fn(data, "<choice>");
+ break;
+ case E_NOT:
+ fn(data, "!");
+ expr_print(e->left.expr, fn, data, E_NOT);
+ break;
+ case E_EQUAL:
+ fn(data, e->left.sym->name);
+ fn(data, "=");
+ fn(data, e->right.sym->name);
+ break;
+ case E_UNEQUAL:
+ fn(data, e->left.sym->name);
+ fn(data, "!=");
+ fn(data, e->right.sym->name);
+ break;
+ case E_OR:
+ expr_print(e->left.expr, fn, data, E_OR);
+ fn(data, " || ");
+ expr_print(e->right.expr, fn, data, E_OR);
+ break;
+ case E_AND:
+ expr_print(e->left.expr, fn, data, E_AND);
+ fn(data, " && ");
+ expr_print(e->right.expr, fn, data, E_AND);
+ break;
+ case E_CHOICE:
+ fn(data, e->right.sym->name);
+ if (e->left.expr) {
+ fn(data, " ^ ");
+ expr_print(e->left.expr, fn, data, E_CHOICE);
+ }
+ break;
+ case E_RANGE:
+ fn(data, "[");
+ fn(data, e->left.sym->name);
+ fn(data, " ");
+ fn(data, e->right.sym->name);
+ fn(data, "]");
+ break;
+ default:
+ {
+ char buf[32];
+ sprintf(buf, "<unknown type %d>", e->type);
+ fn(data, buf);
+ break;
+ }
+ }
+ if (expr_compare_type(prevtoken, e->type) > 0)
+ fn(data, ")");
+}
+
+static void expr_print_file_helper(void *data, const char *str)
+{
+ fwrite(str, strlen(str), 1, data);
+}
+
+void expr_fprint(struct expr *e, FILE *out)
+{
+ expr_print(e, expr_print_file_helper, out, E_NONE);
+}
+
+static void expr_print_gstr_helper(void *data, const char *str)
+{
+ str_append((struct gstr*)data, str);
+}
+
+void expr_gstr_print(struct expr *e, struct gstr *gs)
+{
+ expr_print(e, expr_print_gstr_helper, gs, E_NONE);
+}
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#ifndef EXPR_H
+#define EXPR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+struct file {
+ struct file *next;
+ struct file *parent;
+ char *name;
+ int lineno;
+ int flags;
+};
+
+#define FILE_BUSY 0x0001
+#define FILE_SCANNED 0x0002
+#define FILE_PRINTED 0x0004
+
+typedef enum tristate {
+ no, mod, yes
+} tristate;
+
+enum expr_type {
+ E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+};
+
+union expr_data {
+ struct expr *expr;
+ struct symbol *sym;
+};
+
+struct expr {
+ enum expr_type type;
+ union expr_data left, right;
+};
+
+#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
+#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
+#define E_NOT(dep) (2-(dep))
+
+struct expr_value {
+ struct expr *expr;
+ tristate tri;
+};
+
+struct symbol_value {
+ void *val;
+ tristate tri;
+};
+
+enum symbol_type {
+ S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+};
+
+struct symbol {
+ struct symbol *next;
+ char *name;
+ char *help;
+ enum symbol_type type;
+ struct symbol_value curr, user;
+ tristate visible;
+ int flags;
+ struct property *prop;
+ struct expr *dep, *dep2;
+ struct expr_value rev_dep;
+};
+
+#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)
+
+#define SYMBOL_YES 0x0001
+#define SYMBOL_MOD 0x0002
+#define SYMBOL_NO 0x0004
+#define SYMBOL_CONST 0x0007
+#define SYMBOL_CHECK 0x0008
+#define SYMBOL_CHOICE 0x0010
+#define SYMBOL_CHOICEVAL 0x0020
+#define SYMBOL_PRINTED 0x0040
+#define SYMBOL_VALID 0x0080
+#define SYMBOL_OPTIONAL 0x0100
+#define SYMBOL_WRITE 0x0200
+#define SYMBOL_CHANGED 0x0400
+#define SYMBOL_NEW 0x0800
+#define SYMBOL_AUTO 0x1000
+#define SYMBOL_CHECKED 0x2000
+#define SYMBOL_CHECK_DONE 0x4000
+#define SYMBOL_WARNED 0x8000
+
+#define SYMBOL_MAXLENGTH 256
+#define SYMBOL_HASHSIZE 257
+#define SYMBOL_HASHMASK 0xff
+
+enum prop_type {
+ P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+};
+
+struct property {
+ struct property *next;
+ struct symbol *sym;
+ enum prop_type type;
+ const char *text;
+ struct expr_value visible;
+ struct expr *expr;
+ struct menu *menu;
+ struct file *file;
+ int lineno;
+};
+
+#define for_all_properties(sym, st, tok) \
+ for (st = sym->prop; st; st = st->next) \
+ if (st->type == (tok))
+#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
+#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
+#define for_all_prompts(sym, st) \
+ for (st = sym->prop; st; st = st->next) \
+ if (st->text)
+
+struct menu {
+ struct menu *next;
+ struct menu *parent;
+ struct menu *list;
+ struct symbol *sym;
+ struct property *prompt;
+ struct expr *dep;
+ unsigned int flags;
+ //char *help;
+ struct file *file;
+ int lineno;
+ void *data;
+};
+
+#define MENU_CHANGED 0x0001
+#define MENU_ROOT 0x0002
+
+#ifndef SWIG
+
+extern struct file *file_list;
+extern struct file *current_file;
+struct file *lookup_file(const char *name);
+
+extern struct symbol symbol_yes, symbol_no, symbol_mod;
+extern struct symbol *modules_sym;
+extern int cdebug;
+struct expr *expr_alloc_symbol(struct symbol *sym);
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
+struct expr *expr_copy(struct expr *org);
+void expr_free(struct expr *e);
+int expr_eq(struct expr *e1, struct expr *e2);
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
+tristate expr_calc_value(struct expr *e);
+struct expr *expr_eliminate_yn(struct expr *e);
+struct expr *expr_trans_bool(struct expr *e);
+struct expr *expr_eliminate_dups(struct expr *e);
+struct expr *expr_transform(struct expr *e);
+int expr_contains_symbol(struct expr *dep, struct symbol *sym);
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
+struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
+
+void expr_fprint(struct expr *e, FILE *out);
+struct gstr; /* forward */
+void expr_gstr_print(struct expr *e, struct gstr *gs);
+
+static inline int expr_is_yes(struct expr *e)
+{
+ return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
+}
+
+static inline int expr_is_no(struct expr *e)
+{
+ return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#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 @@
+/* Hey EMACS -*- linux-c -*- */
+/*
+ *
+ * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info>
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "lkc.h"
+#include "images.c"
+
+#include <glade/glade.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+
+//#define DEBUG
+
+enum {
+ SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
+};
+
+static gint view_mode = FULL_VIEW;
+static gboolean show_name = TRUE;
+static gboolean show_range = TRUE;
+static gboolean show_value = TRUE;
+static gboolean show_all = FALSE;
+static gboolean show_debug = FALSE;
+static gboolean resizeable = FALSE;
+
+static gboolean config_changed = FALSE;
+
+static char nohelp_text[] =
+ "Sorry, no help available for this option yet.\n";
+
+GtkWidget *main_wnd = NULL;
+GtkWidget *tree1_w = NULL; // left frame
+GtkWidget *tree2_w = NULL; // right frame
+GtkWidget *text_w = NULL;
+GtkWidget *hpaned = NULL;
+GtkWidget *vpaned = NULL;
+GtkWidget *back_btn = NULL;
+
+GtkTextTag *tag1, *tag2;
+GdkColor color;
+
+GtkTreeStore *tree1, *tree2, *tree;
+GtkTreeModel *model1, *model2;
+static GtkTreeIter *parents[256];
+static gint indent;
+
+static struct menu *current; // current node for SINGLE view
+static struct menu *browsed; // browsed node for SPLIT view
+
+enum {
+ COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
+ COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
+ COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
+ COL_NUMBER
+};
+
+static void display_list(void);
+static void display_tree(struct menu *menu);
+static void display_tree_part(void);
+static void update_tree(struct menu *src, GtkTreeIter * dst);
+static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
+static gchar **fill_row(struct menu *menu);
+
+
+/* Helping/Debugging Functions */
+
+
+const char *dbg_print_stype(int val)
+{
+ static char buf[256];
+
+ bzero(buf, 256);
+
+ if (val == S_UNKNOWN)
+ strcpy(buf, "unknown");
+ if (val == S_BOOLEAN)
+ strcpy(buf, "boolean");
+ if (val == S_TRISTATE)
+ strcpy(buf, "tristate");
+ if (val == S_INT)
+ strcpy(buf, "int");
+ if (val == S_HEX)
+ strcpy(buf, "hex");
+ if (val == S_STRING)
+ strcpy(buf, "string");
+ if (val == S_OTHER)
+ strcpy(buf, "other");
+
+#ifdef DEBUG
+ printf("%s", buf);
+#endif
+
+ return buf;
+}
+
+const char *dbg_print_flags(int val)
+{
+ static char buf[256];
+
+ bzero(buf, 256);
+
+ if (val & SYMBOL_YES)
+ strcat(buf, "yes/");
+ if (val & SYMBOL_MOD)
+ strcat(buf, "mod/");
+ if (val & SYMBOL_NO)
+ strcat(buf, "no/");
+ if (val & SYMBOL_CONST)
+ strcat(buf, "const/");
+ if (val & SYMBOL_CHECK)
+ strcat(buf, "check/");
+ if (val & SYMBOL_CHOICE)
+ strcat(buf, "choice/");
+ if (val & SYMBOL_CHOICEVAL)
+ strcat(buf, "choiceval/");
+ if (val & SYMBOL_PRINTED)
+ strcat(buf, "printed/");
+ if (val & SYMBOL_VALID)
+ strcat(buf, "valid/");
+ if (val & SYMBOL_OPTIONAL)
+ strcat(buf, "optional/");
+ if (val & SYMBOL_WRITE)
+ strcat(buf, "write/");
+ if (val & SYMBOL_CHANGED)
+ strcat(buf, "changed/");
+ if (val & SYMBOL_NEW)
+ strcat(buf, "new/");
+ if (val & SYMBOL_AUTO)
+ strcat(buf, "auto/");
+
+ buf[strlen(buf) - 1] = '\0';
+#ifdef DEBUG
+ printf("%s", buf);
+#endif
+
+ return buf;
+}
+
+const char *dbg_print_ptype(int val)
+{
+ static char buf[256];
+
+ bzero(buf, 256);
+
+ if (val == P_UNKNOWN)
+ strcpy(buf, "unknown");
+ if (val == P_PROMPT)
+ strcpy(buf, "prompt");
+ if (val == P_COMMENT)
+ strcpy(buf, "comment");
+ if (val == P_MENU)
+ strcpy(buf, "menu");
+ if (val == P_DEFAULT)
+ strcpy(buf, "default");
+ if (val == P_CHOICE)
+ strcpy(buf, "choice");
+
+#ifdef DEBUG
+ printf("%s", buf);
+#endif
+
+ return buf;
+}
+
+
+/* Main Window Initialization */
+
+
+void init_main_window(const gchar * glade_file)
+{
+ GladeXML *xml;
+ GtkWidget *widget;
+ GtkTextBuffer *txtbuf;
+ char title[256];
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ GtkStyle *style;
+
+ xml = glade_xml_new(glade_file, "window1", NULL);
+ if (!xml)
+ g_error("GUI loading failed !\n");
+ glade_xml_signal_autoconnect(xml);
+
+ main_wnd = glade_xml_get_widget(xml, "window1");
+ hpaned = glade_xml_get_widget(xml, "hpaned1");
+ vpaned = glade_xml_get_widget(xml, "vpaned1");
+ tree1_w = glade_xml_get_widget(xml, "treeview1");
+ tree2_w = glade_xml_get_widget(xml, "treeview2");
+ text_w = glade_xml_get_widget(xml, "textview3");
+
+ back_btn = glade_xml_get_widget(xml, "button1");
+ gtk_widget_set_sensitive(back_btn, FALSE);
+
+ widget = glade_xml_get_widget(xml, "show_name1");
+ gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+ show_name);
+
+ widget = glade_xml_get_widget(xml, "show_range1");
+ gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+ show_range);
+
+ widget = glade_xml_get_widget(xml, "show_data1");
+ gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+ show_value);
+
+ style = gtk_widget_get_style(main_wnd);
+ widget = glade_xml_get_widget(xml, "toolbar1");
+
+ pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
+ &style->bg[GTK_STATE_NORMAL],
+ (gchar **) xpm_single_view);
+ gtk_image_set_from_pixmap(GTK_IMAGE
+ (((GtkToolbarChild
+ *) (g_list_nth(GTK_TOOLBAR(widget)->
+ children,
+ 5)->data))->icon),
+ pixmap, mask);
+ pixmap =
+ gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
+ &style->bg[GTK_STATE_NORMAL],
+ (gchar **) xpm_split_view);
+ gtk_image_set_from_pixmap(GTK_IMAGE
+ (((GtkToolbarChild
+ *) (g_list_nth(GTK_TOOLBAR(widget)->
+ children,
+ 6)->data))->icon),
+ pixmap, mask);
+ pixmap =
+ gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
+ &style->bg[GTK_STATE_NORMAL],
+ (gchar **) xpm_tree_view);
+ gtk_image_set_from_pixmap(GTK_IMAGE
+ (((GtkToolbarChild
+ *) (g_list_nth(GTK_TOOLBAR(widget)->
+ children,
+ 7)->data))->icon),
+ pixmap, mask);
+
+ switch (view_mode) {
+ case SINGLE_VIEW:
+ widget = glade_xml_get_widget(xml, "button4");
+ g_signal_emit_by_name(widget, "clicked");
+ break;
+ case SPLIT_VIEW:
+ widget = glade_xml_get_widget(xml, "button5");
+ g_signal_emit_by_name(widget, "clicked");
+ break;
+ case FULL_VIEW:
+ widget = glade_xml_get_widget(xml, "button6");
+ g_signal_emit_by_name(widget, "clicked");
+ break;
+ }
+
+ txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+ tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
+ "foreground", "red",
+ "weight", PANGO_WEIGHT_BOLD,
+ NULL);
+ tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
+ /*"style", PANGO_STYLE_OBLIQUE, */
+ NULL);
+
+ sprintf(title, "Linux Kernel v%s Configuration",
+ getenv("KERNELRELEASE"));
+ gtk_window_set_title(GTK_WINDOW(main_wnd), title);
+
+ gtk_widget_show(main_wnd);
+}
+
+void init_tree_model(void)
+{
+ gint i;
+
+ tree = tree2 = gtk_tree_store_new(COL_NUMBER,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_POINTER, GDK_TYPE_COLOR,
+ G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+ model2 = GTK_TREE_MODEL(tree2);
+
+ for (parents[0] = NULL, i = 1; i < 256; i++)
+ parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
+
+ tree1 = gtk_tree_store_new(COL_NUMBER,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_POINTER, GDK_TYPE_COLOR,
+ G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+ model1 = GTK_TREE_MODEL(tree1);
+}
+
+void init_left_tree(void)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *sel;
+ GtkTreeViewColumn *column;
+
+ gtk_tree_view_set_model(view, model1);
+ gtk_tree_view_set_headers_visible(view, TRUE);
+ gtk_tree_view_set_rules_hint(view, FALSE);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(view, column);
+ gtk_tree_view_column_set_title(column, "Options");
+
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "active", COL_BTNACT,
+ "inconsistent", COL_BTNINC,
+ "visible", COL_BTNVIS,
+ "radio", COL_BTNRAD, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "text", COL_OPTION,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+
+ sel = gtk_tree_view_get_selection(view);
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+ gtk_widget_realize(tree1_w);
+}
+
+static void renderer_edited(GtkCellRendererText * cell,
+ const gchar * path_string,
+ const gchar * new_text, gpointer user_data);
+static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
+ gchar * arg1, gpointer user_data);
+
+void init_right_tree(void)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *sel;
+ GtkTreeViewColumn *column;
+ gint i;
+
+ gtk_tree_view_set_model(view, model2);
+ gtk_tree_view_set_headers_visible(view, TRUE);
+ gtk_tree_view_set_rules_hint(view, FALSE);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(view, column);
+ gtk_tree_view_column_set_title(column, "Options");
+
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "pixbuf", COL_PIXBUF,
+ "visible", COL_PIXVIS, NULL);
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "active", COL_BTNACT,
+ "inconsistent", COL_BTNINC,
+ "visible", COL_BTNVIS,
+ "radio", COL_BTNRAD, NULL);
+ /*g_signal_connect(G_OBJECT(renderer), "toggled",
+ G_CALLBACK(renderer_toggled), NULL); */
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "text", COL_OPTION,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "Name", renderer,
+ "text", COL_NAME,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "N", renderer,
+ "text", COL_NO,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "M", renderer,
+ "text", COL_MOD,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "Y", renderer,
+ "text", COL_YES,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "Value", renderer,
+ "text", COL_VALUE,
+ "editable",
+ COL_EDIT,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ g_signal_connect(G_OBJECT(renderer), "edited",
+ G_CALLBACK(renderer_edited), NULL);
+
+ column = gtk_tree_view_get_column(view, COL_NAME);
+ gtk_tree_view_column_set_visible(column, show_name);
+ column = gtk_tree_view_get_column(view, COL_NO);
+ gtk_tree_view_column_set_visible(column, show_range);
+ column = gtk_tree_view_get_column(view, COL_MOD);
+ gtk_tree_view_column_set_visible(column, show_range);
+ column = gtk_tree_view_get_column(view, COL_YES);
+ gtk_tree_view_column_set_visible(column, show_range);
+ column = gtk_tree_view_get_column(view, COL_VALUE);
+ gtk_tree_view_column_set_visible(column, show_value);
+
+ if (resizeable) {
+ for (i = 0; i < COL_VALUE; i++) {
+ column = gtk_tree_view_get_column(view, i);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ }
+ }
+
+ sel = gtk_tree_view_get_selection(view);
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+}
+
+
+/* Utility Functions */
+
+
+static void text_insert_help(struct menu *menu)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ const char *prompt = menu_get_prompt(menu);
+ gchar *name;
+ const char *help = nohelp_text;
+
+ if (!menu->sym)
+ help = "";
+ else if (menu->sym->help)
+ help = menu->sym->help;
+
+ if (menu->sym && menu->sym->name)
+ name = g_strdup_printf(menu->sym->name);
+ else
+ name = g_strdup("");
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
+
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
+ NULL);
+ gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
+ NULL);
+ gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2,
+ NULL);
+}
+
+
+static void text_insert_msg(const char *title, const char *message)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ const char *msg = message;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
+
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
+ NULL);
+ gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
+ NULL);
+}
+
+
+/* Main Windows Callbacks */
+
+void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
+gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
+ gpointer user_data)
+{
+ GtkWidget *dialog, *label;
+ gint result;
+
+ if (config_changed == FALSE)
+ return FALSE;
+
+ dialog = gtk_dialog_new_with_buttons("Warning !",
+ GTK_WINDOW(main_wnd),
+ (GtkDialogFlags)
+ (GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT),
+ GTK_STOCK_OK,
+ GTK_RESPONSE_YES,
+ GTK_STOCK_NO,
+ GTK_RESPONSE_NO,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+ GTK_RESPONSE_CANCEL);
+
+ label = gtk_label_new("\nSave configuration ?\n");
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
+ gtk_widget_show(label);
+
+ result = gtk_dialog_run(GTK_DIALOG(dialog));
+ switch (result) {
+ case GTK_RESPONSE_YES:
+ on_save1_activate(NULL, NULL);
+ return FALSE;
+ case GTK_RESPONSE_NO:
+ return FALSE;
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_DELETE_EVENT:
+ default:
+ gtk_widget_destroy(dialog);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void on_window1_destroy(GtkObject * object, gpointer user_data)
+{
+ gtk_main_quit();
+}
+
+
+void
+on_window1_size_request(GtkWidget * widget,
+ GtkRequisition * requisition, gpointer user_data)
+{
+ static gint old_h;
+ gint w, h;
+
+ if (widget->window == NULL)
+ gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
+ else
+ gdk_window_get_size(widget->window, &w, &h);
+
+ if (h == old_h)
+ return;
+ old_h = h;
+
+ gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
+}
+
+
+/* Menu & Toolbar Callbacks */
+
+
+static void
+load_filename(GtkFileSelection * file_selector, gpointer user_data)
+{
+ const gchar *fn;
+
+ fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
+ (user_data));
+
+ if (conf_read(fn))
+ text_insert_msg("Error", "Unable to load configuration !");
+ else
+ display_tree(&rootmenu);
+}
+
+void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *fs;
+
+ fs = gtk_file_selection_new("Load file...");
+ g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked",
+ G_CALLBACK(load_filename), (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->cancel_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ gtk_widget_show(fs);
+}
+
+
+void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ if (conf_write(NULL))
+ text_insert_msg("Error", "Unable to save configuration !");
+
+ config_changed = FALSE;
+}
+
+
+static void
+store_filename(GtkFileSelection * file_selector, gpointer user_data)
+{
+ const gchar *fn;
+
+ fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
+ (user_data));
+
+ if (conf_write(fn))
+ text_insert_msg("Error", "Unable to save configuration !");
+
+ gtk_widget_destroy(GTK_WIDGET(user_data));
+}
+
+void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *fs;
+
+ fs = gtk_file_selection_new("Save file as...");
+ g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked",
+ G_CALLBACK(store_filename), (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->cancel_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ gtk_widget_show(fs);
+}
+
+
+void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ if (!on_window1_delete_event(NULL, NULL, NULL))
+ gtk_widget_destroy(GTK_WIDGET(main_wnd));
+}
+
+
+void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkTreeViewColumn *col;
+
+ show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_name);
+}
+
+
+void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkTreeViewColumn *col;
+
+ show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_range);
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_range);
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_range);
+
+}
+
+
+void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkTreeViewColumn *col;
+
+ show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_value);
+}
+
+
+void
+on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
+
+ gtk_tree_store_clear(tree2);
+ display_tree(&rootmenu); // instead of update_tree to speed-up
+}
+
+
+void
+on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ update_tree(&rootmenu, NULL);
+}
+
+
+void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *dialog;
+ const gchar *intro_text =
+ "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
+ "for Linux.\n"
+ "For each option, a blank box indicates the feature is disabled, a\n"
+ "check indicates it is enabled, and a dot indicates that it is to\n"
+ "be compiled as a module. Clicking on the box will cycle through the three states.\n"
+ "\n"
+ "If you do not see an option (e.g., a device driver) that you\n"
+ "believe should be present, try turning on Show All Options\n"
+ "under the Options menu.\n"
+ "Although there is no cross reference yet to help you figure out\n"
+ "what other options must be enabled to support the option you\n"
+ "are interested in, you can still view the help of a grayed-out\n"
+ "option.\n"
+ "\n"
+ "Toggling Show Debug Info under the Options menu will show \n"
+ "the dependencies, which you can then match by examining other options.";
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE, intro_text);
+ g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
+ G_CALLBACK(gtk_widget_destroy),
+ GTK_OBJECT(dialog));
+ gtk_widget_show_all(dialog);
+}
+
+
+void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *dialog;
+ const gchar *about_text =
+ "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
+ "Based on the source code from Roman Zippel.\n";
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE, about_text);
+ g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
+ G_CALLBACK(gtk_widget_destroy),
+ GTK_OBJECT(dialog));
+ gtk_widget_show_all(dialog);
+}
+
+
+void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *dialog;
+ const gchar *license_text =
+ "gkc is released under the terms of the GNU GPL v2.\n"
+ "For more information, please see the source code or\n"
+ "visit http://www.fsf.org/licenses/licenses.html\n";
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE, license_text);
+ g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
+ G_CALLBACK(gtk_widget_destroy),
+ GTK_OBJECT(dialog));
+ gtk_widget_show_all(dialog);
+}
+
+
+void on_back_pressed(GtkButton * button, gpointer user_data)
+{
+ enum prop_type ptype;
+
+ current = current->parent;
+ ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
+ if (ptype != P_MENU)
+ current = current->parent;
+ display_tree_part();
+
+ if (current == &rootmenu)
+ gtk_widget_set_sensitive(back_btn, FALSE);
+}
+
+
+void on_load_pressed(GtkButton * button, gpointer user_data)
+{
+ on_load1_activate(NULL, user_data);
+}
+
+
+void on_save_pressed(GtkButton * button, gpointer user_data)
+{
+ on_save1_activate(NULL, user_data);
+}
+
+
+void on_single_clicked(GtkButton * button, gpointer user_data)
+{
+ view_mode = SINGLE_VIEW;
+ gtk_paned_set_position(GTK_PANED(hpaned), 0);
+ gtk_widget_hide(tree1_w);
+ current = &rootmenu;
+ display_tree_part();
+}
+
+
+void on_split_clicked(GtkButton * button, gpointer user_data)
+{
+ gint w, h;
+ view_mode = SPLIT_VIEW;
+ gtk_widget_show(tree1_w);
+ gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
+ gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
+ if (tree2)
+ gtk_tree_store_clear(tree2);
+ display_list();
+}
+
+
+void on_full_clicked(GtkButton * button, gpointer user_data)
+{
+ view_mode = FULL_VIEW;
+ gtk_paned_set_position(GTK_PANED(hpaned), 0);
+ gtk_widget_hide(tree1_w);
+ if (tree2)
+ gtk_tree_store_clear(tree2);
+ display_tree(&rootmenu);
+ gtk_widget_set_sensitive(back_btn, FALSE);
+}
+
+
+void on_collapse_pressed(GtkButton * button, gpointer user_data)
+{
+ gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
+}
+
+
+void on_expand_pressed(GtkButton * button, gpointer user_data)
+{
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
+}
+
+
+/* CTree Callbacks */
+
+/* Change hex/int/string value in the cell */
+static void renderer_edited(GtkCellRendererText * cell,
+ const gchar * path_string,
+ const gchar * new_text, gpointer user_data)
+{
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
+ GtkTreeIter iter;
+ const char *old_def, *new_def;
+ struct menu *menu;
+ struct symbol *sym;
+
+ if (!gtk_tree_model_get_iter(model2, &iter, path))
+ return;
+
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+ sym = menu->sym;
+
+ gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
+ new_def = new_text;
+
+ sym_set_string_value(sym, new_def);
+
+ config_changed = TRUE;
+ update_tree(&rootmenu, NULL);
+
+ gtk_tree_path_free(path);
+}
+
+/* Change the value of a symbol and update the tree */
+static void change_sym_value(struct menu *menu, gint col)
+{
+ struct symbol *sym = menu->sym;
+ tristate oldval, newval;
+
+ if (!sym)
+ return;
+
+ if (col == COL_NO)
+ newval = no;
+ else if (col == COL_MOD)
+ newval = mod;
+ else if (col == COL_YES)
+ newval = yes;
+ else
+ return;
+
+ switch (sym_get_type(sym)) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ oldval = sym_get_tristate_value(sym);
+ if (!sym_tristate_within_range(sym, newval))
+ newval = yes;
+ sym_set_tristate_value(sym, newval);
+ config_changed = TRUE;
+ if (view_mode == FULL_VIEW)
+ update_tree(&rootmenu, NULL);
+ else if (view_mode == SPLIT_VIEW) {
+ update_tree(browsed, NULL);
+ display_list();
+ }
+ else if (view_mode == SINGLE_VIEW)
+ display_tree_part(); //fixme: keep exp/coll
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ default:
+ break;
+ }
+}
+
+static void toggle_sym_value(struct menu *menu)
+{
+ if (!menu->sym)
+ return;
+
+ sym_toggle_tristate_value(menu->sym);
+ if (view_mode == FULL_VIEW)
+ update_tree(&rootmenu, NULL);
+ else if (view_mode == SPLIT_VIEW) {
+ update_tree(browsed, NULL);
+ display_list();
+ }
+ else if (view_mode == SINGLE_VIEW)
+ display_tree_part(); //fixme: keep exp/coll
+}
+
+static void renderer_toggled(GtkCellRendererToggle * cell,
+ gchar * path_string, gpointer user_data)
+{
+ GtkTreePath *path, *sel_path = NULL;
+ GtkTreeIter iter, sel_iter;
+ GtkTreeSelection *sel;
+ struct menu *menu;
+
+ path = gtk_tree_path_new_from_string(path_string);
+ if (!gtk_tree_model_get_iter(model2, &iter, path))
+ return;
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
+ if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
+ sel_path = gtk_tree_model_get_path(model2, &sel_iter);
+ if (!sel_path)
+ goto out1;
+ if (gtk_tree_path_compare(path, sel_path))
+ goto out2;
+
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+ toggle_sym_value(menu);
+
+ out2:
+ gtk_tree_path_free(sel_path);
+ out1:
+ gtk_tree_path_free(path);
+}
+
+static gint column2index(GtkTreeViewColumn * column)
+{
+ gint i;
+
+ for (i = 0; i < COL_NUMBER; i++) {
+ GtkTreeViewColumn *col;
+
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
+ if (col == column)
+ return i;
+ }
+
+ return -1;
+}
+
+
+/* User click: update choice (full) or goes down (single) */
+gboolean
+on_treeview2_button_press_event(GtkWidget * widget,
+ GdkEventButton * event, gpointer user_data)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(widget);
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ struct menu *menu;
+ gint col;
+
+#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
+ gint tx = (gint) event->x;
+ gint ty = (gint) event->y;
+ gint cx, cy;
+
+ gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
+ &cy);
+#else
+ gtk_tree_view_get_cursor(view, &path, &column);
+#endif
+ if (path == NULL)
+ return FALSE;
+
+ if (!gtk_tree_model_get_iter(model2, &iter, path))
+ return FALSE;
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+
+ col = column2index(column);
+ if (event->type == GDK_2BUTTON_PRESS) {
+ enum prop_type ptype;
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+
+ if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
+ // goes down into menu
+ current = menu;
+ display_tree_part();
+ gtk_widget_set_sensitive(back_btn, TRUE);
+ } else if ((col == COL_OPTION)) {
+ toggle_sym_value(menu);
+ gtk_tree_view_expand_row(view, path, TRUE);
+ }
+ } else {
+ if (col == COL_VALUE) {
+ toggle_sym_value(menu);
+ gtk_tree_view_expand_row(view, path, TRUE);
+ } else if (col == COL_NO || col == COL_MOD
+ || col == COL_YES) {
+ change_sym_value(menu, col);
+ gtk_tree_view_expand_row(view, path, TRUE);
+ }
+ }
+
+ return FALSE;
+}
+
+/* Key pressed: update choice */
+gboolean
+on_treeview2_key_press_event(GtkWidget * widget,
+ GdkEventKey * event, gpointer user_data)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(widget);
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ struct menu *menu;
+ gint col;
+
+ gtk_tree_view_get_cursor(view, &path, &column);
+ if (path == NULL)
+ return FALSE;
+
+ if (event->keyval == GDK_space) {
+ if (gtk_tree_view_row_expanded(view, path))
+ gtk_tree_view_collapse_row(view, path);
+ else
+ gtk_tree_view_expand_row(view, path, FALSE);
+ return TRUE;
+ }
+ if (event->keyval == GDK_KP_Enter) {
+ }
+ if (widget == tree1_w)
+ return FALSE;
+
+ gtk_tree_model_get_iter(model2, &iter, path);
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+
+ if (!strcasecmp(event->string, "n"))
+ col = COL_NO;
+ else if (!strcasecmp(event->string, "m"))
+ col = COL_MOD;
+ else if (!strcasecmp(event->string, "y"))
+ col = COL_YES;
+ else
+ col = -1;
+ change_sym_value(menu, col);
+
+ return FALSE;
+}
+
+
+/* Row selection changed: update help */
+void
+on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ struct menu *menu;
+
+ selection = gtk_tree_view_get_selection(treeview);
+ if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+ text_insert_help(menu);
+ }
+}
+
+
+/* User click: display sub-tree in the right frame. */
+gboolean
+on_treeview1_button_press_event(GtkWidget * widget,
+ GdkEventButton * event, gpointer user_data)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(widget);
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ struct menu *menu;
+
+ gint tx = (gint) event->x;
+ gint ty = (gint) event->y;
+ gint cx, cy;
+
+ gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
+ &cy);
+ if (path == NULL)
+ return FALSE;
+
+ gtk_tree_model_get_iter(model1, &iter, path);
+ gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ toggle_sym_value(menu);
+ current = menu;
+ display_tree_part();
+ } else {
+ browsed = menu;
+ display_tree_part();
+ }
+
+ gtk_widget_realize(tree2_w);
+ gtk_tree_view_set_cursor(view, path, NULL, FALSE);
+ gtk_widget_grab_focus(tree2_w);
+
+ return FALSE;
+}
+
+
+/* Fill a row of strings */
+static gchar **fill_row(struct menu *menu)
+{
+ static gchar *row[COL_NUMBER];
+ struct symbol *sym = menu->sym;
+ const char *def;
+ int stype;
+ tristate val;
+ enum prop_type ptype;
+ int i;
+
+ for (i = COL_OPTION; i <= COL_COLOR; i++)
+ g_free(row[i]);
+ bzero(row, sizeof(row));
+
+ row[COL_OPTION] =
+ g_strdup_printf("%s %s", menu_get_prompt(menu),
+ sym ? (sym->
+ flags & SYMBOL_NEW ? "(NEW)" : "") :
+ "");
+
+ if (show_all && !menu_is_visible(menu))
+ row[COL_COLOR] = g_strdup("DarkGray");
+ else
+ row[COL_COLOR] = g_strdup("Black");
+
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ switch (ptype) {
+ case P_MENU:
+ row[COL_PIXBUF] = (gchar *) xpm_menu;
+ if (view_mode == SINGLE_VIEW)
+ row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+ break;
+ case P_COMMENT:
+ row[COL_PIXBUF] = (gchar *) xpm_void;
+ row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+ break;
+ default:
+ row[COL_PIXBUF] = (gchar *) xpm_void;
+ row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
+ break;
+ }
+
+ if (!sym)
+ return row;
+ row[COL_NAME] = g_strdup(sym->name);
+
+ sym_calc_value(sym);
+ sym->flags &= ~SYMBOL_CHANGED;
+
+ if (sym_is_choice(sym)) { // parse childs for getting final value
+ struct menu *child;
+ struct symbol *def_sym = sym_get_choice_value(sym);
+ struct menu *def_menu = NULL;
+
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child)
+ && child->sym == def_sym)
+ def_menu = child;
+ }
+
+ if (def_menu)
+ row[COL_VALUE] =
+ g_strdup(menu_get_prompt(def_menu));
+ }
+ if(sym->flags & SYMBOL_CHOICEVAL)
+ row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
+
+ stype = sym_get_type(sym);
+ switch (stype) {
+ case S_BOOLEAN:
+ if(GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
+ row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
+ if (sym_is_choice(sym))
+ break;
+ case S_TRISTATE:
+ val = sym_get_tristate_value(sym);
+ switch (val) {
+ case no:
+ row[COL_NO] = g_strdup("N");
+ row[COL_VALUE] = g_strdup("N");
+ row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
+ row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
+ break;
+ case mod:
+ row[COL_MOD] = g_strdup("M");
+ row[COL_VALUE] = g_strdup("M");
+ row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
+ break;
+ case yes:
+ row[COL_YES] = g_strdup("Y");
+ row[COL_VALUE] = g_strdup("Y");
+ row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
+ row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
+ break;
+ }
+
+ if (val != no && sym_tristate_within_range(sym, no))
+ row[COL_NO] = g_strdup("_");
+ if (val != mod && sym_tristate_within_range(sym, mod))
+ row[COL_MOD] = g_strdup("_");
+ if (val != yes && sym_tristate_within_range(sym, yes))
+ row[COL_YES] = g_strdup("_");
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ def = sym_get_string_value(sym);
+ row[COL_VALUE] = g_strdup(def);
+ row[COL_EDIT] = GINT_TO_POINTER(TRUE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+ break;
+ }
+
+ return row;
+}
+
+
+/* Set the node content with a row of strings */
+static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
+{
+ GdkColor color;
+ gboolean success;
+ GdkPixbuf *pix;
+
+ pix = gdk_pixbuf_new_from_xpm_data((const char **)
+ row[COL_PIXBUF]);
+
+ gdk_color_parse(row[COL_COLOR], &color);
+ gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
+ FALSE, FALSE, &success);
+
+ gtk_tree_store_set(tree, node,
+ COL_OPTION, row[COL_OPTION],
+ COL_NAME, row[COL_NAME],
+ COL_NO, row[COL_NO],
+ COL_MOD, row[COL_MOD],
+ COL_YES, row[COL_YES],
+ COL_VALUE, row[COL_VALUE],
+ COL_MENU, (gpointer) menu,
+ COL_COLOR, &color,
+ COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
+ COL_PIXBUF, pix,
+ COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
+ COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
+ COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
+ COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
+ COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
+ -1);
+
+ g_object_unref(pix);
+}
+
+
+/* Add a node to the tree */
+static void place_node(struct menu *menu, char **row)
+{
+ GtkTreeIter *parent = parents[indent - 1];
+ GtkTreeIter *node = parents[indent];
+
+ gtk_tree_store_append(tree, node, parent);
+ set_node(node, menu, row);
+}
+
+
+/* Find a node in the GTK+ tree */
+static GtkTreeIter found;
+
+/*
+ * Find a menu in the GtkTree starting at parent.
+ */
+GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
+ struct menu *tofind)
+{
+ GtkTreeIter iter;
+ GtkTreeIter *child = &iter;
+ gboolean valid;
+ GtkTreeIter *ret;
+
+ valid = gtk_tree_model_iter_children(model2, child, parent);
+ while (valid) {
+ struct menu *menu;
+
+ gtk_tree_model_get(model2, child, 6, &menu, -1);
+
+ if (menu == tofind) {
+ memcpy(&found, child, sizeof(GtkTreeIter));
+ return &found;
+ }
+
+ ret = gtktree_iter_find_node(child, tofind);
+ if (ret)
+ return ret;
+
+ valid = gtk_tree_model_iter_next(model2, child);
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Update the tree by adding/removing entries
+ * Does not change other nodes
+ */
+static void update_tree(struct menu *src, GtkTreeIter * dst)
+{
+ struct menu *child1;
+ GtkTreeIter iter, tmp;
+ GtkTreeIter *child2 = &iter;
+ gboolean valid;
+ GtkTreeIter *sibling;
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *menu1, *menu2;
+
+ if (src == &rootmenu)
+ indent = 1;
+
+ valid = gtk_tree_model_iter_children(model2, child2, dst);
+ for (child1 = src->list; child1; child1 = child1->next) {
+
+ prop = child1->prompt;
+ sym = child1->sym;
+
+ reparse:
+ menu1 = child1;
+ if (valid)
+ gtk_tree_model_get(model2, child2, COL_MENU,
+ &menu2, -1);
+ else
+ menu2 = NULL; // force adding of a first child
+
+#ifdef DEBUG
+ printf("%*c%s | %s\n", indent, ' ',
+ menu1 ? menu_get_prompt(menu1) : "nil",
+ menu2 ? menu_get_prompt(menu2) : "nil");
+#endif
+
+ if (!menu_is_visible(child1) && !show_all) { // remove node
+ if (gtktree_iter_find_node(dst, menu1) != NULL) {
+ memcpy(&tmp, child2, sizeof(GtkTreeIter));
+ valid = gtk_tree_model_iter_next(model2,
+ child2);
+ gtk_tree_store_remove(tree2, &tmp);
+ if (!valid)
+ return; // next parent
+ else
+ goto reparse; // next child
+ } else
+ continue;
+ }
+
+ if (menu1 != menu2) {
+ if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node
+ if (!valid && !menu2)
+ sibling = NULL;
+ else
+ sibling = child2;
+ gtk_tree_store_insert_before(tree2,
+ child2,
+ dst, sibling);
+ set_node(child2, menu1, fill_row(menu1));
+ if (menu2 == NULL)
+ valid = TRUE;
+ } else { // remove node
+ memcpy(&tmp, child2, sizeof(GtkTreeIter));
+ valid = gtk_tree_model_iter_next(model2,
+ child2);
+ gtk_tree_store_remove(tree2, &tmp);
+ if (!valid)
+ return; // next parent
+ else
+ goto reparse; // next child
+ }
+ } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
+ set_node(child2, menu1, fill_row(menu1));
+ }
+
+ indent++;
+ update_tree(child1, child2);
+ indent--;
+
+ valid = gtk_tree_model_iter_next(model2, child2);
+ }
+}
+
+
+/* Display the whole tree (single/split/full view) */
+static void display_tree(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+ enum prop_type ptype;
+
+ if (menu == &rootmenu) {
+ indent = 1;
+ current = &rootmenu;
+ }
+
+ for (child = menu->list; child; child = child->next) {
+ prop = child->prompt;
+ sym = child->sym;
+ ptype = prop ? prop->type : P_UNKNOWN;
+
+ if (sym)
+ sym->flags &= ~SYMBOL_CHANGED;
+
+ if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) &&
+ (tree == tree1))
+ continue;
+
+ if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) &&
+ (tree == tree2))
+ continue;
+
+ if (menu_is_visible(child) || show_all)
+ place_node(child, fill_row(child));
+#ifdef DEBUG
+ printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
+ printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
+ dbg_print_ptype(ptype);
+ printf(" | ");
+ if (sym) {
+ dbg_print_stype(sym->type);
+ printf(" | ");
+ dbg_print_flags(sym->flags);
+ printf("\n");
+ } else
+ printf("\n");
+#endif
+ if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
+ && (tree == tree2))
+ continue;
+/*
+ if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) ||
+ (view_mode == FULL_VIEW)
+ || (view_mode == SPLIT_VIEW))*/
+ if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
+ || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) {
+ indent++;
+ display_tree(child);
+ indent--;
+ }
+ }
+}
+
+/* Display a part of the tree starting at current node (single/split view) */
+static void display_tree_part(void)
+{
+ if (tree2)
+ gtk_tree_store_clear(tree2);
+ if(view_mode == SINGLE_VIEW)
+ display_tree(current);
+ else if(view_mode == SPLIT_VIEW)
+ display_tree(browsed);
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
+}
+
+/* Display the list in the left frame (split view) */
+static void display_list(void)
+{
+ if (tree1)
+ gtk_tree_store_clear(tree1);
+
+ tree = tree1;
+ display_tree(&rootmenu);
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
+ tree = tree2;
+}
+
+void fixup_rootmenu(struct menu *menu)
+{
+ struct menu *child;
+ static int menu_cnt = 0;
+
+ menu->flags |= MENU_ROOT;
+ for (child = menu->list; child; child = child->next) {
+ if (child->prompt && child->prompt->type == P_MENU) {
+ menu_cnt++;
+ fixup_rootmenu(child);
+ menu_cnt--;
+ } else if (!menu_cnt)
+ fixup_rootmenu(child);
+ }
+}
+
+
+/* Main */
+
+
+int main(int ac, char *av[])
+{
+ const char *name;
+ char *env;
+ gchar *glade_file;
+
+#ifndef LKC_DIRECT_LINK
+ kconfig_load();
+#endif
+
+ /* GTK stuffs */
+ gtk_set_locale();
+ gtk_init(&ac, &av);
+ glade_init();
+
+ //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
+ //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
+
+ /* Determine GUI path */
+ env = getenv(SRCTREE);
+ if (env)
+ glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL);
+ else if (av[0][0] == '/')
+ glade_file = g_strconcat(av[0], ".glade", NULL);
+ else
+ glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
+
+ /* Load the interface and connect signals */
+ init_main_window(glade_file);
+ init_tree_model();
+ init_left_tree();
+ init_right_tree();
+
+ /* Conf stuffs */
+ if (ac > 1 && av[1][0] == '-') {
+ switch (av[1][1]) {
+ case 'a':
+ //showAll = 1;
+ break;
+ case 'h':
+ case '?':
+ printf("%s <config>\n", av[0]);
+ exit(0);
+ }
+ name = av[2];
+ } else
+ name = av[1];
+
+ conf_parse(name);
+ fixup_rootmenu(&rootmenu);
+ conf_read(NULL);
+
+ switch (view_mode) {
+ case SINGLE_VIEW:
+ display_tree_part();
+ break;
+ case SPLIT_VIEW:
+ display_list();
+ break;
+ case FULL_VIEW:
+ display_tree(&rootmenu);
+ break;
+ }
+
+ gtk_main();
+
+ return 0;
+}
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 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="window1">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Gtk Kernel Configurator</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">640</property>
+ <property name="default_height">480</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <signal name="destroy" handler="on_window1_destroy" object="window1"/>
+ <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/>
+ <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="file1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="file1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="load1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Load a config file</property>
+ <property name="label" translatable="yes">_Load</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_load1_activate"/>
+ <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image27">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="save1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Save the config in .config</property>
+ <property name="label" translatable="yes">_Save</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_save1_activate"/>
+ <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image28">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="save_as1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Save the config in a file</property>
+ <property name="label" translatable="yes">Save _as</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_save_as1_activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image29">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save-as</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="separator1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="quit1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Quit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_quit1_activate"/>
+ <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image30">
+ <property name="visible">True</property>
+ <property name="stock">gtk-quit</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="options1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Options</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="options1_menu">
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="show_name1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show name</property>
+ <property name="label" translatable="yes">Show _name</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="activate" handler="on_show_name1_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="show_range1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show range (Y/M/N)</property>
+ <property name="label" translatable="yes">Show _range</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="activate" handler="on_show_range1_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="show_data1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show value of the option</property>
+ <property name="label" translatable="yes">Show _data</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="activate" handler="on_show_data1_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="separator2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="show_all_options1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show all options</property>
+ <property name="label" translatable="yes">Show all _options</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="activate" handler="on_show_all_options1_activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="show_debug_info1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Show masked options</property>
+ <property name="label" translatable="yes">Show _debug info</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="activate" handler="on_show_debug_info1_activate"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="help1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="help1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="introduction1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Introduction</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_introduction1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
+ <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image31">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-question</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="about1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_About</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_about1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
+ <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image32">
+ <property name="visible">True</property>
+ <property name="stock">gtk-properties</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="license1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_License</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image33">
+ <property name="visible">True</property>
+ <property name="stock">gtk-justify-fill</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHandleBox" id="handlebox1">
+ <property name="visible">True</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <property name="handle_position">GTK_POS_LEFT</property>
+ <property name="snap_edge">GTK_POS_TOP</property>
+
+ <child>
+ <widget class="GtkToolbar" id="toolbar1">
+ <property name="visible">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
+ <property name="tooltips">True</property>
+
+ <child>
+ <widget class="button" id="button1">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Goes up of one level (single view)</property>
+ <property name="label" translatable="yes">Back</property>
+ <property name="use_underline">True</property>
+ <property name="stock_pixmap">gtk-undo</property>
+ <signal name="pressed" handler="on_back_pressed"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkVSeparator" id="vseparator1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button2">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Load a config file</property>
+ <property name="label" translatable="yes">Load</property>
+ <property name="use_underline">True</property>
+ <property name="stock_pixmap">gtk-open</property>
+ <signal name="pressed" handler="on_load_pressed"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button3">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Save a config file</property>
+ <property name="label" translatable="yes">Save</property>
+ <property name="use_underline">True</property>
+ <property name="stock_pixmap">gtk-save</property>
+ <signal name="pressed" handler="on_save_pressed"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkVSeparator" id="vseparator2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button4">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Single view</property>
+ <property name="label" translatable="yes">Single</property>
+ <property name="use_underline">True</property>
+ <property name="stock_pixmap">gtk-missing-image</property>
+ <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button5">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Split view</property>
+ <property name="label" translatable="yes">Split</property>
+ <property name="use_underline">True</property>
+ <property name="stock_pixmap">gtk-missing-image</property>
+ <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button6">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Full view</property>
+ <property name="label" translatable="yes">Full</property>
+ <property name="use_underline">True</property>
+ <property name="stock_pixmap">gtk-missing-image</property>
+ <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkVSeparator" id="vseparator3">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button7">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property>
+ <property name="label" translatable="yes">Collapse</property>
+ <property name="use_underline">True</property>
+ <signal name="pressed" handler="on_collapse_pressed"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="button" id="button8">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property>
+ <property name="label" translatable="yes">Expand</property>
+ <property name="use_underline">True</property>
+ <signal name="pressed" handler="on_expand_pressed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHPaned" id="hpaned1">
+ <property name="width_request">1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="treeview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
+ <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
+ <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVPaned" id="vpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="treeview2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
+ <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
+ <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTextView" id="textview3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_WORD</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">0</property>
+ <property name="right_margin">0</property>
+ <property name="indent">0</property>
+ <property name="text" translatable="yes">Sorry, no help available for this option yet.</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+static const char *xpm_load[] = {
+"22 22 5 1",
+". c None",
+"# c #000000",
+"c c #838100",
+"a c #ffff00",
+"b c #ffffff",
+"......................",
+"......................",
+"......................",
+"............####....#.",
+"...........#....##.##.",
+"..................###.",
+".................####.",
+".####...........#####.",
+"#abab##########.......",
+"#babababababab#.......",
+"#ababababababa#.......",
+"#babababababab#.......",
+"#ababab###############",
+"#babab##cccccccccccc##",
+"#abab##cccccccccccc##.",
+"#bab##cccccccccccc##..",
+"#ab##cccccccccccc##...",
+"#b##cccccccccccc##....",
+"###cccccccccccc##.....",
+"##cccccccccccc##......",
+"###############.......",
+"......................"};
+
+static const char *xpm_save[] = {
+"22 22 5 1",
+". c None",
+"# c #000000",
+"a c #838100",
+"b c #c5c2c5",
+"c c #cdb6d5",
+"......................",
+".####################.",
+".#aa#bbbbbbbbbbbb#bb#.",
+".#aa#bbbbbbbbbbbb#bb#.",
+".#aa#bbbbbbbbbcbb####.",
+".#aa#bbbccbbbbbbb#aa#.",
+".#aa#bbbccbbbbbbb#aa#.",
+".#aa#bbbbbbbbbbbb#aa#.",
+".#aa#bbbbbbbbbbbb#aa#.",
+".#aa#bbbbbbbbbbbb#aa#.",
+".#aa#bbbbbbbbbbbb#aa#.",
+".#aaa############aaa#.",
+".#aaaaaaaaaaaaaaaaaa#.",
+".#aaaaaaaaaaaaaaaaaa#.",
+".#aaa#############aa#.",
+".#aaa#########bbb#aa#.",
+".#aaa#########bbb#aa#.",
+".#aaa#########bbb#aa#.",
+".#aaa#########bbb#aa#.",
+".#aaa#########bbb#aa#.",
+"..##################..",
+"......................"};
+
+static const char *xpm_back[] = {
+"22 22 3 1",
+". c None",
+"# c #000083",
+"a c #838183",
+"......................",
+"......................",
+"......................",
+"......................",
+"......................",
+"...........######a....",
+"..#......##########...",
+"..##...####......##a..",
+"..###.###.........##..",
+"..######..........##..",
+"..#####...........##..",
+"..######..........##..",
+"..#######.........##..",
+"..########.......##a..",
+"...............a###...",
+"...............###....",
+"......................",
+"......................",
+"......................",
+"......................",
+"......................",
+"......................"};
+
+static const char *xpm_tree_view[] = {
+"22 22 2 1",
+". c None",
+"# c #000000",
+"......................",
+"......................",
+"......#...............",
+"......#...............",
+"......#...............",
+"......#...............",
+"......#...............",
+"......########........",
+"......#...............",
+"......#...............",
+"......#...............",
+"......#...............",
+"......#...............",
+"......########........",
+"......#...............",
+"......#...............",
+"......#...............",
+"......#...............",
+"......#...............",
+"......########........",
+"......................",
+"......................"};
+
+static const char *xpm_single_view[] = {
+"22 22 2 1",
+". c None",
+"# c #000000",
+"......................",
+"......................",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"..........#...........",
+"......................",
+"......................"};
+
+static const char *xpm_split_view[] = {
+"22 22 2 1",
+". c None",
+"# c #000000",
+"......................",
+"......................",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......#......#........",
+"......................",
+"......................"};
+
+static const char *xpm_symbol_no[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .......... ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" .......... ",
+" "};
+
+static const char *xpm_symbol_mod[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .......... ",
+" . . ",
+" . . ",
+" . .. . ",
+" . .... . ",
+" . .... . ",
+" . .. . ",
+" . . ",
+" . . ",
+" .......... ",
+" "};
+
+static const char *xpm_symbol_yes[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .......... ",
+" . . ",
+" . . ",
+" . . . ",
+" . .. . ",
+" . . .. . ",
+" . .... . ",
+" . .. . ",
+" . . ",
+" .......... ",
+" "};
+
+static const char *xpm_choice_no[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .... ",
+" .. .. ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" .. .. ",
+" .... ",
+" "};
+
+static const char *xpm_choice_yes[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .... ",
+" .. .. ",
+" . . ",
+" . .. . ",
+" . .... . ",
+" . .... . ",
+" . .. . ",
+" . . ",
+" .. .. ",
+" .... ",
+" "};
+
+static const char *xpm_menu[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .......... ",
+" . . ",
+" . .. . ",
+" . .... . ",
+" . ...... . ",
+" . ...... . ",
+" . .... . ",
+" . .. . ",
+" . . ",
+" .......... ",
+" "};
+
+static const char *xpm_menu_inv[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .......... ",
+" .......... ",
+" .. ...... ",
+" .. .... ",
+" .. .. ",
+" .. .. ",
+" .. .... ",
+" .. ...... ",
+" .......... ",
+" .......... ",
+" "};
+
+static const char *xpm_menuback[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" .......... ",
+" . . ",
+" . .. . ",
+" . .... . ",
+" . ...... . ",
+" . ...... . ",
+" . .... . ",
+" . .. . ",
+" . . ",
+" .......... ",
+" "};
+
+static const char *xpm_void[] = {
+"12 12 2 1",
+" c white",
+". c black",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
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 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "lkc.h"
+
+#define P(name,type,arg) type (*name ## _p) arg
+#include "lkc_proto.h"
+#undef P
+
+void kconfig_load(void)
+{
+ void *handle;
+ char *error;
+
+ handle = dlopen("./libkconfig.so", RTLD_LAZY);
+ if (!handle) {
+ handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY);
+ if (!handle) {
+ fprintf(stderr, "%s\n", dlerror());
+ exit(1);
+ }
+ }
+
+#define P(name,type,arg) \
+{ \
+ name ## _p = dlsym(handle, #name); \
+ if ((error = dlerror())) { \
+ fprintf(stderr, "%s\n", error); \
+ exit(1); \
+ } \
+}
+#include "lkc_proto.h"
+#undef P
+}
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 @@
+
+#line 3 "lex.zconf.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 31
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE zconfrestart(zconfin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int zconfleng;
+
+extern FILE *zconfin, *zconfout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up zconftext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via zconfrestart()), so that the user can continue scanning by
+ * just pointing zconfin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when zconftext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int zconfleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow zconfwrap()'s to do buffer switches
+ * instead of setting up a fresh zconfin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void zconfrestart (FILE *input_file );
+void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size );
+void zconf_delete_buffer (YY_BUFFER_STATE b );
+void zconf_flush_buffer (YY_BUFFER_STATE b );
+void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer );
+void zconfpop_buffer_state (void );
+
+static void zconfensure_buffer_stack (void );
+static void zconf_load_buffer_state (void );
+static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len );
+
+void *zconfalloc (yy_size_t );
+void *zconfrealloc (void *,yy_size_t );
+void zconffree (void * );
+
+#define yy_new_buffer zconf_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ zconfensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ zconfensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define zconfwrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int zconflineno;
+
+int zconflineno = 1;
+
+extern char *zconftext;
+#define yytext_ptr zconftext
+static yyconst flex_int16_t yy_nxt[][38] =
+ {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+ },
+
+ {
+ 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12
+ },
+
+ {
+ 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12
+ },
+
+ {
+ 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
+ 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
+ 27, 18, 28, 29, 30, 18, 18, 16
+ },
+
+ {
+ 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
+ 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
+ 27, 18, 28, 29, 30, 18, 18, 16
+
+ },
+
+ {
+ 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31
+ },
+
+ {
+ 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31
+ },
+
+ {
+ 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
+ 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
+
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34
+ },
+
+ {
+ 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
+ 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34
+ },
+
+ {
+ 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
+ 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
+ 47, 47, 47, 47, 47, 47, 47, 52
+
+ },
+
+ {
+ 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
+ 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
+ 47, 47, 47, 47, 47, 47, 47, 52
+ },
+
+ {
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11, -11
+ },
+
+ {
+ 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12
+ },
+
+ {
+ 11, -13, 53, 54, -13, -13, 55, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13, -13
+ },
+
+ {
+ 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14, -14
+
+ },
+
+ {
+ 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56
+ },
+
+ {
+ 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16, -16
+ },
+
+ {
+ 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17
+ },
+
+ {
+ 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, 58, -18, -18, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -18
+ },
+
+ {
+ 11, -19, -19, -19, -19, -19, -19, -19, -19, -19,
+ -19, -19, -19, 58, -19, -19, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
+ 58, 58, 58, 58, 58, 58, 58, -19
+
+ },
+
+ {
+ 11, -20, -20, -20, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, 58, -20, -20, 58, 58, 58, 58,
+ 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
+ 58, 58, 58, 58, 58, 58, 58, -20
+ },
+
+ {
+ 11, -21, -21, -21, -21, -21, -21, -21, -21, -21,
+ -21, -21, -21, 58, -21, -21, 58, 58, 58, 58,
+ 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -21
+ },
+
+ {
+ 11, -22, -22, -22, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, 58, -22, -22, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
+ 58, 58, 58, 58, 58, 58, 58, -22
+ },
+
+ {
+ 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, 58, -23, -23, 58, 58, 58, 58,
+ 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -23
+ },
+
+ {
+ 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, 58, -24, -24, 58, 58, 58, 58,
+ 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
+ 58, 58, 58, 58, 58, 58, 58, -24
+
+ },
+
+ {
+ 11, -25, -25, -25, -25, -25, -25, -25, -25, -25,
+ -25, -25, -25, 58, -25, -25, 58, 67, 58, 58,
+ 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -25
+ },
+
+ {
+ 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, 58, -26, -26, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 69, 58, 58, 58, 58, 58, 58, -26
+ },
+
+ {
+ 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, 58, -27, -27, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 70, 58, 58, 58, 58, -27
+ },
+
+ {
+ 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, 58, -28, -28, 58, 71, 58, 58,
+ 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -28
+ },
+
+ {
+ 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, 58, -29, -29, 58, 58, 58, 58,
+ 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
+ 58, 58, 58, 58, 75, 58, 58, -29
+
+ },
+
+ {
+ 11, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, 58, -30, -30, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 76, 58, 58, 58, 58, -30
+ },
+
+ {
+ 11, 77, 77, -31, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77
+ },
+
+ {
+ 11, -32, 78, 79, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+
+ -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32, -32
+ },
+
+ {
+ 11, 80, -33, -33, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80
+ },
+
+ {
+ 11, 81, 81, 82, 81, -34, 81, 81, -34, 81,
+ 81, 81, 81, 81, 81, -34, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81
+
+ },
+
+ {
+ 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, -35, -35, -35, -35, -35, -35, -35
+ },
+
+ {
+ 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36, -36
+ },
+
+ {
+ 11, 83, 83, 84, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83
+ },
+
+ {
+ 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, -38, -38
+ },
+
+ {
+ 11, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39
+
+ },
+
+ {
+ 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, 85, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40
+ },
+
+ {
+ 11, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
+ -41, -41, -41, -41, -41, -41, -41, -41
+ },
+
+ {
+ 11, 86, 86, -42, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86
+ },
+
+ {
+ 11, -43, -43, -43, -43, -43, -43, 87, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43
+ },
+
+ {
+ 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, -44, -44, -44
+
+ },
+
+ {
+ 11, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ -45, -45, -45, -45, -45, -45, -45, -45
+ },
+
+ {
+ 11, -46, -46, -46, -46, -46, -46, -46, -46, -46,
+ -46, 88, 89, 89, -46, -46, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -46
+ },
+
+ {
+ 11, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, 89, 89, 89, -47, -47, 89, 89, 89, 89,
+
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -47
+ },
+
+ {
+ 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48, -48
+ },
+
+ {
+ 11, -49, -49, 90, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
+ -49, -49, -49, -49, -49, -49, -49, -49
+
+ },
+
+ {
+ 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, 89, 89, 89, -50, -50, 89, 89, 89, 89,
+ 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -50
+ },
+
+ {
+ 11, -51, -51, -51, -51, -51, -51, -51, -51, -51,
+ -51, 89, 89, 89, -51, -51, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
+ 89, 89, 89, 89, 89, 89, 89, -51
+ },
+
+ {
+ 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+
+ -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52, 93
+ },
+
+ {
+ 11, -53, 53, 54, -53, -53, 55, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53, -53
+ },
+
+ {
+ 11, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
+ -54, -54, -54, -54, -54, -54, -54, -54
+
+ },
+
+ {
+ 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56
+ },
+
+ {
+ 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56
+ },
+
+ {
+ 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57
+ },
+
+ {
+ 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, 58, -58, -58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -58
+ },
+
+ {
+ 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, 58, -59, -59, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
+ 58, 58, 58, 58, 58, 58, 58, -59
+
+ },
+
+ {
+ 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, -60, -60, 58, -60, -60, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
+ 58, 58, 58, 58, 58, 58, 58, -60
+ },
+
+ {
+ 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
+ -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
+ 58, 58, 58, 58, 58, 58, 58, -61
+ },
+
+ {
+ 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
+ -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
+
+ 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
+ 99, 58, 58, 58, 58, 58, 58, -62
+ },
+
+ {
+ 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
+ -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
+ 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -63
+ },
+
+ {
+ 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
+ -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 103, -64
+
+ },
+
+ {
+ 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
+ -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -65
+ },
+
+ {
+ 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
+ -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 104, 58, 58, -66
+ },
+
+ {
+ 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
+ -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -67
+ },
+
+ {
+ 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
+ -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
+ 58, 58, 58, 58, 58, 58, 58, -68
+ },
+
+ {
+ 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
+ -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 107, 58, 58, -69
+
+ },
+
+ {
+ 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
+ -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
+ 58, 58, 58, 58, 58, 58, 58, -70
+ },
+
+ {
+ 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
+ -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
+ 58, 58, 58, 58, 58, 58, 58, -71
+ },
+
+ {
+ 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
+ -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 110, 58, 58, 58, 58, 58, -72
+ },
+
+ {
+ 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
+ -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -73
+ },
+
+ {
+ 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
+ -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 112, 58, -74
+
+ },
+
+ {
+ 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 113, 58, 58, 58, 58, -75
+ },
+
+ {
+ 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
+ -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -76
+ },
+
+ {
+ 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77
+ },
+
+ {
+ 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78
+ },
+
+ {
+ 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80
+
+ },
+
+ {
+ 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
+ -80, -80, -80, -80, -80, -80, -80, -80
+ },
+
+ {
+ 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
+ 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 81, 81, 81, 81
+ },
+
+ {
+ 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+
+ -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
+ -82, -82, -82, -82, -82, -82, -82, -82
+ },
+
+ {
+ 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83
+ },
+
+ {
+ 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84
+
+ },
+
+ {
+ 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
+ -85, -85, -85, -85, -85, -85, -85, -85
+ },
+
+ {
+ 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86
+ },
+
+ {
+ 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+
+ -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
+ -87, -87, -87, -87, -87, -87, -87, -87
+ },
+
+ {
+ 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
+ -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -88
+ },
+
+ {
+ 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -89
+
+ },
+
+ {
+ 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
+ -90, -90, -90, -90, -90, -90, -90, -90
+ },
+
+ {
+ 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -91
+ },
+
+ {
+ 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
+ -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
+
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -92
+ },
+
+ {
+ 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
+ -93, -93, -93, -93, -93, -93, -93, -93
+ },
+
+ {
+ 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
+ -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -94
+
+ },
+
+ {
+ 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
+ -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -95
+ },
+
+ {
+ 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
+ -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -96
+ },
+
+ {
+ 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
+ -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
+
+ 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -97
+ },
+
+ {
+ 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
+ -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -98
+ },
+
+ {
+ 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
+ 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -99
+
+ },
+
+ {
+ 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
+ -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -100
+ },
+
+ {
+ 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
+ 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -101
+ },
+
+ {
+ 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 127, 58, 58, 58, 58, 58, 58, -102
+ },
+
+ {
+ 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -103
+ },
+
+ {
+ 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
+ -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -104
+
+ },
+
+ {
+ 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
+ 58, 58, 58, 58, 58, 58, 58, -105
+ },
+
+ {
+ 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 129, 58, -106
+ },
+
+ {
+ 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -107
+ },
+
+ {
+ 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -108
+ },
+
+ {
+ 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+ -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
+ 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -109
+
+ },
+
+ {
+ 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+ -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 133, 58, -110
+ },
+
+ {
+ 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
+ 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -111
+ },
+
+ {
+ 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 135, 58, 58, 58, 58, -112
+ },
+
+ {
+ 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
+ -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -113
+ },
+
+ {
+ 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
+ -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 137, 58, 58, 58, -114
+
+ },
+
+ {
+ 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
+ -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 89, -115
+ },
+
+ {
+ 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
+ -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
+ 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -116
+ },
+
+ {
+ 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
+ -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -117
+ },
+
+ {
+ 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
+ -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
+ 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -118
+ },
+
+ {
+ 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
+ -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -119
+
+ },
+
+ {
+ 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
+ -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 143, 58, 58, -120
+ },
+
+ {
+ 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
+ -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 144, 58, -121
+ },
+
+ {
+ 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
+ -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
+ 58, 58, 58, 58, 58, 58, 58, -122
+ },
+
+ {
+ 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
+ -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -123
+ },
+
+ {
+ 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
+ -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
+ 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -124
+
+ },
+
+ {
+ 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
+ -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
+ 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -125
+ },
+
+ {
+ 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
+ -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
+ 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -126
+ },
+
+ {
+ 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
+ -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -127
+ },
+
+ {
+ 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
+ -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -128
+ },
+
+ {
+ 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
+ -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -129
+
+ },
+
+ {
+ 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
+ -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
+ 58, 58, 58, 58, 58, 58, 58, -130
+ },
+
+ {
+ 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
+ -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 153, 58, 58, 58, 58, 58, 58, -131
+ },
+
+ {
+ 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
+ -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
+
+ 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -132
+ },
+
+ {
+ 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
+ -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -133
+ },
+
+ {
+ 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
+ -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -134
+
+ },
+
+ {
+ 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -135
+ },
+
+ {
+ 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
+ -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
+ 58, 58, 58, 58, 58, 58, 58, -136
+ },
+
+ {
+ 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
+ -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 159, 58, 58, -137
+ },
+
+ {
+ 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
+ -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -138
+ },
+
+ {
+ 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
+ -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
+ 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -139
+
+ },
+
+ {
+ 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
+ -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
+ 58, 58, 58, 58, 58, 58, 58, -140
+ },
+
+ {
+ 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
+ -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
+ 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -141
+ },
+
+ {
+ 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
+ -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
+ 58, 58, 58, 58, 58, 58, 58, -142
+ },
+
+ {
+ 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
+ -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 165, 58, 58, 58, 58, -143
+ },
+
+ {
+ 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
+ -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -144
+
+ },
+
+ {
+ 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
+ -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
+ 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -145
+ },
+
+ {
+ 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
+ -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
+ 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -146
+ },
+
+ {
+ 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
+ -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
+ 58, 58, 58, 58, 58, 58, 58, -147
+ },
+
+ {
+ 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
+ -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -148
+ },
+
+ {
+ 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
+ -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
+ 58, 58, 58, 58, 58, 58, 58, -149
+
+ },
+
+ {
+ 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
+ -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
+ 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -150
+ },
+
+ {
+ 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
+ -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
+ 58, 58, 58, 58, 58, 58, 58, -151
+ },
+
+ {
+ 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
+ -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
+ 58, 58, 58, 58, 58, 58, 58, -152
+ },
+
+ {
+ 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
+ -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 174, 58, 58, -153
+ },
+
+ {
+ 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
+ -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -154
+
+ },
+
+ {
+ 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
+ -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 175, 58, 58, 58, 58, -155
+ },
+
+ {
+ 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
+ -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 176, 58, 58, -156
+ },
+
+ {
+ 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
+ -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
+
+ 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -157
+ },
+
+ {
+ 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
+ -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
+ 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -158
+ },
+
+ {
+ 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
+ -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -159
+
+ },
+
+ {
+ 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
+ -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
+ 58, 58, 58, 58, 58, 58, 58, -160
+ },
+
+ {
+ 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
+ -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -161
+ },
+
+ {
+ 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
+ -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 181, 58, 58, -162
+ },
+
+ {
+ 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
+ -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -163
+ },
+
+ {
+ 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
+ -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
+ 58, 58, 58, 58, 58, 58, 58, -164
+
+ },
+
+ {
+ 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
+ -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -165
+ },
+
+ {
+ 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
+ -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 184, 58, 58, -166
+ },
+
+ {
+ 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
+ -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 185, 58, 58, 58, -167
+ },
+
+ {
+ 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
+ -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -168
+ },
+
+ {
+ 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
+ -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -169
+
+ },
+
+ {
+ 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
+ -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 187, 58, -170
+ },
+
+ {
+ 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
+ -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
+ 58, 58, 58, 58, 58, 58, 58, -171
+ },
+
+ {
+ 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
+ -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
+ 58, 58, 58, 58, 58, 58, 58, -172
+ },
+
+ {
+ 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
+ -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -173
+ },
+
+ {
+ 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
+ -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -174
+
+ },
+
+ {
+ 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
+ -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
+ 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -175
+ },
+
+ {
+ 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
+ -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -176
+ },
+
+ {
+ 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
+ -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -177
+ },
+
+ {
+ 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
+ -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -178
+ },
+
+ {
+ 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
+ -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 192, 58, 58, -179
+
+ },
+
+ {
+ 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
+ -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -180
+ },
+
+ {
+ 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
+ -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -181
+ },
+
+ {
+ 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
+ -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -182
+ },
+
+ {
+ 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
+ -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 194, 58, 58, 58, -183
+ },
+
+ {
+ 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
+ -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -184
+
+ },
+
+ {
+ 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
+ -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -185
+ },
+
+ {
+ 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
+ -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -186
+ },
+
+ {
+ 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
+ -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -187
+ },
+
+ {
+ 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
+ -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 196, 58, -188
+ },
+
+ {
+ 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
+ -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
+ 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -189
+
+ },
+
+ {
+ 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
+ -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -190
+ },
+
+ {
+ 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
+ -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 199, 58, 58, 58, -191
+ },
+
+ {
+ 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
+ -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
+
+ 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -192
+ },
+
+ {
+ 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
+ -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
+ 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -193
+ },
+
+ {
+ 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
+ -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 202, 58, 58, -194
+
+ },
+
+ {
+ 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
+ -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
+ 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -195
+ },
+
+ {
+ 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
+ -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -196
+ },
+
+ {
+ 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
+ -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -197
+ },
+
+ {
+ 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
+ -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -198
+ },
+
+ {
+ 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
+ -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -199
+
+ },
+
+ {
+ 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
+ -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -200
+ },
+
+ {
+ 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
+ -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -201
+ },
+
+ {
+ 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
+ -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -202
+ },
+
+ {
+ 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
+ -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -203
+ },
+
+ {
+ 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
+ -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
+ 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -204
+
+ },
+
+ {
+ 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
+ -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
+ 58, 58, 58, 58, 58, 58, 58, -205
+ },
+
+ {
+ 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
+ -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 209, 58, 58, -206
+ },
+
+ {
+ 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
+ -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -207
+ },
+
+ {
+ 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
+ -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -208
+ },
+
+ {
+ 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
+ -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
+ 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -209
+
+ },
+
+ {
+ 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
+ -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, -210
+ },
+
+ } ;
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up zconftext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ zconfleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 64
+#define YY_END_OF_BUFFER 65
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[211] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 65, 5, 4, 3, 2, 36, 37, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 63, 60, 62, 55, 59, 58, 57, 53, 48, 42,
+ 47, 51, 53, 40, 41, 50, 50, 43, 53, 50,
+ 50, 53, 4, 3, 2, 2, 1, 35, 35, 35,
+ 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
+ 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
+ 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
+
+ 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
+ 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
+ 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
+ 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
+ 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
+ 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
+
+ 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 6, 1, 1, 7, 8, 9,
+ 10, 1, 1, 1, 11, 12, 12, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 1, 1, 1,
+ 14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 1, 15, 1, 1, 16, 1, 17, 18, 19, 20,
+
+ 21, 22, 23, 24, 25, 13, 13, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 13, 13, 36,
+ 13, 13, 1, 37, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+extern int zconf_flex_debug;
+int zconf_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *zconftext;
+
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define START_STRSIZE 16
+
+char *text;
+static char *text_ptr;
+static int text_size, text_asize;
+
+struct buffer {
+ struct buffer *parent;
+ YY_BUFFER_STATE state;
+};
+
+struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static void zconf_endhelp(void);
+static struct buffer *zconf_endfile(void);
+
+void new_string(void)
+{
+ text = malloc(START_STRSIZE);
+ text_asize = START_STRSIZE;
+ text_ptr = text;
+ text_size = 0;
+ *text_ptr = 0;
+}
+
+void append_string(const char *str, int size)
+{
+ int new_size = text_size + size + 1;
+ if (new_size > text_asize) {
+ text = realloc(text, new_size);
+ text_asize = new_size;
+ text_ptr = text + text_size;
+ }
+ memcpy(text_ptr, str, size);
+ text_ptr += size;
+ text_size += size;
+ *text_ptr = 0;
+}
+
+void alloc_string(const char *str, int size)
+{
+ text = malloc(size + 1);
+ memcpy(text, str, size);
+ text[size] = 0;
+}
+
+#define INITIAL 0
+#define COMMAND 1
+#define HELP 2
+#define STRING 3
+#define PARAM 4
+
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int zconfwrap (void );
+#else
+extern int zconfwrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( zconftext, zconfleng, 1, zconfout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ errno=0; \
+ while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(zconfin); \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int zconflex (void);
+
+#define YY_DECL int zconflex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after zconftext and zconfleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+ int str = 0;
+ int ts, i;
+
+ if ( (yy_init) )
+ {
+ (yy_init) = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! zconfin )
+ zconfin = stdin;
+
+ if ( ! zconfout )
+ zconfout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ zconfensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ zconf_create_buffer(zconfin,YY_BUF_SIZE );
+ }
+
+ zconf_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of zconftext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 )
+ ++yy_cp;
+
+ yy_current_state = -yy_current_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+/* rule 1 can match eol */
+YY_RULE_SETUP
+current_file->lineno++;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+current_file->lineno++; return T_EOL;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+{
+ BEGIN(COMMAND);
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+{
+ unput(zconftext[0]);
+ BEGIN(COMMAND);
+}
+ YY_BREAK
+
+case 6:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_MAINMENU;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_MENU;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_ENDMENU;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_SOURCE;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_CHOICE;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_ENDCHOICE;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_COMMENT;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_CONFIG;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_MENUCONFIG;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_HELP;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_IF;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_ENDIF;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEPENDS;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_REQUIRES;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_OPTIONAL;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEFAULT;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_PROMPT;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_TRISTATE;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEF_TRISTATE;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_BOOLEAN;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_BOOLEAN;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEF_BOOLEAN;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_DEF_BOOLEAN;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_INT;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_HEX;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_STRING;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_SELECT;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_SELECT;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+BEGIN(PARAM); return T_RANGE;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+{
+ alloc_string(zconftext, zconfleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+
+ YY_BREAK
+case 37:
+/* rule 37 can match eol */
+YY_RULE_SETUP
+current_file->lineno++; BEGIN(INITIAL);
+ YY_BREAK
+
+case 38:
+YY_RULE_SETUP
+return T_AND;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+return T_OR;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+return T_OPEN_PAREN;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+return T_CLOSE_PAREN;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+return T_NOT;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+return T_EQUAL;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+return T_UNEQUAL;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+return T_IF;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+return T_ON;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+{
+ str = zconftext[0];
+ new_string();
+ BEGIN(STRING);
+ }
+ YY_BREAK
+case 48:
+/* rule 48 can match eol */
+YY_RULE_SETUP
+BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+/* ignore */
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+{
+ alloc_string(zconftext, zconfleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+/* comment */
+ YY_BREAK
+case 52:
+/* rule 52 can match eol */
+YY_RULE_SETUP
+current_file->lineno++;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+
+ YY_BREAK
+case YY_STATE_EOF(PARAM):
+{
+ BEGIN(INITIAL);
+ }
+ YY_BREAK
+
+case 54:
+/* rule 54 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+ append_string(zconftext, zconfleng);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+{
+ append_string(zconftext, zconfleng);
+ }
+ YY_BREAK
+case 56:
+/* rule 56 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+ append_string(zconftext + 1, zconfleng - 1);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+{
+ append_string(zconftext + 1, zconfleng - 1);
+ }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+{
+ if (str == zconftext[0]) {
+ BEGIN(PARAM);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ } else
+ append_string(zconftext, 1);
+ }
+ YY_BREAK
+case 59:
+/* rule 59 can match eol */
+YY_RULE_SETUP
+{
+ printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
+ current_file->lineno++;
+ BEGIN(INITIAL);
+ return T_EOL;
+ }
+ YY_BREAK
+case YY_STATE_EOF(STRING):
+{
+ BEGIN(INITIAL);
+ }
+ YY_BREAK
+
+case 60:
+YY_RULE_SETUP
+{
+ ts = 0;
+ for (i = 0; i < zconfleng; i++) {
+ if (zconftext[i] == '\t')
+ ts = (ts & ~7) + 8;
+ else
+ ts++;
+ }
+ last_ts = ts;
+ if (first_ts) {
+ if (ts < first_ts) {
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ ts -= first_ts;
+ while (ts > 8) {
+ append_string(" ", 8);
+ ts -= 8;
+ }
+ append_string(" ", ts);
+ }
+ }
+ YY_BREAK
+case 61:
+/* rule 61 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+ current_file->lineno++;
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ YY_BREAK
+case 62:
+/* rule 62 can match eol */
+YY_RULE_SETUP
+{
+ current_file->lineno++;
+ append_string("\n", 1);
+ }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+{
+ append_string(zconftext, zconfleng);
+ if (!first_ts)
+ first_ts = last_ts;
+ }
+ YY_BREAK
+case YY_STATE_EOF(HELP):
+{
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ YY_BREAK
+
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(COMMAND):
+{
+ if (current_buf) {
+ zconf_endfile();
+ return T_EOF;
+ }
+ fclose(zconfin);
+ yyterminate();
+}
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed zconfin at a new source and called
+ * zconflex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( zconfwrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * zconftext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of zconflex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ zconfrestart(zconfin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+
+ yy_current_state = yy_nxt[yy_current_state][1];
+ yy_is_jam = (yy_current_state <= 0);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up zconftext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ zconfrestart(zconfin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( zconfwrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve zconftext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void zconfrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ zconfensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ zconf_create_buffer(zconfin,YY_BUF_SIZE );
+ }
+
+ zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
+ zconf_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * zconfpop_buffer_state();
+ * zconfpush_buffer_state(new_buffer);
+ */
+ zconfensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ zconf_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (zconfwrap()) processing, but the only time this flag
+ * is looked at is after zconfwrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void zconf_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ zconf_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with zconf_create_buffer()
+ *
+ */
+ void zconf_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ zconffree((void *) b->yy_ch_buf );
+
+ zconffree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a zconfrestart() or at EOF.
+ */
+ static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ zconf_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then zconf_init_buffer was _probably_
+ * called from zconfrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void zconf_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ zconf_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ zconfensure_buffer_stack();
+
+ /* This block is copied from zconf_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from zconf_switch_to_buffer. */
+ zconf_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void zconfpop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ zconf_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ zconf_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void zconfensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ zconf_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to zconflex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * zconf_scan_bytes() instead.
+ */
+YY_BUFFER_STATE zconf_scan_string (yyconst char * str )
+{
+
+ return zconf_scan_bytes(str,strlen(str) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) zconfalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = zconf_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up zconftext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ zconftext[zconfleng] = (yy_hold_char); \
+ (yy_c_buf_p) = zconftext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ zconfleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int zconfget_lineno (void)
+{
+
+ return zconflineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *zconfget_in (void)
+{
+ return zconfin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *zconfget_out (void)
+{
+ return zconfout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int zconfget_leng (void)
+{
+ return zconfleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *zconfget_text (void)
+{
+ return zconftext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void zconfset_lineno (int line_number )
+{
+
+ zconflineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see zconf_switch_to_buffer
+ */
+void zconfset_in (FILE * in_str )
+{
+ zconfin = in_str ;
+}
+
+void zconfset_out (FILE * out_str )
+{
+ zconfout = out_str ;
+}
+
+int zconfget_debug (void)
+{
+ return zconf_flex_debug;
+}
+
+void zconfset_debug (int bdebug )
+{
+ zconf_flex_debug = bdebug ;
+}
+
+/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
+int zconflex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ zconf_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ zconfpop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ zconffree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *zconfalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *zconfrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void zconffree (void * ptr )
+{
+ free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+void zconf_starthelp(void)
+{
+ new_string();
+ last_ts = first_ts = 0;
+ BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+ zconflval.string = text;
+ BEGIN(INITIAL);
+}
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+ char *env, fullname[PATH_MAX+1];
+ FILE *f;
+
+ f = fopen(name, "r");
+ if (!f && name[0] != '/') {
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ f = fopen(fullname, "r");
+ }
+ }
+ return f;
+}
+
+void zconf_initscan(const char *name)
+{
+ zconfin = zconf_fopen(name);
+ if (!zconfin) {
+ printf("can't find file %s\n", name);
+ exit(1);
+ }
+
+ current_buf = malloc(sizeof(*current_buf));
+ memset(current_buf, 0, sizeof(*current_buf));
+
+ current_file = file_lookup(name);
+ current_file->lineno = 1;
+ current_file->flags = FILE_BUSY;
+}
+
+void zconf_nextfile(const char *name)
+{
+ struct file *file = file_lookup(name);
+ struct buffer *buf = malloc(sizeof(*buf));
+ memset(buf, 0, sizeof(*buf));
+
+ current_buf->state = YY_CURRENT_BUFFER;
+ zconfin = zconf_fopen(name);
+ if (!zconfin) {
+ printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
+ exit(1);
+ }
+ zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
+ buf->parent = current_buf;
+ current_buf = buf;
+
+ if (file->flags & FILE_BUSY) {
+ printf("recursive scan (%s)?\n", name);
+ exit(1);
+ }
+ if (file->flags & FILE_SCANNED) {
+ printf("file %s already scanned?\n", name);
+ exit(1);
+ }
+ file->flags |= FILE_BUSY;
+ file->lineno = 1;
+ file->parent = current_file;
+ current_file = file;
+}
+
+static struct buffer *zconf_endfile(void)
+{
+ struct buffer *parent;
+
+ current_file->flags |= FILE_SCANNED;
+ current_file->flags &= ~FILE_BUSY;
+ current_file = current_file->parent;
+
+ parent = current_buf->parent;
+ if (parent) {
+ fclose(zconfin);
+ zconf_delete_buffer(YY_CURRENT_BUFFER);
+ zconf_switch_to_buffer(parent->state);
+ }
+ free(current_buf);
+ current_buf = parent;
+
+ return parent;
+}
+
+int zconf_lineno(void)
+{
+ if (current_buf)
+ return current_file->lineno - 1;
+ else
+ return 0;
+}
+
+char *zconf_curname(void)
+{
+ if (current_buf)
+ return current_file->name;
+ else
+ return "<none>";
+}
+
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#ifndef LKC_H
+#define LKC_H
+
+#include "expr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LKC_DIRECT_LINK
+#define P(name,type,arg) extern type name arg
+#else
+#include "lkc_defs.h"
+#define P(name,type,arg) extern type (*name ## _p) arg
+#endif
+#include "lkc_proto.h"
+#undef P
+
+#define SRCTREE "srctree"
+
+int zconfparse(void);
+void zconfdump(FILE *out);
+
+extern int zconfdebug;
+void zconf_starthelp(void);
+FILE *zconf_fopen(const char *name);
+void zconf_initscan(const char *name);
+void zconf_nextfile(const char *name);
+int zconf_lineno(void);
+char *zconf_curname(void);
+
+/* confdata.c */
+extern const char conf_def_filename[];
+extern char conf_filename[];
+
+char *conf_get_default_confname(void);
+
+/* kconfig_load.c */
+void kconfig_load(void);
+
+/* menu.c */
+void menu_init(void);
+void menu_add_menu(void);
+void menu_end_menu(void);
+void menu_add_entry(struct symbol *sym);
+void menu_end_entry(void);
+void menu_add_dep(struct expr *dep);
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
+void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
+void menu_finalize(struct menu *parent);
+void menu_set_type(int type);
+
+/* util.c */
+struct file *file_lookup(const char *name);
+int file_write_dep(const char *name);
+
+struct gstr {
+ size_t len;
+ char *s;
+};
+struct gstr str_new(void);
+struct gstr str_assign(const char *s);
+void str_free(struct gstr *gs);
+void str_append(struct gstr *gs, const char *s);
+void str_printf(struct gstr *gs, const char *fmt, ...);
+const char *str_get(struct gstr *gs);
+
+/* symbol.c */
+void sym_init(void);
+void sym_clear_all_valid(void);
+void sym_set_changed(struct symbol *sym);
+struct symbol *sym_check_deps(struct symbol *sym);
+struct property *prop_alloc(enum prop_type type, struct symbol *sym);
+struct symbol *prop_get_symbol(struct property *prop);
+
+static inline tristate sym_get_tristate_value(struct symbol *sym)
+{
+ return sym->curr.tri;
+}
+
+
+static inline struct symbol *sym_get_choice_value(struct symbol *sym)
+{
+ return (struct symbol *)sym->curr.val;
+}
+
+static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
+{
+ return sym_set_tristate_value(chval, yes);
+}
+
+static inline bool sym_is_choice(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_CHOICE ? true : false;
+}
+
+static inline bool sym_is_choice_value(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_CHOICEVAL ? true : false;
+}
+
+static inline bool sym_is_optional(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_OPTIONAL ? true : false;
+}
+
+static inline bool sym_has_value(struct symbol *sym)
+{
+ return sym->flags & SYMBOL_NEW ? false : true;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#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 @@
+
+/* confdata.c */
+P(conf_parse,void,(const char *name));
+P(conf_read,int,(const char *name));
+P(conf_write,int,(const char *name));
+
+/* menu.c */
+P(rootmenu,struct menu,);
+
+P(menu_is_visible,bool,(struct menu *menu));
+P(menu_get_prompt,const char *,(struct menu *menu));
+P(menu_get_root_menu,struct menu *,(struct menu *menu));
+P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+
+/* symbol.c */
+P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
+P(sym_change_count,int,);
+
+P(sym_lookup,struct symbol *,(const char *name, int isconst));
+P(sym_find,struct symbol *,(const char *name));
+P(sym_re_search,struct symbol **,(const char *pattern));
+P(sym_type_name,const char *,(enum symbol_type type));
+P(sym_calc_value,void,(struct symbol *sym));
+P(sym_get_type,enum symbol_type,(struct symbol *sym));
+P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
+P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
+P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
+P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
+P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
+P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
+P(sym_is_changable,bool,(struct symbol *sym));
+P(sym_get_choice_prop,struct property *,(struct symbol *sym));
+P(sym_get_default_prop,struct property *,(struct symbol *sym));
+P(sym_get_string_value,const char *,(struct symbol *sym));
+
+P(prop_get_type_name,const char *,(enum prop_type type));
+
+/* expr.c */
+P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
+P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken));
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
new file mode 100644
index 000000000000..730d316fe7fe
--- /dev/null
+++ b/scripts/kconfig/mconf.c
@@ -0,0 +1,1090 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ * Introduced single menu mode (show all sub-menus in one large tree).
+ * 2002-11-06 Petr Baudis <pasky@ucw.cz>
+ */
+
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+static char menu_backtitle[128];
+static const char mconf_readme[] =
+"Overview\n"
+"--------\n"
+"Some kernel features may be built directly into the kernel.\n"
+"Some may be made into loadable runtime modules. Some features\n"
+"may be completely removed altogether. There are also certain\n"
+"kernel parameters which are not really features, but must be\n"
+"entered in as decimal or hexadecimal numbers or possibly text.\n"
+"\n"
+"Menu items beginning with [*], <M> or [ ] represent features\n"
+"configured to be built in, modularized or removed respectively.\n"
+"Pointed brackets <> represent module capable features.\n"
+"\n"
+"To change any of these features, highlight it with the cursor\n"
+"keys and press <Y> to build it in, <M> to make it a module or\n"
+"<N> to removed it. You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->M->Y).\n"
+"\n"
+"Some additional keyboard hints:\n"
+"\n"
+"Menus\n"
+"----------\n"
+"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
+" you wish to change or submenu wish to select and press <Enter>.\n"
+" Submenus are designated by \"--->\".\n"
+"\n"
+" Shortcut: Press the option's highlighted letter (hotkey).\n"
+" Pressing a hotkey more than once will sequence\n"
+" through all visible items which use that hotkey.\n"
+"\n"
+" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
+" unseen options into view.\n"
+"\n"
+"o To exit a menu use the cursor keys to highlight the <Exit> button\n"
+" and press <ENTER>.\n"
+"\n"
+" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
+" using those letters. You may press a single <ESC>, but\n"
+" there is a delayed response which you may find annoying.\n"
+"\n"
+" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
+" <Exit> and <Help>\n"
+"\n"
+"o To get help with an item, use the cursor keys to highlight <Help>\n"
+" and Press <ENTER>.\n"
+"\n"
+" Shortcut: Press <H> or <?>.\n"
+"\n"
+"\n"
+"Radiolists (Choice lists)\n"
+"-----------\n"
+"o Use the cursor keys to select the option you wish to set and press\n"
+" <S> or the <SPACE BAR>.\n"
+"\n"
+" Shortcut: Press the first letter of the option you wish to set then\n"
+" press <S> or <SPACE BAR>.\n"
+"\n"
+"o To see available help for the item, use the cursor keys to highlight\n"
+" <Help> and Press <ENTER>.\n"
+"\n"
+" Shortcut: Press <H> or <?>.\n"
+"\n"
+" Also, the <TAB> and cursor keys will cycle between <Select> and\n"
+" <Help>\n"
+"\n"
+"\n"
+"Data Entry\n"
+"-----------\n"
+"o Enter the requested information and press <ENTER>\n"
+" If you are entering hexadecimal values, it is not necessary to\n"
+" add the '0x' prefix to the entry.\n"
+"\n"
+"o For help, use the <TAB> or cursor keys to highlight the help option\n"
+" and press <ENTER>. You can try <TAB><H> as well.\n"
+"\n"
+"\n"
+"Text Box (Help Window)\n"
+"--------\n"
+"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
+" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
+" who are familiar with less and lynx.\n"
+"\n"
+"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
+"\n"
+"\n"
+"Alternate Configuration Files\n"
+"-----------------------------\n"
+"Menuconfig supports the use of alternate configuration files for\n"
+"those who, for various reasons, find it necessary to switch\n"
+"between different kernel configurations.\n"
+"\n"
+"At the end of the main menu you will find two options. One is\n"
+"for saving the current configuration to a file of your choosing.\n"
+"The other option is for loading a previously saved alternate\n"
+"configuration.\n"
+"\n"
+"Even if you don't use alternate configuration files, but you\n"
+"find during a Menuconfig session that you have completely messed\n"
+"up your settings, you may use the \"Load Alternate...\" option to\n"
+"restore your previously saved settings from \".config\" without\n"
+"restarting Menuconfig.\n"
+"\n"
+"Other information\n"
+"-----------------\n"
+"If you use Menuconfig in an XTERM window make sure you have your\n"
+"$TERM variable set to point to a xterm definition which supports color.\n"
+"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n"
+"display correctly in a RXVT window because rxvt displays only one\n"
+"intensity of color, bright.\n"
+"\n"
+"Menuconfig will display larger menus on screens or xterms which are\n"
+"set to display more than the standard 25 row by 80 column geometry.\n"
+"In order for this to work, the \"stty size\" command must be able to\n"
+"display the screen's current row and column geometry. I STRONGLY\n"
+"RECOMMEND that you make sure you do NOT have the shell variables\n"
+"LINES and COLUMNS exported into your environment. Some distributions\n"
+"export those variables via /etc/profile. Some ncurses programs can\n"
+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
+"the true screen size.\n"
+"\n"
+"Optional personality available\n"
+"------------------------------\n"
+"If you prefer to have all of the kernel options listed in a single\n"
+"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
+"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
+"\n"
+"make MENUCONFIG_MODE=single_menu menuconfig\n"
+"\n"
+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
+"is already unrolled.\n"
+"\n"
+"Note that this mode can eventually be a little more CPU expensive\n"
+"(especially with a larger number of unrolled categories) than the\n"
+"default mode.\n",
+menu_instructions[] =
+ "Arrow keys navigate the menu. "
+ "<Enter> selects submenus --->. "
+ "Highlighted letters are hotkeys. "
+ "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
+ "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
+ "Legend: [*] built-in [ ] excluded <M> module < > module capable",
+radiolist_instructions[] =
+ "Use the arrow keys to navigate this window or "
+ "press the hotkey of the item you wish to select "
+ "followed by the <SPACE BAR>. "
+ "Press <?> for additional information about this option.",
+inputbox_instructions_int[] =
+ "Please enter a decimal value. "
+ "Fractions will not be accepted. "
+ "Use the <TAB> key to move from the input field to the buttons below it.",
+inputbox_instructions_hex[] =
+ "Please enter a hexadecimal value. "
+ "Use the <TAB> key to move from the input field to the buttons below it.",
+inputbox_instructions_string[] =
+ "Please enter a string value. "
+ "Use the <TAB> key to move from the input field to the buttons below it.",
+setmod_text[] =
+ "This feature depends on another which has been configured as a module.\n"
+ "As a result, this feature will be built as a module.",
+nohelp_text[] =
+ "There is no help available for this kernel option.\n",
+load_config_text[] =
+ "Enter the name of the configuration file you wish to load. "
+ "Accept the name shown to restore the configuration you "
+ "last retrieved. Leave blank to abort.",
+load_config_help[] =
+ "\n"
+ "For various reasons, one may wish to keep several different kernel\n"
+ "configurations available on a single machine.\n"
+ "\n"
+ "If you have saved a previous configuration in a file other than the\n"
+ "kernel's default, entering the name of the file here will allow you\n"
+ "to modify that configuration.\n"
+ "\n"
+ "If you are uncertain, then you have probably never used alternate\n"
+ "configuration files. You should therefor leave this blank to abort.\n",
+save_config_text[] =
+ "Enter a filename to which this configuration should be saved "
+ "as an alternate. Leave blank to abort.",
+save_config_help[] =
+ "\n"
+ "For various reasons, one may wish to keep different kernel\n"
+ "configurations available on a single machine.\n"
+ "\n"
+ "Entering a file name here will allow you to later retrieve, modify\n"
+ "and use the current configuration as an alternate to whatever\n"
+ "configuration options you have selected at that time.\n"
+ "\n"
+ "If you are uncertain what all this means then you should probably\n"
+ "leave this blank.\n",
+search_help[] =
+ "\n"
+ "Search for CONFIG_ symbols and display their relations.\n"
+ "Example: search for \"^FOO\"\n"
+ "Result:\n"
+ "-----------------------------------------------------------------\n"
+ "Symbol: FOO [=m]\n"
+ "Prompt: Foo bus is used to drive the bar HW\n"
+ "Defined at drivers/pci/Kconfig:47\n"
+ "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+ "Location:\n"
+ " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
+ " -> PCI support (PCI [=y])\n"
+ " -> PCI access mode (<choice> [=y])\n"
+ "Selects: LIBCRC32\n"
+ "Selected by: BAR\n"
+ "-----------------------------------------------------------------\n"
+ "o The line 'Prompt:' shows the text used in the menu structure for\n"
+ " this CONFIG_ symbol\n"
+ "o The 'Defined at' line tell at what file / line number the symbol\n"
+ " is defined\n"
+ "o The 'Depends on:' line tell what symbols needs to be defined for\n"
+ " this symbol to be visible in the menu (selectable)\n"
+ "o The 'Location:' lines tell where in the menu structure this symbol\n"
+ " is located\n"
+ " A location followed by a [=y] indicate that this is a selectable\n"
+ " menu item - and current value is displayed inside brackets.\n"
+ "o The 'Selects:' line tell what symbol will be automatically\n"
+ " selected if this symbol is selected (y or m)\n"
+ "o The 'Selected by' line tell what symbol has selected this symbol\n"
+ "\n"
+ "Only relevant lines are shown.\n"
+ "\n\n"
+ "Search examples:\n"
+ "Examples: USB => find all CONFIG_ symbols containing USB\n"
+ " ^USB => find all CONFIG_ symbols starting with USB\n"
+ " USB$ => find all CONFIG_ symbols ending with USB\n"
+ "\n";
+
+static signed char buf[4096], *bufptr = buf;
+static signed char input_buf[4096];
+static char filename[PATH_MAX+1] = ".config";
+static char *args[1024], **argptr = args;
+static int indent;
+static struct termios ios_org;
+static int rows = 0, cols = 0;
+static struct menu *current_menu;
+static int child_count;
+static int do_resize;
+static int single_menu_mode;
+
+static void conf(struct menu *menu);
+static void conf_choice(struct menu *menu);
+static void conf_string(struct menu *menu);
+static void conf_load(void);
+static void conf_save(void);
+static void show_textbox(const char *title, const char *text, int r, int c);
+static void show_helptext(const char *title, const char *text);
+static void show_help(struct menu *menu);
+static void show_file(const char *filename, const char *title, int r, int c);
+
+static void cprint_init(void);
+static int cprint1(const char *fmt, ...);
+static void cprint_done(void);
+static int cprint(const char *fmt, ...);
+
+static void init_wsize(void)
+{
+ struct winsize ws;
+ char *env;
+
+ if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
+ rows = ws.ws_row;
+ cols = ws.ws_col;
+ }
+
+ if (!rows) {
+ env = getenv("LINES");
+ if (env)
+ rows = atoi(env);
+ if (!rows)
+ rows = 24;
+ }
+ if (!cols) {
+ env = getenv("COLUMNS");
+ if (env)
+ cols = atoi(env);
+ if (!cols)
+ cols = 80;
+ }
+
+ if (rows < 19 || cols < 80) {
+ fprintf(stderr, "Your display is too small to run Menuconfig!\n");
+ fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
+ exit(1);
+ }
+
+ rows -= 4;
+ cols -= 5;
+}
+
+static void cprint_init(void)
+{
+ bufptr = buf;
+ argptr = args;
+ memset(args, 0, sizeof(args));
+ indent = 0;
+ child_count = 0;
+ cprint("./scripts/lxdialog/lxdialog");
+ cprint("--backtitle");
+ cprint(menu_backtitle);
+}
+
+static int cprint1(const char *fmt, ...)
+{
+ va_list ap;
+ int res;
+
+ if (!*argptr)
+ *argptr = bufptr;
+ va_start(ap, fmt);
+ res = vsprintf(bufptr, fmt, ap);
+ va_end(ap);
+ bufptr += res;
+
+ return res;
+}
+
+static void cprint_done(void)
+{
+ *bufptr++ = 0;
+ argptr++;
+}
+
+static int cprint(const char *fmt, ...)
+{
+ va_list ap;
+ int res;
+
+ *argptr++ = bufptr;
+ va_start(ap, fmt);
+ res = vsprintf(bufptr, fmt, ap);
+ va_end(ap);
+ bufptr += res;
+ *bufptr++ = 0;
+
+ return res;
+}
+
+static void get_prompt_str(struct gstr *r, struct property *prop)
+{
+ int i, j;
+ struct menu *submenu[8], *menu;
+
+ str_printf(r, "Prompt: %s\n", prop->text);
+ str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
+ prop->menu->lineno);
+ if (!expr_is_yes(prop->visible.expr)) {
+ str_append(r, " Depends on: ");
+ expr_gstr_print(prop->visible.expr, r);
+ str_append(r, "\n");
+ }
+ menu = prop->menu->parent;
+ for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+ submenu[i++] = menu;
+ if (i > 0) {
+ str_printf(r, " Location:\n");
+ for (j = 4; --i >= 0; j += 2) {
+ menu = submenu[i];
+ str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+ if (menu->sym) {
+ str_printf(r, " (%s [=%s])", menu->sym->name ?
+ menu->sym->name : "<choice>",
+ sym_get_string_value(menu->sym));
+ }
+ str_append(r, "\n");
+ }
+ }
+}
+
+static void get_symbol_str(struct gstr *r, struct symbol *sym)
+{
+ bool hit;
+ struct property *prop;
+
+ str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+ sym_get_string_value(sym));
+ for_all_prompts(sym, prop)
+ get_prompt_str(r, prop);
+ hit = false;
+ for_all_properties(sym, prop, P_SELECT) {
+ if (!hit) {
+ str_append(r, " Selects: ");
+ hit = true;
+ } else
+ str_printf(r, " && ");
+ expr_gstr_print(prop->expr, r);
+ }
+ if (hit)
+ str_append(r, "\n");
+ if (sym->rev_dep.expr) {
+ str_append(r, " Selected by: ");
+ expr_gstr_print(sym->rev_dep.expr, r);
+ str_append(r, "\n");
+ }
+ str_append(r, "\n\n");
+}
+
+static struct gstr get_relations_str(struct symbol **sym_arr)
+{
+ struct symbol *sym;
+ struct gstr res = str_new();
+ int i;
+
+ for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
+ get_symbol_str(&res, sym);
+ if (!i)
+ str_append(&res, "No matches found.\n");
+ return res;
+}
+
+pid_t pid;
+
+static void winch_handler(int sig)
+{
+ if (!do_resize) {
+ kill(pid, SIGINT);
+ do_resize = 1;
+ }
+}
+
+static int exec_conf(void)
+{
+ int pipefd[2], stat, size;
+ struct sigaction sa;
+ sigset_t sset, osset;
+
+ sigemptyset(&sset);
+ sigaddset(&sset, SIGINT);
+ sigprocmask(SIG_BLOCK, &sset, &osset);
+
+ signal(SIGINT, SIG_DFL);
+
+ sa.sa_handler = winch_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGWINCH, &sa, NULL);
+
+ *argptr++ = NULL;
+
+ pipe(pipefd);
+ pid = fork();
+ if (pid == 0) {
+ sigprocmask(SIG_SETMASK, &osset, NULL);
+ dup2(pipefd[1], 2);
+ close(pipefd[0]);
+ close(pipefd[1]);
+ execv(args[0], args);
+ _exit(EXIT_FAILURE);
+ }
+
+ close(pipefd[1]);
+ bufptr = input_buf;
+ while (1) {
+ size = input_buf + sizeof(input_buf) - bufptr;
+ size = read(pipefd[0], bufptr, size);
+ if (size <= 0) {
+ if (size < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ perror("read");
+ }
+ break;
+ }
+ bufptr += size;
+ }
+ *bufptr++ = 0;
+ close(pipefd[0]);
+ waitpid(pid, &stat, 0);
+
+ if (do_resize) {
+ init_wsize();
+ do_resize = 0;
+ sigprocmask(SIG_SETMASK, &osset, NULL);
+ return -1;
+ }
+ if (WIFSIGNALED(stat)) {
+ printf("\finterrupted(%d)\n", WTERMSIG(stat));
+ exit(1);
+ }
+#if 0
+ printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
+ sleep(1);
+#endif
+ sigpending(&sset);
+ if (sigismember(&sset, SIGINT)) {
+ printf("\finterrupted\n");
+ exit(1);
+ }
+ sigprocmask(SIG_SETMASK, &osset, NULL);
+
+ return WEXITSTATUS(stat);
+}
+
+static void search_conf(void)
+{
+ struct symbol **sym_arr;
+ int stat;
+ struct gstr res;
+
+again:
+ cprint_init();
+ cprint("--title");
+ cprint("Search Configuration Parameter");
+ cprint("--inputbox");
+ cprint("Enter Keyword");
+ cprint("10");
+ cprint("75");
+ cprint("");
+ stat = exec_conf();
+ if (stat < 0)
+ goto again;
+ switch (stat) {
+ case 0:
+ break;
+ case 1:
+ show_helptext("Search Configuration", search_help);
+ goto again;
+ default:
+ return;
+ }
+
+ sym_arr = sym_re_search(input_buf);
+ res = get_relations_str(sym_arr);
+ free(sym_arr);
+ show_textbox("Search Results", str_get(&res), 0, 0);
+ str_free(&res);
+}
+
+static void build_conf(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+ int type, tmp, doint = 2;
+ tristate val;
+ char ch;
+
+ if (!menu_is_visible(menu))
+ return;
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ if (!sym) {
+ if (prop && menu != current_menu) {
+ const char *prompt = menu_get_prompt(menu);
+ switch (prop->type) {
+ case P_MENU:
+ child_count++;
+ cprint("m%p", menu);
+
+ if (single_menu_mode) {
+ cprint1("%s%*c%s",
+ menu->data ? "-->" : "++>",
+ indent + 1, ' ', prompt);
+ } else
+ cprint1(" %*c%s --->", indent + 1, ' ', prompt);
+
+ cprint_done();
+ if (single_menu_mode && menu->data)
+ goto conf_childs;
+ return;
+ default:
+ if (prompt) {
+ child_count++;
+ cprint(":%p", menu);
+ cprint("---%*c%s", indent + 1, ' ', prompt);
+ }
+ }
+ } else
+ doint = 0;
+ goto conf_childs;
+ }
+
+ type = sym_get_type(sym);
+ if (sym_is_choice(sym)) {
+ struct symbol *def_sym = sym_get_choice_value(sym);
+ struct menu *def_menu = NULL;
+
+ child_count++;
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child) && child->sym == def_sym)
+ def_menu = child;
+ }
+
+ val = sym_get_tristate_value(sym);
+ if (sym_is_changable(sym)) {
+ cprint("t%p", menu);
+ switch (type) {
+ case S_BOOLEAN:
+ cprint1("[%c]", val == no ? ' ' : '*');
+ break;
+ case S_TRISTATE:
+ switch (val) {
+ case yes: ch = '*'; break;
+ case mod: ch = 'M'; break;
+ default: ch = ' '; break;
+ }
+ cprint1("<%c>", ch);
+ break;
+ }
+ } else {
+ cprint("%c%p", def_menu ? 't' : ':', menu);
+ cprint1(" ");
+ }
+
+ cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ if (val == yes) {
+ if (def_menu) {
+ cprint1(" (%s)", menu_get_prompt(def_menu));
+ cprint1(" --->");
+ cprint_done();
+ if (def_menu->list) {
+ indent += 2;
+ build_conf(def_menu);
+ indent -= 2;
+ }
+ } else
+ cprint_done();
+ return;
+ }
+ cprint_done();
+ } else {
+ if (menu == current_menu) {
+ cprint(":%p", menu);
+ cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ goto conf_childs;
+ }
+ child_count++;
+ val = sym_get_tristate_value(sym);
+ if (sym_is_choice_value(sym) && val == yes) {
+ cprint(":%p", menu);
+ cprint1(" ");
+ } else {
+ switch (type) {
+ case S_BOOLEAN:
+ cprint("t%p", menu);
+ if (sym_is_changable(sym))
+ cprint1("[%c]", val == no ? ' ' : '*');
+ else
+ cprint1("---");
+ break;
+ case S_TRISTATE:
+ cprint("t%p", menu);
+ switch (val) {
+ case yes: ch = '*'; break;
+ case mod: ch = 'M'; break;
+ default: ch = ' '; break;
+ }
+ if (sym_is_changable(sym))
+ cprint1("<%c>", ch);
+ else
+ cprint1("---");
+ break;
+ default:
+ cprint("s%p", menu);
+ tmp = cprint1("(%s)", sym_get_string_value(sym));
+ tmp = indent - tmp + 4;
+ if (tmp < 0)
+ tmp = 0;
+ cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
+ cprint_done();
+ goto conf_childs;
+ }
+ }
+ cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : " (NEW)");
+ if (menu->prompt->type == P_MENU) {
+ cprint1(" --->");
+ cprint_done();
+ return;
+ }
+ cprint_done();
+ }
+
+conf_childs:
+ indent += doint;
+ for (child = menu->list; child; child = child->next)
+ build_conf(child);
+ indent -= doint;
+}
+
+static void conf(struct menu *menu)
+{
+ struct menu *submenu;
+ const char *prompt = menu_get_prompt(menu);
+ struct symbol *sym;
+ char active_entry[40];
+ int stat, type, i;
+
+ unlink("lxdialog.scrltmp");
+ active_entry[0] = 0;
+ while (1) {
+ cprint_init();
+ cprint("--title");
+ cprint("%s", prompt ? prompt : "Main Menu");
+ cprint("--menu");
+ cprint(menu_instructions);
+ cprint("%d", rows);
+ cprint("%d", cols);
+ cprint("%d", rows - 10);
+ cprint("%s", active_entry);
+ current_menu = menu;
+ build_conf(menu);
+ if (!child_count)
+ break;
+ if (menu == &rootmenu) {
+ cprint(":");
+ cprint("--- ");
+ cprint("L");
+ cprint(" Load an Alternate Configuration File");
+ cprint("S");
+ cprint(" Save Configuration to an Alternate File");
+ }
+ stat = exec_conf();
+ if (stat < 0)
+ continue;
+
+ if (stat == 1 || stat == 255)
+ break;
+
+ type = input_buf[0];
+ if (!type)
+ continue;
+
+ for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
+ ;
+ if (i >= sizeof(active_entry))
+ i = sizeof(active_entry) - 1;
+ input_buf[i] = 0;
+ strcpy(active_entry, input_buf);
+
+ sym = NULL;
+ submenu = NULL;
+ if (sscanf(input_buf + 1, "%p", &submenu) == 1)
+ sym = submenu->sym;
+
+ switch (stat) {
+ case 0:
+ switch (type) {
+ case 'm':
+ if (single_menu_mode)
+ submenu->data = (void *) (long) !submenu->data;
+ else
+ conf(submenu);
+ break;
+ case 't':
+ if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
+ conf_choice(submenu);
+ else if (submenu->prompt->type == P_MENU)
+ conf(submenu);
+ break;
+ case 's':
+ conf_string(submenu);
+ break;
+ case 'L':
+ conf_load();
+ break;
+ case 'S':
+ conf_save();
+ break;
+ }
+ break;
+ case 2:
+ if (sym)
+ show_help(submenu);
+ else
+ show_helptext("README", mconf_readme);
+ break;
+ case 3:
+ if (type == 't') {
+ if (sym_set_tristate_value(sym, yes))
+ break;
+ if (sym_set_tristate_value(sym, mod))
+ show_textbox(NULL, setmod_text, 6, 74);
+ }
+ break;
+ case 4:
+ if (type == 't')
+ sym_set_tristate_value(sym, no);
+ break;
+ case 5:
+ if (type == 't')
+ sym_set_tristate_value(sym, mod);
+ break;
+ case 6:
+ if (type == 't')
+ sym_toggle_tristate_value(sym);
+ else if (type == 'm')
+ conf(submenu);
+ break;
+ case 7:
+ search_conf();
+ break;
+ }
+ }
+}
+
+static void show_textbox(const char *title, const char *text, int r, int c)
+{
+ int fd;
+
+ fd = creat(".help.tmp", 0777);
+ write(fd, text, strlen(text));
+ close(fd);
+ show_file(".help.tmp", title, r, c);
+ unlink(".help.tmp");
+}
+
+static void show_helptext(const char *title, const char *text)
+{
+ show_textbox(title, text, 0, 0);
+}
+
+static void show_help(struct menu *menu)
+{
+ struct gstr help = str_new();
+ struct symbol *sym = menu->sym;
+
+ if (sym->help)
+ {
+ if (sym->name) {
+ str_printf(&help, "CONFIG_%s:\n\n", sym->name);
+ str_append(&help, sym->help);
+ str_append(&help, "\n");
+ }
+ } else {
+ str_append(&help, nohelp_text);
+ }
+ get_symbol_str(&help, sym);
+ show_helptext(menu_get_prompt(menu), str_get(&help));
+ str_free(&help);
+}
+
+static void show_file(const char *filename, const char *title, int r, int c)
+{
+ do {
+ cprint_init();
+ if (title) {
+ cprint("--title");
+ cprint("%s", title);
+ }
+ cprint("--textbox");
+ cprint("%s", filename);
+ cprint("%d", r ? r : rows);
+ cprint("%d", c ? c : cols);
+ } while (exec_conf() < 0);
+}
+
+static void conf_choice(struct menu *menu)
+{
+ const char *prompt = menu_get_prompt(menu);
+ struct menu *child;
+ struct symbol *active;
+ int stat;
+
+ active = sym_get_choice_value(menu->sym);
+ while (1) {
+ cprint_init();
+ cprint("--title");
+ cprint("%s", prompt ? prompt : "Main Menu");
+ cprint("--radiolist");
+ cprint(radiolist_instructions);
+ cprint("15");
+ cprint("70");
+ cprint("6");
+
+ current_menu = menu;
+ for (child = menu->list; child; child = child->next) {
+ if (!menu_is_visible(child))
+ continue;
+ cprint("%p", child);
+ cprint("%s", menu_get_prompt(child));
+ if (child->sym == sym_get_choice_value(menu->sym))
+ cprint("ON");
+ else if (child->sym == active)
+ cprint("SELECTED");
+ else
+ cprint("OFF");
+ }
+
+ stat = exec_conf();
+ switch (stat) {
+ case 0:
+ if (sscanf(input_buf, "%p", &child) != 1)
+ break;
+ sym_set_tristate_value(child->sym, yes);
+ return;
+ case 1:
+ if (sscanf(input_buf, "%p", &child) == 1) {
+ show_help(child);
+ active = child->sym;
+ } else
+ show_help(menu);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_string(struct menu *menu)
+{
+ const char *prompt = menu_get_prompt(menu);
+ int stat;
+
+ while (1) {
+ cprint_init();
+ cprint("--title");
+ cprint("%s", prompt ? prompt : "Main Menu");
+ cprint("--inputbox");
+ switch (sym_get_type(menu->sym)) {
+ case S_INT:
+ cprint(inputbox_instructions_int);
+ break;
+ case S_HEX:
+ cprint(inputbox_instructions_hex);
+ break;
+ case S_STRING:
+ cprint(inputbox_instructions_string);
+ break;
+ default:
+ /* panic? */;
+ }
+ cprint("10");
+ cprint("75");
+ cprint("%s", sym_get_string_value(menu->sym));
+ stat = exec_conf();
+ switch (stat) {
+ case 0:
+ if (sym_set_string_value(menu->sym, input_buf))
+ return;
+ show_textbox(NULL, "You have made an invalid entry.", 5, 43);
+ break;
+ case 1:
+ show_help(menu);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_load(void)
+{
+ int stat;
+
+ while (1) {
+ cprint_init();
+ cprint("--inputbox");
+ cprint(load_config_text);
+ cprint("11");
+ cprint("55");
+ cprint("%s", filename);
+ stat = exec_conf();
+ switch(stat) {
+ case 0:
+ if (!input_buf[0])
+ return;
+ if (!conf_read(input_buf))
+ return;
+ show_textbox(NULL, "File does not exist!", 5, 38);
+ break;
+ case 1:
+ show_helptext("Load Alternate Configuration", load_config_help);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_save(void)
+{
+ int stat;
+
+ while (1) {
+ cprint_init();
+ cprint("--inputbox");
+ cprint(save_config_text);
+ cprint("11");
+ cprint("55");
+ cprint("%s", filename);
+ stat = exec_conf();
+ switch(stat) {
+ case 0:
+ if (!input_buf[0])
+ return;
+ if (!conf_write(input_buf))
+ return;
+ show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
+ break;
+ case 1:
+ show_helptext("Save Alternate Configuration", save_config_help);
+ break;
+ case 255:
+ return;
+ }
+ }
+}
+
+static void conf_cleanup(void)
+{
+ tcsetattr(1, TCSAFLUSH, &ios_org);
+ unlink(".help.tmp");
+ unlink("lxdialog.scrltmp");
+}
+
+int main(int ac, char **av)
+{
+ struct symbol *sym;
+ char *mode;
+ int stat;
+
+ conf_parse(av[1]);
+ conf_read(NULL);
+
+ sym = sym_lookup("KERNELRELEASE", 0);
+ sym_calc_value(sym);
+ sprintf(menu_backtitle, "Linux Kernel v%s Configuration",
+ sym_get_string_value(sym));
+
+ mode = getenv("MENUCONFIG_MODE");
+ if (mode) {
+ if (!strcasecmp(mode, "single_menu"))
+ single_menu_mode = 1;
+ }
+
+ tcgetattr(1, &ios_org);
+ atexit(conf_cleanup);
+ init_wsize();
+ conf(&rootmenu);
+
+ do {
+ cprint_init();
+ cprint("--yesno");
+ cprint("Do you wish to save your new kernel configuration?");
+ cprint("5");
+ cprint("60");
+ stat = exec_conf();
+ } while (stat < 0);
+
+ if (stat == 0) {
+ if (conf_write(NULL)) {
+ fprintf(stderr, "\n\n"
+ "Error during writing of the kernel configuration.\n"
+ "Your kernel configuration changes were NOT saved."
+ "\n\n");
+ return 1;
+ }
+ printf("\n\n"
+ "*** End of Linux kernel configuration.\n"
+ "*** Execute 'make' to build the kernel or try 'make help'."
+ "\n\n");
+ } else {
+ fprintf(stderr, "\n\n"
+ "Your kernel configuration changes were NOT saved."
+ "\n\n");
+ }
+
+ return 0;
+}
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+struct menu rootmenu;
+static struct menu **last_entry_ptr;
+
+struct file *file_list;
+struct file *current_file;
+
+static void menu_warn(struct menu *menu, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+static void prop_warn(struct property *prop, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+void menu_init(void)
+{
+ current_entry = current_menu = &rootmenu;
+ last_entry_ptr = &rootmenu.list;
+}
+
+void menu_add_entry(struct symbol *sym)
+{
+ struct menu *menu;
+
+ menu = malloc(sizeof(*menu));
+ memset(menu, 0, sizeof(*menu));
+ menu->sym = sym;
+ menu->parent = current_menu;
+ menu->file = current_file;
+ menu->lineno = zconf_lineno();
+
+ *last_entry_ptr = menu;
+ last_entry_ptr = &menu->next;
+ current_entry = menu;
+}
+
+void menu_end_entry(void)
+{
+}
+
+void menu_add_menu(void)
+{
+ current_menu = current_entry;
+ last_entry_ptr = &current_entry->list;
+}
+
+void menu_end_menu(void)
+{
+ last_entry_ptr = &current_menu->next;
+ current_menu = current_menu->parent;
+}
+
+struct expr *menu_check_dep(struct expr *e)
+{
+ if (!e)
+ return e;
+
+ switch (e->type) {
+ case E_NOT:
+ e->left.expr = menu_check_dep(e->left.expr);
+ break;
+ case E_OR:
+ case E_AND:
+ e->left.expr = menu_check_dep(e->left.expr);
+ e->right.expr = menu_check_dep(e->right.expr);
+ break;
+ case E_SYMBOL:
+ /* change 'm' into 'm' && MODULES */
+ if (e->left.sym == &symbol_mod)
+ return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+ break;
+ default:
+ break;
+ }
+ return e;
+}
+
+void menu_add_dep(struct expr *dep)
+{
+ current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+}
+
+void menu_set_type(int type)
+{
+ struct symbol *sym = current_entry->sym;
+
+ if (sym->type == type)
+ return;
+ if (sym->type == S_UNKNOWN) {
+ sym->type = type;
+ return;
+ }
+ menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n",
+ sym->name ? sym->name : "<choice>",
+ sym_type_name(sym->type), sym_type_name(type));
+}
+
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
+{
+ struct property *prop = prop_alloc(type, current_entry->sym);
+
+ prop->menu = current_entry;
+ prop->text = prompt;
+ prop->expr = expr;
+ prop->visible.expr = menu_check_dep(dep);
+
+ if (prompt) {
+ if (current_entry->prompt)
+ menu_warn(current_entry, "prompt redefined\n");
+ current_entry->prompt = prop;
+ }
+
+ return prop;
+}
+
+void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
+{
+ menu_add_prop(type, prompt, NULL, dep);
+}
+
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
+{
+ menu_add_prop(type, NULL, expr, dep);
+}
+
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
+{
+ menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
+}
+
+void sym_check_prop(struct symbol *sym)
+{
+ struct property *prop;
+ struct symbol *sym2;
+ for (prop = sym->prop; prop; prop = prop->next) {
+ switch (prop->type) {
+ case P_DEFAULT:
+ if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+ prop->expr->type != E_SYMBOL)
+ prop_warn(prop,
+ "default for config symbol '%'"
+ " must be a single symbol", sym->name);
+ break;
+ case P_SELECT:
+ sym2 = prop_get_symbol(prop);
+ if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
+ prop_warn(prop,
+ "config symbol '%s' uses select, but is "
+ "not boolean or tristate", sym->name);
+ else if (sym2->type == S_UNKNOWN)
+ prop_warn(prop,
+ "'select' used by config symbol '%s' "
+ "refer to undefined symbol '%s'",
+ sym->name, sym2->name);
+ else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
+ prop_warn(prop,
+ "'%s' has wrong type. 'select' only "
+ "accept arguments of boolean and "
+ "tristate type", sym2->name);
+ break;
+ case P_RANGE:
+ if (sym->type != S_INT && sym->type != S_HEX)
+ prop_warn(prop, "range is only allowed "
+ "for int or hex symbols");
+ if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
+ !sym_string_valid(sym, prop->expr->right.sym->name))
+ prop_warn(prop, "range is invalid");
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+void menu_finalize(struct menu *parent)
+{
+ struct menu *menu, *last_menu;
+ struct symbol *sym;
+ struct property *prop;
+ struct expr *parentdep, *basedep, *dep, *dep2, **ep;
+
+ sym = parent->sym;
+ if (parent->list) {
+ if (sym && sym_is_choice(sym)) {
+ /* find the first choice value and find out choice type */
+ for (menu = parent->list; menu; menu = menu->next) {
+ if (menu->sym) {
+ current_entry = parent;
+ menu_set_type(menu->sym->type);
+ current_entry = menu;
+ menu_set_type(sym->type);
+ break;
+ }
+ }
+ parentdep = expr_alloc_symbol(sym);
+ } else if (parent->prompt)
+ parentdep = parent->prompt->visible.expr;
+ else
+ parentdep = parent->dep;
+
+ for (menu = parent->list; menu; menu = menu->next) {
+ basedep = expr_transform(menu->dep);
+ basedep = expr_alloc_and(expr_copy(parentdep), basedep);
+ basedep = expr_eliminate_dups(basedep);
+ menu->dep = basedep;
+ if (menu->sym)
+ prop = menu->sym->prop;
+ else
+ prop = menu->prompt;
+ for (; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ dep = expr_transform(prop->visible.expr);
+ dep = expr_alloc_and(expr_copy(basedep), dep);
+ dep = expr_eliminate_dups(dep);
+ if (menu->sym && menu->sym->type != S_TRISTATE)
+ dep = expr_trans_bool(dep);
+ prop->visible.expr = dep;
+ if (prop->type == P_SELECT) {
+ struct symbol *es = prop_get_symbol(prop);
+ es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
+ expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
+ }
+ }
+ }
+ for (menu = parent->list; menu; menu = menu->next)
+ menu_finalize(menu);
+ } else if (sym) {
+ basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
+ basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
+ basedep = expr_eliminate_dups(expr_transform(basedep));
+ last_menu = NULL;
+ for (menu = parent->next; menu; menu = menu->next) {
+ dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
+ if (!expr_contains_symbol(dep, sym))
+ break;
+ if (expr_depends_symbol(dep, sym))
+ goto next;
+ dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
+ dep = expr_eliminate_dups(expr_transform(dep));
+ dep2 = expr_copy(basedep);
+ expr_eliminate_eq(&dep, &dep2);
+ expr_free(dep);
+ if (!expr_is_yes(dep2)) {
+ expr_free(dep2);
+ break;
+ }
+ expr_free(dep2);
+ next:
+ menu_finalize(menu);
+ menu->parent = parent;
+ last_menu = menu;
+ }
+ if (last_menu) {
+ parent->list = parent->next;
+ parent->next = last_menu->next;
+ last_menu->next = NULL;
+ }
+ }
+ for (menu = parent->list; menu; menu = menu->next) {
+ if (sym && sym_is_choice(sym) && menu->sym) {
+ menu->sym->flags |= SYMBOL_CHOICEVAL;
+ if (!menu->prompt)
+ menu_warn(menu, "choice value must have a prompt");
+ for (prop = menu->sym->prop; prop; prop = prop->next) {
+ if (prop->type == P_PROMPT && prop->menu != menu) {
+ prop_warn(prop, "choice values "
+ "currently only support a "
+ "single prompt");
+ }
+ if (prop->type == P_DEFAULT)
+ prop_warn(prop, "defaults for choice "
+ "values not supported");
+ }
+ current_entry = menu;
+ menu_set_type(sym->type);
+ menu_add_symbol(P_CHOICE, sym, NULL);
+ prop = sym_get_choice_prop(sym);
+ for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
+ ;
+ *ep = expr_alloc_one(E_CHOICE, NULL);
+ (*ep)->right.sym = menu->sym;
+ }
+ if (menu->list && (!menu->prompt || !menu->prompt->text)) {
+ for (last_menu = menu->list; ; last_menu = last_menu->next) {
+ last_menu->parent = parent;
+ if (!last_menu->next)
+ break;
+ }
+ last_menu->next = menu->next;
+ menu->next = menu->list;
+ menu->list = NULL;
+ }
+ }
+
+ if (sym && !(sym->flags & SYMBOL_WARNED)) {
+ if (sym->type == S_UNKNOWN)
+ menu_warn(parent, "config symbol defined "
+ "without type\n");
+
+ if (sym_is_choice(sym) && !parent->prompt)
+ menu_warn(parent, "choice must have a prompt\n");
+
+ /* Check properties connected to this symbol */
+ sym_check_prop(sym);
+ sym->flags |= SYMBOL_WARNED;
+ }
+
+ if (sym && !sym_is_optional(sym) && parent->prompt) {
+ sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
+ expr_alloc_and(parent->prompt->visible.expr,
+ expr_alloc_symbol(&symbol_mod)));
+ }
+}
+
+bool menu_is_visible(struct menu *menu)
+{
+ struct menu *child;
+ struct symbol *sym;
+ tristate visible;
+
+ if (!menu->prompt)
+ return false;
+ sym = menu->sym;
+ if (sym) {
+ sym_calc_value(sym);
+ visible = menu->prompt->visible.tri;
+ } else
+ visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
+
+ if (visible != no)
+ return true;
+ if (!sym || sym_get_tristate_value(menu->sym) == no)
+ return false;
+
+ for (child = menu->list; child; child = child->next)
+ if (menu_is_visible(child))
+ return true;
+ return false;
+}
+
+const char *menu_get_prompt(struct menu *menu)
+{
+ if (menu->prompt)
+ return menu->prompt->text;
+ else if (menu->sym)
+ return menu->sym->name;
+ return NULL;
+}
+
+struct menu *menu_get_root_menu(struct menu *menu)
+{
+ return &rootmenu;
+}
+
+struct menu *menu_get_parent_menu(struct menu *menu)
+{
+ enum prop_type type;
+
+ for (; menu != &rootmenu; menu = menu->parent) {
+ type = menu->prompt ? menu->prompt->type : 0;
+ if (type == P_MENU)
+ break;
+ }
+ return menu;
+}
+
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qtoolbar.h>
+#include <qvbox.h>
+#include <qsplitter.h>
+#include <qlistview.h>
+#include <qtextview.h>
+#include <qlineedit.h>
+#include <qmenubar.h>
+#include <qmessagebox.h>
+#include <qaction.h>
+#include <qheader.h>
+#include <qfiledialog.h>
+#include <qregexp.h>
+
+#include <stdlib.h>
+
+#include "lkc.h"
+#include "qconf.h"
+
+#include "qconf.moc"
+#include "images.c"
+
+static QApplication *configApp;
+
+ConfigSettings::ConfigSettings()
+ : showAll(false), showName(false), showRange(false), showData(false)
+{
+}
+
+#if QT_VERSION >= 300
+/**
+ * Reads the list column settings from the application settings.
+ */
+void ConfigSettings::readListSettings()
+{
+ showAll = readBoolEntry("/kconfig/qconf/showAll", false);
+ showName = readBoolEntry("/kconfig/qconf/showName", false);
+ showRange = readBoolEntry("/kconfig/qconf/showRange", false);
+ showData = readBoolEntry("/kconfig/qconf/showData", false);
+}
+
+/**
+ * Reads a list of integer values from the application settings.
+ */
+QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
+{
+ QValueList<int> result;
+ QStringList entryList = readListEntry(key, ok);
+ if (ok) {
+ QStringList::Iterator it;
+ for (it = entryList.begin(); it != entryList.end(); ++it)
+ result.push_back((*it).toInt());
+ }
+
+ return result;
+}
+
+/**
+ * Writes a list of integer values to the application settings.
+ */
+bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
+{
+ QStringList stringList;
+ QValueList<int>::ConstIterator it;
+
+ for (it = value.begin(); it != value.end(); ++it)
+ stringList.push_back(QString::number(*it));
+ return writeEntry(key, stringList);
+}
+#endif
+
+
+/*
+ * update all the children of a menu entry
+ * removes/adds the entries from the parent widget as necessary
+ *
+ * parent: either the menu list widget or a menu entry widget
+ * menu: entry to be updated
+ */
+template <class P>
+void ConfigList::updateMenuList(P* parent, struct menu* menu)
+{
+ struct menu* child;
+ ConfigItem* item;
+ ConfigItem* last;
+ bool visible;
+ enum prop_type type;
+
+ if (!menu) {
+ while ((item = parent->firstChild()))
+ delete item;
+ return;
+ }
+
+ last = parent->firstChild();
+ if (last && !last->goParent)
+ last = 0;
+ for (child = menu->list; child; child = child->next) {
+ item = last ? last->nextSibling() : parent->firstChild();
+ type = child->prompt ? child->prompt->type : P_UNKNOWN;
+
+ switch (mode) {
+ case menuMode:
+ if (!(child->flags & MENU_ROOT))
+ goto hide;
+ break;
+ case symbolMode:
+ if (child->flags & MENU_ROOT)
+ goto hide;
+ break;
+ default:
+ break;
+ }
+
+ visible = menu_is_visible(child);
+ if (showAll || visible) {
+ if (!item || item->menu != child)
+ item = new ConfigItem(parent, last, child, visible);
+ else
+ item->testUpdateMenu(visible);
+
+ if (mode == fullMode || mode == menuMode || type != P_MENU)
+ updateMenuList(item, child);
+ else
+ updateMenuList(item, 0);
+ last = item;
+ continue;
+ }
+ hide:
+ if (item && item->menu == child) {
+ last = parent->firstChild();
+ if (last == item)
+ last = 0;
+ else while (last->nextSibling() != item)
+ last = last->nextSibling();
+ delete item;
+ }
+ }
+}
+
+#if QT_VERSION >= 300
+/*
+ * set the new data
+ * TODO check the value
+ */
+void ConfigItem::okRename(int col)
+{
+ Parent::okRename(col);
+ sym_set_string_value(menu->sym, text(dataColIdx).latin1());
+}
+#endif
+
+/*
+ * update the displayed of a menu entry
+ */
+void ConfigItem::updateMenu(void)
+{
+ ConfigList* list;
+ struct symbol* sym;
+ struct property *prop;
+ QString prompt;
+ int type;
+ tristate expr;
+
+ list = listView();
+ if (goParent) {
+ setPixmap(promptColIdx, list->menuBackPix);
+ prompt = "..";
+ goto set_prompt;
+ }
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ prompt = menu_get_prompt(menu);
+
+ if (prop) switch (prop->type) {
+ case P_MENU:
+ if (list->mode == singleMode || list->mode == symbolMode) {
+ /* a menuconfig entry is displayed differently
+ * depending whether it's at the view root or a child.
+ */
+ if (sym && list->rootEntry == menu)
+ break;
+ setPixmap(promptColIdx, list->menuPix);
+ } else {
+ if (sym)
+ break;
+ setPixmap(promptColIdx, 0);
+ }
+ goto set_prompt;
+ case P_COMMENT:
+ setPixmap(promptColIdx, 0);
+ goto set_prompt;
+ default:
+ ;
+ }
+ if (!sym)
+ goto set_prompt;
+
+ setText(nameColIdx, sym->name);
+
+ type = sym_get_type(sym);
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ char ch;
+
+ if (!sym_is_changable(sym) && !list->showAll) {
+ setPixmap(promptColIdx, 0);
+ setText(noColIdx, 0);
+ setText(modColIdx, 0);
+ setText(yesColIdx, 0);
+ break;
+ }
+ expr = sym_get_tristate_value(sym);
+ switch (expr) {
+ case yes:
+ if (sym_is_choice_value(sym) && type == S_BOOLEAN)
+ setPixmap(promptColIdx, list->choiceYesPix);
+ else
+ setPixmap(promptColIdx, list->symbolYesPix);
+ setText(yesColIdx, "Y");
+ ch = 'Y';
+ break;
+ case mod:
+ setPixmap(promptColIdx, list->symbolModPix);
+ setText(modColIdx, "M");
+ ch = 'M';
+ break;
+ default:
+ if (sym_is_choice_value(sym) && type == S_BOOLEAN)
+ setPixmap(promptColIdx, list->choiceNoPix);
+ else
+ setPixmap(promptColIdx, list->symbolNoPix);
+ setText(noColIdx, "N");
+ ch = 'N';
+ break;
+ }
+ if (expr != no)
+ setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
+ if (expr != mod)
+ setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
+ if (expr != yes)
+ setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
+
+ setText(dataColIdx, QChar(ch));
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ const char* data;
+
+ data = sym_get_string_value(sym);
+#if QT_VERSION >= 300
+ int i = list->mapIdx(dataColIdx);
+ if (i >= 0)
+ setRenameEnabled(i, TRUE);
+#endif
+ setText(dataColIdx, data);
+ if (type == S_STRING)
+ prompt.sprintf("%s: %s", prompt.latin1(), data);
+ else
+ prompt.sprintf("(%s) %s", data, prompt.latin1());
+ break;
+ }
+ if (!sym_has_value(sym) && visible)
+ prompt += " (NEW)";
+set_prompt:
+ setText(promptColIdx, prompt);
+}
+
+void ConfigItem::testUpdateMenu(bool v)
+{
+ ConfigItem* i;
+
+ visible = v;
+ if (!menu)
+ return;
+
+ sym_calc_value(menu->sym);
+ if (menu->flags & MENU_CHANGED) {
+ /* the menu entry changed, so update all list items */
+ menu->flags &= ~MENU_CHANGED;
+ for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
+ i->updateMenu();
+ } else if (listView()->updateAll)
+ updateMenu();
+}
+
+void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
+{
+ ConfigList* list = listView();
+
+ if (visible) {
+ if (isSelected() && !list->hasFocus() && list->mode == menuMode)
+ Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
+ else
+ Parent::paintCell(p, cg, column, width, align);
+ } else
+ Parent::paintCell(p, list->disabledColorGroup, column, width, align);
+}
+
+/*
+ * construct a menu entry
+ */
+void ConfigItem::init(void)
+{
+ if (menu) {
+ ConfigList* list = listView();
+ nextItem = (ConfigItem*)menu->data;
+ menu->data = this;
+
+ if (list->mode != fullMode)
+ setOpen(TRUE);
+ sym_calc_value(menu->sym);
+ }
+ updateMenu();
+}
+
+/*
+ * destruct a menu entry
+ */
+ConfigItem::~ConfigItem(void)
+{
+ if (menu) {
+ ConfigItem** ip = (ConfigItem**)&menu->data;
+ for (; *ip; ip = &(*ip)->nextItem) {
+ if (*ip == this) {
+ *ip = nextItem;
+ break;
+ }
+ }
+ }
+}
+
+void ConfigLineEdit::show(ConfigItem* i)
+{
+ item = i;
+ if (sym_get_string_value(item->menu->sym))
+ setText(sym_get_string_value(item->menu->sym));
+ else
+ setText(0);
+ Parent::show();
+ setFocus();
+}
+
+void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
+{
+ switch (e->key()) {
+ case Key_Escape:
+ break;
+ case Key_Return:
+ case Key_Enter:
+ sym_set_string_value(item->menu->sym, text().latin1());
+ parent()->updateList(item);
+ break;
+ default:
+ Parent::keyPressEvent(e);
+ return;
+ }
+ e->accept();
+ parent()->list->setFocus();
+ hide();
+}
+
+ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv, ConfigSettings* configSettings)
+ : Parent(p), cview(cv),
+ updateAll(false),
+ symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
+ choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
+ menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
+ showAll(false), showName(false), showRange(false), showData(false),
+ rootEntry(0)
+{
+ int i;
+
+ setSorting(-1);
+ setRootIsDecorated(TRUE);
+ disabledColorGroup = palette().active();
+ disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
+ inactivedColorGroup = palette().active();
+ inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
+
+ connect(this, SIGNAL(selectionChanged(void)),
+ SLOT(updateSelection(void)));
+
+ if (configSettings) {
+ showAll = configSettings->showAll;
+ showName = configSettings->showName;
+ showRange = configSettings->showRange;
+ showData = configSettings->showData;
+ }
+
+ for (i = 0; i < colNr; i++)
+ colMap[i] = colRevMap[i] = -1;
+ addColumn(promptColIdx, "Option");
+
+ reinit();
+}
+
+void ConfigList::reinit(void)
+{
+ removeColumn(dataColIdx);
+ removeColumn(yesColIdx);
+ removeColumn(modColIdx);
+ removeColumn(noColIdx);
+ removeColumn(nameColIdx);
+
+ if (showName)
+ addColumn(nameColIdx, "Name");
+ if (showRange) {
+ addColumn(noColIdx, "N");
+ addColumn(modColIdx, "M");
+ addColumn(yesColIdx, "Y");
+ }
+ if (showData)
+ addColumn(dataColIdx, "Value");
+
+ updateListAll();
+}
+
+void ConfigList::updateSelection(void)
+{
+ struct menu *menu;
+ enum prop_type type;
+
+ ConfigItem* item = (ConfigItem*)selectedItem();
+ if (!item)
+ return;
+
+ cview->setHelp(item);
+
+ menu = item->menu;
+ if (!menu)
+ return;
+ type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (mode == menuMode && type == P_MENU)
+ emit menuSelected(menu);
+}
+
+void ConfigList::updateList(ConfigItem* item)
+{
+ ConfigItem* last = 0;
+
+ if (!rootEntry)
+ goto update;
+
+ if (rootEntry != &rootmenu && (mode == singleMode ||
+ (mode == symbolMode && rootEntry->parent != &rootmenu))) {
+ item = firstChild();
+ if (!item)
+ item = new ConfigItem(this, 0, true);
+ last = item;
+ }
+ if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
+ rootEntry->sym && rootEntry->prompt) {
+ item = last ? last->nextSibling() : firstChild();
+ if (!item)
+ item = new ConfigItem(this, last, rootEntry, true);
+ else
+ item->testUpdateMenu(true);
+
+ updateMenuList(item, rootEntry);
+ triggerUpdate();
+ return;
+ }
+update:
+ updateMenuList(this, rootEntry);
+ triggerUpdate();
+}
+
+void ConfigList::setAllOpen(bool open)
+{
+ QListViewItemIterator it(this);
+
+ for (; it.current(); it++)
+ it.current()->setOpen(open);
+}
+
+void ConfigList::setValue(ConfigItem* item, tristate val)
+{
+ struct symbol* sym;
+ int type;
+ tristate oldval;
+
+ sym = item->menu ? item->menu->sym : 0;
+ if (!sym)
+ return;
+
+ type = sym_get_type(sym);
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ oldval = sym_get_tristate_value(sym);
+
+ if (!sym_set_tristate_value(sym, val))
+ return;
+ if (oldval == no && item->menu->list)
+ item->setOpen(TRUE);
+ parent()->updateList(item);
+ break;
+ }
+}
+
+void ConfigList::changeValue(ConfigItem* item)
+{
+ struct symbol* sym;
+ struct menu* menu;
+ int type, oldexpr, newexpr;
+
+ menu = item->menu;
+ if (!menu)
+ return;
+ sym = menu->sym;
+ if (!sym) {
+ if (item->menu->list)
+ item->setOpen(!item->isOpen());
+ return;
+ }
+
+ type = sym_get_type(sym);
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ oldexpr = sym_get_tristate_value(sym);
+ newexpr = sym_toggle_tristate_value(sym);
+ if (item->menu->list) {
+ if (oldexpr == newexpr)
+ item->setOpen(!item->isOpen());
+ else if (oldexpr == no)
+ item->setOpen(TRUE);
+ }
+ if (oldexpr != newexpr)
+ parent()->updateList(item);
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+#if QT_VERSION >= 300
+ if (colMap[dataColIdx] >= 0)
+ item->startRename(colMap[dataColIdx]);
+ else
+#endif
+ parent()->lineEdit->show(item);
+ break;
+ }
+}
+
+void ConfigList::setRootMenu(struct menu *menu)
+{
+ enum prop_type type;
+
+ if (rootEntry == menu)
+ return;
+ type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (type != P_MENU)
+ return;
+ updateMenuList(this, 0);
+ rootEntry = menu;
+ updateListAll();
+ setSelected(currentItem(), hasFocus());
+}
+
+void ConfigList::setParentMenu(void)
+{
+ ConfigItem* item;
+ struct menu *oldroot;
+
+ oldroot = rootEntry;
+ if (rootEntry == &rootmenu)
+ return;
+ setRootMenu(menu_get_parent_menu(rootEntry->parent));
+
+ QListViewItemIterator it(this);
+ for (; (item = (ConfigItem*)it.current()); it++) {
+ if (item->menu == oldroot) {
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ break;
+ }
+ }
+}
+
+void ConfigList::keyPressEvent(QKeyEvent* ev)
+{
+ QListViewItem* i = currentItem();
+ ConfigItem* item;
+ struct menu *menu;
+ enum prop_type type;
+
+ if (ev->key() == Key_Escape && mode != fullMode) {
+ emit parentSelected();
+ ev->accept();
+ return;
+ }
+
+ if (!i) {
+ Parent::keyPressEvent(ev);
+ return;
+ }
+ item = (ConfigItem*)i;
+
+ switch (ev->key()) {
+ case Key_Return:
+ case Key_Enter:
+ if (item->goParent) {
+ emit parentSelected();
+ break;
+ }
+ menu = item->menu;
+ if (!menu)
+ break;
+ type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (type == P_MENU && rootEntry != menu &&
+ mode != fullMode && mode != menuMode) {
+ emit menuSelected(menu);
+ break;
+ }
+ case Key_Space:
+ changeValue(item);
+ break;
+ case Key_N:
+ setValue(item, no);
+ break;
+ case Key_M:
+ setValue(item, mod);
+ break;
+ case Key_Y:
+ setValue(item, yes);
+ break;
+ default:
+ Parent::keyPressEvent(ev);
+ return;
+ }
+ ev->accept();
+}
+
+void ConfigList::contentsMousePressEvent(QMouseEvent* e)
+{
+ //QPoint p(contentsToViewport(e->pos()));
+ //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMousePressEvent(e);
+}
+
+void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ QPoint p(contentsToViewport(e->pos()));
+ ConfigItem* item = (ConfigItem*)itemAt(p);
+ struct menu *menu;
+ enum prop_type ptype;
+ const QPixmap* pm;
+ int idx, x;
+
+ if (!item)
+ goto skip;
+
+ menu = item->menu;
+ x = header()->offset() + p.x();
+ idx = colRevMap[header()->sectionAt(x)];
+ switch (idx) {
+ case promptColIdx:
+ pm = item->pixmap(promptColIdx);
+ if (pm) {
+ int off = header()->sectionPos(0) + itemMargin() +
+ treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
+ if (x >= off && x < off + pm->width()) {
+ if (item->goParent) {
+ emit parentSelected();
+ break;
+ } else if (!menu)
+ break;
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (ptype == P_MENU && rootEntry != menu &&
+ mode != fullMode && mode != menuMode)
+ emit menuSelected(menu);
+ else
+ changeValue(item);
+ }
+ }
+ break;
+ case noColIdx:
+ setValue(item, no);
+ break;
+ case modColIdx:
+ setValue(item, mod);
+ break;
+ case yesColIdx:
+ setValue(item, yes);
+ break;
+ case dataColIdx:
+ changeValue(item);
+ break;
+ }
+
+skip:
+ //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMouseReleaseEvent(e);
+}
+
+void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ //QPoint p(contentsToViewport(e->pos()));
+ //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMouseMoveEvent(e);
+}
+
+void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
+{
+ QPoint p(contentsToViewport(e->pos()));
+ ConfigItem* item = (ConfigItem*)itemAt(p);
+ struct menu *menu;
+ enum prop_type ptype;
+
+ if (!item)
+ goto skip;
+ if (item->goParent) {
+ emit parentSelected();
+ goto skip;
+ }
+ menu = item->menu;
+ if (!menu)
+ goto skip;
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
+ emit menuSelected(menu);
+ else if (menu->sym)
+ changeValue(item);
+
+skip:
+ //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMouseDoubleClickEvent(e);
+}
+
+void ConfigList::focusInEvent(QFocusEvent *e)
+{
+ Parent::focusInEvent(e);
+
+ QListViewItem* item = currentItem();
+ if (!item)
+ return;
+
+ setSelected(item, TRUE);
+ emit gotFocus();
+}
+
+ConfigView* ConfigView::viewList;
+
+ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview,
+ ConfigSettings *configSettings)
+ : Parent(parent)
+{
+ list = new ConfigList(this, cview, configSettings);
+ lineEdit = new ConfigLineEdit(this);
+ lineEdit->hide();
+
+ this->nextView = viewList;
+ viewList = this;
+}
+
+ConfigView::~ConfigView(void)
+{
+ ConfigView** vp;
+
+ for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
+ if (*vp == this) {
+ *vp = nextView;
+ break;
+ }
+ }
+}
+
+void ConfigView::updateList(ConfigItem* item)
+{
+ ConfigView* v;
+
+ for (v = viewList; v; v = v->nextView)
+ v->list->updateList(item);
+}
+
+void ConfigView::updateListAll(void)
+{
+ ConfigView* v;
+
+ for (v = viewList; v; v = v->nextView)
+ v->list->updateListAll();
+}
+
+/*
+ * Construct the complete config widget
+ */
+ConfigMainWindow::ConfigMainWindow(void)
+{
+ QMenuBar* menu;
+ bool ok;
+ int x, y, width, height;
+
+ QWidget *d = configApp->desktop();
+
+ ConfigSettings* configSettings = new ConfigSettings();
+#if QT_VERSION >= 300
+ width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64);
+ height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64);
+ resize(width, height);
+ x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok);
+ if (ok)
+ y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok);
+ if (ok)
+ move(x, y);
+ showDebug = configSettings->readBoolEntry("/kconfig/qconf/showDebug", false);
+
+ // read list settings into configSettings, will be used later for ConfigList setup
+ configSettings->readListSettings();
+#else
+ width = d->width() - 64;
+ height = d->height() - 64;
+ resize(width, height);
+ showDebug = false;
+#endif
+
+ split1 = new QSplitter(this);
+ split1->setOrientation(QSplitter::Horizontal);
+ setCentralWidget(split1);
+
+ menuView = new ConfigView(split1, this, configSettings);
+ menuList = menuView->list;
+
+ split2 = new QSplitter(split1);
+ split2->setOrientation(QSplitter::Vertical);
+
+ // create config tree
+ configView = new ConfigView(split2, this, configSettings);
+ configList = configView->list;
+
+ helpText = new QTextView(split2);
+ helpText->setTextFormat(Qt::RichText);
+
+ setTabOrder(configList, helpText);
+ configList->setFocus();
+
+ menu = menuBar();
+ toolBar = new QToolBar("Tools", this);
+
+ backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
+ connect(backAction, SIGNAL(activated()), SLOT(goBack()));
+ backAction->setEnabled(FALSE);
+ QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
+ connect(quitAction, SIGNAL(activated()), SLOT(close()));
+ QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
+ connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
+ QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
+ connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
+ QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
+ connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
+ QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
+ connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
+ QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
+ connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
+ QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
+ connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
+
+ QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
+ showNameAction->setToggleAction(TRUE);
+ showNameAction->setOn(configList->showName);
+ connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
+ QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
+ showRangeAction->setToggleAction(TRUE);
+ showRangeAction->setOn(configList->showRange);
+ connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
+ QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
+ showDataAction->setToggleAction(TRUE);
+ showDataAction->setOn(configList->showData);
+ connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
+ QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
+ showAllAction->setToggleAction(TRUE);
+ showAllAction->setOn(configList->showAll);
+ connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
+ QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
+ showDebugAction->setToggleAction(TRUE);
+ showDebugAction->setOn(showDebug);
+ connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
+
+ QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
+ connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
+ QAction *showAboutAction = new QAction(NULL, "About", 0, this);
+ connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
+
+ // init tool bar
+ backAction->addTo(toolBar);
+ toolBar->addSeparator();
+ loadAction->addTo(toolBar);
+ saveAction->addTo(toolBar);
+ toolBar->addSeparator();
+ singleViewAction->addTo(toolBar);
+ splitViewAction->addTo(toolBar);
+ fullViewAction->addTo(toolBar);
+
+ // create config menu
+ QPopupMenu* config = new QPopupMenu(this);
+ menu->insertItem("&File", config);
+ loadAction->addTo(config);
+ saveAction->addTo(config);
+ saveAsAction->addTo(config);
+ config->insertSeparator();
+ quitAction->addTo(config);
+
+ // create options menu
+ QPopupMenu* optionMenu = new QPopupMenu(this);
+ menu->insertItem("&Option", optionMenu);
+ showNameAction->addTo(optionMenu);
+ showRangeAction->addTo(optionMenu);
+ showDataAction->addTo(optionMenu);
+ optionMenu->insertSeparator();
+ showAllAction->addTo(optionMenu);
+ showDebugAction->addTo(optionMenu);
+
+ // create help menu
+ QPopupMenu* helpMenu = new QPopupMenu(this);
+ menu->insertSeparator();
+ menu->insertItem("&Help", helpMenu);
+ showIntroAction->addTo(helpMenu);
+ showAboutAction->addTo(helpMenu);
+
+ connect(configList, SIGNAL(menuSelected(struct menu *)),
+ SLOT(changeMenu(struct menu *)));
+ connect(configList, SIGNAL(parentSelected()),
+ SLOT(goBack()));
+ connect(menuList, SIGNAL(menuSelected(struct menu *)),
+ SLOT(changeMenu(struct menu *)));
+
+ connect(configList, SIGNAL(gotFocus(void)),
+ SLOT(listFocusChanged(void)));
+ connect(menuList, SIGNAL(gotFocus(void)),
+ SLOT(listFocusChanged(void)));
+
+#if QT_VERSION >= 300
+ QString listMode = configSettings->readEntry("/kconfig/qconf/listMode", "symbol");
+ if (listMode == "single")
+ showSingleView();
+ else if (listMode == "full")
+ showFullView();
+ else /*if (listMode == "split")*/
+ showSplitView();
+
+ // UI setup done, restore splitter positions
+ QValueList<int> sizes = configSettings->readSizes("/kconfig/qconf/split1", &ok);
+ if (ok)
+ split1->setSizes(sizes);
+
+ sizes = configSettings->readSizes("/kconfig/qconf/split2", &ok);
+ if (ok)
+ split2->setSizes(sizes);
+#else
+ showSplitView();
+#endif
+ delete configSettings;
+}
+
+static QString print_filter(const char *str)
+{
+ QRegExp re("[<>&\"\\n]");
+ QString res = str;
+ for (int i = 0; (i = res.find(re, i)) >= 0;) {
+ switch (res[i].latin1()) {
+ case '<':
+ res.replace(i, 1, "&lt;");
+ i += 4;
+ break;
+ case '>':
+ res.replace(i, 1, "&gt;");
+ i += 4;
+ break;
+ case '&':
+ res.replace(i, 1, "&amp;");
+ i += 5;
+ break;
+ case '"':
+ res.replace(i, 1, "&quot;");
+ i += 6;
+ break;
+ case '\n':
+ res.replace(i, 1, "<br>");
+ i += 4;
+ break;
+ }
+ }
+ return res;
+}
+
+static void expr_print_help(void *data, const char *str)
+{
+ ((QString*)data)->append(print_filter(str));
+}
+
+/*
+ * display a new help entry as soon as a new menu entry is selected
+ */
+void ConfigMainWindow::setHelp(QListViewItem* item)
+{
+ struct symbol* sym;
+ struct menu* menu = 0;
+
+ configList->parent()->lineEdit->hide();
+ if (item)
+ menu = ((ConfigItem*)item)->menu;
+ if (!menu) {
+ helpText->setText(NULL);
+ return;
+ }
+
+ QString head, debug, help;
+ menu = ((ConfigItem*)item)->menu;
+ sym = menu->sym;
+ if (sym) {
+ if (menu->prompt) {
+ head += "<big><b>";
+ head += print_filter(menu->prompt->text);
+ head += "</b></big>";
+ if (sym->name) {
+ head += " (";
+ head += print_filter(sym->name);
+ head += ")";
+ }
+ } else if (sym->name) {
+ head += "<big><b>";
+ head += print_filter(sym->name);
+ head += "</b></big>";
+ }
+ head += "<br><br>";
+
+ if (showDebug) {
+ debug += "type: ";
+ debug += print_filter(sym_type_name(sym->type));
+ if (sym_is_choice(sym))
+ debug += " (choice)";
+ debug += "<br>";
+ if (sym->rev_dep.expr) {
+ debug += "reverse dep: ";
+ expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ }
+ for (struct property *prop = sym->prop; prop; prop = prop->next) {
+ switch (prop->type) {
+ case P_PROMPT:
+ case P_MENU:
+ debug += "prompt: ";
+ debug += print_filter(prop->text);
+ debug += "<br>";
+ break;
+ case P_DEFAULT:
+ debug += "default: ";
+ expr_print(prop->expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ break;
+ case P_CHOICE:
+ if (sym_is_choice(sym)) {
+ debug += "choice: ";
+ expr_print(prop->expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ }
+ break;
+ case P_SELECT:
+ debug += "select: ";
+ expr_print(prop->expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ break;
+ case P_RANGE:
+ debug += "range: ";
+ expr_print(prop->expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ break;
+ default:
+ debug += "unknown property: ";
+ debug += prop_get_type_name(prop->type);
+ debug += "<br>";
+ }
+ if (prop->visible.expr) {
+ debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
+ expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ }
+ }
+ debug += "<br>";
+ }
+
+ help = print_filter(sym->help);
+ } else if (menu->prompt) {
+ head += "<big><b>";
+ head += print_filter(menu->prompt->text);
+ head += "</b></big><br><br>";
+ if (showDebug) {
+ if (menu->prompt->visible.expr) {
+ debug += "&nbsp;&nbsp;dep: ";
+ expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
+ debug += "<br><br>";
+ }
+ }
+ }
+ if (showDebug)
+ debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
+ helpText->setText(head + debug + help);
+}
+
+void ConfigMainWindow::loadConfig(void)
+{
+ QString s = QFileDialog::getOpenFileName(".config", NULL, this);
+ if (s.isNull())
+ return;
+ if (conf_read(s.latin1()))
+ QMessageBox::information(this, "qconf", "Unable to load configuration!");
+ ConfigView::updateListAll();
+}
+
+void ConfigMainWindow::saveConfig(void)
+{
+ if (conf_write(NULL))
+ QMessageBox::information(this, "qconf", "Unable to save configuration!");
+}
+
+void ConfigMainWindow::saveConfigAs(void)
+{
+ QString s = QFileDialog::getSaveFileName(".config", NULL, this);
+ if (s.isNull())
+ return;
+ if (conf_write(s.latin1()))
+ QMessageBox::information(this, "qconf", "Unable to save configuration!");
+}
+
+void ConfigMainWindow::changeMenu(struct menu *menu)
+{
+ configList->setRootMenu(menu);
+ backAction->setEnabled(TRUE);
+}
+
+void ConfigMainWindow::listFocusChanged(void)
+{
+ if (menuList->hasFocus()) {
+ if (menuList->mode == menuMode)
+ configList->clearSelection();
+ setHelp(menuList->selectedItem());
+ } else if (configList->hasFocus()) {
+ setHelp(configList->selectedItem());
+ }
+}
+
+void ConfigMainWindow::goBack(void)
+{
+ ConfigItem* item;
+
+ configList->setParentMenu();
+ if (configList->rootEntry == &rootmenu)
+ backAction->setEnabled(FALSE);
+ item = (ConfigItem*)menuList->selectedItem();
+ while (item) {
+ if (item->menu == configList->rootEntry) {
+ menuList->setSelected(item, TRUE);
+ break;
+ }
+ item = (ConfigItem*)item->parent();
+ }
+}
+
+void ConfigMainWindow::showSingleView(void)
+{
+ menuView->hide();
+ menuList->setRootMenu(0);
+ configList->mode = singleMode;
+ if (configList->rootEntry == &rootmenu)
+ configList->updateListAll();
+ else
+ configList->setRootMenu(&rootmenu);
+ configList->setAllOpen(TRUE);
+ configList->setFocus();
+}
+
+void ConfigMainWindow::showSplitView(void)
+{
+ configList->mode = symbolMode;
+ if (configList->rootEntry == &rootmenu)
+ configList->updateListAll();
+ else
+ configList->setRootMenu(&rootmenu);
+ configList->setAllOpen(TRUE);
+ configApp->processEvents();
+ menuList->mode = menuMode;
+ menuList->setRootMenu(&rootmenu);
+ menuList->setAllOpen(TRUE);
+ menuView->show();
+ menuList->setFocus();
+}
+
+void ConfigMainWindow::showFullView(void)
+{
+ menuView->hide();
+ menuList->setRootMenu(0);
+ configList->mode = fullMode;
+ if (configList->rootEntry == &rootmenu)
+ configList->updateListAll();
+ else
+ configList->setRootMenu(&rootmenu);
+ configList->setAllOpen(FALSE);
+ configList->setFocus();
+}
+
+void ConfigMainWindow::setShowAll(bool b)
+{
+ if (configList->showAll == b)
+ return;
+ configList->showAll = b;
+ configList->updateListAll();
+ menuList->showAll = b;
+ menuList->updateListAll();
+}
+
+void ConfigMainWindow::setShowDebug(bool b)
+{
+ if (showDebug == b)
+ return;
+ showDebug = b;
+}
+
+void ConfigMainWindow::setShowName(bool b)
+{
+ if (configList->showName == b)
+ return;
+ configList->showName = b;
+ configList->reinit();
+ menuList->showName = b;
+ menuList->reinit();
+}
+
+void ConfigMainWindow::setShowRange(bool b)
+{
+ if (configList->showRange == b)
+ return;
+ configList->showRange = b;
+ configList->reinit();
+ menuList->showRange = b;
+ menuList->reinit();
+}
+
+void ConfigMainWindow::setShowData(bool b)
+{
+ if (configList->showData == b)
+ return;
+ configList->showData = b;
+ configList->reinit();
+ menuList->showData = b;
+ menuList->reinit();
+}
+
+/*
+ * ask for saving configuration before quitting
+ * TODO ask only when something changed
+ */
+void ConfigMainWindow::closeEvent(QCloseEvent* e)
+{
+ if (!sym_change_count) {
+ e->accept();
+ return;
+ }
+ QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
+ QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
+ mb.setButtonText(QMessageBox::Yes, "&Save Changes");
+ mb.setButtonText(QMessageBox::No, "&Discard Changes");
+ mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
+ switch (mb.exec()) {
+ case QMessageBox::Yes:
+ conf_write(NULL);
+ case QMessageBox::No:
+ e->accept();
+ break;
+ case QMessageBox::Cancel:
+ e->ignore();
+ break;
+ }
+}
+
+void ConfigMainWindow::showIntro(void)
+{
+ static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
+ "For each option, a blank box indicates the feature is disabled, a check\n"
+ "indicates it is enabled, and a dot indicates that it is to be compiled\n"
+ "as a module. Clicking on the box will cycle through the three states.\n\n"
+ "If you do not see an option (e.g., a device driver) that you believe\n"
+ "should be present, try turning on Show All Options under the Options menu.\n"
+ "Although there is no cross reference yet to help you figure out what other\n"
+ "options must be enabled to support the option you are interested in, you can\n"
+ "still view the help of a grayed-out option.\n\n"
+ "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
+ "which you can then match by examining other options.\n\n";
+
+ QMessageBox::information(this, "qconf", str);
+}
+
+void ConfigMainWindow::showAbout(void)
+{
+ static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
+ "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
+
+ QMessageBox::information(this, "qconf", str);
+}
+
+void ConfigMainWindow::saveSettings(void)
+{
+#if QT_VERSION >= 300
+ ConfigSettings *configSettings = new ConfigSettings;
+ configSettings->writeEntry("/kconfig/qconf/window x", pos().x());
+ configSettings->writeEntry("/kconfig/qconf/window y", pos().y());
+ configSettings->writeEntry("/kconfig/qconf/window width", size().width());
+ configSettings->writeEntry("/kconfig/qconf/window height", size().height());
+ configSettings->writeEntry("/kconfig/qconf/showName", configList->showName);
+ configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange);
+ configSettings->writeEntry("/kconfig/qconf/showData", configList->showData);
+ configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll);
+ configSettings->writeEntry("/kconfig/qconf/showDebug", showDebug);
+
+ QString entry;
+ switch(configList->mode) {
+ case singleMode :
+ entry = "single";
+ break;
+
+ case symbolMode :
+ entry = "split";
+ break;
+
+ case fullMode :
+ entry = "full";
+ break;
+ }
+ configSettings->writeEntry("/kconfig/qconf/listMode", entry);
+
+ configSettings->writeSizes("/kconfig/qconf/split1", split1->sizes());
+ configSettings->writeSizes("/kconfig/qconf/split2", split2->sizes());
+
+ delete configSettings;
+#endif
+}
+
+void fixup_rootmenu(struct menu *menu)
+{
+ struct menu *child;
+ static int menu_cnt = 0;
+
+ menu->flags |= MENU_ROOT;
+ for (child = menu->list; child; child = child->next) {
+ if (child->prompt && child->prompt->type == P_MENU) {
+ menu_cnt++;
+ fixup_rootmenu(child);
+ menu_cnt--;
+ } else if (!menu_cnt)
+ fixup_rootmenu(child);
+ }
+}
+
+static const char *progname;
+
+static void usage(void)
+{
+ printf("%s <config>\n", progname);
+ exit(0);
+}
+
+int main(int ac, char** av)
+{
+ ConfigMainWindow* v;
+ const char *name;
+
+#ifndef LKC_DIRECT_LINK
+ kconfig_load();
+#endif
+
+ progname = av[0];
+ configApp = new QApplication(ac, av);
+ if (ac > 1 && av[1][0] == '-') {
+ switch (av[1][1]) {
+ case 'h':
+ case '?':
+ usage();
+ }
+ name = av[2];
+ } else
+ name = av[1];
+ if (!name)
+ usage();
+
+ conf_parse(name);
+ fixup_rootmenu(&rootmenu);
+ conf_read(NULL);
+ //zconfdump(stdout);
+
+ v = new ConfigMainWindow();
+
+ //zconfdump(stdout);
+ v->show();
+ configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
+ configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
+ configApp->exec();
+
+ return 0;
+}
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <qlistview.h>
+#if QT_VERSION >= 300
+#include <qsettings.h>
+#else
+class QSettings { };
+#endif
+
+class ConfigList;
+class ConfigItem;
+class ConfigLineEdit;
+class ConfigMainWindow;
+
+
+class ConfigSettings : public QSettings {
+public:
+ ConfigSettings();
+
+#if QT_VERSION >= 300
+ void readListSettings();
+ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok);
+ bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value);
+#endif
+
+ bool showAll;
+ bool showName;
+ bool showRange;
+ bool showData;
+};
+
+class ConfigView : public QVBox {
+ Q_OBJECT
+ typedef class QVBox Parent;
+public:
+ ConfigView(QWidget* parent, ConfigMainWindow* cview, ConfigSettings* configSettings);
+ ~ConfigView(void);
+ static void updateList(ConfigItem* item);
+ static void updateListAll(void);
+
+public:
+ ConfigList* list;
+ ConfigLineEdit* lineEdit;
+
+ static ConfigView* viewList;
+ ConfigView* nextView;
+};
+
+enum colIdx {
+ promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
+};
+enum listMode {
+ singleMode, menuMode, symbolMode, fullMode
+};
+
+class ConfigList : public QListView {
+ Q_OBJECT
+ typedef class QListView Parent;
+public:
+ ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings);
+ void reinit(void);
+ ConfigView* parent(void) const
+ {
+ return (ConfigView*)Parent::parent();
+ }
+
+protected:
+ ConfigMainWindow* cview;
+
+ void keyPressEvent(QKeyEvent *e);
+ void contentsMousePressEvent(QMouseEvent *e);
+ void contentsMouseReleaseEvent(QMouseEvent *e);
+ void contentsMouseMoveEvent(QMouseEvent *e);
+ void contentsMouseDoubleClickEvent(QMouseEvent *e);
+ void focusInEvent(QFocusEvent *e);
+public slots:
+ void setRootMenu(struct menu *menu);
+
+ void updateList(ConfigItem *item);
+ void setValue(ConfigItem* item, tristate val);
+ void changeValue(ConfigItem* item);
+ void updateSelection(void);
+signals:
+ void menuSelected(struct menu *menu);
+ void parentSelected(void);
+ void gotFocus(void);
+
+public:
+ void updateListAll(void)
+ {
+ updateAll = true;
+ updateList(NULL);
+ updateAll = false;
+ }
+ ConfigList* listView()
+ {
+ return this;
+ }
+ ConfigItem* firstChild() const
+ {
+ return (ConfigItem *)Parent::firstChild();
+ }
+ int mapIdx(colIdx idx)
+ {
+ return colMap[idx];
+ }
+ void addColumn(colIdx idx, const QString& label)
+ {
+ colMap[idx] = Parent::addColumn(label);
+ colRevMap[colMap[idx]] = idx;
+ }
+ void removeColumn(colIdx idx)
+ {
+ int col = colMap[idx];
+ if (col >= 0) {
+ Parent::removeColumn(col);
+ colRevMap[col] = colMap[idx] = -1;
+ }
+ }
+ void setAllOpen(bool open);
+ void setParentMenu(void);
+
+ template <class P>
+ void ConfigList::updateMenuList(P*, struct menu*);
+
+ bool updateAll;
+
+ QPixmap symbolYesPix, symbolModPix, symbolNoPix;
+ QPixmap choiceYesPix, choiceNoPix;
+ QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
+
+ bool showAll, showName, showRange, showData;
+ enum listMode mode;
+ struct menu *rootEntry;
+ QColorGroup disabledColorGroup;
+ QColorGroup inactivedColorGroup;
+
+private:
+ int colMap[colNr];
+ int colRevMap[colNr];
+};
+
+class ConfigItem : public QListViewItem {
+ typedef class QListViewItem Parent;
+public:
+ ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
+ : Parent(parent, after), menu(m), visible(v), goParent(false)
+ {
+ init();
+ }
+ ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
+ : Parent(parent, after), menu(m), visible(v), goParent(false)
+ {
+ init();
+ }
+ ConfigItem(QListView *parent, ConfigItem *after, bool v)
+ : Parent(parent, after), menu(0), visible(v), goParent(true)
+ {
+ init();
+ }
+ ~ConfigItem(void);
+ void init(void);
+#if QT_VERSION >= 300
+ void okRename(int col);
+#endif
+ void updateMenu(void);
+ void testUpdateMenu(bool v);
+ ConfigList* listView() const
+ {
+ return (ConfigList*)Parent::listView();
+ }
+ ConfigItem* firstChild() const
+ {
+ return (ConfigItem *)Parent::firstChild();
+ }
+ ConfigItem* nextSibling() const
+ {
+ return (ConfigItem *)Parent::nextSibling();
+ }
+ void setText(colIdx idx, const QString& text)
+ {
+ Parent::setText(listView()->mapIdx(idx), text);
+ }
+ QString text(colIdx idx) const
+ {
+ return Parent::text(listView()->mapIdx(idx));
+ }
+ void setPixmap(colIdx idx, const QPixmap& pm)
+ {
+ Parent::setPixmap(listView()->mapIdx(idx), pm);
+ }
+ const QPixmap* pixmap(colIdx idx) const
+ {
+ return Parent::pixmap(listView()->mapIdx(idx));
+ }
+ void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
+
+ ConfigItem* nextItem;
+ struct menu *menu;
+ bool visible;
+ bool goParent;
+};
+
+class ConfigLineEdit : public QLineEdit {
+ Q_OBJECT
+ typedef class QLineEdit Parent;
+public:
+ ConfigLineEdit(ConfigView* parent)
+ : Parent(parent)
+ { }
+ ConfigView* parent(void) const
+ {
+ return (ConfigView*)Parent::parent();
+ }
+ void show(ConfigItem *i);
+ void keyPressEvent(QKeyEvent *e);
+
+public:
+ ConfigItem *item;
+};
+
+class ConfigMainWindow : public QMainWindow {
+ Q_OBJECT
+public:
+ ConfigMainWindow(void);
+public slots:
+ void setHelp(QListViewItem* item);
+ void changeMenu(struct menu *);
+ void listFocusChanged(void);
+ void goBack(void);
+ void loadConfig(void);
+ void saveConfig(void);
+ void saveConfigAs(void);
+ void showSingleView(void);
+ void showSplitView(void);
+ void showFullView(void);
+ void setShowAll(bool);
+ void setShowDebug(bool);
+ void setShowRange(bool);
+ void setShowName(bool);
+ void setShowData(bool);
+ void showIntro(void);
+ void showAbout(void);
+ void saveSettings(void);
+
+protected:
+ void closeEvent(QCloseEvent *e);
+
+ ConfigView *menuView;
+ ConfigList *menuList;
+ ConfigView *configView;
+ ConfigList *configList;
+ QTextView *helpText;
+ QToolBar *toolBar;
+ QAction *backAction;
+ QSplitter* split1;
+ QSplitter* split2;
+
+ bool showDebug;
+};
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 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <regex.h>
+#include <sys/utsname.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+struct symbol symbol_yes = {
+ .name = "y",
+ .curr = { "y", yes },
+ .flags = SYMBOL_YES|SYMBOL_VALID,
+}, symbol_mod = {
+ .name = "m",
+ .curr = { "m", mod },
+ .flags = SYMBOL_MOD|SYMBOL_VALID,
+}, symbol_no = {
+ .name = "n",
+ .curr = { "n", no },
+ .flags = SYMBOL_NO|SYMBOL_VALID,
+}, symbol_empty = {
+ .name = "",
+ .curr = { "", no },
+ .flags = SYMBOL_VALID,
+};
+
+int sym_change_count;
+struct symbol *modules_sym;
+tristate modules_val;
+
+void sym_add_default(struct symbol *sym, const char *def)
+{
+ struct property *prop = prop_alloc(P_DEFAULT, sym);
+
+ prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
+}
+
+void sym_init(void)
+{
+ struct symbol *sym;
+ struct utsname uts;
+ char *p;
+ static bool inited = false;
+
+ if (inited)
+ return;
+ inited = true;
+
+ uname(&uts);
+
+ sym = sym_lookup("ARCH", 0);
+ sym->type = S_STRING;
+ sym->flags |= SYMBOL_AUTO;
+ p = getenv("ARCH");
+ if (p)
+ sym_add_default(sym, p);
+
+ sym = sym_lookup("KERNELRELEASE", 0);
+ sym->type = S_STRING;
+ sym->flags |= SYMBOL_AUTO;
+ p = getenv("KERNELRELEASE");
+ if (p)
+ sym_add_default(sym, p);
+
+ sym = sym_lookup("UNAME_RELEASE", 0);
+ sym->type = S_STRING;
+ sym->flags |= SYMBOL_AUTO;
+ sym_add_default(sym, uts.release);
+}
+
+enum symbol_type sym_get_type(struct symbol *sym)
+{
+ enum symbol_type type = sym->type;
+
+ if (type == S_TRISTATE) {
+ if (sym_is_choice_value(sym) && sym->visible == yes)
+ type = S_BOOLEAN;
+ else if (modules_val == no)
+ type = S_BOOLEAN;
+ }
+ return type;
+}
+
+const char *sym_type_name(enum symbol_type type)
+{
+ switch (type) {
+ case S_BOOLEAN:
+ return "boolean";
+ case S_TRISTATE:
+ return "tristate";
+ case S_INT:
+ return "integer";
+ case S_HEX:
+ return "hex";
+ case S_STRING:
+ return "string";
+ case S_UNKNOWN:
+ return "unknown";
+ case S_OTHER:
+ break;
+ }
+ return "???";
+}
+
+struct property *sym_get_choice_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_choices(sym, prop)
+ return prop;
+ return NULL;
+}
+
+struct property *sym_get_default_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_defaults(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri != no)
+ return prop;
+ }
+ return NULL;
+}
+
+struct property *sym_get_range_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_properties(sym, prop, P_RANGE) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri != no)
+ return prop;
+ }
+ return NULL;
+}
+
+static void sym_calc_visibility(struct symbol *sym)
+{
+ struct property *prop;
+ tristate tri;
+
+ /* any prompt visible? */
+ tri = no;
+ for_all_prompts(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ tri = E_OR(tri, prop->visible.tri);
+ }
+ if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
+ tri = yes;
+ if (sym->visible != tri) {
+ sym->visible = tri;
+ sym_set_changed(sym);
+ }
+ if (sym_is_choice_value(sym))
+ return;
+ tri = no;
+ if (sym->rev_dep.expr)
+ tri = expr_calc_value(sym->rev_dep.expr);
+ if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ tri = yes;
+ if (sym->rev_dep.tri != tri) {
+ sym->rev_dep.tri = tri;
+ sym_set_changed(sym);
+ }
+}
+
+static struct symbol *sym_calc_choice(struct symbol *sym)
+{
+ struct symbol *def_sym;
+ struct property *prop;
+ struct expr *e;
+
+ /* is the user choice visible? */
+ def_sym = sym->user.val;
+ if (def_sym) {
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* any of the defaults visible? */
+ for_all_defaults(sym, prop) {
+ prop->visible.tri = expr_calc_value(prop->visible.expr);
+ if (prop->visible.tri == no)
+ continue;
+ def_sym = prop_get_symbol(prop);
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* just get the first visible value */
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr) {
+ def_sym = e->right.sym;
+ sym_calc_visibility(def_sym);
+ if (def_sym->visible != no)
+ return def_sym;
+ }
+
+ /* no choice? reset tristate value */
+ sym->curr.tri = no;
+ return NULL;
+}
+
+void sym_calc_value(struct symbol *sym)
+{
+ struct symbol_value newval, oldval;
+ struct property *prop;
+ struct expr *e;
+
+ if (!sym)
+ return;
+
+ if (sym->flags & SYMBOL_VALID)
+ return;
+ sym->flags |= SYMBOL_VALID;
+
+ oldval = sym->curr;
+
+ switch (sym->type) {
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ newval = symbol_empty.curr;
+ break;
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ newval = symbol_no.curr;
+ break;
+ default:
+ sym->curr.val = sym->name;
+ sym->curr.tri = no;
+ return;
+ }
+ if (!sym_is_choice_value(sym))
+ sym->flags &= ~SYMBOL_WRITE;
+
+ sym_calc_visibility(sym);
+
+ /* set default if recursively called */
+ sym->curr = newval;
+
+ switch (sym_get_type(sym)) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ if (sym_is_choice_value(sym) && sym->visible == yes) {
+ prop = sym_get_choice_prop(sym);
+ newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+ } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym))
+ newval.tri = sym->user.tri;
+ else if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop)
+ newval.tri = expr_calc_value(prop->expr);
+ }
+ newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+ } else if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = expr_calc_value(prop->expr);
+ }
+ }
+ if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
+ newval.tri = yes;
+ break;
+ case S_STRING:
+ case S_HEX:
+ case S_INT:
+ if (sym->visible != no) {
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.val = sym->user.val;
+ break;
+ }
+ }
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ struct symbol *ds = prop_get_symbol(prop);
+ if (ds) {
+ sym->flags |= SYMBOL_WRITE;
+ sym_calc_value(ds);
+ newval.val = ds->curr.val;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+
+ sym->curr = newval;
+ if (sym_is_choice(sym) && newval.tri == yes)
+ sym->curr.val = sym_calc_choice(sym);
+
+ if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
+ sym_set_changed(sym);
+ if (modules_sym == sym)
+ modules_val = modules_sym->curr.tri;
+
+ if (sym_is_choice(sym)) {
+ int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
+ prop = sym_get_choice_prop(sym);
+ for (e = prop->expr; e; e = e->left.expr) {
+ e->right.sym->flags |= flags;
+ if (flags & SYMBOL_CHANGED)
+ sym_set_changed(e->right.sym);
+ }
+ }
+}
+
+void sym_clear_all_valid(void)
+{
+ struct symbol *sym;
+ int i;
+
+ for_all_symbols(i, sym)
+ sym->flags &= ~SYMBOL_VALID;
+ sym_change_count++;
+ if (modules_sym)
+ sym_calc_value(modules_sym);
+}
+
+void sym_set_changed(struct symbol *sym)
+{
+ struct property *prop;
+
+ sym->flags |= SYMBOL_CHANGED;
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu)
+ prop->menu->flags |= MENU_CHANGED;
+ }
+}
+
+void sym_set_all_changed(void)
+{
+ struct symbol *sym;
+ int i;
+
+ for_all_symbols(i, sym)
+ sym_set_changed(sym);
+}
+
+bool sym_tristate_within_range(struct symbol *sym, tristate val)
+{
+ int type = sym_get_type(sym);
+
+ if (sym->visible == no)
+ return false;
+
+ if (type != S_BOOLEAN && type != S_TRISTATE)
+ return false;
+
+ if (type == S_BOOLEAN && val == mod)
+ return false;
+ if (sym->visible <= sym->rev_dep.tri)
+ return false;
+ if (sym_is_choice_value(sym) && sym->visible == yes)
+ return val == yes;
+ return val >= sym->rev_dep.tri && val <= sym->visible;
+}
+
+bool sym_set_tristate_value(struct symbol *sym, tristate val)
+{
+ tristate oldval = sym_get_tristate_value(sym);
+
+ if (oldval != val && !sym_tristate_within_range(sym, val))
+ return false;
+
+ if (sym->flags & SYMBOL_NEW) {
+ sym->flags &= ~SYMBOL_NEW;
+ sym_set_changed(sym);
+ }
+ if (sym_is_choice_value(sym) && val == yes) {
+ struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+
+ cs->user.val = sym;
+ cs->flags &= ~SYMBOL_NEW;
+ }
+
+ sym->user.tri = val;
+ if (oldval != val) {
+ sym_clear_all_valid();
+ if (sym == modules_sym)
+ sym_set_all_changed();
+ }
+
+ return true;
+}
+
+tristate sym_toggle_tristate_value(struct symbol *sym)
+{
+ tristate oldval, newval;
+
+ oldval = newval = sym_get_tristate_value(sym);
+ do {
+ switch (newval) {
+ case no:
+ newval = mod;
+ break;
+ case mod:
+ newval = yes;
+ break;
+ case yes:
+ newval = no;
+ break;
+ }
+ if (sym_set_tristate_value(sym, newval))
+ break;
+ } while (oldval != newval);
+ return newval;
+}
+
+bool sym_string_valid(struct symbol *sym, const char *str)
+{
+ signed char ch;
+
+ switch (sym->type) {
+ case S_STRING:
+ return true;
+ case S_INT:
+ ch = *str++;
+ if (ch == '-')
+ ch = *str++;
+ if (!isdigit(ch))
+ return false;
+ if (ch == '0' && *str != 0)
+ return false;
+ while ((ch = *str++)) {
+ if (!isdigit(ch))
+ return false;
+ }
+ return true;
+ case S_HEX:
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+ str += 2;
+ ch = *str++;
+ do {
+ if (!isxdigit(ch))
+ return false;
+ } while ((ch = *str++));
+ return true;
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (str[0]) {
+ case 'y': case 'Y':
+ case 'm': case 'M':
+ case 'n': case 'N':
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool sym_string_within_range(struct symbol *sym, const char *str)
+{
+ struct property *prop;
+ int val;
+
+ switch (sym->type) {
+ case S_STRING:
+ return sym_string_valid(sym, str);
+ case S_INT:
+ if (!sym_string_valid(sym, str))
+ return false;
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return true;
+ val = strtol(str, NULL, 10);
+ return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
+ val <= strtol(prop->expr->right.sym->name, NULL, 10);
+ case S_HEX:
+ if (!sym_string_valid(sym, str))
+ return false;
+ prop = sym_get_range_prop(sym);
+ if (!prop)
+ return true;
+ val = strtol(str, NULL, 16);
+ return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
+ val <= strtol(prop->expr->right.sym->name, NULL, 16);
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (str[0]) {
+ case 'y': case 'Y':
+ return sym_tristate_within_range(sym, yes);
+ case 'm': case 'M':
+ return sym_tristate_within_range(sym, mod);
+ case 'n': case 'N':
+ return sym_tristate_within_range(sym, no);
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool sym_set_string_value(struct symbol *sym, const char *newval)
+{
+ const char *oldval;
+ char *val;
+ int size;
+
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (newval[0]) {
+ case 'y': case 'Y':
+ return sym_set_tristate_value(sym, yes);
+ case 'm': case 'M':
+ return sym_set_tristate_value(sym, mod);
+ case 'n': case 'N':
+ return sym_set_tristate_value(sym, no);
+ }
+ return false;
+ default:
+ ;
+ }
+
+ if (!sym_string_within_range(sym, newval))
+ return false;
+
+ if (sym->flags & SYMBOL_NEW) {
+ sym->flags &= ~SYMBOL_NEW;
+ sym_set_changed(sym);
+ }
+
+ oldval = sym->user.val;
+ size = strlen(newval) + 1;
+ if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
+ size += 2;
+ sym->user.val = val = malloc(size);
+ *val++ = '0';
+ *val++ = 'x';
+ } else if (!oldval || strcmp(oldval, newval))
+ sym->user.val = val = malloc(size);
+ else
+ return true;
+
+ strcpy(val, newval);
+ free((void *)oldval);
+ sym_clear_all_valid();
+
+ return true;
+}
+
+const char *sym_get_string_value(struct symbol *sym)
+{
+ tristate val;
+
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ val = sym_get_tristate_value(sym);
+ switch (val) {
+ case no:
+ return "n";
+ case mod:
+ return "m";
+ case yes:
+ return "y";
+ }
+ break;
+ default:
+ ;
+ }
+ return (const char *)sym->curr.val;
+}
+
+bool sym_is_changable(struct symbol *sym)
+{
+ return sym->visible > sym->rev_dep.tri;
+}
+
+struct symbol *sym_lookup(const char *name, int isconst)
+{
+ struct symbol *symbol;
+ const char *ptr;
+ char *new_name;
+ int hash = 0;
+
+ if (name) {
+ if (name[0] && !name[1]) {
+ switch (name[0]) {
+ case 'y': return &symbol_yes;
+ case 'm': return &symbol_mod;
+ case 'n': return &symbol_no;
+ }
+ }
+ for (ptr = name; *ptr; ptr++)
+ hash += *ptr;
+ hash &= 0xff;
+
+ for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+ if (!strcmp(symbol->name, name)) {
+ if ((isconst && symbol->flags & SYMBOL_CONST) ||
+ (!isconst && !(symbol->flags & SYMBOL_CONST)))
+ return symbol;
+ }
+ }
+ new_name = strdup(name);
+ } else {
+ new_name = NULL;
+ hash = 256;
+ }
+
+ symbol = malloc(sizeof(*symbol));
+ memset(symbol, 0, sizeof(*symbol));
+ symbol->name = new_name;
+ symbol->type = S_UNKNOWN;
+ symbol->flags = SYMBOL_NEW;
+ if (isconst)
+ symbol->flags |= SYMBOL_CONST;
+
+ symbol->next = symbol_hash[hash];
+ symbol_hash[hash] = symbol;
+
+ return symbol;
+}
+
+struct symbol *sym_find(const char *name)
+{
+ struct symbol *symbol = NULL;
+ const char *ptr;
+ int hash = 0;
+
+ if (!name)
+ return NULL;
+
+ if (name[0] && !name[1]) {
+ switch (name[0]) {
+ case 'y': return &symbol_yes;
+ case 'm': return &symbol_mod;
+ case 'n': return &symbol_no;
+ }
+ }
+ for (ptr = name; *ptr; ptr++)
+ hash += *ptr;
+ hash &= 0xff;
+
+ for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+ if (!strcmp(symbol->name, name) &&
+ !(symbol->flags & SYMBOL_CONST))
+ break;
+ }
+
+ return symbol;
+}
+
+struct symbol **sym_re_search(const char *pattern)
+{
+ struct symbol *sym, **sym_arr = NULL;
+ int i, cnt, size;
+ regex_t re;
+
+ cnt = size = 0;
+ /* Skip if empty */
+ if (strlen(pattern) == 0)
+ return NULL;
+ if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+ return NULL;
+
+ for_all_symbols(i, sym) {
+ if (sym->flags & SYMBOL_CONST || !sym->name)
+ continue;
+ if (regexec(&re, sym->name, 0, NULL, 0))
+ continue;
+ if (cnt + 1 >= size) {
+ void *tmp = sym_arr;
+ size += 16;
+ sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
+ if (!sym_arr) {
+ free(tmp);
+ return NULL;
+ }
+ }
+ sym_arr[cnt++] = sym;
+ }
+ if (sym_arr)
+ sym_arr[cnt] = NULL;
+ regfree(&re);
+
+ return sym_arr;
+}
+
+
+struct symbol *sym_check_deps(struct symbol *sym);
+
+static struct symbol *sym_check_expr_deps(struct expr *e)
+{
+ struct symbol *sym;
+
+ if (!e)
+ return NULL;
+ switch (e->type) {
+ case E_OR:
+ case E_AND:
+ sym = sym_check_expr_deps(e->left.expr);
+ if (sym)
+ return sym;
+ return sym_check_expr_deps(e->right.expr);
+ case E_NOT:
+ return sym_check_expr_deps(e->left.expr);
+ case E_EQUAL:
+ case E_UNEQUAL:
+ sym = sym_check_deps(e->left.sym);
+ if (sym)
+ return sym;
+ return sym_check_deps(e->right.sym);
+ case E_SYMBOL:
+ return sym_check_deps(e->left.sym);
+ default:
+ break;
+ }
+ printf("Oops! How to check %d?\n", e->type);
+ return NULL;
+}
+
+struct symbol *sym_check_deps(struct symbol *sym)
+{
+ struct symbol *sym2;
+ struct property *prop;
+
+ if (sym->flags & SYMBOL_CHECK_DONE)
+ return NULL;
+ if (sym->flags & SYMBOL_CHECK) {
+ printf("Warning! Found recursive dependency: %s", sym->name);
+ return sym;
+ }
+
+ sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+ sym2 = sym_check_expr_deps(sym->rev_dep.expr);
+ if (sym2)
+ goto out;
+
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->type == P_CHOICE || prop->type == P_SELECT)
+ continue;
+ sym2 = sym_check_expr_deps(prop->visible.expr);
+ if (sym2)
+ goto out;
+ if (prop->type != P_DEFAULT || sym_is_choice(sym))
+ continue;
+ sym2 = sym_check_expr_deps(prop->expr);
+ if (sym2)
+ goto out;
+ }
+out:
+ if (sym2)
+ printf(" %s", sym->name);
+ sym->flags &= ~SYMBOL_CHECK;
+ return sym2;
+}
+
+struct property *prop_alloc(enum prop_type type, struct symbol *sym)
+{
+ struct property *prop;
+ struct property **propp;
+
+ prop = malloc(sizeof(*prop));
+ memset(prop, 0, sizeof(*prop));
+ prop->type = type;
+ prop->sym = sym;
+ prop->file = current_file;
+ prop->lineno = zconf_lineno();
+
+ /* append property to the prop list of symbol */
+ if (sym) {
+ for (propp = &sym->prop; *propp; propp = &(*propp)->next)
+ ;
+ *propp = prop;
+ }
+
+ return prop;
+}
+
+struct symbol *prop_get_symbol(struct property *prop)
+{
+ if (prop->expr && (prop->expr->type == E_SYMBOL ||
+ prop->expr->type == E_CHOICE))
+ return prop->expr->left.sym;
+ return NULL;
+}
+
+const char *prop_get_type_name(enum prop_type type)
+{
+ switch (type) {
+ case P_PROMPT:
+ return "prompt";
+ case P_COMMENT:
+ return "comment";
+ case P_MENU:
+ return "menu";
+ case P_DEFAULT:
+ return "default";
+ case P_CHOICE:
+ return "choice";
+ case P_SELECT:
+ return "select";
+ case P_RANGE:
+ return "range";
+ case P_UNKNOWN:
+ break;
+ }
+ return "unknown";
+}
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 @@
+/*
+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <string.h>
+#include "lkc.h"
+
+/* file already present in list? If not add it */
+struct file *file_lookup(const char *name)
+{
+ struct file *file;
+
+ for (file = file_list; file; file = file->next) {
+ if (!strcmp(name, file->name))
+ return file;
+ }
+
+ file = malloc(sizeof(*file));
+ memset(file, 0, sizeof(*file));
+ file->name = strdup(name);
+ file->next = file_list;
+ file_list = file;
+ return file;
+}
+
+/* write a dependency file as used by kbuild to track dependencies */
+int file_write_dep(const char *name)
+{
+ struct file *file;
+ FILE *out;
+
+ if (!name)
+ name = ".config.cmd";
+ out = fopen("..config.tmp", "w");
+ if (!out)
+ return 1;
+ fprintf(out, "deps_config := \\\n");
+ for (file = file_list; file; file = file->next) {
+ if (file->next)
+ fprintf(out, "\t%s \\\n", file->name);
+ else
+ fprintf(out, "\t%s\n", file->name);
+ }
+ fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
+ fclose(out);
+ rename("..config.tmp", name);
+ return 0;
+}
+
+
+/* Allocate initial growable sting */
+struct gstr str_new(void)
+{
+ struct gstr gs;
+ gs.s = malloc(sizeof(char) * 64);
+ gs.len = 16;
+ strcpy(gs.s, "\0");
+ return gs;
+}
+
+/* Allocate and assign growable string */
+struct gstr str_assign(const char *s)
+{
+ struct gstr gs;
+ gs.s = strdup(s);
+ gs.len = strlen(s) + 1;
+ return gs;
+}
+
+/* Free storage for growable string */
+void str_free(struct gstr *gs)
+{
+ if (gs->s)
+ free(gs->s);
+ gs->s = NULL;
+ gs->len = 0;
+}
+
+/* Append to growable string */
+void str_append(struct gstr *gs, const char *s)
+{
+ size_t l = strlen(gs->s) + strlen(s) + 1;
+ if (l > gs->len) {
+ gs->s = realloc(gs->s, l);
+ gs->len = l;
+ }
+ strcat(gs->s, s);
+}
+
+/* Append printf formatted string to growable string */
+void str_printf(struct gstr *gs, const char *fmt, ...)
+{
+ va_list ap;
+ char s[10000]; /* big enough... */
+ va_start(ap, fmt);
+ vsnprintf(s, sizeof(s), fmt, ap);
+ str_append(gs, s);
+ va_end(ap);
+}
+
+/* Retreive value of growable string */
+const char *str_get(struct gstr *gs)
+{
+ return gs->s;
+}
+
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 @@
+%option backup nostdinit noyywrap never-interactive full ecs
+%option 8bit backup nodefault perf-report perf-report
+%x COMMAND HELP STRING PARAM
+%{
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define START_STRSIZE 16
+
+char *text;
+static char *text_ptr;
+static int text_size, text_asize;
+
+struct buffer {
+ struct buffer *parent;
+ YY_BUFFER_STATE state;
+};
+
+struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static void zconf_endhelp(void);
+static struct buffer *zconf_endfile(void);
+
+void new_string(void)
+{
+ text = malloc(START_STRSIZE);
+ text_asize = START_STRSIZE;
+ text_ptr = text;
+ text_size = 0;
+ *text_ptr = 0;
+}
+
+void append_string(const char *str, int size)
+{
+ int new_size = text_size + size + 1;
+ if (new_size > text_asize) {
+ text = realloc(text, new_size);
+ text_asize = new_size;
+ text_ptr = text + text_size;
+ }
+ memcpy(text_ptr, str, size);
+ text_ptr += size;
+ text_size += size;
+ *text_ptr = 0;
+}
+
+void alloc_string(const char *str, int size)
+{
+ text = malloc(size + 1);
+ memcpy(text, str, size);
+ text[size] = 0;
+}
+%}
+
+ws [ \n\t]
+n [A-Za-z0-9_]
+
+%%
+ int str = 0;
+ int ts, i;
+
+[ \t]*#.*\n current_file->lineno++;
+[ \t]*#.*
+
+[ \t]*\n current_file->lineno++; return T_EOL;
+
+[ \t]+ {
+ BEGIN(COMMAND);
+}
+
+. {
+ unput(yytext[0]);
+ BEGIN(COMMAND);
+}
+
+
+<COMMAND>{
+ "mainmenu" BEGIN(PARAM); return T_MAINMENU;
+ "menu" BEGIN(PARAM); return T_MENU;
+ "endmenu" BEGIN(PARAM); return T_ENDMENU;
+ "source" BEGIN(PARAM); return T_SOURCE;
+ "choice" BEGIN(PARAM); return T_CHOICE;
+ "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
+ "comment" BEGIN(PARAM); return T_COMMENT;
+ "config" BEGIN(PARAM); return T_CONFIG;
+ "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
+ "help" BEGIN(PARAM); return T_HELP;
+ "if" BEGIN(PARAM); return T_IF;
+ "endif" BEGIN(PARAM); return T_ENDIF;
+ "depends" BEGIN(PARAM); return T_DEPENDS;
+ "requires" BEGIN(PARAM); return T_REQUIRES;
+ "optional" BEGIN(PARAM); return T_OPTIONAL;
+ "default" BEGIN(PARAM); return T_DEFAULT;
+ "prompt" BEGIN(PARAM); return T_PROMPT;
+ "tristate" BEGIN(PARAM); return T_TRISTATE;
+ "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
+ "bool" BEGIN(PARAM); return T_BOOLEAN;
+ "boolean" BEGIN(PARAM); return T_BOOLEAN;
+ "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
+ "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
+ "int" BEGIN(PARAM); return T_INT;
+ "hex" BEGIN(PARAM); return T_HEX;
+ "string" BEGIN(PARAM); return T_STRING;
+ "select" BEGIN(PARAM); return T_SELECT;
+ "enable" BEGIN(PARAM); return T_SELECT;
+ "range" BEGIN(PARAM); return T_RANGE;
+ {n}+ {
+ alloc_string(yytext, yyleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ .
+ \n current_file->lineno++; BEGIN(INITIAL);
+}
+
+<PARAM>{
+ "&&" return T_AND;
+ "||" return T_OR;
+ "(" return T_OPEN_PAREN;
+ ")" return T_CLOSE_PAREN;
+ "!" return T_NOT;
+ "=" return T_EQUAL;
+ "!=" return T_UNEQUAL;
+ "if" return T_IF;
+ "on" return T_ON;
+ \"|\' {
+ str = yytext[0];
+ new_string();
+ BEGIN(STRING);
+ }
+ \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+ --- /* ignore */
+ ({n}|[-/.])+ {
+ alloc_string(yytext, yyleng);
+ zconflval.string = text;
+ return T_WORD;
+ }
+ #.* /* comment */
+ \\\n current_file->lineno++;
+ .
+ <<EOF>> {
+ BEGIN(INITIAL);
+ }
+}
+
+<STRING>{
+ [^'"\\\n]+/\n {
+ append_string(yytext, yyleng);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ [^'"\\\n]+ {
+ append_string(yytext, yyleng);
+ }
+ \\.?/\n {
+ append_string(yytext + 1, yyleng - 1);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ }
+ \\.? {
+ append_string(yytext + 1, yyleng - 1);
+ }
+ \'|\" {
+ if (str == yytext[0]) {
+ BEGIN(PARAM);
+ zconflval.string = text;
+ return T_WORD_QUOTE;
+ } else
+ append_string(yytext, 1);
+ }
+ \n {
+ printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
+ current_file->lineno++;
+ BEGIN(INITIAL);
+ return T_EOL;
+ }
+ <<EOF>> {
+ BEGIN(INITIAL);
+ }
+}
+
+<HELP>{
+ [ \t]+ {
+ ts = 0;
+ for (i = 0; i < yyleng; i++) {
+ if (yytext[i] == '\t')
+ ts = (ts & ~7) + 8;
+ else
+ ts++;
+ }
+ last_ts = ts;
+ if (first_ts) {
+ if (ts < first_ts) {
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ ts -= first_ts;
+ while (ts > 8) {
+ append_string(" ", 8);
+ ts -= 8;
+ }
+ append_string(" ", ts);
+ }
+ }
+ [ \t]*\n/[^ \t\n] {
+ current_file->lineno++;
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+ [ \t]*\n {
+ current_file->lineno++;
+ append_string("\n", 1);
+ }
+ [^ \t\n].* {
+ append_string(yytext, yyleng);
+ if (!first_ts)
+ first_ts = last_ts;
+ }
+ <<EOF>> {
+ zconf_endhelp();
+ return T_HELPTEXT;
+ }
+}
+
+<<EOF>> {
+ if (current_buf) {
+ zconf_endfile();
+ return T_EOF;
+ }
+ fclose(yyin);
+ yyterminate();
+}
+
+%%
+void zconf_starthelp(void)
+{
+ new_string();
+ last_ts = first_ts = 0;
+ BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+ zconflval.string = text;
+ BEGIN(INITIAL);
+}
+
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+ char *env, fullname[PATH_MAX+1];
+ FILE *f;
+
+ f = fopen(name, "r");
+ if (!f && name[0] != '/') {
+ env = getenv(SRCTREE);
+ if (env) {
+ sprintf(fullname, "%s/%s", env, name);
+ f = fopen(fullname, "r");
+ }
+ }
+ return f;
+}
+
+void zconf_initscan(const char *name)
+{
+ yyin = zconf_fopen(name);
+ if (!yyin) {
+ printf("can't find file %s\n", name);
+ exit(1);
+ }
+
+ current_buf = malloc(sizeof(*current_buf));
+ memset(current_buf, 0, sizeof(*current_buf));
+
+ current_file = file_lookup(name);
+ current_file->lineno = 1;
+ current_file->flags = FILE_BUSY;
+}
+
+void zconf_nextfile(const char *name)
+{
+ struct file *file = file_lookup(name);
+ struct buffer *buf = malloc(sizeof(*buf));
+ memset(buf, 0, sizeof(*buf));
+
+ current_buf->state = YY_CURRENT_BUFFER;
+ yyin = zconf_fopen(name);
+ if (!yyin) {
+ printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
+ exit(1);
+ }
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ buf->parent = current_buf;
+ current_buf = buf;
+
+ if (file->flags & FILE_BUSY) {
+ printf("recursive scan (%s)?\n", name);
+ exit(1);
+ }
+ if (file->flags & FILE_SCANNED) {
+ printf("file %s already scanned?\n", name);
+ exit(1);
+ }
+ file->flags |= FILE_BUSY;
+ file->lineno = 1;
+ file->parent = current_file;
+ current_file = file;
+}
+
+static struct buffer *zconf_endfile(void)
+{
+ struct buffer *parent;
+
+ current_file->flags |= FILE_SCANNED;
+ current_file->flags &= ~FILE_BUSY;
+ current_file = current_file->parent;
+
+ parent = current_buf->parent;
+ if (parent) {
+ fclose(yyin);
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(parent->state);
+ }
+ free(current_buf);
+ current_buf = parent;
+
+ return parent;
+}
+
+int zconf_lineno(void)
+{
+ if (current_buf)
+ return current_file->lineno - 1;
+ else
+ return 0;
+}
+
+char *zconf_curname(void)
+{
+ if (current_buf)
+ return current_file->name;
+ else
+ return "<none>";
+}
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 @@
+/* A Bison parser, made by GNU Bison 1.875a. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse zconfparse
+#define yylex zconflex
+#define yyerror zconferror
+#define yylval zconflval
+#define yychar zconfchar
+#define yydebug zconfdebug
+#define yynerrs zconfnerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ T_MAINMENU = 258,
+ T_MENU = 259,
+ T_ENDMENU = 260,
+ T_SOURCE = 261,
+ T_CHOICE = 262,
+ T_ENDCHOICE = 263,
+ T_COMMENT = 264,
+ T_CONFIG = 265,
+ T_MENUCONFIG = 266,
+ T_HELP = 267,
+ T_HELPTEXT = 268,
+ T_IF = 269,
+ T_ENDIF = 270,
+ T_DEPENDS = 271,
+ T_REQUIRES = 272,
+ T_OPTIONAL = 273,
+ T_PROMPT = 274,
+ T_DEFAULT = 275,
+ T_TRISTATE = 276,
+ T_DEF_TRISTATE = 277,
+ T_BOOLEAN = 278,
+ T_DEF_BOOLEAN = 279,
+ T_STRING = 280,
+ T_INT = 281,
+ T_HEX = 282,
+ T_WORD = 283,
+ T_WORD_QUOTE = 284,
+ T_UNEQUAL = 285,
+ T_EOF = 286,
+ T_EOL = 287,
+ T_CLOSE_PAREN = 288,
+ T_OPEN_PAREN = 289,
+ T_ON = 290,
+ T_SELECT = 291,
+ T_RANGE = 292,
+ T_OR = 293,
+ T_AND = 294,
+ T_EQUAL = 295,
+ T_NOT = 296
+ };
+#endif
+#define T_MAINMENU 258
+#define T_MENU 259
+#define T_ENDMENU 260
+#define T_SOURCE 261
+#define T_CHOICE 262
+#define T_ENDCHOICE 263
+#define T_COMMENT 264
+#define T_CONFIG 265
+#define T_MENUCONFIG 266
+#define T_HELP 267
+#define T_HELPTEXT 268
+#define T_IF 269
+#define T_ENDIF 270
+#define T_DEPENDS 271
+#define T_REQUIRES 272
+#define T_OPTIONAL 273
+#define T_PROMPT 274
+#define T_DEFAULT 275
+#define T_TRISTATE 276
+#define T_DEF_TRISTATE 277
+#define T_BOOLEAN 278
+#define T_DEF_BOOLEAN 279
+#define T_STRING 280
+#define T_INT 281
+#define T_HEX 282
+#define T_WORD 283
+#define T_WORD_QUOTE 284
+#define T_UNEQUAL 285
+#define T_EOF 286
+#define T_EOL 287
+#define T_CLOSE_PAREN 288
+#define T_OPEN_PAREN 289
+#define T_ON 290
+#define T_SELECT 291
+#define T_RANGE 292
+#define T_OR 293
+#define T_AND 294
+#define T_EQUAL 295
+#define T_NOT 296
+
+
+
+
+/* Copy the first part of user declarations. */
+
+
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
+
+#define PRINTD 0x0001
+#define DEBUG_PARSE 0x0002
+
+int cdebug = PRINTD;
+
+extern int zconflex(void);
+static void zconfprint(const char *err, ...);
+static void zconferror(const char *err);
+static bool zconf_endtoken(int token, int starttoken, int endtoken);
+
+struct symbol *symbol_hash[257];
+
+static struct menu *current_menu, *current_entry;
+
+#define YYERROR_VERBOSE
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+
+typedef union YYSTYPE {
+ int token;
+ char *string;
+ struct symbol *symbol;
+ struct expr *expr;
+ struct menu *menu;
+} YYSTYPE;
+/* Line 191 of yacc.c. */
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+
+/* Line 214 of yacc.c. */
+
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 201
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 42
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 41
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 104
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 182
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 296
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short yyprhs[] =
+{
+ 0, 0, 3, 4, 7, 9, 11, 13, 17, 19,
+ 21, 23, 26, 28, 30, 32, 34, 36, 38, 42,
+ 45, 49, 52, 53, 56, 59, 62, 65, 69, 74,
+ 78, 83, 87, 91, 95, 100, 105, 110, 116, 119,
+ 122, 124, 128, 131, 132, 135, 138, 141, 144, 149,
+ 153, 157, 160, 165, 166, 169, 173, 175, 179, 182,
+ 183, 186, 189, 192, 196, 199, 201, 205, 208, 209,
+ 212, 215, 218, 222, 226, 228, 232, 235, 238, 241,
+ 242, 245, 248, 253, 257, 261, 262, 265, 267, 269,
+ 272, 275, 278, 280, 282, 283, 286, 288, 292, 296,
+ 300, 303, 307, 311, 313
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 43, 0, -1, -1, 43, 44, -1, 45, -1, 55,
+ -1, 66, -1, 3, 77, 79, -1, 5, -1, 15,
+ -1, 8, -1, 1, 79, -1, 61, -1, 71, -1,
+ 47, -1, 49, -1, 69, -1, 79, -1, 10, 28,
+ 32, -1, 46, 50, -1, 11, 28, 32, -1, 48,
+ 50, -1, -1, 50, 51, -1, 50, 75, -1, 50,
+ 73, -1, 50, 32, -1, 21, 76, 32, -1, 22,
+ 81, 80, 32, -1, 23, 76, 32, -1, 24, 81,
+ 80, 32, -1, 26, 76, 32, -1, 27, 76, 32,
+ -1, 25, 76, 32, -1, 19, 77, 80, 32, -1,
+ 20, 81, 80, 32, -1, 36, 28, 80, 32, -1,
+ 37, 82, 82, 80, 32, -1, 7, 32, -1, 52,
+ 56, -1, 78, -1, 53, 58, 54, -1, 53, 58,
+ -1, -1, 56, 57, -1, 56, 75, -1, 56, 73,
+ -1, 56, 32, -1, 19, 77, 80, 32, -1, 21,
+ 76, 32, -1, 23, 76, 32, -1, 18, 32, -1,
+ 20, 28, 80, 32, -1, -1, 58, 45, -1, 14,
+ 81, 32, -1, 78, -1, 59, 62, 60, -1, 59,
+ 62, -1, -1, 62, 45, -1, 62, 66, -1, 62,
+ 55, -1, 4, 77, 32, -1, 63, 74, -1, 78,
+ -1, 64, 67, 65, -1, 64, 67, -1, -1, 67,
+ 45, -1, 67, 66, -1, 67, 55, -1, 67, 1,
+ 32, -1, 6, 77, 32, -1, 68, -1, 9, 77,
+ 32, -1, 70, 74, -1, 12, 32, -1, 72, 13,
+ -1, -1, 74, 75, -1, 74, 32, -1, 16, 35,
+ 81, 32, -1, 16, 81, 32, -1, 17, 81, 32,
+ -1, -1, 77, 80, -1, 28, -1, 29, -1, 5,
+ 79, -1, 8, 79, -1, 15, 79, -1, 32, -1,
+ 31, -1, -1, 14, 81, -1, 82, -1, 82, 40,
+ 82, -1, 82, 30, 82, -1, 34, 81, 33, -1,
+ 41, 81, -1, 81, 38, 81, -1, 81, 39, 81,
+ -1, 28, -1, 29, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 94, 94, 95, 98, 99, 100, 101, 102, 103,
+ 104, 105, 109, 110, 111, 112, 113, 114, 120, 128,
+ 134, 142, 152, 154, 155, 156, 157, 160, 166, 173,
+ 179, 186, 192, 198, 204, 210, 216, 222, 230, 239,
+ 245, 254, 255, 261, 263, 264, 265, 266, 269, 275,
+ 281, 287, 293, 299, 301, 306, 315, 324, 325, 331,
+ 333, 334, 335, 340, 347, 353, 362, 363, 369, 371,
+ 372, 373, 374, 377, 383, 390, 397, 404, 410, 417,
+ 418, 419, 422, 427, 432, 440, 442, 447, 448, 451,
+ 452, 453, 457, 457, 459, 460, 463, 464, 465, 466,
+ 467, 468, 469, 472, 473
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
+ "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
+ "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
+ "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE",
+ "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT",
+ "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL",
+ "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR",
+ "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block",
+ "common_block", "config_entry_start", "config_stmt",
+ "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
+ "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
+ "choice_option_list", "choice_option", "choice_block", "if", "if_end",
+ "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt",
+ "menu_block", "source", "source_stmt", "comment", "comment_stmt",
+ "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
+ "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 42, 43, 43, 44, 44, 44, 44, 44, 44,
+ 44, 44, 45, 45, 45, 45, 45, 45, 46, 47,
+ 48, 49, 50, 50, 50, 50, 50, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 52, 53,
+ 54, 55, 55, 56, 56, 56, 56, 56, 57, 57,
+ 57, 57, 57, 58, 58, 59, 60, 61, 61, 62,
+ 62, 62, 62, 63, 64, 65, 66, 66, 67, 67,
+ 67, 67, 67, 68, 69, 70, 71, 72, 73, 74,
+ 74, 74, 75, 75, 75, 76, 76, 77, 77, 78,
+ 78, 78, 79, 79, 80, 80, 81, 81, 81, 81,
+ 81, 81, 81, 82, 82
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 1, 3, 1, 1,
+ 1, 2, 1, 1, 1, 1, 1, 1, 3, 2,
+ 3, 2, 0, 2, 2, 2, 2, 3, 4, 3,
+ 4, 3, 3, 3, 4, 4, 4, 5, 2, 2,
+ 1, 3, 2, 0, 2, 2, 2, 2, 4, 3,
+ 3, 2, 4, 0, 2, 3, 1, 3, 2, 0,
+ 2, 2, 2, 3, 2, 1, 3, 2, 0, 2,
+ 2, 2, 3, 3, 1, 3, 2, 2, 2, 0,
+ 2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
+ 2, 2, 1, 1, 0, 2, 1, 3, 3, 3,
+ 2, 3, 3, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 2, 0, 1, 0, 0, 0, 8, 0, 0, 10,
+ 0, 0, 0, 0, 9, 93, 92, 3, 4, 22,
+ 14, 22, 15, 43, 53, 5, 59, 12, 79, 68,
+ 6, 74, 16, 79, 13, 17, 11, 87, 88, 0,
+ 0, 0, 38, 0, 0, 0, 103, 104, 0, 0,
+ 0, 96, 19, 21, 39, 42, 58, 64, 0, 76,
+ 7, 63, 73, 75, 18, 20, 0, 100, 55, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 85, 0,
+ 85, 0, 85, 85, 85, 26, 0, 0, 23, 0,
+ 25, 24, 0, 0, 0, 85, 85, 47, 44, 46,
+ 45, 0, 0, 0, 54, 41, 40, 60, 62, 57,
+ 61, 56, 81, 80, 0, 69, 71, 66, 70, 65,
+ 99, 101, 102, 98, 97, 77, 0, 0, 0, 94,
+ 94, 0, 94, 94, 0, 94, 0, 0, 0, 94,
+ 0, 78, 51, 94, 94, 0, 0, 89, 90, 91,
+ 72, 0, 83, 84, 0, 0, 0, 27, 86, 0,
+ 29, 0, 33, 31, 32, 0, 94, 0, 0, 49,
+ 50, 82, 95, 34, 35, 28, 30, 36, 0, 48,
+ 52, 37
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short yydefgoto[] =
+{
+ -1, 1, 17, 18, 19, 20, 21, 22, 52, 88,
+ 23, 24, 105, 25, 54, 98, 55, 26, 109, 27,
+ 56, 28, 29, 117, 30, 58, 31, 32, 33, 34,
+ 89, 90, 57, 91, 131, 132, 106, 35, 155, 50,
+ 51
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -99
+static const short yypact[] =
+{
+ -99, 48, -99, 38, 46, 46, -99, 46, -29, -99,
+ 46, -17, -3, -11, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, -99, -99, -99, -99, -99, 38,
+ 12, 15, -99, 18, 51, 62, -99, -99, -11, -11,
+ 4, -24, 138, 138, 160, 121, 110, -4, 81, -4,
+ -99, -99, -99, -99, -99, -99, -19, -99, -99, -11,
+ -11, 70, 70, 73, 32, -11, 46, -11, 46, -11,
+ 46, -11, 46, 46, 46, -99, 36, 70, -99, 95,
+ -99, -99, 96, 46, 106, 46, 46, -99, -99, -99,
+ -99, 38, 38, 38, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, 112, -99, -99, -99, -99, -99,
+ -99, 117, -99, -99, -99, -99, -11, 33, 65, 131,
+ 1, 119, 131, 1, 136, 1, 153, 154, 155, 131,
+ 70, -99, -99, 131, 131, 156, 157, -99, -99, -99,
+ -99, 101, -99, -99, -11, 158, 159, -99, -99, 161,
+ -99, 162, -99, -99, -99, 163, 131, 164, 165, -99,
+ -99, -99, 99, -99, -99, -99, -99, -99, 166, -99,
+ -99, -99
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short yypgoto[] =
+{
+ -99, -99, -99, 111, -99, -99, -99, -99, 178, -99,
+ -99, -99, -99, 91, -99, -99, -99, -99, -99, -99,
+ -99, -99, -99, -99, 115, -99, -99, -99, -99, -99,
+ -99, 146, 168, 89, 27, 0, 126, -1, -98, -48,
+ -63
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -68
+static const short yytable[] =
+{
+ 66, 67, 36, 42, 39, 40, 71, 41, 123, 124,
+ 43, 44, 74, 75, 120, 154, 72, 46, 47, 69,
+ 70, 121, 122, 48, 140, 45, 127, 128, 112, 130,
+ 49, 133, 156, 135, 158, 159, 68, 161, 60, 69,
+ 70, 165, 69, 70, 61, 167, 168, 62, 2, 3,
+ 63, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 46, 47, 13, 14, 139, 152, 48, 126, 178, 15,
+ 16, 69, 70, 49, 37, 38, 129, 166, 151, 15,
+ 16, -67, 114, 64, -67, 5, 101, 7, 8, 102,
+ 10, 11, 12, 143, 65, 13, 103, 153, 46, 47,
+ 147, 148, 149, 69, 70, 125, 172, 134, 141, 136,
+ 137, 138, 15, 16, 5, 101, 7, 8, 102, 10,
+ 11, 12, 145, 146, 13, 103, 101, 7, 142, 102,
+ 10, 11, 12, 171, 144, 13, 103, 69, 70, 69,
+ 70, 15, 16, 100, 150, 154, 113, 108, 113, 116,
+ 73, 157, 15, 16, 74, 75, 70, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 104, 107, 160, 115,
+ 85, 110, 73, 118, 86, 87, 74, 75, 92, 93,
+ 94, 95, 111, 96, 119, 162, 163, 164, 169, 170,
+ 173, 174, 97, 175, 176, 177, 179, 180, 181, 53,
+ 99, 59
+};
+
+static const unsigned char yycheck[] =
+{
+ 48, 49, 3, 32, 4, 5, 30, 7, 71, 72,
+ 10, 28, 16, 17, 33, 14, 40, 28, 29, 38,
+ 39, 69, 70, 34, 87, 28, 74, 75, 32, 77,
+ 41, 79, 130, 81, 132, 133, 32, 135, 39, 38,
+ 39, 139, 38, 39, 32, 143, 144, 32, 0, 1,
+ 32, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 28, 29, 14, 15, 28, 32, 34, 35, 166, 31,
+ 32, 38, 39, 41, 28, 29, 76, 140, 126, 31,
+ 32, 0, 1, 32, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 93, 32, 14, 15, 32, 28, 29,
+ 101, 102, 103, 38, 39, 32, 154, 80, 13, 82,
+ 83, 84, 31, 32, 4, 5, 6, 7, 8, 9,
+ 10, 11, 95, 96, 14, 15, 5, 6, 32, 8,
+ 9, 10, 11, 32, 28, 14, 15, 38, 39, 38,
+ 39, 31, 32, 54, 32, 14, 57, 56, 59, 58,
+ 12, 32, 31, 32, 16, 17, 39, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 55, 56, 32, 58,
+ 32, 56, 12, 58, 36, 37, 16, 17, 18, 19,
+ 20, 21, 56, 23, 58, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 21,
+ 54, 33
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 43, 0, 1, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 14, 15, 31, 32, 44, 45, 46,
+ 47, 48, 49, 52, 53, 55, 59, 61, 63, 64,
+ 66, 68, 69, 70, 71, 79, 79, 28, 29, 77,
+ 77, 77, 32, 77, 28, 28, 28, 29, 34, 41,
+ 81, 82, 50, 50, 56, 58, 62, 74, 67, 74,
+ 79, 32, 32, 32, 32, 32, 81, 81, 32, 38,
+ 39, 30, 40, 12, 16, 17, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 32, 36, 37, 51, 72,
+ 73, 75, 18, 19, 20, 21, 23, 32, 57, 73,
+ 75, 5, 8, 15, 45, 54, 78, 45, 55, 60,
+ 66, 78, 32, 75, 1, 45, 55, 65, 66, 78,
+ 33, 81, 81, 82, 82, 32, 35, 81, 81, 77,
+ 81, 76, 77, 81, 76, 81, 76, 76, 76, 28,
+ 82, 13, 32, 77, 28, 76, 76, 79, 79, 79,
+ 32, 81, 32, 32, 14, 80, 80, 32, 80, 80,
+ 32, 80, 32, 32, 32, 80, 82, 80, 80, 32,
+ 32, 32, 81, 32, 32, 32, 32, 32, 80, 32,
+ 32, 32
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.first_line = Rhs[1].first_line; \
+ Current.first_column = Rhs[1].first_column; \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (cinluded). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short *bottom;
+ short *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylineno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylineno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 8:
+
+ { zconfprint("unexpected 'endmenu' statement"); ;}
+ break;
+
+ case 9:
+
+ { zconfprint("unexpected 'endif' statement"); ;}
+ break;
+
+ case 10:
+
+ { zconfprint("unexpected 'endchoice' statement"); ;}
+ break;
+
+ case 11:
+
+ { zconfprint("syntax error"); yyerrok; ;}
+ break;
+
+ case 18:
+
+ {
+ struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+;}
+ break;
+
+ case 19:
+
+ {
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 20:
+
+ {
+ struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+;}
+ break;
+
+ case 21:
+
+ {
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 27:
+
+ {
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 28:
+
+ {
+ menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 29:
+
+ {
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 30:
+
+ {
+ menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 31:
+
+ {
+ menu_set_type(S_INT);
+ printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 32:
+
+ {
+ menu_set_type(S_HEX);
+ printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 33:
+
+ {
+ menu_set_type(S_STRING);
+ printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 34:
+
+ {
+ menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 35:
+
+ {
+ menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 36:
+
+ {
+ menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 37:
+
+ {
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 38:
+
+ {
+ struct symbol *sym = sym_lookup(NULL, 0);
+ sym->flags |= SYMBOL_CHOICE;
+ menu_add_entry(sym);
+ menu_add_expr(P_CHOICE, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 39:
+
+ {
+ menu_end_entry();
+ menu_add_menu();
+;}
+ break;
+
+ case 40:
+
+ {
+ if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+ }
+;}
+ break;
+
+ case 42:
+
+ {
+ printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+;}
+ break;
+
+ case 48:
+
+ {
+ menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 49:
+
+ {
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 50:
+
+ {
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 51:
+
+ {
+ current_entry->sym->flags |= SYMBOL_OPTIONAL;
+ printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 52:
+
+ {
+ menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 55:
+
+ {
+ printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+ menu_add_entry(NULL);
+ menu_add_dep(yyvsp[-1].expr);
+ menu_end_entry();
+ menu_add_menu();
+;}
+ break;
+
+ case 56:
+
+ {
+ if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+ }
+;}
+ break;
+
+ case 58:
+
+ {
+ printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+;}
+ break;
+
+ case 63:
+
+ {
+ menu_add_entry(NULL);
+ menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 64:
+
+ {
+ menu_end_entry();
+ menu_add_menu();
+;}
+ break;
+
+ case 65:
+
+ {
+ if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+ }
+;}
+ break;
+
+ case 67:
+
+ {
+ printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+;}
+ break;
+
+ case 72:
+
+ { zconfprint("invalid menu option"); yyerrok; ;}
+ break;
+
+ case 73:
+
+ {
+ yyval.string = yyvsp[-1].string;
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+;}
+ break;
+
+ case 74:
+
+ {
+ zconf_nextfile(yyvsp[0].string);
+;}
+ break;
+
+ case 75:
+
+ {
+ menu_add_entry(NULL);
+ menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 76:
+
+ {
+ menu_end_entry();
+;}
+ break;
+
+ case 77:
+
+ {
+ printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+ zconf_starthelp();
+;}
+ break;
+
+ case 78:
+
+ {
+ current_entry->sym->help = yyvsp[0].string;
+;}
+ break;
+
+ case 82:
+
+ {
+ menu_add_dep(yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 83:
+
+ {
+ menu_add_dep(yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 84:
+
+ {
+ menu_add_dep(yyvsp[-1].expr);
+ printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
+;}
+ break;
+
+ case 86:
+
+ {
+ menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr);
+;}
+ break;
+
+ case 89:
+
+ { yyval.token = T_ENDMENU; ;}
+ break;
+
+ case 90:
+
+ { yyval.token = T_ENDCHOICE; ;}
+ break;
+
+ case 91:
+
+ { yyval.token = T_ENDIF; ;}
+ break;
+
+ case 94:
+
+ { yyval.expr = NULL; ;}
+ break;
+
+ case 95:
+
+ { yyval.expr = yyvsp[0].expr; ;}
+ break;
+
+ case 96:
+
+ { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;}
+ break;
+
+ case 97:
+
+ { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ break;
+
+ case 98:
+
+ { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ break;
+
+ case 99:
+
+ { yyval.expr = yyvsp[-1].expr; ;}
+ break;
+
+ case 100:
+
+ { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;}
+ break;
+
+ case 101:
+
+ { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ break;
+
+ case 102:
+
+ { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ break;
+
+ case 103:
+
+ { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;}
+ break;
+
+ case 104:
+
+ { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;}
+ break;
+
+
+ }
+
+/* Line 999 of yacc.c. */
+
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("syntax error, unexpected ") + 1;
+ yysize += yystrlen (yytname[yytype]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ {
+ /* Pop the error token. */
+ YYPOPSTACK;
+ /* Pop the rest of the stack. */
+ while (yyss < yyssp)
+ {
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ YYPOPSTACK;
+ }
+ YYABORT;
+ }
+
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action. |
+`----------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ yyvsp--;
+ yystate = *--yyssp;
+
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+
+
+
+void conf_parse(const char *name)
+{
+ struct symbol *sym;
+ int i;
+
+ zconf_initscan(name);
+
+ sym_init();
+ menu_init();
+ modules_sym = sym_lookup("MODULES", 0);
+ rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
+
+ //zconfdebug = 1;
+ zconfparse();
+ if (zconfnerrs)
+ exit(1);
+ menu_finalize(&rootmenu);
+ for_all_symbols(i, sym) {
+ if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
+ printf("\n");
+ else
+ sym->flags |= SYMBOL_CHECK_DONE;
+ }
+
+ sym_change_count = 1;
+}
+
+const char *zconf_tokenname(int token)
+{
+ switch (token) {
+ case T_MENU: return "menu";
+ case T_ENDMENU: return "endmenu";
+ case T_CHOICE: return "choice";
+ case T_ENDCHOICE: return "endchoice";
+ case T_IF: return "if";
+ case T_ENDIF: return "endif";
+ }
+ return "<token>";
+}
+
+static bool zconf_endtoken(int token, int starttoken, int endtoken)
+{
+ if (token != endtoken) {
+ zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ if (current_menu->file != current_file) {
+ zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfprint("location of the '%s'", zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ return true;
+}
+
+static void zconfprint(const char *err, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
+ va_start(ap, err);
+ vfprintf(stderr, err, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static void zconferror(const char *err)
+{
+ fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+}
+
+void print_quoted_string(FILE *out, const char *str)
+{
+ const char *p;
+ int len;
+
+ putc('"', out);
+ while ((p = strchr(str, '"'))) {
+ len = p - str;
+ if (len)
+ fprintf(out, "%.*s", len, str);
+ fputs("\\\"", out);
+ str = p + 1;
+ }
+ fputs(str, out);
+ putc('"', out);
+}
+
+void print_symbol(FILE *out, struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ struct property *prop;
+
+ if (sym_is_choice(sym))
+ fprintf(out, "choice\n");
+ else
+ fprintf(out, "config %s\n", sym->name);
+ switch (sym->type) {
+ case S_BOOLEAN:
+ fputs(" boolean\n", out);
+ break;
+ case S_TRISTATE:
+ fputs(" tristate\n", out);
+ break;
+ case S_STRING:
+ fputs(" string\n", out);
+ break;
+ case S_INT:
+ fputs(" integer\n", out);
+ break;
+ case S_HEX:
+ fputs(" hex\n", out);
+ break;
+ default:
+ fputs(" ???\n", out);
+ break;
+ }
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ switch (prop->type) {
+ case P_PROMPT:
+ fputs(" prompt ", out);
+ print_quoted_string(out, prop->text);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_DEFAULT:
+ fputs( " default ", out);
+ expr_fprint(prop->expr, out);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_CHOICE:
+ fputs(" #choice value\n", out);
+ break;
+ default:
+ fprintf(out, " unknown prop %d!\n", prop->type);
+ break;
+ }
+ }
+ if (sym->help) {
+ int len = strlen(sym->help);
+ while (sym->help[--len] == '\n')
+ sym->help[len] = 0;
+ fprintf(out, " help\n%s\n", sym->help);
+ }
+ fputc('\n', out);
+}
+
+void zconfdump(FILE *out)
+{
+ struct property *prop;
+ struct symbol *sym;
+ struct menu *menu;
+
+ menu = rootmenu.list;
+ while (menu) {
+ if ((sym = menu->sym))
+ print_symbol(out, menu);
+ else if ((prop = menu->prompt)) {
+ switch (prop->type) {
+ case P_COMMENT:
+ fputs("\ncomment ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ case P_MENU:
+ fputs("\nmenu ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ default:
+ ;
+ }
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" depends ", out);
+ expr_fprint(prop->visible.expr, out);
+ fputc('\n', out);
+ }
+ fputs("\n", out);
+ }
+
+ if (menu->list)
+ menu = menu->list;
+ else if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->prompt && menu->prompt->type == P_MENU)
+ fputs("\nendmenu\n", out);
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+}
+
+#include "lex.zconf.c"
+#include "util.c"
+#include "confdata.c"
+#include "expr.c"
+#include "symbol.c"
+#include "menu.c"
+
+
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 @@
+/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifndef BISON_ZCONF_TAB_H
+# define BISON_ZCONF_TAB_H
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ T_MAINMENU = 258,
+ T_MENU = 259,
+ T_ENDMENU = 260,
+ T_SOURCE = 261,
+ T_CHOICE = 262,
+ T_ENDCHOICE = 263,
+ T_COMMENT = 264,
+ T_CONFIG = 265,
+ T_HELP = 266,
+ T_HELPTEXT = 267,
+ T_IF = 268,
+ T_ENDIF = 269,
+ T_DEPENDS = 270,
+ T_REQUIRES = 271,
+ T_OPTIONAL = 272,
+ T_PROMPT = 273,
+ T_DEFAULT = 274,
+ T_TRISTATE = 275,
+ T_BOOLEAN = 276,
+ T_INT = 277,
+ T_HEX = 278,
+ T_WORD = 279,
+ T_STRING = 280,
+ T_UNEQUAL = 281,
+ T_EOF = 282,
+ T_EOL = 283,
+ T_CLOSE_PAREN = 284,
+ T_OPEN_PAREN = 285,
+ T_ON = 286,
+ T_OR = 287,
+ T_AND = 288,
+ T_EQUAL = 289,
+ T_NOT = 290
+ };
+#endif
+#define T_MAINMENU 258
+#define T_MENU 259
+#define T_ENDMENU 260
+#define T_SOURCE 261
+#define T_CHOICE 262
+#define T_ENDCHOICE 263
+#define T_COMMENT 264
+#define T_CONFIG 265
+#define T_HELP 266
+#define T_HELPTEXT 267
+#define T_IF 268
+#define T_ENDIF 269
+#define T_DEPENDS 270
+#define T_REQUIRES 271
+#define T_OPTIONAL 272
+#define T_PROMPT 273
+#define T_DEFAULT 274
+#define T_TRISTATE 275
+#define T_BOOLEAN 276
+#define T_INT 277
+#define T_HEX 278
+#define T_WORD 279
+#define T_STRING 280
+#define T_UNEQUAL 281
+#define T_EOF 282
+#define T_EOL 283
+#define T_CLOSE_PAREN 284
+#define T_OPEN_PAREN 285
+#define T_ON 286
+#define T_OR 287
+#define T_AND 288
+#define T_EQUAL 289
+#define T_NOT 290
+
+
+
+
+#ifndef YYSTYPE
+#line 33 "zconf.y"
+typedef union {
+ int token;
+ char *string;
+ struct symbol *symbol;
+ struct expr *expr;
+ struct menu *menu;
+} yystype;
+/* Line 1281 of /usr/share/bison/yacc.c. */
+#line 118 "zconf.tab.h"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE zconflval;
+
+
+#endif /* not BISON_ZCONF_TAB_H */
+
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 @@
+%{
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
+
+#define PRINTD 0x0001
+#define DEBUG_PARSE 0x0002
+
+int cdebug = PRINTD;
+
+extern int zconflex(void);
+static void zconfprint(const char *err, ...);
+static void zconferror(const char *err);
+static bool zconf_endtoken(int token, int starttoken, int endtoken);
+
+struct symbol *symbol_hash[257];
+
+static struct menu *current_menu, *current_entry;
+
+#define YYERROR_VERBOSE
+%}
+%expect 40
+
+%union
+{
+ int token;
+ char *string;
+ struct symbol *symbol;
+ struct expr *expr;
+ struct menu *menu;
+}
+
+%token T_MAINMENU
+%token T_MENU
+%token T_ENDMENU
+%token T_SOURCE
+%token T_CHOICE
+%token T_ENDCHOICE
+%token T_COMMENT
+%token T_CONFIG
+%token T_MENUCONFIG
+%token T_HELP
+%token <string> T_HELPTEXT
+%token T_IF
+%token T_ENDIF
+%token T_DEPENDS
+%token T_REQUIRES
+%token T_OPTIONAL
+%token T_PROMPT
+%token T_DEFAULT
+%token T_TRISTATE
+%token T_DEF_TRISTATE
+%token T_BOOLEAN
+%token T_DEF_BOOLEAN
+%token T_STRING
+%token T_INT
+%token T_HEX
+%token <string> T_WORD
+%token <string> T_WORD_QUOTE
+%token T_UNEQUAL
+%token T_EOF
+%token T_EOL
+%token T_CLOSE_PAREN
+%token T_OPEN_PAREN
+%token T_ON
+%token T_SELECT
+%token T_RANGE
+
+%left T_OR
+%left T_AND
+%left T_EQUAL T_UNEQUAL
+%nonassoc T_NOT
+
+%type <string> prompt
+%type <string> source
+%type <symbol> symbol
+%type <expr> expr
+%type <expr> if_expr
+%type <token> end
+
+%{
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+%}
+%%
+input: /* empty */
+ | input block
+;
+
+block: common_block
+ | choice_stmt
+ | menu_stmt
+ | T_MAINMENU prompt nl_or_eof
+ | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
+ | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
+ | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
+ | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
+;
+
+common_block:
+ if_stmt
+ | comment_stmt
+ | config_stmt
+ | menuconfig_stmt
+ | source_stmt
+ | nl_or_eof
+;
+
+
+/* config/menuconfig entry */
+
+config_entry_start: T_CONFIG T_WORD T_EOL
+{
+ struct symbol *sym = sym_lookup($2, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+config_stmt: config_entry_start config_option_list
+{
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+};
+
+menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
+{
+ struct symbol *sym = sym_lookup($2, 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+menuconfig_stmt: menuconfig_entry_start config_option_list
+{
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+};
+
+config_option_list:
+ /* empty */
+ | config_option_list config_option
+ | config_option_list depends
+ | config_option_list help
+ | config_option_list T_EOL
+;
+
+config_option: T_TRISTATE prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_DEF_TRISTATE expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_BOOLEAN prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_DEF_BOOLEAN expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_INT prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_INT);
+ printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_HEX prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_HEX);
+ printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_STRING prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_STRING);
+ printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_PROMPT prompt if_expr T_EOL
+{
+ menu_add_prompt(P_PROMPT, $2, $3);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_DEFAULT expr if_expr T_EOL
+{
+ menu_add_expr(P_DEFAULT, $2, $3);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_SELECT T_WORD if_expr T_EOL
+{
+ menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_RANGE symbol symbol if_expr T_EOL
+{
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
+ printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+};
+
+/* choice entry */
+
+choice: T_CHOICE T_EOL
+{
+ struct symbol *sym = sym_lookup(NULL, 0);
+ sym->flags |= SYMBOL_CHOICE;
+ menu_add_entry(sym);
+ menu_add_expr(P_CHOICE, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+};
+
+choice_entry: choice choice_option_list
+{
+ menu_end_entry();
+ menu_add_menu();
+};
+
+choice_end: end
+{
+ if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+ }
+};
+
+choice_stmt:
+ choice_entry choice_block choice_end
+ | choice_entry choice_block
+{
+ printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+};
+
+choice_option_list:
+ /* empty */
+ | choice_option_list choice_option
+ | choice_option_list depends
+ | choice_option_list help
+ | choice_option_list T_EOL
+;
+
+choice_option: T_PROMPT prompt if_expr T_EOL
+{
+ menu_add_prompt(P_PROMPT, $2, $3);
+ printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_TRISTATE prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_TRISTATE);
+ printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
+{
+ menu_set_type(S_BOOLEAN);
+ printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_OPTIONAL T_EOL
+{
+ current_entry->sym->flags |= SYMBOL_OPTIONAL;
+ printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_DEFAULT T_WORD if_expr T_EOL
+{
+ menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
+ printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+};
+
+choice_block:
+ /* empty */
+ | choice_block common_block
+;
+
+/* if entry */
+
+if: T_IF expr T_EOL
+{
+ printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+ menu_add_entry(NULL);
+ menu_add_dep($2);
+ menu_end_entry();
+ menu_add_menu();
+};
+
+if_end: end
+{
+ if (zconf_endtoken($1, T_IF, T_ENDIF)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+ }
+};
+
+if_stmt:
+ if if_block if_end
+ | if if_block
+{
+ printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+};
+
+if_block:
+ /* empty */
+ | if_block common_block
+ | if_block menu_stmt
+ | if_block choice_stmt
+;
+
+/* menu entry */
+
+menu: T_MENU prompt T_EOL
+{
+ menu_add_entry(NULL);
+ menu_add_prop(P_MENU, $2, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+};
+
+menu_entry: menu depends_list
+{
+ menu_end_entry();
+ menu_add_menu();
+};
+
+menu_end: end
+{
+ if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
+ menu_end_menu();
+ printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+ }
+};
+
+menu_stmt:
+ menu_entry menu_block menu_end
+ | menu_entry menu_block
+{
+ printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
+ zconfnerrs++;
+};
+
+menu_block:
+ /* empty */
+ | menu_block common_block
+ | menu_block menu_stmt
+ | menu_block choice_stmt
+ | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
+;
+
+source: T_SOURCE prompt T_EOL
+{
+ $$ = $2;
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+source_stmt: source
+{
+ zconf_nextfile($1);
+};
+
+/* comment entry */
+
+comment: T_COMMENT prompt T_EOL
+{
+ menu_add_entry(NULL);
+ menu_add_prop(P_COMMENT, $2, NULL, NULL);
+ printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+};
+
+comment_stmt: comment depends_list
+{
+ menu_end_entry();
+};
+
+/* help option */
+
+help_start: T_HELP T_EOL
+{
+ printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+ zconf_starthelp();
+};
+
+help: help_start T_HELPTEXT
+{
+ current_entry->sym->help = $2;
+};
+
+/* depends option */
+
+depends_list: /* empty */
+ | depends_list depends
+ | depends_list T_EOL
+;
+
+depends: T_DEPENDS T_ON expr T_EOL
+{
+ menu_add_dep($3);
+ printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+}
+ | T_DEPENDS expr T_EOL
+{
+ menu_add_dep($2);
+ printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+}
+ | T_REQUIRES expr T_EOL
+{
+ menu_add_dep($2);
+ printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
+};
+
+/* prompt statement */
+
+prompt_stmt_opt:
+ /* empty */
+ | prompt if_expr
+{
+ menu_add_prop(P_PROMPT, $1, NULL, $2);
+};
+
+prompt: T_WORD
+ | T_WORD_QUOTE
+;
+
+end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
+ | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
+ | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
+;
+
+nl_or_eof:
+ T_EOL | T_EOF;
+
+if_expr: /* empty */ { $$ = NULL; }
+ | T_IF expr { $$ = $2; }
+;
+
+expr: symbol { $$ = expr_alloc_symbol($1); }
+ | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
+ | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
+ | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
+ | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
+ | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
+ | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
+;
+
+symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
+ | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
+;
+
+%%
+
+void conf_parse(const char *name)
+{
+ struct symbol *sym;
+ int i;
+
+ zconf_initscan(name);
+
+ sym_init();
+ menu_init();
+ modules_sym = sym_lookup("MODULES", 0);
+ rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
+
+ //zconfdebug = 1;
+ zconfparse();
+ if (zconfnerrs)
+ exit(1);
+ menu_finalize(&rootmenu);
+ for_all_symbols(i, sym) {
+ if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
+ printf("\n");
+ else
+ sym->flags |= SYMBOL_CHECK_DONE;
+ }
+
+ sym_change_count = 1;
+}
+
+const char *zconf_tokenname(int token)
+{
+ switch (token) {
+ case T_MENU: return "menu";
+ case T_ENDMENU: return "endmenu";
+ case T_CHOICE: return "choice";
+ case T_ENDCHOICE: return "endchoice";
+ case T_IF: return "if";
+ case T_ENDIF: return "endif";
+ }
+ return "<token>";
+}
+
+static bool zconf_endtoken(int token, int starttoken, int endtoken)
+{
+ if (token != endtoken) {
+ zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ if (current_menu->file != current_file) {
+ zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
+ zconfprint("location of the '%s'", zconf_tokenname(starttoken));
+ zconfnerrs++;
+ return false;
+ }
+ return true;
+}
+
+static void zconfprint(const char *err, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
+ va_start(ap, err);
+ vfprintf(stderr, err, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static void zconferror(const char *err)
+{
+ fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+}
+
+void print_quoted_string(FILE *out, const char *str)
+{
+ const char *p;
+ int len;
+
+ putc('"', out);
+ while ((p = strchr(str, '"'))) {
+ len = p - str;
+ if (len)
+ fprintf(out, "%.*s", len, str);
+ fputs("\\\"", out);
+ str = p + 1;
+ }
+ fputs(str, out);
+ putc('"', out);
+}
+
+void print_symbol(FILE *out, struct menu *menu)
+{
+ struct symbol *sym = menu->sym;
+ struct property *prop;
+
+ if (sym_is_choice(sym))
+ fprintf(out, "choice\n");
+ else
+ fprintf(out, "config %s\n", sym->name);
+ switch (sym->type) {
+ case S_BOOLEAN:
+ fputs(" boolean\n", out);
+ break;
+ case S_TRISTATE:
+ fputs(" tristate\n", out);
+ break;
+ case S_STRING:
+ fputs(" string\n", out);
+ break;
+ case S_INT:
+ fputs(" integer\n", out);
+ break;
+ case S_HEX:
+ fputs(" hex\n", out);
+ break;
+ default:
+ fputs(" ???\n", out);
+ break;
+ }
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ switch (prop->type) {
+ case P_PROMPT:
+ fputs(" prompt ", out);
+ print_quoted_string(out, prop->text);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_DEFAULT:
+ fputs( " default ", out);
+ expr_fprint(prop->expr, out);
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" if ", out);
+ expr_fprint(prop->visible.expr, out);
+ }
+ fputc('\n', out);
+ break;
+ case P_CHOICE:
+ fputs(" #choice value\n", out);
+ break;
+ default:
+ fprintf(out, " unknown prop %d!\n", prop->type);
+ break;
+ }
+ }
+ if (sym->help) {
+ int len = strlen(sym->help);
+ while (sym->help[--len] == '\n')
+ sym->help[len] = 0;
+ fprintf(out, " help\n%s\n", sym->help);
+ }
+ fputc('\n', out);
+}
+
+void zconfdump(FILE *out)
+{
+ struct property *prop;
+ struct symbol *sym;
+ struct menu *menu;
+
+ menu = rootmenu.list;
+ while (menu) {
+ if ((sym = menu->sym))
+ print_symbol(out, menu);
+ else if ((prop = menu->prompt)) {
+ switch (prop->type) {
+ case P_COMMENT:
+ fputs("\ncomment ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ case P_MENU:
+ fputs("\nmenu ", out);
+ print_quoted_string(out, prop->text);
+ fputs("\n", out);
+ break;
+ default:
+ ;
+ }
+ if (!expr_is_yes(prop->visible.expr)) {
+ fputs(" depends ", out);
+ expr_fprint(prop->visible.expr, out);
+ fputc('\n', out);
+ }
+ fputs("\n", out);
+ }
+
+ if (menu->list)
+ menu = menu->list;
+ else if (menu->next)
+ menu = menu->next;
+ else while ((menu = menu->parent)) {
+ if (menu->prompt && menu->prompt->type == P_MENU)
+ fputs("\nendmenu\n", out);
+ if (menu->next) {
+ menu = menu->next;
+ break;
+ }
+ }
+ }
+}
+
+#include "lex.zconf.c"
+#include "util.c"
+#include "confdata.c"
+#include "expr.c"
+#include "symbol.c"
+#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 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
+## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
+## Copyright (C) 2001 Simon Huggins ##
+## ##
+## #define enhancements by Armin Kuster <akuster@mvista.com> ##
+## Copyright (c) 2000 MontaVista Software, Inc. ##
+## ##
+## This software falls under the GNU General Public License. ##
+## Please read the COPYING file for more information ##
+
+# w.o. 03-11-2000: added the '-filelist' option.
+
+# 18/01/2001 - Cleanups
+# Functions prototyped as foo(void) same as foo()
+# Stop eval'ing where we don't need to.
+# -- huggie@earth.li
+
+# 27/06/2001 - Allowed whitespace after initial "/**" and
+# allowed comments before function declarations.
+# -- Christian Kreibich <ck@whoop.org>
+
+# Still to do:
+# - add perldoc documentation
+# - Look more closely at some of the scarier bits :)
+
+# 26/05/2001 - Support for separate source and object trees.
+# Return error code.
+# Keith Owens <kaos@ocs.com.au>
+
+# 23/09/2001 - Added support for typedefs, structs, enums and unions
+# Support for Context section; can be terminated using empty line
+# Small fixes (like spaces vs. \s in regex)
+# -- Tim Jansen <tim@tjansen.de>
+
+
+#
+# This will read a 'c' file and scan for embedded comments in the
+# style of gnome comments (+minor extensions - see below).
+#
+
+# Note: This only supports 'c'.
+
+# usage:
+# kerneldoc [ -docbook | -html | -text | -man ]
+# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
+# or
+# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
+#
+# Set output format using one of -docbook -html -text or -man. Default is man.
+#
+# -function funcname
+# If set, then only generate documentation for the given function(s). All
+# other functions are ignored.
+#
+# -nofunction funcname
+# If set, then only generate documentation for the other function(s). All
+# other functions are ignored. Cannot be used with -function together
+# (yes thats a bug - perl hackers can fix it 8))
+#
+# c files - list of 'c' files to process
+#
+# All output goes to stdout, with errors to stderr.
+
+#
+# format of comments.
+# In the following table, (...)? signifies optional structure.
+# (...)* signifies 0 or more structure elements
+# /**
+# * function_name(:)? (- short description)?
+# (* @parameterx: (description of parameter x)?)*
+# (* a blank line)?
+# * (Description:)? (Description of function)?
+# * (section header: (section description)? )*
+# (*)?*/
+#
+# So .. the trivial example would be:
+#
+# /**
+# * my_function
+# **/
+#
+# If the Description: header tag is ommitted, then there must be a blank line
+# after the last parameter specification.
+# e.g.
+# /**
+# * my_function - does my stuff
+# * @my_arg: its mine damnit
+# *
+# * Does my stuff explained.
+# */
+#
+# or, could also use:
+# /**
+# * my_function - does my stuff
+# * @my_arg: its mine damnit
+# * Description: Does my stuff explained.
+# */
+# etc.
+#
+# Beside functions you can also write documentation for structs, unions,
+# enums and typedefs. Instead of the function name you must write the name
+# of the declaration; the struct/union/enum/typedef must always precede
+# the name. Nesting of declarations is not supported.
+# Use the argument mechanism to document members or constants.
+# e.g.
+# /**
+# * struct my_struct - short description
+# * @a: first member
+# * @b: second member
+# *
+# * Longer description
+# */
+# struct my_struct {
+# int a;
+# int b;
+# };
+#
+# All descriptions can be multiline, except the short function description.
+#
+# You can also add additional sections. When documenting kernel functions you
+# should document the "Context:" of the function, e.g. whether the functions
+# can be called form interrupts. Unlike other sections you can end it with an
+# empty line.
+# Example-sections should contain the string EXAMPLE so that they are marked
+# appropriately in DocBook.
+#
+# Example:
+# /**
+# * user_function - function that can only be called in user context
+# * @a: some argument
+# * Context: !in_interrupt()
+# *
+# * Some description
+# * Example:
+# * user_function(22);
+# */
+# ...
+#
+#
+# All descriptive text is further processed, scanning for the following special
+# patterns, which are highlighted appropriately.
+#
+# 'funcname()' - function
+# '$ENVVAR' - environmental variable
+# '&struct_name' - name of a structure (up to two words including 'struct')
+# '@parameter' - name of a parameter
+# '%CONST' - name of a constant.
+
+my $errors = 0;
+my $warnings = 0;
+
+# match expressions used to find embedded type information
+my $type_constant = '\%([-_\w]+)';
+my $type_func = '(\w+)\(\)';
+my $type_param = '\@(\w+)';
+my $type_struct = '\&((struct\s*)?[_\w]+)';
+my $type_env = '(\$\w+)';
+
+# Output conversion substitutions.
+# One for each output format
+
+# these work fairly well
+my %highlights_html = ( $type_constant, "<i>\$1</i>",
+ $type_func, "<b>\$1</b>",
+ $type_struct, "<i>\$1</i>",
+ $type_param, "<tt><b>\$1</b></tt>" );
+my $blankline_html = "<p>";
+
+# XML, docbook format
+my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
+ $type_constant, "<constant>\$1</constant>",
+ $type_func, "<function>\$1</function>",
+ $type_struct, "<structname>\$1</structname>",
+ $type_env, "<envar>\$1</envar>",
+ $type_param, "<parameter>\$1</parameter>" );
+my $blankline_xml = "</para><para>\n";
+
+# gnome, docbook format
+my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
+ $type_func, "<function>\$1</function>",
+ $type_struct, "<structname>\$1</structname>",
+ $type_env, "<envar>\$1</envar>",
+ $type_param, "<parameter>\$1</parameter>" );
+my $blankline_gnome = "</para><para>\n";
+
+# these are pretty rough
+my %highlights_man = ( $type_constant, "\$1",
+ $type_func, "\\\\fB\$1\\\\fP",
+ $type_struct, "\\\\fI\$1\\\\fP",
+ $type_param, "\\\\fI\$1\\\\fP" );
+my $blankline_man = "";
+
+# text-mode
+my %highlights_text = ( $type_constant, "\$1",
+ $type_func, "\$1",
+ $type_struct, "\$1",
+ $type_param, "\$1" );
+my $blankline_text = "";
+
+
+sub usage {
+ print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
+ print " [ -function funcname [ -function funcname ...] ]\n";
+ print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
+ print " c source file(s) > outputfile\n";
+ exit 1;
+}
+
+# read arguments
+if ($#ARGV==-1) {
+ usage();
+}
+
+my $verbose = 0;
+my $output_mode = "man";
+my %highlights = %highlights_man;
+my $blankline = $blankline_man;
+my $modulename = "Kernel API";
+my $function_only = 0;
+my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
+ 'July', 'August', 'September', 'October',
+ 'November', 'December')[(localtime)[4]] .
+ " " . ((localtime)[5]+1900);
+
+# Essentially these are globals
+# They probably want to be tidied up made more localised or summat.
+# CAVEAT EMPTOR! Some of the others I localised may not want to be which
+# could cause "use of undefined value" or other bugs.
+my ($function, %function_table,%parametertypes,$declaration_purpose);
+my ($type,$declaration_name,$return_type);
+my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
+
+# Generated docbook code is inserted in a template at a point where
+# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
+# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
+# We keep track of number of generated entries and generate a dummy
+# if needs be to ensure the expanded template can be postprocessed
+# into html.
+my $section_counter = 0;
+
+my $lineprefix="";
+
+# states
+# 0 - normal code
+# 1 - looking for function name
+# 2 - scanning field start.
+# 3 - scanning prototype.
+# 4 - documentation block
+my $state;
+
+#declaration types: can be
+# 'function', 'struct', 'union', 'enum', 'typedef'
+my $decl_type;
+
+my $doc_special = "\@\%\$\&";
+
+my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
+my $doc_end = '\*/';
+my $doc_com = '\s*\*\s*';
+my $doc_decl = $doc_com.'(\w+)';
+my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
+my $doc_content = $doc_com.'(.*)';
+my $doc_block = $doc_com.'DOC:\s*(.*)?';
+
+my %constants;
+my %parameterdescs;
+my @parameterlist;
+my %sections;
+my @sectionlist;
+
+my $contents = "";
+my $section_default = "Description"; # default section
+my $section_intro = "Introduction";
+my $section = $section_default;
+my $section_context = "Context";
+
+my $undescribed = "-- undescribed --";
+
+reset_state();
+
+while ($ARGV[0] =~ m/^-(.*)/) {
+ my $cmd = shift @ARGV;
+ if ($cmd eq "-html") {
+ $output_mode = "html";
+ %highlights = %highlights_html;
+ $blankline = $blankline_html;
+ } elsif ($cmd eq "-man") {
+ $output_mode = "man";
+ %highlights = %highlights_man;
+ $blankline = $blankline_man;
+ } elsif ($cmd eq "-text") {
+ $output_mode = "text";
+ %highlights = %highlights_text;
+ $blankline = $blankline_text;
+ } elsif ($cmd eq "-docbook") {
+ $output_mode = "xml";
+ %highlights = %highlights_xml;
+ $blankline = $blankline_xml;
+ } elsif ($cmd eq "-gnome") {
+ $output_mode = "gnome";
+ %highlights = %highlights_gnome;
+ $blankline = $blankline_gnome;
+ } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
+ $modulename = shift @ARGV;
+ } elsif ($cmd eq "-function") { # to only output specific functions
+ $function_only = 1;
+ $function = shift @ARGV;
+ $function_table{$function} = 1;
+ } elsif ($cmd eq "-nofunction") { # to only output specific functions
+ $function_only = 2;
+ $function = shift @ARGV;
+ $function_table{$function} = 1;
+ } elsif ($cmd eq "-v") {
+ $verbose = 1;
+ } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
+ usage();
+ } elsif ($cmd eq '-filelist') {
+ $filelist = shift @ARGV;
+ }
+}
+
+
+# generate a sequence of code that will splice in highlighting information
+# using the s// operator.
+my $dohighlight = "";
+foreach my $pattern (keys %highlights) {
+# print "scanning pattern $pattern ($highlights{$pattern})\n";
+ $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
+}
+
+##
+# dumps section contents to arrays/hashes intended for that purpose.
+#
+sub dump_section {
+ my $name = shift;
+ my $contents = join "\n", @_;
+
+ if ($name =~ m/$type_constant/) {
+ $name = $1;
+# print STDERR "constant section '$1' = '$contents'\n";
+ $constants{$name} = $contents;
+ } elsif ($name =~ m/$type_param/) {
+# print STDERR "parameter def '$1' = '$contents'\n";
+ $name = $1;
+ $parameterdescs{$name} = $contents;
+ } else {
+# print STDERR "other section '$name' = '$contents'\n";
+ $sections{$name} = $contents;
+ push @sectionlist, $name;
+ }
+}
+
+##
+# output function
+#
+# parameterdescs, a hash.
+# function => "function name"
+# parameterlist => @list of parameters
+# parameterdescs => %parameter descriptions
+# sectionlist => @list of sections
+# sections => %descriont descriptions
+#
+
+sub output_highlight {
+ my $contents = join "\n",@_;
+ my $line;
+
+# DEBUG
+# if (!defined $contents) {
+# use Carp;
+# confess "output_highlight got called with no args?\n";
+# }
+
+ eval $dohighlight;
+ die $@ if $@;
+ foreach $line (split "\n", $contents) {
+ if ($line eq ""){
+ print $lineprefix, $blankline;
+ } else {
+ $line =~ s/\\\\\\/\&/g;
+ print $lineprefix, $line;
+ }
+ print "\n";
+ }
+}
+
+#output sections in html
+sub output_section_html(%) {
+ my %args = %{$_[0]};
+ my $section;
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<h3>$section</h3>\n";
+ print "<blockquote>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</blockquote>\n";
+ }
+}
+
+# output enum in html
+sub output_enum_html(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $count;
+ print "<h2>enum ".$args{'enum'}."</h2>\n";
+
+ print "<b>enum ".$args{'enum'}."</b> {<br>\n";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " <b>".$parameter."</b>";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",\n";
+ }
+ print "<br>";
+ }
+ print "};<br>\n";
+
+ print "<h3>Constants</h3>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<dt><b>".$parameter."</b>\n";
+ print "<dd>";
+ output_highlight($args{'parameterdescs'}{$parameter});
+ }
+ print "</dl>\n";
+ output_section_html(@_);
+ print "<hr>\n";
+}
+
+# output tyepdef in html
+sub output_typedef_html(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $count;
+ print "<h2>typedef ".$args{'typedef'}."</h2>\n";
+
+ print "<b>typedef ".$args{'typedef'}."</b>\n";
+ output_section_html(@_);
+ print "<hr>\n";
+}
+
+# output struct in html
+sub output_struct_html(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+
+ print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n";
+ print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ if ($parameter =~ /^#/) {
+ print "$parameter<br>\n";
+ next;
+ }
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
+ } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+ print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
+ } else {
+ print " <i>$type</i> <b>$parameter</b>;<br>\n";
+ }
+ }
+ print "};<br>\n";
+
+ print "<h3>Members</h3>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ ($parameter =~ /^#/) && next;
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print "<dt><b>".$parameter."</b>\n";
+ print "<dd>";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ }
+ print "</dl>\n";
+ output_section_html(@_);
+ print "<hr>\n";
+}
+
+# output function in html
+sub output_function_html(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ print "<h2>Function</h2>\n";
+
+ print "<i>".$args{'functiontype'}."</i>\n";
+ print "<b>".$args{'function'}."</b>\n";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
+ } else {
+ print "<i>".$type."</i> <b>".$parameter."</b>";
+ }
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",\n";
+ }
+ }
+ print ")\n";
+
+ print "<h3>Arguments</h3>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print "<dt><b>".$parameter."</b>\n";
+ print "<dd>";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ }
+ print "</dl>\n";
+ output_section_html(@_);
+ print "<hr>\n";
+}
+
+# output intro in html
+sub output_intro_html(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<h3>$section</h3>\n";
+ print "<ul>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</ul>\n";
+ }
+ print "<hr>\n";
+}
+
+sub output_section_xml(%) {
+ my %args = %{$_[0]};
+ my $section;
+ # print out each section
+ $lineprefix=" ";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<refsect1>\n <title>$section</title>\n <para>\n";
+ if ($section =~ m/EXAMPLE/i) {
+ print "<example><para>\n";
+ }
+ output_highlight($args{'sections'}{$section});
+ if ($section =~ m/EXAMPLE/i) {
+ print "</para></example>\n";
+ }
+ print " </para>\n</refsect1>\n";
+ }
+}
+
+# output function in XML DocBook
+sub output_function_xml(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $id;
+
+ $id = "API-".$args{'function'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<refentry>\n";
+ print "<refmeta>\n";
+ print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
+ print "</refmeta>\n";
+ print "<refnamediv>\n";
+ print " <refname>".$args{'function'}."</refname>\n";
+ print " <refpurpose>\n";
+ print " ";
+ output_highlight ($args{'purpose'});
+ print " </refpurpose>\n";
+ print "</refnamediv>\n";
+
+ print "<refsynopsisdiv>\n";
+ print " <title>Synopsis</title>\n";
+ print " <funcsynopsis><funcprototype>\n";
+ print " <funcdef>".$args{'functiontype'}." ";
+ print "<function>".$args{'function'}." </function></funcdef>\n";
+
+ $count = 0;
+ if ($#{$args{'parameterlist'}} >= 0) {
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print " <paramdef>$1<parameter>$parameter</parameter>)\n";
+ print " <funcparams>$2</funcparams></paramdef>\n";
+ } else {
+ print " <paramdef>".$type;
+ print " <parameter>$parameter</parameter></paramdef>\n";
+ }
+ }
+ } else {
+ print " <void>\n";
+ }
+ print " </funcprototype></funcsynopsis>\n";
+ print "</refsynopsisdiv>\n";
+
+ # print parameters
+ print "<refsect1>\n <title>Arguments</title>\n";
+ if ($#{$args{'parameterlist'}} >= 0) {
+ print " <variablelist>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n";
+ print " <listitem>\n <para>\n";
+ $lineprefix=" ";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ print " </para>\n </listitem>\n </varlistentry>\n";
+ }
+ print " </variablelist>\n";
+ } else {
+ print " <para>\n None\n </para>\n";
+ }
+ print "</refsect1>\n";
+
+ output_section_xml(@_);
+ print "</refentry>\n\n";
+}
+
+# output struct in XML DocBook
+sub output_struct_xml(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $id;
+
+ $id = "API-struct-".$args{'struct'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<refentry>\n";
+ print "<refmeta>\n";
+ print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
+ print "</refmeta>\n";
+ print "<refnamediv>\n";
+ print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
+ print " <refpurpose>\n";
+ print " ";
+ output_highlight ($args{'purpose'});
+ print " </refpurpose>\n";
+ print "</refnamediv>\n";
+
+ print "<refsynopsisdiv>\n";
+ print " <title>Synopsis</title>\n";
+ print " <programlisting>\n";
+ print $args{'type'}." ".$args{'struct'}." {\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ if ($parameter =~ /^#/) {
+ print "$parameter\n";
+ next;
+ }
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ defined($args{'parameterdescs'}{$parameter_name}) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print " $1 $parameter) ($2);\n";
+ } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+ print " $1 $parameter$2;\n";
+ } else {
+ print " ".$type." ".$parameter.";\n";
+ }
+ }
+ print "};";
+ print " </programlisting>\n";
+ print "</refsynopsisdiv>\n";
+
+ print " <refsect1>\n";
+ print " <title>Members</title>\n";
+
+ print " <variablelist>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ ($parameter =~ /^#/) && next;
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ defined($args{'parameterdescs'}{$parameter_name}) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print " <varlistentry>";
+ print " <term>$parameter</term>\n";
+ print " <listitem><para>\n";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ print " </para></listitem>\n";
+ print " </varlistentry>\n";
+ }
+ print " </variablelist>\n";
+ print " </refsect1>\n";
+
+ output_section_xml(@_);
+
+ print "</refentry>\n\n";
+}
+
+# output enum in XML DocBook
+sub output_enum_xml(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $id;
+
+ $id = "API-enum-".$args{'enum'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<refentry>\n";
+ print "<refmeta>\n";
+ print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n";
+ print "</refmeta>\n";
+ print "<refnamediv>\n";
+ print " <refname>enum ".$args{'enum'}."</refname>\n";
+ print " <refpurpose>\n";
+ print " ";
+ output_highlight ($args{'purpose'});
+ print " </refpurpose>\n";
+ print "</refnamediv>\n";
+
+ print "<refsynopsisdiv>\n";
+ print " <title>Synopsis</title>\n";
+ print " <programlisting>\n";
+ print "enum ".$args{'enum'}." {\n";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " $parameter";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",";
+ }
+ print "\n";
+ }
+ print "};";
+ print " </programlisting>\n";
+ print "</refsynopsisdiv>\n";
+
+ print "<refsect1>\n";
+ print " <title>Constants</title>\n";
+ print " <variablelist>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ print " <varlistentry>";
+ print " <term>$parameter</term>\n";
+ print " <listitem><para>\n";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ print " </para></listitem>\n";
+ print " </varlistentry>\n";
+ }
+ print " </variablelist>\n";
+ print "</refsect1>\n";
+
+ output_section_xml(@_);
+
+ print "</refentry>\n\n";
+}
+
+# output typedef in XML DocBook
+sub output_typedef_xml(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $id;
+
+ $id = "API-typedef-".$args{'typedef'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<refentry>\n";
+ print "<refmeta>\n";
+ print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n";
+ print "</refmeta>\n";
+ print "<refnamediv>\n";
+ print " <refname>typedef ".$args{'typedef'}."</refname>\n";
+ print " <refpurpose>\n";
+ print " ";
+ output_highlight ($args{'purpose'});
+ print " </refpurpose>\n";
+ print "</refnamediv>\n";
+
+ print "<refsynopsisdiv>\n";
+ print " <title>Synopsis</title>\n";
+ print " <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n";
+ print "</refsynopsisdiv>\n";
+
+ output_section_xml(@_);
+
+ print "</refentry>\n\n";
+}
+
+# output in XML DocBook
+sub output_intro_xml(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ my $id = $args{'module'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ # print out each section
+ $lineprefix=" ";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<refsect1>\n <title>$section</title>\n <para>\n";
+ if ($section =~ m/EXAMPLE/i) {
+ print "<example><para>\n";
+ }
+ output_highlight($args{'sections'}{$section});
+ if ($section =~ m/EXAMPLE/i) {
+ print "</para></example>\n";
+ }
+ print " </para>\n</refsect1>\n";
+ }
+
+ print "\n\n";
+}
+
+# output in XML DocBook
+sub output_function_gnome {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $id;
+
+ $id = $args{'module'}."-".$args{'function'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<sect2>\n";
+ print " <title id=\"$id\">".$args{'function'}."</title>\n";
+
+ print " <funcsynopsis>\n";
+ print " <funcdef>".$args{'functiontype'}." ";
+ print "<function>".$args{'function'}." ";
+ print "</function></funcdef>\n";
+
+ $count = 0;
+ if ($#{$args{'parameterlist'}} >= 0) {
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print " <paramdef>$1 <parameter>$parameter</parameter>)\n";
+ print " <funcparams>$2</funcparams></paramdef>\n";
+ } else {
+ print " <paramdef>".$type;
+ print " <parameter>$parameter</parameter></paramdef>\n";
+ }
+ }
+ } else {
+ print " <void>\n";
+ }
+ print " </funcsynopsis>\n";
+ if ($#{$args{'parameterlist'}} >= 0) {
+ print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
+ print "<tgroup cols=\"2\">\n";
+ print "<colspec colwidth=\"2*\">\n";
+ print "<colspec colwidth=\"8*\">\n";
+ print "<tbody>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
+ print " <entry>\n";
+ $lineprefix=" ";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ print " </entry></row>\n";
+ }
+ print " </tbody></tgroup></informaltable>\n";
+ } else {
+ print " <para>\n None\n </para>\n";
+ }
+
+ # print out each section
+ $lineprefix=" ";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<simplesect>\n <title>$section</title>\n";
+ if ($section =~ m/EXAMPLE/i) {
+ print "<example><programlisting>\n";
+ } else {
+ }
+ print "<para>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</para>\n";
+ if ($section =~ m/EXAMPLE/i) {
+ print "</programlisting></example>\n";
+ } else {
+ }
+ print " </simplesect>\n";
+ }
+
+ print "</sect2>\n\n";
+}
+
+##
+# output function in man
+sub output_function_man(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
+
+ print ".SH NAME\n";
+ print $args{'function'}." \\- ".$args{'purpose'}."\n";
+
+ print ".SH SYNOPSIS\n";
+ print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n";
+ $count = 0;
+ my $parenth = "(";
+ my $post = ",";
+ foreach my $parameter (@{$args{'parameterlist'}}) {
+ if ($count == $#{$args{'parameterlist'}}) {
+ $post = ");";
+ }
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n";
+ } else {
+ $type =~ s/([^\*])$/$1 /;
+ print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n";
+ }
+ $count++;
+ $parenth = "";
+ }
+
+ print ".SH ARGUMENTS\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ print ".IP \"".$parameter."\" 12\n";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"", uc $section, "\"\n";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# output enum in man
+sub output_enum_man(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
+
+ print ".SH NAME\n";
+ print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
+
+ print ".SH SYNOPSIS\n";
+ print "enum ".$args{'enum'}." {\n";
+ $count = 0;
+ foreach my $parameter (@{$args{'parameterlist'}}) {
+ print ".br\n.BI \" $parameter\"\n";
+ if ($count == $#{$args{'parameterlist'}}) {
+ print "\n};\n";
+ last;
+ }
+ else {
+ print ", \n.br\n";
+ }
+ $count++;
+ }
+
+ print ".SH Constants\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ print ".IP \"".$parameter."\" 12\n";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"$section\"\n";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# output struct in man
+sub output_struct_man(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+
+ print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
+
+ print ".SH NAME\n";
+ print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
+
+ print ".SH SYNOPSIS\n";
+ print $args{'type'}." ".$args{'struct'}." {\n.br\n";
+
+ foreach my $parameter (@{$args{'parameterlist'}}) {
+ if ($parameter =~ /^#/) {
+ print ".BI \"$parameter\"\n.br\n";
+ next;
+ }
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print ".BI \" ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
+ } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+ print ".BI \" ".$1."\" ".$parameter.$2." \""."\"\n;\n";
+ } else {
+ $type =~ s/([^\*])$/$1 /;
+ print ".BI \" ".$type."\" ".$parameter." \""."\"\n;\n";
+ }
+ print "\n.br\n";
+ }
+ print "};\n.br\n";
+
+ print ".SH Arguments\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ ($parameter =~ /^#/) && next;
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print ".IP \"".$parameter."\" 12\n";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"$section\"\n";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# output typedef in man
+sub output_typedef_man(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+
+ print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
+
+ print ".SH NAME\n";
+ print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"$section\"\n";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+sub output_intro_man(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"$section\"\n";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# output in text
+sub output_function_text(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+
+ print "Function:\n\n";
+ my $start=$args{'functiontype'}." ".$args{'function'}." (";
+ print $start;
+ my $count = 0;
+ foreach my $parameter (@{$args{'parameterlist'}}) {
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print $1.$parameter.") (".$2;
+ } else {
+ print $type." ".$parameter;
+ }
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",\n";
+ print " " x length($start);
+ } else {
+ print ");\n\n";
+ }
+ }
+
+ print "Arguments:\n\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ print $parameter."\n\t".$args{'parameterdescs'}{$parameter_name}."\n";
+ }
+ output_section_text(@_);
+}
+
+#output sections in text
+sub output_section_text(%) {
+ my %args = %{$_[0]};
+ my $section;
+
+ print "\n";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "$section:\n\n";
+ output_highlight($args{'sections'}{$section});
+ }
+ print "\n\n";
+}
+
+# output enum in text
+sub output_enum_text(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $count;
+ print "Enum:\n\n";
+
+ print "enum ".$args{'enum'}." {\n";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "\t$parameter";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",";
+ }
+ print "\n";
+ }
+ print "};\n\n";
+
+ print "Constants:\n\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "$parameter\n\t";
+ print $args{'parameterdescs'}{$parameter}."\n";
+ }
+
+ output_section_text(@_);
+}
+
+# output typedef in text
+sub output_typedef_text(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $count;
+ print "Typedef:\n\n";
+
+ print "typedef ".$args{'typedef'}."\n";
+ output_section_text(@_);
+}
+
+# output struct as text
+sub output_struct_text(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+
+ print $args{'type'}." ".$args{'struct'}.":\n\n";
+ print $args{'type'}." ".$args{'struct'}." {\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ if ($parameter =~ /^#/) {
+ print "$parameter\n";
+ next;
+ }
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print "\t$1 $parameter) ($2);\n";
+ } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+ print "\t$1 $parameter$2;\n";
+ } else {
+ print "\t".$type." ".$parameter.";\n";
+ }
+ }
+ print "};\n\n";
+
+ print "Members:\n\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ ($parameter =~ /^#/) && next;
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print "$parameter\n\t";
+ print $args{'parameterdescs'}{$parameter_name}."\n";
+ }
+ print "\n";
+ output_section_text(@_);
+}
+
+sub output_intro_text(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ print " $section:\n";
+ print " -> ";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# generic output function for typedefs
+sub output_declaration {
+ no strict 'refs';
+ my $name = shift;
+ my $functype = shift;
+ my $func = "output_${functype}_$output_mode";
+ if (($function_only==0) ||
+ ( $function_only == 1 && defined($function_table{$name})) ||
+ ( $function_only == 2 && !defined($function_table{$name})))
+ {
+ &$func(@_);
+ $section_counter++;
+ }
+}
+
+##
+# generic output function - calls the right one based
+# on current output mode.
+sub output_intro {
+ no strict 'refs';
+ my $func = "output_intro_".$output_mode;
+ &$func(@_);
+ $section_counter++;
+}
+
+##
+# takes a declaration (struct, union, enum, typedef) and
+# invokes the right handler. NOT called for functions.
+sub dump_declaration($$) {
+ no strict 'refs';
+ my ($prototype, $file) = @_;
+ my $func = "dump_".$decl_type;
+ &$func(@_);
+}
+
+sub dump_union($$) {
+ dump_struct(@_);
+}
+
+sub dump_struct($$) {
+ my $x = shift;
+ my $file = shift;
+
+ if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
+ $declaration_name = $2;
+ my $members = $3;
+
+ # ignore embedded structs or unions
+ $members =~ s/{.*?}//g;
+
+ create_parameterlist($members, ';', $file);
+
+ output_declaration($declaration_name,
+ 'struct',
+ {'struct' => $declaration_name,
+ 'module' => $modulename,
+ 'parameterlist' => \@parameterlist,
+ 'parameterdescs' => \%parameterdescs,
+ 'parametertypes' => \%parametertypes,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $declaration_purpose,
+ 'type' => $decl_type
+ });
+ }
+ else {
+ print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
+ ++$errors;
+ }
+}
+
+sub dump_enum($$) {
+ my $x = shift;
+ my $file = shift;
+
+ if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
+ $declaration_name = $1;
+ my $members = $2;
+
+ foreach my $arg (split ',', $members) {
+ $arg =~ s/^\s*(\w+).*/$1/;
+ push @parameterlist, $arg;
+ if (!$parameterdescs{$arg}) {
+ $parameterdescs{$arg} = $undescribed;
+ print STDERR "Warning(${file}:$.): Enum value '$arg' ".
+ "not described in enum '$declaration_name'\n";
+ }
+
+ }
+
+ output_declaration($declaration_name,
+ 'enum',
+ {'enum' => $declaration_name,
+ 'module' => $modulename,
+ 'parameterlist' => \@parameterlist,
+ 'parameterdescs' => \%parameterdescs,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $declaration_purpose
+ });
+ }
+ else {
+ print STDERR "Error(${file}:$.): Cannot parse enum!\n";
+ ++$errors;
+ }
+}
+
+sub dump_typedef($$) {
+ my $x = shift;
+ my $file = shift;
+
+ while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
+ $x =~ s/\(*.\)\s*;$/;/;
+ $x =~ s/\[*.\]\s*;$/;/;
+ }
+
+ if ($x =~ /typedef.*\s+(\w+)\s*;/) {
+ $declaration_name = $1;
+
+ output_declaration($declaration_name,
+ 'typedef',
+ {'typedef' => $declaration_name,
+ 'module' => $modulename,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $declaration_purpose
+ });
+ }
+ else {
+ print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
+ ++$errors;
+ }
+}
+
+sub create_parameterlist($$$) {
+ my $args = shift;
+ my $splitter = shift;
+ my $file = shift;
+ my $type;
+ my $param;
+
+ while ($args =~ /(\([^\),]+),/) {
+ $args =~ s/(\([^\),]+),/$1#/g;
+ }
+
+ foreach my $arg (split($splitter, $args)) {
+ # strip comments
+ $arg =~ s/\/\*.*\*\///;
+ # strip leading/trailing spaces
+ $arg =~ s/^\s*//;
+ $arg =~ s/\s*$//;
+ $arg =~ s/\s+/ /;
+
+ if ($arg =~ /^#/) {
+ # Treat preprocessor directive as a typeless variable just to fill
+ # corresponding data structures "correctly". Catch it later in
+ # output_* subs.
+ push_parameter($arg, "", $file);
+ } elsif ($arg =~ m/\(/) {
+ # pointer-to-function
+ $arg =~ tr/#/,/;
+ $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
+ $param = $1;
+ $type = $arg;
+ $type =~ s/([^\(]+\(\*)$param/$1/;
+ push_parameter($param, $type, $file);
+ } else {
+ $arg =~ s/\s*:\s*/:/g;
+ $arg =~ s/\s*\[/\[/g;
+
+ my @args = split('\s*,\s*', $arg);
+ if ($args[0] =~ m/\*/) {
+ $args[0] =~ s/(\*+)\s*/ $1/;
+ }
+ my @first_arg = split('\s+', shift @args);
+ unshift(@args, pop @first_arg);
+ $type = join " ", @first_arg;
+
+ foreach $param (@args) {
+ if ($param =~ m/^(\*+)\s*(.*)/) {
+ push_parameter($2, "$type $1", $file);
+ }
+ elsif ($param =~ m/(.*?):(\d+)/) {
+ push_parameter($1, "$type:$2", $file)
+ }
+ else {
+ push_parameter($param, $type, $file);
+ }
+ }
+ }
+ }
+}
+
+sub push_parameter($$$) {
+ my $param = shift;
+ my $type = shift;
+ my $file = shift;
+
+ my $param_name = $param;
+ $param_name =~ s/\[.*//;
+
+ if ($type eq "" && $param eq "...")
+ {
+ $type="";
+ $param="...";
+ $parameterdescs{"..."} = "variable arguments";
+ }
+ elsif ($type eq "" && ($param eq "" or $param eq "void"))
+ {
+ $type="";
+ $param="void";
+ $parameterdescs{void} = "no arguments";
+ }
+ if (defined $type && $type && !defined $parameterdescs{$param_name}) {
+ $parameterdescs{$param_name} = $undescribed;
+
+ if (($type eq 'function') || ($type eq 'enum')) {
+ print STDERR "Warning(${file}:$.): Function parameter ".
+ "or member '$param' not " .
+ "described in '$declaration_name'\n";
+ }
+ print STDERR "Warning(${file}:$.):".
+ " No description found for parameter '$param'\n";
+ ++$warnings;
+ }
+
+ push @parameterlist, $param;
+ $parametertypes{$param} = $type;
+}
+
+##
+# takes a function prototype and the name of the current file being
+# processed and spits out all the details stored in the global
+# arrays/hashes.
+sub dump_function($$) {
+ my $prototype = shift;
+ my $file = shift;
+
+ $prototype =~ s/^static +//;
+ $prototype =~ s/^extern +//;
+ $prototype =~ s/^inline +//;
+ $prototype =~ s/^__inline__ +//;
+ $prototype =~ s/^#define +//; #ak added
+ $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
+
+ # Yes, this truly is vile. We are looking for:
+ # 1. Return type (may be nothing if we're looking at a macro)
+ # 2. Function name
+ # 3. Function parameters.
+ #
+ # All the while we have to watch out for function pointer parameters
+ # (which IIRC is what the two sections are for), C types (these
+ # regexps don't even start to express all the possibilities), and
+ # so on.
+ #
+ # If you mess with these regexps, it's a good idea to check that
+ # the following functions' documentation still comes out right:
+ # - parport_register_device (function pointer parameters)
+ # - atomic_set (macro)
+ # - pci_match_device (long return type)
+
+ if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
+ $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) {
+ $return_type = $1;
+ $declaration_name = $2;
+ my $args = $3;
+
+ create_parameterlist($args, ',', $file);
+ } else {
+ print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
+ ++$errors;
+ return;
+ }
+
+ output_declaration($declaration_name,
+ 'function',
+ {'function' => $declaration_name,
+ 'module' => $modulename,
+ 'functiontype' => $return_type,
+ 'parameterlist' => \@parameterlist,
+ 'parameterdescs' => \%parameterdescs,
+ 'parametertypes' => \%parametertypes,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $declaration_purpose
+ });
+}
+
+sub process_file($);
+
+# Read the file that maps relative names to absolute names for
+# separate source and object directories and for shadow trees.
+if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
+ my ($relname, $absname);
+ while(<SOURCE_MAP>) {
+ chop();
+ ($relname, $absname) = (split())[0..1];
+ $relname =~ s:^/+::;
+ $source_map{$relname} = $absname;
+ }
+ close(SOURCE_MAP);
+}
+
+if ($filelist) {
+ open(FLIST,"<$filelist") or die "Can't open file list $filelist";
+ while(<FLIST>) {
+ chop;
+ process_file($_);
+ }
+}
+
+foreach (@ARGV) {
+ chomp;
+ process_file($_);
+}
+if ($verbose && $errors) {
+ print STDERR "$errors errors\n";
+}
+if ($verbose && $warnings) {
+ print STDERR "$warnings warnings\n";
+}
+
+exit($errors);
+
+sub reset_state {
+ $function = "";
+ %constants = ();
+ %parameterdescs = ();
+ %parametertypes = ();
+ @parameterlist = ();
+ %sections = ();
+ @sectionlist = ();
+ $prototype = "";
+
+ $state = 0;
+}
+
+sub process_state3_function($$) {
+ my $x = shift;
+ my $file = shift;
+
+ if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) {
+ # do nothing
+ }
+ elsif ($x =~ /([^\{]*)/) {
+ $prototype .= $1;
+ }
+ if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
+ $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
+ $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
+ $prototype =~ s@^\s+@@gos; # strip leading spaces
+ dump_function($prototype,$file);
+ reset_state();
+ }
+}
+
+sub process_state3_type($$) {
+ my $x = shift;
+ my $file = shift;
+
+ $x =~ s@/\*.*?\*/@@gos; # strip comments.
+ $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
+ $x =~ s@^\s+@@gos; # strip leading spaces
+ $x =~ s@\s+$@@gos; # strip trailing spaces
+ if ($x =~ /^#/) {
+ # To distinguish preprocessor directive from regular declaration later.
+ $x .= ";";
+ }
+
+ while (1) {
+ if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
+ $prototype .= $1 . $2;
+ ($2 eq '{') && $brcount++;
+ ($2 eq '}') && $brcount--;
+ if (($2 eq ';') && ($brcount == 0)) {
+ dump_declaration($prototype,$file);
+ reset_state();
+ last;
+ }
+ $x = $3;
+ } else {
+ $prototype .= $x;
+ last;
+ }
+ }
+}
+
+# replace <, >, and &
+sub xml_escape($) {
+ my $text = shift;
+ $text =~ s/\&/\\\\\\amp;/g;
+ $text =~ s/\</\\\\\\lt;/g;
+ $text =~ s/\>/\\\\\\gt;/g;
+ return $text;
+}
+
+sub process_file($) {
+ my ($file) = "$ENV{'SRCTREE'}@_";
+ my $identifier;
+ my $func;
+ my $initial_section_counter = $section_counter;
+
+ if (defined($source_map{$file})) {
+ $file = $source_map{$file};
+ }
+
+ if (!open(IN,"<$file")) {
+ print STDERR "Error: Cannot open file $file\n";
+ ++$errors;
+ return;
+ }
+
+ $section_counter = 0;
+ while (<IN>) {
+ if ($state == 0) {
+ if (/$doc_start/o) {
+ $state = 1; # next line is always the function name
+ }
+ } elsif ($state == 1) { # this line is the function name (always)
+ if (/$doc_block/o) {
+ $state = 4;
+ $contents = "";
+ if ( $1 eq "" ) {
+ $section = $section_intro;
+ } else {
+ $section = $1;
+ }
+ }
+ elsif (/$doc_decl/o) {
+ $identifier = $1;
+ if (/\s*([\w\s]+?)\s*-/) {
+ $identifier = $1;
+ }
+
+ $state = 2;
+ if (/-(.*)/) {
+ $declaration_purpose = xml_escape($1);
+ } else {
+ $declaration_purpose = "";
+ }
+ if ($identifier =~ m/^struct/) {
+ $decl_type = 'struct';
+ } elsif ($identifier =~ m/^union/) {
+ $decl_type = 'union';
+ } elsif ($identifier =~ m/^enum/) {
+ $decl_type = 'enum';
+ } elsif ($identifier =~ m/^typedef/) {
+ $decl_type = 'typedef';
+ } else {
+ $decl_type = 'function';
+ }
+
+ if ($verbose) {
+ print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
+ }
+ } else {
+ print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
+ " - I thought it was a doc line\n";
+ ++$warnings;
+ $state = 0;
+ }
+ } elsif ($state == 2) { # look for head: lines, and include content
+ if (/$doc_sect/o) {
+ $newsection = $1;
+ $newcontents = $2;
+
+ if ($contents ne "") {
+ dump_section($section, xml_escape($contents));
+ $section = $section_default;
+ }
+
+ $contents = $newcontents;
+ if ($contents ne "") {
+ $contents .= "\n";
+ }
+ $section = $newsection;
+ } elsif (/$doc_end/) {
+
+ if ($contents ne "") {
+ dump_section($section, xml_escape($contents));
+ $section = $section_default;
+ $contents = "";
+ }
+
+ $prototype = "";
+ $state = 3;
+ $brcount = 0;
+# print STDERR "end of doc comment, looking for prototype\n";
+ } elsif (/$doc_content/) {
+ # miguel-style comment kludge, look for blank lines after
+ # @parameter line to signify start of description
+ if ($1 eq "" &&
+ ($section =~ m/^@/ || $section eq $section_context)) {
+ dump_section($section, xml_escape($contents));
+ $section = $section_default;
+ $contents = "";
+ } else {
+ $contents .= $1."\n";
+ }
+ } else {
+ # i dont know - bad line? ignore.
+ print STDERR "Warning(${file}:$.): bad line: $_";
+ ++$warnings;
+ }
+ } elsif ($state == 3) { # scanning for function { (end of prototype)
+ if ($decl_type eq 'function') {
+ process_state3_function($_, $file);
+ } else {
+ process_state3_type($_, $file);
+ }
+ } elsif ($state == 4) {
+ # Documentation block
+ if (/$doc_block/) {
+ dump_section($section, $contents);
+ output_intro({'sectionlist' => \@sectionlist,
+ 'sections' => \%sections });
+ $contents = "";
+ $function = "";
+ %constants = ();
+ %parameterdescs = ();
+ %parametertypes = ();
+ @parameterlist = ();
+ %sections = ();
+ @sectionlist = ();
+ $prototype = "";
+ if ( $1 eq "" ) {
+ $section = $section_intro;
+ } else {
+ $section = $1;
+ }
+ }
+ elsif (/$doc_end/)
+ {
+ dump_section($section, $contents);
+ output_intro({'sectionlist' => \@sectionlist,
+ 'sections' => \%sections });
+ $contents = "";
+ $function = "";
+ %constants = ();
+ %parameterdescs = ();
+ %parametertypes = ();
+ @parameterlist = ();
+ %sections = ();
+ @sectionlist = ();
+ $prototype = "";
+ $state = 0;
+ }
+ elsif (/$doc_content/)
+ {
+ if ( $1 eq "" )
+ {
+ $contents .= $blankline;
+ }
+ else
+ {
+ $contents .= $1 . "\n";
+ }
+ }
+ }
+ }
+ if ($initial_section_counter == $section_counter) {
+ print STDERR "Warning(${file}): no structured comments found\n";
+ if ($output_mode eq "xml") {
+ # The template wants at least one RefEntry here; make one.
+ print "<refentry>\n";
+ print " <refnamediv>\n";
+ print " <refname>\n";
+ print " ${file}\n";
+ print " </refname>\n";
+ print " <refpurpose>\n";
+ print " Document generation inconsistency\n";
+ print " </refpurpose>\n";
+ print " </refnamediv>\n";
+ print " <refsect1>\n";
+ print " <title>\n";
+ print " Oops\n";
+ print " </title>\n";
+ print " <warning>\n";
+ print " <para>\n";
+ print " The template for this document tried to insert\n";
+ print " the structured comment from the file\n";
+ print " <filename>${file}</filename> at this point,\n";
+ print " but none was found.\n";
+ print " This dummy section is inserted to allow\n";
+ print " generation to continue.\n";
+ print " </para>\n";
+ print " </warning>\n";
+ print " </refsect1>\n";
+ print "</refentry>\n";
+ }
+ }
+}
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 @@
+ksymoops has been removed from the kernel. It was always meant to be a
+free standing utility, not linked to any particular kernel version.
+The latest version can be found in
+ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together
+with patches to other utilities in order to give more accurate Oops
+debugging.
+
+Keith 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 @@
+This is NOT the official version of dialog. This version has been
+significantly modified from the original. It is for use by the Linux
+kernel configuration script. Please do not bother Savio Lam with
+questions 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 @@
+HOST_EXTRACFLAGS := -DLOCALE
+ifeq ($(shell uname),SunOS)
+HOST_LOADLIBES := -lcurses
+else
+HOST_LOADLIBES := -lncurses
+endif
+
+ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
+ HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
+else
+ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
+ HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
+else
+ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
+ HOST_EXTRACFLAGS += -DCURSES_LOC="<ncurses.h>"
+else
+ HOST_EXTRACFLAGS += -DCURSES_LOC="<curses.h>"
+endif
+endif
+endif
+
+hostprogs-y := lxdialog
+always := ncurses $(hostprogs-y)
+
+lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
+ util.o lxdialog.o msgbox.o
+
+.PHONY: $(obj)/ncurses
+$(obj)/ncurses:
+ @echo "main() {}" > lxtemp.c
+ @if $(HOSTCC) lxtemp.c $(HOST_LOADLIBES); then \
+ rm -f lxtemp.c a.out; \
+ else \
+ rm -f lxtemp.c; \
+ echo -e "\007" ;\
+ echo ">> Unable to find the Ncurses libraries." ;\
+ echo ">>" ;\
+ echo ">> You must install ncurses-devel in order" ;\
+ echo ">> to use 'make menuconfig'" ;\
+ echo ;\
+ exit 1 ;\
+ 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 @@
+/*
+ * checklist.c -- implements the checklist box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static int list_width, check_x, item_x, checkflag;
+
+/*
+ * Print list item
+ */
+static void
+print_item (WINDOW * win, const char *item, int status,
+ int choice, int selected)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset (win, menubox_attr);
+ wmove (win, choice, 0);
+ for (i = 0; i < list_width; i++)
+ waddch (win, ' ');
+
+ wmove (win, choice, check_x);
+ wattrset (win, selected ? check_selected_attr : check_attr);
+ if (checkflag == FLAG_CHECK)
+ wprintw (win, "[%c]", status ? 'X' : ' ');
+ else
+ wprintw (win, "(%c)", status ? 'X' : ' ');
+
+ wattrset (win, selected ? tag_selected_attr : tag_attr);
+ mvwaddch(win, choice, item_x, item[0]);
+ wattrset (win, selected ? item_selected_attr : item_attr);
+ waddstr (win, (char *)item+1);
+ if (selected) {
+ wmove (win, choice, check_x+1);
+ wrefresh (win);
+ }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void
+print_arrows (WINDOW * win, int choice, int item_no, int scroll,
+ int y, int x, int height)
+{
+ wmove(win, y, x);
+
+ if (scroll > 0) {
+ wattrset (win, uarrow_attr);
+ waddch (win, ACS_UARROW);
+ waddstr (win, "(-)");
+ }
+ else {
+ wattrset (win, menubox_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+
+ y = y + height + 1;
+ wmove(win, y, x);
+
+ if ((height < item_no) && (scroll + choice < item_no - 1)) {
+ wattrset (win, darrow_attr);
+ waddch (win, ACS_DARROW);
+ waddstr (win, "(+)");
+ }
+ else {
+ wattrset (win, menubox_border_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+}
+
+/*
+ * Display the termination buttons
+ */
+static void
+print_buttons( WINDOW *dialog, int height, int width, int selected)
+{
+ int x = width / 2 - 11;
+ int y = height - 2;
+
+ print_button (dialog, "Select", y, x, selected == 0);
+ print_button (dialog, " Help ", y, x + 14, selected == 1);
+
+ wmove(dialog, y, x+1 + 14*selected);
+ wrefresh (dialog);
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * The `flag' parameter is used to select between radiolist and checklist.
+ */
+int
+dialog_checklist (const char *title, const char *prompt, int height, int width,
+ int list_height, int item_no, const char * const * items, int flag)
+
+{
+ int i, x, y, box_x, box_y;
+ int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+ WINDOW *dialog, *list;
+
+ checkflag = flag;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = malloc (sizeof (int) * item_no)) == NULL) {
+ endwin ();
+ fprintf (stderr,
+ "\nCan't allocate memory in dialog_checklist().\n");
+ exit (-1);
+ }
+
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = !strcasecmp (items[i * 3 + 2], "on");
+ if ((!choice && status[i]) || !strcasecmp (items[i * 3 + 2], "selected"))
+ choice = i + 1;
+ }
+ if (choice)
+ choice--;
+
+ max_choice = MIN (list_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ list_width = width - 6;
+ box_y = height - list_height - 5;
+ box_x = (width - list_width) / 2 - 1;
+
+ /* create new window for the list */
+ list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
+
+ keypad (list, TRUE);
+
+ /* draw a box around the list items */
+ draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
+ menubox_border_attr, menubox_attr);
+
+ /* Find length of longest item in order to center checklist */
+ check_x = 0;
+ for (i = 0; i < item_no; i++)
+ check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
+
+ check_x = (list_width - check_x) / 2;
+ item_x = check_x + 4;
+
+ if (choice >= list_height) {
+ scroll = choice - list_height + 1;
+ choice -= scroll;
+ }
+
+ /* Print the list */
+ for (i = 0; i < max_choice; i++) {
+ print_item (list, items[(scroll+i) * 3 + 1],
+ status[i+scroll], i, i == choice);
+ }
+
+ print_arrows(dialog, choice, item_no, scroll,
+ box_y, box_x + check_x + 5, list_height);
+
+ print_buttons(dialog, height, width, 0);
+
+ wnoutrefresh (list);
+ wnoutrefresh (dialog);
+ doupdate ();
+
+ while (key != ESC) {
+ key = wgetch (dialog);
+
+ for (i = 0; i < max_choice; i++)
+ if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
+ break;
+
+
+ if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
+ key == '+' || key == '-' ) {
+ if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (!scroll)
+ continue;
+ /* Scroll list down */
+ if (list_height > 1) {
+ /* De-highlight current first item */
+ print_item (list, items[scroll * 3 + 1],
+ status[scroll], 0, FALSE);
+ scrollok (list, TRUE);
+ wscrl (list, -1);
+ scrollok (list, FALSE);
+ }
+ scroll--;
+ print_item (list, items[scroll * 3 + 1],
+ status[scroll], 0, TRUE);
+ wnoutrefresh (list);
+
+ print_arrows(dialog, choice, item_no, scroll,
+ box_y, box_x + check_x + 5, list_height);
+
+ wrefresh (dialog);
+
+ continue; /* wait for another key press */
+ } else
+ i = choice - 1;
+ } else if (key == KEY_DOWN || key == '+') {
+ if (choice == max_choice - 1) {
+ if (scroll + choice >= item_no - 1)
+ continue;
+ /* Scroll list up */
+ if (list_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
+ status[scroll + max_choice - 1],
+ max_choice - 1, FALSE);
+ scrollok (list, TRUE);
+ wscrl (list, 1);
+ scrollok (list, FALSE);
+ }
+ scroll++;
+ print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
+ status[scroll + max_choice - 1],
+ max_choice - 1, TRUE);
+ wnoutrefresh (list);
+
+ print_arrows(dialog, choice, item_no, scroll,
+ box_y, box_x + check_x + 5, list_height);
+
+ wrefresh (dialog);
+
+ continue; /* wait for another key press */
+ } else
+ i = choice + 1;
+ }
+ if (i != choice) {
+ /* De-highlight current item */
+ print_item (list, items[(scroll + choice) * 3 + 1],
+ status[scroll + choice], choice, FALSE);
+ /* Highlight new item */
+ choice = i;
+ print_item (list, items[(scroll + choice) * 3 + 1],
+ status[scroll + choice], choice, TRUE);
+ wnoutrefresh (list);
+ wrefresh (dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ switch (key) {
+ case 'H':
+ case 'h':
+ case '?':
+ fprintf (stderr, "%s", items[(scroll + choice) * 3]);
+ delwin (dialog);
+ free (status);
+ return 1;
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = ((key == KEY_LEFT ? --button : ++button) < 0)
+ ? 1 : (button > 1 ? 0 : button);
+
+ print_buttons(dialog, height, width, button);
+ wrefresh (dialog);
+ break;
+ case 'S':
+ case 's':
+ case ' ':
+ case '\n':
+ if (!button) {
+ if (flag == FLAG_CHECK) {
+ status[scroll + choice] = !status[scroll + choice];
+ wmove (list, choice, check_x);
+ wattrset (list, check_selected_attr);
+ wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
+ } else {
+ if (!status[scroll + choice]) {
+ for (i = 0; i < item_no; i++)
+ status[i] = 0;
+ status[scroll + choice] = 1;
+ for (i = 0; i < max_choice; i++)
+ print_item (list, items[(scroll + i) * 3 + 1],
+ status[scroll + i], i, i == choice);
+ }
+ }
+ wnoutrefresh (list);
+ wrefresh (dialog);
+
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ if (flag == FLAG_CHECK) {
+ fprintf (stderr, "\"%s\" ", items[i * 3]);
+ } else {
+ fprintf (stderr, "%s", items[i * 3]);
+ }
+
+ }
+ }
+ } else
+ fprintf (stderr, "%s", items[(scroll + choice) * 3]);
+ delwin (dialog);
+ free (status);
+ return button;
+ case 'X':
+ case 'x':
+ key = ESC;
+ case ESC:
+ break;
+ }
+
+ /* Now, update everything... */
+ doupdate ();
+ }
+
+
+ delwin (dialog);
+ free (status);
+ return -1; /* ESC pressed */
+}
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 @@
+/*
+ * colors.h -- color attribute definitions
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * Default color definitions
+ *
+ * *_FG = foreground
+ * *_BG = background
+ * *_HL = highlight?
+ */
+#define SCREEN_FG COLOR_CYAN
+#define SCREEN_BG COLOR_BLUE
+#define SCREEN_HL TRUE
+
+#define SHADOW_FG COLOR_BLACK
+#define SHADOW_BG COLOR_BLACK
+#define SHADOW_HL TRUE
+
+#define DIALOG_FG COLOR_BLACK
+#define DIALOG_BG COLOR_WHITE
+#define DIALOG_HL FALSE
+
+#define TITLE_FG COLOR_YELLOW
+#define TITLE_BG COLOR_WHITE
+#define TITLE_HL TRUE
+
+#define BORDER_FG COLOR_WHITE
+#define BORDER_BG COLOR_WHITE
+#define BORDER_HL TRUE
+
+#define BUTTON_ACTIVE_FG COLOR_WHITE
+#define BUTTON_ACTIVE_BG COLOR_BLUE
+#define BUTTON_ACTIVE_HL TRUE
+
+#define BUTTON_INACTIVE_FG COLOR_BLACK
+#define BUTTON_INACTIVE_BG COLOR_WHITE
+#define BUTTON_INACTIVE_HL FALSE
+
+#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
+#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
+#define BUTTON_KEY_ACTIVE_HL TRUE
+
+#define BUTTON_KEY_INACTIVE_FG COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
+#define BUTTON_KEY_INACTIVE_HL FALSE
+
+#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
+#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
+#define BUTTON_LABEL_ACTIVE_HL TRUE
+
+#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
+#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
+#define BUTTON_LABEL_INACTIVE_HL TRUE
+
+#define INPUTBOX_FG COLOR_BLACK
+#define INPUTBOX_BG COLOR_WHITE
+#define INPUTBOX_HL FALSE
+
+#define INPUTBOX_BORDER_FG COLOR_BLACK
+#define INPUTBOX_BORDER_BG COLOR_WHITE
+#define INPUTBOX_BORDER_HL FALSE
+
+#define SEARCHBOX_FG COLOR_BLACK
+#define SEARCHBOX_BG COLOR_WHITE
+#define SEARCHBOX_HL FALSE
+
+#define SEARCHBOX_TITLE_FG COLOR_YELLOW
+#define SEARCHBOX_TITLE_BG COLOR_WHITE
+#define SEARCHBOX_TITLE_HL TRUE
+
+#define SEARCHBOX_BORDER_FG COLOR_WHITE
+#define SEARCHBOX_BORDER_BG COLOR_WHITE
+#define SEARCHBOX_BORDER_HL TRUE
+
+#define POSITION_INDICATOR_FG COLOR_YELLOW
+#define POSITION_INDICATOR_BG COLOR_WHITE
+#define POSITION_INDICATOR_HL TRUE
+
+#define MENUBOX_FG COLOR_BLACK
+#define MENUBOX_BG COLOR_WHITE
+#define MENUBOX_HL FALSE
+
+#define MENUBOX_BORDER_FG COLOR_WHITE
+#define MENUBOX_BORDER_BG COLOR_WHITE
+#define MENUBOX_BORDER_HL TRUE
+
+#define ITEM_FG COLOR_BLACK
+#define ITEM_BG COLOR_WHITE
+#define ITEM_HL FALSE
+
+#define ITEM_SELECTED_FG COLOR_WHITE
+#define ITEM_SELECTED_BG COLOR_BLUE
+#define ITEM_SELECTED_HL TRUE
+
+#define TAG_FG COLOR_YELLOW
+#define TAG_BG COLOR_WHITE
+#define TAG_HL TRUE
+
+#define TAG_SELECTED_FG COLOR_YELLOW
+#define TAG_SELECTED_BG COLOR_BLUE
+#define TAG_SELECTED_HL TRUE
+
+#define TAG_KEY_FG COLOR_YELLOW
+#define TAG_KEY_BG COLOR_WHITE
+#define TAG_KEY_HL TRUE
+
+#define TAG_KEY_SELECTED_FG COLOR_YELLOW
+#define TAG_KEY_SELECTED_BG COLOR_BLUE
+#define TAG_KEY_SELECTED_HL TRUE
+
+#define CHECK_FG COLOR_BLACK
+#define CHECK_BG COLOR_WHITE
+#define CHECK_HL FALSE
+
+#define CHECK_SELECTED_FG COLOR_WHITE
+#define CHECK_SELECTED_BG COLOR_BLUE
+#define CHECK_SELECTED_HL TRUE
+
+#define UARROW_FG COLOR_GREEN
+#define UARROW_BG COLOR_WHITE
+#define UARROW_HL TRUE
+
+#define DARROW_FG COLOR_GREEN
+#define DARROW_BG COLOR_WHITE
+#define DARROW_HL TRUE
+
+/* End of default color definitions */
+
+#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
+#define COLOR_NAME_LEN 10
+#define COLOR_COUNT 8
+
+/*
+ * Global variables
+ */
+
+extern 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 @@
+
+/*
+ * dialog.h -- common declarations for all dialog modules
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __sun__
+#define CURS_MACROS
+#endif
+#include CURSES_LOC
+
+/*
+ * Colors in ncurses 1.9.9e do not work properly since foreground and
+ * background colors are OR'd rather than separately masked. This version
+ * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
+ * with standard curses. The simplest fix (to make this work with standard
+ * curses) uses the wbkgdset() function, not used in the original hack.
+ * Turn it off if we're building with 1.9.9e, since it just confuses things.
+ */
+#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
+#define OLD_NCURSES 1
+#undef wbkgdset
+#define wbkgdset(w,p) /*nothing*/
+#else
+#define OLD_NCURSES 0
+#endif
+
+#define TR(params) _tracef params
+
+#define ESC 27
+#define TAB 9
+#define MAX_LEN 2048
+#define BUF_SIZE (10*1024)
+#define MIN(x,y) (x < y ? x : y)
+#define MAX(x,y) (x > y ? x : y)
+
+
+#ifndef ACS_ULCORNER
+#define ACS_ULCORNER '+'
+#endif
+#ifndef ACS_LLCORNER
+#define ACS_LLCORNER '+'
+#endif
+#ifndef ACS_URCORNER
+#define ACS_URCORNER '+'
+#endif
+#ifndef ACS_LRCORNER
+#define ACS_LRCORNER '+'
+#endif
+#ifndef ACS_HLINE
+#define ACS_HLINE '-'
+#endif
+#ifndef ACS_VLINE
+#define ACS_VLINE '|'
+#endif
+#ifndef ACS_LTEE
+#define ACS_LTEE '+'
+#endif
+#ifndef ACS_RTEE
+#define ACS_RTEE '+'
+#endif
+#ifndef ACS_UARROW
+#define ACS_UARROW '^'
+#endif
+#ifndef ACS_DARROW
+#define ACS_DARROW 'v'
+#endif
+
+/*
+ * Attribute names
+ */
+#define screen_attr attributes[0]
+#define shadow_attr attributes[1]
+#define dialog_attr attributes[2]
+#define title_attr attributes[3]
+#define border_attr attributes[4]
+#define button_active_attr attributes[5]
+#define button_inactive_attr attributes[6]
+#define button_key_active_attr attributes[7]
+#define button_key_inactive_attr attributes[8]
+#define button_label_active_attr attributes[9]
+#define button_label_inactive_attr attributes[10]
+#define inputbox_attr attributes[11]
+#define inputbox_border_attr attributes[12]
+#define searchbox_attr attributes[13]
+#define searchbox_title_attr attributes[14]
+#define searchbox_border_attr attributes[15]
+#define position_indicator_attr attributes[16]
+#define menubox_attr attributes[17]
+#define menubox_border_attr attributes[18]
+#define item_attr attributes[19]
+#define item_selected_attr attributes[20]
+#define tag_attr attributes[21]
+#define tag_selected_attr attributes[22]
+#define tag_key_attr attributes[23]
+#define tag_key_selected_attr attributes[24]
+#define check_attr attributes[25]
+#define check_selected_attr attributes[26]
+#define uarrow_attr attributes[27]
+#define darrow_attr attributes[28]
+
+/* number of attributes */
+#define ATTRIBUTE_COUNT 29
+
+/*
+ * Global variables
+ */
+extern bool use_colors;
+extern bool use_shadow;
+
+extern chtype attributes[];
+
+extern const char *backtitle;
+
+/*
+ * Function prototypes
+ */
+extern void create_rc (const char *filename);
+extern int parse_rc (void);
+
+
+void init_dialog (void);
+void end_dialog (void);
+void attr_clear (WINDOW * win, int height, int width, chtype attr);
+void dialog_clear (void);
+void color_setup (void);
+void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
+void print_button (WINDOW * win, const char *label, int y, int x, int selected);
+void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
+ chtype border);
+void draw_shadow (WINDOW * win, int y, int x, int height, int width);
+
+int first_alpha (const char *string, const char *exempt);
+int dialog_yesno (const char *title, const char *prompt, int height, int width);
+int dialog_msgbox (const char *title, const char *prompt, int height,
+ int width, int pause);
+int dialog_textbox (const char *title, const char *file, int height, int width);
+int dialog_menu (const char *title, const char *prompt, int height, int width,
+ int menu_height, const char *choice, int item_no,
+ const char * const * items);
+int dialog_checklist (const char *title, const char *prompt, int height,
+ int width, int list_height, int item_no,
+ const char * const * items, int flag);
+extern unsigned char dialog_input_result[];
+int dialog_inputbox (const char *title, const char *prompt, int height,
+ int width, const char *init);
+
+/*
+ * This is the base for fictitious keys, which activate
+ * the buttons.
+ *
+ * Mouse-generated keys are the following:
+ * -- the first 32 are used as numbers, in addition to '0'-'9'
+ * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
+ * -- uppercase chars are used to invoke the button (M_EVENT + 'O')
+ */
+#define M_EVENT (KEY_MAX+1)
+
+
+/*
+ * The `flag' parameter in checklist is used to select between
+ * radiolist and checklist
+ */
+#define FLAG_CHECK 1
+#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 @@
+/*
+ * inputbox.c -- implements the input box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+unsigned char dialog_input_result[MAX_LEN + 1];
+
+/*
+ * Print the termination buttons
+ */
+static void
+print_buttons(WINDOW *dialog, int height, int width, int selected)
+{
+ int x = width / 2 - 11;
+ int y = height - 2;
+
+ print_button (dialog, " Ok ", y, x, selected==0);
+ print_button (dialog, " Help ", y, x + 14, selected==1);
+
+ wmove(dialog, y, x+1+14*selected);
+ wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int
+dialog_inputbox (const char *title, const char *prompt, int height, int width,
+ const char *init)
+{
+ int i, x, y, box_y, box_x, box_width;
+ int input_x = 0, scroll = 0, key = 0, button = -1;
+ unsigned char *instr = dialog_input_result;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ /* Draw the input field box */
+ box_width = width - 6;
+ getyx (dialog, y, x);
+ box_y = y + 2;
+ box_x = (width - box_width) / 2;
+ draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
+ border_attr, dialog_attr);
+
+ print_buttons(dialog, height, width, 0);
+
+ /* Set up the initial value */
+ wmove (dialog, box_y, box_x);
+ wattrset (dialog, inputbox_attr);
+
+ if (!init)
+ instr[0] = '\0';
+ else
+ strcpy (instr, init);
+
+ input_x = strlen (instr);
+
+ if (input_x >= box_width) {
+ scroll = input_x - box_width + 1;
+ input_x = box_width - 1;
+ for (i = 0; i < box_width - 1; i++)
+ waddch (dialog, instr[scroll + i]);
+ } else
+ waddstr (dialog, instr);
+
+ wmove (dialog, box_y, box_x + input_x);
+
+ wrefresh (dialog);
+
+ while (key != ESC) {
+ key = wgetch (dialog);
+
+ if (button == -1) { /* Input box selected */
+ switch (key) {
+ case TAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ break;
+ case KEY_LEFT:
+ continue;
+ case KEY_RIGHT:
+ continue;
+ case KEY_BACKSPACE:
+ case 127:
+ if (input_x || scroll) {
+ wattrset (dialog, inputbox_attr);
+ if (!input_x) {
+ scroll = scroll < box_width - 1 ?
+ 0 : scroll - (box_width - 1);
+ wmove (dialog, box_y, box_x);
+ for (i = 0; i < box_width; i++)
+ waddch (dialog, instr[scroll + input_x + i] ?
+ instr[scroll + input_x + i] : ' ');
+ input_x = strlen (instr) - scroll;
+ } else
+ input_x--;
+ instr[scroll + input_x] = '\0';
+ mvwaddch (dialog, box_y, input_x + box_x, ' ');
+ wmove (dialog, box_y, input_x + box_x);
+ wrefresh (dialog);
+ }
+ continue;
+ default:
+ if (key < 0x100 && isprint (key)) {
+ if (scroll + input_x < MAX_LEN) {
+ wattrset (dialog, inputbox_attr);
+ instr[scroll + input_x] = key;
+ instr[scroll + input_x + 1] = '\0';
+ if (input_x == box_width - 1) {
+ scroll++;
+ wmove (dialog, box_y, box_x);
+ for (i = 0; i < box_width - 1; i++)
+ waddch (dialog, instr[scroll + i]);
+ } else {
+ wmove (dialog, box_y, input_x++ + box_x);
+ waddch (dialog, key);
+ }
+ wrefresh (dialog);
+ } else
+ flash (); /* Alarm user about overflow */
+ continue;
+ }
+ }
+ }
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin (dialog);
+ return 0;
+ case 'H':
+ case 'h':
+ delwin (dialog);
+ return 1;
+ case KEY_UP:
+ case KEY_LEFT:
+ switch (button) {
+ case -1:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_buttons(dialog, height, width, 1);
+ break;
+ case 0:
+ button = -1; /* Indicates input box is selected */
+ print_buttons(dialog, height, width, 0);
+ wmove (dialog, box_y, box_x + input_x);
+ wrefresh (dialog);
+ break;
+ case 1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_buttons(dialog, height, width, 0);
+ break;
+ }
+ break;
+ case TAB:
+ case KEY_DOWN:
+ case KEY_RIGHT:
+ switch (button) {
+ case -1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_buttons(dialog, height, width, 0);
+ break;
+ case 0:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_buttons(dialog, height, width, 1);
+ break;
+ case 1:
+ button = -1; /* Indicates input box is selected */
+ print_buttons(dialog, height, width, 0);
+ wmove (dialog, box_y, box_x + input_x);
+ wrefresh (dialog);
+ break;
+ }
+ break;
+ case ' ':
+ case '\n':
+ delwin (dialog);
+ return (button == -1 ? 0 : button);
+ case 'X':
+ case 'x':
+ key = ESC;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ return -1; /* ESC pressed */
+}
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 @@
+/*
+ * dialog - Display simple dialog boxes from shell scripts
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void Usage (const char *name);
+
+typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
+
+struct Mode {
+ char *name;
+ int argmin, argmax, argmod;
+ jumperFn *jumper;
+};
+
+jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
+jumperFn j_msgbox, j_infobox;
+
+static struct Mode modes[] =
+{
+ {"--menu", 9, 0, 3, j_menu},
+ {"--checklist", 9, 0, 3, j_checklist},
+ {"--radiolist", 9, 0, 3, j_radiolist},
+ {"--yesno", 5,5,1, j_yesno},
+ {"--textbox", 5,5,1, j_textbox},
+ {"--inputbox", 5, 6, 1, j_inputbox},
+ {"--msgbox", 5, 5, 1, j_msgbox},
+ {"--infobox", 5, 5, 1, j_infobox},
+ {NULL, 0, 0, 0, NULL}
+};
+
+static struct Mode *modePtr;
+
+#ifdef LOCALE
+#include <locale.h>
+#endif
+
+int
+main (int argc, const char * const * argv)
+{
+ int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
+ const char *title = NULL;
+
+#ifdef LOCALE
+ (void) setlocale (LC_ALL, "");
+#endif
+
+#ifdef TRACE
+ trace(TRACE_CALLS|TRACE_UPDATE);
+#endif
+ if (argc < 2) {
+ Usage (argv[0]);
+ exit (-1);
+ }
+
+ while (offset < argc - 1 && !end_common_opts) { /* Common options */
+ if (!strcmp (argv[offset + 1], "--title")) {
+ if (argc - offset < 3 || title != NULL) {
+ Usage (argv[0]);
+ exit (-1);
+ } else {
+ title = argv[offset + 2];
+ offset += 2;
+ }
+ } else if (!strcmp (argv[offset + 1], "--backtitle")) {
+ if (backtitle != NULL) {
+ Usage (argv[0]);
+ exit (-1);
+ } else {
+ backtitle = argv[offset + 2];
+ offset += 2;
+ }
+ } else if (!strcmp (argv[offset + 1], "--clear")) {
+ if (opt_clear) { /* Hey, "--clear" can't appear twice! */
+ Usage (argv[0]);
+ exit (-1);
+ } else if (argc == 2) { /* we only want to clear the screen */
+ init_dialog ();
+ refresh (); /* init_dialog() will clear the screen for us */
+ end_dialog ();
+ return 0;
+ } else {
+ opt_clear = 1;
+ offset++;
+ }
+ } else /* no more common options */
+ end_common_opts = 1;
+ }
+
+ if (argc - 1 == offset) { /* no more options */
+ Usage (argv[0]);
+ exit (-1);
+ }
+ /* use a table to look for the requested mode, to avoid code duplication */
+
+ for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
+ if (!strcmp (argv[offset + 1], modePtr->name))
+ break;
+
+ if (!modePtr->name)
+ Usage (argv[0]);
+ if (argc - offset < modePtr->argmin)
+ Usage (argv[0]);
+ if (modePtr->argmax && argc - offset > modePtr->argmax)
+ Usage (argv[0]);
+
+
+
+ init_dialog ();
+ retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
+
+ if (opt_clear) { /* clear screen before exit */
+ attr_clear (stdscr, LINES, COLS, screen_attr);
+ refresh ();
+ }
+ end_dialog();
+
+ exit (retval);
+}
+
+/*
+ * Print program usage
+ */
+static void
+Usage (const char *name)
+{
+ fprintf (stderr, "\
+\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
+\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
+\n modified/gutted for use as a Linux kernel config tool by \
+\n William Roadcap (roadcapw@cfw.com)\
+\n\
+\n* Display dialog boxes from shell scripts *\
+\n\
+\nUsage: %s --clear\
+\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
+\n\
+\nBox options:\
+\n\
+\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
+\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
+\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
+\n --textbox <file> <height> <width>\
+\n --inputbox <text> <height> <width> [<init>]\
+\n --yesno <text> <height> <width>\
+\n", name, name);
+ exit (-1);
+}
+
+/*
+ * These are the program jumpers
+ */
+
+int
+j_menu (const char *t, int ac, const char * const * av)
+{
+ return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
+ atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
+}
+
+int
+j_checklist (const char *t, int ac, const char * const * av)
+{
+ return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
+ atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
+}
+
+int
+j_radiolist (const char *t, int ac, const char * const * av)
+{
+ return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
+ atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
+}
+
+int
+j_textbox (const char *t, int ac, const char * const * av)
+{
+ return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
+}
+
+int
+j_yesno (const char *t, int ac, const char * const * av)
+{
+ return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
+}
+
+int
+j_inputbox (const char *t, int ac, const char * const * av)
+{
+ int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
+ ac == 6 ? av[5] : (char *) NULL);
+ if (ret == 0)
+ fprintf(stderr, dialog_input_result);
+ return ret;
+}
+
+int
+j_msgbox (const char *t, int ac, const char * const * av)
+{
+ return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
+}
+
+int
+j_infobox (const char *t, int ac, const char * const * av)
+{
+ return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
+}
+
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 @@
+/*
+ * menubox.c -- implements the menu box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Changes by Clifford Wolf (god@clifford.at)
+ *
+ * [ 1998-06-13 ]
+ *
+ * *) A bugfix for the Page-Down problem
+ *
+ * *) Formerly when I used Page Down and Page Up, the cursor would be set
+ * to the first position in the menu box. Now lxdialog is a bit
+ * smarter and works more like other menu systems (just have a look at
+ * it).
+ *
+ * *) Formerly if I selected something my scrolling would be broken because
+ * lxdialog is re-invoked by the Menuconfig shell script, can't
+ * remember the last scrolling position, and just sets it so that the
+ * cursor is at the bottom of the box. Now it writes the temporary file
+ * lxdialog.scrltmp which contains this information. The file is
+ * deleted by lxdialog if the user leaves a submenu or enters a new
+ * one, but it would be nice if Menuconfig could make another "rm -f"
+ * just to be sure. Just try it out - you will recognise a difference!
+ *
+ * [ 1998-06-14 ]
+ *
+ * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
+ * and menus change their size on the fly.
+ *
+ * *) If for some reason the last scrolling position is not saved by
+ * lxdialog, it sets the scrolling so that the selected item is in the
+ * middle of the menu box, not at the bottom.
+ *
+ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
+ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
+ * This fixes a bug in Menuconfig where using ' ' to descend into menus
+ * would leave mis-synchronized lxdialog.scrltmp files lying around,
+ * fscanf would read in 'scroll', and eventually that value would get used.
+ */
+
+#include "dialog.h"
+
+static int menu_width, item_x;
+
+/*
+ * Print menu item
+ */
+static void
+print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
+{
+ int j;
+ char menu_item[menu_width+1];
+
+ strncpy(menu_item, item, menu_width);
+ menu_item[menu_width] = 0;
+ j = first_alpha(menu_item, "YyNnMmHh");
+
+ /* Clear 'residue' of last item */
+ wattrset (win, menubox_attr);
+ wmove (win, choice, 0);
+#if OLD_NCURSES
+ {
+ int i;
+ for (i = 0; i < menu_width; i++)
+ waddch (win, ' ');
+ }
+#else
+ wclrtoeol(win);
+#endif
+ wattrset (win, selected ? item_selected_attr : item_attr);
+ mvwaddstr (win, choice, item_x, menu_item);
+ if (hotkey) {
+ wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
+ mvwaddch(win, choice, item_x+j, menu_item[j]);
+ }
+ if (selected) {
+ wmove (win, choice, item_x+1);
+ wrefresh (win);
+ }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void
+print_arrows (WINDOW * win, int item_no, int scroll,
+ int y, int x, int height)
+{
+ int cur_y, cur_x;
+
+ getyx(win, cur_y, cur_x);
+
+ wmove(win, y, x);
+
+ if (scroll > 0) {
+ wattrset (win, uarrow_attr);
+ waddch (win, ACS_UARROW);
+ waddstr (win, "(-)");
+ }
+ else {
+ wattrset (win, menubox_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+
+ y = y + height + 1;
+ wmove(win, y, x);
+
+ if ((height < item_no) && (scroll + height < item_no)) {
+ wattrset (win, darrow_attr);
+ waddch (win, ACS_DARROW);
+ waddstr (win, "(+)");
+ }
+ else {
+ wattrset (win, menubox_border_attr);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ waddch (win, ACS_HLINE);
+ }
+
+ wmove(win, cur_y, cur_x);
+}
+
+/*
+ * Display the termination buttons.
+ */
+static void
+print_buttons (WINDOW *win, int height, int width, int selected)
+{
+ int x = width / 2 - 16;
+ int y = height - 2;
+
+ print_button (win, "Select", y, x, selected == 0);
+ print_button (win, " Exit ", y, x + 12, selected == 1);
+ print_button (win, " Help ", y, x + 24, selected == 2);
+
+ wmove(win, y, x+1+12*selected);
+ wrefresh (win);
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int
+dialog_menu (const char *title, const char *prompt, int height, int width,
+ int menu_height, const char *current, int item_no,
+ const char * const * items)
+
+{
+ int i, j, x, y, box_x, box_y;
+ int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
+ WINDOW *dialog, *menu;
+ FILE *f;
+
+ max_choice = MIN (menu_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height - 3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ wbkgdset (dialog, dialog_attr & A_COLOR);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ menu_width = width - 6;
+ box_y = height - menu_height - 5;
+ box_x = (width - menu_width) / 2 - 1;
+
+ /* create new window for the menu */
+ menu = subwin (dialog, menu_height, menu_width,
+ y + box_y + 1, x + box_x + 1);
+ keypad (menu, TRUE);
+
+ /* draw a box around the menu items */
+ draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
+ menubox_border_attr, menubox_attr);
+
+ /*
+ * Find length of longest item in order to center menu.
+ * Set 'choice' to default item.
+ */
+ item_x = 0;
+ for (i = 0; i < item_no; i++) {
+ item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
+ if (strcmp(current, items[i*2]) == 0) choice = i;
+ }
+
+ item_x = (menu_width - item_x) / 2;
+
+ /* get the scroll info from the temp file */
+ if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
+ if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
+ (scroll+max_choice > choice) && (scroll >= 0) &&
+ (scroll+max_choice <= item_no) ) {
+ first_item = scroll;
+ choice = choice - scroll;
+ fclose(f);
+ } else {
+ scroll=0;
+ remove("lxdialog.scrltmp");
+ fclose(f);
+ f=NULL;
+ }
+ }
+ if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
+ if (choice >= item_no-max_choice/2)
+ scroll = first_item = item_no-max_choice;
+ else
+ scroll = first_item = choice - max_choice/2;
+ choice = choice - scroll;
+ }
+
+ /* Print the menu */
+ for (i=0; i < max_choice; i++) {
+ print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
+ (items[(first_item + i)*2][0] != ':'));
+ }
+
+ wnoutrefresh (menu);
+
+ print_arrows(dialog, item_no, scroll,
+ box_y, box_x+item_x+1, menu_height);
+
+ print_buttons (dialog, height, width, 0);
+ wmove (menu, choice, item_x+1);
+ wrefresh (menu);
+
+ while (key != ESC) {
+ key = wgetch(menu);
+
+ if (key < 256 && isalpha(key)) key = tolower(key);
+
+ if (strchr("ynmh", key))
+ i = max_choice;
+ else {
+ for (i = choice+1; i < max_choice; i++) {
+ j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
+ if (key == tolower(items[(scroll+i)*2+1][j]))
+ break;
+ }
+ if (i == max_choice)
+ for (i = 0; i < max_choice; i++) {
+ j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
+ if (key == tolower(items[(scroll+i)*2+1][j]))
+ break;
+ }
+ }
+
+ if (i < max_choice ||
+ key == KEY_UP || key == KEY_DOWN ||
+ key == '-' || key == '+' ||
+ key == KEY_PPAGE || key == KEY_NPAGE) {
+
+ print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
+ (items[(scroll+choice)*2][0] != ':'));
+
+ if (key == KEY_UP || key == '-') {
+ if (choice < 2 && scroll) {
+ /* Scroll menu down */
+ scrollok (menu, TRUE);
+ wscrl (menu, -1);
+ scrollok (menu, FALSE);
+
+ scroll--;
+
+ print_item (menu, items[scroll * 2 + 1], 0, FALSE,
+ (items[scroll*2][0] != ':'));
+ } else
+ choice = MAX(choice - 1, 0);
+
+ } else if (key == KEY_DOWN || key == '+') {
+
+ print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
+ (items[(scroll+choice)*2][0] != ':'));
+
+ if ((choice > max_choice-3) &&
+ (scroll + max_choice < item_no)
+ ) {
+ /* Scroll menu up */
+ scrollok (menu, TRUE);
+ wscrl (menu, 1);
+ scrollok (menu, FALSE);
+
+ scroll++;
+
+ print_item (menu, items[(scroll+max_choice-1)*2+1],
+ max_choice-1, FALSE,
+ (items[(scroll+max_choice-1)*2][0] != ':'));
+ } else
+ choice = MIN(choice+1, max_choice-1);
+
+ } else if (key == KEY_PPAGE) {
+ scrollok (menu, TRUE);
+ for (i=0; (i < max_choice); i++) {
+ if (scroll > 0) {
+ wscrl (menu, -1);
+ scroll--;
+ print_item (menu, items[scroll * 2 + 1], 0, FALSE,
+ (items[scroll*2][0] != ':'));
+ } else {
+ if (choice > 0)
+ choice--;
+ }
+ }
+ scrollok (menu, FALSE);
+
+ } else if (key == KEY_NPAGE) {
+ for (i=0; (i < max_choice); i++) {
+ if (scroll+max_choice < item_no) {
+ scrollok (menu, TRUE);
+ wscrl (menu, 1);
+ scrollok (menu, FALSE);
+ scroll++;
+ print_item (menu, items[(scroll+max_choice-1)*2+1],
+ max_choice-1, FALSE,
+ (items[(scroll+max_choice-1)*2][0] != ':'));
+ } else {
+ if (choice+1 < max_choice)
+ choice++;
+ }
+ }
+
+ } else
+ choice = i;
+
+ print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
+ (items[(scroll+choice)*2][0] != ':'));
+
+ print_arrows(dialog, item_no, scroll,
+ box_y, box_x+item_x+1, menu_height);
+
+ wnoutrefresh (dialog);
+ wrefresh (menu);
+
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_LEFT:
+ case TAB:
+ case KEY_RIGHT:
+ button = ((key == KEY_LEFT ? --button : ++button) < 0)
+ ? 2 : (button > 2 ? 0 : button);
+
+ print_buttons(dialog, height, width, button);
+ wrefresh (menu);
+ break;
+ case ' ':
+ case 's':
+ case 'y':
+ case 'n':
+ case 'm':
+ case '/':
+ /* save scroll info */
+ if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
+ fprintf(f,"%d\n",scroll);
+ fclose(f);
+ }
+ delwin (dialog);
+ fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+ switch (key) {
+ case 's': return 3;
+ case 'y': return 3;
+ case 'n': return 4;
+ case 'm': return 5;
+ case ' ': return 6;
+ case '/': return 7;
+ }
+ return 0;
+ case 'h':
+ case '?':
+ button = 2;
+ case '\n':
+ delwin (dialog);
+ if (button == 2)
+ fprintf(stderr, "%s \"%s\"\n",
+ items[(scroll + choice) * 2],
+ items[(scroll + choice) * 2 + 1] +
+ first_alpha(items[(scroll + choice) * 2 + 1],""));
+ else
+ fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+
+ remove("lxdialog.scrltmp");
+ return button;
+ case 'e':
+ case 'x':
+ key = ESC;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ remove("lxdialog.scrltmp");
+ return -1; /* ESC pressed */
+}
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 @@
+/*
+ * msgbox.c -- implements the message box and info box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int
+dialog_msgbox (const char *title, const char *prompt, int height, int width,
+ int pause)
+{
+ int i, x, y, key = 0;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 2);
+
+ if (pause) {
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height - 3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ print_button (dialog, " Ok ",
+ height - 2, width / 2 - 4, TRUE);
+
+ wrefresh (dialog);
+ while (key != ESC && key != '\n' && key != ' ' &&
+ key != 'O' && key != 'o' && key != 'X' && key != 'x')
+ key = wgetch (dialog);
+ } else {
+ key = '\n';
+ wrefresh (dialog);
+ }
+
+ delwin (dialog);
+ return key == ESC ? -1 : 0;
+}
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 @@
+/*
+ * textbox.c -- implements the text box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void back_lines (int n);
+static void print_page (WINDOW * win, int height, int width);
+static void print_line (WINDOW * win, int row, int width);
+static char *get_line (void);
+static void print_position (WINDOW * win, int height, int width);
+
+static int hscroll, fd, file_size, bytes_read;
+static int begin_reached = 1, end_reached, page_length;
+static char *buf, *page;
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int
+dialog_textbox (const char *title, const char *file, int height, int width)
+{
+ int i, x, y, cur_x, cur_y, fpos, key = 0;
+ int passed_end;
+ char search_term[MAX_LEN + 1];
+ WINDOW *dialog, *text;
+
+ search_term[0] = '\0'; /* no search term entered yet */
+
+ /* Open input file for reading */
+ if ((fd = open (file, O_RDONLY)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nCan't open input file in dialog_textbox().\n");
+ exit (-1);
+ }
+ /* Get file size. Actually, 'file_size' is the real file size - 1,
+ since it's only the last byte offset from the beginning */
+ if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
+ exit (-1);
+ }
+ /* Restore file pointer to beginning of file after getting file size */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ /* Allocate space for read buffer */
+ if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
+ endwin ();
+ fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
+ exit (-1);
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in dialog_textbox().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0'; /* mark end of valid data */
+ page = buf; /* page is pointer to start of page to be displayed */
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ /* Create window for text region, used for scrolling text */
+ text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
+ wattrset (text, dialog_attr);
+ wbkgdset (text, dialog_attr & A_COLOR);
+
+ keypad (text, TRUE);
+
+ /* register the new window, along with its borders */
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ wbkgdset (dialog, dialog_attr & A_COLOR);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+ print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+ wnoutrefresh (dialog);
+ getyx (dialog, cur_y, cur_x); /* Save cursor position */
+
+ /* Print first page of text */
+ attr_clear (text, height - 4, width - 2, dialog_attr);
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+
+ while ((key != ESC) && (key != '\n')) {
+ key = wgetch (dialog);
+ switch (key) {
+ case 'E': /* Exit */
+ case 'e':
+ case 'X':
+ case 'x':
+ delwin (dialog);
+ free (buf);
+ close (fd);
+ return 0;
+ case 'g': /* First page */
+ case KEY_HOME:
+ if (!begin_reached) {
+ begin_reached = 1;
+ /* First page not in buffer? */
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ if (fpos > bytes_read) { /* Yes, we have to read it in */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "dialog_textbox().\n");
+ exit (-1);
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError reading file in dialog_textbox().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf;
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ }
+ break;
+ case 'G': /* Last page */
+ case KEY_END:
+
+ end_reached = 1;
+ /* Last page not in buffer? */
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ if (fpos < file_size) { /* Yes, we have to read it in */
+ if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in dialog_textbox().\n");
+ exit (-1);
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError reading file in dialog_textbox().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf + bytes_read;
+ back_lines (height - 4);
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ break;
+ case 'K': /* Previous line */
+ case 'k':
+ case KEY_UP:
+ if (!begin_reached) {
+ back_lines (page_length + 1);
+
+ /* We don't call print_page() here but use scrolling to ensure
+ faster screen update. However, 'end_reached' and
+ 'page_length' should still be updated, and 'page' should
+ point to start of next page. This is done by calling
+ get_line() in the following 'for' loop. */
+ scrollok (text, TRUE);
+ wscrl (text, -1); /* Scroll text region down one line */
+ scrollok (text, FALSE);
+ page_length = 0;
+ passed_end = 0;
+ for (i = 0; i < height - 4; i++) {
+ if (!i) {
+ /* print first line of page */
+ print_line (text, 0, width - 2);
+ wnoutrefresh (text);
+ } else
+ /* Called to update 'end_reached' and 'page' */
+ get_line ();
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ }
+ break;
+ case 'B': /* Previous page */
+ case 'b':
+ case KEY_PPAGE:
+ if (begin_reached)
+ break;
+ back_lines (page_length + height - 4);
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case 'J': /* Next line */
+ case 'j':
+ case KEY_DOWN:
+ if (!end_reached) {
+ begin_reached = 0;
+ scrollok (text, TRUE);
+ scroll (text); /* Scroll text region up one line */
+ scrollok (text, FALSE);
+ print_line (text, height - 5, width - 2);
+ wnoutrefresh (text);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh (dialog);
+ }
+ break;
+ case KEY_NPAGE: /* Next page */
+ case ' ':
+ if (end_reached)
+ break;
+
+ begin_reached = 0;
+ print_page (text, height - 4, width - 2);
+ print_position (dialog, height, width);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case '0': /* Beginning of line */
+ case 'H': /* Scroll left */
+ case 'h':
+ case KEY_LEFT:
+ if (hscroll <= 0)
+ break;
+
+ if (key == '0')
+ hscroll = 0;
+ else
+ hscroll--;
+ /* Reprint current page to scroll horizontally */
+ back_lines (page_length);
+ print_page (text, height - 4, width - 2);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case 'L': /* Scroll right */
+ case 'l':
+ case KEY_RIGHT:
+ if (hscroll >= MAX_LEN)
+ break;
+ hscroll++;
+ /* Reprint current page to scroll horizontally */
+ back_lines (page_length);
+ print_page (text, height - 4, width - 2);
+ wmove (dialog, cur_y, cur_x);
+ wrefresh (dialog);
+ break;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ free (buf);
+ close (fd);
+ return -1; /* ESC pressed */
+}
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void
+back_lines (int n)
+{
+ int i, fpos;
+
+ begin_reached = 0;
+ /* We have to distinguish between end_reached and !end_reached
+ since at end of file, the line is not ended by a '\n'.
+ The code inside 'if' basically does a '--page' to move one
+ character backward so as to skip '\n' of the previous line */
+ if (!end_reached) {
+ /* Either beginning of buffer or beginning of file reached? */
+ if (page == buf) {
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "back_lines().\n");
+ exit (-1);
+ }
+ if (fpos > bytes_read) { /* Not beginning of file yet */
+ /* We've reached beginning of buffer, but not beginning of
+ file yet, so read previous part of file into buffer.
+ Note that we only move backward for BUF_SIZE/2 bytes,
+ but not BUF_SIZE bytes to avoid re-reading again in
+ print_page() later */
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE / 2 + bytes_read) {
+ /* No, move less then */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "back_lines().\n");
+ exit (-1);
+ }
+ page = buf + fpos - bytes_read;
+ } else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
+ == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer "
+ "in back_lines().\n");
+ exit (-1);
+ }
+ page = buf + BUF_SIZE / 2;
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in back_lines().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ } else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ if (*(--page) != '\n') { /* '--page' here */
+ /* Something's wrong... */
+ endwin ();
+ fprintf (stderr, "\nInternal error in back_lines().\n");
+ exit (-1);
+ }
+ }
+ /* Go back 'n' lines */
+ for (i = 0; i < n; i++)
+ do {
+ if (page == buf) {
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr,
+ "\nError moving file pointer in back_lines().\n");
+ exit (-1);
+ }
+ if (fpos > bytes_read) {
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE / 2 + bytes_read) {
+ /* No, move less then */
+ if (lseek (fd, 0, SEEK_SET) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer "
+ "in back_lines().\n");
+ exit (-1);
+ }
+ page = buf + fpos - bytes_read;
+ } else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
+ SEEK_CUR) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer"
+ " in back_lines().\n");
+ exit (-1);
+ }
+ page = buf + BUF_SIZE / 2;
+ }
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in "
+ "back_lines().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ } else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ } while (*(--page) != '\n');
+ page++;
+}
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void
+print_page (WINDOW * win, int height, int width)
+{
+ int i, passed_end = 0;
+
+ page_length = 0;
+ for (i = 0; i < height; i++) {
+ print_line (win, i, width);
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+ wnoutrefresh (win);
+}
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void
+print_line (WINDOW * win, int row, int width)
+{
+ int y, x;
+ char *line;
+
+ line = get_line ();
+ line += MIN (strlen (line), hscroll); /* Scroll horizontally */
+ wmove (win, row, 0); /* move cursor to correct line */
+ waddch (win, ' ');
+ waddnstr (win, line, MIN (strlen (line), width - 2));
+
+ getyx (win, y, x);
+ /* Clear 'residue' of previous line */
+#if OLD_NCURSES
+ {
+ int i;
+ for (i = 0; i < width - x; i++)
+ waddch (win, ' ');
+ }
+#else
+ wclrtoeol(win);
+#endif
+}
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static char *
+get_line (void)
+{
+ int i = 0, fpos;
+ static char line[MAX_LEN + 1];
+
+ end_reached = 0;
+ while (*page != '\n') {
+ if (*page == '\0') {
+ /* Either end of file or end of buffer reached */
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in "
+ "get_line().\n");
+ exit (-1);
+ }
+ if (fpos < file_size) { /* Not end of file yet */
+ /* We've reached end of buffer, but not end of file yet,
+ so read next part of file into buffer */
+ if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError reading file in get_line().\n");
+ exit (-1);
+ }
+ buf[bytes_read] = '\0';
+ page = buf;
+ } else {
+ if (!end_reached)
+ end_reached = 1;
+ break;
+ }
+ } else if (i < MAX_LEN)
+ line[i++] = *(page++);
+ else {
+ /* Truncate lines longer than MAX_LEN characters */
+ if (i == MAX_LEN)
+ line[i++] = '\0';
+ page++;
+ }
+ }
+ if (i <= MAX_LEN)
+ line[i] = '\0';
+ if (!end_reached)
+ page++; /* move pass '\n' */
+
+ return line;
+}
+
+/*
+ * Print current position
+ */
+static void
+print_position (WINDOW * win, int height, int width)
+{
+ int fpos, percent;
+
+ if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
+ endwin ();
+ fprintf (stderr, "\nError moving file pointer in print_position().\n");
+ exit (-1);
+ }
+ wattrset (win, position_indicator_attr);
+ wbkgdset (win, position_indicator_attr & A_COLOR);
+ percent = !file_size ?
+ 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
+ wmove (win, height - 3, width - 9);
+ wprintw (win, "(%3d%%)", percent);
+}
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 @@
+/*
+ * util.c
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+
+/* use colors by default? */
+bool use_colors = 1;
+
+const char *backtitle = NULL;
+
+const char *dialog_result;
+
+/*
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] =
+{
+ A_NORMAL, /* screen_attr */
+ A_NORMAL, /* shadow_attr */
+ A_NORMAL, /* dialog_attr */
+ A_BOLD, /* title_attr */
+ A_NORMAL, /* border_attr */
+ A_REVERSE, /* button_active_attr */
+ A_DIM, /* button_inactive_attr */
+ A_REVERSE, /* button_key_active_attr */
+ A_BOLD, /* button_key_inactive_attr */
+ A_REVERSE, /* button_label_active_attr */
+ A_NORMAL, /* button_label_inactive_attr */
+ A_NORMAL, /* inputbox_attr */
+ A_NORMAL, /* inputbox_border_attr */
+ A_NORMAL, /* searchbox_attr */
+ A_BOLD, /* searchbox_title_attr */
+ A_NORMAL, /* searchbox_border_attr */
+ A_BOLD, /* position_indicator_attr */
+ A_NORMAL, /* menubox_attr */
+ A_NORMAL, /* menubox_border_attr */
+ A_NORMAL, /* item_attr */
+ A_REVERSE, /* item_selected_attr */
+ A_BOLD, /* tag_attr */
+ A_REVERSE, /* tag_selected_attr */
+ A_BOLD, /* tag_key_attr */
+ A_REVERSE, /* tag_key_selected_attr */
+ A_BOLD, /* check_attr */
+ A_REVERSE, /* check_selected_attr */
+ A_BOLD, /* uarrow_attr */
+ A_BOLD /* darrow_attr */
+};
+
+
+#include "colors.h"
+
+/*
+ * Table of color values
+ */
+int color_table[][3] =
+{
+ {SCREEN_FG, SCREEN_BG, SCREEN_HL},
+ {SHADOW_FG, SHADOW_BG, SHADOW_HL},
+ {DIALOG_FG, DIALOG_BG, DIALOG_HL},
+ {TITLE_FG, TITLE_BG, TITLE_HL},
+ {BORDER_FG, BORDER_BG, BORDER_HL},
+ {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
+ {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
+ {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
+ {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
+ {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
+ {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
+ BUTTON_LABEL_INACTIVE_HL},
+ {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
+ {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
+ {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
+ {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
+ {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
+ {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
+ {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
+ {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
+ {ITEM_FG, ITEM_BG, ITEM_HL},
+ {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
+ {TAG_FG, TAG_BG, TAG_HL},
+ {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
+ {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
+ {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
+ {CHECK_FG, CHECK_BG, CHECK_HL},
+ {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
+ {UARROW_FG, UARROW_BG, UARROW_HL},
+ {DARROW_FG, DARROW_BG, DARROW_HL},
+}; /* color_table */
+
+/*
+ * Set window to attribute 'attr'
+ */
+void
+attr_clear (WINDOW * win, int height, int width, chtype attr)
+{
+ int i, j;
+
+ wattrset (win, attr);
+ for (i = 0; i < height; i++) {
+ wmove (win, i, 0);
+ for (j = 0; j < width; j++)
+ waddch (win, ' ');
+ }
+ touchwin (win);
+}
+
+void dialog_clear (void)
+{
+ attr_clear (stdscr, LINES, COLS, screen_attr);
+ /* Display background title if it exists ... - SLH */
+ if (backtitle != NULL) {
+ int i;
+
+ wattrset (stdscr, screen_attr);
+ mvwaddstr (stdscr, 0, 1, (char *)backtitle);
+ wmove (stdscr, 1, 1);
+ for (i = 1; i < COLS - 1; i++)
+ waddch (stdscr, ACS_HLINE);
+ }
+ wnoutrefresh (stdscr);
+}
+
+/*
+ * Do some initialization for dialog
+ */
+void
+init_dialog (void)
+{
+ initscr (); /* Init curses */
+ keypad (stdscr, TRUE);
+ cbreak ();
+ noecho ();
+
+
+ if (use_colors) /* Set up colors */
+ color_setup ();
+
+
+ dialog_clear ();
+}
+
+/*
+ * Setup for color display
+ */
+void
+color_setup (void)
+{
+ int i;
+
+ if (has_colors ()) { /* Terminal supports color? */
+ start_color ();
+
+ /* Initialize color pairs */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ init_pair (i + 1, color_table[i][0], color_table[i][1]);
+
+ /* Setup color attributes */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ attributes[i] = C_ATTR (color_table[i][2], i + 1);
+ }
+}
+
+/*
+ * End using dialog functions.
+ */
+void
+end_dialog (void)
+{
+ endwin ();
+}
+
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Newline
+ * characters '\n' are replaced by spaces. We start on a new line
+ * if there is no room for at least 4 nonblanks following a double-space.
+ */
+void
+print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
+{
+ int newl, cur_x, cur_y;
+ int i, prompt_len, room, wlen;
+ char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
+
+ strcpy (tempstr, prompt);
+
+ prompt_len = strlen(tempstr);
+
+ /*
+ * Remove newlines
+ */
+ for(i=0; i<prompt_len; i++) {
+ if(tempstr[i] == '\n') tempstr[i] = ' ';
+ }
+
+ if (prompt_len <= width - x * 2) { /* If prompt is short */
+ wmove (win, y, (width - prompt_len) / 2);
+ waddstr (win, tempstr);
+ } else {
+ cur_x = x;
+ cur_y = y;
+ newl = 1;
+ word = tempstr;
+ while (word && *word) {
+ sp = index(word, ' ');
+ if (sp)
+ *sp++ = 0;
+
+ /* Wrap to next line if either the word does not fit,
+ or it is the first word of a new sentence, and it is
+ short, and the next word does not fit. */
+ room = width - cur_x;
+ wlen = strlen(word);
+ if (wlen > room ||
+ (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
+ && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
+ cur_y++;
+ cur_x = x;
+ }
+ wmove (win, cur_y, cur_x);
+ waddstr (win, word);
+ getyx (win, cur_y, cur_x);
+ cur_x++;
+ if (sp && *sp == ' ') {
+ cur_x++; /* double space */
+ while (*++sp == ' ');
+ newl = 1;
+ } else
+ newl = 0;
+ word = sp;
+ }
+ }
+}
+
+/*
+ * Print a button
+ */
+void
+print_button (WINDOW * win, const char *label, int y, int x, int selected)
+{
+ int i, temp;
+
+ wmove (win, y, x);
+ wattrset (win, selected ? button_active_attr : button_inactive_attr);
+ waddstr (win, "<");
+ temp = strspn (label, " ");
+ label += temp;
+ wattrset (win, selected ? button_label_active_attr
+ : button_label_inactive_attr);
+ for (i = 0; i < temp; i++)
+ waddch (win, ' ');
+ wattrset (win, selected ? button_key_active_attr
+ : button_key_inactive_attr);
+ waddch (win, label[0]);
+ wattrset (win, selected ? button_label_active_attr
+ : button_label_inactive_attr);
+ waddstr (win, (char *)label + 1);
+ wattrset (win, selected ? button_active_attr : button_inactive_attr);
+ waddstr (win, ">");
+ wmove (win, y, x + temp + 1);
+}
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void
+draw_box (WINDOW * win, int y, int x, int height, int width,
+ chtype box, chtype border)
+{
+ int i, j;
+
+ wattrset (win, 0);
+ for (i = 0; i < height; i++) {
+ wmove (win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (!i && !j)
+ waddch (win, border | ACS_ULCORNER);
+ else if (i == height - 1 && !j)
+ waddch (win, border | ACS_LLCORNER);
+ else if (!i && j == width - 1)
+ waddch (win, box | ACS_URCORNER);
+ else if (i == height - 1 && j == width - 1)
+ waddch (win, box | ACS_LRCORNER);
+ else if (!i)
+ waddch (win, border | ACS_HLINE);
+ else if (i == height - 1)
+ waddch (win, box | ACS_HLINE);
+ else if (!j)
+ waddch (win, border | ACS_VLINE);
+ else if (j == width - 1)
+ waddch (win, box | ACS_VLINE);
+ else
+ waddch (win, box | ' ');
+ }
+}
+
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void
+draw_shadow (WINDOW * win, int y, int x, int height, int width)
+{
+ int i;
+
+ if (has_colors ()) { /* Whether terminal supports color? */
+ wattrset (win, shadow_attr);
+ wmove (win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ waddch (win, winch (win) & A_CHARTEXT);
+ for (i = y + 1; i < y + height + 1; i++) {
+ wmove (win, i, x + width);
+ waddch (win, winch (win) & A_CHARTEXT);
+ waddch (win, winch (win) & A_CHARTEXT);
+ }
+ wnoutrefresh (win);
+ }
+}
+
+/*
+ * Return the position of the first alphabetic character in a string.
+ */
+int
+first_alpha(const char *string, const char *exempt)
+{
+ int i, in_paren=0, c;
+
+ for (i = 0; i < strlen(string); i++) {
+ c = tolower(string[i]);
+
+ if (strchr("<[(", c)) ++in_paren;
+ if (strchr(">])", c) && in_paren > 0) --in_paren;
+
+ if ((! in_paren) && isalpha(c) &&
+ strchr(exempt, c) == 0)
+ return i;
+ }
+
+ return 0;
+}
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 @@
+/*
+ * yesno.c -- implements the yes/no box
+ *
+ * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display termination buttons
+ */
+static void
+print_buttons(WINDOW *dialog, int height, int width, int selected)
+{
+ int x = width / 2 - 10;
+ int y = height - 2;
+
+ print_button (dialog, " Yes ", y, x, selected == 0);
+ print_button (dialog, " No ", y, x + 13, selected == 1);
+
+ wmove(dialog, y, x+1 + 13*selected );
+ wrefresh (dialog);
+}
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int
+dialog_yesno (const char *title, const char *prompt, int height, int width)
+{
+ int i, x, y, key = 0, button = 0;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width) / 2;
+ y = (LINES - height) / 2;
+
+ draw_shadow (stdscr, y, x, height, width);
+
+ dialog = newwin (height, width, y, x);
+ keypad (dialog, TRUE);
+
+ draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset (dialog, border_attr);
+ mvwaddch (dialog, height-3, 0, ACS_LTEE);
+ for (i = 0; i < width - 2; i++)
+ waddch (dialog, ACS_HLINE);
+ wattrset (dialog, dialog_attr);
+ waddch (dialog, ACS_RTEE);
+
+ if (title != NULL && strlen(title) >= width-2 ) {
+ /* truncate long title -- mec */
+ char * title2 = malloc(width-2+1);
+ memcpy( title2, title, width-2 );
+ title2[width-2] = '\0';
+ title = title2;
+ }
+
+ if (title != NULL) {
+ wattrset (dialog, title_attr);
+ mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
+ waddstr (dialog, (char *)title);
+ waddch (dialog, ' ');
+ }
+
+ wattrset (dialog, dialog_attr);
+ print_autowrap (dialog, prompt, width - 2, 1, 3);
+
+ print_buttons(dialog, height, width, 0);
+
+ while (key != ESC) {
+ key = wgetch (dialog);
+ switch (key) {
+ case 'Y':
+ case 'y':
+ delwin (dialog);
+ return 0;
+ case 'N':
+ case 'n':
+ delwin (dialog);
+ return 1;
+
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = ((key == KEY_LEFT ? --button : ++button) < 0)
+ ? 1 : (button > 1 ? 0 : button);
+
+ print_buttons(dialog, height, width, button);
+ wrefresh (dialog);
+ break;
+ case ' ':
+ case '\n':
+ delwin (dialog);
+ return button;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin (dialog);
+ return -1; /* ESC pressed */
+}
diff --git a/scripts/makelst b/scripts/makelst
new file mode 100755
index 000000000000..34bd72391238
--- /dev/null
+++ b/scripts/makelst
@@ -0,0 +1,31 @@
+#!/bin/bash
+# A script to dump mixed source code & assembly
+# with correct relocations from System.map
+# Requires the following lines in Rules.make.
+# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+# William Stearns <wstearns@pobox.com>
+#%.lst: %.c
+# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+# $(TOPDIR)/scripts/makelst $*.o $(TOPDIR)/System.map $(OBJDUMP)
+#
+# Copyright (C) 2000 IBM Corporation
+# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+#
+
+t1=`$3 --syms $1 | grep .text | grep " F " | head -n 1`
+if [ -n "$t1" ]; then
+ t2=`echo $t1 | gawk '{ print $6 }'`
+ if [ ! -r $2 ]; then
+ echo "No System.map" >&2
+ t7=0
+ else
+ t3=`grep $t2 $2`
+ t4=`echo $t3 | gawk '{ print $1 }'`
+ t5=`echo $t1 | gawk '{ print $1 }'`
+ t6=`echo $t4 - $t5 | tr a-f A-F`
+ t7=`( echo ibase=16 ; echo $t6 ) | bc`
+ fi
+else
+ t7=0
+fi
+$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 @@
+#!/usr/bin/perl
+
+use strict;
+
+## Copyright (C) Michael Still (mikal@stillhq.com)
+## Released under the terms of the GNU GPL
+##
+## A script to make or install the manpages extracted by split-man
+##
+## Arguements: $1 -- the word "convert" or "install"
+## $2 -- the directory containing the SGML files for the manpages
+## $3 -- the filename which contained the sgmldoc output
+## (I need this so I know which manpages to convert)
+
+my($LISTING, $GENERATED, $INPUT, $OUTPUT, $front, $mode, $filename, $tmpdir);
+
+if($ARGV[0] eq ""){
+ die "Usage: makeman [convert | install] <dir> <file>\n";
+}
+
+if( ! -d "$ARGV[1]" ){
+ die "Output directory \"$ARGV[1]\" does not exist\n";
+}
+
+if($ENV{"TMPDIR"} ne ""){
+ $tmpdir = $ENV{"TMPDIR"};
+}
+else{
+ $tmpdir = "/tmp";
+}
+
+if($ARGV[0] eq "convert"){
+ open LISTING, "grep \"<refentrytitle>\" $ARGV[2] |";
+ while(<LISTING>){
+ s/<\/.*$//;
+ s/^.*>//;
+ s/\.sgml//;
+ s/struct //;
+ s/typedef //;
+
+ chomp;
+ $filename = $_;
+ print "Processing $filename\n";
+
+ # Open the input file to extract the front matter, generate the man page,
+ # and open it, and the rearrange everything until it is happy
+ open INPUT, "< $ARGV[1]/$filename.sgml";
+ $front = "";
+ $mode = 0;
+
+ # The modes used here are:
+ # mode = 0
+ # <!-- BEGINFRONTTAG -->
+ # <!-- <bookinfo> mode = 1
+ # <!-- <legalnotice> mode = 2
+ # <!-- ...GPL or whatever...
+ # <!-- </legalnotice> mode = 4
+ # <!-- </bookinfo> mode = 3
+ # <!-- ENDFRONTTAG -->
+ #
+ # ...doco...
+
+ # I know that some of the if statements in this while loop are in a funny
+ # order, but that is deliberate...
+ while(<INPUT>){
+ if($mode > 0){
+ s/<!-- //;
+ s/ -->//;
+ s/<docinfo>//i;
+ s<\/docinfo>//i;
+ s/^[ \t]*//i;
+ }
+
+ if($mode == 2){
+ if(/<para>/i){
+ }
+ elsif(/<\/para>/i){
+ $front = "$front.\\\" \n";
+ }
+ elsif(/<\/legalnotice>/i){
+ $mode = 4;
+ }
+ elsif(/^[ \t]*$/){
+ }
+ else{
+ $front = "$front.\\\" $_";
+ }
+ }
+
+ if($mode == 1){
+ if(/<title>(.*)<\/title>/i){
+ $front = "$front.\\\" This documentation was generated from the book titled \"$1\", which is part of the Linux kernel source.\n.\\\" \n";
+ }
+ elsif(/<legalnotice>/i){
+ $front = "$front.\\\" This documentation comes with the following legal notice:\n.\\\" \n";
+ $mode = 2;
+ }
+
+ elsif(/<author>/i){
+ $front = "$front.\\\" Documentation by: ";
+ }
+ elsif(/<firstname>(.*)<\/firstname>/i){
+ $front = "$front$1 ";
+ }
+ elsif(/<surname>(.*)<\/surname>/i){
+ $front = "$front$1 ";
+ }
+ elsif(/<email>(.*)<\/email>/i){
+ $front = "$front($1)";
+ }
+ elsif(/\/author>/i){
+ $front = "$front\n";
+ }
+
+ elsif(/<copyright>/i){
+ $front = "$front.\\\" Documentation copyright: ";
+ }
+ elsif(/<holder>(.*)<\/holder>/i){
+ $front = "$front$1 ";
+ }
+ elsif(/<year>(.*)<\/year>/i){
+ $front = "$front$1 ";
+ }
+ elsif(/\/copyright>/i){
+ $front = "$front\n";
+ }
+
+ elsif(/^[ \t]*$/
+ || /<affiliation>/i
+ || /<\/affiliation>/i
+ || /<address>/i
+ || /<\/address>/i
+ || /<authorgroup>/i
+ || /<\/authorgroup>/i
+ || /<\/legalnotice>/i
+ || /<date>/i
+ || /<\/date>/i
+ || /<edition>/i
+ || /<\/edition>/i
+ || /<pubdate>/i
+ || /<\/pubdate>/i){
+ }
+ else{
+ print "Unknown tag in manpage conversion: $_";
+ }
+ }
+
+ if($mode == 0){
+ if(/<bookinfo>/i){
+ $mode = 1;
+ }
+ }
+
+ if($mode == 4){
+ if(/<\/bookinfo>/i){
+ $mode = 3;
+ }
+ }
+ }
+ close INPUT;
+
+ system("cd $ARGV[1]; docbook2man $filename.sgml; mv $filename.9 $tmpdir/$$.9\n");
+ open GENERATED, "< $tmpdir/$$.9";
+ open OUTPUT, "> $ARGV[1]/$filename.9";
+
+ print OUTPUT "$front";
+ print OUTPUT ".\\\" For comments on the formatting of this manpage, please contact Michael Still <mikal\@stillhq.com>\n\n";
+ while(<GENERATED>){
+ print OUTPUT "$_";
+ }
+ close OUTPUT;
+ close GENERATED;
+
+ system("gzip -f $ARGV[1]/$filename.9\n");
+ unlink("$tmpdir/$$.9");
+ }
+}
+elsif($ARGV[0] eq "install"){
+ system("mkdir -p /usr/local/man/man9/; install $ARGV[1]/*.9.gz /usr/local/man/man9/");
+}
+else{
+ die "Usage: makeman [convert | install] <dir> <file>\n";
+}
+
+print "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 @@
+TARGET=$1
+ARCH=$2
+SMP=$3
+CC=$4
+
+# If compile.h exists already and we don't own autoconf.h
+# (i.e. we're not the same user who did make *config), don't
+# modify compile.h
+# So "sudo make install" won't change the "compiled by <user>"
+# do "compiled by root"
+
+if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then
+ echo " SKIPPED $TARGET"
+ exit 0
+fi
+
+# Do not expand names
+set -f
+
+if [ -r .version ]; then
+ VERSION=`cat .version`
+else
+ VERSION=0
+ echo 0 > .version
+fi
+
+
+UTS_VERSION="#$VERSION"
+if [ -n "$SMP" ] ; then UTS_VERSION="$UTS_VERSION SMP"; fi
+UTS_VERSION="$UTS_VERSION `LC_ALL=C LANG=C date`"
+
+# Truncate to maximum length
+
+UTS_LEN=64
+UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
+
+# Generate a temporary compile.h
+
+( echo /\* This file is auto generated, version $VERSION \*/
+
+ echo \#define UTS_MACHINE \"$ARCH\"
+
+ echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"
+
+ echo \#define LINUX_COMPILE_TIME \"`LC_ALL=C LANG=C date +%T`\"
+ echo \#define LINUX_COMPILE_BY \"`whoami`\"
+ echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
+
+ if [ -x /bin/dnsdomainname ]; then
+ echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname | $UTS_TRUNCATE`\"
+ elif [ -x /bin/domainname ]; then
+ echo \#define LINUX_COMPILE_DOMAIN \"`domainname | $UTS_TRUNCATE`\"
+ else
+ echo \#define LINUX_COMPILE_DOMAIN
+ fi
+
+ echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\"
+) > .tmpcompile
+
+# Only replace the real compile.h if the new one is different,
+# in order to preserve the timestamp and avoid unnecessary
+# recompilations.
+# We don't consider the file changed if only the date/time changed.
+# A kernel config change will increase the generation number, thus
+# causing compile.h to be updated (including date/time) due to the
+# changed comment in the
+# first line.
+
+if [ -r $TARGET ] && \
+ grep -v 'UTS_VERSION\|LINUX_COMPILE_TIME' $TARGET > .tmpver.1 && \
+ grep -v 'UTS_VERSION\|LINUX_COMPILE_TIME' .tmpcompile > .tmpver.2 && \
+ cmp -s .tmpver.1 .tmpver.2; then
+ rm -f .tmpcompile
+else
+ echo " UPD $TARGET"
+ mv -f .tmpcompile $TARGET
+fi
+rm -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 @@
+#!/bin/sh
+# Generates a small Makefile used in the root of the output
+# directory, to allow make to be started from there.
+# The Makefile also allow for more convinient build of external modules
+
+# Usage
+# $1 - Kernel src directory
+# $2 - Output directory
+# $3 - version
+# $4 - patchlevel
+
+
+cat << EOF
+# Automatically generated by $0: don't edit
+
+VERSION = $3
+PATCHLEVEL = $4
+
+KERNELSRC := $1
+KERNELOUTPUT := $2
+
+MAKEFLAGS += --no-print-directory
+
+all:
+ \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT)
+
+%::
+ \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@
+
+EOF
+
diff --git a/scripts/mksysmap b/scripts/mksysmap
new file mode 100644
index 000000000000..a6430e05972d
--- /dev/null
+++ b/scripts/mksysmap
@@ -0,0 +1,44 @@
+#!/bin/sh -x
+# Based on the vmlinux file create the System.map file
+# System.map is used by module-init tools and some debugging
+# tools to retreive the actual addresses of symbols in the kernel.
+#
+# Usage
+# mksysmap vmlinux System.map
+
+
+#####
+# Generate System.map (actual filename passed as second argument)
+
+# $NM produces the following output:
+# f0081e80 T alloc_vfsmnt
+
+# The second row specify the type of the symbol:
+# A = Absolute
+# B = Uninitialised data (.bss)
+# C = Comon symbol
+# D = Initialised data
+# G = Initialised data for small objects
+# I = Indirect reference to another symbol
+# N = Debugging symbol
+# R = Read only
+# S = Uninitialised data for small objects
+# T = Text code symbol
+# U = Undefined symbol
+# V = Weak symbol
+# W = Weak symbol
+# Corresponding small letters are local symbols
+
+# For System.map filter away:
+# a - local absolute symbols
+# U - undefined global symbols
+# w - local weak symbols
+
+# readprofile starts reading symbols when _stext is found, and
+# continue until it finds a symbol which is not either of 'T', 't',
+# 'W' or 'w'. __crc_ are 'A' and placed in the middle
+# so we just ignore them to let readprofile continue to work.
+# (At least sparc64 has __crc_ in the middle).
+
+$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2
+
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 @@
+#!/bin/bash
+
+#
+# Build U-Boot image when `mkimage' tool is available.
+#
+
+MKIMAGE=$(type -path mkimage)
+
+if [ -z "${MKIMAGE}" ]; then
+ # Doesn't exist
+ echo '"mkimage" command not found - U-Boot images will not be built' >&2
+ exit 0;
+fi
+
+# Call "mkimage" to create U-Boot image
+${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 @@
+if [ ! -f .version ]
+then
+ echo 1
+else
+ expr 0`cat .version` + 1
+fi
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 @@
+hostprogs-y := modpost mk_elfconfig
+always := $(hostprogs-y) empty.o
+
+modpost-objs := modpost.o file2alias.o sumversion.o
+
+# dependencies on generated files need to be listed explicitly
+
+$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h
+
+quiet_cmd_elfconfig = MKELF $@
+ cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
+
+$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
+ $(call if_changed,elfconfig)
+
+targets += 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 @@
+/* Simple code to turn various tables in an ELF file into alias definitions.
+ * This deals with kernel datastructures where they should be
+ * dealt with: in the kernel source.
+ *
+ * Copyright 2002-2003 Rusty Russell, IBM Corporation
+ * 2003 Kai Germaschewski
+ *
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#include "modpost.h"
+
+/* We use the ELF typedefs for kernel_ulong_t but bite the bullet and
+ * use either stdint.h or inttypes.h for the rest. */
+#if KERNEL_ELFCLASS == ELFCLASS32
+typedef Elf32_Addr kernel_ulong_t;
+#else
+typedef Elf64_Addr kernel_ulong_t;
+#endif
+#ifdef __sun__
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+typedef uint32_t __u32;
+typedef uint16_t __u16;
+typedef unsigned char __u8;
+
+/* Big exception to the "don't include kernel headers into userspace, which
+ * even potentially has different endianness and word sizes, since
+ * we handle those differences explicitly below */
+#include "../../include/linux/mod_devicetable.h"
+
+#define ADD(str, sep, cond, field) \
+do { \
+ strcat(str, sep); \
+ if (cond) \
+ sprintf(str + strlen(str), \
+ sizeof(field) == 1 ? "%02X" : \
+ sizeof(field) == 2 ? "%04X" : \
+ sizeof(field) == 4 ? "%08X" : "", \
+ field); \
+ else \
+ sprintf(str + strlen(str), "*"); \
+} while(0)
+
+/* Looks like "usb:vNpNdlNdhNdcNdscNdpNicNiscNipN" */
+static int do_usb_entry(const char *filename,
+ struct usb_device_id *id, char *alias)
+{
+ id->match_flags = TO_NATIVE(id->match_flags);
+ id->idVendor = TO_NATIVE(id->idVendor);
+ id->idProduct = TO_NATIVE(id->idProduct);
+ id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo);
+ id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi);
+
+ /*
+ * Some modules (visor) have empty slots as placeholder for
+ * run-time specification that results in catch-all alias
+ */
+ if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
+ return 1;
+
+ strcpy(alias, "usb:");
+ ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
+ id->idVendor);
+ ADD(alias, "p", id->match_flags&USB_DEVICE_ID_MATCH_PRODUCT,
+ id->idProduct);
+ ADD(alias, "dl", id->match_flags&USB_DEVICE_ID_MATCH_DEV_LO,
+ id->bcdDevice_lo);
+ ADD(alias, "dh", id->match_flags&USB_DEVICE_ID_MATCH_DEV_HI,
+ id->bcdDevice_hi);
+ ADD(alias, "dc", id->match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS,
+ id->bDeviceClass);
+ ADD(alias, "dsc",
+ id->match_flags&USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
+ id->bDeviceSubClass);
+ ADD(alias, "dp",
+ id->match_flags&USB_DEVICE_ID_MATCH_DEV_PROTOCOL,
+ id->bDeviceProtocol);
+ ADD(alias, "ic",
+ id->match_flags&USB_DEVICE_ID_MATCH_INT_CLASS,
+ id->bInterfaceClass);
+ ADD(alias, "isc",
+ id->match_flags&USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+ id->bInterfaceSubClass);
+ ADD(alias, "ip",
+ id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
+ id->bInterfaceProtocol);
+ return 1;
+}
+
+/* Looks like: ieee1394:venNmoNspNverN */
+static int do_ieee1394_entry(const char *filename,
+ struct ieee1394_device_id *id, char *alias)
+{
+ id->match_flags = TO_NATIVE(id->match_flags);
+ id->vendor_id = TO_NATIVE(id->vendor_id);
+ id->model_id = TO_NATIVE(id->model_id);
+ id->specifier_id = TO_NATIVE(id->specifier_id);
+ id->version = TO_NATIVE(id->version);
+
+ strcpy(alias, "ieee1394:");
+ ADD(alias, "ven", id->match_flags & IEEE1394_MATCH_VENDOR_ID,
+ id->vendor_id);
+ ADD(alias, "mo", id->match_flags & IEEE1394_MATCH_MODEL_ID,
+ id->model_id);
+ ADD(alias, "sp", id->match_flags & IEEE1394_MATCH_SPECIFIER_ID,
+ id->specifier_id);
+ ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION,
+ id->version);
+
+ return 1;
+}
+
+/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
+static int do_pci_entry(const char *filename,
+ struct pci_device_id *id, char *alias)
+{
+ /* Class field can be divided into these three. */
+ unsigned char baseclass, subclass, interface,
+ baseclass_mask, subclass_mask, interface_mask;
+
+ id->vendor = TO_NATIVE(id->vendor);
+ id->device = TO_NATIVE(id->device);
+ id->subvendor = TO_NATIVE(id->subvendor);
+ id->subdevice = TO_NATIVE(id->subdevice);
+ id->class = TO_NATIVE(id->class);
+ id->class_mask = TO_NATIVE(id->class_mask);
+
+ strcpy(alias, "pci:");
+ ADD(alias, "v", id->vendor != PCI_ANY_ID, id->vendor);
+ ADD(alias, "d", id->device != PCI_ANY_ID, id->device);
+ ADD(alias, "sv", id->subvendor != PCI_ANY_ID, id->subvendor);
+ ADD(alias, "sd", id->subdevice != PCI_ANY_ID, id->subdevice);
+
+ baseclass = (id->class) >> 16;
+ baseclass_mask = (id->class_mask) >> 16;
+ subclass = (id->class) >> 8;
+ subclass_mask = (id->class_mask) >> 8;
+ interface = id->class;
+ interface_mask = id->class_mask;
+
+ if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
+ || (subclass_mask != 0 && subclass_mask != 0xFF)
+ || (interface_mask != 0 && interface_mask != 0xFF)) {
+ fprintf(stderr,
+ "*** Warning: Can't handle masks in %s:%04X\n",
+ filename, id->class_mask);
+ return 0;
+ }
+
+ ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
+ ADD(alias, "sc", subclass_mask == 0xFF, subclass);
+ ADD(alias, "i", interface_mask == 0xFF, interface);
+ return 1;
+}
+
+/* looks like: "ccw:tNmNdtNdmN" */
+static int do_ccw_entry(const char *filename,
+ struct ccw_device_id *id, char *alias)
+{
+ id->match_flags = TO_NATIVE(id->match_flags);
+ id->cu_type = TO_NATIVE(id->cu_type);
+ id->cu_model = TO_NATIVE(id->cu_model);
+ id->dev_type = TO_NATIVE(id->dev_type);
+ id->dev_model = TO_NATIVE(id->dev_model);
+
+ strcpy(alias, "ccw:");
+ ADD(alias, "t", id->match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE,
+ id->cu_type);
+ ADD(alias, "m", id->match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL,
+ id->cu_model);
+ ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE,
+ id->dev_type);
+ ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE,
+ id->dev_model);
+ return 1;
+}
+
+/* Looks like: "serio:tyNprNidNexN" */
+static int do_serio_entry(const char *filename,
+ struct serio_device_id *id, char *alias)
+{
+ id->type = TO_NATIVE(id->type);
+ id->proto = TO_NATIVE(id->proto);
+ id->id = TO_NATIVE(id->id);
+ id->extra = TO_NATIVE(id->extra);
+
+ strcpy(alias, "serio:");
+ ADD(alias, "ty", id->type != SERIO_ANY, id->type);
+ ADD(alias, "pr", id->proto != SERIO_ANY, id->proto);
+ ADD(alias, "id", id->id != SERIO_ANY, id->id);
+ ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
+
+ return 1;
+}
+
+/* looks like: "pnp:dD" */
+static int do_pnp_entry(const char *filename,
+ struct pnp_device_id *id, char *alias)
+{
+ sprintf(alias, "pnp:d%s", id->id);
+ return 1;
+}
+
+/* looks like: "pnp:cCdD..." */
+static int do_pnp_card_entry(const char *filename,
+ struct pnp_card_device_id *id, char *alias)
+{
+ int i;
+
+ sprintf(alias, "pnp:c%s", id->id);
+ for (i = 0; i < PNP_MAX_DEVICES; i++) {
+ if (! *id->devs[i].id)
+ break;
+ sprintf(alias + strlen(alias), "d%s", id->devs[i].id);
+ }
+ return 1;
+}
+
+/* Ignore any prefix, eg. v850 prepends _ */
+static inline int sym_is(const char *symbol, const char *name)
+{
+ const char *match;
+
+ match = strstr(symbol, name);
+ if (!match)
+ return 0;
+ return match[strlen(symbol)] == '\0';
+}
+
+static void do_table(void *symval, unsigned long size,
+ unsigned long id_size,
+ void *function,
+ struct module *mod)
+{
+ unsigned int i;
+ char alias[500];
+ int (*do_entry)(const char *, void *entry, char *alias) = function;
+
+ if (size % id_size || size < id_size) {
+ fprintf(stderr, "*** Warning: %s ids %lu bad size "
+ "(each on %lu)\n", mod->name, size, id_size);
+ }
+ /* Leave last one: it's the terminator. */
+ size -= id_size;
+
+ for (i = 0; i < size; i += id_size) {
+ if (do_entry(mod->name, symval+i, alias)) {
+ /* Always end in a wildcard, for future extension */
+ if (alias[strlen(alias)-1] != '*')
+ strcat(alias, "*");
+ buf_printf(&mod->dev_table_buf,
+ "MODULE_ALIAS(\"%s\");\n", alias);
+ }
+ }
+}
+
+/* Create MODULE_ALIAS() statements.
+ * At this time, we cannot write the actual output C source yet,
+ * so we write into the mod->dev_table_buf buffer. */
+void handle_moddevtable(struct module *mod, struct elf_info *info,
+ Elf_Sym *sym, const char *symname)
+{
+ void *symval;
+
+ /* We're looking for a section relative symbol */
+ if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
+ return;
+
+ symval = (void *)info->hdr
+ + info->sechdrs[sym->st_shndx].sh_offset
+ + sym->st_value;
+
+ if (sym_is(symname, "__mod_pci_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct pci_device_id),
+ do_pci_entry, mod);
+ else if (sym_is(symname, "__mod_usb_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct usb_device_id),
+ do_usb_entry, mod);
+ else if (sym_is(symname, "__mod_ieee1394_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id),
+ do_ieee1394_entry, mod);
+ else if (sym_is(symname, "__mod_ccw_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct ccw_device_id),
+ do_ccw_entry, mod);
+ else if (sym_is(symname, "__mod_serio_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct serio_device_id),
+ do_serio_entry, mod);
+ else if (sym_is(symname, "__mod_pnp_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct pnp_device_id),
+ do_pnp_entry, mod);
+ else if (sym_is(symname, "__mod_pnp_card_device_table"))
+ do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),
+ do_pnp_card_entry, mod);
+}
+
+/* Now add out buffered information to the generated C source */
+void add_moddevtable(struct buffer *buf, struct module *mod)
+{
+ buf_printf(buf, "\n");
+ buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
+ free(mod->dev_table_buf.p);
+}
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 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <elf.h>
+
+int
+main(int argc, char **argv)
+{
+ unsigned char ei[EI_NIDENT];
+ union { short s; char c[2]; } endian_test;
+
+ if (argc != 2) {
+ fprintf(stderr, "Error: no arch\n");
+ }
+ if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
+ fprintf(stderr, "Error: input truncated\n");
+ return 1;
+ }
+ if (memcmp(ei, ELFMAG, SELFMAG) != 0) {
+ fprintf(stderr, "Error: not ELF\n");
+ return 1;
+ }
+ switch (ei[EI_CLASS]) {
+ case ELFCLASS32:
+ printf("#define KERNEL_ELFCLASS ELFCLASS32\n");
+ break;
+ case ELFCLASS64:
+ printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
+ break;
+ default:
+ abort();
+ }
+ switch (ei[EI_DATA]) {
+ case ELFDATA2LSB:
+ printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
+ break;
+ case ELFDATA2MSB:
+ printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
+ break;
+ default:
+ abort();
+ }
+
+ if (sizeof(unsigned long) == 4) {
+ printf("#define HOST_ELFCLASS ELFCLASS32\n");
+ } else if (sizeof(unsigned long) == 8) {
+ printf("#define HOST_ELFCLASS ELFCLASS64\n");
+ }
+
+ endian_test.s = 0x0102;
+ if (memcmp(endian_test.c, "\x01\x02", 2) == 0)
+ printf("#define HOST_ELFDATA ELFDATA2MSB\n");
+ else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
+ printf("#define HOST_ELFDATA ELFDATA2LSB\n");
+ else
+ abort();
+
+ if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
+ printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
+ else
+ printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
+
+ return 0;
+}
+
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 @@
+/* Postprocess module symbol versions
+ *
+ * Copyright 2003 Kai Germaschewski
+ * Copyright 2002-2004 Rusty Russell, IBM Corporation
+ *
+ * Based in part on module-init-tools/depmod.c,file2alias
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Usage: modpost vmlinux module1.o module2.o ...
+ */
+
+#include <ctype.h>
+#include "modpost.h"
+
+/* Are we using CONFIG_MODVERSIONS? */
+int modversions = 0;
+/* Warn about undefined symbols? (do so if we have vmlinux) */
+int have_vmlinux = 0;
+/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
+static int all_versions = 0;
+
+void
+fatal(const char *fmt, ...)
+{
+ va_list arglist;
+
+ fprintf(stderr, "FATAL: ");
+
+ va_start(arglist, fmt);
+ vfprintf(stderr, fmt, arglist);
+ va_end(arglist);
+
+ exit(1);
+}
+
+void
+warn(const char *fmt, ...)
+{
+ va_list arglist;
+
+ fprintf(stderr, "WARNING: ");
+
+ va_start(arglist, fmt);
+ vfprintf(stderr, fmt, arglist);
+ va_end(arglist);
+}
+
+void *do_nofail(void *ptr, const char *expr)
+{
+ if (!ptr) {
+ fatal("modpost: Memory allocation failure: %s.\n", expr);
+ }
+ return ptr;
+}
+
+/* A list of all modules we processed */
+
+static struct module *modules;
+
+struct module *
+find_module(char *modname)
+{
+ struct module *mod;
+
+ for (mod = modules; mod; mod = mod->next)
+ if (strcmp(mod->name, modname) == 0)
+ break;
+ return mod;
+}
+
+struct module *
+new_module(char *modname)
+{
+ struct module *mod;
+ char *p, *s;
+
+ mod = NOFAIL(malloc(sizeof(*mod)));
+ memset(mod, 0, sizeof(*mod));
+ p = NOFAIL(strdup(modname));
+
+ /* strip trailing .o */
+ if ((s = strrchr(p, '.')) != NULL)
+ if (strcmp(s, ".o") == 0)
+ *s = '\0';
+
+ /* add to list */
+ mod->name = p;
+ mod->next = modules;
+ modules = mod;
+
+ return mod;
+}
+
+/* A hash of all exported symbols,
+ * struct symbol is also used for lists of unresolved symbols */
+
+#define SYMBOL_HASH_SIZE 1024
+
+struct symbol {
+ struct symbol *next;
+ struct module *module;
+ unsigned int crc;
+ int crc_valid;
+ unsigned int weak:1;
+ char name[0];
+};
+
+static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
+
+/* This is based on the hash agorithm from gdbm, via tdb */
+static inline unsigned int tdb_hash(const char *name)
+{
+ unsigned value; /* Used to compute the hash value. */
+ unsigned i; /* Used to cycle through random values. */
+
+ /* Set the initial value from the key size. */
+ for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
+ value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
+
+ return (1103515243 * value + 12345);
+}
+
+/* Allocate a new symbols for use in the hash of exported symbols or
+ * the list of unresolved symbols per module */
+
+struct symbol *
+alloc_symbol(const char *name, unsigned int weak, struct symbol *next)
+{
+ struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
+
+ memset(s, 0, sizeof(*s));
+ strcpy(s->name, name);
+ s->weak = weak;
+ s->next = next;
+ return s;
+}
+
+/* For the hash of exported symbols */
+
+void
+new_symbol(const char *name, struct module *module, unsigned int *crc)
+{
+ unsigned int hash;
+ struct symbol *new;
+
+ hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
+ new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
+ new->module = module;
+ if (crc) {
+ new->crc = *crc;
+ new->crc_valid = 1;
+ }
+}
+
+struct symbol *
+find_symbol(const char *name)
+{
+ struct symbol *s;
+
+ /* For our purposes, .foo matches foo. PPC64 needs this. */
+ if (name[0] == '.')
+ name++;
+
+ for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
+ if (strcmp(s->name, name) == 0)
+ return s;
+ }
+ return NULL;
+}
+
+/* Add an exported symbol - it may have already been added without a
+ * CRC, in this case just update the CRC */
+void
+add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
+{
+ struct symbol *s = find_symbol(name);
+
+ if (!s) {
+ new_symbol(name, module, crc);
+ return;
+ }
+ if (crc) {
+ s->crc = *crc;
+ s->crc_valid = 1;
+ }
+}
+
+void *
+grab_file(const char *filename, unsigned long *size)
+{
+ struct stat st;
+ void *map;
+ int fd;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0 || fstat(fd, &st) != 0)
+ return NULL;
+
+ *size = st.st_size;
+ map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ close(fd);
+
+ if (map == MAP_FAILED)
+ return NULL;
+ return map;
+}
+
+/*
+ Return a copy of the next line in a mmap'ed file.
+ spaces in the beginning of the line is trimmed away.
+ Return a pointer to a static buffer.
+*/
+char*
+get_next_line(unsigned long *pos, void *file, unsigned long size)
+{
+ static char line[4096];
+ int skip = 1;
+ size_t len = 0;
+ signed char *p = (signed char *)file + *pos;
+ char *s = line;
+
+ for (; *pos < size ; (*pos)++)
+ {
+ if (skip && isspace(*p)) {
+ p++;
+ continue;
+ }
+ skip = 0;
+ if (*p != '\n' && (*pos < size)) {
+ len++;
+ *s++ = *p++;
+ if (len > 4095)
+ break; /* Too long, stop */
+ } else {
+ /* End of string */
+ *s = '\0';
+ return line;
+ }
+ }
+ /* End of buffer */
+ return NULL;
+}
+
+void
+release_file(void *file, unsigned long size)
+{
+ munmap(file, size);
+}
+
+void
+parse_elf(struct elf_info *info, const char *filename)
+{
+ unsigned int i;
+ Elf_Ehdr *hdr = info->hdr;
+ Elf_Shdr *sechdrs;
+ Elf_Sym *sym;
+
+ hdr = grab_file(filename, &info->size);
+ if (!hdr) {
+ perror(filename);
+ abort();
+ }
+ info->hdr = hdr;
+ if (info->size < sizeof(*hdr))
+ goto truncated;
+
+ /* Fix endianness in ELF header */
+ hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
+ hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
+ hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
+ hdr->e_machine = TO_NATIVE(hdr->e_machine);
+ sechdrs = (void *)hdr + hdr->e_shoff;
+ info->sechdrs = sechdrs;
+
+ /* Fix endianness in section headers */
+ for (i = 0; i < hdr->e_shnum; i++) {
+ sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
+ sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
+ sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
+ sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
+ sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
+ }
+ /* Find symbol table. */
+ for (i = 1; i < hdr->e_shnum; i++) {
+ const char *secstrings
+ = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ if (sechdrs[i].sh_offset > info->size)
+ goto truncated;
+ if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) {
+ info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
+ info->modinfo_len = sechdrs[i].sh_size;
+ }
+ if (sechdrs[i].sh_type != SHT_SYMTAB)
+ continue;
+
+ info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
+ info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
+ + sechdrs[i].sh_size;
+ info->strtab = (void *)hdr +
+ sechdrs[sechdrs[i].sh_link].sh_offset;
+ }
+ if (!info->symtab_start) {
+ fprintf(stderr, "modpost: %s no symtab?\n", filename);
+ abort();
+ }
+ /* Fix endianness in symbols */
+ for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
+ sym->st_shndx = TO_NATIVE(sym->st_shndx);
+ sym->st_name = TO_NATIVE(sym->st_name);
+ sym->st_value = TO_NATIVE(sym->st_value);
+ sym->st_size = TO_NATIVE(sym->st_size);
+ }
+ return;
+
+ truncated:
+ fprintf(stderr, "modpost: %s is truncated.\n", filename);
+ abort();
+}
+
+void
+parse_elf_finish(struct elf_info *info)
+{
+ release_file(info->hdr, info->size);
+}
+
+#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
+#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
+
+void
+handle_modversions(struct module *mod, struct elf_info *info,
+ Elf_Sym *sym, const char *symname)
+{
+ unsigned int crc;
+
+ switch (sym->st_shndx) {
+ case SHN_COMMON:
+ fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n",
+ symname, mod->name);
+ break;
+ case SHN_ABS:
+ /* CRC'd symbol */
+ if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
+ crc = (unsigned int) sym->st_value;
+ add_exported_symbol(symname + strlen(CRC_PFX),
+ mod, &crc);
+ }
+ break;
+ case SHN_UNDEF:
+ /* undefined symbol */
+ if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
+ ELF_ST_BIND(sym->st_info) != STB_WEAK)
+ break;
+ /* ignore global offset table */
+ if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* ignore __this_module, it will be resolved shortly */
+ if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
+ break;
+#ifdef STT_REGISTER
+ if (info->hdr->e_machine == EM_SPARC ||
+ info->hdr->e_machine == EM_SPARCV9) {
+ /* Ignore register directives. */
+ if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER)
+ break;
+ }
+#endif
+
+ if (memcmp(symname, MODULE_SYMBOL_PREFIX,
+ strlen(MODULE_SYMBOL_PREFIX)) == 0)
+ mod->unres = alloc_symbol(symname +
+ strlen(MODULE_SYMBOL_PREFIX),
+ ELF_ST_BIND(sym->st_info) == STB_WEAK,
+ mod->unres);
+ break;
+ default:
+ /* All exported symbols */
+ if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
+ add_exported_symbol(symname + strlen(KSYMTAB_PFX),
+ mod, NULL);
+ }
+ if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
+ mod->has_init = 1;
+ if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
+ mod->has_cleanup = 1;
+ break;
+ }
+}
+
+int
+is_vmlinux(const char *modname)
+{
+ const char *myname;
+
+ if ((myname = strrchr(modname, '/')))
+ myname++;
+ else
+ myname = modname;
+
+ return strcmp(myname, "vmlinux") == 0;
+}
+
+/* Parse tag=value strings from .modinfo section */
+static char *next_string(char *string, unsigned long *secsize)
+{
+ /* Skip non-zero chars */
+ while (string[0]) {
+ string++;
+ if ((*secsize)-- <= 1)
+ return NULL;
+ }
+
+ /* Skip any zero padding. */
+ while (!string[0]) {
+ string++;
+ if ((*secsize)-- <= 1)
+ return NULL;
+ }
+ return string;
+}
+
+static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
+ const char *tag)
+{
+ char *p;
+ unsigned int taglen = strlen(tag);
+ unsigned long size = modinfo_len;
+
+ for (p = modinfo; p; p = next_string(p, &size)) {
+ if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
+ return p + taglen + 1;
+ }
+ return NULL;
+}
+
+void
+read_symbols(char *modname)
+{
+ const char *symname;
+ char *version;
+ struct module *mod;
+ struct elf_info info = { };
+ Elf_Sym *sym;
+
+ parse_elf(&info, modname);
+
+ mod = new_module(modname);
+
+ /* When there's no vmlinux, don't print warnings about
+ * unresolved symbols (since there'll be too many ;) */
+ if (is_vmlinux(modname)) {
+ unsigned int fake_crc = 0;
+ have_vmlinux = 1;
+ add_exported_symbol("struct_module", mod, &fake_crc);
+ mod->skip = 1;
+ }
+
+ for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
+ symname = info.strtab + sym->st_name;
+
+ handle_modversions(mod, &info, sym, symname);
+ handle_moddevtable(mod, &info, sym, symname);
+ }
+
+ version = get_modinfo(info.modinfo, info.modinfo_len, "version");
+ if (version)
+ maybe_frob_rcs_version(modname, version, info.modinfo,
+ version - (char *)info.hdr);
+ if (version || (all_versions && !is_vmlinux(modname)))
+ get_src_version(modname, mod->srcversion,
+ sizeof(mod->srcversion)-1);
+
+ parse_elf_finish(&info);
+
+ /* Our trick to get versioning for struct_module - it's
+ * never passed as an argument to an exported function, so
+ * the automatic versioning doesn't pick it up, but it's really
+ * important anyhow */
+ if (modversions)
+ mod->unres = alloc_symbol("struct_module", 0, mod->unres);
+}
+
+#define SZ 500
+
+/* We first write the generated file into memory using the
+ * following helper, then compare to the file on disk and
+ * only update the later if anything changed */
+
+void __attribute__((format(printf, 2, 3)))
+buf_printf(struct buffer *buf, const char *fmt, ...)
+{
+ char tmp[SZ];
+ int len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ len = vsnprintf(tmp, SZ, fmt, ap);
+ if (buf->size - buf->pos < len + 1) {
+ buf->size += 128;
+ buf->p = realloc(buf->p, buf->size);
+ }
+ strncpy(buf->p + buf->pos, tmp, len + 1);
+ buf->pos += len;
+ va_end(ap);
+}
+
+void
+buf_write(struct buffer *buf, const char *s, int len)
+{
+ if (buf->size - buf->pos < len) {
+ buf->size += len;
+ buf->p = realloc(buf->p, buf->size);
+ }
+ strncpy(buf->p + buf->pos, s, len);
+ buf->pos += len;
+}
+
+/* Header for the generated file */
+
+void
+add_header(struct buffer *b, struct module *mod)
+{
+ buf_printf(b, "#include <linux/module.h>\n");
+ buf_printf(b, "#include <linux/vermagic.h>\n");
+ buf_printf(b, "#include <linux/compiler.h>\n");
+ buf_printf(b, "\n");
+ buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
+ buf_printf(b, "\n");
+ buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */
+ buf_printf(b, "struct module __this_module\n");
+ buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
+ buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n");
+ if (mod->has_init)
+ buf_printf(b, " .init = init_module,\n");
+ if (mod->has_cleanup)
+ buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
+ " .exit = cleanup_module,\n"
+ "#endif\n");
+ buf_printf(b, "};\n");
+}
+
+/* Record CRCs for unresolved symbols */
+
+void
+add_versions(struct buffer *b, struct module *mod)
+{
+ struct symbol *s, *exp;
+
+ for (s = mod->unres; s; s = s->next) {
+ exp = find_symbol(s->name);
+ if (!exp || exp->module == mod) {
+ if (have_vmlinux && !s->weak)
+ fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
+ "undefined!\n", s->name, mod->name);
+ continue;
+ }
+ s->module = exp->module;
+ s->crc_valid = exp->crc_valid;
+ s->crc = exp->crc;
+ }
+
+ if (!modversions)
+ return;
+
+ buf_printf(b, "\n");
+ buf_printf(b, "static const struct modversion_info ____versions[]\n");
+ buf_printf(b, "__attribute_used__\n");
+ buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
+
+ for (s = mod->unres; s; s = s->next) {
+ if (!s->module) {
+ continue;
+ }
+ if (!s->crc_valid) {
+ fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
+ "has no CRC!\n",
+ s->name, mod->name);
+ continue;
+ }
+ buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
+ }
+
+ buf_printf(b, "};\n");
+}
+
+void
+add_depends(struct buffer *b, struct module *mod, struct module *modules)
+{
+ struct symbol *s;
+ struct module *m;
+ int first = 1;
+
+ for (m = modules; m; m = m->next) {
+ m->seen = is_vmlinux(m->name);
+ }
+
+ buf_printf(b, "\n");
+ buf_printf(b, "static const char __module_depends[]\n");
+ buf_printf(b, "__attribute_used__\n");
+ buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
+ buf_printf(b, "\"depends=");
+ for (s = mod->unres; s; s = s->next) {
+ if (!s->module)
+ continue;
+
+ if (s->module->seen)
+ continue;
+
+ s->module->seen = 1;
+ buf_printf(b, "%s%s", first ? "" : ",",
+ strrchr(s->module->name, '/') + 1);
+ first = 0;
+ }
+ buf_printf(b, "\";\n");
+}
+
+void
+add_srcversion(struct buffer *b, struct module *mod)
+{
+ if (mod->srcversion[0]) {
+ buf_printf(b, "\n");
+ buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
+ mod->srcversion);
+ }
+}
+
+void
+write_if_changed(struct buffer *b, const char *fname)
+{
+ char *tmp;
+ FILE *file;
+ struct stat st;
+
+ file = fopen(fname, "r");
+ if (!file)
+ goto write;
+
+ if (fstat(fileno(file), &st) < 0)
+ goto close_write;
+
+ if (st.st_size != b->pos)
+ goto close_write;
+
+ tmp = NOFAIL(malloc(b->pos));
+ if (fread(tmp, 1, b->pos, file) != b->pos)
+ goto free_write;
+
+ if (memcmp(tmp, b->p, b->pos) != 0)
+ goto free_write;
+
+ free(tmp);
+ fclose(file);
+ return;
+
+ free_write:
+ free(tmp);
+ close_write:
+ fclose(file);
+ write:
+ file = fopen(fname, "w");
+ if (!file) {
+ perror(fname);
+ exit(1);
+ }
+ if (fwrite(b->p, 1, b->pos, file) != b->pos) {
+ perror(fname);
+ exit(1);
+ }
+ fclose(file);
+}
+
+void
+read_dump(const char *fname)
+{
+ unsigned long size, pos = 0;
+ void *file = grab_file(fname, &size);
+ char *line;
+
+ if (!file)
+ /* No symbol versions, silently ignore */
+ return;
+
+ while ((line = get_next_line(&pos, file, size))) {
+ char *symname, *modname, *d;
+ unsigned int crc;
+ struct module *mod;
+
+ if (!(symname = strchr(line, '\t')))
+ goto fail;
+ *symname++ = '\0';
+ if (!(modname = strchr(symname, '\t')))
+ goto fail;
+ *modname++ = '\0';
+ if (strchr(modname, '\t'))
+ goto fail;
+ crc = strtoul(line, &d, 16);
+ if (*symname == '\0' || *modname == '\0' || *d != '\0')
+ goto fail;
+
+ if (!(mod = find_module(modname))) {
+ if (is_vmlinux(modname)) {
+ have_vmlinux = 1;
+ }
+ mod = new_module(NOFAIL(strdup(modname)));
+ mod->skip = 1;
+ }
+ add_exported_symbol(symname, mod, &crc);
+ }
+ return;
+fail:
+ fatal("parse error in symbol dump file\n");
+}
+
+void
+write_dump(const char *fname)
+{
+ struct buffer buf = { };
+ struct symbol *symbol;
+ int n;
+
+ for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
+ symbol = symbolhash[n];
+ while (symbol) {
+ symbol = symbol->next;
+ }
+ }
+
+ for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
+ symbol = symbolhash[n];
+ while (symbol) {
+ buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
+ symbol->name, symbol->module->name);
+ symbol = symbol->next;
+ }
+ }
+ write_if_changed(&buf, fname);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct module *mod;
+ struct buffer buf = { };
+ char fname[SZ];
+ char *dump_read = NULL, *dump_write = NULL;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "i:mo:a")) != -1) {
+ switch(opt) {
+ case 'i':
+ dump_read = optarg;
+ break;
+ case 'm':
+ modversions = 1;
+ break;
+ case 'o':
+ dump_write = optarg;
+ break;
+ case 'a':
+ all_versions = 1;
+ break;
+ default:
+ exit(1);
+ }
+ }
+
+ if (dump_read)
+ read_dump(dump_read);
+
+ while (optind < argc) {
+ read_symbols(argv[optind++]);
+ }
+
+ for (mod = modules; mod; mod = mod->next) {
+ if (mod->skip)
+ continue;
+
+ buf.pos = 0;
+
+ add_header(&buf, mod);
+ add_versions(&buf, mod);
+ add_depends(&buf, mod, modules);
+ add_moddevtable(&buf, mod);
+ add_srcversion(&buf, mod);
+
+ sprintf(fname, "%s.mod.c", mod->name);
+ write_if_changed(&buf, fname);
+ }
+
+ if (dump_write)
+ write_dump(dump_write);
+
+ return 0;
+}
+
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 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+
+#include "elfconfig.h"
+
+#if KERNEL_ELFCLASS == ELFCLASS32
+
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define ELF_ST_BIND ELF32_ST_BIND
+#define ELF_ST_TYPE ELF32_ST_TYPE
+
+#else
+
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define ELF_ST_BIND ELF64_ST_BIND
+#define ELF_ST_TYPE ELF64_ST_TYPE
+
+#endif
+
+#if KERNEL_ELFDATA != HOST_ELFDATA
+
+static inline void __endian(const void *src, void *dest, unsigned int size)
+{
+ unsigned int i;
+ for (i = 0; i < size; i++)
+ ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
+}
+
+
+
+#define TO_NATIVE(x) \
+({ \
+ typeof(x) __x; \
+ __endian(&(x), &(__x), sizeof(__x)); \
+ __x; \
+})
+
+#else /* endianness matches */
+
+#define TO_NATIVE(x) (x)
+
+#endif
+
+#define NOFAIL(ptr) do_nofail((ptr), #ptr)
+void *do_nofail(void *ptr, const char *expr);
+
+struct buffer {
+ char *p;
+ int pos;
+ int size;
+};
+
+void __attribute__((format(printf, 2, 3)))
+buf_printf(struct buffer *buf, const char *fmt, ...);
+
+void
+buf_write(struct buffer *buf, const char *s, int len);
+
+struct module {
+ struct module *next;
+ const char *name;
+ struct symbol *unres;
+ int seen;
+ int skip;
+ int has_init;
+ int has_cleanup;
+ struct buffer dev_table_buf;
+ char srcversion[25];
+};
+
+struct elf_info {
+ unsigned long size;
+ Elf_Ehdr *hdr;
+ Elf_Shdr *sechdrs;
+ Elf_Sym *symtab_start;
+ Elf_Sym *symtab_stop;
+ const char *strtab;
+ char *modinfo;
+ unsigned int modinfo_len;
+};
+
+void handle_moddevtable(struct module *mod, struct elf_info *info,
+ Elf_Sym *sym, const char *symname);
+
+void add_moddevtable(struct buffer *buf, struct module *mod);
+
+void maybe_frob_rcs_version(const char *modfilename,
+ char *version,
+ void *modinfo,
+ unsigned long modinfo_offset);
+void get_src_version(const char *modname, char sum[], unsigned sumlen);
+
+void *grab_file(const char *filename, unsigned long *size);
+char* get_next_line(unsigned long *pos, void *file, unsigned long size);
+void 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 @@
+#include <netinet/in.h>
+#ifdef __sun__
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include "modpost.h"
+
+/*
+ * Stolen form Cryptographic API.
+ *
+ * MD4 Message Digest Algorithm (RFC1320).
+ *
+ * Implementation derived from Andrew Tridgell and Steve French's
+ * CIFS MD4 implementation, and the cryptoapi implementation
+ * originally based on the public domain implementation written
+ * by Colin Plumb in 1993.
+ *
+ * Copyright (c) Andrew Tridgell 1997-1998.
+ * Modified by Steve French (sfrench@us.ibm.com) 2002
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#define MD4_DIGEST_SIZE 16
+#define MD4_HMAC_BLOCK_SIZE 64
+#define MD4_BLOCK_WORDS 16
+#define MD4_HASH_WORDS 4
+
+struct md4_ctx {
+ uint32_t hash[MD4_HASH_WORDS];
+ uint32_t block[MD4_BLOCK_WORDS];
+ uint64_t byte_count;
+};
+
+static inline uint32_t lshift(uint32_t x, unsigned int s)
+{
+ x &= 0xFFFFFFFF;
+ return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
+}
+
+static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z)
+{
+ return (x & y) | ((~x) & z);
+}
+
+static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z)
+{
+ return (x & y) | (x & z) | (y & z);
+}
+
+static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z)
+{
+ return x ^ y ^ z;
+}
+
+#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
+#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (uint32_t)0x5A827999,s))
+#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (uint32_t)0x6ED9EBA1,s))
+
+/* XXX: this stuff can be optimized */
+static inline void le32_to_cpu_array(uint32_t *buf, unsigned int words)
+{
+ while (words--) {
+ *buf = ntohl(*buf);
+ buf++;
+ }
+}
+
+static inline void cpu_to_le32_array(uint32_t *buf, unsigned int words)
+{
+ while (words--) {
+ *buf = htonl(*buf);
+ buf++;
+ }
+}
+
+static void md4_transform(uint32_t *hash, uint32_t const *in)
+{
+ uint32_t a, b, c, d;
+
+ a = hash[0];
+ b = hash[1];
+ c = hash[2];
+ d = hash[3];
+
+ ROUND1(a, b, c, d, in[0], 3);
+ ROUND1(d, a, b, c, in[1], 7);
+ ROUND1(c, d, a, b, in[2], 11);
+ ROUND1(b, c, d, a, in[3], 19);
+ ROUND1(a, b, c, d, in[4], 3);
+ ROUND1(d, a, b, c, in[5], 7);
+ ROUND1(c, d, a, b, in[6], 11);
+ ROUND1(b, c, d, a, in[7], 19);
+ ROUND1(a, b, c, d, in[8], 3);
+ ROUND1(d, a, b, c, in[9], 7);
+ ROUND1(c, d, a, b, in[10], 11);
+ ROUND1(b, c, d, a, in[11], 19);
+ ROUND1(a, b, c, d, in[12], 3);
+ ROUND1(d, a, b, c, in[13], 7);
+ ROUND1(c, d, a, b, in[14], 11);
+ ROUND1(b, c, d, a, in[15], 19);
+
+ ROUND2(a, b, c, d,in[ 0], 3);
+ ROUND2(d, a, b, c, in[4], 5);
+ ROUND2(c, d, a, b, in[8], 9);
+ ROUND2(b, c, d, a, in[12], 13);
+ ROUND2(a, b, c, d, in[1], 3);
+ ROUND2(d, a, b, c, in[5], 5);
+ ROUND2(c, d, a, b, in[9], 9);
+ ROUND2(b, c, d, a, in[13], 13);
+ ROUND2(a, b, c, d, in[2], 3);
+ ROUND2(d, a, b, c, in[6], 5);
+ ROUND2(c, d, a, b, in[10], 9);
+ ROUND2(b, c, d, a, in[14], 13);
+ ROUND2(a, b, c, d, in[3], 3);
+ ROUND2(d, a, b, c, in[7], 5);
+ ROUND2(c, d, a, b, in[11], 9);
+ ROUND2(b, c, d, a, in[15], 13);
+
+ ROUND3(a, b, c, d,in[ 0], 3);
+ ROUND3(d, a, b, c, in[8], 9);
+ ROUND3(c, d, a, b, in[4], 11);
+ ROUND3(b, c, d, a, in[12], 15);
+ ROUND3(a, b, c, d, in[2], 3);
+ ROUND3(d, a, b, c, in[10], 9);
+ ROUND3(c, d, a, b, in[6], 11);
+ ROUND3(b, c, d, a, in[14], 15);
+ ROUND3(a, b, c, d, in[1], 3);
+ ROUND3(d, a, b, c, in[9], 9);
+ ROUND3(c, d, a, b, in[5], 11);
+ ROUND3(b, c, d, a, in[13], 15);
+ ROUND3(a, b, c, d, in[3], 3);
+ ROUND3(d, a, b, c, in[11], 9);
+ ROUND3(c, d, a, b, in[7], 11);
+ ROUND3(b, c, d, a, in[15], 15);
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+}
+
+static inline void md4_transform_helper(struct md4_ctx *ctx)
+{
+ le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(uint32_t));
+ md4_transform(ctx->hash, ctx->block);
+}
+
+static void md4_init(struct md4_ctx *mctx)
+{
+ mctx->hash[0] = 0x67452301;
+ mctx->hash[1] = 0xefcdab89;
+ mctx->hash[2] = 0x98badcfe;
+ mctx->hash[3] = 0x10325476;
+ mctx->byte_count = 0;
+}
+
+static void md4_update(struct md4_ctx *mctx,
+ const unsigned char *data, unsigned int len)
+{
+ const uint32_t avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+ mctx->byte_count += len;
+
+ if (avail > len) {
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, len);
+ return;
+ }
+
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, avail);
+
+ md4_transform_helper(mctx);
+ data += avail;
+ len -= avail;
+
+ while (len >= sizeof(mctx->block)) {
+ memcpy(mctx->block, data, sizeof(mctx->block));
+ md4_transform_helper(mctx);
+ data += sizeof(mctx->block);
+ len -= sizeof(mctx->block);
+ }
+
+ memcpy(mctx->block, data, len);
+}
+
+static void md4_final_ascii(struct md4_ctx *mctx, char *out, unsigned int len)
+{
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (uint64_t));
+ md4_transform_helper(mctx);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = mctx->byte_count << 3;
+ mctx->block[15] = mctx->byte_count >> 29;
+ le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+ sizeof(uint64_t)) / sizeof(uint32_t));
+ md4_transform(mctx->hash, mctx->block);
+ cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(uint32_t));
+
+ snprintf(out, len, "%08X%08X%08X%08X",
+ mctx->hash[0], mctx->hash[1], mctx->hash[2], mctx->hash[3]);
+}
+
+static inline void add_char(unsigned char c, struct md4_ctx *md)
+{
+ md4_update(md, &c, 1);
+}
+
+static int parse_string(const char *file, unsigned long len,
+ struct md4_ctx *md)
+{
+ unsigned long i;
+
+ add_char(file[0], md);
+ for (i = 1; i < len; i++) {
+ add_char(file[i], md);
+ if (file[i] == '"' && file[i-1] != '\\')
+ break;
+ }
+ return i;
+}
+
+static int parse_comment(const char *file, unsigned long len)
+{
+ unsigned long i;
+
+ for (i = 2; i < len; i++) {
+ if (file[i-1] == '*' && file[i] == '/')
+ break;
+ }
+ return i;
+}
+
+/* FIXME: Handle .s files differently (eg. # starts comments) --RR */
+static int parse_file(const signed char *fname, struct md4_ctx *md)
+{
+ signed char *file;
+ unsigned long i, len;
+
+ file = grab_file(fname, &len);
+ if (!file)
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ /* Collapse and ignore \ and CR. */
+ if (file[i] == '\\' && (i+1 < len) && file[i+1] == '\n') {
+ i++;
+ continue;
+ }
+
+ /* Ignore whitespace */
+ if (isspace(file[i]))
+ continue;
+
+ /* Handle strings as whole units */
+ if (file[i] == '"') {
+ i += parse_string(file+i, len - i, md);
+ continue;
+ }
+
+ /* Comments: ignore */
+ if (file[i] == '/' && file[i+1] == '*') {
+ i += parse_comment(file+i, len - i);
+ continue;
+ }
+
+ add_char(file[i], md);
+ }
+ release_file(file, len);
+ return 1;
+}
+
+/* We have dir/file.o. Open dir/.file.o.cmd, look for deps_ line to
+ * figure out source file. */
+static int parse_source_files(const char *objfile, struct md4_ctx *md)
+{
+ char *cmd, *file, *line, *dir;
+ const char *base;
+ unsigned long flen, pos = 0;
+ int dirlen, ret = 0, check_files = 0;
+
+ cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd")));
+
+ base = strrchr(objfile, '/');
+ if (base) {
+ base++;
+ dirlen = base - objfile;
+ sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base);
+ } else {
+ dirlen = 0;
+ sprintf(cmd, ".%s.cmd", objfile);
+ }
+ dir = NOFAIL(malloc(dirlen + 1));
+ strncpy(dir, objfile, dirlen);
+ dir[dirlen] = '\0';
+
+ file = grab_file(cmd, &flen);
+ if (!file) {
+ fprintf(stderr, "Warning: could not find %s for %s\n",
+ cmd, objfile);
+ goto out;
+ }
+
+ /* There will be a line like so:
+ deps_drivers/net/dummy.o := \
+ drivers/net/dummy.c \
+ $(wildcard include/config/net/fastroute.h) \
+ include/linux/config.h \
+ $(wildcard include/config/h.h) \
+ include/linux/module.h \
+
+ Sum all files in the same dir or subdirs.
+ */
+ while ((line = get_next_line(&pos, file, flen)) != NULL) {
+ signed char* p = line;
+ if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) {
+ check_files = 1;
+ continue;
+ }
+ if (!check_files)
+ continue;
+
+ /* Continue until line does not end with '\' */
+ if ( *(p + strlen(p)-1) != '\\')
+ break;
+ /* Terminate line at first space, to get rid of final ' \' */
+ while (*p) {
+ if (isspace(*p)) {
+ *p = '\0';
+ break;
+ }
+ p++;
+ }
+
+ /* Check if this file is in same dir as objfile */
+ if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
+ if (!parse_file(line, md)) {
+ fprintf(stderr,
+ "Warning: could not open %s: %s\n",
+ line, strerror(errno));
+ goto out_file;
+ }
+
+ }
+
+ }
+
+ /* Everyone parsed OK */
+ ret = 1;
+out_file:
+ release_file(file, flen);
+out:
+ free(dir);
+ free(cmd);
+ return ret;
+}
+
+/* Calc and record src checksum. */
+void get_src_version(const char *modname, char sum[], unsigned sumlen)
+{
+ void *file;
+ unsigned long len;
+ struct md4_ctx md;
+ char *sources, *end, *fname;
+ const char *basename;
+ char filelist[strlen(getenv("MODVERDIR")) + strlen("/") +
+ strlen(modname) - strlen(".o") + strlen(".mod") + 1 ];
+
+ /* Source files for module are in .tmp_versions/modname.mod,
+ after the first line. */
+ if (strrchr(modname, '/'))
+ basename = strrchr(modname, '/') + 1;
+ else
+ basename = modname;
+ sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"),
+ (int) strlen(basename) - 2, basename);
+
+ file = grab_file(filelist, &len);
+ if (!file) {
+ fprintf(stderr, "Warning: could not find versions for %s\n",
+ filelist);
+ return;
+ }
+
+ sources = strchr(file, '\n');
+ if (!sources) {
+ fprintf(stderr, "Warning: malformed versions file for %s\n",
+ modname);
+ goto release;
+ }
+
+ sources++;
+ end = strchr(sources, '\n');
+ if (!end) {
+ fprintf(stderr, "Warning: bad ending versions file for %s\n",
+ modname);
+ goto release;
+ }
+ *end = '\0';
+
+ md4_init(&md);
+ while ((fname = strsep(&sources, " ")) != NULL) {
+ if (!*fname)
+ continue;
+ if (!parse_source_files(fname, &md))
+ goto release;
+ }
+
+ md4_final_ascii(&md, sum, sumlen);
+release:
+ release_file(file, len);
+}
+
+static void write_version(const char *filename, const char *sum,
+ unsigned long offset)
+{
+ int fd;
+
+ fd = open(filename, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "Warning: changing sum in %s failed: %s\n",
+ filename, strerror(errno));
+ return;
+ }
+
+ if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
+ fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n",
+ filename, offset, strerror(errno));
+ goto out;
+ }
+
+ if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
+ fprintf(stderr, "Warning: writing sum in %s failed: %s\n",
+ filename, strerror(errno));
+ goto out;
+ }
+out:
+ close(fd);
+}
+
+static int strip_rcs_crap(signed char *version)
+{
+ unsigned int len, full_len;
+
+ if (strncmp(version, "$Revision", strlen("$Revision")) != 0)
+ return 0;
+
+ /* Space for version string follows. */
+ full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2;
+
+ /* Move string to start with version number: prefix will be
+ * $Revision$ or $Revision: */
+ len = strlen("$Revision");
+ if (version[len] == ':' || version[len] == '$')
+ len++;
+ while (isspace(version[len]))
+ len++;
+ memmove(version, version+len, full_len-len);
+ full_len -= len;
+
+ /* Preserve up to next whitespace. */
+ len = 0;
+ while (version[len] && !isspace(version[len]))
+ len++;
+ memmove(version + len, version + strlen(version),
+ full_len - strlen(version));
+ return 1;
+}
+
+/* Clean up RCS-style version numbers. */
+void maybe_frob_rcs_version(const char *modfilename,
+ char *version,
+ void *modinfo,
+ unsigned long version_offset)
+{
+ if (strip_rcs_crap(version))
+ write_version(modfilename, version, version_offset);
+}
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 @@
+#!/usr/bin/perl -w
+#
+# namespace.pl. Mon Aug 30 2004
+#
+# Perform a name space analysis on the linux kernel.
+#
+# Copyright Keith Owens <kaos@ocs.com.au>. GPL.
+#
+# Invoke by changing directory to the top of the kernel object
+# tree then namespace.pl, no parameters.
+#
+# Tuned for 2.1.x kernels with the new module handling, it will
+# work with 2.0 kernels as well.
+#
+# Last change 2.6.9-rc1, adding support for separate source and object
+# trees.
+#
+# The source must be compiled/assembled first, the object files
+# are the primary input to this script. Incomplete or missing
+# objects will result in a flawed analysis. Compile both vmlinux
+# and modules.
+#
+# Even with complete objects, treat the result of the analysis
+# with caution. Some external references are only used by
+# certain architectures, others with certain combinations of
+# configuration parameters. Ideally the source should include
+# something like
+#
+# #ifndef CONFIG_...
+# static
+# #endif
+# symbol_definition;
+#
+# so the symbols are defined as static unless a particular
+# CONFIG_... requires it to be external.
+#
+# A symbol that is suffixed with '(export only)' has these properties
+#
+# * It is global.
+# * It is marked EXPORT_SYMBOL or EXPORT_SYMBOL_GPL, either in the same
+# source file or a different source file.
+# * Given the current .config, nothing uses the symbol.
+#
+# The symbol is a candidate for conversion to static, plus removal of the
+# export. But be careful that a different .config might use the symbol.
+#
+#
+# Name space analysis and cleanup is an iterative process. You cannot
+# expect to find all the problems in a single pass.
+#
+# * Identify possibly unnecessary global declarations, verify that they
+# really are unnecessary and change them to static.
+# * Compile and fix up gcc warnings about static, removing dead symbols
+# as necessary.
+# * make clean and rebuild with different configs (especially
+# CONFIG_MODULES=n) to see which symbols are being defined when the
+# config does not require them. These symbols bloat the kernel object
+# for no good reason, which is frustrating for embedded systems.
+# * Wrap config sensitive symbols in #ifdef CONFIG_foo, as long as the
+# code does not get too ugly.
+# * Repeat the name space analysis until you can live with with the
+# result.
+#
+
+require 5; # at least perl 5
+use strict;
+use File::Find;
+
+my $nm = "/usr/bin/nm -p";
+my $objdump = "/usr/bin/objdump -s -j .comment";
+my $srctree = "";
+my $objtree = "";
+$srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'}));
+$objtree = "$ENV{'objtree'}/" if (exists($ENV{'objtree'}));
+
+if ($#ARGV != -1) {
+ print STDERR "usage: $0 takes no parameters\n";
+ die("giving up\n");
+}
+
+my %nmdata = (); # nm data for each object
+my %def = (); # all definitions for each name
+my %ksymtab = (); # names that appear in __ksymtab_
+my %ref = (); # $ref{$name} exists if there is a true external reference to $name
+my %export = (); # $export{$name} exists if there is an EXPORT_... of $name
+
+&find(\&linux_objects, '.'); # find the objects and do_nm on them
+&list_multiply_defined();
+&resolve_external_references();
+&list_extra_externals();
+
+exit(0);
+
+sub linux_objects
+{
+ # Select objects, ignoring objects which are only created by
+ # merging other objects. Also ignore all of modules, scripts
+ # and compressed. Most conglomerate objects are handled by do_nm,
+ # this list only contains the special cases. These include objects
+ # that are linked from just one other object and objects for which
+ # there is really no permanent source file.
+ my $basename = $_;
+ $_ = $File::Find::name;
+ s:^\./::;
+ if (/.*\.o$/ &&
+ ! (
+ m:/built-in.o$:
+ || m:arch/i386/kernel/vsyscall-syms.o$:
+ || m:arch/ia64/ia32/ia32.o$:
+ || m:arch/ia64/kernel/gate-syms.o$:
+ || m:arch/ia64/lib/__divdi3.o$:
+ || m:arch/ia64/lib/__divsi3.o$:
+ || m:arch/ia64/lib/__moddi3.o$:
+ || m:arch/ia64/lib/__modsi3.o$:
+ || m:arch/ia64/lib/__udivdi3.o$:
+ || m:arch/ia64/lib/__udivsi3.o$:
+ || m:arch/ia64/lib/__umoddi3.o$:
+ || m:arch/ia64/lib/__umodsi3.o$:
+ || m:arch/ia64/scripts/check_gas_for_hint.o$:
+ || m:arch/ia64/sn/kernel/xp.o$:
+ || m:boot/bbootsect.o$:
+ || m:boot/bsetup.o$:
+ || m:/bootsect.o$:
+ || m:/boot/setup.o$:
+ || m:/compressed/:
+ || m:drivers/cdrom/driver.o$:
+ || m:drivers/char/drm/tdfx_drv.o$:
+ || m:drivers/ide/ide-detect.o$:
+ || m:drivers/ide/pci/idedriver-pci.o$:
+ || m:drivers/media/media.o$:
+ || m:drivers/scsi/sd_mod.o$:
+ || m:drivers/video/video.o$:
+ || m:fs/devpts/devpts.o$:
+ || m:fs/exportfs/exportfs.o$:
+ || m:fs/hugetlbfs/hugetlbfs.o$:
+ || m:fs/msdos/msdos.o$:
+ || m:fs/nls/nls.o$:
+ || m:fs/ramfs/ramfs.o$:
+ || m:fs/romfs/romfs.o$:
+ || m:fs/vfat/vfat.o$:
+ || m:init/mounts.o$:
+ || m:^modules/:
+ || m:net/netlink/netlink.o$:
+ || m:net/sched/sched.o$:
+ || m:/piggy.o$:
+ || m:^scripts/:
+ || m:sound/.*/snd-:
+ || m:^.*/\.tmp_:
+ || m:^\.tmp_:
+ || m:/vmlinux-obj.o$:
+ )
+ ) {
+ do_nm($basename, $_);
+ }
+ $_ = $basename; # File::Find expects $_ untouched (undocumented)
+}
+
+sub do_nm
+{
+ my ($basename, $fullname) = @_;
+ my ($source, $type, $name);
+ if (! -e $basename) {
+ printf STDERR "$basename does not exist\n";
+ return;
+ }
+ if ($fullname !~ /\.o$/) {
+ printf STDERR "$fullname is not an object file\n";
+ return;
+ }
+ ($source = $fullname) =~ s/\.o$//;
+ if (-e "$objtree$source.c" || -e "$objtree$source.S") {
+ $source = "$objtree$source";
+ } else {
+ $source = "$srctree$source";
+ }
+ if (! -e "$source.c" && ! -e "$source.S") {
+ # No obvious source, exclude the object if it is conglomerate
+ if (! open(OBJDUMPDATA, "$objdump $basename|")) {
+ printf STDERR "$objdump $fullname failed $!\n";
+ return;
+ }
+ my $comment;
+ while (<OBJDUMPDATA>) {
+ chomp();
+ if (/^In archive/) {
+ # Archives are always conglomerate
+ $comment = "GCC:GCC:";
+ last;
+ }
+ next if (! /^[ 0-9a-f]{5,} /);
+ $comment .= substr($_, 43);
+ }
+ close(OBJDUMPDATA);
+ if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
+ printf STDERR "No source file found for $fullname\n";
+ }
+ return;
+ }
+ if (! open(NMDATA, "$nm $basename|")) {
+ printf STDERR "$nm $fullname failed $!\n";
+ return;
+ }
+ my @nmdata;
+ while (<NMDATA>) {
+ chop;
+ ($type, $name) = (split(/ +/, $_, 3))[1..2];
+ # Expected types
+ # A absolute symbol
+ # B weak external reference to data that has been resolved
+ # C global variable, uninitialised
+ # D global variable, initialised
+ # G global variable, initialised, small data section
+ # R global array, initialised
+ # S global variable, uninitialised, small bss
+ # T global label/procedure
+ # U external reference
+ # W weak external reference to text that has been resolved
+ # a assembler equate
+ # b static variable, uninitialised
+ # d static variable, initialised
+ # g static variable, initialised, small data section
+ # r static array, initialised
+ # s static variable, uninitialised, small bss
+ # t static label/procedures
+ # w weak external reference to text that has not been resolved
+ # ? undefined type, used a lot by modules
+ if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) {
+ printf STDERR "nm output for $fullname contains unknown type '$_'\n";
+ }
+ elsif ($name =~ /\./) {
+ # name with '.' is local static
+ }
+ else {
+ $type = 'R' if ($type eq '?'); # binutils replaced ? with R at one point
+ # binutils keeps changing the type for exported symbols, force it to R
+ $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
+ $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this
+ if ($type =~ /[ABCDGRSTW]/ &&
+ $name ne 'init_module' &&
+ $name ne 'cleanup_module' &&
+ $name ne 'Using_Versions' &&
+ $name !~ /^Version_[0-9]+$/ &&
+ $name !~ /^__parm_/ &&
+ $name !~ /^__kstrtab/ &&
+ $name !~ /^__ksymtab/ &&
+ $name !~ /^__kcrctab_/ &&
+ $name !~ /^__exitcall_/ &&
+ $name !~ /^__initcall_/ &&
+ $name !~ /^__kdb_initcall_/ &&
+ $name !~ /^__kdb_exitcall_/ &&
+ $name !~ /^__module_/ &&
+ $name !~ /^__mod_/ &&
+ $name !~ /^__crc_/ &&
+ $name ne '__this_module' &&
+ $name ne 'kernel_version') {
+ if (!exists($def{$name})) {
+ $def{$name} = [];
+ }
+ push(@{$def{$name}}, $fullname);
+ }
+ push(@nmdata, "$type $name");
+ if ($name =~ /^__ksymtab_/) {
+ $name = substr($name, 10);
+ if (!exists($ksymtab{$name})) {
+ $ksymtab{$name} = [];
+ }
+ push(@{$ksymtab{$name}}, $fullname);
+ }
+ }
+ }
+ close(NMDATA);
+ if ($#nmdata < 0) {
+ if (
+ $fullname ne "lib/brlock.o"
+ && $fullname ne "lib/dec_and_lock.o"
+ && $fullname ne "fs/xfs/xfs_macros.o"
+ && $fullname ne "drivers/ide/ide-probe-mini.o"
+ && $fullname ne "usr/initramfs_data.o"
+ && $fullname ne "drivers/acpi/executer/exdump.o"
+ && $fullname ne "drivers/acpi/resources/rsdump.o"
+ && $fullname ne "drivers/acpi/namespace/nsdumpdv.o"
+ && $fullname ne "drivers/acpi/namespace/nsdump.o"
+ && $fullname ne "arch/ia64/sn/kernel/sn2/io.o"
+ && $fullname ne "arch/ia64/kernel/gate-data.o"
+ && $fullname ne "drivers/ieee1394/oui.o"
+ && $fullname ne "security/capability.o"
+ && $fullname ne "sound/core/wrappers.o"
+ && $fullname ne "fs/ntfs/sysctl.o"
+ && $fullname ne "fs/jfs/jfs_debug.o"
+ ) {
+ printf "No nm data for $fullname\n";
+ }
+ return;
+ }
+ $nmdata{$fullname} = \@nmdata;
+}
+
+sub drop_def
+{
+ my ($object, $name) = @_;
+ my $nmdata = $nmdata{$object};
+ my ($i, $j);
+ for ($i = 0; $i <= $#{$nmdata}; ++$i) {
+ if ($name eq (split(' ', $nmdata->[$i], 2))[1]) {
+ splice(@{$nmdata{$object}}, $i, 1);
+ my $def = $def{$name};
+ for ($j = 0; $j < $#{$def{$name}}; ++$j) {
+ if ($def{$name}[$j] eq $object) {
+ splice(@{$def{$name}}, $j, 1);
+ }
+ }
+ last;
+ }
+ }
+}
+
+sub list_multiply_defined
+{
+ my ($name, $module);
+ foreach $name (keys(%def)) {
+ if ($#{$def{$name}} > 0) {
+ # Special case for cond_syscall
+ if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
+ ($def{$name}[0] eq "kernel/sys.o" ||
+ $def{$name}[1] eq "kernel/sys.o")) {
+ &drop_def("kernel/sys.o", $name);
+ next;
+ }
+ # Special case for i386 entry code
+ if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ &&
+ $def{$name}[0] eq "arch/i386/kernel/vsyscall-int80.o" &&
+ $def{$name}[1] eq "arch/i386/kernel/vsyscall-sysenter.o") {
+ &drop_def("arch/i386/kernel/vsyscall-sysenter.o", $name);
+ next;
+ }
+ printf "$name is multiply defined in :-\n";
+ foreach $module (@{$def{$name}}) {
+ printf "\t$module\n";
+ }
+ }
+ }
+}
+
+sub resolve_external_references
+{
+ my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export);
+ printf "\n";
+ foreach $object (keys(%nmdata)) {
+ my $nmdata = $nmdata{$object};
+ for ($i = 0; $i <= $#{$nmdata}; ++$i) {
+ ($type, $name) = split(' ', $nmdata->[$i], 2);
+ if ($type eq "U" || $type eq "w") {
+ if (exists($def{$name}) || exists($ksymtab{$name})) {
+ # add the owning object to the nmdata
+ $nmdata->[$i] = "$type $name $object";
+ # only count as a reference if it is not EXPORT_...
+ $kstrtab = "R __kstrtab_$name";
+ $ksymtab = "R __ksymtab_$name";
+ $export = 0;
+ for ($j = 0; $j <= $#{$nmdata}; ++$j) {
+ if ($nmdata->[$j] eq $kstrtab ||
+ $nmdata->[$j] eq $ksymtab) {
+ $export = 1;
+ last;
+ }
+ }
+ if ($export) {
+ $export{$name} = "";
+ }
+ else {
+ $ref{$name} = ""
+ }
+ }
+ elsif ( $name ne "mod_use_count_"
+ && $name ne "__initramfs_end"
+ && $name ne "__initramfs_start"
+ && $name ne "_einittext"
+ && $name ne "_sinittext"
+ && $name ne "kallsyms_names"
+ && $name ne "kallsyms_num_syms"
+ && $name ne "kallsyms_addresses"
+ && $name ne "__this_module"
+ && $name ne "_etext"
+ && $name ne "_edata"
+ && $name ne "_end"
+ && $name ne "__bss_start"
+ && $name ne "_text"
+ && $name ne "_stext"
+ && $name ne "__gp"
+ && $name ne "ia64_unw_start"
+ && $name ne "ia64_unw_end"
+ && $name ne "__init_begin"
+ && $name ne "__init_end"
+ && $name ne "__bss_stop"
+ && $name ne "__nosave_begin"
+ && $name ne "__nosave_end"
+ && $name ne "pg0"
+ && $name ne "__module_text_address"
+ && $name !~ /^__sched_text_/
+ && $name !~ /^__start_/
+ && $name !~ /^__end_/
+ && $name !~ /^__stop_/
+ && $name !~ /^__scheduling_functions_.*_here/
+ && $name !~ /^__.*initcall_/
+ && $name !~ /^__.*per_cpu_start/
+ && $name !~ /^__.*per_cpu_end/
+ && $name !~ /^__alt_instructions/
+ && $name !~ /^__setup_/
+ && $name !~ /^jiffies/
+ && $name !~ /^__mod_timer/
+ && $name !~ /^__mod_page_state/
+ && $name !~ /^init_module/
+ && $name !~ /^cleanup_module/
+ ) {
+ printf "Cannot resolve ";
+ printf "weak " if ($type eq "w");
+ printf "reference to $name from $object\n";
+ }
+ }
+ }
+ }
+}
+
+sub list_extra_externals
+{
+ my %noref = ();
+ my ($name, @module, $module, $export);
+ foreach $name (keys(%def)) {
+ if (! exists($ref{$name})) {
+ @module = @{$def{$name}};
+ foreach $module (@module) {
+ if (! exists($noref{$module})) {
+ $noref{$module} = [];
+ }
+ push(@{$noref{$module}}, $name);
+ }
+ }
+ }
+ if (%noref) {
+ printf "\nExternally defined symbols with no external references\n";
+ foreach $module (sort(keys(%noref))) {
+ printf " $module\n";
+ foreach (sort(@{$noref{$module}})) {
+ if (exists($export{$_})) {
+ $export = " (export only)";
+ }
+ else {
+ $export = "";
+ }
+ printf " $_$export\n";
+ }
+ }
+ }
+}
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 @@
+# Makefile for the different targets used to generate full packages of a kernel
+# It uses the generic clean infrastructure of kbuild
+
+# Ignore the following files/directories during tar operation
+TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS
+
+
+# RPM target
+# ---------------------------------------------------------------------------
+# The rpm target generates two rpm files:
+# /usr/src/packages/SRPMS/kernel-2.6.7rc2-1.src.rpm
+# /usr/src/packages/RPMS/i386/kernel-2.6.7rc2-1.<arch>.rpm
+# The src.rpm files includes all source for the kernel being built
+# The <arch>.rpm includes kernel configuration, modules etc.
+#
+# Process to create the rpm files
+# a) clean the kernel
+# b) Generate .spec file
+# c) Build a tar ball, using symlink to make kernel version
+# first entry in the path
+# d) and pack the result to a tar.gz file
+# e) generate the rpm files, based on kernel.spec
+# - Use /. to avoid tar packing just the symlink
+
+# Do we have rpmbuild, otherwise fall back to the older rpm
+RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
+ else echo rpm; fi)
+
+# Remove hyphens since they have special meaning in RPM filenames
+KERNELPATH := kernel-$(subst -,,$(KERNELRELEASE))
+MKSPEC := $(srctree)/scripts/package/mkspec
+PREV := set -e; cd ..;
+
+# rpm-pkg
+.PHONY: rpm-pkg rpm
+
+$(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
+ $(CONFIG_SHELL) $(MKSPEC) > $@
+
+rpm-pkg rpm: $(objtree)/kernel.spec
+ $(MAKE) clean
+ $(PREV) ln -sf $(srctree) $(KERNELPATH)
+ $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
+ $(PREV) rm $(KERNELPATH)
+
+ set -e; \
+ $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
+ set -e; \
+ mv -f $(objtree)/.tmp_version $(objtree)/.version
+
+ $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz
+ rm ../$(KERNELPATH).tar.gz
+
+clean-files := $(objtree)/kernel.spec
+
+# binrpm-pkg
+.PHONY: binrpm-pkg
+$(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile
+ $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@
+
+binrpm-pkg: $(objtree)/binkernel.spec
+ $(MAKE)
+ set -e; \
+ $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
+ set -e; \
+ mv -f $(objtree)/.tmp_version $(objtree)/.version
+
+ $(RPM) --define "_builddir $(srctree)" --target $(UTS_MACHINE) -bb $<
+
+clean-files += $(objtree)/binkernel.spec
+
+# Deb target
+# ---------------------------------------------------------------------------
+#
+.PHONY: deb-pkg
+deb-pkg:
+ $(MAKE)
+ $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb
+
+clean-dirs += $(objtree)/debian/
+
+
+# Help text displayed when executing 'make help'
+# ---------------------------------------------------------------------------
+help:
+ @echo ' rpm-pkg - Build the kernel as an RPM package'
+ @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel & modules'
+ @echo ' deb-pkg - Build the kernel as an deb package'
+
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 @@
+#!/bin/sh
+#
+# builddeb 1.2
+# Copyright 2003 Wichert Akkerman <wichert@wiggy.net>
+#
+# Simple script to generate a deb package for a Linux kernel. All the
+# complexity of what to do with a kernel after it is installer or removed
+# is left to other scripts and packages: they can install scripts in the
+# /etc/kernel/{pre,post}{inst,rm}.d/ directories that will be called on
+# package install and removal.
+
+set -e
+
+# Some variables and settings used throughout the script
+version=$KERNELRELEASE
+tmpdir="$objtree/debian/tmp"
+
+# Setup the directory structure
+rm -rf "$tmpdir"
+mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot"
+
+# Build and install the kernel
+cp System.map "$tmpdir/boot/System.map-$version"
+cp .config "$tmpdir/boot/config-$version"
+cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
+
+if grep -q '^CONFIG_MODULES=y' .config ; then
+ INSTALL_MOD_PATH="$tmpdir" make modules_install
+fi
+
+# Install the maintainer scripts
+for script in postinst postrm preinst prerm ; do
+ mkdir -p "$tmpdir/etc/kernel/$script.d"
+ cat <<EOF > "$tmpdir/DEBIAN/$script"
+#!/bin/sh
+
+set -e
+
+test -d /etc/kernel/$script.d && run-parts --arg="$version" /etc/kernel/$script.d
+exit 0
+EOF
+ chmod 755 "$tmpdir/DEBIAN/$script"
+done
+
+name="Kernel Compiler <$(id -nu)@$(hostname -f)>"
+# Generate a simple changelog template
+cat <<EOF > debian/changelog
+linux ($version) unstable; urgency=low
+
+ * A standard release
+
+ -- $name $(date -R)
+EOF
+
+# Generate a control file
+cat <<EOF > debian/control
+Source: linux
+Section: base
+Priority: optional
+Maintainer: $name
+Standards-Version: 3.6.1
+
+Package: linux-$version
+Architecture: any
+Description: Linux kernel, version $version
+ This package contains the Linux kernel, modules and corresponding other
+ files version $version.
+EOF
+
+# Fix some ownership and permissions
+chown -R root:root "$tmpdir"
+chmod -R go-w "$tmpdir"
+
+# Perform the final magic
+dpkg-gencontrol -isp
+dpkg --build "$tmpdir" ..
+
+exit 0
+
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 @@
+#!/bin/sh
+#
+# Output a simple RPM spec file that uses no fancy features requring
+# RPM v4. This is intended to work with any RPM distro.
+#
+# The only gothic bit here is redefining install_post to avoid
+# stripping the symbols from files in the kernel which we want
+#
+# Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net>
+#
+
+# how we were called determines which rpms we build and how we build them
+if [ "$1" = "prebuilt" ]; then
+ PREBUILT=true
+else
+ PREBUILT=false
+fi
+
+# starting to output the spec
+if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then
+ PROVIDES=kernel-drm
+fi
+
+PROVIDES="$PROVIDES kernel-$KERNELRELEASE"
+__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-//g"`
+
+echo "Name: kernel"
+echo "Summary: The Linux Kernel"
+echo "Version: $__KERNELRELEASE"
+# we need to determine the NEXT version number so that uname and
+# rpm -q will agree
+echo "Release: `. $srctree/scripts/mkversion`"
+echo "License: GPL"
+echo "Group: System Environment/Kernel"
+echo "Vendor: The Linux Community"
+echo "URL: http://www.kernel.org"
+
+if ! $PREBUILT; then
+echo "Source: kernel-$__KERNELRELEASE.tar.gz"
+fi
+
+echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root"
+echo "Provides: $PROVIDES"
+echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
+echo "%define debug_package %{nil}"
+echo ""
+echo "%description"
+echo "The Linux Kernel, the operating system core itself"
+echo ""
+
+if ! $PREBUILT; then
+echo "%prep"
+echo "%setup -q"
+echo ""
+fi
+
+echo "%build"
+
+if ! $PREBUILT; then
+echo "make clean && make %{_smp_mflags}"
+echo ""
+fi
+
+echo "%install"
+echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules'
+
+echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install'
+echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
+
+echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE"
+
+echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE"
+echo ""
+echo "%clean"
+echo '#echo -rf $RPM_BUILD_ROOT'
+echo ""
+echo "%files"
+echo '%defattr (-, root, root)'
+echo "%dir /lib/modules"
+echo "/lib/modules/$KERNELRELEASE"
+echo "/boot/*"
+echo ""
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 @@
+#! /bin/sh
+# Script to apply kernel patches.
+# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
+# The source directory defaults to /usr/src/linux, and the patch
+# directory defaults to the current directory.
+# e.g.
+# scripts/patch-kernel . ..
+# Update the kernel tree in the current directory using patches in the
+# directory above to the latest Linus kernel
+# scripts/patch-kernel . .. -ac
+# Get the latest Linux kernel and patch it with the latest ac patch
+# scripts/patch-kernel . .. 2.4.9
+# Gets standard kernel 2.4.9
+# scripts/patch-kernel . .. 2.4.9 -ac
+# Gets 2.4.9 with latest ac patches
+# scripts/patch-kernel . .. 2.4.9 -ac11
+# Gets 2.4.9 with ac patch ac11
+# Note: It uses the patches relative to the Linus kernels, not the
+# ac to ac relative patches
+#
+# It determines the current kernel version from the top-level Makefile.
+# It then looks for patches for the next sublevel in the patch directory.
+# This is applied using "patch -p1 -s" from within the kernel directory.
+# A check is then made for "*.rej" files to see if the patch was
+# successful. If it is, then all of the "*.orig" files are removed.
+#
+# Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995.
+#
+# Added support for handling multiple types of compression. What includes
+# gzip, bzip, bzip2, zip, compress, and plaintext.
+#
+# Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997.
+#
+# Added ability to stop at a given version number
+# Put the full version number (i.e. 2.3.31) as the last parameter
+# Dave Gilbert <linux@treblig.org>, 11th December 1999.
+
+# Fixed previous patch so that if we are already at the correct version
+# not to patch up.
+#
+# Added -ac option, use -ac or -ac9 (say) to stop at a particular version
+# Dave Gilbert <linux@treblig.org>, 29th September 2001.
+#
+# Add support for (use of) EXTRAVERSION (to support 2.6.8.x, e.g.);
+# update usage message;
+# fix some whitespace damage;
+# be smarter about stopping when current version is larger than requested;
+# Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.
+
+# Set directories from arguments, or use defaults.
+sourcedir=${1-/usr/src/linux}
+patchdir=${2-.}
+stopvers=${3-default}
+
+if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then
+cat << USAGE
+usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
+ source directory defaults to /usr/src/linux,
+ patch directory defaults to the current directory,
+ stopversion defaults to <all in patchdir>.
+USAGE
+exit 1
+fi
+
+# See if we have any -ac options
+for PARM in $*
+do
+ case $PARM in
+ -ac*)
+ gotac=$PARM;
+
+ esac;
+done
+
+# ---------------------------------------------------------------------------
+# Find a file, first parameter is basename of file
+# it tries many compression mechanisms and sets variables to say how to get it
+findFile () {
+ filebase=$1;
+
+ if [ -r ${filebase}.gz ]; then
+ ext=".gz"
+ name="gzip"
+ uncomp="gunzip -dc"
+ elif [ -r ${filebase}.bz ]; then
+ ext=".bz"
+ name="bzip"
+ uncomp="bunzip -dc"
+ elif [ -r ${filebase}.bz2 ]; then
+ ext=".bz2"
+ name="bzip2"
+ uncomp="bunzip2 -dc"
+ elif [ -r ${filebase}.zip ]; then
+ ext=".zip"
+ name="zip"
+ uncomp="unzip -d"
+ elif [ -r ${filebase}.Z ]; then
+ ext=".Z"
+ name="uncompress"
+ uncomp="uncompress -c"
+ elif [ -r ${filebase} ]; then
+ ext=""
+ name="plaintext"
+ uncomp="cat"
+ else
+ return 1;
+ fi
+
+ return 0;
+}
+
+# ---------------------------------------------------------------------------
+# Apply a patch and check it goes in cleanly
+# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension
+
+applyPatch () {
+ echo -n "Applying $1 (${name})... "
+ if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir
+ then
+ echo "done."
+ else
+ echo "failed. Clean up yourself."
+ return 1;
+ fi
+ if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ]
+ then
+ echo "Aborting. Reject files found."
+ return 1;
+ fi
+ # Remove backup files
+ find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \;
+
+ return 0;
+}
+
+# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
+TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; }
+grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE
+tr -d [:blank:] < $TMPFILE > $TMPFILE.1
+source $TMPFILE.1
+rm -f $TMPFILE*
+if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
+then
+ echo "unable to determine current kernel version" >&2
+ exit 1
+fi
+
+NAME=`grep ^NAME $sourcedir/Makefile`
+NAME=${NAME##*=}
+
+echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($NAME)"
+
+# strip EXTRAVERSION to just a number (drop leading '.' and trailing additions)
+EXTRAVER=
+if [ x$EXTRAVERSION != "x" ]
+then
+ if [ ${EXTRAVERSION:0:1} == "." ]; then
+ EXTRAVER=${EXTRAVERSION:1}
+ else
+ EXTRAVER=$EXTRAVERSION
+ fi
+ EXTRAVER=${EXTRAVER%%[[:punct:]]*}
+ #echo "patch-kernel: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
+fi
+
+#echo "stopvers=$stopvers"
+if [ $stopvers != "default" ]; then
+ STOPSUBLEVEL=`echo $stopvers | cut -d. -f3`
+ STOPEXTRA=`echo $stopvers | cut -d. -f4`
+ #echo "STOPSUBLEVEL=$STOPSUBLEVEL, STOPEXTRA=$STOPEXTRA"
+else
+ STOPSUBLEVEL=9999
+ STOPEXTRA=9999
+fi
+
+while : # incrementing SUBLEVEL (s in v.p.s)
+do
+ if [ x$EXTRAVER != "x" ]; then
+ CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
+ else
+ CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
+ fi
+
+ if [ $stopvers == $CURRENTFULLVERSION ]; then
+ echo "Stopping at $CURRENTFULLVERSION base as requested."
+ break
+ fi
+
+ while : # incrementing EXTRAVER (x in v.p.s.x)
+ do
+ EXTRAVER=$((EXTRAVER + 1))
+ FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
+ #echo "... trying $FULLVERSION ..."
+
+ patch=patch-$FULLVERSION
+
+ # See if the file exists and find extension
+ findFile $patchdir/${patch} || break
+
+ # Apply the patch and check all is OK
+ applyPatch $patch || break
+
+ continue 2
+ done
+
+ EXTRAVER=
+ SUBLEVEL=$((SUBLEVEL + 1))
+ FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
+ #echo "___ trying $FULLVERSION ___"
+
+ if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then
+ echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)"
+ exit 1
+ fi
+
+ patch=patch-$FULLVERSION
+
+ # See if the file exists and find extension
+ findFile $patchdir/${patch} || break
+
+ # Apply the patch and check all is OK
+ applyPatch $patch || break
+done
+#echo "base all done"
+
+if [ x$gotac != x ]; then
+ # Out great user wants the -ac patches
+ # They could have done -ac (get latest) or -acxx where xx=version they want
+ if [ $gotac == "-ac" ]; then
+ # They want the latest version
+ HIGHESTPATCH=0
+ for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.*
+ do
+ ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'`
+ # Check it is actually a recognised patch type
+ findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break
+
+ if [ $ACVALUE -gt $HIGHESTPATCH ]; then
+ HIGHESTPATCH=$ACVALUE
+ fi
+ done
+
+ if [ $HIGHESTPATCH -ne 0 ]; then
+ findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break
+ applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH}
+ else
+ echo "No -ac patches found"
+ fi
+ else
+ # They want an exact version
+ findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || {
+ echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum."
+ exit 1
+ }
+ applyPatch patch-${CURRENTFULLVERSION}${gotac}
+ fi
+fi
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 @@
+
+/*
+ * Convert a logo in ASCII PNM format to C source suitable for inclusion in
+ * the Linux kernel
+ *
+ * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char *programname;
+static const char *filename;
+static const char *logoname = "linux_logo";
+static const char *outputname;
+static FILE *out;
+
+
+#define LINUX_LOGO_MONO 1 /* monochrome black/white */
+#define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */
+#define LINUX_LOGO_CLUT224 3 /* 224 colors */
+#define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */
+
+static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
+ [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
+ [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
+ [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
+ [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
+};
+
+#define MAX_LINUX_LOGO_COLORS 224
+
+struct color {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+};
+
+static const struct color clut_vga16[16] = {
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0xaa },
+ { 0x00, 0xaa, 0x00 },
+ { 0x00, 0xaa, 0xaa },
+ { 0xaa, 0x00, 0x00 },
+ { 0xaa, 0x00, 0xaa },
+ { 0xaa, 0x55, 0x00 },
+ { 0xaa, 0xaa, 0xaa },
+ { 0x55, 0x55, 0x55 },
+ { 0x55, 0x55, 0xff },
+ { 0x55, 0xff, 0x55 },
+ { 0x55, 0xff, 0xff },
+ { 0xff, 0x55, 0x55 },
+ { 0xff, 0x55, 0xff },
+ { 0xff, 0xff, 0x55 },
+ { 0xff, 0xff, 0xff },
+};
+
+
+static int logo_type = LINUX_LOGO_CLUT224;
+static unsigned int logo_width;
+static unsigned int logo_height;
+static struct color **logo_data;
+static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
+static unsigned int logo_clutsize;
+
+static void die(const char *fmt, ...)
+ __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
+static void usage(void) __attribute ((noreturn));
+
+
+static unsigned int get_number(FILE *fp)
+{
+ int c, val;
+
+ /* Skip leading whitespace */
+ do {
+ c = fgetc(fp);
+ if (c == EOF)
+ die("%s: end of file\n", filename);
+ if (c == '#') {
+ /* Ignore comments 'till end of line */
+ do {
+ c = fgetc(fp);
+ if (c == EOF)
+ die("%s: end of file\n", filename);
+ } while (c != '\n');
+ }
+ } while (isspace(c));
+
+ /* Parse decimal number */
+ val = 0;
+ while (isdigit(c)) {
+ val = 10*val+c-'0';
+ c = fgetc(fp);
+ if (c == EOF)
+ die("%s: end of file\n", filename);
+ }
+ return val;
+}
+
+static unsigned int get_number255(FILE *fp, unsigned int maxval)
+{
+ unsigned int val = get_number(fp);
+ return (255*val+maxval/2)/maxval;
+}
+
+static void read_image(void)
+{
+ FILE *fp;
+ unsigned int i, j;
+ int magic;
+ unsigned int maxval;
+
+ /* open image file */
+ fp = fopen(filename, "r");
+ if (!fp)
+ die("Cannot open file %s: %s\n", filename, strerror(errno));
+
+ /* check file type and read file header */
+ magic = fgetc(fp);
+ if (magic != 'P')
+ die("%s is not a PNM file\n", filename);
+ magic = fgetc(fp);
+ switch (magic) {
+ case '1':
+ case '2':
+ case '3':
+ /* Plain PBM/PGM/PPM */
+ break;
+
+ case '4':
+ case '5':
+ case '6':
+ /* Binary PBM/PGM/PPM */
+ die("%s: Binary PNM is not supported\n"
+ "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
+
+ default:
+ die("%s is not a PNM file\n", filename);
+ }
+ logo_width = get_number(fp);
+ logo_height = get_number(fp);
+
+ /* allocate image data */
+ logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
+ if (!logo_data)
+ die("%s\n", strerror(errno));
+ for (i = 0; i < logo_height; i++) {
+ logo_data[i] = malloc(logo_width*sizeof(struct color));
+ if (!logo_data[i])
+ die("%s\n", strerror(errno));
+ }
+
+ /* read image data */
+ switch (magic) {
+ case '1':
+ /* Plain PBM */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ logo_data[i][j].red = logo_data[i][j].green =
+ logo_data[i][j].blue = 255*(1-get_number(fp));
+ break;
+
+ case '2':
+ /* Plain PGM */
+ maxval = get_number(fp);
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ logo_data[i][j].red = logo_data[i][j].green =
+ logo_data[i][j].blue = get_number255(fp, maxval);
+ break;
+
+ case '3':
+ /* Plain PPM */
+ maxval = get_number(fp);
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ logo_data[i][j].red = get_number255(fp, maxval);
+ logo_data[i][j].green = get_number255(fp, maxval);
+ logo_data[i][j].blue = get_number255(fp, maxval);
+ }
+ break;
+ }
+
+ /* close file */
+ fclose(fp);
+}
+
+static inline int is_black(struct color c)
+{
+ return c.red == 0 && c.green == 0 && c.blue == 0;
+}
+
+static inline int is_white(struct color c)
+{
+ return c.red == 255 && c.green == 255 && c.blue == 255;
+}
+
+static inline int is_gray(struct color c)
+{
+ return c.red == c.green && c.red == c.blue;
+}
+
+static inline int is_equal(struct color c1, struct color c2)
+{
+ return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
+}
+
+static void write_header(void)
+{
+ /* open logo file */
+ if (outputname) {
+ out = fopen(outputname, "w");
+ if (!out)
+ die("Cannot create file %s: %s\n", outputname, strerror(errno));
+ } else {
+ out = stdout;
+ }
+
+ fputs("/*\n", out);
+ fputs(" * DO NOT EDIT THIS FILE!\n", out);
+ fputs(" *\n", out);
+ fprintf(out, " * It was automatically generated from %s\n", filename);
+ fputs(" *\n", out);
+ fprintf(out, " * Linux logo %s\n", logoname);
+ fputs(" */\n\n", out);
+ fputs("#include <linux/linux_logo.h>\n\n", out);
+ fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
+ logoname);
+}
+
+static void write_footer(void)
+{
+ fputs("\n};\n\n", out);
+ fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
+ fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
+ fprintf(out, " .width\t= %d,\n", logo_width);
+ fprintf(out, " .height\t= %d,\n", logo_height);
+ if (logo_type == LINUX_LOGO_CLUT224) {
+ fprintf(out, " .clutsize\t= %d,\n", logo_clutsize);
+ fprintf(out, " .clut\t= %s_clut,\n", logoname);
+ }
+ fprintf(out, " .data\t= %s_data\n", logoname);
+ fputs("};\n\n", out);
+
+ /* close logo file */
+ if (outputname)
+ fclose(out);
+}
+
+static int write_hex_cnt;
+
+static void write_hex(unsigned char byte)
+{
+ if (write_hex_cnt % 12)
+ fprintf(out, ", 0x%02x", byte);
+ else if (write_hex_cnt)
+ fprintf(out, ",\n\t0x%02x", byte);
+ else
+ fprintf(out, "\t0x%02x", byte);
+ write_hex_cnt++;
+}
+
+static void write_logo_mono(void)
+{
+ unsigned int i, j;
+ unsigned char val, bit;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
+ die("Image must be monochrome\n");
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++) {
+ for (j = 0; j < logo_width;) {
+ for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
+ if (logo_data[i][j].red)
+ val |= bit;
+ write_hex(val);
+ }
+ }
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void write_logo_vga16(void)
+{
+ unsigned int i, j, k;
+ unsigned char val;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < 16; k++)
+ if (is_equal(logo_data[i][j], clut_vga16[k]))
+ break;
+ if (k == 16)
+ die("Image must use the 16 console colors only\n"
+ "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
+ "of colors\n");
+ }
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < 16; k++)
+ if (is_equal(logo_data[i][j], clut_vga16[k]))
+ break;
+ val = k<<4;
+ if (++j < logo_width) {
+ for (k = 0; k < 16; k++)
+ if (is_equal(logo_data[i][j], clut_vga16[k]))
+ break;
+ val |= k;
+ }
+ write_hex(val);
+ }
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void write_logo_clut224(void)
+{
+ unsigned int i, j, k;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < logo_clutsize; k++)
+ if (is_equal(logo_data[i][j], logo_clut[k]))
+ break;
+ if (k == logo_clutsize) {
+ if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
+ die("Image has more than %d colors\n"
+ "Use ppmquant(1) to reduce the number of colors\n",
+ MAX_LINUX_LOGO_COLORS);
+ logo_clut[logo_clutsize++] = logo_data[i][j];
+ }
+ }
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < logo_clutsize; k++)
+ if (is_equal(logo_data[i][j], logo_clut[k]))
+ break;
+ write_hex(k+32);
+ }
+ fputs("\n};\n\n", out);
+
+ /* write logo clut */
+ fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
+ logoname);
+ write_hex_cnt = 0;
+ for (i = 0; i < logo_clutsize; i++) {
+ write_hex(logo_clut[i].red);
+ write_hex(logo_clut[i].green);
+ write_hex(logo_clut[i].blue);
+ }
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void write_logo_gray256(void)
+{
+ unsigned int i, j;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ if (!is_gray(logo_data[i][j]))
+ die("Image must be grayscale\n");
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ write_hex(logo_data[i][j].red);
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void die(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ exit(1);
+}
+
+static void usage(void)
+{
+ die("\n"
+ "Usage: %s [options] <filename>\n"
+ "\n"
+ "Valid options:\n"
+ " -h : display this usage information\n"
+ " -n <name> : specify logo name (default: linux_logo)\n"
+ " -o <output> : output to file <output> instead of stdout\n"
+ " -t <type> : specify logo type, one of\n"
+ " mono : monochrome black/white\n"
+ " vga16 : 16 colors VGA text palette\n"
+ " clut224 : 224 colors (default)\n"
+ " gray256 : 256 levels grayscale\n"
+ "\n", programname);
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+
+ programname = argv[0];
+
+ opterr = 0;
+ while (1) {
+ opt = getopt(argc, argv, "hn:o:t:");
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'h':
+ usage();
+ break;
+
+ case 'n':
+ logoname = optarg;
+ break;
+
+ case 'o':
+ outputname = optarg;
+ break;
+
+ case 't':
+ if (!strcmp(optarg, "mono"))
+ logo_type = LINUX_LOGO_MONO;
+ else if (!strcmp(optarg, "vga16"))
+ logo_type = LINUX_LOGO_VGA16;
+ else if (!strcmp(optarg, "clut224"))
+ logo_type = LINUX_LOGO_CLUT224;
+ else if (!strcmp(optarg, "gray256"))
+ logo_type = LINUX_LOGO_GRAY256;
+ else
+ usage();
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ }
+ if (optind != argc-1)
+ usage();
+
+ filename = argv[optind];
+
+ read_image();
+ switch (logo_type) {
+ case LINUX_LOGO_MONO:
+ write_logo_mono();
+ break;
+
+ case LINUX_LOGO_VGA16:
+ write_logo_vga16();
+ break;
+
+ case LINUX_LOGO_CLUT224:
+ write_logo_clut224();
+ break;
+
+ case LINUX_LOGO_GRAY256:
+ write_logo_gray256();
+ break;
+ }
+ exit(0);
+}
+
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 @@
+#!/usr/bin/perl -w
+#
+# reference_discarded.pl (C) Keith Owens 2001 <kaos@ocs.com.au>
+#
+# Released under GPL V2.
+#
+# List dangling references to vmlinux discarded sections.
+
+use strict;
+die($0 . " takes no arguments\n") if($#ARGV >= 0);
+
+my %object;
+my $object;
+my $line;
+my $ignore;
+my $errorcount;
+
+$| = 1;
+
+# printf("Finding objects, ");
+open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
+while (defined($line = <OBJDUMP_LIST>)) {
+ chomp($line);
+ if ($line =~ /:\s+file format/) {
+ ($object = $line) =~ s/:.*//;
+ $object{$object}->{'module'} = 0;
+ $object{$object}->{'size'} = 0;
+ $object{$object}->{'off'} = 0;
+ }
+ if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
+ $object{$object}->{'module'} = 1;
+ }
+ if ($line =~ /^\s*\d+\s+\.comment\s+/) {
+ ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
+ }
+}
+close(OBJDUMP_LIST);
+# printf("%d objects, ", scalar keys(%object));
+$ignore = 0;
+foreach $object (keys(%object)) {
+ if ($object{$object}->{'module'}) {
+ ++$ignore;
+ delete($object{$object});
+ }
+}
+# printf("ignoring %d module(s)\n", $ignore);
+
+# Ignore conglomerate objects, they have been built from multiple objects and we
+# only care about the individual objects. If an object has more than one GCC:
+# string in the comment section then it is conglomerate. This does not filter
+# out conglomerates that consist of exactly one object, can't be helped.
+
+# printf("Finding conglomerates, ");
+$ignore = 0;
+foreach $object (keys(%object)) {
+ if (exists($object{$object}->{'off'})) {
+ my ($off, $size, $comment, $l);
+ $off = hex($object{$object}->{'off'});
+ $size = hex($object{$object}->{'size'});
+ open(OBJECT, "<$object") || die "cannot read $object";
+ seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
+ $l = read(OBJECT, $comment, $size);
+ die "read $size bytes from $object .comment failed" if ($l != $size);
+ close(OBJECT);
+ if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
+ ++$ignore;
+ delete($object{$object});
+ }
+ }
+}
+# printf("ignoring %d conglomerate(s)\n", $ignore);
+
+# printf("Scanning objects\n");
+$errorcount = 0;
+foreach $object (keys(%object)) {
+ my $from;
+ open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
+ while (defined($line = <OBJDUMP>)) {
+ chomp($line);
+ if ($line =~ /RELOCATION RECORDS FOR /) {
+ ($from = $line) =~ s/.*\[([^]]*).*/$1/;
+ }
+ if (($line =~ /\.text\.exit$/ ||
+ $line =~ /\.exit\.text$/ ||
+ $line =~ /\.data\.exit$/ ||
+ $line =~ /\.exit\.data$/ ||
+ $line =~ /\.exitcall\.exit$/) &&
+ ($from !~ /\.text\.exit$/ &&
+ $from !~ /\.exit\.text$/ &&
+ $from !~ /\.data\.exit$/ &&
+ $from !~ /\.exit\.data$/ &&
+ $from !~ /\.altinstructions$/ &&
+ $from !~ /\.pdr$/ &&
+ $from !~ /\.debug_info$/ &&
+ $from !~ /\.debug_aranges$/ &&
+ $from !~ /\.debug_ranges$/ &&
+ $from !~ /\.debug_line$/ &&
+ $from !~ /\.debug_frame$/ &&
+ $from !~ /\.exitcall\.exit$/ &&
+ $from !~ /\.eh_frame$/ &&
+ $from !~ /\.stab$/)) {
+ printf("Error: %s %s refers to %s\n", $object, $from, $line);
+ $errorcount = $errorcount + 1;
+ }
+ }
+ close(OBJDUMP);
+}
+# printf("Done\n");
+
+exit(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 @@
+#!/usr/bin/perl -w
+#
+# reference_init.pl (C) Keith Owens 2002 <kaos@ocs.com.au>
+#
+# List references to vmlinux init sections from non-init sections.
+
+# Unfortunately I had to exclude references from read only data to .init
+# sections, almost all of these are false positives, they are created by
+# gcc. The downside of excluding rodata is that there really are some
+# user references from rodata to init code, e.g. drivers/video/vgacon.c
+#
+# const struct consw vga_con = {
+# con_startup: vgacon_startup,
+#
+# where vgacon_startup is __init. If you want to wade through the false
+# positives, take out the check for rodata.
+
+use strict;
+die($0 . " takes no arguments\n") if($#ARGV >= 0);
+
+my %object;
+my $object;
+my $line;
+my $ignore;
+
+$| = 1;
+
+printf("Finding objects, ");
+open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
+while (defined($line = <OBJDUMP_LIST>)) {
+ chomp($line);
+ if ($line =~ /:\s+file format/) {
+ ($object = $line) =~ s/:.*//;
+ $object{$object}->{'module'} = 0;
+ $object{$object}->{'size'} = 0;
+ $object{$object}->{'off'} = 0;
+ }
+ if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
+ $object{$object}->{'module'} = 1;
+ }
+ if ($line =~ /^\s*\d+\s+\.comment\s+/) {
+ ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
+ }
+}
+close(OBJDUMP_LIST);
+printf("%d objects, ", scalar keys(%object));
+$ignore = 0;
+foreach $object (keys(%object)) {
+ if ($object{$object}->{'module'}) {
+ ++$ignore;
+ delete($object{$object});
+ }
+}
+printf("ignoring %d module(s)\n", $ignore);
+
+# Ignore conglomerate objects, they have been built from multiple objects and we
+# only care about the individual objects. If an object has more than one GCC:
+# string in the comment section then it is conglomerate. This does not filter
+# out conglomerates that consist of exactly one object, can't be helped.
+
+printf("Finding conglomerates, ");
+$ignore = 0;
+foreach $object (keys(%object)) {
+ if (exists($object{$object}->{'off'})) {
+ my ($off, $size, $comment, $l);
+ $off = hex($object{$object}->{'off'});
+ $size = hex($object{$object}->{'size'});
+ open(OBJECT, "<$object") || die "cannot read $object";
+ seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
+ $l = read(OBJECT, $comment, $size);
+ die "read $size bytes from $object .comment failed" if ($l != $size);
+ close(OBJECT);
+ if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
+ ++$ignore;
+ delete($object{$object});
+ }
+ }
+}
+printf("ignoring %d conglomerate(s)\n", $ignore);
+
+printf("Scanning objects\n");
+foreach $object (sort(keys(%object))) {
+ my $from;
+ open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
+ while (defined($line = <OBJDUMP>)) {
+ chomp($line);
+ if ($line =~ /RELOCATION RECORDS FOR /) {
+ ($from = $line) =~ s/.*\[([^]]*).*/$1/;
+ }
+ if (($line =~ /\.init$/ || $line =~ /\.init\./) &&
+ ($from !~ /\.init$/ &&
+ $from !~ /\.init\./ &&
+ $from !~ /\.stab$/ &&
+ $from !~ /\.rodata$/ &&
+ $from !~ /\.text\.lock$/ &&
+ $from !~ /\.pci_fixup_header$/ &&
+ $from !~ /\.pci_fixup_final$/ &&
+ $from !~ /\.pdr$/ &&
+ $from !~ /\__param$/ &&
+ $from !~ /\.altinstructions/ &&
+ $from !~ /\.debug_/)) {
+ printf("Error: %s %s refers to %s\n", $object, $from, $line);
+ }
+ }
+ close(OBJDUMP);
+}
+printf("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 @@
+#!/usr/bin/env python
+#
+# show_deltas: Read list of printk messages instrumented with
+# time data, and format with time deltas.
+#
+# Also, you can show the times relative to a fixed point.
+#
+# Copyright 2003 Sony Corporation
+#
+# GPL 2.0 applies.
+
+import sys
+import string
+
+def usage():
+ print """usage: show_delta [<options>] <filename>
+
+This program parses the output from a set of printk message lines which
+have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
+the kernel command line option "time" is specified. When run with no
+options, the time information is converted to show the time delta between
+each printk line and the next. When run with the '-b' option, all times
+are relative to a single (base) point in time.
+
+Options:
+ -h Show this usage help.
+ -b <base> Specify a base for time references.
+ <base> can be a number or a string.
+ If it is a string, the first message line
+ which matches (at the beginning of the
+ line) is used as the time reference.
+
+ex: $ dmesg >timefile
+ $ show_delta -b NET4 timefile
+
+will show times relative to the line in the kernel output
+starting with "NET4".
+"""
+ sys.exit(1)
+
+# returns a tuple containing the seconds and text for each message line
+# seconds is returned as a float
+# raise an exception if no timing data was found
+def get_time(line):
+ if line[0]!="[":
+ raise ValueError
+
+ # split on closing bracket
+ (time_str, rest) = string.split(line[1:],']',1)
+ time = string.atof(time_str)
+
+ #print "time=", time
+ return (time, rest)
+
+
+# average line looks like:
+# [ 0.084282] VFS: Mounted root (romfs filesystem) readonly
+# time data is expressed in seconds.useconds,
+# convert_line adds a delta for each line
+last_time = 0.0
+def convert_line(line, base_time):
+ global last_time
+
+ try:
+ (time, rest) = get_time(line)
+ except:
+ # if any problem parsing time, don't convert anything
+ return line
+
+ if base_time:
+ # show time from base
+ delta = time - base_time
+ else:
+ # just show time from last line
+ delta = time - last_time
+ last_time = time
+
+ return ("[%5.6f < %5.6f >]" % (time, delta)) + rest
+
+def main():
+ base_str = ""
+ filein = ""
+ for arg in sys.argv[1:]:
+ if arg=="-b":
+ base_str = sys.argv[sys.argv.index("-b")+1]
+ elif arg=="-h":
+ usage()
+ else:
+ filein = arg
+
+ if not filein:
+ usage()
+
+ try:
+ lines = open(filein,"r").readlines()
+ except:
+ print "Problem opening file: %s" % filein
+ sys.exit(1)
+
+ if base_str:
+ print 'base= "%s"' % base_str
+ # assume a numeric base. If that fails, try searching
+ # for a matching line.
+ try:
+ base_time = float(base_str)
+ except:
+ # search for line matching <base> string
+ found = 0
+ for line in lines:
+ try:
+ (time, rest) = get_time(line)
+ except:
+ continue
+ if string.find(rest, base_str)==1:
+ base_time = time
+ found = 1
+ # stop at first match
+ break
+ if not found:
+ print 'Couldn\'t find line matching base pattern "%s"' % base_str
+ sys.exit(1)
+ else:
+ base_time = 0.0
+
+ for line in lines:
+ print convert_line(line, base_time),
+
+main()
+
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 @@
+#!/usr/bin/perl
+
+use strict;
+
+## Copyright (C) Michael Still (mikal@stillhq.com)
+## Released under the terms of the GNU GPL
+##
+## Hoon through the specified DocBook SGML file, and split out the
+## man pages. These can then be processed into groff format, and
+## installed if desired...
+##
+## Arguements: $1 -- the name of the sgml file
+## $2 -- the directory to put the generated SGML files in
+## $3 -- kernel version
+
+my($SGML, $REF, $front, $refdata, $mode, $filename);
+
+if(($ARGV[0] eq "") || ($ARGV[1] eq "") || ($ARGV[2] eq "")){
+ die "Usage: split-man <sgml file> <output dir> <kernel version>\n";
+}
+
+open SGML, "< $ARGV[0]" or die "Could not open input file \"$ARGV[0]\"\n";
+if( ! -d "$ARGV[1]" ){
+ die "Output directory \"$ARGV[1]\" does not exist\n";
+}
+
+# Possible modes:
+# 0: Looking for input I care about
+# 1: Inside book front matter
+# 2: Inside a refentry
+# 3: Inside a refentry, and we know the filename
+
+$mode = 0;
+$refdata = "";
+$front = "";
+while(<SGML>){
+ # Starting modes
+ if(/<bookinfo>/ || /<docinfo>/){
+ $mode = 1;
+ }
+ elsif(/<refentry>/){
+ $mode = 2;
+ }
+ elsif(/<refentrytitle><phrase[^>]*>([^<]*)<.*$/){
+ $mode = 3;
+ $filename = $1;
+
+ $filename =~ s/struct //;
+ $filename =~ s/typedef //;
+
+ print "Found manpage for $filename\n";
+ open REF, "> $ARGV[1]/$filename.sgml" or
+ die "Couldn't open output file \"$ARGV[1]/$filename.sgml\": $!\n";
+ print REF <<EOF;
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<!-- BEGINFRONTTAG: The following is front matter for the parent book -->
+$front
+<!-- ENDFRONTTAG: End front matter -->
+
+$refdata
+EOF
+ $refdata = "";
+ }
+
+ # Extraction
+ if($mode == 1){
+ chomp $_;
+ $front = "$front<!-- $_ -->\n";
+ }
+ elsif($mode == 2){
+ $refdata = "$refdata$_";
+ }
+ elsif($mode == 3){
+ # There are some fixups which need to be applied
+ if(/<\/refmeta>/){
+ print REF "<manvolnum>9</manvolnum>\n";
+ }
+ if(/<\/refentry>/){
+ print REF <<EOF;
+<refsect1><title>About this document</title>
+<para>
+This documentation was generated with kernel version $ARGV[2].
+</para>
+</refsect1>
+EOF
+ }
+
+ # For some reason, we title the synopsis twice in the main DocBook
+ if(! /<title>Synopsis<\/title>/){
+ if(/<refentrytitle>/){
+ s/struct //;
+ s/typedef //;
+ }
+
+ print REF "$_";
+ }
+ }
+
+ # Ending modes
+ if(/<\/bookinfo>/ || /<\/docinfo>/){
+ $mode = 0;
+ }
+ elsif(/<\/refentry>/){
+ $mode = 0;
+ close REF;
+ }
+}
+
+# And make sure we don't process this unnessesarily
+$ARGV[0] =~ s/\.sgml/.9/;
+`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 @@
+#!/bin/sh
+# Before running this script please ensure that your PATH is
+# typical as you use for compilation/istallation. I use
+# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
+# differ on your system.
+#
+PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:$PATH
+echo 'If some fields are empty or look unusual you may have an old version.'
+echo 'Compare to the current minimal requirements in Documentation/Changes.'
+echo ' '
+
+uname -a
+echo ' '
+
+gcc --version 2>&1| head -n 1 | grep -v gcc | awk \
+'NR==1{print "Gnu C ", $1}'
+
+gcc --version 2>&1| grep gcc | awk \
+'NR==1{print "Gnu C ", $3}'
+
+make --version 2>&1 | awk -F, '{print $1}' | awk \
+ '/GNU Make/{print "Gnu make ",$NF}'
+
+ld -v | awk -F\) '{print $1}' | awk \
+'/BFD/{print "binutils ",$NF} \
+/^GNU/{print "binutils ",$4}'
+
+fdformat --version | awk -F\- '{print "util-linux ", $NF}'
+
+mount --version | awk -F\- '{print "mount ", $NF}'
+
+depmod -V 2>&1 | awk 'NR==1 {print "module-init-tools ",$NF}'
+
+tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \
+'NR==1 {print "e2fsprogs ", $2}'
+
+fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \
+'NR==1 {print "jfsutils ", $3}'
+
+reiserfsck -V 2>&1 | grep reiserfsck | awk \
+'NR==1{print "reiserfsprogs ", $2}'
+
+fsck.reiser4 -V 2>&1 | grep fsck.reiser4 | awk \
+'NR==1{print "reiser4progs ", $2}'
+
+xfs_db -V 2>&1 | grep version | awk \
+'NR==1{print "xfsprogs ", $3}'
+
+cardmgr -V 2>&1| grep version | awk \
+'NR==1{print "pcmcia-cs ", $3}'
+
+quota -V 2>&1 | grep version | awk \
+'NR==1{print "quota-tools ", $NF}'
+
+pppd --version 2>&1| grep version | awk \
+'NR==1{print "PPP ", $3}'
+
+isdnctrl 2>&1 | grep version | awk \
+'NR==1{print "isdn4k-utils ", $NF}'
+
+showmount --version 2>&1 | grep nfs-utils | awk \
+'NR==1{print "nfs-utils ", $NF}'
+
+ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \
+-e 's/\.so$//' | awk -F'[.-]' '{print "Linux C Library " \
+$(NF-2)"."$(NF-1)"."$NF}'
+
+ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -n 1 | awk \
+'NR==1{print "Dynamic linker (ldd) ", $NF}'
+
+ls -l /usr/lib/lib{g,stdc}++.so 2>/dev/null | awk -F. \
+ '{print "Linux C++ Library " $4"."$5"."$6}'
+
+ps --version 2>&1 | grep version | awk \
+'NR==1{print "Procps ", $NF}'
+
+ifconfig --version 2>&1 | grep tools | awk \
+'NR==1{print "Net-tools ", $NF}'
+
+# Kbd needs 'loadkeys -h',
+loadkeys -h 2>&1 | awk \
+'(NR==1 && ($3 !~ /option/)) {print "Kbd ", $3}'
+
+# while console-tools needs 'loadkeys -V'.
+loadkeys -V 2>&1 | awk \
+'(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools ", $3}'
+
+expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}'
+
+udevinfo -V | awk '{print "udev ", $3}'
+
+if [ -e /proc/modules ]; then
+ X=`cat /proc/modules | sed -e "s/ .*$//"`
+ echo "Modules Loaded "$X
+fi