(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
cmd_scripts/conmakehash := gcc -Wp,-MD,scripts/.conmakehash.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/conmakehash scripts/conmakehash.c
deps_scripts/conmakehash := \
scripts/conmakehash.c \
/usr/include/stdio.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/stdlib.h \
/usr/include/sys/types.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/alloca.h \
/usr/include/sysexits.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ctype.h \
scripts/conmakehash: $(deps_scripts/conmakehash)
$(deps_scripts/conmakehash):

View File

@@ -0,0 +1,41 @@
cmd_scripts/kallsyms := gcc -Wp,-MD,scripts/.kallsyms.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/kallsyms scripts/kallsyms.c
deps_scripts/kallsyms := \
scripts/kallsyms.c \
/usr/include/stdio.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/stdlib.h \
/usr/include/sys/types.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ctype.h \
scripts/kallsyms: $(deps_scripts/kallsyms)
$(deps_scripts/kallsyms):

View File

@@ -0,0 +1,2 @@
#!/bin/sh
indent -kr -i8 -ts8 -sob -l80 -ss -ncs "$@"

View File

@@ -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

View File

@@ -0,0 +1,331 @@
# ==========================================================================
# 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)
CHECKFLAGS += -I$(shell $(CC) -print-file-name=include)
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

View File

@@ -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

View File

@@ -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)

View File

@@ -0,0 +1,261 @@
# ===========================================================================
# 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
# ===========================================================================
# 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 $? \
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
$(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 $^),$^)\
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
$(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 $? \
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@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

View File

@@ -0,0 +1,28 @@
# ==========================================================================
# 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
modinst_dir = $(MODLIB)/$(if $(filter ../% /%,$@),$(INSTALL_MOD_DIR)/,kernel/$(@D))
$(modules):
$(call cmd,modules_install,$(modinst_dir))

View File

@@ -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

View File

@@ -0,0 +1,201 @@
Menuconfig gives the Linux kernel configuration a long needed face
lift. Featuring text based color menus and dialogs, it does not
require X Windows (however, you need ncurses in order to use it).
With this utility you can easily select a kernel option to modify
without sifting through 100 other options.
Overview
--------
Some kernel features may be built directly into the kernel.
Some may be made into loadable runtime modules. Some features
may be completely removed altogether. There are also certain
kernel parameters which are not really features, but must be
entered in as decimal or hexadecimal numbers or possibly text.
Menu items beginning with [*], <M> or [ ] represent features
configured to be built in, modularized or removed respectively.
Pointed brackets <> represent module capable features.
more...
To change any of these features, highlight it with the cursor
keys and press <Y> to build it in, <M> to make it a module or
<N> to removed it. You may also press the <Space Bar> to cycle
through the available options (ie. Y->N->M->Y).
Items beginning with numbers or other text within parenthesis can
be changed by highlighting the item and pressing <Enter>. Then
enter the new parameter into the dialog box that pops up.
Some additional keyboard hints:
Menus
----------
o Use the Up/Down arrow keys (cursor keys) to highlight the item
you wish to change or submenu wish to select and press <Enter>.
Submenus are designated by "--->".
Shortcut: Press the option's highlighted letter (hotkey).
Pressing a hotkey more than once will sequence
through all visible items which use that hotkey.
You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll
unseen options into view.
o To exit a menu use the cursor keys to highlight the <Exit> button
and press <ENTER>.
Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey
using those letters. You may press a single <ESC>, but
there is a delayed response which you may find annoying.
Also, the <TAB> and cursor keys will cycle between <Select>,
<Exit> and <Help>
o To get help with an item, use the cursor keys to highlight <Help>
and Press <ENTER>.
Shortcut: Press <H> or <?>.
Radiolists (Choice lists)
-----------
o Use the cursor keys to select the option you wish to set and press
<S> or the <SPACE BAR>.
Shortcut: Press the first letter of the option you wish to set then
press <S> or <SPACE BAR>.
o To see available help for the item, use the cursor keys to highlight
<Help> and Press <ENTER>.
Shortcut: Press <H> or <?>.
Also, the <TAB> and cursor keys will cycle between <Select> and
<Help>
Data Entry
-----------
o Enter the requested information and press <ENTER>
If you are entering hexadecimal values, it is not necessary to
add the '0x' prefix to the entry.
o For help, use the <TAB> or cursor keys to highlight the help option
and press <ENTER>. You can try <TAB><H> as well.
Text Box (Help Window)
--------
o Use the cursor keys to scroll up/down/left/right. The VI editor
keys h,j,k,l function here as do <SPACE BAR> and <B> for those
who are familiar with less and lynx.
o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.
Final Acceptance
----------------
With the exception of the old style sound configuration,
YOUR CHANGES ARE NOT FINAL. You will be given a last chance to
confirm them prior to exiting Menuconfig.
If Menuconfig quits with an error while saving your configuration,
you may look in the file /usr/src/linux/.menuconfig.log for
information which may help you determine the cause.
Alternate Configuration Files
-----------------------------
Menuconfig supports the use of alternate configuration files for
those who, for various reasons, find it necessary to switch
between different kernel configurations.
At the end of the main menu you will find two options. One is
for saving the current configuration to a file of your choosing.
The other option is for loading a previously saved alternate
configuration.
Even if you don't use alternate configuration files, but you
find during a Menuconfig session that you have completely messed
up your settings, you may use the "Load Alternate..." option to
restore your previously saved settings from ".config" without
restarting Menuconfig.
Other information
-----------------
The windowing utility, lxdialog, will only be rebuilt if your kernel
source tree is fresh, or changes are patched into it via a kernel
patch or you do 'make mrproper'. If changes to lxdialog are patched
in, most likely the rebuild time will be short. You may force a
complete rebuild of lxdialog by changing to its directory and doing
'make clean all'
If you use Menuconfig in an XTERM window make sure you have your
$TERM variable set to point to a xterm definition which supports color.
Otherwise, Menuconfig will look rather bad. Menuconfig will not
display correctly in a RXVT window because rxvt displays only one
intensity of color, bright.
Menuconfig will display larger menus on screens or xterms which are
set to display more than the standard 25 row by 80 column geometry.
In order for this to work, the "stty size" command must be able to
display the screen's current row and column geometry. I STRONGLY
RECOMMEND that you make sure you do NOT have the shell variables
LINES and COLUMNS exported into your environment. Some distributions
export those variables via /etc/profile. Some ncurses programs can
become confused when those variables (LINES & COLUMNS) don't reflect
the true screen size.
NOTICE: lxdialog requires the ncurses libraries to compile. If you
don't already have ncurses you really should get it.
The makefile for lxdialog attempts to find your ncurses
header file. Although it should find the header for older
versions of ncurses, it is probably a good idea to get the
latest ncurses anyway.
If you have upgraded your ncurses libraries, MAKE SURE you
remove the old ncurses header files. If you don't you
will most certainly get a segmentation fault.
WARNING: It is not recommended that you change any defines in
lxdialog's header files. If you have a grayscale display and
are brave, you may tinker with color.h to tune the colors to
your preference.
COMPATIBILITY ISSUE:
There have been some compatibility problems reported with
older versions of bash and sed. I am trying to work these
out but it is preferable that you upgrade those utilities.
******** IMPORTANT, OPTIONAL ALTERNATE PERSONALITY AVAILABLE ********
******** ********
If you prefer to have all of the kernel options listed in a single
menu, rather than the default multimenu hierarchy, run the menuconfig
with MENUCONFIG_MODE environment variable set to single_menu. Example:
make menuconfig MENUCONFIG_MODE=single_menu
<Enter> will then unroll the appropriate category, or enfold it if it
is already unrolled.
Note that this mode can eventually be a little more CPU expensive
(especially with a larger number of unrolled categories) than the
default mode.
*********************************************************************
Propaganda
----------
The windowing support utility (lxdialog) is a VERY modified version of
the dialog utility by Savio Lam <lam836@cs.cuhk.hk>. Although lxdialog
is significantly different from dialog, I have left Savio's copyrights
intact. Please DO NOT contact Savio with questions about lxdialog.
He will not be able to assist.
William Roadcap was the original author of Menuconfig.
Michael Elizabeth Chastain <mec@shout.net> is the current maintainer.
<END OF FILE>

View File

@@ -0,0 +1,66 @@
cmd_scripts/basic/docproc := gcc -Wp,-MD,scripts/basic/.docproc.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/docproc scripts/basic/docproc.c
deps_scripts/basic/docproc := \
scripts/basic/docproc.c \
/usr/include/stdio.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/stdlib.h \
/usr/include/sys/types.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ctype.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/limits.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
/usr/include/sys/wait.h \
/usr/include/signal.h \
/usr/include/bits/signum.h \
/usr/include/bits/siginfo.h \
/usr/include/bits/sigaction.h \
/usr/include/bits/sigcontext.h \
/usr/include/asm/sigcontext.h \
/usr/include/linux/compiler.h \
/usr/include/bits/sigstack.h \
/usr/include/bits/sigthread.h \
/usr/include/sys/resource.h \
/usr/include/bits/resource.h \
/usr/include/bits/waitflags.h \
/usr/include/bits/waitstatus.h \
scripts/basic/docproc: $(deps_scripts/basic/docproc)
$(deps_scripts/basic/docproc):

View File

@@ -0,0 +1,75 @@
cmd_scripts/basic/fixdep := gcc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/fixdep scripts/basic/fixdep.c
deps_scripts/basic/fixdep := \
scripts/basic/fixdep.c \
$(wildcard include/config/his/driver.h) \
$(wildcard include/config/my/option.h) \
$(wildcard include/config/.h) \
$(wildcard include/config/foo.h) \
$(wildcard include/config/boom.h) \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/sys/stat.h \
/usr/include/bits/stat.h \
/usr/include/sys/mman.h \
/usr/include/bits/mman.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/limits.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
/usr/include/ctype.h \
/usr/include/arpa/inet.h \
/usr/include/netinet/in.h \
/usr/include/stdint.h \
/usr/include/sys/socket.h \
/usr/include/sys/uio.h \
/usr/include/bits/uio.h \
/usr/include/bits/socket.h \
/usr/include/bits/sockaddr.h \
/usr/include/asm/socket.h \
/usr/include/asm/sockios.h \
/usr/include/bits/in.h \
/usr/include/bits/byteswap.h \
scripts/basic/fixdep: $(deps_scripts/basic/fixdep)
$(deps_scripts/basic/fixdep):

View File

@@ -0,0 +1,56 @@
cmd_scripts/basic/split-include := gcc -Wp,-MD,scripts/basic/.split-include.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/split-include scripts/basic/split-include.c
deps_scripts/basic/split-include := \
scripts/basic/split-include.c \
$(wildcard include/config/.h) \
/usr/include/sys/stat.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/bits/stat.h \
/usr/include/sys/types.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/ctype.h \
/usr/include/errno.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
/usr/include/asm-generic/errno.h \
/usr/include/asm-generic/errno-base.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
scripts/basic/split-include: $(deps_scripts/basic/split-include)
$(deps_scripts/basic/split-include):

View File

@@ -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

Binary file not shown.

View File

@@ -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;
}

Binary file not shown.

View File

@@ -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;
}

Binary file not shown.

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,115 @@
#!/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
# 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;
} 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 > 0x80000000) {
$size = - $size;
$size += 0x80000000;
$size += 0x80000000;
}
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;

View File

@@ -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);
}

Binary file not shown.

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,118 @@
#!/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 pointed
# out by the environment variable: CONFIG_INITRAMFS_SOURCE
#
# If CONFIG_INITRAMFS_SOURCE is non-existing then generate a small dummy file.
#
# The output is suitable for gen_init_cpio as found in usr/Makefile.
#
# TODO: Add support for symlinks, sockets and pipes when gen_init_cpio
# supports them.
simple_initramfs() {
cat <<-EOF
# This is a very simple 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"
if [ -f "${argv1}" ]; then
echo "file"
elif [ -d "${argv1}" ]; then
echo "dir"
elif [ -b "${argv1}" -o -c "${argv1}" ]; then
echo "nod"
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}//}"
local mode="$2"
local uid="$3"
local gid="$4"
local ftype=$(filetype "${location}")
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}"
;;
*)
str="${ftype} ${name} ${str}"
;;
esac
echo "${str}"
return 0
}
if [ -z "$1" ]; then
simple_initramfs
elif [ -f "$1" ]; then
print_mtime "$1"
cat "$1"
elif [ -d "$1" ]; then
srcdir=$(echo "$1" | 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 "$1"
echo "${dirlist}" | \
while read x; do
parse ${x}
done
else
# Failsafe in case directory is empty
simple_initramfs
fi
else
echo " $0: Cannot open '$1' (CONFIG_INITRAMFS_SOURCE)" >&2
exit 1
fi
exit 0

View File

@@ -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

View File

@@ -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;
}

View File

@@ -0,0 +1,96 @@
/* 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>
#include <assert.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); assert(__ptr || size == 0); __ptr; })
#define xstrdup(str) ({ char *__str = strdup(str); assert(__str); __str; })
#endif /* genksyms.h */

View File

@@ -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;
}

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -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);
}

Binary file not shown.

View File

