diff options
author | 2005-04-16 15:20:36 -0700 | |
---|---|---|
committer | 2005-04-16 15:20:36 -0700 | |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /scripts | |
download | linux-dev-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.xz linux-dev-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip |
Linux-2.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')
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 = ¤t_entry->list; +} + +void menu_end_menu(void) +{ + last_entry_ptr = ¤t_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 |