@@ -0,0 +1,677 @@
/* 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;
}
/* 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;
}

View File

@@ -0,0 +1,51 @@
cmd_scripts/kconfig/conf.o := gcc -Wp,-MD,scripts/kconfig/.conf.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -c -o scripts/kconfig/conf.o scripts/kconfig/conf.c
deps_scripts/kconfig/conf.o := \
scripts/kconfig/conf.c \
/usr/include/ctype.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/stdlib.h \
/usr/include/sys/types.h \
/usr/include/time.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/sys/stat.h \
/usr/include/bits/stat.h \
scripts/kconfig/lkc.h \
scripts/kconfig/expr.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/kconfig/lkc_proto.h \
scripts/kconfig/conf.o: $(deps_scripts/kconfig/conf.o)
$(deps_scripts/kconfig/conf.o):

View File

@@ -0,0 +1 @@
cmd_scripts/kconfig/mconf := gcc -o scripts/kconfig/mconf scripts/kconfig/mconf.o scripts/kconfig/zconf.tab.o

View File

@@ -0,0 +1,89 @@
cmd_scripts/kconfig/mconf.o := gcc -Wp,-MD,scripts/kconfig/.mconf.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -c -o scripts/kconfig/mconf.o scripts/kconfig/mconf.c
deps_scripts/kconfig/mconf.o := \
scripts/kconfig/mconf.c \
$(wildcard include/config/.h) \
$(wildcard include/config/mode.h) \
/usr/include/sys/ioctl.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/ioctls.h \
/usr/include/asm/ioctls.h \
/usr/include/asm/ioctl.h \
/usr/include/bits/ioctl-types.h \
/usr/include/sys/ttydefaults.h \
/usr/include/sys/wait.h \
/usr/include/signal.h \
/usr/include/bits/sigset.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/bits/signum.h \
/usr/include/time.h \
/usr/include/bits/siginfo.h \
/usr/include/bits/sigaction.h \
/usr/include/bits/sigcontext.h \
/usr/include/asm/sigcontext.h \
/usr/include/linux/compiler.h \
/usr/include/bits/sigstack.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/bits/sigthread.h \
/usr/include/sys/resource.h \
/usr/include/bits/resource.h \
/usr/include/bits/time.h \
/usr/include/bits/waitflags.h \
/usr/include/bits/waitstatus.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/ctype.h \
/usr/include/errno.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
/usr/include/asm-generic/errno.h \
/usr/include/asm-generic/errno-base.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/sys/types.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/sys/sysmacros.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/limits.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/termios.h \
/usr/include/bits/termios.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/regex.h \
scripts/kconfig/lkc.h \
scripts/kconfig/expr.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/kconfig/lkc_proto.h \
scripts/kconfig/mconf.o: $(deps_scripts/kconfig/mconf.o)
$(deps_scripts/kconfig/mconf.o):

View File

@@ -0,0 +1,73 @@
cmd_scripts/kconfig/zconf.tab.o := gcc -Wp,-MD,scripts/kconfig/.zconf.tab.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -Iscripts/kconfig -c -o scripts/kconfig/zconf.tab.o scripts/kconfig/zconf.tab.c
deps_scripts/kconfig/zconf.tab.o := \
scripts/kconfig/zconf.tab.c \
/usr/include/ctype.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/stdlib.h \
/usr/include/sys/types.h \
/usr/include/time.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/kconfig/lkc.h \
scripts/kconfig/expr.h \
scripts/kconfig/lkc_proto.h \
scripts/kconfig/lex.zconf.c \
/usr/include/errno.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
/usr/include/asm-generic/errno.h \
/usr/include/asm-generic/errno-base.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/limits.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
scripts/kconfig/confdata.c \
$(wildcard include/config/.h) \
$(wildcard include/config/notimestamp.h) \
/usr/include/sys/stat.h \
/usr/include/bits/stat.h \
scripts/kconfig/expr.c \
scripts/kconfig/symbol.c \
/usr/include/sys/utsname.h \
/usr/include/bits/utsname.h \
scripts/kconfig/menu.c \
scripts/kconfig/zconf.tab.o: $(deps_scripts/kconfig/zconf.tab.o)
$(deps_scripts/kconfig/zconf.tab.o):

View File

@@ -0,0 +1,202 @@
# ===========================================================================
# 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 ' oldconfig - 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 ' 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)/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

View File

@@ -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;
}

Binary file not shown.

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
/*
* 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);
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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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>

View File

@@ -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",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};

View File

@@ -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
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
/*
* 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);
struct file *file_lookup(const char *name);
int file_write_dep(const char *name);
/* 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 */

View File

@@ -0,0 +1,39 @@
/* 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_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));

Binary file not shown.

View File

@@ -0,0 +1,942 @@
/*
* 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>
#include <regex.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
static char menu_backtitle[128];
static const char 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"
;
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_readme(void);
static void show_file(const char *filename, const char *title, int r, int c);
static void show_expr(struct menu *menu, FILE *fp);
static void search_conf(char *pattern);
static int regex_match(const char *string, regex_t *re);
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;
}
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 int regex_match(const char *string, regex_t *re)
{
int rc;
rc = regexec(re, string, (size_t) 0, NULL, 0);
if (rc)
return 0;
return 1;
}
static void show_expr(struct menu *menu, FILE *fp)
{
bool hit = false;
fprintf(fp, "Depends:\n ");
if (menu->prompt->visible.expr) {
if (!hit)
hit = true;
expr_fprint(menu->prompt->visible.expr, fp);
}
if (!hit)
fprintf(fp, "None");
if (menu->sym) {
struct property *prop;
hit = false;
fprintf(fp, "\nSelects:\n ");
for_all_properties(menu->sym, prop, P_SELECT) {
if (!hit)
hit = true;
expr_fprint(prop->expr, fp);
}
if (!hit)
fprintf(fp, "None");
hit = false;
fprintf(fp, "\nSelected by:\n ");
if (menu->sym->rev_dep.expr) {
hit = true;
expr_fprint(menu->sym->rev_dep.expr, fp);
}
if (!hit)
fprintf(fp, "None");
}
}
static void search_conf(char *pattern)
{
struct symbol *sym = NULL;
struct menu *menu[32] = { 0 };
struct property *prop = NULL;
FILE *fp = NULL;
bool hit = false;
int i, j, k, l;
regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB))
return;
fp = fopen(".search.tmp", "w");
if (fp == NULL) {
perror("fopen");
return;
}
for_all_symbols(i, sym) {
if (!sym->name)
continue;
if (!regex_match(sym->name, &re))
continue;
for_all_prompts(sym, prop) {
struct menu *submenu = prop->menu;
if (!submenu)
continue;
j = 0;
hit = false;
while (submenu) {
menu[j++] = submenu;
submenu = submenu->parent;
}
if (j > 0) {
if (!hit)
hit = true;
fprintf(fp, "%s (%s)\n", prop->text, sym->name);
fprintf(fp, "Location:\n");
}
for (k = j-2, l=1; k > 0; k--, l++) {
const char *prompt = menu_get_prompt(menu[k]);
if (menu[k]->sym)
fprintf(fp, "%*c-> %s (%s)\n",
l, ' ',
prompt,
menu[k]->sym->name);
else
fprintf(fp, "%*c-> %s\n",
l, ' ',
prompt);
}
if (hit) {
show_expr(menu[0], fp);
fprintf(fp, "\n\n\n");
}
}
}
if (!hit)
fprintf(fp, "No matches found.");
regfree(&re);
fclose(fp);
show_file(".search.tmp", "Search Results", rows, cols);
unlink(".search.tmp");
}
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 == 26) {
char *pattern;
if (!strlen(input_buf))
continue;
pattern = malloc(sizeof(char)*sizeof(input_buf));
if (pattern == NULL) {
perror("malloc");
continue;
}
for (i = 0; input_buf[i]; i++)
pattern[i] = toupper(input_buf[i]);
pattern[i] = '\0';
search_conf(pattern);
free(pattern);
continue;
}
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_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;
}
}
}
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, rows, cols);
}
static void show_help(struct menu *menu)
{
const char *help;
char *helptext;
struct symbol *sym = menu->sym;
help = sym->help;
if (!help)
help = nohelp_text;
if (sym->name) {
helptext = malloc(strlen(sym->name) + strlen(help) + 16);
sprintf(helptext, "CONFIG_%s:\n\n%s", sym->name, help);
show_helptext(menu_get_prompt(menu), helptext);
free(helptext);
} else
show_helptext(menu_get_prompt(menu), help);
}
static void show_readme(void)
{
show_file("scripts/README.Menuconfig", NULL, rows, cols);
}
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);
cprint("%d", c);
} 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;
}

Binary file not shown.

View File

@@ -0,0 +1,430 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <stdlib.h>
#include <string.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct menu rootmenu;
static struct menu **last_entry_ptr;
struct file *file_list;
struct file *current_file;
static void menu_warn(struct menu *menu, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
static void prop_warn(struct property *prop, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
void menu_init(void)
{
current_entry = current_menu = &rootmenu;
last_entry_ptr = &rootmenu.list;
}
void menu_add_entry(struct symbol *sym)
{
struct menu *menu;
menu = malloc(sizeof(*menu));
memset(menu, 0, sizeof(*menu));
menu->sym = sym;
menu->parent = current_menu;
menu->file = current_file;
menu->lineno = zconf_lineno();
*last_entry_ptr = menu;
last_entry_ptr = &menu->next;
current_entry = menu;
}
void menu_end_entry(void)
{
}
void menu_add_menu(void)
{
current_menu = current_entry;
last_entry_ptr = &current_entry->list;
}
void menu_end_menu(void)
{
last_entry_ptr = &current_menu->next;
current_menu = current_menu->parent;
}
struct expr *menu_check_dep(struct expr *e)
{
if (!e)
return e;
switch (e->type) {
case E_NOT:
e->left.expr = menu_check_dep(e->left.expr);
break;
case E_OR:
case E_AND:
e->left.expr = menu_check_dep(e->left.expr);
e->right.expr = menu_check_dep(e->right.expr);
break;
case E_SYMBOL:
/* change 'm' into 'm' && MODULES */
if (e->left.sym == &symbol_mod)
return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
break;
default:
break;
}
return e;
}
void menu_add_dep(struct expr *dep)
{
current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
}
void menu_set_type(int type)
{
struct symbol *sym = current_entry->sym;
if (sym->type == type)
return;
if (sym->type == S_UNKNOWN) {
sym->type = type;
return;
}
menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n",
sym->name ? sym->name : "<choice>",
sym_type_name(sym->type), sym_type_name(type));
}
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
{
struct property *prop = prop_alloc(type, current_entry->sym);
prop->menu = current_entry;
prop->text = prompt;
prop->expr = expr;
prop->visible.expr = menu_check_dep(dep);
if (prompt) {
if (current_entry->prompt)
menu_warn(current_entry, "prompt redefined\n");
current_entry->prompt = prop;
}
return prop;
}
void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
{
menu_add_prop(type, prompt, NULL, dep);
}
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
{
menu_add_prop(type, NULL, expr, dep);
}
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
{
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
}
void sym_check_prop(struct symbol *sym)
{
struct property *prop;
struct symbol *sym2;
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
case P_DEFAULT:
if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
prop->expr->type != E_SYMBOL)
prop_warn(prop,
"default for config symbol '%'"
" must be a single symbol", sym->name);
break;
case P_SELECT:
sym2 = prop_get_symbol(prop);
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
prop_warn(prop,
"config symbol '%s' uses select, but is "
"not boolean or tristate", sym->name);
else if (sym2->type == S_UNKNOWN)
prop_warn(prop,
"'select' used by config symbol '%s' "
"refer to undefined symbol '%s'",
sym->name, sym2->name);
else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
prop_warn(prop,
"'%s' has wrong type. 'select' only "
"accept arguments of boolean and "
"tristate type", sym2->name);
break;
case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
!sym_string_valid(sym, prop->expr->right.sym->name))
prop_warn(prop, "range is invalid");
break;
default:
;
}
}
}
void menu_finalize(struct menu *parent)
{
struct menu *menu, *last_menu;
struct symbol *sym;
struct property *prop;
struct expr *parentdep, *basedep, *dep, *dep2, **ep;
sym = parent->sym;
if (parent->list) {
if (sym && sym_is_choice(sym)) {
/* find the first choice value and find out choice type */
for (menu = parent->list; menu; menu = menu->next) {
if (menu->sym) {
current_entry = parent;
menu_set_type(menu->sym->type);
current_entry = menu;
menu_set_type(sym->type);
break;
}
}
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
parentdep = parent->prompt->visible.expr;
else
parentdep = parent->dep;
for (menu = parent->list; menu; menu = menu->next) {
basedep = expr_transform(menu->dep);
basedep = expr_alloc_and(expr_copy(parentdep), basedep);
basedep = expr_eliminate_dups(basedep);
menu->dep = basedep;
if (menu->sym)
prop = menu->sym->prop;
else
prop = menu->prompt;
for (; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
dep = expr_transform(prop->visible.expr);
dep = expr_alloc_and(expr_copy(basedep), dep);
dep = expr_eliminate_dups(dep);
if (menu->sym && menu->sym->type != S_TRISTATE)
dep = expr_trans_bool(dep);
prop->visible.expr = dep;
if (prop->type == P_SELECT) {
struct symbol *es = prop_get_symbol(prop);
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
}
}
}
for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu);
} else if (sym) {
basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep));
last_menu = NULL;
for (menu = parent->next; menu; menu = menu->next) {
dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
if (!expr_contains_symbol(dep, sym))
break;
if (expr_depends_symbol(dep, sym))
goto next;
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
dep = expr_eliminate_dups(expr_transform(dep));
dep2 = expr_copy(basedep);
expr_eliminate_eq(&dep, &dep2);
expr_free(dep);
if (!expr_is_yes(dep2)) {
expr_free(dep2);
break;
}
expr_free(dep2);
next:
menu_finalize(menu);
menu->parent = parent;
last_menu = menu;
}
if (last_menu) {
parent->list = parent->next;
parent->next = last_menu->next;
last_menu->next = NULL;
}
}
for (menu = parent->list; menu; menu = menu->next) {
if (sym && sym_is_choice(sym) && menu->sym) {
menu->sym->flags |= SYMBOL_CHOICEVAL;
if (!menu->prompt)
menu_warn(menu, "choice value must have a prompt");
for (prop = menu->sym->prop; prop; prop = prop->next) {
if (prop->type == P_PROMPT && prop->menu != menu) {
prop_warn(prop, "choice values "
"currently only support a "
"single prompt");
}
if (prop->type == P_DEFAULT)
prop_warn(prop, "defaults for choice "
"values not supported");
}
current_entry = menu;
menu_set_type(sym->type);
menu_add_symbol(P_CHOICE, sym, NULL);
prop = sym_get_choice_prop(sym);
for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
;
*ep = expr_alloc_one(E_CHOICE, NULL);
(*ep)->right.sym = menu->sym;
}
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
for (last_menu = menu->list; ; last_menu = last_menu->next) {
last_menu->parent = parent;
if (!last_menu->next)
break;
}
last_menu->next = menu->next;
menu->next = menu->list;
menu->list = NULL;
}
}
if (sym && !(sym->flags & SYMBOL_WARNED)) {
if (sym->type == S_UNKNOWN)
menu_warn(parent, "config symbol defined "
"without type\n");
if (sym_is_choice(sym) && !parent->prompt)
menu_warn(parent, "choice must have a prompt\n");
/* Check properties connected to this symbol */
sym_check_prop(sym);
sym->flags |= SYMBOL_WARNED;
}
if (sym && !sym_is_optional(sym) && parent->prompt) {
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
expr_alloc_and(parent->prompt->visible.expr,
expr_alloc_symbol(&symbol_mod)));
}
}
bool menu_is_visible(struct menu *menu)
{
struct menu *child;
struct symbol *sym;
tristate visible;
if (!menu->prompt)
return false;
sym = menu->sym;
if (sym) {
sym_calc_value(sym);
visible = menu->prompt->visible.tri;
} else
visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
if (visible != no)
return true;
if (!sym || sym_get_tristate_value(menu->sym) == no)
return false;
for (child = menu->list; child; child = child->next)
if (menu_is_visible(child))
return true;
return false;
}
const char *menu_get_prompt(struct menu *menu)
{
if (menu->prompt)
return menu->prompt->text;
else if (menu->sym)
return menu->sym->name;
return NULL;
}
struct menu *menu_get_root_menu(struct menu *menu)
{
return &rootmenu;
}
struct menu *menu_get_parent_menu(struct menu *menu)
{
enum prop_type type;
for (; menu != &rootmenu; menu = menu->parent) {
type = menu->prompt ? menu->prompt->type : 0;
if (type == P_MENU)
break;
}
return menu;
}
struct file *file_lookup(const char *name)
{
struct file *file;
for (file = file_list; file; file = file->next) {
if (!strcmp(name, file->name))
return file;
}
file = malloc(sizeof(*file));
memset(file, 0, sizeof(*file));
file->name = strdup(name);
file->next = file_list;
file_list = file;
return file;
}
int file_write_dep(const char *name)
{
struct file *file;
FILE *out;
if (!name)
name = ".config.cmd";
out = fopen("..config.tmp", "w");
if (!out)
return 1;
fprintf(out, "deps_config := \\\n");
for (file = file_list; file; file = file->next) {
if (file->next)
fprintf(out, "\t%s \\\n", file->name);
else
fprintf(out, "\t%s\n", file->name);
}
fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
fclose(out);
rename("..config.tmp", name);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,263 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <qlistview.h>
#if QT_VERSION >= 300
#include <qsettings.h>
#else
class QSettings { };
#endif
class ConfigList;
class ConfigItem;
class ConfigLineEdit;
class ConfigMainWindow;
class ConfigSettings : public QSettings {
public:
ConfigSettings();
#if QT_VERSION >= 300
void readListSettings();
QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok);
bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value);
#endif
bool showAll;
bool showName;
bool showRange;
bool showData;
};
class ConfigView : public QVBox {
Q_OBJECT
typedef class QVBox Parent;
public:
ConfigView(QWidget* parent, ConfigMainWindow* cview, ConfigSettings* configSettings);
~ConfigView(void);
static void updateList(ConfigItem* item);
static void updateListAll(void);
public:
ConfigList* list;
ConfigLineEdit* lineEdit;
static ConfigView* viewList;
ConfigView* nextView;
};
enum colIdx {
promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
};
enum listMode {
singleMode, menuMode, symbolMode, fullMode
};
class ConfigList : public QListView {
Q_OBJECT
typedef class QListView Parent;
public:
ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings);
void reinit(void);
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
protected:
ConfigMainWindow* cview;
void keyPressEvent(QKeyEvent *e);
void contentsMousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e);
void contentsMouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e);
public slots:
void setRootMenu(struct menu *menu);
void updateList(ConfigItem *item);
void setValue(ConfigItem* item, tristate val);
void changeValue(ConfigItem* item);
void updateSelection(void);
signals:
void menuSelected(struct menu *menu);
void parentSelected(void);
void gotFocus(void);
public:
void updateListAll(void)
{
updateAll = true;
updateList(NULL);
updateAll = false;
}
ConfigList* listView()
{
return this;
}
ConfigItem* firstChild() const
{
return (ConfigItem *)Parent::firstChild();
}
int mapIdx(colIdx idx)
{
return colMap[idx];
}
void addColumn(colIdx idx, const QString& label)
{
colMap[idx] = Parent::addColumn(label);
colRevMap[colMap[idx]] = idx;
}
void removeColumn(colIdx idx)
{
int col = colMap[idx];
if (col >= 0) {
Parent::removeColumn(col);
colRevMap[col] = colMap[idx] = -1;
}
}
void setAllOpen(bool open);
void setParentMenu(void);
template <class P>
void ConfigList::updateMenuList(P*, struct menu*);
bool updateAll;
QPixmap symbolYesPix, symbolModPix, symbolNoPix;
QPixmap choiceYesPix, choiceNoPix;
QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
bool showAll, showName, showRange, showData;
enum listMode mode;
struct menu *rootEntry;
QColorGroup disabledColorGroup;
QColorGroup inactivedColorGroup;
private:
int colMap[colNr];
int colRevMap[colNr];
};
class ConfigItem : public QListViewItem {
typedef class QListViewItem Parent;
public:
ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), menu(m), visible(v), goParent(false)
{
init();
}
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), menu(m), visible(v), goParent(false)
{
init();
}
ConfigItem(QListView *parent, ConfigItem *after, bool v)
: Parent(parent, after), menu(0), visible(v), goParent(true)
{
init();
}
~ConfigItem(void);
void init(void);
#if QT_VERSION >= 300
void okRename(int col);
#endif
void updateMenu(void);
void testUpdateMenu(bool v);
ConfigList* listView() const
{
return (ConfigList*)Parent::listView();
}
ConfigItem* firstChild() const
{
return (ConfigItem *)Parent::firstChild();
}
ConfigItem* nextSibling() const
{
return (ConfigItem *)Parent::nextSibling();
}
void setText(colIdx idx, const QString& text)
{
Parent::setText(listView()->mapIdx(idx), text);
}
QString text(colIdx idx) const
{
return Parent::text(listView()->mapIdx(idx));
}
void setPixmap(colIdx idx, const QPixmap& pm)
{
Parent::setPixmap(listView()->mapIdx(idx), pm);
}
const QPixmap* pixmap(colIdx idx) const
{
return Parent::pixmap(listView()->mapIdx(idx));
}
void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
ConfigItem* nextItem;
struct menu *menu;
bool visible;
bool goParent;
};
class ConfigLineEdit : public QLineEdit {
Q_OBJECT
typedef class QLineEdit Parent;
public:
ConfigLineEdit(ConfigView* parent)
: Parent(parent)
{ }
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
void show(ConfigItem *i);
void keyPressEvent(QKeyEvent *e);
public:
ConfigItem *item;
};
class ConfigMainWindow : public QMainWindow {
Q_OBJECT
public:
ConfigMainWindow(void);
public slots:
void setHelp(QListViewItem* item);
void changeMenu(struct menu *);
void listFocusChanged(void);
void goBack(void);
void loadConfig(void);
void saveConfig(void);
void saveConfigAs(void);
void showSingleView(void);
void showSplitView(void);
void showFullView(void);
void setShowAll(bool);
void setShowDebug(bool);
void setShowRange(bool);
void setShowName(bool);
void setShowData(bool);
void showIntro(void);
void showAbout(void);
void saveSettings(void);
protected:
void closeEvent(QCloseEvent *e);
ConfigView *menuView;
ConfigList *menuList;
ConfigView *configView;
ConfigList *configList;
QTextView *helpText;
QToolBar *toolBar;
QAction *backAction;
QSplitter* split1;
QSplitter* split2;
bool showDebug;
};

View File

@@ -0,0 +1,778 @@
/*
* 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 <sys/utsname.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
.flags = SYMBOL_YES|SYMBOL_VALID,
}, symbol_mod = {
.name = "m",
.curr = { "m", mod },
.flags = SYMBOL_MOD|SYMBOL_VALID,
}, symbol_no = {
.name = "n",
.curr = { "n", no },
.flags = SYMBOL_NO|SYMBOL_VALID,
}, symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
};
int sym_change_count;
struct symbol *modules_sym;
tristate modules_val;
void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = prop_alloc(P_DEFAULT, sym);
prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
}
void sym_init(void)
{
struct symbol *sym;
struct utsname uts;
char *p;
static bool inited = false;
if (inited)
return;
inited = true;
uname(&uts);
sym = sym_lookup("ARCH", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("ARCH");
if (p)
sym_add_default(sym, p);
sym = sym_lookup("KERNELRELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
p = getenv("KERNELRELEASE");
if (p)
sym_add_default(sym, p);
sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
sym_add_default(sym, uts.release);
}
enum symbol_type sym_get_type(struct symbol *sym)
{
enum symbol_type type = sym->type;
if (type == S_TRISTATE) {
if (sym_is_choice_value(sym) && sym->visible == yes)
type = S_BOOLEAN;
else if (modules_val == no)
type = S_BOOLEAN;
}
return type;
}
const char *sym_type_name(enum symbol_type type)
{
switch (type) {
case S_BOOLEAN:
return "boolean";
case S_TRISTATE:
return "tristate";
case S_INT:
return "integer";
case S_HEX:
return "hex";
case S_STRING:
return "string";
case S_UNKNOWN:
return "unknown";
case S_OTHER:
break;
}
return "???";
}
struct property *sym_get_choice_prop(struct symbol *sym)
{
struct property *prop;
for_all_choices(sym, prop)
return prop;
return NULL;
}
struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
for_all_defaults(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri != no)
return prop;
}
return NULL;
}
struct property *sym_get_range_prop(struct symbol *sym)
{
struct property *prop;
for_all_properties(sym, prop, P_RANGE) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri != no)
return prop;
}
return NULL;
}
static void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
tristate tri;
/* any prompt visible? */
tri = no;
for_all_prompts(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
tri = E_OR(tri, prop->visible.tri);
}
if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
tri = yes;
if (sym->visible != tri) {
sym->visible = tri;
sym_set_changed(sym);
}
if (sym_is_choice_value(sym))
return;
tri = no;
if (sym->rev_dep.expr)
tri = expr_calc_value(sym->rev_dep.expr);
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
tri = yes;
if (sym->rev_dep.tri != tri) {
sym->rev_dep.tri = tri;
sym_set_changed(sym);
}
}
static struct symbol *sym_calc_choice(struct symbol *sym)
{
struct symbol *def_sym;
struct property *prop;
struct expr *e;
/* is the user choice visible? */
def_sym = sym->user.val;
if (def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
return def_sym;
}
/* any of the defaults visible? */
for_all_defaults(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri == no)
continue;
def_sym = prop_get_symbol(prop);
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
return def_sym;
}
/* just get the first visible value */
prop = sym_get_choice_prop(sym);
for (e = prop->expr; e; e = e->left.expr) {
def_sym = e->right.sym;
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
return def_sym;
}
/* no choice? reset tristate value */
sym->curr.tri = no;
return NULL;
}
void sym_calc_value(struct symbol *sym)
{
struct symbol_value newval, oldval;
struct property *prop;
struct expr *e;
if (!sym)
return;
if (sym->flags & SYMBOL_VALID)
return;
sym->flags |= SYMBOL_VALID;
oldval = sym->curr;
switch (sym->type) {
case S_INT:
case S_HEX:
case S_STRING:
newval = symbol_empty.curr;
break;
case S_BOOLEAN:
case S_TRISTATE:
newval = symbol_no.curr;
break;
default:
sym->curr.val = sym->name;
sym->curr.tri = no;
return;
}
if (!sym_is_choice_value(sym))
sym->flags &= ~SYMBOL_WRITE;
sym_calc_visibility(sym);
/* set default if recursively called */
sym->curr = newval;
switch (sym_get_type(sym)) {
case S_BOOLEAN:
case S_TRISTATE:
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym))
newval.tri = sym->user.tri;
else if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym);
if (prop)
newval.tri = expr_calc_value(prop->expr);
}
newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
} else if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym);
if (prop) {
sym->flags |= SYMBOL_WRITE;
newval.tri = expr_calc_value(prop->expr);
}
}
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
break;
case S_STRING:
case S_HEX:
case S_INT:
if (sym->visible != no) {
sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) {
newval.val = sym->user.val;
break;
}
}
prop = sym_get_default_prop(sym);
if (prop) {
struct symbol *ds = prop_get_symbol(prop);
if (ds) {
sym->flags |= SYMBOL_WRITE;
sym_calc_value(ds);
newval.val = ds->curr.val;
}
}
break;
default:
;
}
sym->curr = newval;
if (sym_is_choice(sym) && newval.tri == yes)
sym->curr.val = sym_calc_choice(sym);
if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
sym_set_changed(sym);
if (modules_sym == sym)
modules_val = modules_sym->curr.tri;
if (sym_is_choice(sym)) {
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
prop = sym_get_choice_prop(sym);
for (e = prop->expr; e; e = e->left.expr) {
e->right.sym->flags |= flags;
if (flags & SYMBOL_CHANGED)
sym_set_changed(e->right.sym);
}
}
}
void sym_clear_all_valid(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
sym_change_count++;
if (modules_sym)
sym_calc_value(modules_sym);
}
void sym_set_changed(struct symbol *sym)
{
struct property *prop;
sym->flags |= SYMBOL_CHANGED;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu)
prop->menu->flags |= MENU_CHANGED;
}
}
void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym_set_changed(sym);
}
bool sym_tristate_within_range(struct symbol *sym, tristate val)
{
int type = sym_get_type(sym);
if (sym->visible == no)
return false;
if (type != S_BOOLEAN && type != S_TRISTATE)
return false;
if (type == S_BOOLEAN && val == mod)
return false;
if (sym->visible <= sym->rev_dep.tri)
return false;
if (sym_is_choice_value(sym) && sym->visible == yes)
return val == yes;
return val >= sym->rev_dep.tri && val <= sym->visible;
}
bool sym_set_tristate_value(struct symbol *sym, tristate val)
{
tristate oldval = sym_get_tristate_value(sym);
if (oldval != val && !sym_tristate_within_range(sym, val))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
sym_set_changed(sym);
}
if (sym_is_choice_value(sym) && val == yes) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
cs->user.val = sym;
cs->flags &= ~SYMBOL_NEW;
}
sym->user.tri = val;
if (oldval != val) {
sym_clear_all_valid();
if (sym == modules_sym)
sym_set_all_changed();
}
return true;
}
tristate sym_toggle_tristate_value(struct symbol *sym)
{
tristate oldval, newval;
oldval = newval = sym_get_tristate_value(sym);
do {
switch (newval) {
case no:
newval = mod;
break;
case mod:
newval = yes;
break;
case yes:
newval = no;
break;
}
if (sym_set_tristate_value(sym, newval))
break;
} while (oldval != newval);
return newval;
}
bool sym_string_valid(struct symbol *sym, const char *str)
{
signed char ch;
switch (sym->type) {
case S_STRING:
return true;
case S_INT:
ch = *str++;
if (ch == '-')
ch = *str++;
if (!isdigit(ch))
return false;
if (ch == '0' && *str != 0)
return false;
while ((ch = *str++)) {
if (!isdigit(ch))
return false;
}
return true;
case S_HEX:
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
str += 2;
ch = *str++;
do {
if (!isxdigit(ch))
return false;
} while ((ch = *str++));
return true;
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
case 'y': case 'Y':
case 'm': case 'M':
case 'n': case 'N':
return true;
}
return false;
default:
return false;
}
}
bool sym_string_within_range(struct symbol *sym, const char *str)
{
struct property *prop;
int val;
switch (sym->type) {
case S_STRING:
return sym_string_valid(sym, str);
case S_INT:
if (!sym_string_valid(sym, str))
return false;
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtol(str, NULL, 10);
return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
val <= strtol(prop->expr->right.sym->name, NULL, 10);
case S_HEX:
if (!sym_string_valid(sym, str))
return false;
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtol(str, NULL, 16);
return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
val <= strtol(prop->expr->right.sym->name, NULL, 16);
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
case 'y': case 'Y':
return sym_tristate_within_range(sym, yes);
case 'm': case 'M':
return sym_tristate_within_range(sym, mod);
case 'n': case 'N':
return sym_tristate_within_range(sym, no);
}
return false;
default:
return false;
}
}
bool sym_set_string_value(struct symbol *sym, const char *newval)
{
const char *oldval;
char *val;
int size;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (newval[0]) {
case 'y': case 'Y':
return sym_set_tristate_value(sym, yes);
case 'm': case 'M':
return sym_set_tristate_value(sym, mod);
case 'n': case 'N':
return sym_set_tristate_value(sym, no);
}
return false;
default:
;
}
if (!sym_string_within_range(sym, newval))
return false;
if (sym->flags & SYMBOL_NEW) {
sym->flags &= ~SYMBOL_NEW;
sym_set_changed(sym);
}
oldval = sym->user.val;
size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2;
sym->user.val = val = malloc(size);
*val++ = '0';
*val++ = 'x';
} else if (!oldval || strcmp(oldval, newval))
sym->user.val = val = malloc(size);
else
return true;
strcpy(val, newval);
free((void *)oldval);
sym_clear_all_valid();
return true;
}
const char *sym_get_string_value(struct symbol *sym)
{
tristate val;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
val = sym_get_tristate_value(sym);
switch (val) {
case no:
return "n";
case mod:
return "m";
case yes:
return "y";
}
break;
default:
;
}
return (const char *)sym->curr.val;
}
bool sym_is_changable(struct symbol *sym)
{
return sym->visible > sym->rev_dep.tri;
}
struct symbol *sym_lookup(const char *name, int isconst)
{
struct symbol *symbol;
const char *ptr;
char *new_name;
int hash = 0;
if (name) {
if (name[0] && !name[1]) {
switch (name[0]) {
case 'y': return &symbol_yes;
case 'm': return &symbol_mod;
case 'n': return &symbol_no;
}
}
for (ptr = name; *ptr; ptr++)
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name)) {
if ((isconst && symbol->flags & SYMBOL_CONST) ||
(!isconst && !(symbol->flags & SYMBOL_CONST)))
return symbol;
}
}
new_name = strdup(name);
} else {
new_name = NULL;
hash = 256;
}
symbol = malloc(sizeof(*symbol));
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
symbol->flags = SYMBOL_NEW;
if (isconst)
symbol->flags |= SYMBOL_CONST;
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
return symbol;
}
struct symbol *sym_find(const char *name)
{
struct symbol *symbol = NULL;
const char *ptr;
int hash = 0;
if (!name)
return NULL;
if (name[0] && !name[1]) {
switch (name[0]) {
case 'y': return &symbol_yes;
case 'm': return &symbol_mod;
case 'n': return &symbol_no;
}
}
for (ptr = name; *ptr; ptr++)
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name) &&
!(symbol->flags & SYMBOL_CONST))
break;
}
return symbol;
}
struct symbol *sym_check_deps(struct symbol *sym);
static struct symbol *sym_check_expr_deps(struct expr *e)
{
struct symbol *sym;
if (!e)
return NULL;
switch (e->type) {
case E_OR:
case E_AND:
sym = sym_check_expr_deps(e->left.expr);
if (sym)
return sym;
return sym_check_expr_deps(e->right.expr);
case E_NOT:
return sym_check_expr_deps(e->left.expr);
case E_EQUAL:
case E_UNEQUAL:
sym = sym_check_deps(e->left.sym);
if (sym)
return sym;
return sym_check_deps(e->right.sym);
case E_SYMBOL:
return sym_check_deps(e->left.sym);
default:
break;
}
printf("Oops! How to check %d?\n", e->type);
return NULL;
}
struct symbol *sym_check_deps(struct symbol *sym)
{
struct symbol *sym2;
struct property *prop;
if (sym->flags & SYMBOL_CHECK_DONE)
return NULL;
if (sym->flags & SYMBOL_CHECK) {
printf("Warning! Found recursive dependency: %s", sym->name);
return sym;
}
sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
if (sym2)
goto out;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->type == P_CHOICE || prop->type == P_SELECT)
continue;
sym2 = sym_check_expr_deps(prop->visible.expr);
if (sym2)
goto out;
if (prop->type != P_DEFAULT || sym_is_choice(sym))
continue;
sym2 = sym_check_expr_deps(prop->expr);
if (sym2)
goto out;
}
out:
if (sym2)
printf(" %s", sym->name);
sym->flags &= ~SYMBOL_CHECK;
return sym2;
}
struct property *prop_alloc(enum prop_type type, struct symbol *sym)
{
struct property *prop;
struct property **propp;
prop = malloc(sizeof(*prop));
memset(prop, 0, sizeof(*prop));
prop->type = type;
prop->sym = sym;
prop->file = current_file;
prop->lineno = zconf_lineno();
/* append property to the prop list of symbol */
if (sym) {
for (propp = &sym->prop; *propp; propp = &(*propp)->next)
;
*propp = prop;
}
return prop;
}
struct symbol *prop_get_symbol(struct property *prop)
{
if (prop->expr && (prop->expr->type == E_SYMBOL ||
prop->expr->type == E_CHOICE))
return prop->expr->left.sym;
return NULL;
}
const char *prop_get_type_name(enum prop_type type)
{
switch (type) {
case P_PROMPT:
return "prompt";
case P_COMMENT:
return "comment";
case P_MENU:
return "menu";
case P_DEFAULT:
return "default";
case P_CHOICE:
return "choice";
case P_SELECT:
return "select";
case P_RANGE:
return "range";
case P_UNKNOWN:
break;
}
return "unknown";
}

View File

@@ -0,0 +1,366 @@
%option backup nostdinit noyywrap never-interactive full ecs
%option 8bit backup nodefault perf-report perf-report
%x COMMAND HELP STRING PARAM
%{
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#define START_STRSIZE 16
char *text;
static char *text_ptr;
static int text_size, text_asize;
struct buffer {
struct buffer *parent;
YY_BUFFER_STATE state;
};
struct buffer *current_buf;
static int last_ts, first_ts;
static void zconf_endhelp(void);
static struct buffer *zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
text_ptr = text;
text_size = 0;
*text_ptr = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
text = realloc(text, new_size);
text_asize = new_size;
text_ptr = text + text_size;
}
memcpy(text_ptr, str, size);
text_ptr += size;
text_size += size;
*text_ptr = 0;
}
void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
memcpy(text, str, size);
text[size] = 0;
}
%}
ws [ \n\t]
n [A-Za-z0-9_]
%%
int str = 0;
int ts, i;
[ \t]*#.*\n current_file->lineno++;
[ \t]*#.*
[ \t]*\n current_file->lineno++; return T_EOL;
[ \t]+ {
BEGIN(COMMAND);
}
. {
unput(yytext[0]);
BEGIN(COMMAND);
}
<COMMAND>{
"mainmenu" BEGIN(PARAM); return T_MAINMENU;
"menu" BEGIN(PARAM); return T_MENU;
"endmenu" BEGIN(PARAM); return T_ENDMENU;
"source" BEGIN(PARAM); return T_SOURCE;
"choice" BEGIN(PARAM); return T_CHOICE;
"endchoice" BEGIN(PARAM); return T_ENDCHOICE;
"comment" BEGIN(PARAM); return T_COMMENT;
"config" BEGIN(PARAM); return T_CONFIG;
"menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
"help" BEGIN(PARAM); return T_HELP;
"if" BEGIN(PARAM); return T_IF;
"endif" BEGIN(PARAM); return T_ENDIF;
"depends" BEGIN(PARAM); return T_DEPENDS;
"requires" BEGIN(PARAM); return T_REQUIRES;
"optional" BEGIN(PARAM); return T_OPTIONAL;
"default" BEGIN(PARAM); return T_DEFAULT;
"prompt" BEGIN(PARAM); return T_PROMPT;
"tristate" BEGIN(PARAM); return T_TRISTATE;
"def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
"bool" BEGIN(PARAM); return T_BOOLEAN;
"boolean" BEGIN(PARAM); return T_BOOLEAN;
"def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
"def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
"int" BEGIN(PARAM); return T_INT;
"hex" BEGIN(PARAM); return T_HEX;
"string" BEGIN(PARAM); return T_STRING;
"select" BEGIN(PARAM); return T_SELECT;
"enable" BEGIN(PARAM); return T_SELECT;
"range" BEGIN(PARAM); return T_RANGE;
{n}+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
.
\n current_file->lineno++; BEGIN(INITIAL);
}
<PARAM>{
"&&" return T_AND;
"||" return T_OR;
"(" return T_OPEN_PAREN;
")" return T_CLOSE_PAREN;
"!" return T_NOT;
"=" return T_EQUAL;
"!=" return T_UNEQUAL;
"if" return T_IF;
"on" return T_ON;
\"|\' {
str = yytext[0];
new_string();
BEGIN(STRING);
}
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
--- /* ignore */
({n}|[-/.])+ {
alloc_string(yytext, yyleng);
zconflval.string = text;
return T_WORD;
}
#.* /* comment */
\\\n current_file->lineno++;
.
<<EOF>> {
BEGIN(INITIAL);
}
}
<STRING>{
[^'"\\\n]+/\n {
append_string(yytext, yyleng);
zconflval.string = text;
return T_WORD_QUOTE;
}
[^'"\\\n]+ {
append_string(yytext, yyleng);
}
\\.?/\n {
append_string(yytext + 1, yyleng - 1);
zconflval.string = text;
return T_WORD_QUOTE;
}
\\.? {
append_string(yytext + 1, yyleng - 1);
}
\'|\" {
if (str == yytext[0]) {
BEGIN(PARAM);
zconflval.string = text;
return T_WORD_QUOTE;
} else
append_string(yytext, 1);
}
\n {
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
current_file->lineno++;
BEGIN(INITIAL);
return T_EOL;
}
<<EOF>> {
BEGIN(INITIAL);
}
}
<HELP>{
[ \t]+ {
ts = 0;
for (i = 0; i < yyleng; i++) {
if (yytext[i] == '\t')
ts = (ts & ~7) + 8;
else
ts++;
}
last_ts = ts;
if (first_ts) {
if (ts < first_ts) {
zconf_endhelp();
return T_HELPTEXT;
}
ts -= first_ts;
while (ts > 8) {
append_string(" ", 8);
ts -= 8;
}
append_string(" ", ts);
}
}
[ \t]*\n/[^ \t\n] {
current_file->lineno++;
zconf_endhelp();
return T_HELPTEXT;
}
[ \t]*\n {
current_file->lineno++;
append_string("\n", 1);
}
[^ \t\n].* {
append_string(yytext, yyleng);
if (!first_ts)
first_ts = last_ts;
}
<<EOF>> {
zconf_endhelp();
return T_HELPTEXT;
}
}
<<EOF>> {
if (current_buf) {
zconf_endfile();
return T_EOF;
}
fclose(yyin);
yyterminate();
}
%%
void zconf_starthelp(void)
{
new_string();
last_ts = first_ts = 0;
BEGIN(HELP);
}
static void zconf_endhelp(void)
{
zconflval.string = text;
BEGIN(INITIAL);
}
/*
* Try to open specified file with following names:
* ./name
* $(srctree)/name
* The latter is used when srctree is separate from objtree
* when compiling the kernel.
* Return NULL if file is not found.
*/
FILE *zconf_fopen(const char *name)
{
char *env, fullname[PATH_MAX+1];
FILE *f;
f = fopen(name, "r");
if (!f && name[0] != '/') {
env = getenv(SRCTREE);
if (env) {
sprintf(fullname, "%s/%s", env, name);
f = fopen(fullname, "r");
}
}
return f;
}
void zconf_initscan(const char *name)
{
yyin = zconf_fopen(name);
if (!yyin) {
printf("can't find file %s\n", name);
exit(1);
}
current_buf = malloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
current_file->lineno = 1;
current_file->flags = FILE_BUSY;
}
void zconf_nextfile(const char *name)
{
struct file *file = file_lookup(name);
struct buffer *buf = malloc(sizeof(*buf));
memset(buf, 0, sizeof(*buf));
current_buf->state = YY_CURRENT_BUFFER;
yyin = zconf_fopen(name);
if (!yyin) {
printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
exit(1);
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf;
current_buf = buf;
if (file->flags & FILE_BUSY) {
printf("recursive scan (%s)?\n", name);
exit(1);
}
if (file->flags & FILE_SCANNED) {
printf("file %s already scanned?\n", name);
exit(1);
}
file->flags |= FILE_BUSY;
file->lineno = 1;
file->parent = current_file;
current_file = file;
}
static struct buffer *zconf_endfile(void)
{
struct buffer *parent;
current_file->flags |= FILE_SCANNED;
current_file->flags &= ~FILE_BUSY;
current_file = current_file->parent;
parent = current_buf->parent;
if (parent) {
fclose(yyin);
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(parent->state);
}
free(current_buf);
current_buf = parent;
return parent;
}
int zconf_lineno(void)
{
if (current_buf)
return current_file->lineno - 1;
else
return 0;
}
char *zconf_curname(void)
{
if (current_buf)
return current_file->name;
else
return "<none>";
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,125 @@
/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
#ifndef BISON_ZCONF_TAB_H
# define BISON_ZCONF_TAB_H
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
T_MAINMENU = 258,
T_MENU = 259,
T_ENDMENU = 260,
T_SOURCE = 261,
T_CHOICE = 262,
T_ENDCHOICE = 263,
T_COMMENT = 264,
T_CONFIG = 265,
T_HELP = 266,
T_HELPTEXT = 267,
T_IF = 268,
T_ENDIF = 269,
T_DEPENDS = 270,
T_REQUIRES = 271,
T_OPTIONAL = 272,
T_PROMPT = 273,
T_DEFAULT = 274,
T_TRISTATE = 275,
T_BOOLEAN = 276,
T_INT = 277,
T_HEX = 278,
T_WORD = 279,
T_STRING = 280,
T_UNEQUAL = 281,
T_EOF = 282,
T_EOL = 283,
T_CLOSE_PAREN = 284,
T_OPEN_PAREN = 285,
T_ON = 286,
T_OR = 287,
T_AND = 288,
T_EQUAL = 289,
T_NOT = 290
};
#endif
#define T_MAINMENU 258
#define T_MENU 259
#define T_ENDMENU 260
#define T_SOURCE 261
#define T_CHOICE 262
#define T_ENDCHOICE 263
#define T_COMMENT 264
#define T_CONFIG 265
#define T_HELP 266
#define T_HELPTEXT 267
#define T_IF 268
#define T_ENDIF 269
#define T_DEPENDS 270
#define T_REQUIRES 271
#define T_OPTIONAL 272
#define T_PROMPT 273
#define T_DEFAULT 274
#define T_TRISTATE 275
#define T_BOOLEAN 276
#define T_INT 277
#define T_HEX 278
#define T_WORD 279
#define T_STRING 280
#define T_UNEQUAL 281
#define T_EOF 282
#define T_EOL 283
#define T_CLOSE_PAREN 284
#define T_OPEN_PAREN 285
#define T_ON 286
#define T_OR 287
#define T_AND 288
#define T_EQUAL 289
#define T_NOT 290
#ifndef YYSTYPE
#line 33 "zconf.y"
typedef union {
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
} yystype;
/* Line 1281 of /usr/share/bison/yacc.c. */
#line 118 "zconf.tab.h"
# define YYSTYPE yystype
#endif
extern YYSTYPE zconflval;
#endif /* not BISON_ZCONF_TAB_H */

View File

@@ -0,0 +1,125 @@
/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
#ifndef BISON_ZCONF_TAB_H
# define BISON_ZCONF_TAB_H
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
T_MAINMENU = 258,
T_MENU = 259,
T_ENDMENU = 260,
T_SOURCE = 261,
T_CHOICE = 262,
T_ENDCHOICE = 263,
T_COMMENT = 264,
T_CONFIG = 265,
T_HELP = 266,
T_HELPTEXT = 267,
T_IF = 268,
T_ENDIF = 269,
T_DEPENDS = 270,
T_REQUIRES = 271,
T_OPTIONAL = 272,
T_PROMPT = 273,
T_DEFAULT = 274,
T_TRISTATE = 275,
T_BOOLEAN = 276,
T_INT = 277,
T_HEX = 278,
T_WORD = 279,
T_STRING = 280,
T_UNEQUAL = 281,
T_EOF = 282,
T_EOL = 283,
T_CLOSE_PAREN = 284,
T_OPEN_PAREN = 285,
T_ON = 286,
T_OR = 287,
T_AND = 288,
T_EQUAL = 289,
T_NOT = 290
};
#endif
#define T_MAINMENU 258
#define T_MENU 259
#define T_ENDMENU 260
#define T_SOURCE 261
#define T_CHOICE 262
#define T_ENDCHOICE 263
#define T_COMMENT 264
#define T_CONFIG 265
#define T_HELP 266
#define T_HELPTEXT 267
#define T_IF 268
#define T_ENDIF 269
#define T_DEPENDS 270
#define T_REQUIRES 271
#define T_OPTIONAL 272
#define T_PROMPT 273
#define T_DEFAULT 274
#define T_TRISTATE 275
#define T_BOOLEAN 276
#define T_INT 277
#define T_HEX 278
#define T_WORD 279
#define T_STRING 280
#define T_UNEQUAL 281
#define T_EOF 282
#define T_EOL 283
#define T_CLOSE_PAREN 284
#define T_OPEN_PAREN 285
#define T_ON 286
#define T_OR 287
#define T_AND 288
#define T_EQUAL 289
#define T_NOT 290
#ifndef YYSTYPE
#line 33 "zconf.y"
typedef union {
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
} yystype;
/* Line 1281 of /usr/share/bison/yacc.c. */
#line 118 "zconf.tab.h"
# define YYSTYPE yystype
#endif
extern YYSTYPE zconflval;
#endif /* not BISON_ZCONF_TAB_H */

Binary file not shown.

View File

@@ -0,0 +1,689 @@
%{
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
#define DEBUG_PARSE 0x0002
int cdebug = PRINTD;
extern int zconflex(void);
static void zconfprint(const char *err, ...);
static void zconferror(const char *err);
static bool zconf_endtoken(int token, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
static struct menu *current_menu, *current_entry;
#define YYERROR_VERBOSE
%}
%expect 40
%union
{
int token;
char *string;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
}
%token T_MAINMENU
%token T_MENU
%token T_ENDMENU
%token T_SOURCE
%token T_CHOICE
%token T_ENDCHOICE
%token T_COMMENT
%token T_CONFIG
%token T_MENUCONFIG
%token T_HELP
%token <string> T_HELPTEXT
%token T_IF
%token T_ENDIF
%token T_DEPENDS
%token T_REQUIRES
%token T_OPTIONAL
%token T_PROMPT
%token T_DEFAULT
%token T_TRISTATE
%token T_DEF_TRISTATE
%token T_BOOLEAN
%token T_DEF_BOOLEAN
%token T_STRING
%token T_INT
%token T_HEX
%token <string> T_WORD
%token <string> T_WORD_QUOTE
%token T_UNEQUAL
%token T_EOF
%token T_EOL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_ON
%token T_SELECT
%token T_RANGE
%left T_OR
%left T_AND
%left T_EQUAL T_UNEQUAL
%nonassoc T_NOT
%type <string> prompt
%type <string> source
%type <symbol> symbol
%type <expr> expr
%type <expr> if_expr
%type <token> end
%{
#define LKC_DIRECT_LINK
#include "lkc.h"
%}
%%
input: /* empty */
| input block
;
block: common_block
| choice_stmt
| menu_stmt
| T_MAINMENU prompt nl_or_eof
| T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
| T_ENDIF { zconfprint("unexpected 'endif' statement"); }
| T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
| error nl_or_eof { zconfprint("syntax error"); yyerrok; }
;
common_block:
if_stmt
| comment_stmt
| config_stmt
| menuconfig_stmt
| source_stmt
| nl_or_eof
;
/* config/menuconfig entry */
config_entry_start: T_CONFIG T_WORD T_EOL
{
struct symbol *sym = sym_lookup($2, 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
};
config_stmt: config_entry_start config_option_list
{
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
};
menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
{
struct symbol *sym = sym_lookup($2, 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
};
menuconfig_stmt: menuconfig_entry_start config_option_list
{
if (current_entry->prompt)
current_entry->prompt->type = P_MENU;
else
zconfprint("warning: menuconfig statement without prompt");
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
};
config_option_list:
/* empty */
| config_option_list config_option
| config_option_list depends
| config_option_list help
| config_option_list T_EOL
;
config_option: T_TRISTATE prompt_stmt_opt T_EOL
{
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
};
config_option: T_DEF_TRISTATE expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_BOOLEAN prompt_stmt_opt T_EOL
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_DEF_BOOLEAN expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_INT prompt_stmt_opt T_EOL
{
menu_set_type(S_INT);
printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
};
config_option: T_HEX prompt_stmt_opt T_EOL
{
menu_set_type(S_HEX);
printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
};
config_option: T_STRING prompt_stmt_opt T_EOL
{
menu_set_type(S_STRING);
printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
};
config_option: T_PROMPT prompt if_expr T_EOL
{
menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
config_option: T_DEFAULT expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
config_option: T_SELECT T_WORD if_expr T_EOL
{
menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
};
config_option: T_RANGE symbol symbol if_expr T_EOL
{
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
};
/* choice entry */
choice: T_CHOICE T_EOL
{
struct symbol *sym = sym_lookup(NULL, 0);
sym->flags |= SYMBOL_CHOICE;
menu_add_entry(sym);
menu_add_expr(P_CHOICE, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
};
choice_entry: choice choice_option_list
{
menu_end_entry();
menu_add_menu();
};
choice_end: end
{
if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
};
choice_stmt:
choice_entry choice_block choice_end
| choice_entry choice_block
{
printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
choice_option_list:
/* empty */
| choice_option_list choice_option
| choice_option_list depends
| choice_option_list help
| choice_option_list T_EOL
;
choice_option: T_PROMPT prompt if_expr T_EOL
{
menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
};
choice_option: T_TRISTATE prompt_stmt_opt T_EOL
{
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
};
choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
};
choice_option: T_OPTIONAL T_EOL
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
};
choice_option: T_DEFAULT T_WORD if_expr T_EOL
{
menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
};
choice_block:
/* empty */
| choice_block common_block
;
/* if entry */
if: T_IF expr T_EOL
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
menu_add_dep($2);
menu_end_entry();
menu_add_menu();
};
if_end: end
{
if (zconf_endtoken($1, T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
};
if_stmt:
if if_block if_end
| if if_block
{
printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
if_block:
/* empty */
| if_block common_block
| if_block menu_stmt
| if_block choice_stmt
;
/* menu entry */
menu: T_MENU prompt T_EOL
{
menu_add_entry(NULL);
menu_add_prop(P_MENU, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
};
menu_entry: menu depends_list
{
menu_end_entry();
menu_add_menu();
};
menu_end: end
{
if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
};
menu_stmt:
menu_entry menu_block menu_end
| menu_entry menu_block
{
printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
menu_block:
/* empty */
| menu_block common_block
| menu_block menu_stmt
| menu_block choice_stmt
| menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
;
source: T_SOURCE prompt T_EOL
{
$$ = $2;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
};
source_stmt: source
{
zconf_nextfile($1);
};
/* comment entry */
comment: T_COMMENT prompt T_EOL
{
menu_add_entry(NULL);
menu_add_prop(P_COMMENT, $2, NULL, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
};
comment_stmt: comment depends_list
{
menu_end_entry();
};
/* help option */
help_start: T_HELP T_EOL
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
zconf_starthelp();
};
help: help_start T_HELPTEXT
{
current_entry->sym->help = $2;
};
/* depends option */
depends_list: /* empty */
| depends_list depends
| depends_list T_EOL
;
depends: T_DEPENDS T_ON expr T_EOL
{
menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
}
| T_DEPENDS expr T_EOL
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
}
| T_REQUIRES expr T_EOL
{
menu_add_dep($2);
printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
};
/* prompt statement */
prompt_stmt_opt:
/* empty */
| prompt if_expr
{
menu_add_prop(P_PROMPT, $1, NULL, $2);
};
prompt: T_WORD
| T_WORD_QUOTE
;
end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
| T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
| T_ENDIF nl_or_eof { $$ = T_ENDIF; }
;
nl_or_eof:
T_EOL | T_EOF;
if_expr: /* empty */ { $$ = NULL; }
| T_IF expr { $$ = $2; }
;
expr: symbol { $$ = expr_alloc_symbol($1); }
| symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
| T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
| expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
;
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
| T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
;
%%
void conf_parse(const char *name)
{
struct symbol *sym;
int i;
zconf_initscan(name);
sym_init();
menu_init();
modules_sym = sym_lookup("MODULES", 0);
rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
//zconfdebug = 1;
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
printf("\n");
else
sym->flags |= SYMBOL_CHECK_DONE;
}
sym_change_count = 1;
}
const char *zconf_tokenname(int token)
{
switch (token) {
case T_MENU: return "menu";
case T_ENDMENU: return "endmenu";
case T_CHOICE: return "choice";
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
}
return "<token>";
}
static bool zconf_endtoken(int token, int starttoken, int endtoken)
{
if (token != endtoken) {
zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
zconfprint("location of the '%s'", zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
return true;
}
static void zconfprint(const char *err, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
fprintf(stderr, "\n");
}
static void zconferror(const char *err)
{
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
}
void print_quoted_string(FILE *out, const char *str)
{
const char *p;
int len;
putc('"', out);
while ((p = strchr(str, '"'))) {
len = p - str;
if (len)
fprintf(out, "%.*s", len, str);
fputs("\\\"", out);
str = p + 1;
}
fputs(str, out);
putc('"', out);
}
void print_symbol(FILE *out, struct menu *menu)
{
struct symbol *sym = menu->sym;
struct property *prop;
if (sym_is_choice(sym))
fprintf(out, "choice\n");
else
fprintf(out, "config %s\n", sym->name);
switch (sym->type) {
case S_BOOLEAN:
fputs(" boolean\n", out);
break;
case S_TRISTATE:
fputs(" tristate\n", out);
break;
case S_STRING:
fputs(" string\n", out);
break;
case S_INT:
fputs(" integer\n", out);
break;
case S_HEX:
fputs(" hex\n", out);
break;
default:
fputs(" ???\n", out);
break;
}
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu != menu)
continue;
switch (prop->type) {
case P_PROMPT:
fputs(" prompt ", out);
print_quoted_string(out, prop->text);
if (!expr_is_yes(prop->visible.expr)) {
fputs(" if ", out);
expr_fprint(prop->visible.expr, out);
}
fputc('\n', out);
break;
case P_DEFAULT:
fputs( " default ", out);
expr_fprint(prop->expr, out);
if (!expr_is_yes(prop->visible.expr)) {
fputs(" if ", out);
expr_fprint(prop->visible.expr, out);
}
fputc('\n', out);
break;
case P_CHOICE:
fputs(" #choice value\n", out);
break;
default:
fprintf(out, " unknown prop %d!\n", prop->type);
break;
}
}
if (sym->help) {
int len = strlen(sym->help);
while (sym->help[--len] == '\n')
sym->help[len] = 0;
fprintf(out, " help\n%s\n", sym->help);
}
fputc('\n', out);
}
void zconfdump(FILE *out)
{
struct property *prop;
struct symbol *sym;
struct menu *menu;
menu = rootmenu.list;
while (menu) {
if ((sym = menu->sym))
print_symbol(out, menu);
else if ((prop = menu->prompt)) {
switch (prop->type) {
case P_COMMENT:
fputs("\ncomment ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
case P_MENU:
fputs("\nmenu ", out);
print_quoted_string(out, prop->text);
fputs("\n", out);
break;
default:
;
}
if (!expr_is_yes(prop->visible.expr)) {
fputs(" depends ", out);
expr_fprint(prop->visible.expr, out);
fputc('\n', out);
}
fputs("\n", out);
}
if (menu->list)
menu = menu->list;
else if (menu->next)
menu = menu->next;
else while ((menu = menu->parent)) {
if (menu->prompt && menu->prompt->type == P_MENU)
fputs("\nendmenu\n", out);
if (menu->next) {
menu = menu->next;
break;
}
}
}
}
#include "lex.zconf.c"
#include "confdata.c"
#include "expr.c"
#include "symbol.c"
#include "menu.c"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
ksymoops has been removed from the kernel. It was always meant to be a
free standing utility, not linked to any particular kernel version.
The latest version can be found in
ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together
with patches to other utilities in order to give more accurate Oops
debugging.
Keith Owens <kaos@ocs.com.au> Sat Jun 19 10:30:34 EST 1999

View File

@@ -0,0 +1,53 @@
cmd_scripts/lxdialog/checklist.o := gcc -Wp,-MD,scripts/lxdialog/.checklist.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/checklist.o scripts/lxdialog/checklist.c
deps_scripts/lxdialog/checklist.o := \
scripts/lxdialog/checklist.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/checklist.o: $(deps_scripts/lxdialog/checklist.o)
$(deps_scripts/lxdialog/checklist.o):

View File

@@ -0,0 +1,53 @@
cmd_scripts/lxdialog/inputbox.o := gcc -Wp,-MD,scripts/lxdialog/.inputbox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/inputbox.o scripts/lxdialog/inputbox.c
deps_scripts/lxdialog/inputbox.o := \
scripts/lxdialog/inputbox.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/inputbox.o: $(deps_scripts/lxdialog/inputbox.o)
$(deps_scripts/lxdialog/inputbox.o):

View File

@@ -0,0 +1 @@
cmd_scripts/lxdialog/lxdialog := gcc -o scripts/lxdialog/lxdialog scripts/lxdialog/checklist.o scripts/lxdialog/menubox.o scripts/lxdialog/textbox.o scripts/lxdialog/yesno.o scripts/lxdialog/inputbox.o scripts/lxdialog/util.o scripts/lxdialog/lxdialog.o scripts/lxdialog/msgbox.o -lncurses

View File

@@ -0,0 +1,55 @@
cmd_scripts/lxdialog/lxdialog.o := gcc -Wp,-MD,scripts/lxdialog/.lxdialog.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/lxdialog.o scripts/lxdialog/lxdialog.c
deps_scripts/lxdialog/lxdialog.o := \
scripts/lxdialog/lxdialog.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
/usr/include/locale.h \
/usr/include/bits/locale.h \
scripts/lxdialog/lxdialog.o: $(deps_scripts/lxdialog/lxdialog.o)
$(deps_scripts/lxdialog/lxdialog.o):

View File

@@ -0,0 +1,53 @@
cmd_scripts/lxdialog/menubox.o := gcc -Wp,-MD,scripts/lxdialog/.menubox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/menubox.o scripts/lxdialog/menubox.c
deps_scripts/lxdialog/menubox.o := \
scripts/lxdialog/menubox.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/menubox.o: $(deps_scripts/lxdialog/menubox.o)
$(deps_scripts/lxdialog/menubox.o):

View File

@@ -0,0 +1,53 @@
cmd_scripts/lxdialog/msgbox.o := gcc -Wp,-MD,scripts/lxdialog/.msgbox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/msgbox.o scripts/lxdialog/msgbox.c
deps_scripts/lxdialog/msgbox.o := \
scripts/lxdialog/msgbox.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/msgbox.o: $(deps_scripts/lxdialog/msgbox.o)
$(deps_scripts/lxdialog/msgbox.o):

View File

@@ -0,0 +1,53 @@
cmd_scripts/lxdialog/textbox.o := gcc -Wp,-MD,scripts/lxdialog/.textbox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/textbox.o scripts/lxdialog/textbox.c
deps_scripts/lxdialog/textbox.o := \
scripts/lxdialog/textbox.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/textbox.o: $(deps_scripts/lxdialog/textbox.o)
$(deps_scripts/lxdialog/textbox.o):

View File

@@ -0,0 +1,54 @@
cmd_scripts/lxdialog/util.o := gcc -Wp,-MD,scripts/lxdialog/.util.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/util.o scripts/lxdialog/util.c
deps_scripts/lxdialog/util.o := \
scripts/lxdialog/util.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/colors.h \
scripts/lxdialog/util.o: $(deps_scripts/lxdialog/util.o)
$(deps_scripts/lxdialog/util.o):

View File

@@ -0,0 +1,53 @@
cmd_scripts/lxdialog/yesno.o := gcc -Wp,-MD,scripts/lxdialog/.yesno.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -DLOCALE -DCURSES_LOC="<ncurses.h>" -c -o scripts/lxdialog/yesno.o scripts/lxdialog/yesno.c
deps_scripts/lxdialog/yesno.o := \
scripts/lxdialog/yesno.c \
scripts/lxdialog/dialog.h \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/bits/sigset.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/unistd.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
/usr/include/ctype.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/usr/include/ncurses.h \
/usr/include/ncurses_dll.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/unctrl.h \
/usr/include/curses.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdbool.h \
scripts/lxdialog/yesno.o: $(deps_scripts/lxdialog/yesno.o)
$(deps_scripts/lxdialog/yesno.o):

View File

@@ -0,0 +1,4 @@
This is NOT the official version of dialog. This version has been
significantly modified from the original. It is for use by the Linux
kernel configuration script. Please do not bother Savio Lam with
questions about this program.

View File

@@ -0,0 +1,42 @@
HOST_EXTRACFLAGS := -DLOCALE
ifeq ($(shell uname),SunOS)
HOST_LOADLIBES := -lcurses
else
HOST_LOADLIBES := -lncurses
endif
ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
else
ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
else
ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
HOST_EXTRACFLAGS += -DCURSES_LOC="<ncurses.h>"
else
HOST_EXTRACFLAGS += -DCURSES_LOC="<curses.h>"
endif
endif
endif
hostprogs-y := lxdialog
always := ncurses $(hostprogs-y)
lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
util.o lxdialog.o msgbox.o
.PHONY: $(obj)/ncurses
$(obj)/ncurses:
@echo "main() {}" > lxtemp.c
@if $(HOSTCC) lxtemp.c $(HOST_LOADLIBES); then \
rm -f lxtemp.c a.out; \
else \
rm -f lxtemp.c; \
echo -e "\007" ;\
echo ">> Unable to find the Ncurses libraries." ;\
echo ">>" ;\
echo ">> You must install ncurses-devel in order" ;\
echo ">> to use 'make menuconfig'" ;\
echo ;\
exit 1 ;\
fi

View File

@@ -0,0 +1,373 @@
/*
* checklist.c -- implements the checklist box
*
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
* Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
* Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dialog.h"
static int list_width, check_x, item_x, checkflag;
/*
* Print list item
*/
static void
print_item (WINDOW * win, const char *item, int status,
int choice, int selected)
{
int i;
/* Clear 'residue' of last item */
wattrset (win, menubox_attr);
wmove (win, choice, 0);
for (i = 0; i < list_width; i++)
waddch (win, ' ');
wmove (win, choice, check_x);
wattrset (win, selected ? check_selected_attr : check_attr);
if (checkflag == FLAG_CHECK)
wprintw (win, "[%c]", status ? 'X' : ' ');
else
wprintw (win, "(%c)", status ? 'X' : ' ');
wattrset (win, selected ? tag_selected_attr : tag_attr);
mvwaddch(win, choice, item_x, item[0]);
wattrset (win, selected ? item_selected_attr : item_attr);
waddstr (win, (char *)item+1);
if (selected) {
wmove (win, choice, check_x+1);
wrefresh (win);
}
}
/*
* Print the scroll indicators.
*/
static void
print_arrows (WINDOW * win, int choice, int item_no, int scroll,
int y, int x, int height)
{
wmove(win, y, x);
if (scroll > 0) {
wattrset (win, uarrow_attr);
waddch (win, ACS_UARROW);
waddstr (win, "(-)");
}
else {
wattrset (win, menubox_attr);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
}
y = y + height + 1;
wmove(win, y, x);
if ((height < item_no) && (scroll + choice < item_no - 1)) {
wattrset (win, darrow_attr);
waddch (win, ACS_DARROW);
waddstr (win, "(+)");
}
else {
wattrset (win, menubox_border_attr);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
}
}
/*
* Display the termination buttons
*/
static void
print_buttons( WINDOW *dialog, int height, int width, int selected)
{
int x = width / 2 - 11;
int y = height - 2;
print_button (dialog, "Select", y, x, selected == 0);
print_button (dialog, " Help ", y, x + 14, selected == 1);
wmove(dialog, y, x+1 + 14*selected);
wrefresh (dialog);
}
/*
* Display a dialog box with a list of options that can be turned on or off
* The `flag' parameter is used to select between radiolist and checklist.
*/
int
dialog_checklist (const char *title, const char *prompt, int height, int width,
int list_height, int item_no, const char * const * items, int flag)
{
int i, x, y, box_x, box_y;
int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
WINDOW *dialog, *list;
checkflag = flag;
/* Allocate space for storing item on/off status */
if ((status = malloc (sizeof (int) * item_no)) == NULL) {
endwin ();
fprintf (stderr,
"\nCan't allocate memory in dialog_checklist().\n");
exit (-1);
}
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = !strcasecmp (items[i * 3 + 2], "on");
if ((!choice && status[i]) || !strcasecmp (items[i * 3 + 2], "selected"))
choice = i + 1;
}
if (choice)
choice--;
max_choice = MIN (list_height, item_no);
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
draw_shadow (stdscr, y, x, height, width);
dialog = newwin (height, width, y, x);
keypad (dialog, TRUE);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset (dialog, border_attr);
mvwaddch (dialog, height-3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) {
/* truncate long title -- mec */
char * title2 = malloc(width-2+1);
memcpy( title2, title, width-2 );
title2[width-2] = '\0';
title = title2;
}
if (title != NULL) {
wattrset (dialog, title_attr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
wattrset (dialog, dialog_attr);
print_autowrap (dialog, prompt, width - 2, 1, 3);
list_width = width - 6;
box_y = height - list_height - 5;
box_x = (width - list_width) / 2 - 1;
/* create new window for the list */
list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
keypad (list, TRUE);
/* draw a box around the list items */
draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
menubox_border_attr, menubox_attr);
/* Find length of longest item in order to center checklist */
check_x = 0;
for (i = 0; i < item_no; i++)
check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
if (choice >= list_height) {
scroll = choice - list_height + 1;
choice -= scroll;
}
/* Print the list */
for (i = 0; i < max_choice; i++) {
print_item (list, items[(scroll+i) * 3 + 1],
status[i+scroll], i, i == choice);
}
print_arrows(dialog, choice, item_no, scroll,
box_y, box_x + check_x + 5, list_height);
print_buttons(dialog, height, width, 0);
wnoutrefresh (list);
wnoutrefresh (dialog);
doupdate ();
while (key != ESC) {
key = wgetch (dialog);
for (i = 0; i < max_choice; i++)
if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
break;
if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
key == '+' || key == '-' ) {
if (key == KEY_UP || key == '-') {
if (!choice) {
if (!scroll)
continue;
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
print_item (list, items[scroll * 3 + 1],
status[scroll], 0, FALSE);
scrollok (list, TRUE);
wscrl (list, -1);
scrollok (list, FALSE);
}
scroll--;
print_item (list, items[scroll * 3 + 1],
status[scroll], 0, TRUE);
wnoutrefresh (list);
print_arrows(dialog, choice, item_no, scroll,
box_y, box_x + check_x + 5, list_height);
wrefresh (dialog);
continue; /* wait for another key press */
} else
i = choice - 1;
} else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll + choice >= item_no - 1)
continue;
/* Scroll list up */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1],
max_choice - 1, FALSE);
scrollok (list, TRUE);
scroll (list);
scrollok (list, FALSE);
}
scroll++;
print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1],
max_choice - 1, TRUE);
wnoutrefresh (list);
print_arrows(dialog, choice, item_no, scroll,
box_y, box_x + check_x + 5, list_height);
wrefresh (dialog);
continue; /* wait for another key press */
} else
i = choice + 1;
}
if (i != choice) {
/* De-highlight current item */
print_item (list, items[(scroll + choice) * 3 + 1],
status[scroll + choice], choice, FALSE);
/* Highlight new item */
choice = i;
print_item (list, items[(scroll + choice) * 3 + 1],
status[scroll + choice], choice, TRUE);
wnoutrefresh (list);
wrefresh (dialog);
}
continue; /* wait for another key press */
}
switch (key) {
case 'H':
case 'h':
case '?':
fprintf (stderr, "%s", items[(scroll + choice) * 3]);
delwin (dialog);
free (status);
return 1;
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 1 : (button > 1 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh (dialog);
break;
case 'S':
case 's':
case ' ':
case '\n':
if (!button) {
if (flag == FLAG_CHECK) {
status[scroll + choice] = !status[scroll + choice];
wmove (list, choice, check_x);
wattrset (list, check_selected_attr);
wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
} else {
if (!status[scroll + choice]) {
for (i = 0; i < item_no; i++)
status[i] = 0;
status[scroll + choice] = 1;
for (i = 0; i < max_choice; i++)
print_item (list, items[(scroll + i) * 3 + 1],
status[scroll + i], i, i == choice);
}
}
wnoutrefresh (list);
wrefresh (dialog);
for (i = 0; i < item_no; i++) {
if (status[i]) {
if (flag == FLAG_CHECK) {
fprintf (stderr, "\"%s\" ", items[i * 3]);
} else {
fprintf (stderr, "%s", items[i * 3]);
}
}
}
} else
fprintf (stderr, "%s", items[(scroll + choice) * 3]);
delwin (dialog);
free (status);
return button;
case 'X':
case 'x':
key = ESC;
case ESC:
break;
}
/* Now, update everything... */
doupdate ();
}
delwin (dialog);
free (status);
return -1; /* ESC pressed */
}

Binary file not shown.

View File

@@ -0,0 +1,161 @@
/*
* colors.h -- color attribute definitions
*
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Default color definitions
*
* *_FG = foreground
* *_BG = background
* *_HL = highlight?
*/
#define SCREEN_FG COLOR_CYAN
#define SCREEN_BG COLOR_BLUE
#define SCREEN_HL TRUE
#define SHADOW_FG COLOR_BLACK
#define SHADOW_BG COLOR_BLACK
#define SHADOW_HL TRUE
#define DIALOG_FG COLOR_BLACK
#define DIALOG_BG COLOR_WHITE
#define DIALOG_HL FALSE
#define TITLE_FG COLOR_YELLOW
#define TITLE_BG COLOR_WHITE
#define TITLE_HL TRUE
#define BORDER_FG COLOR_WHITE
#define BORDER_BG COLOR_WHITE
#define BORDER_HL TRUE
#define BUTTON_ACTIVE_FG COLOR_WHITE
#define BUTTON_ACTIVE_BG COLOR_BLUE
#define BUTTON_ACTIVE_HL TRUE
#define BUTTON_INACTIVE_FG COLOR_BLACK
#define BUTTON_INACTIVE_BG COLOR_WHITE
#define BUTTON_INACTIVE_HL FALSE
#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
#define BUTTON_KEY_ACTIVE_HL TRUE
#define BUTTON_KEY_INACTIVE_FG COLOR_RED
#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
#define BUTTON_KEY_INACTIVE_HL FALSE
#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
#define BUTTON_LABEL_ACTIVE_HL TRUE
#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
#define BUTTON_LABEL_INACTIVE_HL TRUE
#define INPUTBOX_FG COLOR_BLACK
#define INPUTBOX_BG COLOR_WHITE
#define INPUTBOX_HL FALSE
#define INPUTBOX_BORDER_FG COLOR_BLACK
#define INPUTBOX_BORDER_BG COLOR_WHITE
#define INPUTBOX_BORDER_HL FALSE
#define SEARCHBOX_FG COLOR_BLACK
#define SEARCHBOX_BG COLOR_WHITE
#define SEARCHBOX_HL FALSE
#define SEARCHBOX_TITLE_FG COLOR_YELLOW
#define SEARCHBOX_TITLE_BG COLOR_WHITE
#define SEARCHBOX_TITLE_HL TRUE
#define SEARCHBOX_BORDER_FG COLOR_WHITE
#define SEARCHBOX_BORDER_BG COLOR_WHITE
#define SEARCHBOX_BORDER_HL TRUE
#define POSITION_INDICATOR_FG COLOR_YELLOW
#define POSITION_INDICATOR_BG COLOR_WHITE
#define POSITION_INDICATOR_HL TRUE
#define MENUBOX_FG COLOR_BLACK
#define MENUBOX_BG COLOR_WHITE
#define MENUBOX_HL FALSE
#define MENUBOX_BORDER_FG COLOR_WHITE
#define MENUBOX_BORDER_BG COLOR_WHITE
#define MENUBOX_BORDER_HL TRUE
#define ITEM_FG COLOR_BLACK
#define ITEM_BG COLOR_WHITE
#define ITEM_HL FALSE
#define ITEM_SELECTED_FG COLOR_WHITE
#define ITEM_SELECTED_BG COLOR_BLUE
#define ITEM_SELECTED_HL TRUE
#define TAG_FG COLOR_YELLOW
#define TAG_BG COLOR_WHITE
#define TAG_HL TRUE
#define TAG_SELECTED_FG COLOR_YELLOW
#define TAG_SELECTED_BG COLOR_BLUE
#define TAG_SELECTED_HL TRUE
#define TAG_KEY_FG COLOR_YELLOW
#define TAG_KEY_BG COLOR_WHITE
#define TAG_KEY_HL TRUE
#define TAG_KEY_SELECTED_FG COLOR_YELLOW
#define TAG_KEY_SELECTED_BG COLOR_BLUE
#define TAG_KEY_SELECTED_HL TRUE
#define CHECK_FG COLOR_BLACK
#define CHECK_BG COLOR_WHITE
#define CHECK_HL FALSE
#define CHECK_SELECTED_FG COLOR_WHITE
#define CHECK_SELECTED_BG COLOR_BLUE
#define CHECK_SELECTED_HL TRUE
#define UARROW_FG COLOR_GREEN
#define UARROW_BG COLOR_WHITE
#define UARROW_HL TRUE
#define DARROW_FG COLOR_GREEN
#define DARROW_BG COLOR_WHITE
#define DARROW_HL TRUE
/* End of default color definitions */
#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
#define COLOR_NAME_LEN 10
#define COLOR_COUNT 8
/*
* Global variables
*/
typedef struct {
char name[COLOR_NAME_LEN];
int value;
} color_names_st;
extern color_names_st color_names[];
extern int color_table[][3];

View File

@@ -0,0 +1,187 @@
/*
* dialog.h -- common declarations for all dialog modules
*
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef __sun__
#define CURS_MACROS
#endif
#include CURSES_LOC
/*
* Colors in ncurses 1.9.9e do not work properly since foreground and
* background colors are OR'd rather than separately masked. This version
* of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
* with standard curses. The simplest fix (to make this work with standard
* curses) uses the wbkgdset() function, not used in the original hack.
* Turn it off if we're building with 1.9.9e, since it just confuses things.
*/
#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
#define OLD_NCURSES 1
#undef wbkgdset
#define wbkgdset(w,p) /*nothing*/
#else
#define OLD_NCURSES 0
#endif
#define TR(params) _tracef params
#define ESC 27
#define TAB 9
#define MAX_LEN 2048
#define BUF_SIZE (10*1024)
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
#ifndef ACS_ULCORNER
#define ACS_ULCORNER '+'
#endif
#ifndef ACS_LLCORNER
#define ACS_LLCORNER '+'
#endif
#ifndef ACS_URCORNER
#define ACS_URCORNER '+'
#endif
#ifndef ACS_LRCORNER
#define ACS_LRCORNER '+'
#endif
#ifndef ACS_HLINE
#define ACS_HLINE '-'
#endif
#ifndef ACS_VLINE
#define ACS_VLINE '|'
#endif
#ifndef ACS_LTEE
#define ACS_LTEE '+'
#endif
#ifndef ACS_RTEE
#define ACS_RTEE '+'
#endif
#ifndef ACS_UARROW
#define ACS_UARROW '^'
#endif
#ifndef ACS_DARROW
#define ACS_DARROW 'v'
#endif
/*
* Attribute names
*/
#define screen_attr attributes[0]
#define shadow_attr attributes[1]
#define dialog_attr attributes[2]
#define title_attr attributes[3]
#define border_attr attributes[4]
#define button_active_attr attributes[5]
#define button_inactive_attr attributes[6]
#define button_key_active_attr attributes[7]
#define button_key_inactive_attr attributes[8]
#define button_label_active_attr attributes[9]
#define button_label_inactive_attr attributes[10]
#define inputbox_attr attributes[11]
#define inputbox_border_attr attributes[12]
#define searchbox_attr attributes[13]
#define searchbox_title_attr attributes[14]
#define searchbox_border_attr attributes[15]
#define position_indicator_attr attributes[16]
#define menubox_attr attributes[17]
#define menubox_border_attr attributes[18]
#define item_attr attributes[19]
#define item_selected_attr attributes[20]
#define tag_attr attributes[21]
#define tag_selected_attr attributes[22]
#define tag_key_attr attributes[23]
#define tag_key_selected_attr attributes[24]
#define check_attr attributes[25]
#define check_selected_attr attributes[26]
#define uarrow_attr attributes[27]
#define darrow_attr attributes[28]
/* number of attributes */
#define ATTRIBUTE_COUNT 29
/*
* Global variables
*/
extern bool use_colors;
extern bool use_shadow;
extern chtype attributes[];
extern const char *backtitle;
/*
* Function prototypes
*/
extern void create_rc (const char *filename);
extern int parse_rc (void);
void init_dialog (void);
void end_dialog (void);
void attr_clear (WINDOW * win, int height, int width, chtype attr);
void dialog_clear (void);
void color_setup (void);
void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
void print_button (WINDOW * win, const char *label, int y, int x, int selected);
void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
chtype border);
void draw_shadow (WINDOW * win, int y, int x, int height, int width);
int first_alpha (const char *string, const char *exempt);
int dialog_yesno (const char *title, const char *prompt, int height, int width);
int dialog_msgbox (const char *title, const char *prompt, int height,
int width, int pause);
int dialog_textbox (const char *title, const char *file, int height, int width);
int dialog_menu (const char *title, const char *prompt, int height, int width,
int menu_height, const char *choice, int item_no,
const char * const * items);
int dialog_checklist (const char *title, const char *prompt, int height,
int width, int list_height, int item_no,
const char * const * items, int flag);
extern unsigned char dialog_input_result[];
int dialog_inputbox (const char *title, const char *prompt, int height,
int width, const char *init);
/*
* This is the base for fictitious keys, which activate
* the buttons.
*
* Mouse-generated keys are the following:
* -- the first 32 are used as numbers, in addition to '0'-'9'
* -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
* -- uppercase chars are used to invoke the button (M_EVENT + 'O')
*/
#define M_EVENT (KEY_MAX+1)
/*
* The `flag' parameter in checklist is used to select between
* radiolist and checklist
*/
#define FLAG_CHECK 1
#define FLAG_RADIO 0

View File

@@ -0,0 +1,240 @@
/*
* inputbox.c -- implements the input box
*
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dialog.h"
unsigned char dialog_input_result[MAX_LEN + 1];
/*
* Print the termination buttons
*/
static void
print_buttons(WINDOW *dialog, int height, int width, int selected)
{
int x = width / 2 - 11;
int y = height - 2;
print_button (dialog, " Ok ", y, x, selected==0);
print_button (dialog, " Help ", y, x + 14, selected==1);
wmove(dialog, y, x+1+14*selected);
wrefresh(dialog);
}
/*
* Display a dialog box for inputing a string
*/
int
dialog_inputbox (const char *title, const char *prompt, int height, int width,
const char *init)
{
int i, x, y, box_y, box_x, box_width;
int input_x = 0, scroll = 0, key = 0, button = -1;
unsigned char *instr = dialog_input_result;
WINDOW *dialog;
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
draw_shadow (stdscr, y, x, height, width);
dialog = newwin (height, width, y, x);
keypad (dialog, TRUE);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset (dialog, border_attr);
mvwaddch (dialog, height-3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) {
/* truncate long title -- mec */
char * title2 = malloc(width-2+1);
memcpy( title2, title, width-2 );
title2[width-2] = '\0';
title = title2;
}
if (title != NULL) {
wattrset (dialog, title_attr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
wattrset (dialog, dialog_attr);
print_autowrap (dialog, prompt, width - 2, 1, 3);
/* Draw the input field box */
box_width = width - 6;
getyx (dialog, y, x);
box_y = y + 2;
box_x = (width - box_width) / 2;
draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
border_attr, dialog_attr);
print_buttons(dialog, height, width, 0);
/* Set up the initial value */
wmove (dialog, box_y, box_x);
wattrset (dialog, inputbox_attr);
if (!init)
instr[0] = '\0';
else
strcpy (instr, init);
input_x = strlen (instr);
if (input_x >= box_width) {
scroll = input_x - box_width + 1;
input_x = box_width - 1;
for (i = 0; i < box_width - 1; i++)
waddch (dialog, instr[scroll + i]);
} else
waddstr (dialog, instr);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
while (key != ESC) {
key = wgetch (dialog);
if (button == -1) { /* Input box selected */
switch (key) {
case TAB:
case KEY_UP:
case KEY_DOWN:
break;
case KEY_LEFT:
continue;
case KEY_RIGHT:
continue;
case KEY_BACKSPACE:
case 127:
if (input_x || scroll) {
wattrset (dialog, inputbox_attr);
if (!input_x) {
scroll = scroll < box_width - 1 ?
0 : scroll - (box_width - 1);
wmove (dialog, box_y, box_x);
for (i = 0; i < box_width; i++)
waddch (dialog, instr[scroll + input_x + i] ?
instr[scroll + input_x + i] : ' ');
input_x = strlen (instr) - scroll;
} else
input_x--;
instr[scroll + input_x] = '\0';
mvwaddch (dialog, box_y, input_x + box_x, ' ');
wmove (dialog, box_y, input_x + box_x);
wrefresh (dialog);
}
continue;
default:
if (key < 0x100 && isprint (key)) {
if (scroll + input_x < MAX_LEN) {
wattrset (dialog, inputbox_attr);
instr[scroll + input_x] = key;
instr[scroll + input_x + 1] = '\0';
if (input_x == box_width - 1) {
scroll++;
wmove (dialog, box_y, box_x);
for (i = 0; i < box_width - 1; i++)
waddch (dialog, instr[scroll + i]);
} else {
wmove (dialog, box_y, input_x++ + box_x);
waddch (dialog, key);
}
wrefresh (dialog);
} else
flash (); /* Alarm user about overflow */
continue;
}
}
}
switch (key) {
case 'O':
case 'o':
delwin (dialog);
return 0;
case 'H':
case 'h':
delwin (dialog);
return 1;
case KEY_UP:
case KEY_LEFT:
switch (button) {
case -1:
button = 1; /* Indicates "Cancel" button is selected */
print_buttons(dialog, height, width, 1);
break;
case 0:
button = -1; /* Indicates input box is selected */
print_buttons(dialog, height, width, 0);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
break;
case 1:
button = 0; /* Indicates "OK" button is selected */
print_buttons(dialog, height, width, 0);
break;
}
break;
case TAB:
case KEY_DOWN:
case KEY_RIGHT:
switch (button) {
case -1:
button = 0; /* Indicates "OK" button is selected */
print_buttons(dialog, height, width, 0);
break;
case 0:
button = 1; /* Indicates "Cancel" button is selected */
print_buttons(dialog, height, width, 1);
break;
case 1:
button = -1; /* Indicates input box is selected */
print_buttons(dialog, height, width, 0);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
break;
}
break;
case ' ':
case '\n':
delwin (dialog);
return (button == -1 ? 0 : button);
case 'X':
case 'x':
key = ESC;
case ESC:
break;
}
}
delwin (dialog);
return -1; /* ESC pressed */
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,226 @@
/*
* dialog - Display simple dialog boxes from shell scripts
*
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dialog.h"
static void Usage (const char *name);
typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
struct Mode {
char *name;
int argmin, argmax, argmod;
jumperFn *jumper;
};
jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
jumperFn j_msgbox, j_infobox;
static struct Mode modes[] =
{
{"--menu", 9, 0, 3, j_menu},
{"--checklist", 9, 0, 3, j_checklist},
{"--radiolist", 9, 0, 3, j_radiolist},
{"--yesno", 5,5,1, j_yesno},
{"--textbox", 5,5,1, j_textbox},
{"--inputbox", 5, 6, 1, j_inputbox},
{"--msgbox", 5, 5, 1, j_msgbox},
{"--infobox", 5, 5, 1, j_infobox},
{NULL, 0, 0, 0, NULL}
};
static struct Mode *modePtr;
#ifdef LOCALE
#include <locale.h>
#endif
int
main (int argc, const char * const * argv)
{
int offset = 0, clear_screen = 0, end_common_opts = 0, retval;
const char *title = NULL;
#ifdef LOCALE
(void) setlocale (LC_ALL, "");
#endif
#ifdef TRACE
trace(TRACE_CALLS|TRACE_UPDATE);
#endif
if (argc < 2) {
Usage (argv[0]);
exit (-1);
}
while (offset < argc - 1 && !end_common_opts) { /* Common options */
if (!strcmp (argv[offset + 1], "--title")) {
if (argc - offset < 3 || title != NULL) {
Usage (argv[0]);
exit (-1);
} else {
title = argv[offset + 2];
offset += 2;
}
} else if (!strcmp (argv[offset + 1], "--backtitle")) {
if (backtitle != NULL) {
Usage (argv[0]);
exit (-1);
} else {
backtitle = argv[offset + 2];
offset += 2;
}
} else if (!strcmp (argv[offset + 1], "--clear")) {
if (clear_screen) { /* Hey, "--clear" can't appear twice! */
Usage (argv[0]);
exit (-1);
} else if (argc == 2) { /* we only want to clear the screen */
init_dialog ();
refresh (); /* init_dialog() will clear the screen for us */
end_dialog ();
return 0;
} else {
clear_screen = 1;
offset++;
}
} else /* no more common options */
end_common_opts = 1;
}
if (argc - 1 == offset) { /* no more options */
Usage (argv[0]);
exit (-1);
}
/* use a table to look for the requested mode, to avoid code duplication */
for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
if (!strcmp (argv[offset + 1], modePtr->name))
break;
if (!modePtr->name)
Usage (argv[0]);
if (argc - offset < modePtr->argmin)
Usage (argv[0]);
if (modePtr->argmax && argc - offset > modePtr->argmax)
Usage (argv[0]);
init_dialog ();
retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
if (clear_screen) { /* clear screen before exit */
attr_clear (stdscr, LINES, COLS, screen_attr);
refresh ();
}
end_dialog();
exit (retval);
}
/*
* Print program usage
*/
static void
Usage (const char *name)
{
fprintf (stderr, "\
\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
\n modified/gutted for use as a Linux kernel config tool by \
\n William Roadcap (roadcapw@cfw.com)\
\n\
\n* Display dialog boxes from shell scripts *\
\n\
\nUsage: %s --clear\
\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
\n\
\nBox options:\
\n\
\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
\n --textbox <file> <height> <width>\
\n --inputbox <text> <height> <width> [<init>]\
\n --yesno <text> <height> <width>\
\n", name, name);
exit (-1);
}
/*
* These are the program jumpers
*/
int
j_menu (const char *t, int ac, const char * const * av)
{
return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
}
int
j_checklist (const char *t, int ac, const char * const * av)
{
return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
}
int
j_radiolist (const char *t, int ac, const char * const * av)
{
return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
}
int
j_textbox (const char *t, int ac, const char * const * av)
{
return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
}
int
j_yesno (const char *t, int ac, const char * const * av)
{
return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
}
int
j_inputbox (const char *t, int ac, const char * const * av)
{
int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
ac == 6 ? av[5] : (char *) NULL);
if (ret == 0)
fprintf(stderr, dialog_input_result);
return ret;
}
int
j_msgbox (const char *t, int ac, const char * const * av)
{
return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
}
int
j_infobox (const char *t, int ac, const char * const * av)
{
return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
}

Binary file not shown.

View File

@@ -0,0 +1,452 @@
/*
* menubox.c -- implements the menu box
*
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Changes by Clifford Wolf (god@clifford.at)
*
* [ 1998-06-13 ]
*
* *) A bugfix for the Page-Down problem
*
* *) Formerly when I used Page Down and Page Up, the cursor would be set
* to the first position in the menu box. Now lxdialog is a bit
* smarter and works more like other menu systems (just have a look at
* it).
*
* *) Formerly if I selected something my scrolling would be broken because
* lxdialog is re-invoked by the Menuconfig shell script, can't
* remember the last scrolling position, and just sets it so that the
* cursor is at the bottom of the box. Now it writes the temporary file
* lxdialog.scrltmp which contains this information. The file is
* deleted by lxdialog if the user leaves a submenu or enters a new
* one, but it would be nice if Menuconfig could make another "rm -f"
* just to be sure. Just try it out - you will recognise a difference!
*
* [ 1998-06-14 ]
*
* *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
* and menus change their size on the fly.
*
* *) If for some reason the last scrolling position is not saved by
* lxdialog, it sets the scrolling so that the selected item is in the
* middle of the menu box, not at the bottom.
*
* 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
* Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
* This fixes a bug in Menuconfig where using ' ' to descend into menus
* would leave mis-synchronized lxdialog.scrltmp files lying around,
* fscanf would read in 'scroll', and eventually that value would get used.
*/
#include "dialog.h"
static int menu_width, item_x;
/*
* Print menu item
*/
static void
print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
{
int j;
char menu_item[menu_width+1];
strncpy(menu_item, item, menu_width);
menu_item[menu_width] = 0;
j = first_alpha(menu_item, "YyNnMmHh");
/* Clear 'residue' of last item */
wattrset (win, menubox_attr);
wmove (win, choice, 0);
#if OLD_NCURSES
{
int i;
for (i = 0; i < menu_width; i++)
waddch (win, ' ');
}
#else
wclrtoeol(win);
#endif
wattrset (win, selected ? item_selected_attr : item_attr);
mvwaddstr (win, choice, item_x, menu_item);
if (hotkey) {
wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
mvwaddch(win, choice, item_x+j, menu_item[j]);
}
if (selected) {
wmove (win, choice, item_x+1);
wrefresh (win);
}
}
/*
* Print the scroll indicators.
*/
static void
print_arrows (WINDOW * win, int item_no, int scroll,
int y, int x, int height)
{
int cur_y, cur_x;
getyx(win, cur_y, cur_x);
wmove(win, y, x);
if (scroll > 0) {
wattrset (win, uarrow_attr);
waddch (win, ACS_UARROW);
waddstr (win, "(-)");
}
else {
wattrset (win, menubox_attr);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
}
y = y + height + 1;
wmove(win, y, x);
if ((height < item_no) && (scroll + height < item_no)) {
wattrset (win, darrow_attr);
waddch (win, ACS_DARROW);
waddstr (win, "(+)");
}
else {
wattrset (win, menubox_border_attr);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
waddch (win, ACS_HLINE);
}
wmove(win, cur_y, cur_x);
}
/*
* Display the termination buttons.
*/
static void
print_buttons (WINDOW *win, int height, int width, int selected)
{
int x = width / 2 - 16;
int y = height - 2;
print_button (win, "Select", y, x, selected == 0);
print_button (win, " Exit ", y, x + 12, selected == 1);
print_button (win, " Help ", y, x + 24, selected == 2);
wmove(win, y, x+1+12*selected);
wrefresh (win);
}
/*
* Display a menu for choosing among a number of options
*/
int
dialog_menu (const char *title, const char *prompt, int height, int width,
int menu_height, const char *current, int item_no,
const char * const * items)
{
int i, j, x, y, box_x, box_y;
int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
WINDOW *dialog, *menu;
FILE *f;
max_choice = MIN (menu_height, item_no);
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
draw_shadow (stdscr, y, x, height, width);
dialog = newwin (height, width, y, x);
keypad (dialog, TRUE);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset (dialog, border_attr);
mvwaddch (dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
wbkgdset (dialog, dialog_attr & A_COLOR);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) {
/* truncate long title -- mec */
char * title2 = malloc(width-2+1);
memcpy( title2, title, width-2 );
title2[width-2] = '\0';
title = title2;
}
if (title != NULL) {
wattrset (dialog, title_attr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
wattrset (dialog, dialog_attr);
print_autowrap (dialog, prompt, width - 2, 1, 3);
menu_width = width - 6;
box_y = height - menu_height - 5;
box_x = (width - menu_width) / 2 - 1;
/* create new window for the menu */
menu = subwin (dialog, menu_height, menu_width,
y + box_y + 1, x + box_x + 1);
keypad (menu, TRUE);
/* draw a box around the menu items */
draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
menubox_border_attr, menubox_attr);
/*
* Find length of longest item in order to center menu.
* Set 'choice' to default item.
*/
item_x = 0;
for (i = 0; i < item_no; i++) {
item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
if (strcmp(current, items[i*2]) == 0) choice = i;
}
item_x = (menu_width - item_x) / 2;
/* get the scroll info from the temp file */
if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
(scroll+max_choice > choice) && (scroll >= 0) &&
(scroll+max_choice <= item_no) ) {
first_item = scroll;
choice = choice - scroll;
fclose(f);
} else {
scroll=0;
remove("lxdialog.scrltmp");
fclose(f);
f=NULL;
}
}
if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
if (choice >= item_no-max_choice/2)
scroll = first_item = item_no-max_choice;
else
scroll = first_item = choice - max_choice/2;
choice = choice - scroll;
}
/* Print the menu */
for (i=0; i < max_choice; i++) {
print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
(items[(first_item + i)*2][0] != ':'));
}
wnoutrefresh (menu);
print_arrows(dialog, item_no, scroll,
box_y, box_x+item_x+1, menu_height);
print_buttons (dialog, height, width, 0);
wmove (menu, choice, item_x+1);
wrefresh (menu);
while (key != ESC) {
key = wgetch(menu);
if ( key == '/' ) {
int ret = dialog_inputbox("Search Configuration Parameter",
"Enter Keyword", height, width,
(char *) NULL);
if (ret == 0) {
fprintf(stderr, "%s", dialog_input_result);
return 26;
}
}
if (key < 256 && isalpha(key)) key = tolower(key);
if (strchr("ynmh", key))
i = max_choice;
else {
for (i = choice+1; i < max_choice; i++) {
j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
if (key == tolower(items[(scroll+i)*2+1][j]))
break;
}
if (i == max_choice)
for (i = 0; i < max_choice; i++) {
j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
if (key == tolower(items[(scroll+i)*2+1][j]))
break;
}
}
if (i < max_choice ||
key == KEY_UP || key == KEY_DOWN ||
key == '-' || key == '+' ||
key == KEY_PPAGE || key == KEY_NPAGE) {
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
(items[(scroll+choice)*2][0] != ':'));
if (key == KEY_UP || key == '-') {
if (choice < 2 && scroll) {
/* Scroll menu down */
scrollok (menu, TRUE);
wscrl (menu, -1);
scrollok (menu, FALSE);
scroll--;
print_item (menu, items[scroll * 2 + 1], 0, FALSE,
(items[scroll*2][0] != ':'));
} else
choice = MAX(choice - 1, 0);
} else if (key == KEY_DOWN || key == '+') {
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
(items[(scroll+choice)*2][0] != ':'));
if ((choice > max_choice-3) &&
(scroll + max_choice < item_no)
) {
/* Scroll menu up */
scrollok (menu, TRUE);
scroll (menu);
scrollok (menu, FALSE);
scroll++;
print_item (menu, items[(scroll+max_choice-1)*2+1],
max_choice-1, FALSE,
(items[(scroll+max_choice-1)*2][0] != ':'));
} else
choice = MIN(choice+1, max_choice-1);
} else if (key == KEY_PPAGE) {
scrollok (menu, TRUE);
for (i=0; (i < max_choice); i++) {
if (scroll > 0) {
wscrl (menu, -1);
scroll--;
print_item (menu, items[scroll * 2 + 1], 0, FALSE,
(items[scroll*2][0] != ':'));
} else {
if (choice > 0)
choice--;
}
}
scrollok (menu, FALSE);
} else if (key == KEY_NPAGE) {
for (i=0; (i < max_choice); i++) {
if (scroll+max_choice < item_no) {
scrollok (menu, TRUE);
scroll(menu);
scrollok (menu, FALSE);
scroll++;
print_item (menu, items[(scroll+max_choice-1)*2+1],
max_choice-1, FALSE,
(items[(scroll+max_choice-1)*2][0] != ':'));
} else {
if (choice+1 < max_choice)
choice++;
}
}
} else
choice = i;
print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
(items[(scroll+choice)*2][0] != ':'));
print_arrows(dialog, item_no, scroll,
box_y, box_x+item_x+1, menu_height);
wnoutrefresh (dialog);
wrefresh (menu);
continue; /* wait for another key press */
}
switch (key) {
case KEY_LEFT:
case TAB:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 2 : (button > 2 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh (menu);
break;
case ' ':
case 's':
case 'y':
case 'n':
case 'm':
/* save scroll info */
if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
fprintf(f,"%d\n",scroll);
fclose(f);
}
delwin (dialog);
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
switch (key) {
case 's': return 3;
case 'y': return 3;
case 'n': return 4;
case 'm': return 5;
case ' ': return 6;
}
return 0;
case 'h':
case '?':
button = 2;
case '\n':
delwin (dialog);
if (button == 2)
fprintf(stderr, "%s \"%s\"\n",
items[(scroll + choice) * 2],
items[(scroll + choice) * 2 + 1] +
first_alpha(items[(scroll + choice) * 2 + 1],""));
else
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
remove("lxdialog.scrltmp");
return button;
case 'e':
case 'x':
key = ESC;
case ESC:
break;
}
}
delwin (dialog);
remove("lxdialog.scrltmp");
return -1; /* ESC pressed */
}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More