diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2010-09-02 17:08:11 +0200 |
---|---|---|
committer | Peter Korsgaard <jacmet@sunsite.dk> | 2010-09-02 17:08:11 +0200 |
commit | e62ed84b19d114870daf1f16aae177f60f9d6ad3 (patch) | |
tree | 9b3471d639525410bd65e36c5e5aa94b77c29a28 | |
parent | 9bc12b85e83266c83f1fee0b9dd2d38e43d9252c (diff) | |
parent | 40177240fab04c710fd756a24816b451b37dc1b8 (diff) |
Merge branch 'for-2010.11/kconfig-upgrade' of git://git.busybox.net/~tpetazzoni/git/buildroot
50 files changed, 5712 insertions, 2502 deletions
@@ -25,12 +25,11 @@ # absolute path TOPDIR:=$(shell pwd) CONFIG_CONFIG_IN=Config.in -CONFIG_DEFCONFIG=.defconfig CONFIG=package/config DATE:=$(shell date +%Y%m%d) -noconfig_targets:=menuconfig gconfig xconfig config oldconfig randconfig \ - defconfig allyesconfig allnoconfig release \ +noconfig_targets:=menuconfig nconfig gconfig xconfig config oldconfig randconfig \ + defconfig %_defconfig savedefconfig allyesconfig allnoconfig silentoldconfig release \ randpackageconfig allyespackageconfig allnopackageconfig \ source-check help @@ -323,17 +322,17 @@ TARGETS_ALL:=$(patsubst %,__real_tgt_%,$(TARGETS)) # all targets depend on the crosscompiler and it's prerequisites $(TARGETS_ALL): __real_tgt_%: $(BASE_TARGETS) % -$(BR2_DEPENDS_DIR): $(CONFIG_DIR)/.config -# rm -rf $@ -# mkdir -p $(@D) -# cp -dpRf $(CONFIG)/buildroot-config $@ - dirs: $(DL_DIR) $(TOOLCHAIN_DIR) $(BUILD_DIR) $(STAGING_DIR) $(TARGET_DIR) \ $(HOST_DIR) $(BR2_DEPENDS_DIR) $(BINARIES_DIR) $(STAMP_DIR) $(BASE_TARGETS): dirs -world: dependencies dirs $(BASE_TARGETS) $(TARGETS_ALL) +$(BUILD_DIR)/buildroot-config/auto.conf: $(CONFIG_DIR)/.config + $(MAKE) $(EXTRAMAKEARGS) silentoldconfig + +prepare: $(BUILD_DIR)/buildroot-config/auto.conf + +world: prepare dependencies dirs $(BASE_TARGETS) $(TARGETS_ALL) .PHONY: all world dirs clean distclean source \ @@ -468,99 +467,98 @@ export HOSTCFLAGS $(BUILD_DIR)/buildroot-config/%onf: mkdir -p $(@D)/lxdialog - $(MAKE) CC="$(HOSTCC)" obj=$(@D) -C $(CONFIG) $(@F) - -@if [ ! -f $(CONFIG_DIR)/.config ]; then \ - cp $(CONFIG_DEFCONFIG) $(CONFIG_DIR)/.config; \ - fi + $(MAKE) CC="$(HOSTCC)" obj=$(@D) -C $(CONFIG) -f Makefile.br $(@F) + +COMMON_CONFIG_ENV = \ + KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ + KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ + KCONFIG_TRISTATE=$(BUILD_DIR)/buildroot-config/tristate.config \ + BUILDROOT_CONFIG=$(CONFIG_DIR)/.config xconfig: $(BUILD_DIR)/buildroot-config/qconf @mkdir -p $(BUILD_DIR)/buildroot-config - @if ! KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< $(CONFIG_CONFIG_IN); then \ + @if ! $(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN); then \ test -f $(CONFIG_DIR)/.config.cmd || rm -f $(CONFIG_DIR)/.config; \ fi gconfig: $(BUILD_DIR)/buildroot-config/gconf @mkdir -p $(BUILD_DIR)/buildroot-config - @if ! KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - srctree=$(TOPDIR) \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< $(CONFIG_CONFIG_IN); then \ + @if ! $(COMMON_CONFIG_ENV) srctree=$(TOPDIR) \ + $< $(CONFIG_CONFIG_IN); then \ test -f $(CONFIG_DIR)/.config.cmd || rm -f $(CONFIG_DIR)/.config; \ fi menuconfig: $(BUILD_DIR)/buildroot-config/mconf @mkdir -p $(BUILD_DIR)/buildroot-config - @if ! KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< $(CONFIG_CONFIG_IN); then \ + @if ! $(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN); then \ + test -f $(CONFIG_DIR)/.config.cmd || rm -f $(CONFIG_DIR)/.config; \ + fi + +nconfig: $(BUILD_DIR)/buildroot-config/nconf + @mkdir -p $(BUILD_DIR)/buildroot-config + @if ! $(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN); then \ test -f $(CONFIG_DIR)/.config.cmd || rm -f $(CONFIG_DIR)/.config; \ fi config: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< $(CONFIG_CONFIG_IN) + @$(COMMON_CONFIG_ENV) $< $(CONFIG_CONFIG_IN) oldconfig: $(BUILD_DIR)/buildroot-config/conf mkdir -p $(BUILD_DIR)/buildroot-config - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -o $(CONFIG_CONFIG_IN) + @$(COMMON_CONFIG_ENV) $< --oldconfig $(CONFIG_CONFIG_IN) randconfig: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -r $(CONFIG_CONFIG_IN) + @$(COMMON_CONFIG_ENV) $< --randconfig $(CONFIG_CONFIG_IN) allyesconfig: $(BUILD_DIR)/buildroot-config/conf - cat $(CONFIG_DEFCONFIG) > $(CONFIG_DIR)/.config @mkdir -p $(BUILD_DIR)/buildroot-config - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -y $(CONFIG_CONFIG_IN) + @$(COMMON_CONFIG_ENV) $< --allyesconfig $(CONFIG_CONFIG_IN) allnoconfig: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -n $(CONFIG_CONFIG_IN) + @$(COMMON_CONFIG_ENV) $< --allnoconfig $(CONFIG_CONFIG_IN) randpackageconfig: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config @grep -v BR2_PACKAGE_ $(CONFIG_DIR)/.config > $(CONFIG_DIR)/.config.nopkg - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ + @$(COMMON_CONFIG_ENV) \ KCONFIG_ALLCONFIG=$(CONFIG_DIR)/.config.nopkg \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -r $(CONFIG_CONFIG_IN) + $< --randconfig $(CONFIG_CONFIG_IN) @rm -f $(CONFIG_DIR)/.config.nopkg allyespackageconfig: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config @grep -v BR2_PACKAGE_ $(CONFIG_DIR)/.config > $(CONFIG_DIR)/.config.nopkg - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ + @$(COMMON_CONFIG_ENV) \ KCONFIG_ALLCONFIG=$(CONFIG_DIR)/.config.nopkg \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -y $(CONFIG_CONFIG_IN) + $< --allyesconfig $(CONFIG_CONFIG_IN) @rm -f $(CONFIG_DIR)/.config.nopkg allnopackageconfig: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config @grep -v BR2_PACKAGE_ $(CONFIG_DIR)/.config > $(CONFIG_DIR)/.config.nopkg - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ + @$(COMMON_CONFIG_ENV) \ KCONFIG_ALLCONFIG=$(CONFIG_DIR)/.config.nopkg \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -n $(CONFIG_CONFIG_IN) + $< --allnoconfig $(CONFIG_CONFIG_IN) @rm -f $(CONFIG_DIR)/.config.nopkg +silentoldconfig: $(BUILD_DIR)/buildroot-config/conf + @mkdir -p $(BUILD_DIR)/buildroot-config + $(COMMON_CONFIG_ENV) $< --silentoldconfig $(CONFIG_CONFIG_IN) + defconfig: $(BUILD_DIR)/buildroot-config/conf @mkdir -p $(BUILD_DIR)/buildroot-config - @KCONFIG_AUTOCONFIG=$(BUILD_DIR)/buildroot-config/auto.conf \ - KCONFIG_AUTOHEADER=$(BUILD_DIR)/buildroot-config/autoconf.h \ - BUILDROOT_CONFIG=$(CONFIG_DIR)/.config $< -d $(CONFIG_CONFIG_IN) + @$(COMMON_CONFIG_ENV) $< --defconfig $(CONFIG_CONFIG_IN) + +%_defconfig: $(BUILD_DIR)/buildroot-config/conf $(TOPDIR)/configs/%_defconfig + @mkdir -p $(BUILD_DIR)/buildroot-config + @$(COMMON_CONFIG_ENV) $< --defconfig=$(TOPDIR)/configs/$@ $(CONFIG_CONFIG_IN) + +savedefconfig: $(BUILD_DIR)/buildroot-config/conf + @mkdir -p $(BUILD_DIR)/buildroot-config + @$(COMMON_CONFIG_ENV) $< --savedefconfig=$(TOPDIR)/defconfig $(CONFIG_CONFIG_IN) # check if download URLs are outdated source-check: allyesconfig @@ -589,10 +587,6 @@ endif flush: rm -f $(BUILD_DIR)/tgt-config.cache $(BUILD_DIR)/host-config.cache -%_defconfig: $(TOPDIR)/configs/%_defconfig - cp $^ $(CONFIG_DIR)/.config - @$(MAKE) $(EXTRAMAKEARGS) oldconfig - configured: dirs host-sed kernel-headers uclibc-config busybox-config linux26-config prepatch: gcc-patched binutils-patched gdb-patched uclibc-patched diff --git a/package/config/.gitignore b/package/config/.gitignore index 1ea18a233..106bc1258 100644 --- a/package/config/.gitignore +++ b/package/config/.gitignore @@ -1,9 +1,28 @@ -/conf -/mconf -/qconf -/qconf.moc -/.tmp_qtcheck -/lkc_defs.h -/lex.zconf.c -/zconf.hash.c -/zconf.tab.c +# +# Generated files +# +config* +lex.*.c +*.tab.c +*.tab.h +zconf.hash.c +*.moc +lkc_defs.h +gconf.glade.h +*.pot +*.mo + +# +# configuration programs +# +conf +mconf +nconf +qconf +gconf +kxgettext + +# +# Quilt is being used to handle the patch series +# +.pc diff --git a/package/config/Makefile b/package/config/Makefile index 2b266b872..d8d44b042 100644 --- a/package/config/Makefile +++ b/package/config/Makefile @@ -1,53 +1,365 @@ -src := . -top_srcdir=../../ -top_builddir=../../ -srctree := . -obj ?= . - -include Makefile.kconfig -#HOSTCFLAGS+=-Dinline="" -include foo.h --include $(obj)/.depend -$(obj)/.depend: $(wildcard *.h *.c) - $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) -MM *.c > $@ 2>/dev/null || : - -__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) -host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) -host-cmulti := $(foreach m,$(__hostprogs),\ - $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) -host-cxxmulti := $(foreach m,$(__hostprogs),\ - $(if $($(m)-cxxobjs),$(m),$(if $($(m)-objs),))) -host-cobjs := $(addprefix $(obj)/,$(sort $(foreach m,$(__hostprogs),$($(m)-objs)))) -host-cxxobjs := $(addprefix $(obj)/,$(sort $(foreach m,$(__hostprogs),$($(m)-cxxobjs)))) - -HOST_EXTRACFLAGS += -I$(obj) - -$(host-csingle): %: %.c - $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $< $(HOST_LOADLIBES) -o $(obj)/$@ - -$(host-cmulti): %: $(host-cobjs) $(host-cshlib) - $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(addprefix $(obj)/,$($(@F)-objs)) $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) -o $(obj)/$@ - -$(host-cxxmulti): %: $(host-cxxobjs) $(host-cobjs) $(host-cshlib) - $(HOSTCXX) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCXXFLAGS_$@) $(addprefix $(obj)/,$($(@F)-objs) $($(@F)-cxxobjs)) $(HOSTLOADLIBES_$(@F)) -o $(obj)/$@ - -$(obj)/%.o: %.c - $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) -c $< -o $@ - -$(obj)/%.o: $(obj)/%.c - $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) -c $< -o $@ - -$(obj)/%.o: %.cc - $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCXXFLAGS_$(@F)) -c $< -o $@ - -$(obj)/%:: $(src)/%_shipped - $(Q)cat $< > $@ - -clean: - $(Q)rm -f $(addprefix $(obj)/,$(clean-files)) -distclean: clean - $(Q)rm -f $(addprefix $(obj)/,$(lxdialog) $(conf-objs) $(mconf-objs) $(kxgettext-objs) \ - $(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs) \ - mconf .depend) - -FORCE: -.PHONY: FORCE clean distclean +# =========================================================================== +# Kernel configuration targets +# These targets are used from top-level makefile + +PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ + localmodconfig localyesconfig + +ifdef KBUILD_KCONFIG +Kconfig := $(KBUILD_KCONFIG) +else +Kconfig := arch/$(SRCARCH)/Kconfig +endif + +xconfig: $(obj)/qconf + $< $(Kconfig) + +gconfig: $(obj)/gconf + $< $(Kconfig) + +menuconfig: $(obj)/mconf + $< $(Kconfig) + +config: $(obj)/conf + $< --oldaskconfig $(Kconfig) + +nconfig: $(obj)/nconf + $< $(Kconfig) + +oldconfig: $(obj)/conf + $< --$@ $(Kconfig) + +silentoldconfig: $(obj)/conf + $(Q)mkdir -p include/generated + $< --$@ $(Kconfig) + +# if no path is given, then use src directory to find file +ifdef LSMOD +LSMOD_F := $(LSMOD) +ifeq ($(findstring /,$(LSMOD)),) + LSMOD_F := $(objtree)/$(LSMOD) +endif +endif + +localmodconfig: $(obj)/streamline_config.pl $(obj)/conf + $(Q)mkdir -p include/generated + $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config + $(Q)if [ -f .config ]; then \ + cmp -s .tmp.config .config || \ + (mv -f .config .config.old.1; \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ + mv -f .config.old.1 .config.old) \ + else \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ + fi + $(Q)rm -f .tmp.config + +localyesconfig: $(obj)/streamline_config.pl $(obj)/conf + $(Q)mkdir -p include/generated + $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config + $(Q)sed -i s/=m/=y/ .tmp.config + $(Q)if [ -f .config ]; then \ + cmp -s .tmp.config .config || \ + (mv -f .config .config.old.1; \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ + mv -f .config.old.1 .config.old) \ + else \ + mv -f .tmp.config .config; \ + $(obj)/conf --silentoldconfig $(Kconfig); \ + fi + $(Q)rm -f .tmp.config + +# Create new linux.pot file +# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files +# The symlink is used to repair a deficiency in arch/um +update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h + $(Q)echo " GEN config" + $(Q)xgettext --default-domain=linux \ + --add-comments --keyword=_ --keyword=N_ \ + --from-code=UTF-8 \ + --files-from=scripts/kconfig/POTFILES.in \ + --output $(obj)/config.pot + $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot + $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch + $(Q)(for i in `ls arch/*/Kconfig`; \ + do \ + echo " GEN $$i"; \ + $(obj)/kxgettext $$i \ + >> $(obj)/config.pot; \ + done ) + $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ + --output $(obj)/linux.pot + $(Q)rm -f arch/um/Kconfig.arch + $(Q)rm -f $(obj)/config.pot + +PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig + +allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf + $< --$@ $(Kconfig) + +PHONY += listnewconfig oldnoconfig savedefconfig defconfig + +listnewconfig oldnoconfig: $(obj)/conf + $< --$@ $(Kconfig) + +savedefconfig: $(obj)/conf + $< --$@=defconfig $(Kconfig) + +defconfig: $(obj)/conf +ifeq ($(KBUILD_DEFCONFIG),) + $< --defconfig $(Kconfig) +else + @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" + $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) +endif + +%_defconfig: $(obj)/conf + $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + +# Help text used by make help +help: + @echo ' config - Update current config utilising a line-oriented program' + @echo ' nconfig - Update current config utilising a ncurses menu based program' + @echo ' menuconfig - Update current config utilising a menu based program' + @echo ' xconfig - Update current config utilising a QT based front-end' + @echo ' gconfig - Update current config utilising a GTK based front-end' + @echo ' oldconfig - Update current config utilising a provided .config as base' + @echo ' localmodconfig - Update current config disabling modules not loaded' + @echo ' localyesconfig - Update current config converting local mods to core' + @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' + @echo ' defconfig - New config with default from ARCH supplied defconfig' + @echo ' savedefconfig - Save current config as ./defconfig (minimal config)' + @echo ' allnoconfig - New config where all options are answered with no' + @echo ' allyesconfig - New config where all options are accepted with yes' + @echo ' allmodconfig - New config selecting modules when possible' + @echo ' alldefconfig - New config with all symbols set to default' + @echo ' randconfig - New config with random answer to all options' + @echo ' listnewconfig - List new options' + @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)' + +# lxdialog stuff +check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh + +# Use recursively expanded variables so we do not call gcc unless +# we really need to do so. (Do not call gcc as part of make mrproper) +HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) +HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) + +HOST_EXTRACFLAGS += -DLOCALE + + +# =========================================================================== +# Shared Makefile for the various kconfig executables: +# conf: Used for defconfig, oldconfig and related targets +# nconf: Used for the nconfig target. +# Utilizes ncurses +# mconf: Used for the menuconfig 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 + +lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o +lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o + +conf-objs := conf.o zconf.tab.o +mconf-objs := mconf.o zconf.tab.o $(lxdialog) +nconf-objs := nconf.o zconf.tab.o nconf.gui.o +kxgettext-objs := kxgettext.o zconf.tab.o + +hostprogs-y := conf qconf gconf kxgettext + +ifeq ($(MAKECMDGOALS),nconfig) + hostprogs-y += nconf +endif +ifeq ($(findstring nconf,$(MAKECMDGOALS)),nconf) + hostprogs-y += nconf +endif + +ifeq ($(MAKECMDGOALS),menuconfig) + hostprogs-y += mconf +endif +ifeq ($(findstring mconf,$(MAKECMDGOALS)),mconf) + hostprogs-y += mconf +endif + +ifeq ($(MAKECMDGOALS),xconfig) + qconf-target := 1 +endif +ifeq ($(findstring qconf,$(MAKECMDGOALS)),qconf) + qconf-target := 1 +endif + +ifeq ($(MAKECMDGOALS),gconfig) + gconf-target := 1 +endif +ifeq ($(findstring gconf,$(MAKECMDGOALS)),gconf) + 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 lex.zconf.c zconf.hash.c gconf.glade.h +clean-files += config.pot linux.pot +clean-files += conf $(conf-objs) +clean-files += mconf $(mconf-objs) +clean-files += nconf $(nconf-objs) +clean-files += qconf qconf.o +clean-files += gconf gconf.o +clean-files += kconfig_load.o zconf.tab.o +clean-files += $(kxgettext-objs) + +# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) +PHONY += $(obj)/dochecklxdialog +$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog +$(obj)/dochecklxdialog: + $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) + +always := dochecklxdialog + +# Add environment specific flags +HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) + +# 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 = $(KC_QT_LIBS) -ldl +HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK + +HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl +HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ + -D LKC_DIRECT_LINK + +HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses +$(obj)/qconf.o: $(obj)/.tmp_qtcheck + +ifeq ($(qconf-target),1) +$(obj)/.tmp_qtcheck: $(src)/Makefile +-include $(obj)/.tmp_qtcheck + +# QT needs some extra effort... +$(obj)/.tmp_qtcheck: + @set -e; echo " CHECK qt"; dir=""; pkg=""; \ + pkg-config --exists qt 2> /dev/null && pkg=qt; \ + pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ + if [ -n "$$pkg" ]; then \ + cflags="\$$(shell pkg-config $$pkg --cflags)"; \ + libs="\$$(shell pkg-config $$pkg --libs)"; \ + moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ + dir="$$(pkg-config $$pkg --variable=prefix)"; \ + else \ + 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 QT3 installation. Please make sure that"; \ + echo "* the QT3 development package is correctly installed and"; \ + echo "* either install pkg-config or set the QTDIR environment"; \ + echo "* variable to the correct location."; \ + echo "*"; \ + false; \ + fi; \ + libpath=$$dir/lib; lib=qt; osdir=""; \ + $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ + osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ + test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ + test -f $$libpath/libqt-mt.so && lib=qt-mt; \ + cflags="-I$$dir/include"; \ + libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ + moc="$$dir/bin/moc"; \ + fi; \ + 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 "*"; \ + moc="/usr/bin/moc"; \ + fi; \ + echo "KC_QT_CFLAGS=$$cflags" > $@; \ + echo "KC_QT_LIBS=$$libs" >> $@; \ + echo "KC_QT_MOC=$$moc" >> $@ +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 --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ + if `pkg-config --atleast-version=2.0.0 gtk+-2.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)/zconf.hash.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 + $(KC_QT_MOC) -i $< -o $@ + +$(obj)/lkc_defs.h: $(src)/lkc_proto.h + sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + +# Extract gconf menu items for I18N support +$(obj)/gconf.glade.h: $(obj)/gconf.glade + intltool-extract --type=gettext/glade $(obj)/gconf.glade + +### +# The following requires flex/bison/gperf +# 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: $(src)/zconf.y +$(obj)/lex.zconf.c: $(src)/zconf.l +$(obj)/zconf.hash.c: $(src)/zconf.gperf + +%.tab.c: %.y + bison -l -b $* -p $(notdir $*) $< + cp $@ $@_shipped + +lex.%.c: %.l + flex -L -P$(notdir $*) -o$@ $< + cp $@ $@_shipped + +%.hash.c: %.gperf + gperf < $< > $@ + cp $@ $@_shipped + +endif diff --git a/package/config/Makefile.br b/package/config/Makefile.br new file mode 100644 index 000000000..c24b6b50f --- /dev/null +++ b/package/config/Makefile.br @@ -0,0 +1,53 @@ +src := . +top_srcdir=../../ +top_builddir=../../ +srctree := . +obj ?= . + +include Makefile +#HOSTCFLAGS+=-Dinline="" -include foo.h +-include $(obj)/.depend +$(obj)/.depend: $(wildcard *.h *.c) + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) -MM *.c > $@ 2>/dev/null || : + +__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) +host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) +host-cmulti := $(foreach m,$(__hostprogs),\ + $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) +host-cxxmulti := $(foreach m,$(__hostprogs),\ + $(if $($(m)-cxxobjs),$(m),$(if $($(m)-objs),))) +host-cobjs := $(addprefix $(obj)/,$(sort $(foreach m,$(__hostprogs),$($(m)-objs)))) +host-cxxobjs := $(addprefix $(obj)/,$(sort $(foreach m,$(__hostprogs),$($(m)-cxxobjs)))) + +HOST_EXTRACFLAGS += -I$(obj) + +$(host-csingle): %: %.c + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $< $(HOST_LOADLIBES) -o $(obj)/$@ + +$(host-cmulti): %: $(host-cobjs) $(host-cshlib) + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(addprefix $(obj)/,$($(@F)-objs)) $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) -o $(obj)/$@ + +$(host-cxxmulti): %: $(host-cxxobjs) $(host-cobjs) $(host-cshlib) + $(HOSTCXX) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCXXFLAGS_$@) $(addprefix $(obj)/,$($(@F)-objs) $($(@F)-cxxobjs)) $(HOSTLOADLIBES_$(@F)) -o $(obj)/$@ + +$(obj)/%.o: %.c + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) -c $< -o $@ + +$(obj)/%.o: $(obj)/%.c + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) -c $< -o $@ + +$(obj)/%.o: %.cc + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCXXFLAGS_$(@F)) -c $< -o $@ + +$(obj)/%:: $(src)/%_shipped + $(Q)cat $< > $@ + +clean: + $(Q)rm -f $(addprefix $(obj)/,$(clean-files)) +distclean: clean + $(Q)rm -f $(addprefix $(obj)/,$(lxdialog) $(conf-objs) $(mconf-objs) $(kxgettext-objs) \ + $(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs) \ + mconf .depend) + +FORCE: +.PHONY: FORCE clean distclean diff --git a/package/config/Makefile.kconfig b/package/config/Makefile.kconfig deleted file mode 100644 index f2693482e..000000000 --- a/package/config/Makefile.kconfig +++ /dev/null @@ -1,303 +0,0 @@ -# =========================================================================== -# Kernel configuration targets -# These targets are used from top-level makefile - -PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config - -ifdef KBUILD_KCONFIG -Kconfig := $(KBUILD_KCONFIG) -else -Kconfig := arch/$(SRCARCH)/Kconfig -endif - -xconfig: $(obj)/qconf - $< $(Kconfig) - -gconfig: $(obj)/gconf - $< $(Kconfig) - -menuconfig: $(obj)/mconf - $< $(Kconfig) - -config: $(obj)/conf - $< $(Kconfig) - -oldconfig: $(obj)/conf - $< -o $(Kconfig) - -silentoldconfig: $(obj)/conf - $< -s $(Kconfig) - -# Create new linux.pot file -# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files -# The symlink is used to repair a deficiency in arch/um -update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h - $(Q)echo " GEN config" - $(Q)xgettext --default-domain=linux \ - --add-comments --keyword=_ --keyword=N_ \ - --from-code=UTF-8 \ - --files-from=scripts/kconfig/POTFILES.in \ - --output $(obj)/config.pot - $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot - $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch - $(Q)(for i in `ls arch/*/Kconfig`; \ - do \ - echo " GEN $$i"; \ - $(obj)/kxgettext $$i \ - >> $(obj)/config.pot; \ - done ) - $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ - --output $(obj)/linux.pot - $(Q)rm -f arch/um/Kconfig.arch - $(Q)rm -f $(obj)/config.pot - -PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig - -randconfig: $(obj)/conf - $< -r $(Kconfig) - -allyesconfig: $(obj)/conf - $< -y $(Kconfig) - -allnoconfig: $(obj)/conf - $< -n $(Kconfig) - -allmodconfig: $(obj)/conf - $< -m $(Kconfig) - -defconfig: $(obj)/conf -ifeq ($(KBUILD_DEFCONFIG),) - $< -d $(Kconfig) -else - @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" - $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) -endif - -%_defconfig: $(obj)/conf - $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) - -# Help text used by make help -help: - @echo ' config - Update current config utilising a line-oriented program' - @echo ' menuconfig - Update current config utilising a menu based program' - @echo ' xconfig - Update current config utilising a QT based front-end' - @echo ' gconfig - Update current config utilising a GTK based front-end' - @echo ' oldconfig - Update current config utilising a provided .config as base' - @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' - @echo ' randconfig - New config with random answer to all options' - @echo ' defconfig - New config with default answer to all options' - @echo ' allmodconfig - New config selecting modules when possible' - @echo ' allyesconfig - New config where all options are accepted with yes' - @echo ' allnoconfig - New config where all options are answered with no' - -# lxdialog stuff -check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh - -# Use recursively expanded variables so we do not call gcc unless -# we really need to do so. (Do not call gcc as part of make mrproper) -HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) -HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) - -HOST_EXTRACFLAGS += -DLOCALE - - -# =========================================================================== -# Shared Makefile for the various kconfig executables: -# conf: Used for defconfig, oldconfig and related targets -# mconf: Used for the menuconfig 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 - -lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o -lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o - -conf-objs := conf.o zconf.tab.o -mconf-objs := mconf.o zconf.tab.o $(lxdialog) -kxgettext-objs := kxgettext.o zconf.tab.o - -hostprogs-y := conf qconf gconf kxgettext - -ifeq ($(MAKECMDGOALS),menuconfig) - hostprogs-y += mconf -endif -ifeq ($(findstring mconf,$(MAKECMDGOALS)),mconf) - hostprogs-y += mconf -endif - -ifeq ($(MAKECMDGOALS),xconfig) - qconf-target := 1 -endif -ifeq ($(findstring qconf,$(MAKECMDGOALS)),qconf) - qconf-target := 1 -endif - -ifeq ($(MAKECMDGOALS),gconfig) - gconf-target := 1 -endif -ifeq ($(findstring gconf,$(MAKECMDGOALS)),gconf) - 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 lex.zconf.c zconf.hash.c gconf.glade.h -clean-files += config.pot linux.pot -clean-files += conf $(conf-objs) -clean-files += mconf $(mconf-objs) -clean-files += qconf qconf.o -clean-files += gconf gconf.o -clean-files += kconfig_load.o zconf.tab.o -clean-files += $(kxgettext-objs) - -# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) -PHONY += $(obj)/dochecklxdialog -$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog -$(obj)/dochecklxdialog: - $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) - -always := dochecklxdialog - -# Add environment specific flags -HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) - -# 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 = $(KC_QT_LIBS) -ldl -HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK - -HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl -HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ - -D LKC_DIRECT_LINK - -$(obj)/qconf.o: $(obj)/.tmp_qtcheck - -ifeq ($(qconf-target),1) -$(obj)/.tmp_qtcheck: $(src)/Makefile --include $(obj)/.tmp_qtcheck - -# QT needs some extra effort... -$(obj)/.tmp_qtcheck: - @set -e; echo " CHECK qt"; dir=""; pkg=""; \ - pkg-config --exists qt 2> /dev/null && pkg=qt; \ - pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ - if [ -n "$$pkg" ]; then \ - cflags="\$$(shell pkg-config $$pkg --cflags)"; \ - libs="\$$(shell pkg-config $$pkg --libs)"; \ - moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ - dir="$$(pkg-config $$pkg --variable=prefix)"; \ - else \ - 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 QT3 installation. Please make sure that"; \ - echo "* the QT3 development package is correctly installed and"; \ - echo "* either install pkg-config or set the QTDIR environment"; \ - echo "* variable to the correct location."; \ - echo "*"; \ - false; \ - fi; \ - libpath=$$dir/lib; lib=qt; osdir=""; \ - $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ - osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ - test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ - test -f $$libpath/libqt-mt.so && lib=qt-mt; \ - cflags="-I$$dir/include"; \ - libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ - moc="$$dir/bin/moc"; \ - fi; \ - 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 "*"; \ - moc="/usr/bin/moc"; \ - fi; \ - echo "KC_QT_CFLAGS=$$cflags" > $@; \ - echo "KC_QT_LIBS=$$libs" >> $@; \ - echo "KC_QT_MOC=$$moc" >> $@ -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 --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ - if `pkg-config --atleast-version=2.0.0 gtk+-2.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)/zconf.hash.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 - $(KC_QT_MOC) -i $< -o $@ - -$(obj)/lkc_defs.h: $(src)/lkc_proto.h - sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' - -# Extract gconf menu items for I18N support -$(obj)/gconf.glade.h: $(obj)/gconf.glade - intltool-extract --type=gettext/glade $(obj)/gconf.glade - -### -# The following requires flex/bison/gperf -# 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: $(src)/zconf.y -$(obj)/lex.zconf.c: $(src)/zconf.l -$(obj)/zconf.hash.c: $(src)/zconf.gperf - -%.tab.c: %.y - bison -l -b $* -p $(notdir $*) $< - cp $@ $@_shipped - -lex.%.c: %.l - flex -L -P$(notdir $*) -o$@ $< - cp $@ $@_shipped - -%.hash.c: %.gperf - gperf < $< > $@ - cp $@ $@_shipped - -endif diff --git a/package/config/README.buildroot2 b/package/config/README.buildroot2 index bd4479060..8ff0d095b 100644 --- a/package/config/README.buildroot2 +++ b/package/config/README.buildroot2 @@ -1,16 +1,12 @@ -This is a copy of the kconfig code in the kernel (currently 2.6.24.4) tweaked +This is a copy of the kconfig code in the kernel (currently 2.6.36-rc1) tweaked to suit Buildroot. To update: cp -r /usr/src/linux/scripts/kconfig package/config.new cd package/config.new - cp /usr/src/linux/Documentation/kbuild/kconfig-language.txt . - patch -p1 < ../config/kconfig-to-buildroot2.patch - mv Makefile Makefile.kconfig - cp ../config/README.buildroot2 . - cp ../config/foo.h . - cp ../config/Makefile . - cp ../config/kconfig-to-buildroot2.patch . + cp -a ../config/patches ../config/README.buildroot2 . + quilt push -a + # Fix any conflict cd .. rm -rf config mv config.new config @@ -19,4 +15,6 @@ Then verify the toplevel targets work: config defconfig menuconfig + xconfig + gconfig oldconfig diff --git a/package/config/conf.c b/package/config/conf.c index 2485dcd5e..2062b57d4 100644 --- a/package/config/conf.c +++ b/package/config/conf.c @@ -10,6 +10,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <getopt.h> #include <sys/stat.h> #include <sys/time.h> @@ -19,16 +20,21 @@ 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; +enum input_mode { + oldaskconfig, + silentoldconfig, + oldconfig, + allnoconfig, + allyesconfig, + allmodconfig, + alldefconfig, + randconfig, + defconfig, + savedefconfig, + listnewconfig, + oldnoconfig, +} input_mode = oldaskconfig; + char *defconfig_file; static int indent = 1; @@ -38,14 +44,14 @@ static int conf_cnt; static char line[128]; static struct menu *rootEntry; -static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); - -static const char *get_help(struct menu *menu) +static void print_help(struct menu *menu) { - if (menu_has_help(menu)) - return _(menu_get_help(menu)); - else - return nohelp_text; + struct gstr help = str_new(); + + menu_get_ext_help(menu, &help); + + printf("\n%s\n", str_get(&help)); + str_free(&help); } static void strip(char *str) @@ -93,16 +99,16 @@ static int conf_askvalue(struct symbol *sym, const char *def) } switch (input_mode) { - case ask_new: - case ask_silent: + case oldconfig: + case silentoldconfig: if (sym_has_value(sym)) { printf("%s\n", def); return 0; } check_stdin(); - case ask_all: + case oldaskconfig: fflush(stdout); - fgets(line, 128, stdin); + xfgets(line, 128, stdin); return 1; default: break; @@ -121,7 +127,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) return 1; } -int conf_string(struct menu *menu) +static int conf_string(struct menu *menu) { struct symbol *sym = menu->sym; const char *def; @@ -140,7 +146,7 @@ int conf_string(struct menu *menu) case '?': /* print help */ if (line[1] == '\n') { - printf("\n%s\n", get_help(menu)); + print_help(menu); def = NULL; break; } @@ -156,14 +162,12 @@ int conf_string(struct menu *menu) static int conf_sym(struct menu *menu) { struct symbol *sym = menu->sym; - int type; tristate oldval, newval; 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) { @@ -220,7 +224,7 @@ static int conf_sym(struct menu *menu) if (sym_set_tristate_value(sym, newval)) return 0; help: - printf("\n%s\n", get_help(menu)); + print_help(menu); } } @@ -228,11 +232,9 @@ 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); @@ -294,20 +296,20 @@ static int conf_choice(struct menu *menu) printf("?"); printf("]: "); switch (input_mode) { - case ask_new: - case ask_silent: + case oldconfig: + case silentoldconfig: if (!is_new) { cnt = def; printf("%d\n", cnt); break; } check_stdin(); - case ask_all: + case oldaskconfig: fflush(stdout); - fgets(line, 128, stdin); + xfgets(line, 128, stdin); strip(line); if (line[0] == '?') { - printf("\n%s\n", get_help(menu)); + print_help(menu); continue; } if (!line[0]) @@ -331,7 +333,7 @@ static int conf_choice(struct menu *menu) if (!child) continue; if (line[strlen(line) - 1] == '?') { - printf("\n%s\n", get_help(child)); + print_help(child); continue; } sym_set_choice_value(sym, child->sym); @@ -360,7 +362,10 @@ static void conf(struct menu *menu) switch (prop->type) { case P_MENU: - if (input_mode == ask_silent && rootEntry != menu) { + if ((input_mode == silentoldconfig || + input_mode == listnewconfig || + input_mode == oldnoconfig) && + rootEntry != menu) { check_conf(menu); return; } @@ -418,10 +423,16 @@ static void check_conf(struct menu *menu) if (sym && !sym_has_value(sym)) { if (sym_is_changable(sym) || (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { - if (!conf_cnt++) - printf(_("*\n* Restart config...\n*\n")); - rootEntry = menu_get_parent_menu(menu); - conf(rootEntry); + if (input_mode == listnewconfig) { + if (sym->name && !sym_is_choice_value(sym)) { + printf("CONFIG_%s\n", sym->name); + } + } else { + if (!conf_cnt++) + printf(_("*\n* Restart config...\n*\n")); + rootEntry = menu_get_parent_menu(menu); + conf(rootEntry); + } } } @@ -429,6 +440,22 @@ static void check_conf(struct menu *menu) check_conf(child); } +static struct option long_opts[] = { + {"oldaskconfig", no_argument, NULL, oldaskconfig}, + {"oldconfig", no_argument, NULL, oldconfig}, + {"silentoldconfig", no_argument, NULL, silentoldconfig}, + {"defconfig", optional_argument, NULL, defconfig}, + {"savedefconfig", required_argument, NULL, savedefconfig}, + {"allnoconfig", no_argument, NULL, allnoconfig}, + {"allyesconfig", no_argument, NULL, allyesconfig}, + {"allmodconfig", no_argument, NULL, allmodconfig}, + {"alldefconfig", no_argument, NULL, alldefconfig}, + {"randconfig", no_argument, NULL, randconfig}, + {"listnewconfig", no_argument, NULL, listnewconfig}, + {"oldnoconfig", no_argument, NULL, oldnoconfig}, + {NULL, 0, NULL, 0} +}; + int main(int ac, char **av) { int opt; @@ -439,32 +466,17 @@ int main(int ac, char **av) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { + while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) { + input_mode = (enum input_mode)opt; switch (opt) { - case 'o': - input_mode = ask_silent; - break; - case 's': - input_mode = ask_silent; + case silentoldconfig: sync_kconfig = 1; break; - case 'd': - input_mode = set_default; - break; - case 'D': - input_mode = set_default; + case defconfig: + case savedefconfig: defconfig_file = optarg; break; - case 'n': - input_mode = set_no; - break; - case 'm': - input_mode = set_mod; - break; - case 'y': - input_mode = set_yes; - break; - case 'r': + case randconfig: { struct timeval now; unsigned int seed; @@ -477,17 +489,12 @@ int main(int ac, char **av) seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); srand(seed); - - input_mode = set_random; break; } - case 'h': - printf(_("See README for usage info\n")); - exit(0); - break; - default: + case '?': fprintf(stderr, _("See README for usage info\n")); exit(1); + break; } } if (ac == optind) { @@ -500,7 +507,7 @@ int main(int ac, char **av) name = conf_get_configname(); if (stat(name, &tmpstat)) { fprintf(stderr, _("***\n" - "*** You have not yet configured Buildroot!\n" + "*** You have not yet configured your Buildroot!\n" "*** (missing .config file \"%s\")\n" "***\n" "*** Please run some configurator (e.g. \"make oldconfig\" or\n" @@ -511,7 +518,7 @@ int main(int ac, char **av) } switch (input_mode) { - case set_default: + case defconfig: if (!defconfig_file) defconfig_file = conf_get_default_confname(); if (conf_read(defconfig_file)) { @@ -521,25 +528,32 @@ int main(int ac, char **av) exit(1); } break; - case ask_silent: - case ask_all: - case ask_new: + case savedefconfig: + conf_read(NULL); + break; + case silentoldconfig: + case oldaskconfig: + case oldconfig: + case listnewconfig: + case oldnoconfig: conf_read(NULL); break; - case set_no: - case set_mod: - case set_yes: - case set_random: + case allnoconfig: + case allyesconfig: + case allmodconfig: + case alldefconfig: + case randconfig: name = getenv("KCONFIG_ALLCONFIG"); if (name && !stat(name, &tmpstat)) { conf_read_simple(name, S_DEF_USER); break; } switch (input_mode) { - case set_no: name = "allno.config"; break; - case set_mod: name = "allmod.config"; break; - case set_yes: name = "allyes.config"; break; - case set_random: name = "allrandom.config"; break; + case allnoconfig: name = "allno.config"; break; + case allyesconfig: name = "allyes.config"; break; + case allmodconfig: name = "allmod.config"; break; + case alldefconfig: name = "alldef.config"; break; + case randconfig: name = "allrandom.config"; break; default: break; } if (!stat(name, &tmpstat)) @@ -564,33 +578,42 @@ int main(int ac, char **av) } switch (input_mode) { - case set_no: + case allnoconfig: conf_set_all_new_symbols(def_no); break; - case set_yes: + case allyesconfig: conf_set_all_new_symbols(def_yes); break; - case set_mod: + case allmodconfig: conf_set_all_new_symbols(def_mod); break; - case set_random: + case alldefconfig: + conf_set_all_new_symbols(def_default); + break; + case randconfig: conf_set_all_new_symbols(def_random); break; - case set_default: + case defconfig: conf_set_all_new_symbols(def_default); break; - case ask_new: - case ask_all: + case savedefconfig: + break; + case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); - input_mode = ask_silent; + input_mode = silentoldconfig; /* fall through */ - case ask_silent: + case oldconfig: + case listnewconfig: + case oldnoconfig: + case silentoldconfig: /* Update until a loop caused no more changes */ do { conf_cnt = 0; check_conf(&rootmenu); - } while (conf_cnt); + } while (conf_cnt && + (input_mode != listnewconfig && + input_mode != oldnoconfig)); break; } @@ -606,15 +629,28 @@ int main(int ac, char **av) fprintf(stderr, _("\n*** Error during update of the Buildroot configuration.\n\n")); return 1; } - } else { + } else if (input_mode == savedefconfig) { + if (conf_write_defconfig(defconfig_file)) { + fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), + defconfig_file); + return 1; + } + } else if (input_mode != listnewconfig) { if (conf_write(NULL)) { fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n")); exit(1); } - if (conf_write_autoconf()) { - fprintf(stderr, _("\n*** Error during update of the Buildroot configuration.\n\n")); - return 1; - } } return 0; } +/* + * Helper function to facilitate fgets() by Jean Sacren. + */ +void xfgets(str, size, in) + char *str; + int size; + FILE *in; +{ + if (fgets(str, size, in) == NULL) + fprintf(stderr, "\nError in reading or end of file.\n"); +} diff --git a/package/config/confdata.c b/package/config/confdata.c index 38424702a..ba1f8a7ed 100644 --- a/package/config/confdata.c +++ b/package/config/confdata.c @@ -169,8 +169,11 @@ int conf_read_simple(const char *name, int def) if (in) goto load; sym_add_change_count(1); - if (!sym_defconfig_list) + if (!sym_defconfig_list) { + if (modules_sym) + sym_calc_value(modules_sym); return 1; + } for_all_defaults(sym_defconfig_list, prop) { if (expr_calc_value(prop->visible.expr) == no || @@ -391,15 +394,148 @@ int conf_read(const char *name) return 0; } +/* Write a S_STRING */ +static void conf_write_string(bool headerfile, const char *name, + const char *str, FILE *out) +{ + int l; + if (headerfile) + fprintf(out, "#define %s \"", name); + else + fprintf(out, "%s=\"", name); + + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + xfwrite(str, l, 1, out); + str += l; + } + if (!*str) + break; + fprintf(out, "\\%c", *str++); + } + fputs("\"\n", out); +} + +static void conf_write_symbol(struct symbol *sym, enum symbol_type type, + FILE *out, bool write_no) +{ + const char *str; + + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + if (write_no) + fprintf(out, "# %s is not set\n", sym->name); + break; + case mod: + fprintf(out, "%s=m\n", sym->name); + break; + case yes: + fprintf(out, "%s=y\n", sym->name); + break; + } + break; + case S_STRING: + conf_write_string(false, sym->name, sym_get_string_value(sym), out); + break; + case S_HEX: + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "%s=%s\n", sym->name, str); + break; + case S_OTHER: + case S_UNKNOWN: + break; + } +} + +/* + * Write out a minimal config. + * All values that has default values are skipped as this is redundant. + */ +int conf_write_defconfig(const char *filename) +{ + struct symbol *sym; + struct menu *menu; + FILE *out; + + out = fopen(filename, "w"); + if (!out) + return 1; + + sym_clear_all_valid(); + + /* Traverse all menus to find all relevant symbols */ + menu = rootmenu.list; + + while (menu != NULL) + { + sym = menu->sym; + if (sym == NULL) { + if (!menu_is_visible(menu)) + goto next_menu; + } else if (!sym_is_choice(sym)) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE)) + goto next_menu; + sym->flags &= ~SYMBOL_WRITE; + /* If we cannot change the symbol - skip */ + if (!sym_is_changable(sym)) + goto next_menu; + /* If symbol equals to default value - skip */ + if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) + goto next_menu; + + /* + * If symbol is a choice value and equals to the + * default for a choice - skip. + * But only if value is bool and equal to "y" . + */ + if (sym_is_choice_value(sym)) { + struct symbol *cs; + struct symbol *ds; + + cs = prop_get_symbol(sym_get_choice_prop(sym)); + ds = sym_choice_default(cs); + if (sym == ds) { + if ((sym->type == S_BOOLEAN) && + sym_get_tristate_value(sym) == yes) + goto next_menu; + } + } + conf_write_symbol(sym, sym->type, out, true); + } +next_menu: + if (menu->list != NULL) { + menu = menu->list; + } + else if (menu->next != NULL) { + menu = menu->next; + } else { + while ((menu = menu->parent)) { + if (menu->next != NULL) { + menu = menu->next; + break; + } + } + } + } + fclose(out); + return 0; +} + int conf_write(const char *name) { FILE *out; struct symbol *sym; struct menu *menu; const char *basename; - char dirname[128], tmpname[128], newname[128]; - int type, l; const char *str; + char dirname[128], tmpname[128], newname[128]; + enum symbol_type type; time_t now; int use_timestamp = 1; char *env; @@ -480,50 +616,11 @@ int conf_write(const char *name) 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, "# %s is not set\n", sym->name); - break; - case mod: - fprintf(out, "%s=m\n", sym->name); - break; - case yes: - fprintf(out, "%s=y\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "%s=\"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str++); - } - fputs("\"\n", out); - break; - case S_HEX: - str = sym_get_string_value(sym); - if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "%s=%s\n", sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); - fprintf(out, "%s=%s\n", sym->name, str); - break; - } + /* Write config symbol to file */ + conf_write_symbol(sym, type, out, true); } - next: +next: if (menu->list) { menu = menu->list; continue; @@ -556,7 +653,7 @@ int conf_write(const char *name) return 0; } -int conf_split_config(void) +static int conf_split_config(void) { const char *name; char path[128]; @@ -572,7 +669,7 @@ int conf_split_config(void) opwd = malloc(256); _name = strdup(name); if (opwd == NULL || _name == NULL) - return 1; + return 1; opwd = getcwd(opwd, 256); dir = dirname(_name); if (dir == NULL) { @@ -688,9 +785,9 @@ int conf_write_autoconf(void) struct symbol *sym; const char *str; const char *name; - FILE *out, *out_h; + FILE *out, *tristate, *out_h; time_t now; - int i, l; + int i; char dir[PATH_MAX+1], buf[PATH_MAX+1]; char *s; @@ -714,10 +811,18 @@ int conf_write_autoconf(void) if (!out) return 1; + sprintf(buf, "%s.tmpconfig_tristate", dir); + tristate = fopen(buf, "w"); + if (!tristate) { + fclose(out); + return 1; + } + sprintf(buf, "%s.tmpconfig.h", dir); out_h = fopen(buf, "w"); if (!out_h) { fclose(out); + fclose(tristate); return 1; } @@ -729,6 +834,9 @@ int conf_write_autoconf(void) "# %s" "#\n", ctime(&now)); + fprintf(tristate, "#\n" + "# Automatically generated - do not edit\n" + "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" " * %s" @@ -739,6 +847,11 @@ int conf_write_autoconf(void) sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE) || !sym->name) continue; + + /* write symbol to config file */ + conf_write_symbol(sym, sym->type, out, false); + + /* update autoconf and tristate files */ switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: @@ -746,45 +859,28 @@ int conf_write_autoconf(void) case no: break; case mod: - fprintf(out, "%s=m\n", sym->name); + fprintf(tristate, "%s=M\n", sym->name); fprintf(out_h, "#define %s_MODULE 1\n", sym->name); break; case yes: - fprintf(out, "%s=y\n", sym->name); + if (sym->type == S_TRISTATE) + fprintf(tristate, "%s=Y\n", + sym->name); fprintf(out_h, "#define %s 1\n", sym->name); break; } break; case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "%s=\"", sym->name); - fprintf(out_h, "#define %s \"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - fwrite(str, l, 1, out_h); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str); - fprintf(out_h, "\\%c", *str); - str++; - } - fputs("\"\n", out); - fputs("\"\n", out_h); + conf_write_string(true, sym->name, sym_get_string_value(sym), out_h); break; case S_HEX: str = sym_get_string_value(sym); if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "%s=%s\n", sym->name, str); fprintf(out_h, "#define %s 0x%s\n", sym->name, str); break; } case S_INT: str = sym_get_string_value(sym); - fprintf(out, "%s=%s\n", sym->name, str); fprintf(out_h, "#define %s %s\n", sym->name, str); break; default: @@ -792,14 +888,21 @@ int conf_write_autoconf(void) } } fclose(out); + fclose(tristate); fclose(out_h); name = getenv("KCONFIG_AUTOHEADER"); if (!name) - name = "include/linux/autoconf.h"; + name = "include/generated/autoconf.h"; sprintf(buf, "%s.tmpconfig.h", dir); if (rename(buf, name)) return 1; + name = getenv("KCONFIG_TRISTATE"); + if (!name) + name = "include/config/tristate.conf"; + sprintf(buf, "%s.tmpconfig_tristate", dir); + if (rename(buf, name)) + return 1; name = conf_get_autoconfig_name(); /* * This must be the last step, kbuild has a dependency on auto.conf @@ -839,13 +942,73 @@ void conf_set_changed_callback(void (*fn)(void)) conf_changed_callback = fn; } +static void randomize_choice_values(struct symbol *csym) +{ + struct property *prop; + struct symbol *sym; + struct expr *e; + int cnt, def; -void conf_set_all_new_symbols(enum conf_def_mode mode) + /* + * If choice is mod then we may have more items slected + * and if no then no-one. + * In both cases stop. + */ + if (csym->curr.tri != yes) + return; + + prop = sym_get_choice_prop(csym); + + /* count entries in choice block */ + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) + cnt++; + + /* + * find a random value and set it to yes, + * set the rest to no so we have only one set + */ + def = (rand() % cnt); + + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) { + if (def == cnt++) { + sym->def[S_DEF_USER].tri = yes; + csym->def[S_DEF_USER].val = sym; + } + else { + sym->def[S_DEF_USER].tri = no; + } + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~(SYMBOL_VALID); +} + +static void set_all_choice_values(struct symbol *csym) { - struct symbol *sym, *csym; struct property *prop; + struct symbol *sym; struct expr *e; - int i, cnt, def, prob = 50; + + prop = sym_get_choice_prop(csym); + + /* + * Set all non-assinged choice values to no + */ + expr_list_for_each_sym(prop->expr, e, sym) { + if (!sym_has_value(sym)) + sym->def[S_DEF_USER].tri = no; + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~(SYMBOL_VALID); +} + +void conf_set_all_new_symbols(enum conf_def_mode mode) +{ + struct symbol *sym, *csym; + int i, cnt, prob = 50; if (mode == def_random) { char *endp, *env = getenv("KCONFIG_PROBABILITY"); @@ -897,8 +1060,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) sym_clear_all_valid(); - if (mode != def_random) - return; /* * We have different type of choice blocks. * If curr.tri equal to mod then we can select several @@ -913,35 +1074,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) continue; sym_calc_value(csym); - - if (csym->curr.tri != yes) - continue; - - prop = sym_get_choice_prop(csym); - - /* count entries in choice block */ - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) - cnt++; - - /* - * find a random value and set it to yes, - * set the rest to no so we have only one set - */ - def = (rand() % cnt); - - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (def == cnt++) { - sym->def[S_DEF_USER].tri = yes; - csym->def[S_DEF_USER].val = sym; - } - else { - sym->def[S_DEF_USER].tri = no; - } - } - csym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - csym->flags &= ~(SYMBOL_VALID); + if (mode == def_random) + randomize_choice_values(csym); + else + set_all_choice_values(csym); } } diff --git a/package/config/expr.c b/package/config/expr.c index 392c7e94f..88aace9c9 100644 --- a/package/config/expr.c +++ b/package/config/expr.c @@ -348,7 +348,7 @@ struct expr *expr_trans_bool(struct expr *e) /* * e1 || e2 -> ? */ -struct expr *expr_join_or(struct expr *e1, struct expr *e2) +static struct expr *expr_join_or(struct expr *e1, struct expr *e2) { struct expr *tmp; struct symbol *sym1, *sym2; @@ -412,7 +412,7 @@ struct expr *expr_join_or(struct expr *e1, struct expr *e2) return NULL; } -struct expr *expr_join_and(struct expr *e1, struct expr *e2) +static struct expr *expr_join_and(struct expr *e1, struct expr *e2) { struct expr *tmp; struct symbol *sym1, *sym2; @@ -1087,7 +1087,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) { - fwrite(str, strlen(str), 1, data); + xfwrite(str, strlen(str), 1, data); } void expr_fprint(struct expr *e, FILE *out) @@ -1097,7 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out) static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) { - str_append((struct gstr*)data, str); + struct gstr *gs = (struct gstr*)data; + const char *sym_str = NULL; + + if (sym) + sym_str = sym_get_string_value(sym); + + if (gs->max_width) { + unsigned extra_length = strlen(str); + const char *last_cr = strrchr(gs->s, '\n'); + unsigned last_line_length; + + if (sym_str) + extra_length += 4 + strlen(sym_str); + + if (!last_cr) + last_cr = gs->s; + + last_line_length = strlen(gs->s) - (last_cr - gs->s); + + if ((last_line_length + extra_length) > gs->max_width) + str_append(gs, "\\\n"); + } + + str_append(gs, str); + if (sym && sym->type != S_UNKNOWN) + str_printf(gs, " [=%s]", sym_str); } void expr_gstr_print(struct expr *e, struct gstr *gs) diff --git a/package/config/expr.h b/package/config/expr.h index 6408fefae..6ee2e4fb1 100644 --- a/package/config/expr.h +++ b/package/config/expr.h @@ -83,10 +83,11 @@ struct symbol { tristate visible; int flags; struct property *prop; + struct expr_value dir_dep; 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 for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) #define SYMBOL_CONST 0x0001 /* symbol is const */ #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ @@ -108,8 +109,7 @@ struct symbol { #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ #define SYMBOL_MAXLENGTH 256 -#define SYMBOL_HASHSIZE 257 -#define SYMBOL_HASHMASK 0xff +#define SYMBOL_HASHSIZE 9973 /* A property represent the config options that can be associated * with a config "symbol". @@ -132,6 +132,7 @@ enum prop_type { P_SELECT, /* select BAR */ P_RANGE, /* range 7..100 (for a symbol) */ P_ENV, /* value from environment variable */ + P_SYMBOL, /* where a symbol is defined */ }; struct property { @@ -164,6 +165,7 @@ struct menu { struct symbol *sym; struct property *prompt; struct expr *dep; + struct expr *dir_dep; unsigned int flags; char *help; struct file *file; diff --git a/package/config/gconf.c b/package/config/gconf.c index 7c4c76cf6..f626061de 100644 --- a/package/config/gconf.c +++ b/package/config/gconf.c @@ -30,13 +30,16 @@ enum { SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW }; +enum { + OPT_NORMAL, OPT_ALL, OPT_PROMPT +}; + static gint view_mode = FULL_VIEW; static gboolean show_name = TRUE; static gboolean show_range = TRUE; static gboolean show_value = TRUE; -static gboolean show_all = FALSE; -static gboolean show_debug = FALSE; static gboolean resizeable = FALSE; +static int opt_mode = OPT_NORMAL; GtkWidget *main_wnd = NULL; GtkWidget *tree1_w = NULL; // left frame @@ -76,36 +79,7 @@ static void conf_changed(void); /* Helping/Debugging Functions */ - -const char *dbg_print_stype(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val == S_UNKNOWN) - strcpy(buf, "unknown"); - if (val == S_BOOLEAN) - strcpy(buf, "boolean"); - if (val == S_TRISTATE) - strcpy(buf, "tristate"); - if (val == S_INT) - strcpy(buf, "int"); - if (val == S_HEX) - strcpy(buf, "hex"); - if (val == S_STRING) - strcpy(buf, "string"); - if (val == S_OTHER) - strcpy(buf, "other"); - -#ifdef DEBUG - printf("%s", buf); -#endif - - return buf; -} - -const char *dbg_print_flags(int val) +const char *dbg_sym_flags(int val) { static char buf[256]; @@ -131,40 +105,10 @@ const char *dbg_print_flags(int val) strcat(buf, "auto/"); buf[strlen(buf) - 1] = '\0'; -#ifdef DEBUG - printf("%s", buf); -#endif return buf; } -const char *dbg_print_ptype(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val == P_UNKNOWN) - strcpy(buf, "unknown"); - if (val == P_PROMPT) - strcpy(buf, "prompt"); - if (val == P_COMMENT) - strcpy(buf, "comment"); - if (val == P_MENU) - strcpy(buf, "menu"); - if (val == P_DEFAULT) - strcpy(buf, "default"); - if (val == P_CHOICE) - strcpy(buf, "choice"); - -#ifdef DEBUG - printf("%s", buf); -#endif - - return buf; -} - - void replace_button_icon(GladeXML * xml, GdkDrawable * window, GtkStyle * style, gchar * btn_name, gchar ** xpm) { @@ -456,19 +400,9 @@ static void text_insert_help(struct menu *menu) GtkTextBuffer *buffer; GtkTextIter start, end; const char *prompt = _(menu_get_prompt(menu)); - gchar *name; - const char *help; - - help = menu_get_help(menu); - - /* Gettextize if the help text not empty */ - if ((help != 0) && (help[0] != 0)) - help = _(help); + struct gstr help = str_new(); - if (menu->sym && menu->sym->name) - name = g_strdup_printf(menu->sym->name); - else - name = g_strdup(""); + menu_get_ext_help(menu, &help); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); gtk_text_buffer_get_bounds(buffer, &start, &end); @@ -478,14 +412,11 @@ static void text_insert_help(struct menu *menu) gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, NULL); - gtk_text_buffer_insert_at_cursor(buffer, " ", 1); - gtk_text_buffer_get_end_iter(buffer, &end); - gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1, - NULL); gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); gtk_text_buffer_get_end_iter(buffer, &end); - gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2, + gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2, NULL); + str_free(&help); } @@ -710,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) void -on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) +on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data) { - show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; + opt_mode = OPT_NORMAL; + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); /* instead of update_tree to speed-up */ +} + +void +on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data) +{ + opt_mode = OPT_ALL; gtk_tree_store_clear(tree2); - display_tree(&rootmenu); // instead of update_tree to speed-up + display_tree(&rootmenu); /* instead of update_tree to speed-up */ } void -on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) +on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) { - show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; - update_tree(&rootmenu, NULL); + opt_mode = OPT_PROMPT; + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); /* instead of update_tree to speed-up */ } @@ -1174,9 +1114,12 @@ static gchar **fill_row(struct menu *menu) row[COL_OPTION] = g_strdup_printf("%s %s", _(menu_get_prompt(menu)), - sym && sym_has_value(sym) ? "(NEW)" : ""); + sym && !sym_has_value(sym) ? "(NEW)" : ""); - if (show_all && !menu_is_visible(menu)) + if (opt_mode == OPT_ALL && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else if (opt_mode == OPT_PROMPT && + menu_has_prompt(menu) && !menu_is_visible(menu)) row[COL_COLOR] = g_strdup("DarkGray"); else row[COL_COLOR] = g_strdup("Black"); @@ -1399,16 +1342,20 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) menu2 ? menu_get_prompt(menu2) : "nil"); #endif - if (!menu_is_visible(child1) && !show_all) { // remove node + if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || + (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || + (opt_mode == OPT_ALL && !menu_get_prompt(child1))) { + + /* remove node */ if (gtktree_iter_find_node(dst, menu1) != NULL) { memcpy(&tmp, child2, sizeof(GtkTreeIter)); valid = gtk_tree_model_iter_next(model2, child2); gtk_tree_store_remove(tree2, &tmp); if (!valid) - return; // next parent + return; /* next parent */ else - goto reparse; // next child + goto reparse; /* next child */ } else continue; } @@ -1477,17 +1424,19 @@ static void display_tree(struct menu *menu) && (tree == tree2)) continue; - if (menu_is_visible(child) || show_all) + if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || + (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || + (opt_mode == OPT_ALL && menu_get_prompt(child))) place_node(child, fill_row(child)); #ifdef DEBUG printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); - dbg_print_ptype(ptype); + printf("%s", prop_get_type_name(ptype)); printf(" | "); if (sym) { - dbg_print_stype(sym->type); + printf("%s", sym_type_name(sym->type)); printf(" | "); - dbg_print_flags(sym->flags); + printf("%s", dbg_sym_flags(sym->flags)); printf("\n"); } else printf("\n"); diff --git a/package/config/gconf.glade b/package/config/gconf.glade index 5656bf7a3..8e7d99e37 100644 --- a/package/config/gconf.glade +++ b/package/config/gconf.glade @@ -190,26 +190,40 @@ </child> <child> - <widget class="GtkCheckMenuItem" id="show_all_options1"> + <widget class="GtkRadioMenuItem" id="set_option_mode1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Show normal options</property> + <property name="label" translatable="yes">Show normal options</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <signal name="activate" handler="on_set_option_mode1_activate"/> + </widget> + </child> + + <child> + <widget class="GtkRadioMenuItem" id="set_option_mode2"> <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"/> + <property name="group">set_option_mode1</property> + <signal name="activate" handler="on_set_option_mode2_activate"/> </widget> </child> <child> - <widget class="GtkCheckMenuItem" id="show_debug_info1"> + <widget class="GtkRadioMenuItem" id="set_option_mode3"> <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="tooltip" translatable="yes">Show all options with prompts</property> + <property name="label" translatable="yes">Show all prompt options</property> <property name="use_underline">True</property> <property name="active">False</property> - <signal name="activate" handler="on_show_debug_info1_activate"/> + <property name="group">set_option_mode1</property> + <signal name="activate" handler="on_set_option_mode3_activate"/> </widget> </child> + </widget> </child> </widget> @@ -547,7 +561,7 @@ <property name="headers_visible">True</property> <property name="rules_hint">False</property> <property name="reorderable">False</property> - <property name="enable_search">True</property> + <property name="enable_search">False</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"/> @@ -582,7 +596,7 @@ <property name="headers_visible">True</property> <property name="rules_hint">False</property> <property name="reorderable">False</property> - <property name="enable_search">True</property> + <property name="enable_search">False</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"/> diff --git a/package/config/kconfig-language.txt b/package/config/kconfig-language.txt deleted file mode 100644 index c412c2458..000000000 --- a/package/config/kconfig-language.txt +++ /dev/null @@ -1,379 +0,0 @@ -Introduction ------------- - -The configuration database is a collection of configuration options -organized in a tree structure: - - +- Code maturity level options - | +- Prompt for development and/or incomplete code/drivers - +- General setup - | +- Networking support - | +- System V IPC - | +- BSD Process Accounting - | +- Sysctl support - +- Loadable module support - | +- Enable loadable module support - | +- Set version information on all module symbols - | +- Kernel module loader - +- ... - -Every entry has its own dependencies. These dependencies are used -to determine the visibility of an entry. Any child entry is only -visible if its parent entry is also visible. - -Menu entries ------------- - -Most entries define a config option; all other entries help to organize -them. A single configuration option is defined like this: - -config MODVERSIONS - bool "Set version information on all module symbols" - depends on MODULES - help - Usually, modules have to be recompiled whenever you switch to a new - kernel. ... - -Every line starts with a key word and can be followed by multiple -arguments. "config" starts a new config entry. The following lines -define attributes for this config option. Attributes can be the type of -the config option, input prompt, dependencies, help text and default -values. A config option can be defined multiple times with the same -name, but every definition can have only a single input prompt and the -type must not conflict. - -Menu attributes ---------------- - -A menu entry can have a number of attributes. Not all of them are -applicable everywhere (see syntax). - -- type definition: "bool"/"tristate"/"string"/"hex"/"int" - Every config option must have a type. There are only two basic types: - tristate and string; the other types are based on these two. The type - definition optionally accepts an input prompt, so these two examples - are equivalent: - - bool "Networking support" - and - bool - prompt "Networking support" - -- input prompt: "prompt" <prompt> ["if" <expr>] - Every menu entry can have at most one prompt, which is used to display - to the user. Optionally dependencies only for this prompt can be added - with "if". - -- default value: "default" <expr> ["if" <expr>] - A config option can have any number of default values. If multiple - default values are visible, only the first defined one is active. - Default values are not limited to the menu entry where they are - defined. This means the default can be defined somewhere else or be - overridden by an earlier definition. - The default value is only assigned to the config symbol if no other - value was set by the user (via the input prompt above). If an input - prompt is visible the default value is presented to the user and can - be overridden by him. - Optionally, dependencies only for this default value can be added with - "if". - -- type definition + default value: - "def_bool"/"def_tristate" <expr> ["if" <expr>] - This is a shorthand notation for a type definition plus a value. - Optionally dependencies for this default value can be added with "if". - -- dependencies: "depends on" <expr> - This defines a dependency for this menu entry. If multiple - dependencies are defined, they are connected with '&&'. Dependencies - are applied to all other options within this menu entry (which also - accept an "if" expression), so these two examples are equivalent: - - bool "foo" if BAR - default y if BAR - and - depends on BAR - bool "foo" - default y - -- reverse dependencies: "select" <symbol> ["if" <expr>] - While normal dependencies reduce the upper limit of a symbol (see - below), reverse dependencies can be used to force a lower limit of - another symbol. The value of the current menu symbol is used as the - minimal value <symbol> can be set to. If <symbol> is selected multiple - times, the limit is set to the largest selection. - Reverse dependencies can only be used with boolean or tristate - symbols. - Note: - select should be used with care. select will force - a symbol to a value without visiting the dependencies. - By abusing select you are able to select a symbol FOO even - if FOO depends on BAR that is not set. - In general use select only for non-visible symbols - (no prompts anywhere) and for symbols with no dependencies. - That will limit the usefulness but on the other hand avoid - the illegal configurations all over. - kconfig should one day warn about such things. - -- numerical ranges: "range" <symbol> <symbol> ["if" <expr>] - This allows to limit the range of possible input values for int - and hex symbols. The user can only input a value which is larger than - or equal to the first symbol and smaller than or equal to the second - symbol. - -- help text: "help" or "---help---" - This defines a help text. The end of the help text is determined by - the indentation level, this means it ends at the first line which has - a smaller indentation than the first line of the help text. - "---help---" and "help" do not differ in behaviour, "---help---" is - used to help visually separate configuration logic from help within - the file as an aid to developers. - -- misc options: "option" <symbol>[=<value>] - Various less common options can be defined via this option syntax, - which can modify the behaviour of the menu entry and its config - symbol. These options are currently possible: - - - "defconfig_list" - This declares a list of default entries which can be used when - looking for the default configuration (which is used when the main - .config doesn't exists yet.) - - - "modules" - This declares the symbol to be used as the MODULES symbol, which - enables the third modular state for all config symbols. - - - "env"=<value> - This imports the environment variable into Kconfig. It behaves like - a default, except that the value comes from the environment, this - also means that the behaviour when mixing it with normal defaults is - undefined at this point. The symbol is currently not exported back - to the build environment (if this is desired, it can be done via - another symbol). - -Menu dependencies ------------------ - -Dependencies define the visibility of a menu entry and can also reduce -the input range of tristate symbols. The tristate logic used in the -expressions uses one more state than normal boolean logic to express the -module state. Dependency expressions have the following syntax: - -<expr> ::= <symbol> (1) - <symbol> '=' <symbol> (2) - <symbol> '!=' <symbol> (3) - '(' <expr> ')' (4) - '!' <expr> (5) - <expr> '&&' <expr> (6) - <expr> '||' <expr> (7) - -Expressions are listed in decreasing order of precedence. - -(1) Convert the symbol into an expression. Boolean and tristate symbols - are simply converted into the respective expression values. All - other symbol types result in 'n'. -(2) If the values of both symbols are equal, it returns 'y', - otherwise 'n'. -(3) If the values of both symbols are equal, it returns 'n', - otherwise 'y'. -(4) Returns the value of the expression. Used to override precedence. -(5) Returns the result of (2-/expr/). -(6) Returns the result of min(/expr/, /expr/). -(7) Returns the result of max(/expr/, /expr/). - -An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 -respectively for calculations). A menu entry becomes visible when it's -expression evaluates to 'm' or 'y'. - -There are two types of symbols: constant and non-constant symbols. -Non-constant symbols are the most common ones and are defined with the -'config' statement. Non-constant symbols consist entirely of alphanumeric -characters or underscores. -Constant symbols are only part of expressions. Constant symbols are -always surrounded by single or double quotes. Within the quote, any -other character is allowed and the quotes can be escaped using '\'. - -Menu structure --------------- - -The position of a menu entry in the tree is determined in two ways. First -it can be specified explicitly: - -menu "Network device support" - depends on NET - -config NETDEVICES - ... - -endmenu - -All entries within the "menu" ... "endmenu" block become a submenu of -"Network device support". All subentries inherit the dependencies from -the menu entry, e.g. this means the dependency "NET" is added to the -dependency list of the config option NETDEVICES. - -The other way to generate the menu structure is done by analyzing the -dependencies. If a menu entry somehow depends on the previous entry, it -can be made a submenu of it. First, the previous (parent) symbol must -be part of the dependency list and then one of these two conditions -must be true: -- the child entry must become invisible, if the parent is set to 'n' -- the child entry must only be visible, if the parent is visible - -config MODULES - bool "Enable loadable module support" - -config MODVERSIONS - bool "Set version information on all module symbols" - depends on MODULES - -comment "module support disabled" - depends on !MODULES - -MODVERSIONS directly depends on MODULES, this means it's only visible if -MODULES is different from 'n'. The comment on the other hand is always -visible when MODULES is visible (the (empty) dependency of MODULES is -also part of the comment dependencies). - - -Kconfig syntax --------------- - -The configuration file describes a series of menu entries, where every -line starts with a keyword (except help texts). The following keywords -end a menu entry: -- config -- menuconfig -- choice/endchoice -- comment -- menu/endmenu -- if/endif -- source -The first five also start the definition of a menu entry. - -config: - - "config" <symbol> - <config options> - -This defines a config symbol <symbol> and accepts any of above -attributes as options. - -menuconfig: - "menuconfig" <symbol> - <config options> - -This is similar to the simple config entry above, but it also gives a -hint to front ends, that all suboptions should be displayed as a -separate list of options. - -choices: - - "choice" - <choice options> - <choice block> - "endchoice" - -This defines a choice group and accepts any of the above attributes as -options. A choice can only be of type bool or tristate, while a boolean -choice only allows a single config entry to be selected, a tristate -choice also allows any number of config entries to be set to 'm'. This -can be used if multiple drivers for a single hardware exists and only a -single driver can be compiled/loaded into the kernel, but all drivers -can be compiled as modules. -A choice accepts another option "optional", which allows to set the -choice to 'n' and no entry needs to be selected. - -comment: - - "comment" <prompt> - <comment options> - -This defines a comment which is displayed to the user during the -configuration process and is also echoed to the output files. The only -possible options are dependencies. - -menu: - - "menu" <prompt> - <menu options> - <menu block> - "endmenu" - -This defines a menu block, see "Menu structure" above for more -information. The only possible options are dependencies. - -if: - - "if" <expr> - <if block> - "endif" - -This defines an if block. The dependency expression <expr> is appended -to all enclosed menu entries. - -source: - - "source" <prompt> - -This reads the specified configuration file. This file is always parsed. - -mainmenu: - - "mainmenu" <prompt> - -This sets the config program's title bar if the config program chooses -to use it. - - -Kconfig hints -------------- -This is a collection of Kconfig tips, most of which aren't obvious at -first glance and most of which have become idioms in several Kconfig -files. - -Adding common features and make the usage configurable -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is a common idiom to implement a feature/functionality that are -relevant for some architectures but not all. -The recommended way to do so is to use a config variable named HAVE_* -that is defined in a common Kconfig file and selected by the relevant -architectures. -An example is the generic IOMAP functionality. - -We would in lib/Kconfig see: - -# Generic IOMAP is used to ... -config HAVE_GENERIC_IOMAP - -config GENERIC_IOMAP - depends on HAVE_GENERIC_IOMAP && FOO - -And in lib/Makefile we would see: -obj-$(CONFIG_GENERIC_IOMAP) += iomap.o - -For each architecture using the generic IOMAP functionality we would see: - -config X86 - select ... - select HAVE_GENERIC_IOMAP - select ... - -Note: we use the existing config option and avoid creating a new -config variable to select HAVE_GENERIC_IOMAP. - -Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is -introduced to overcome the limitation of select which will force a -config option to 'y' no matter the dependencies. -The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the -situation where select forces a symbol equals to 'y'. - -Build as module only -~~~~~~~~~~~~~~~~~~~~ -To restrict a component build to module-only, qualify its config symbol -with "depends on m". E.g.: - -config FOO - depends on BAR && m - -limits FOO to module (=m) or disabled (=n). - diff --git a/package/config/kconfig-to-buildroot2.patch b/package/config/kconfig-to-buildroot2.patch deleted file mode 100644 index db72ea8dd..000000000 --- a/package/config/kconfig-to-buildroot2.patch +++ /dev/null @@ -1,917 +0,0 @@ ---- - Makefile | 7 +++ - README.buildroot2 | 22 ++++++++++ - conf.c | 17 ++++---- - confdata.c | 101 ++++++++++++++++++++++++++------------------------ - expr.c | 42 ++++++++++---------- - gconf.c | 4 - - gconf.glade | 2 - mconf.c | 39 +++++++++---------- - qconf.cc | 5 +- - util.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++- - zconf.tab.c_shipped | 2 - zconf.y | 2 - 12 files changed, 244 insertions(+), 104 deletions(-) - -Index: config/Makefile -=================================================================== ---- config.orig/Makefile -+++ config/Makefile -@@ -124,10 +124,21 @@ - ifeq ($(MAKECMDGOALS),menuconfig) - hostprogs-y += mconf - endif -+ifeq ($(findstring mconf,$(MAKECMDGOALS)),mconf) -+ hostprogs-y += mconf -+endif - - ifeq ($(MAKECMDGOALS),xconfig) - qconf-target := 1 - endif -+ifeq ($(findstring qconf,$(MAKECMDGOALS)),qconf) -+ qconf-target := 1 -+endif -+ - ifeq ($(MAKECMDGOALS),gconfig) - gconf-target := 1 - endif -+ifeq ($(findstring gconf,$(MAKECMDGOALS)),gconf) -+ gconf-target := 1 -+endif -+ -Index: config/README.buildroot2 -=================================================================== ---- /dev/null -+++ config/README.buildroot2 -@@ -0,0 +1,22 @@ -+This is a copy of the kconfig code in the kernel (currently 2.6.24.4) tweaked -+to suit Buildroot. -+ -+To update: -+ cp -r /usr/src/linux/scripts/kconfig package/config.new -+ cd package/config.new -+ cp /usr/src/linux/Documentation/kbuild/kconfig-language.txt . -+ patch -p1 < ../config/kconfig-to-buildroot2.patch -+ mv Makefile Makefile.kconfig -+ cp ../config/README.buildroot2 . -+ cp ../config/foo.h . -+ cp ../config/Makefile . -+ cp ../config/kconfig-to-buildroot2.patch . -+ cd .. -+ rm -rf config -+ mv config.new config -+ -+Then verify the toplevel targets work: -+ config -+ defconfig -+ menuconfig -+ oldconfig -Index: config/conf.c -=================================================================== ---- config.orig/conf.c -+++ config/conf.c -@@ -496,13 +496,12 @@ - } - name = av[optind]; - conf_parse(name); -- //zconfdump(stdout); - if (sync_kconfig) { - name = conf_get_configname(); - if (stat(name, &tmpstat)) { - fprintf(stderr, _("***\n" -- "*** You have not yet configured your kernel!\n" -- "*** (missing kernel config file \"%s\")\n" -+ "*** You have not yet configured Buildroot!\n" -+ "*** (missing .config file \"%s\")\n" - "***\n" - "*** Please run some configurator (e.g. \"make oldconfig\" or\n" - "*** \"make menuconfig\" or \"make xconfig\").\n" -@@ -557,7 +556,7 @@ - name = getenv("KCONFIG_NOSILENTUPDATE"); - if (name && *name) { - fprintf(stderr, -- _("\n*** Kernel configuration requires explicit update.\n\n")); -+ _("\n*** Buildroot configuration requires explicit update.\n\n")); - return 1; - } - } -@@ -600,18 +599,22 @@ - * All other commands are only used to generate a config. - */ - if (conf_get_changed() && conf_write(NULL)) { -- fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); -+ fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n")); - exit(1); - } - if (conf_write_autoconf()) { -- fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); -+ fprintf(stderr, _("\n*** Error during update of the Buildroot configuration.\n\n")); - return 1; - } - } else { - if (conf_write(NULL)) { -- fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); -+ fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n")); - exit(1); - } -+ if (conf_write_autoconf()) { -+ fprintf(stderr, _("\n*** Error during update of the Buildroot configuration.\n\n")); -+ return 1; -+ } - } - return 0; - } -Index: config/confdata.c -=================================================================== ---- config.orig/confdata.c -+++ config/confdata.c -@@ -11,6 +11,7 @@ - #include <string.h> - #include <time.h> - #include <unistd.h> -+#include <libgen.h> - - #define LKC_DIRECT_LINK - #include "lkc.h" -@@ -21,7 +22,7 @@ - static const char *conf_filename; - static int conf_lineno, conf_warnings, conf_unsaved; - --const char conf_defname[] = "arch/$ARCH/defconfig"; -+const char conf_defname[] = ".defconfig"; - - static void conf_warning(const char *fmt, ...) - { -@@ -36,16 +37,14 @@ - - const char *conf_get_configname(void) - { -- char *name = getenv("KCONFIG_CONFIG"); -+ char *name = getenv("BUILDROOT_CONFIG"); - - return name ? name : ".config"; - } - - const char *conf_get_autoconfig_name(void) - { -- char *name = getenv("KCONFIG_AUTOCONFIG"); -- -- return name ? name : "include/config/auto.conf"; -+ return getenv("KCONFIG_AUTOCONFIG"); - } - - static char *conf_expand_value(const char *in) -@@ -219,22 +218,22 @@ - sym = NULL; - switch (line[0]) { - case '#': -- if (memcmp(line + 2, "CONFIG_", 7)) -+ if (line[1]!=' ') - continue; -- p = strchr(line + 9, ' '); -+ p = strchr(line + 2, ' '); - if (!p) - continue; - *p++ = 0; - if (strncmp(p, "is not set", 10)) - continue; - if (def == S_DEF_USER) { -- sym = sym_find(line + 9); -+ sym = sym_find(line + 2); - if (!sym) { - sym_add_change_count(1); - break; - } - } else { -- sym = sym_lookup(line + 9, 0); -+ sym = sym_lookup(line + 2, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_BOOLEAN; - } -@@ -251,12 +250,8 @@ - ; - } - break; -- case 'C': -- if (memcmp(line, "CONFIG_", 7)) { -- conf_warning("unexpected data"); -- continue; -- } -- p = strchr(line + 7, '='); -+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': -+ p = strchr(line, '='); - if (!p) - continue; - *p++ = 0; -@@ -267,13 +262,13 @@ - *p2 = 0; - } - if (def == S_DEF_USER) { -- sym = sym_find(line + 7); -+ sym = sym_find(line); - if (!sym) { - sym_add_change_count(1); - break; - } - } else { -- sym = sym_lookup(line + 7, 0); -+ sym = sym_lookup(line, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_OTHER; - } -@@ -443,7 +438,7 @@ - if (!out) - return 1; - -- sym = sym_lookup("KERNELVERSION", 0); -+ sym = sym_lookup("BR2_VERSION", 0); - sym_calc_value(sym); - time(&now); - env = getenv("KCONFIG_NOTIMESTAMP"); -@@ -452,10 +447,8 @@ - - 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) : ""); - -@@ -489,19 +482,19 @@ - case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: -- fprintf(out, "# CONFIG_%s is not set\n", sym->name); -+ fprintf(out, "# %s is not set\n", sym->name); - break; - case mod: -- fprintf(out, "CONFIG_%s=m\n", sym->name); -+ fprintf(out, "%s=m\n", sym->name); - break; - case yes: -- fprintf(out, "CONFIG_%s=y\n", sym->name); -+ fprintf(out, "%s=y\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); -- fprintf(out, "CONFIG_%s=\"", sym->name); -+ fprintf(out, "%s=\"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { -@@ -517,12 +510,12 @@ - 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); -+ fprintf(out, "%s=%s\n", sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); -- fprintf(out, "CONFIG_%s=%s\n", sym->name, str); -+ fprintf(out, "%s=%s\n", sym->name, str); - break; - } - } -@@ -564,6 +557,7 @@ - { - const char *name; - char path[128]; -+ char *opwd, *dir, *_name; - char *s, *d, c; - struct symbol *sym; - struct stat sb; -@@ -572,8 +566,20 @@ - name = conf_get_autoconfig_name(); - conf_read_simple(name, S_DEF_AUTO); - -- if (chdir("include/config")) -+ opwd = malloc(256); -+ _name = strdup(name); -+ if (opwd == NULL || _name == NULL) - return 1; -+ opwd = getcwd(opwd, 256); -+ dir = dirname(_name); -+ if (dir == NULL) { -+ res = 1; -+ goto err; -+ } -+ if (chdir(dir)) { -+ res = 1; -+ goto err; -+ } - - res = 0; - for_all_symbols(i, sym) { -@@ -666,9 +672,11 @@ - close(fd); - } - out: -- if (chdir("../..")) -- return 1; -- -+ if (chdir(opwd)) -+ res = 1; -+err: -+ free(opwd); -+ free(_name); - return res; - } - -@@ -683,7 +691,7 @@ - - sym_clear_all_valid(); - -- file_write_dep("include/config/auto.conf.cmd"); -+ file_write_dep(".config.cmd"); - - if (conf_split_config()) - return 1; -@@ -698,22 +706,19 @@ - return 1; - } - -- sym = sym_lookup("KERNELVERSION", 0); -+ sym = sym_lookup("BR2_VERSION", 0); - sym_calc_value(sym); - time(&now); - fprintf(out, "#\n" - "# Automatically generated make config: don't edit\n" -- "# Linux kernel version: %s\n" - "# %s" - "#\n", -- sym_get_string_value(sym), ctime(&now)); -+ ctime(&now)); - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" -- " * Linux kernel version: %s\n" - " * %s" -- " */\n" -- "#define AUTOCONF_INCLUDED\n", -- sym_get_string_value(sym), ctime(&now)); -+ " */\n", -+ ctime(&now)); - - for_all_symbols(i, sym) { - sym_calc_value(sym); -@@ -726,19 +731,19 @@ - case no: - break; - case mod: -- fprintf(out, "CONFIG_%s=m\n", sym->name); -- fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); -+ fprintf(out, "%s=m\n", sym->name); -+ fprintf(out_h, "#define %s_MODULE 1\n", sym->name); - break; - case yes: -- fprintf(out, "CONFIG_%s=y\n", sym->name); -- fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); -+ fprintf(out, "%s=y\n", sym->name); -+ fprintf(out_h, "#define %s 1\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); -- fprintf(out, "CONFIG_%s=\"", sym->name); -- fprintf(out_h, "#define CONFIG_%s \"", sym->name); -+ fprintf(out, "%s=\"", sym->name); -+ fprintf(out_h, "#define %s \"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { -@@ -758,14 +763,14 @@ - 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); -- fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); -+ fprintf(out, "%s=%s\n", sym->name, str); -+ fprintf(out_h, "#define %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); -- fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); -+ fprintf(out, "%s=%s\n", sym->name, str); -+ fprintf(out_h, "#define %s %s\n", sym->name, str); - break; - default: - break; -Index: config/expr.c -=================================================================== ---- config.orig/expr.c -+++ config/expr.c -@@ -331,7 +331,7 @@ - e->right.expr = expr_trans_bool(e->right.expr); - break; - case E_UNEQUAL: -- // FOO!=n -> FOO -+ /* FOO!=n -> FOO */ - if (e->left.sym->type == S_TRISTATE) { - if (e->right.sym == &symbol_no) { - e->type = E_SYMBOL; -@@ -380,19 +380,19 @@ - if (e1->type == E_EQUAL && e2->type == E_EQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || - (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { -- // (a='y') || (a='m') -> (a!='n') -+ /* (a='y') || (a='m') -> (a!='n') */ - return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); - } - if (e1->type == E_EQUAL && e2->type == E_EQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { -- // (a='y') || (a='n') -> (a!='m') -+ /* (a='y') || (a='n') -> (a!='m') */ - return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); - } - if (e1->type == E_EQUAL && e2->type == E_EQUAL && - ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { -- // (a='m') || (a='n') -> (a!='y') -+ /* (a='m') || (a='n') -> (a!='y') */ - return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); - } - } -@@ -443,29 +443,29 @@ - - if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || - (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) -- // (a) && (a='y') -> (a='y') -+ /* (a) && (a='y') -> (a='y') */ - return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); - - if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || - (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) -- // (a) && (a!='n') -> (a) -+ /* (a) && (a!='n') -> (a) */ - return expr_alloc_symbol(sym1); - - if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || - (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) -- // (a) && (a!='m') -> (a='y') -+ /* (a) && (a!='m') -> (a='y') */ - return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); - - if (sym1->type == S_TRISTATE) { - if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { -- // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' -+ /* (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' */ - sym2 = e1->right.sym; - if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) - return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) - : expr_alloc_symbol(&symbol_no); - } - if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { -- // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' -+ /* (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' */ - sym2 = e2->right.sym; - if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) - return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) -@@ -474,19 +474,19 @@ - if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) -- // (a!='y') && (a!='n') -> (a='m') -+ /* (a!='y') && (a!='n') -> (a='m') */ - return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); - - if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && - ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || - (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) -- // (a!='y') && (a!='m') -> (a='n') -+ /* (a!='y') && (a!='m') -> (a='n') */ - return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); - - if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && - ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || - (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) -- // (a!='m') && (a!='n') -> (a='m') -+ /* (a!='m') && (a!='n') -> (a='m') */ - return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); - - if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || -@@ -579,7 +579,7 @@ - switch (e1->type) { - case E_OR: - expr_eliminate_dups2(e1->type, &e1, &e1); -- // (FOO || BAR) && (!FOO && !BAR) -> n -+ /* (FOO || BAR) && (!FOO && !BAR) -> n */ - tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); - tmp2 = expr_copy(e2); - tmp = expr_extract_eq_and(&tmp1, &tmp2); -@@ -594,7 +594,7 @@ - break; - case E_AND: - expr_eliminate_dups2(e1->type, &e1, &e1); -- // (FOO && BAR) || (!FOO || !BAR) -> y -+ /* (FOO && BAR) || (!FOO || !BAR) -> y */ - tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); - tmp2 = expr_copy(e2); - tmp = expr_extract_eq_or(&tmp1, &tmp2); -@@ -703,7 +703,7 @@ - case E_NOT: - switch (e->left.expr->type) { - case E_NOT: -- // !!a -> a -+ /* !!a -> a */ - tmp = e->left.expr->left.expr; - free(e->left.expr); - free(e); -@@ -712,14 +712,14 @@ - break; - case E_EQUAL: - case E_UNEQUAL: -- // !a='x' -> a!='x' -+ /* !a='x' -> a!='x' */ - tmp = e->left.expr; - free(e); - e = tmp; - e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; - break; - case E_OR: -- // !(a || b) -> !a && !b -+ /* !(a || b) -> !a && !b */ - tmp = e->left.expr; - e->type = E_AND; - e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); -@@ -728,7 +728,7 @@ - e = expr_transform(e); - break; - case E_AND: -- // !(a && b) -> !a || !b -+ /* !(a && b) -> !a || !b */ - tmp = e->left.expr; - e->type = E_OR; - e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); -@@ -738,7 +738,7 @@ - break; - case E_SYMBOL: - if (e->left.expr->left.sym == &symbol_yes) { -- // !'y' -> 'n' -+ /* !'y' -> 'n' */ - tmp = e->left.expr; - free(e); - e = tmp; -@@ -747,7 +747,7 @@ - break; - } - if (e->left.expr->left.sym == &symbol_mod) { -- // !'m' -> 'm' -+ /* !'m' -> 'm' */ - tmp = e->left.expr; - free(e); - e = tmp; -@@ -756,7 +756,7 @@ - break; - } - if (e->left.expr->left.sym == &symbol_no) { -- // !'n' -> 'y' -+ /* !'n' -> 'y' */ - tmp = e->left.expr; - free(e); - e = tmp; -Index: config/gconf.c -=================================================================== ---- config.orig/gconf.c -+++ config/gconf.c -@@ -266,8 +266,8 @@ - /*"style", PANGO_STYLE_OBLIQUE, */ - NULL); - -- sprintf(title, _("Linux Kernel v%s Configuration"), -- getenv("KERNELVERSION")); -+ sprintf(title, _("Buildroot v%s Configuration"), -+ getenv("BR2_VERSION")); - gtk_window_set_title(GTK_WINDOW(main_wnd), title); - - gtk_widget_show(main_wnd); -Index: config/gconf.glade -=================================================================== ---- config.orig/gconf.glade -+++ config/gconf.glade -@@ -5,7 +5,7 @@ - - <widget class="GtkWindow" id="window1"> - <property name="visible">True</property> -- <property name="title" translatable="yes">Gtk Kernel Configurator</property> -+ <property name="title" translatable="yes">Gtk Buildroot Configurator</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> -Index: config/mconf.c -=================================================================== ---- config.orig/mconf.c -+++ config/mconf.c -@@ -25,10 +25,9 @@ - static const char mconf_readme[] = N_( - "Overview\n" - "--------\n" --"Some kernel features may be built directly into the kernel.\n" --"Some may be made into loadable runtime modules. Some features\n" -+"Some features may be built directly into Buildroot. Some features\n" - "may be completely removed altogether. There are also certain\n" --"kernel parameters which are not really features, but must be\n" -+"parameters which are not really features, but must be\n" - "entered in as decimal or hexadecimal numbers or possibly text.\n" - "\n" - "Menu items beginning with following braces represent features that\n" -@@ -115,7 +114,7 @@ - "-----------------------------\n" - "Menuconfig supports the use of alternate configuration files for\n" - "those who, for various reasons, find it necessary to switch\n" --"between different kernel configurations.\n" -+"between different configurations.\n" - "\n" - "At the end of the main menu you will find two options. One is\n" - "for saving the current configuration to a file of your choosing.\n" -@@ -148,7 +147,7 @@ - "\n" - "Optional personality available\n" - "------------------------------\n" --"If you prefer to have all of the kernel options listed in a single\n" -+"If you prefer to have all of the options listed in a single\n" - "menu, rather than the default multimenu hierarchy, run the menuconfig\n" - "with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" - "\n" -@@ -178,9 +177,9 @@ - "Arrow keys navigate the menu. " - "<Enter> selects submenus --->. " - "Highlighted letters are hotkeys. " -- "Pressing <Y> includes, <N> excludes, <M> modularizes features. " -+ "Pressing <Y> selectes a feature, while <N> will exclude a feature. " - "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " -- "Legend: [*] built-in [ ] excluded <M> module < > module capable"), -+ "Legend: [*] feature is selected [ ] feature is excluded"), - radiolist_instructions[] = N_( - "Use the arrow keys to navigate this window or " - "press the hotkey of the item you wish to select " -@@ -200,18 +199,18 @@ - "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[] = N_( -- "There is no help available for this kernel option.\n"), -+ "There is no help available for this option.\n"), - load_config_text[] = N_( - "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_( - "\n" -- "For various reasons, one may wish to keep several different kernel\n" -+ "For various reasons, one may wish to keep several different Buildroot\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" -+ "Buildroot'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" -@@ -221,7 +220,7 @@ - "as an alternate. Leave blank to abort."), - save_config_help[] = N_( - "\n" -- "For various reasons, one may wish to keep different kernel\n" -+ "For various reasons, one may wish to keep different Buildroot\n" - "configurations available on a single machine.\n" - "\n" - "Entering a file name here will allow you to later retrieve, modify\n" -@@ -364,10 +363,10 @@ - int size; - struct symbol *sym; - -- sym = sym_lookup("KERNELVERSION", 0); -+ sym = sym_lookup("BR2_VERSION", 0); - sym_calc_value(sym); - size = snprintf(menu_backtitle, sizeof(menu_backtitle), -- _("%s - Linux Kernel v%s Configuration"), -+ _("%s - buildroot v%s Configuration"), - config_filename, sym_get_string_value(sym)); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; -@@ -902,7 +901,7 @@ - if (conf_get_changed()) - res = dialog_yesno(NULL, - _("Do you wish to save your " -- "new kernel configuration?\n" -+ "new Buildroot configuration?\n" - "<ESC><ESC> to continue."), - 6, 60); - else -@@ -914,23 +913,23 @@ - case 0: - if (conf_write(filename)) { - fprintf(stderr, _("\n\n" -- "Error during writing of the kernel configuration.\n" -- "Your kernel configuration changes were NOT saved." -+ "Error during writing of the Buildroot configuration.\n" -+ "Your Buildroot configuration changes were NOT saved." - "\n\n")); - return 1; - } - case -1: - printf(_("\n\n" -- "*** End of Linux kernel configuration.\n" -- "*** Execute 'make' to build the kernel or try 'make help'." -+ "*** End of Buildroot configuration.\n" -+ "*** Execute 'make' to build Buildroot or try 'make help'." - "\n\n")); - break; - default: - fprintf(stderr, _("\n\n" -- "Your kernel configuration changes were NOT saved." -+ "Your Buildroot configuration changes were NOT saved." - "\n\n")); - } - -- return 0; -+ return conf_write_autoconf(); - } - -Index: config/qconf.cc -=================================================================== ---- config.orig/qconf.cc -+++ config/qconf.cc -@@ -1277,8 +1277,7 @@ - char title[256]; - - QDesktopWidget *d = configApp->desktop(); -- snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"), -- getenv("KERNELVERSION")); -+ snprintf(title, sizeof(title), _("Buildroot Configuration")); - setCaption(title); - - width = configSettings->readNumEntry("/window width", d->width() - 64); -@@ -1612,6 +1611,7 @@ - { - if (!conf_get_changed()) { - e->accept(); -+ conf_write_autoconf(); - return; - } - QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning, -@@ -1622,6 +1622,7 @@ - switch (mb.exec()) { - case QMessageBox::Yes: - conf_write(NULL); -+ conf_write_autoconf(); - case QMessageBox::No: - e->accept(); - break; -Index: config/util.c -=================================================================== ---- config.orig/util.c -+++ config/util.c -@@ -26,6 +26,109 @@ - return file; - } - -+static char* br2_symbol_printer(const char * const in) -+{ -+ ssize_t i, j, len = strlen(in); -+ char *ret; -+ if (len < 1) -+ return NULL; -+ ret = malloc(len); -+ if (!ret) { -+ printf("Out of memory!"); -+ exit(1); -+ } -+ memset(ret, 0, len); -+ i = j = 0; -+ if (strncmp("BR2_", in, 4) == 0) -+ i += 4; -+ if (strncmp("PACKAGE_", in + i, 8) == 0) -+ i += 8; -+ else if (strncmp("TARGET_", in + i, 7) == 0) -+ i += 7; -+ while (i <= len) -+ ret[j++] = tolower(in[i++]); -+ return ret; -+} -+ -+/* write dependencies of the infividual config-symbols */ -+static int write_make_deps(const char *name) -+{ -+ struct menu *menu; -+ struct symbol *sym; -+ struct property *prop, *p; -+ unsigned done; -+ const char * const name_tmp = "..make.deps.tmp"; -+ FILE *out; -+ if (!name) -+ name = ".auto.deps"; -+ out = fopen(name_tmp, "w"); -+ if (!out) -+ return 1; -+ fprintf(out, "# ATTENTION! This does not handle 'depends', just 'select'! \n" -+ "# See package/config/util.c write_make_deps()\n#\n"); -+ menu = &rootmenu;//rootmenu.list; -+ while (menu) { -+ sym = menu->sym; -+ if (!sym) { -+ if (!menu_is_visible(menu)) -+ goto next; -+ } else if (!(sym->flags & SYMBOL_CHOICE)) { -+ sym_calc_value(sym); -+ if (sym->type == S_BOOLEAN -+ && sym_get_tristate_value(sym) != no) { -+ done = 0; -+ for_all_prompts(sym, prop) { -+ struct expr *e; -+//printf("\nname=%s\n", sym->name); -+ for_all_properties(sym, p, P_SELECT) { -+ e = p->expr; -+ if (e && e->left.sym->name) { -+ if (!done) { -+ fprintf(out, "%s: $(BASE_TARGETS)", br2_symbol_printer(sym->name)); -+ done = 1; -+ } -+//printf("SELECTS %s\n",e->left.sym->name); -+ fprintf(out, " %s",br2_symbol_printer(e->left.sym->name)); -+ } -+ } -+ if (done) -+ fprintf(out, "\n"); -+#if 0 -+ e = sym->rev_dep.expr; -+ if (e && e->type == E_SYMBOL -+ && e->left.sym->name) { -+ fprintf(out, "%s: %s", br2_symbol_printer(e->left.sym->name), -+ br2_symbol_printer(sym->name)); -+printf("%s is Selected BY: %s", sym->name, e->left.sym->name); -+ } -+#endif -+ } -+ } -+ } -+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); -+ rename(name_tmp, name); -+ printf(_("#\n" -+ "# make dependencies written to %s\n" -+ "# ATTENTION buildroot devels!\n" -+ "# See top of this file before playing with this auto-preprequisites!\n" -+ "#\n"), name); -+ return 0; -+} -+ - /* write a dependency file as used by kbuild to track dependencies */ - int file_write_dep(const char *name) - { -@@ -68,7 +171,7 @@ - fprintf(out, "\n$(deps_config): ;\n"); - fclose(out); - rename("..config.tmp", name); -- return 0; -+ return write_make_deps(NULL); - } - - -Index: config/zconf.tab.c_shipped -=================================================================== ---- config.orig/zconf.tab.c_shipped -+++ config/zconf.tab.c_shipped -@@ -2259,7 +2259,7 @@ - modules_sym = sym_lookup(NULL, 0); - modules_sym->type = S_BOOLEAN; - modules_sym->flags |= SYMBOL_AUTO; -- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); -+ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL); - - #if YYDEBUG - if (getenv("ZCONF_DEBUG")) -Index: config/zconf.y -=================================================================== ---- config.orig/zconf.y -+++ config/zconf.y -@@ -476,7 +476,7 @@ - modules_sym = sym_lookup(NULL, 0); - modules_sym->type = S_BOOLEAN; - modules_sym->flags |= SYMBOL_AUTO; -- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); -+ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL); - - #if YYDEBUG - if (getenv("ZCONF_DEBUG")) diff --git a/package/config/kxgettext.c b/package/config/kxgettext.c index 8d9ce22b0..dcc3fcc0c 100644 --- a/package/config/kxgettext.c +++ b/package/config/kxgettext.c @@ -166,7 +166,7 @@ static int message__add(const char *msg, char *option, char *file, int lineno) return rc; } -void menu_build_message_list(struct menu *menu) +static void menu_build_message_list(struct menu *menu) { struct menu *child; @@ -211,7 +211,7 @@ static void message__print_gettext_msgid_msgstr(struct message *self) "msgstr \"\"\n", self->msg); } -void menu__xgettext(void) +static void menu__xgettext(void) { struct message *m = message__list; diff --git a/package/config/lex.zconf.c_shipped b/package/config/lex.zconf.c_shipped index dc3e81807..fdc7113b0 100644 --- a/package/config/lex.zconf.c_shipped +++ b/package/config/lex.zconf.c_shipped @@ -160,7 +160,15 @@ typedef unsigned int flex_uint32_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -802,7 +810,7 @@ static int last_ts, first_ts; static void zconf_endhelp(void); static void zconf_endfile(void); -void new_string(void) +static void new_string(void) { text = malloc(START_STRSIZE); text_asize = START_STRSIZE; @@ -810,7 +818,7 @@ void new_string(void) *text = 0; } -void append_string(const char *str, int size) +static void append_string(const char *str, int size) { int new_size = text_size + size + 1; if (new_size > text_asize) { @@ -824,7 +832,7 @@ void append_string(const char *str, int size) text[text_size] = 0; } -void alloc_string(const char *str, int size) +static void alloc_string(const char *str, int size) { text = malloc(size + 1); memcpy(text, str, size); @@ -914,7 +922,12 @@ static int input (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -922,7 +935,7 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( zconftext, zconfleng, 1, zconfout ) +#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -2060,8 +2073,8 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr ) /** Setup the input buffer state to scan the given bytes. The next call to zconflex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ diff --git a/package/config/lkc.h b/package/config/lkc.h index f379b0bf8..bdf71bd31 100644 --- a/package/config/lkc.h +++ b/package/config/lkc.h @@ -72,6 +72,9 @@ void zconf_nextfile(const char *name); int zconf_lineno(void); char *zconf_curname(void); +/* conf.c */ +void xfgets(char *str, int size, FILE *in); + /* confdata.c */ const char *conf_get_configname(void); const char *conf_get_autoconfig_name(void); @@ -80,11 +83,18 @@ void sym_set_change_count(int count); void sym_add_change_count(int count); void conf_set_all_new_symbols(enum conf_def_mode mode); +/* confdata.c and expr.c */ +static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) +{ + if (fwrite(str, len, count, out) < count) + fprintf(stderr, "\nError in writing or end of file.\n"); +} + /* kconfig_load.c */ void kconfig_load(void); /* menu.c */ -void menu_init(void); +void _menu_init(void); void menu_warn(struct menu *menu, const char *fmt, ...); struct menu *menu_add_menu(void); void menu_end_menu(void); @@ -106,6 +116,11 @@ int file_write_dep(const char *name); struct gstr { size_t len; char *s; + /* + * when max_width is not zero long lines in string s (if any) get + * wrapped not to exceed the max_width value + */ + int max_width; }; struct gstr str_new(void); struct gstr str_assign(const char *s); @@ -121,6 +136,8 @@ void sym_init(void); void sym_clear_all_valid(void); void sym_set_all_changed(void); void sym_set_changed(struct symbol *sym); +struct symbol *sym_choice_default(struct symbol *sym); +const char *sym_get_string_default(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); diff --git a/package/config/lkc_proto.h b/package/config/lkc_proto.h index 8e6946131..9a948c9ce 100644 --- a/package/config/lkc_proto.h +++ b/package/config/lkc_proto.h @@ -3,6 +3,7 @@ P(conf_parse,void,(const char *name)); P(conf_read,int,(const char *name)); P(conf_read_simple,int,(const char *name, int)); +P(conf_write_defconfig,int,(const char *name)); P(conf_write,int,(const char *name)); P(conf_write_autoconf,int,(void)); P(conf_get_changed,bool,(void)); @@ -11,12 +12,16 @@ P(conf_set_changed_callback, void,(void (*fn)(void))); /* menu.c */ P(rootmenu,struct menu,); -P(menu_is_visible,bool,(struct menu *menu)); +P(menu_is_visible, bool, (struct menu *menu)); +P(menu_has_prompt, 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)); P(menu_has_help,bool,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu)); +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym)); +P(get_relations_str, struct gstr, (struct symbol **sym_arr)); +P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); /* symbol.c */ P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); diff --git a/package/config/lxdialog/.gitignore b/package/config/lxdialog/.gitignore new file mode 100644 index 000000000..90b08ff02 --- /dev/null +++ b/package/config/lxdialog/.gitignore @@ -0,0 +1,4 @@ +# +# Generated files +# +lxdialog diff --git a/package/config/lxdialog/checklist.c b/package/config/lxdialog/checklist.c index bcc6f19c3..a2eb80fbc 100644 --- a/package/config/lxdialog/checklist.c +++ b/package/config/lxdialog/checklist.c @@ -31,6 +31,10 @@ static int list_width, check_x, item_x; static void print_item(WINDOW * win, int choice, int selected) { int i; + char *list_item = malloc(list_width + 1); + + strncpy(list_item, item_str(), list_width - item_x); + list_item[list_width - item_x] = '\0'; /* Clear 'residue' of last item */ wattrset(win, dlg.menubox.atr); @@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected) wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); - mvwaddch(win, choice, item_x, item_str()[0]); + mvwaddch(win, choice, item_x, list_item[0]); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); - waddstr(win, (char *)item_str() + 1); + waddstr(win, list_item + 1); if (selected) { wmove(win, choice, check_x + 1); wrefresh(win); } + free(list_item); } /* @@ -175,6 +180,7 @@ do_resize: check_x = 0; item_foreach() check_x = MAX(check_x, strlen(item_str()) + 4); + check_x = MIN(check_x, list_width); check_x = (list_width - check_x) / 2; item_x = check_x + 4; diff --git a/package/config/lxdialog/inputbox.c b/package/config/lxdialog/inputbox.c index 616c60138..dd8e587c5 100644 --- a/package/config/lxdialog/inputbox.c +++ b/package/config/lxdialog/inputbox.c @@ -180,7 +180,7 @@ do_resize: case KEY_LEFT: switch (button) { case -1: - button = 1; /* Indicates "Cancel" button is selected */ + button = 1; /* Indicates "Help" button is selected */ print_buttons(dialog, height, width, 1); break; case 0: @@ -204,7 +204,7 @@ do_resize: print_buttons(dialog, height, width, 0); break; case 0: - button = 1; /* Indicates "Cancel" button is selected */ + button = 1; /* Indicates "Help" button is selected */ print_buttons(dialog, height, width, 1); break; case 1: diff --git a/package/config/lxdialog/menubox.c b/package/config/lxdialog/menubox.c index fa9d633f2..1d604738f 100644 --- a/package/config/lxdialog/menubox.c +++ b/package/config/lxdialog/menubox.c @@ -383,6 +383,10 @@ do_resize: case 'n': case 'm': case '/': + case 'h': + case '?': + case 'z': + case '\n': /* save scroll info */ *s_scroll = scroll; delwin(menu); @@ -390,8 +394,10 @@ do_resize: item_set(scroll + choice); item_set_selected(1); switch (key) { + case 'h': + case '?': + return 2; case 's': - return 3; case 'y': return 3; case 'n': @@ -402,18 +408,12 @@ do_resize: return 6; case '/': return 7; + case 'z': + return 8; + case '\n': + return button; } return 0; - case 'h': - case '?': - button = 2; - case '\n': - *s_scroll = scroll; - delwin(menu); - delwin(dialog); - item_set(scroll + choice); - item_set_selected(1); - return button; case 'e': case 'x': key = KEY_ESC; diff --git a/package/config/lxdialog/util.c b/package/config/lxdialog/util.c index 86d95cca4..f2375ad7e 100644 --- a/package/config/lxdialog/util.c +++ b/package/config/lxdialog/util.c @@ -19,6 +19,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <stdarg.h> + #include "dialog.h" struct dialog_info dlg; diff --git a/package/config/mconf.c b/package/config/mconf.c index 11901e9c1..3d1ed3ac4 100644 --- a/package/config/mconf.c +++ b/package/config/mconf.c @@ -66,13 +66,15 @@ static const char mconf_readme[] = N_( " there is a delayed response which you may find annoying.\n" "\n" " Also, the <TAB> and cursor keys will cycle between <Select>,\n" -" <Exit> and <Help>\n" +" <Exit> and <Help>.\n" "\n" "o To get help with an item, use the cursor keys to highlight <Help>\n" -" and Press <ENTER>.\n" +" and press <ENTER>.\n" "\n" " Shortcut: Press <H> or <?>.\n" "\n" +"o To toggle the display of hidden options, press <Z>.\n" +"\n" "\n" "Radiolists (Choice lists)\n" "-----------\n" @@ -198,8 +200,6 @@ inputbox_instructions_string[] = N_( setmod_text[] = N_( "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[] = N_( - "There is no help available for this option.\n"), load_config_text[] = N_( "Enter the name of the configuration file you wish to load. " "Accept the name shown to restore the configuration you " @@ -214,7 +214,7 @@ load_config_help[] = 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"), + "configuration files. You should therefore leave this blank to abort.\n"), save_config_text[] = N_( "Enter a filename to which this configuration should be saved " "as an alternate. Leave blank to abort."), @@ -273,6 +273,7 @@ static int indent; static struct menu *current_menu; static int child_count; static int single_menu_mode; +static int show_all_options; static void conf(struct menu *menu); static void conf_choice(struct menu *menu); @@ -283,79 +284,6 @@ 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 get_prompt_str(struct gstr *r, struct property *prop) -{ - int i, j; - struct menu *submenu[8], *menu; - - str_printf(r, _("Prompt: %s\n"), _(prop->text)); - str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, _(" Depends on: ")); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); - } - menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) - submenu[i++] = menu; - if (i > 0) { - str_printf(r, _(" Location:\n")); - for (j = 4; --i >= 0; j += 2) { - menu = submenu[i]; - str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); - if (menu->sym) { - str_printf(r, " (%s [=%s])", menu->sym->name ? - menu->sym->name : _("<choice>"), - sym_get_string_value(menu->sym)); - } - str_append(r, "\n"); - } - } -} - -static void get_symbol_str(struct gstr *r, struct symbol *sym) -{ - bool hit; - struct property *prop; - - if (sym && sym->name) - str_printf(r, "Symbol: %s [=%s]\n", sym->name, - sym_get_string_value(sym)); - for_all_prompts(sym, prop) - get_prompt_str(r, prop); - hit = false; - for_all_properties(sym, prop, P_SELECT) { - if (!hit) { - str_append(r, " Selects: "); - hit = true; - } else - str_printf(r, " && "); - expr_gstr_print(prop->expr, r); - } - if (hit) - str_append(r, "\n"); - if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print(sym->rev_dep.expr, r); - str_append(r, "\n"); - } - str_append(r, "\n\n"); -} - -static struct gstr get_relations_str(struct symbol **sym_arr) -{ - struct symbol *sym; - struct gstr res = str_new(); - int i; - - for (i = 0; sym_arr && (sym = sym_arr[i]); i++) - get_symbol_str(&res, sym); - if (!i) - str_append(&res, _("No matches found.\n")); - return res; -} - static char filename[PATH_MAX+1]; static void set_config_filename(const char *config_filename) { @@ -420,8 +348,16 @@ static void build_conf(struct menu *menu) int type, tmp, doint = 2; tristate val; char ch; - - if (!menu_is_visible(menu)) + bool visible; + + /* + * note: menu_is_visible() has side effect that it will + * recalc the value of the symbol. + */ + visible = menu_is_visible(menu); + if (show_all_options && !menu_has_prompt(menu)) + return; + else if (!show_all_options && !visible) return; sym = menu->sym; @@ -680,6 +616,9 @@ static void conf(struct menu *menu) case 7: search_conf(); break; + case 8: + show_all_options = !show_all_options; + break; } } } @@ -698,19 +637,10 @@ static void show_helptext(const char *title, const char *text) static void show_help(struct menu *menu) { struct gstr help = str_new(); - struct symbol *sym = menu->sym; - - if (menu_has_help(menu)) - { - if (sym->name) { - str_printf(&help, "CONFIG_%s:\n\n", sym->name); - str_append(&help, _(menu_get_help(menu))); - str_append(&help, "\n"); - } - } else { - str_append(&help, nohelp_text); - } - get_symbol_str(&help, sym); + + help.max_width = getmaxx(stdscr) - 10; + menu_get_ext_help(menu, &help); + show_helptext(_(menu_get_prompt(menu)), str_get(&help)); str_free(&help); } @@ -887,6 +817,8 @@ int main(int ac, char **av) single_menu_mode = 1; } + initscr(); + getyx(stdscr, saved_y, saved_x); if (init_dialog(NULL)) { fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); @@ -930,6 +862,6 @@ int main(int ac, char **av) "\n\n")); } - return conf_write_autoconf(); + return 0; } diff --git a/package/config/menu.c b/package/config/menu.c index 07ff8d105..4fb590247 100644 --- a/package/config/menu.c +++ b/package/config/menu.c @@ -9,6 +9,9 @@ #define LKC_DIRECT_LINK #include "lkc.h" +static const char nohelp_text[] = N_( + "There is no help available for this kernel option.\n"); + struct menu rootmenu; static struct menu **last_entry_ptr; @@ -35,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...) va_end(ap); } -void menu_init(void) +void _menu_init(void) { current_entry = current_menu = &rootmenu; last_entry_ptr = &rootmenu.list; @@ -55,6 +58,8 @@ void menu_add_entry(struct symbol *sym) *last_entry_ptr = menu; last_entry_ptr = &menu->next; current_entry = menu; + if (sym) + menu_add_symbol(P_SYMBOL, sym, NULL); } void menu_end_entry(void) @@ -74,7 +79,7 @@ void menu_end_menu(void) current_menu = current_menu->parent; } -struct expr *menu_check_dep(struct expr *e) +static struct expr *menu_check_dep(struct expr *e) { if (!e) return e; @@ -102,6 +107,7 @@ struct expr *menu_check_dep(struct expr *e) void menu_add_dep(struct expr *dep) { current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); + current_entry->dir_dep = current_entry->dep; } void menu_set_type(int type) @@ -184,7 +190,7 @@ static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); } -void sym_check_prop(struct symbol *sym) +static void sym_check_prop(struct symbol *sym) { struct property *prop; struct symbol *sym2; @@ -194,7 +200,7 @@ void sym_check_prop(struct symbol *sym) 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 '%'" + "default for config symbol '%s'" " must be a single symbol", sym->name); break; case P_SELECT: @@ -285,6 +291,10 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { + /* ignore inherited dependencies for dir_dep */ + sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); + sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); @@ -387,6 +397,13 @@ void menu_finalize(struct menu *parent) } } +bool menu_has_prompt(struct menu *menu) +{ + if (!menu->prompt) + return false; + return true; +} + bool menu_is_visible(struct menu *menu) { struct menu *child; @@ -395,6 +412,7 @@ bool menu_is_visible(struct menu *menu) if (!menu->prompt) return false; + sym = menu->sym; if (sym) { sym_calc_value(sym); @@ -404,12 +422,18 @@ bool menu_is_visible(struct menu *menu) 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)) + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child)) { + if (sym) + sym->flags |= SYMBOL_DEF_USER; return true; + } + } + return false; } @@ -451,3 +475,104 @@ const char *menu_get_help(struct menu *menu) else return ""; } + +static void get_prompt_str(struct gstr *r, struct property *prop) +{ + int i, j; + struct menu *submenu[8], *menu; + + str_printf(r, _("Prompt: %s\n"), _(prop->text)); + str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, _(" Depends on: ")); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + menu = prop->menu->parent; + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) + submenu[i++] = menu; + if (i > 0) { + str_printf(r, _(" Location:\n")); + for (j = 4; --i >= 0; j += 2) { + menu = submenu[i]; + str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); + if (menu->sym) { + str_printf(r, " (%s [=%s])", menu->sym->name ? + menu->sym->name : _("<choice>"), + sym_get_string_value(menu->sym)); + } + str_append(r, "\n"); + } + } +} + +void get_symbol_str(struct gstr *r, struct symbol *sym) +{ + bool hit; + struct property *prop; + + if (sym && sym->name) { + str_printf(r, "Symbol: %s [=%s]\n", sym->name, + sym_get_string_value(sym)); + str_printf(r, "Type : %s\n", sym_type_name(sym->type)); + if (sym->type == S_INT || sym->type == S_HEX) { + prop = sym_get_range_prop(sym); + if (prop) { + str_printf(r, "Range : "); + expr_gstr_print(prop->expr, r); + str_append(r, "\n"); + } + } + } + for_all_prompts(sym, prop) + get_prompt_str(r, prop); + hit = false; + for_all_properties(sym, prop, P_SELECT) { + if (!hit) { + str_append(r, " Selects: "); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); + if (sym->rev_dep.expr) { + str_append(r, _(" Selected by: ")); + expr_gstr_print(sym->rev_dep.expr, r); + str_append(r, "\n"); + } + str_append(r, "\n\n"); +} + +struct gstr get_relations_str(struct symbol **sym_arr) +{ + struct symbol *sym; + struct gstr res = str_new(); + int i; + + for (i = 0; sym_arr && (sym = sym_arr[i]); i++) + get_symbol_str(&res, sym); + if (!i) + str_append(&res, _("No matches found.\n")); + return res; +} + + +void menu_get_ext_help(struct menu *menu, struct gstr *help) +{ + struct symbol *sym = menu->sym; + + if (menu_has_help(menu)) { + if (sym->name) { + str_printf(help, "CONFIG_%s:\n\n", sym->name); + str_append(help, _(menu_get_help(menu))); + str_append(help, "\n"); + } + } else { + str_append(help, nohelp_text); + } + if (sym) + get_symbol_str(help, sym); +} diff --git a/package/config/nconf.c b/package/config/nconf.c new file mode 100644 index 000000000..2ba71bcd3 --- /dev/null +++ b/package/config/nconf.c @@ -0,0 +1,1570 @@ +/* + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? + * Released under the terms of the GNU GPL v2.0. + * + * Derived from menuconfig. + * + */ +#define LKC_DIRECT_LINK +#include "lkc.h" +#include "nconf.h" + +static const char nconf_readme[] = N_( +"Overview\n" +"--------\n" +"Some kernel features may be built directly into the kernel.\n" +"Some may be made into loadable runtime modules. Some features\n" +"may be completely removed altogether. There are also certain\n" +"kernel parameters which are not really features, but must be\n" +"entered in as decimal or hexadecimal numbers or possibly text.\n" +"\n" +"Menu items beginning with following braces represent features that\n" +" [ ] can be built in or removed\n" +" < > can be built in, modularized or removed\n" +" { } can be built in or modularized (selected by other feature)\n" +" - - are selected by other feature,\n" +" XXX cannot be selected. use Symbol Info to find out why,\n" +"while *, M or whitespace inside braces means to build in, build as\n" +"a module or to exclude the feature respectively.\n" +"\n" +"To change any of these features, highlight it with the cursor\n" +"keys and press <Y> to build it in, <M> to make it a module or\n" +"<N> to removed it. You may also press the <Space Bar> to cycle\n" +"through the available options (ie. Y->N->M->Y).\n" +"\n" +"Some additional keyboard hints:\n" +"\n" +"Menus\n" +"----------\n" +"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" +" you wish to change use <Enter> or <Space>. Goto submenu by \n" +" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" +" Submenus are designated by \"--->\".\n" +"\n" +" Shortcut: Press the option's highlighted letter (hotkey).\n" +" Pressing a hotkey more than once will sequence\n" +" through all visible items which use that hotkey.\n" +"\n" +" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" +" unseen options into view.\n" +"\n" +"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n" +"\n" +"o To get help with an item, press <F1>\n" +" Shortcut: Press <h> or <?>.\n" +"\n" +"\n" +"Radiolists (Choice lists)\n" +"-----------\n" +"o Use the cursor keys to select the option you wish to set and press\n" +" <S> or the <SPACE BAR>.\n" +"\n" +" Shortcut: Press the first letter of the option you wish to set then\n" +" press <S> or <SPACE BAR>.\n" +"\n" +"o To see available help for the item, press <F1>\n" +" Shortcut: Press <H> or <?>.\n" +"\n" +"\n" +"Data Entry\n" +"-----------\n" +"o Enter the requested information and press <ENTER>\n" +" If you are entering hexadecimal values, it is not necessary to\n" +" add the '0x' prefix to the entry.\n" +"\n" +"o For help, press <F1>.\n" +"\n" +"\n" +"Text Box (Help Window)\n" +"--------\n" +"o Use the cursor keys to scroll up/down/left/right. The VI editor\n" +" keys h,j,k,l function here as do <SPACE BAR> for those\n" +" who are familiar with less and lynx.\n" +"\n" +"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n" +"\n" +"\n" +"Alternate Configuration Files\n" +"-----------------------------\n" +"nconfig supports the use of alternate configuration files for\n" +"those who, for various reasons, find it necessary to switch\n" +"between different kernel configurations.\n" +"\n" +"At the end of the main menu you will find two options. One is\n" +"for saving the current configuration to a file of your choosing.\n" +"The other option is for loading a previously saved alternate\n" +"configuration.\n" +"\n" +"Even if you don't use alternate configuration files, but you\n" +"find during a nconfig session that you have completely messed\n" +"up your settings, you may use the \"Load Alternate...\" option to\n" +"restore your previously saved settings from \".config\" without\n" +"restarting nconfig.\n" +"\n" +"Other information\n" +"-----------------\n" +"If you use nconfig in an XTERM window make sure you have your\n" +"$TERM variable set to point to a xterm definition which supports color.\n" +"Otherwise, nconfig will look rather bad. nconfig will not\n" +"display correctly in a RXVT window because rxvt displays only one\n" +"intensity of color, bright.\n" +"\n" +"nconfig will display larger menus on screens or xterms which are\n" +"set to display more than the standard 25 row by 80 column geometry.\n" +"In order for this to work, the \"stty size\" command must be able to\n" +"display the screen's current row and column geometry. I STRONGLY\n" +"RECOMMEND that you make sure you do NOT have the shell variables\n" +"LINES and COLUMNS exported into your environment. Some distributions\n" +"export those variables via /etc/profile. Some ncurses programs can\n" +"become confused when those variables (LINES & COLUMNS) don't reflect\n" +"the true screen size.\n" +"\n" +"Optional personality available\n" +"------------------------------\n" +"If you prefer to have all of the kernel options listed in a single\n" +"menu, rather than the default multimenu hierarchy, run the nconfig\n" +"with NCONFIG_MODE environment variable set to single_menu. Example:\n" +"\n" +"make NCONFIG_MODE=single_menu nconfig\n" +"\n" +"<Enter> will then unroll the appropriate category, or enfold it if it\n" +"is already unrolled.\n" +"\n" +"Note that this mode can eventually be a little more CPU expensive\n" +"(especially with a larger number of unrolled categories) than the\n" +"default mode.\n" +"\n"), +menu_no_f_instructions[] = N_( +" You do not have function keys support. Please follow the\n" +" following instructions:\n" +" Arrow keys navigate the menu.\n" +" <Enter> or <right-arrow> selects submenus --->.\n" +" Capital Letters are hotkeys.\n" +" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" +" Pressing SpaceBar toggles between the above options\n" +" Press <Esc> or <left-arrow> to go back one menu, \n" +" <?> or <h> for Help, </> for Search.\n" +" <1> is interchangable with <F1>, <2> with <F2>, etc.\n" +" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" +" <Esc> always leaves the current window\n"), +menu_instructions[] = N_( +" Arrow keys navigate the menu.\n" +" <Enter> or <right-arrow> selects submenus --->.\n" +" Capital Letters are hotkeys.\n" +" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" +" Pressing SpaceBar toggles between the above options\n" +" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n" +" <?>, <F1> or <h> for Help, </> for Search.\n" +" <1> is interchangable with <F1>, <2> with <F2>, etc.\n" +" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" +" <Esc> always leaves the current window\n"), +radiolist_instructions[] = N_( +" Use the arrow keys to navigate this window or\n" +" press the hotkey of the item you wish to select\n" +" followed by the <SPACE BAR>.\n" +" Press <?>, <F1> or <h> for additional information about this option.\n"), +inputbox_instructions_int[] = N_( +"Please enter a decimal value.\n" +"Fractions will not be accepted.\n" +"Press <RETURN> to accept, <ESC> to cancel."), +inputbox_instructions_hex[] = N_( +"Please enter a hexadecimal value.\n" +"Press <RETURN> to accept, <ESC> to cancel."), +inputbox_instructions_string[] = N_( +"Please enter a string value.\n" +"Press <RETURN> to accept, <ESC> to cancel."), +setmod_text[] = N_( +"This feature depends on another which\n" +"has been configured as a module.\n" +"As a result, this feature will be built as a module."), +nohelp_text[] = N_( +"There is no help available for this kernel option.\n"), +load_config_text[] = N_( +"Enter the name of the configuration file you wish to load.\n" +"Accept the name shown to restore the configuration you\n" +"last retrieved. Leave blank to abort."), +load_config_help[] = N_( +"\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[] = N_( +"Enter a filename to which this configuration should be saved\n" +"as an alternate. Leave blank to abort."), +save_config_help[] = N_( +"\n" +"For various reasons, one may wish to keep different kernel\n" +"configurations available on a single machine.\n" +"\n" +"Entering a file name here will allow you to later retrieve, modify\n" +"and use the current configuration as an alternate to whatever\n" +"configuration options you have selected at that time.\n" +"\n" +"If you are uncertain what all this means then you should probably\n" +"leave this blank.\n"), +search_help[] = N_( +"\n" +"Search for CONFIG_ symbols and display their relations.\n" +"Regular expressions are allowed.\n" +"Example: search for \"^FOO\"\n" +"Result:\n" +"-----------------------------------------------------------------\n" +"Symbol: FOO [ = m]\n" +"Prompt: Foo bus is used to drive the bar HW\n" +"Defined at drivers/pci/Kconfig:47\n" +"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" +"Location:\n" +" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" +" -> PCI support (PCI [ = y])\n" +" -> PCI access mode (<choice> [ = y])\n" +"Selects: LIBCRC32\n" +"Selected by: BAR\n" +"-----------------------------------------------------------------\n" +"o The line 'Prompt:' shows the text used in the menu structure for\n" +" this CONFIG_ symbol\n" +"o The 'Defined at' line tell at what file / line number the symbol\n" +" is defined\n" +"o The 'Depends on:' line tell what symbols needs to be defined for\n" +" this symbol to be visible in the menu (selectable)\n" +"o The 'Location:' lines tell where in the menu structure this symbol\n" +" is located\n" +" A location followed by a [ = y] indicate that this is a selectable\n" +" menu item - and current value is displayed inside brackets.\n" +"o The 'Selects:' line tell what symbol will be automatically\n" +" selected if this symbol is selected (y or m)\n" +"o The 'Selected by' line tell what symbol has selected this symbol\n" +"\n" +"Only relevant lines are shown.\n" +"\n\n" +"Search examples:\n" +"Examples: USB = > find all CONFIG_ symbols containing USB\n" +" ^USB => find all CONFIG_ symbols starting with USB\n" +" USB$ => find all CONFIG_ symbols ending with USB\n" +"\n"); + +struct mitem { + char str[256]; + char tag; + void *usrptr; + int is_hot; + int is_visible; +}; + +#define MAX_MENU_ITEMS 4096 +static int show_all_items; +static int indent; +static struct menu *current_menu; +static int child_count; +static int single_menu_mode; +/* the window in which all information appears */ +static WINDOW *main_window; +/* the largest size of the menu window */ +static int mwin_max_lines; +static int mwin_max_cols; +/* the window in which we show option buttons */ +static MENU *curses_menu; +static ITEM *curses_menu_items[MAX_MENU_ITEMS]; +static struct mitem k_menu_items[MAX_MENU_ITEMS]; +static int items_num; +static int global_exit; +/* the currently selected button */ +const char *current_instructions = menu_instructions; +/* this array is used to implement hot keys. it is updated in item_make and + * resetted in clean_items. It would be better to use a hash, but lets keep it + * simple... */ +#define MAX_SAME_KEY MAX_MENU_ITEMS +struct { + int count; + int ptrs[MAX_MENU_ITEMS]; +} hotkeys[1<<(sizeof(char)*8)]; + +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_help(struct menu *menu); +static int do_exit(void); +static void setup_windows(void); + +typedef void (*function_key_handler_t)(int *key, struct menu *menu); +static void handle_f1(int *key, struct menu *current_item); +static void handle_f2(int *key, struct menu *current_item); +static void handle_f3(int *key, struct menu *current_item); +static void handle_f4(int *key, struct menu *current_item); +static void handle_f5(int *key, struct menu *current_item); +static void handle_f6(int *key, struct menu *current_item); +static void handle_f7(int *key, struct menu *current_item); +static void handle_f8(int *key, struct menu *current_item); + +struct function_keys { + const char *key_str; + const char *func; + function_key key; + function_key_handler_t handler; +}; + +static const int function_keys_num = 8; +struct function_keys function_keys[] = { + { + .key_str = "F1", + .func = "Help", + .key = F_HELP, + .handler = handle_f1, + }, + { + .key_str = "F2", + .func = "Symbol Info", + .key = F_SYMBOL, + .handler = handle_f2, + }, + { + .key_str = "F3", + .func = "Instructions", + .key = F_INSTS, + .handler = handle_f3, + }, + { + .key_str = "F4", + .func = "Config", + .key = F_CONF, + .handler = handle_f4, + }, + { + .key_str = "F5", + .func = "Back", + .key = F_BACK, + .handler = handle_f5, + }, + { + .key_str = "F6", + .func = "Save", + .key = F_SAVE, + .handler = handle_f6, + }, + { + .key_str = "F7", + .func = "Load", + .key = F_LOAD, + .handler = handle_f7, + }, + { + .key_str = "F8", + .func = "Exit", + .key = F_EXIT, + .handler = handle_f8, + }, +}; + +static void print_function_line(void) +{ + int i; + int offset = 1; + const int skip = 1; + + for (i = 0; i < function_keys_num; i++) { + wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); + mvwprintw(main_window, LINES-3, offset, + "%s", + function_keys[i].key_str); + wattrset(main_window, attributes[FUNCTION_TEXT]); + offset += strlen(function_keys[i].key_str); + mvwprintw(main_window, LINES-3, + offset, "%s", + function_keys[i].func); + offset += strlen(function_keys[i].func) + skip; + } + wattrset(main_window, attributes[NORMAL]); +} + +/* help */ +static void handle_f1(int *key, struct menu *current_item) +{ + show_scroll_win(main_window, + _("README"), _(nconf_readme)); + return; +} + +/* symbole help */ +static void handle_f2(int *key, struct menu *current_item) +{ + show_help(current_item); + return; +} + +/* instructions */ +static void handle_f3(int *key, struct menu *current_item) +{ + show_scroll_win(main_window, + _("Instructions"), + _(current_instructions)); + return; +} + +/* config */ +static void handle_f4(int *key, struct menu *current_item) +{ + int res = btn_dialog(main_window, + _("Show all symbols?"), + 2, + " <Show All> ", + "<Don't show all>"); + if (res == 0) + show_all_items = 1; + else if (res == 1) + show_all_items = 0; + + return; +} + +/* back */ +static void handle_f5(int *key, struct menu *current_item) +{ + *key = KEY_LEFT; + return; +} + +/* save */ +static void handle_f6(int *key, struct menu *current_item) +{ + conf_save(); + return; +} + +/* load */ +static void handle_f7(int *key, struct menu *current_item) +{ + conf_load(); + return; +} + +/* exit */ +static void handle_f8(int *key, struct menu *current_item) +{ + do_exit(); + return; +} + +/* return != 0 to indicate the key was handles */ +static int process_special_keys(int *key, struct menu *menu) +{ + int i; + + if (*key == KEY_RESIZE) { + setup_windows(); + return 1; + } + + for (i = 0; i < function_keys_num; i++) { + if (*key == KEY_F(function_keys[i].key) || + *key == '0' + function_keys[i].key){ + function_keys[i].handler(key, menu); + return 1; + } + } + + return 0; +} + +static void clean_items(void) +{ + int i; + for (i = 0; curses_menu_items[i]; i++) + free_item(curses_menu_items[i]); + bzero(curses_menu_items, sizeof(curses_menu_items)); + bzero(k_menu_items, sizeof(k_menu_items)); + bzero(hotkeys, sizeof(hotkeys)); + items_num = 0; +} + +/* return the index of the next hot item, or -1 if no such item exists */ +static int get_next_hot(int c) +{ + static int hot_index; + static int hot_char; + + if (c < 0 || c > 255 || hotkeys[c].count <= 0) + return -1; + + if (hot_char == c) { + hot_index = (hot_index+1)%hotkeys[c].count; + return hotkeys[c].ptrs[hot_index]; + } else { + hot_char = c; + hot_index = 0; + return hotkeys[c].ptrs[0]; + } +} + +/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */ +static int canbhot(char c) +{ + c = tolower(c); + return isalnum(c) && c != 'y' && c != 'm' && c != 'h' && + c != 'n' && c != '?'; +} + +/* check if str already contains a hot key. */ +static int is_hot(int index) +{ + return k_menu_items[index].is_hot; +} + +/* find the first possible hot key, and mark it. + * index is the index of the item in the menu + * return 0 on success*/ +static int make_hot(char *dest, int len, const char *org, int index) +{ + int position = -1; + int i; + int tmp; + int c; + int org_len = strlen(org); + + if (org == NULL || is_hot(index)) + return 1; + + /* make sure not to make hot keys out of markers. + * find where to start looking for a hot key + */ + i = 0; + /* skip white space */ + while (i < org_len && org[i] == ' ') + i++; + if (i == org_len) + return -1; + /* if encountering '(' or '<' or '[', find the match and look from there + **/ + if (org[i] == '[' || org[i] == '<' || org[i] == '(') { + i++; + for (; i < org_len; i++) + if (org[i] == ']' || org[i] == '>' || org[i] == ')') + break; + } + if (i == org_len) + return -1; + for (; i < org_len; i++) { + if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') { + position = i; + break; + } + } + if (position == -1) + return 1; + + /* ok, char at org[position] should be a hot key to this item */ + c = tolower(org[position]); + tmp = hotkeys[c].count; + hotkeys[c].ptrs[tmp] = index; + hotkeys[c].count++; + /* + snprintf(dest, len, "%.*s(%c)%s", position, org, org[position], + &org[position+1]); + */ + /* make org[position] uppercase, and all leading letter small case */ + strncpy(dest, org, len); + for (i = 0; i < position; i++) + dest[i] = tolower(dest[i]); + dest[position] = toupper(dest[position]); + k_menu_items[index].is_hot = 1; + return 0; +} + +/* Make a new item. Add a hotkey mark in the first possible letter. + * As ncurses does not allow any attributes inside menue item, we mark the + * hot key as the first capitalized letter in the string */ +static void item_make(struct menu *menu, char tag, const char *fmt, ...) +{ + va_list ap; + char tmp_str[256]; + + if (items_num > MAX_MENU_ITEMS-1) + return; + + bzero(&k_menu_items[items_num], sizeof(k_menu_items[0])); + k_menu_items[items_num].tag = tag; + k_menu_items[items_num].usrptr = menu; + if (menu != NULL) + k_menu_items[items_num].is_visible = + menu_is_visible(menu); + else + k_menu_items[items_num].is_visible = 1; + + va_start(ap, fmt); + vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); + if (!k_menu_items[items_num].is_visible) + memcpy(tmp_str, "XXX", 3); + va_end(ap); + if (make_hot( + k_menu_items[items_num].str, + sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) + strncpy(k_menu_items[items_num].str, + tmp_str, + sizeof(k_menu_items[items_num].str)); + + curses_menu_items[items_num] = new_item( + k_menu_items[items_num].str, + k_menu_items[items_num].str); + set_item_userptr(curses_menu_items[items_num], + &k_menu_items[items_num]); + /* + if (!k_menu_items[items_num].is_visible) + item_opts_off(curses_menu_items[items_num], O_SELECTABLE); + */ + + items_num++; + curses_menu_items[items_num] = NULL; +} + +/* very hackish. adds a string to the last item added */ +static void item_add_str(const char *fmt, ...) +{ + va_list ap; + int index = items_num-1; + char new_str[256]; + char tmp_str[256]; + + if (index < 0) + return; + + va_start(ap, fmt); + vsnprintf(new_str, sizeof(new_str), fmt, ap); + va_end(ap); + snprintf(tmp_str, sizeof(tmp_str), "%s%s", + k_menu_items[index].str, new_str); + if (make_hot(k_menu_items[index].str, + sizeof(k_menu_items[index].str), tmp_str, index) != 0) + strncpy(k_menu_items[index].str, + tmp_str, + sizeof(k_menu_items[index].str)); + + free_item(curses_menu_items[index]); + curses_menu_items[index] = new_item( + k_menu_items[index].str, + k_menu_items[index].str); + set_item_userptr(curses_menu_items[index], + &k_menu_items[index]); +} + +/* get the tag of the currently selected item */ +static char item_tag(void) +{ + ITEM *cur; + struct mitem *mcur; + + cur = current_item(curses_menu); + if (cur == NULL) + return 0; + mcur = (struct mitem *) item_userptr(cur); + return mcur->tag; +} + +static int curses_item_index(void) +{ + return item_index(current_item(curses_menu)); +} + +static void *item_data(void) +{ + ITEM *cur; + struct mitem *mcur; + + cur = current_item(curses_menu); + if (!cur) + return NULL; + mcur = (struct mitem *) item_userptr(cur); + return mcur->usrptr; + +} + +static int item_is_tag(char tag) +{ + return item_tag() == tag; +} + +static char filename[PATH_MAX+1]; +static char menu_backtitle[PATH_MAX+128]; +static const char *set_config_filename(const char *config_filename) +{ + int size; + struct symbol *sym; + + sym = sym_lookup("KERNELVERSION", 0); + sym_calc_value(sym); + size = snprintf(menu_backtitle, sizeof(menu_backtitle), + _("%s - Linux Kernel v%s Configuration"), + config_filename, sym_get_string_value(sym)); + if (size >= sizeof(menu_backtitle)) + menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + + size = snprintf(filename, sizeof(filename), "%s", config_filename); + if (size >= sizeof(filename)) + filename[sizeof(filename)-1] = '\0'; + return menu_backtitle; +} + +/* command = 0 is supress, 1 is restore */ +static void supress_stdout(int command) +{ + static FILE *org_stdout; + static FILE *org_stderr; + + if (command == 0) { + org_stdout = stdout; + org_stderr = stderr; + stdout = fopen("/dev/null", "a"); + stderr = fopen("/dev/null", "a"); + } else { + fclose(stdout); + fclose(stderr); + stdout = org_stdout; + stderr = org_stderr; + } +} + +/* return = 0 means we are successful. + * -1 means go on doing what you were doing + */ +static int do_exit(void) +{ + int res; + if (!conf_get_changed()) { + global_exit = 1; + return 0; + } + res = btn_dialog(main_window, + _("Do you wish to save your " + "new kernel configuration?\n" + "<ESC> to cancel and resume nconfig."), + 2, + " <save> ", + "<don't save>"); + if (res == KEY_EXIT) { + global_exit = 0; + return -1; + } + + /* if we got here, the user really wants to exit */ + switch (res) { + case 0: + supress_stdout(0); + res = conf_write(filename); + supress_stdout(1); + if (res) + btn_dialog( + main_window, + _("Error during writing of the kernel " + "configuration.\n" + "Your kernel configuration " + "changes were NOT saved."), + 1, + "<OK>"); + else { + char buf[1024]; + snprintf(buf, 1024, + _("Configuration written to %s\n" + "End of Linux kernel configuration.\n" + "Execute 'make' to build the kernel or try" + " 'make help'."), filename); + btn_dialog( + main_window, + buf, + 1, + "<OK>"); + } + break; + default: + btn_dialog( + main_window, + _("Your kernel configuration changes were NOT saved."), + 1, + "<OK>"); + break; + } + global_exit = 1; + return 0; +} + + +static void search_conf(void) +{ + struct symbol **sym_arr; + struct gstr res; + char dialog_input_result[100]; + char *dialog_input; + int dres; +again: + dres = dialog_inputbox(main_window, + _("Search Configuration Parameter"), + _("Enter CONFIG_ (sub)string to search for " + "(with or without \"CONFIG\")"), + "", dialog_input_result, 99); + switch (dres) { + case 0: + break; + case 1: + show_scroll_win(main_window, + _("Search Configuration"), search_help); + goto again; + default: + return; + } + + /* strip CONFIG_ if necessary */ + dialog_input = dialog_input_result; + if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) + dialog_input += 7; + + sym_arr = sym_re_search(dialog_input); + res = get_relations_str(sym_arr); + free(sym_arr); + show_scroll_win(main_window, + _("Search Results"), str_get(&res)); + str_free(&res); +} + + +static void build_conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + int type, tmp, doint = 2; + tristate val; + char ch; + + if (!menu || (!show_all_items && !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); + enum prop_type ptype; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + switch (ptype) { + case P_MENU: + child_count++; + prompt = _(prompt); + if (single_menu_mode) { + item_make(menu, 'm', + "%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); + } else + item_make(menu, 'm', + " %*c%s --->", + indent + 1, + ' ', prompt); + + if (single_menu_mode && menu->data) + goto conf_childs; + return; + case P_COMMENT: + if (prompt) { + child_count++; + item_make(menu, ':', + " %*c*** %s ***", + indent + 1, ' ', + _(prompt)); + } + break; + default: + if (prompt) { + child_count++; + item_make(menu, ':', "---%*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)) { + switch (type) { + case S_BOOLEAN: + item_make(menu, 't', "[%c]", + val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: + ch = '*'; + break; + case mod: + ch = 'M'; + break; + default: + ch = ' '; + break; + } + item_make(menu, 't', "<%c>", ch); + break; + } + } else { + item_make(menu, def_menu ? 't' : ':', " "); + } + + item_add_str("%*c%s", indent + 1, + ' ', _(menu_get_prompt(menu))); + if (val == yes) { + if (def_menu) { + item_add_str(" (%s)", + _(menu_get_prompt(def_menu))); + item_add_str(" --->"); + if (def_menu->list) { + indent += 2; + build_conf(def_menu); + indent -= 2; + } + } + return; + } + } else { + if (menu == current_menu) { + item_make(menu, ':', + "---%*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) { + item_make(menu, ':', " "); + } else { + switch (type) { + case S_BOOLEAN: + if (sym_is_changable(sym)) + item_make(menu, 't', "[%c]", + val == no ? ' ' : '*'); + else + item_make(menu, 't', "-%c-", + val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: + ch = '*'; + break; + case mod: + ch = 'M'; + break; + default: + ch = ' '; + break; + } + if (sym_is_changable(sym)) { + if (sym->rev_dep.tri == mod) + item_make(menu, + 't', "{%c}", ch); + else + item_make(menu, + 't', "<%c>", ch); + } else + item_make(menu, 't', "-%c-", ch); + break; + default: + tmp = 2 + strlen(sym_get_string_value(sym)); + item_make(menu, 's', " (%s)", + sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + item_add_str("%*c%s%s", tmp, ' ', + _(menu_get_prompt(menu)), + (sym_has_value(sym) || + !sym_is_changable(sym)) ? "" : + _(" (NEW)")); + goto conf_childs; + } + } + item_add_str("%*c%s%s", indent + 1, ' ', + _(menu_get_prompt(menu)), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : _(" (NEW)")); + if (menu->prompt && menu->prompt->type == P_MENU) { + item_add_str(" --->"); + return; + } + } + +conf_childs: + indent += doint; + for (child = menu->list; child; child = child->next) + build_conf(child); + indent -= doint; +} + +static void reset_menu(void) +{ + unpost_menu(curses_menu); + clean_items(); +} + +/* adjust the menu to show this item. + * prefer not to scroll the menu if possible*/ +static void center_item(int selected_index, int *last_top_row) +{ + int toprow; + int maxy, maxx; + + scale_menu(curses_menu, &maxy, &maxx); + set_top_row(curses_menu, *last_top_row); + toprow = top_row(curses_menu); + if (selected_index >= toprow && selected_index < toprow+maxy) { + /* we can only move the selected item. no need to scroll */ + set_current_item(curses_menu, + curses_menu_items[selected_index]); + } else { + toprow = max(selected_index-maxy/2, 0); + if (toprow >= item_count(curses_menu)-maxy) + toprow = item_count(curses_menu)-mwin_max_lines; + set_top_row(curses_menu, toprow); + set_current_item(curses_menu, + curses_menu_items[selected_index]); + } + *last_top_row = toprow; + post_menu(curses_menu); + refresh_all_windows(main_window); +} + +/* this function assumes reset_menu has been called before */ +static void show_menu(const char *prompt, const char *instructions, + int selected_index, int *last_top_row) +{ + int maxx, maxy; + WINDOW *menu_window; + + current_instructions = instructions; + + clear(); + wattrset(main_window, attributes[NORMAL]); + print_in_middle(stdscr, 1, 0, COLS, + menu_backtitle, + attributes[MAIN_HEADING]); + + wattrset(main_window, attributes[MAIN_MENU_BOX]); + box(main_window, 0, 0); + wattrset(main_window, attributes[MAIN_MENU_HEADING]); + mvwprintw(main_window, 0, 3, " %s ", prompt); + wattrset(main_window, attributes[NORMAL]); + + set_menu_items(curses_menu, curses_menu_items); + + /* position the menu at the middle of the screen */ + scale_menu(curses_menu, &maxy, &maxx); + maxx = min(maxx, mwin_max_cols-2); + maxy = mwin_max_lines-2; + menu_window = derwin(main_window, + maxy, + maxx, + 2, + (mwin_max_cols-maxx)/2); + keypad(menu_window, TRUE); + set_menu_win(curses_menu, menu_window); + set_menu_sub(curses_menu, menu_window); + + /* must reassert this after changing items, otherwise returns to a + * default of 16 + */ + set_menu_format(curses_menu, maxy, 1); + center_item(selected_index, last_top_row); + set_menu_format(curses_menu, maxy, 1); + + print_function_line(); + + /* Post the menu */ + post_menu(curses_menu); + refresh_all_windows(main_window); +} + + +static void conf(struct menu *menu) +{ + char pattern[256]; + struct menu *submenu = 0; + const char *prompt = menu_get_prompt(menu); + struct symbol *sym; + struct menu *active_menu = NULL; + int res; + int current_index = 0; + int last_top_row = 0; + + bzero(pattern, sizeof(pattern)); + + while (!global_exit) { + reset_menu(); + current_menu = menu; + build_conf(menu); + if (!child_count) + break; + + show_menu(prompt ? _(prompt) : _("Main Menu"), + _(menu_instructions), + current_index, &last_top_row); + keypad((menu_win(curses_menu)), TRUE); + while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { + if (process_special_keys(&res, + (struct menu *) item_data())) + break; + switch (res) { + case KEY_DOWN: + menu_driver(curses_menu, REQ_DOWN_ITEM); + break; + case KEY_UP: + menu_driver(curses_menu, REQ_UP_ITEM); + break; + case KEY_NPAGE: + menu_driver(curses_menu, REQ_SCR_DPAGE); + break; + case KEY_PPAGE: + menu_driver(curses_menu, REQ_SCR_UPAGE); + break; + case KEY_HOME: + menu_driver(curses_menu, REQ_FIRST_ITEM); + break; + case KEY_END: + menu_driver(curses_menu, REQ_LAST_ITEM); + break; + case 'h': + case '?': + show_help((struct menu *) item_data()); + break; + } + if (res == 10 || res == 27 || + res == 32 || res == 'n' || res == 'y' || + res == KEY_LEFT || res == KEY_RIGHT || + res == 'm' || res == '/') + break; + else if (canbhot(res)) { + /* check for hot keys: */ + int tmp = get_next_hot(res); + if (tmp != -1) + center_item(tmp, &last_top_row); + } + refresh_all_windows(main_window); + } + + refresh_all_windows(main_window); + /* if ESC or left*/ + if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) + break; + + /* remember location in the menu */ + last_top_row = top_row(curses_menu); + current_index = curses_item_index(); + + if (!item_tag()) + continue; + + submenu = (struct menu *) item_data(); + active_menu = (struct menu *)item_data(); + if (!submenu || !menu_is_visible(submenu)) + continue; + if (submenu) + sym = submenu->sym; + else + sym = NULL; + + switch (res) { + case ' ': + if (item_is_tag('t')) + sym_toggle_tristate_value(sym); + else if (item_is_tag('m')) + conf(submenu); + break; + case KEY_RIGHT: + case 10: /* ENTER WAS PRESSED */ + switch (item_tag()) { + 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 && + submenu->prompt->type == P_MENU) + conf(submenu); + else if (res == 10) + sym_toggle_tristate_value(sym); + break; + case 's': + conf_string(submenu); + break; + } + break; + case 'y': + if (item_is_tag('t')) { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + btn_dialog(main_window, setmod_text, 0); + } + break; + case 'n': + if (item_is_tag('t')) + sym_set_tristate_value(sym, no); + break; + case 'm': + if (item_is_tag('t')) + sym_set_tristate_value(sym, mod); + break; + case '/': + search_conf(); + break; + } + } +} + +static void show_help(struct menu *menu) +{ + struct gstr help = str_new(); + + if (menu && menu->sym && menu_has_help(menu)) { + if (menu->sym->name) { + str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name); + str_append(&help, _(menu_get_help(menu))); + str_append(&help, "\n"); + get_symbol_str(&help, menu->sym); + } + } else { + str_append(&help, nohelp_text); + } + show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); + str_free(&help); +} + +static void conf_choice(struct menu *menu) +{ + const char *prompt = _(menu_get_prompt(menu)); + struct menu *child = 0; + struct symbol *active; + int selected_index = 0; + int last_top_row = 0; + int res, i = 0; + + active = sym_get_choice_value(menu->sym); + /* this is mostly duplicated from the conf() function. */ + while (!global_exit) { + reset_menu(); + + for (i = 0, child = menu->list; child; child = child->next) { + if (!show_all_items && !menu_is_visible(child)) + continue; + + if (child->sym == sym_get_choice_value(menu->sym)) + item_make(child, ':', "<X> %s", + _(menu_get_prompt(child))); + else + item_make(child, ':', " %s", + _(menu_get_prompt(child))); + if (child->sym == active){ + last_top_row = top_row(curses_menu); + selected_index = i; + } + i++; + } + show_menu(prompt ? _(prompt) : _("Choice Menu"), + _(radiolist_instructions), + selected_index, + &last_top_row); + while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { + if (process_special_keys( + &res, + (struct menu *) item_data())) + break; + switch (res) { + case KEY_DOWN: + menu_driver(curses_menu, REQ_DOWN_ITEM); + break; + case KEY_UP: + menu_driver(curses_menu, REQ_UP_ITEM); + break; + case KEY_NPAGE: + menu_driver(curses_menu, REQ_SCR_DPAGE); + break; + case KEY_PPAGE: + menu_driver(curses_menu, REQ_SCR_UPAGE); + break; + case KEY_HOME: + menu_driver(curses_menu, REQ_FIRST_ITEM); + break; + case KEY_END: + menu_driver(curses_menu, REQ_LAST_ITEM); + break; + case 'h': + case '?': + show_help((struct menu *) item_data()); + break; + } + if (res == 10 || res == 27 || res == ' ' || + res == KEY_LEFT) + break; + else if (canbhot(res)) { + /* check for hot keys: */ + int tmp = get_next_hot(res); + if (tmp != -1) + center_item(tmp, &last_top_row); + } + refresh_all_windows(main_window); + } + /* if ESC or left */ + if (res == 27 || res == KEY_LEFT) + break; + + child = item_data(); + if (!child || !menu_is_visible(child)) + continue; + switch (res) { + case ' ': + case 10: + case KEY_RIGHT: + sym_set_tristate_value(child->sym, yes); + return; + case 'h': + case '?': + show_help(child); + active = child->sym; + break; + case KEY_EXIT: + return; + } + } +} + +static void conf_string(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + char dialog_input_result[256]; + + while (1) { + int res; + const char *heading; + + switch (sym_get_type(menu->sym)) { + case S_INT: + heading = _(inputbox_instructions_int); + break; + case S_HEX: + heading = _(inputbox_instructions_hex); + break; + case S_STRING: + heading = _(inputbox_instructions_string); + break; + default: + heading = _("Internal nconf error!"); + } + res = dialog_inputbox(main_window, + prompt ? _(prompt) : _("Main Menu"), + heading, + sym_get_string_value(menu->sym), + dialog_input_result, + sizeof(dialog_input_result)); + switch (res) { + case 0: + if (sym_set_string_value(menu->sym, + dialog_input_result)) + return; + btn_dialog(main_window, + _("You have made an invalid entry."), 0); + break; + case 1: + show_help(menu); + break; + case KEY_EXIT: + return; + } + } +} + +static void conf_load(void) +{ + char dialog_input_result[256]; + while (1) { + int res; + res = dialog_inputbox(main_window, + NULL, load_config_text, + filename, + dialog_input_result, + sizeof(dialog_input_result)); + switch (res) { + case 0: + if (!dialog_input_result[0]) + return; + if (!conf_read(dialog_input_result)) { + set_config_filename(dialog_input_result); + sym_set_change_count(1); + return; + } + btn_dialog(main_window, _("File does not exist!"), 0); + break; + case 1: + show_scroll_win(main_window, + _("Load Alternate Configuration"), + load_config_help); + break; + case KEY_EXIT: + return; + } + } +} + +static void conf_save(void) +{ + char dialog_input_result[256]; + while (1) { + int res; + res = dialog_inputbox(main_window, + NULL, save_config_text, + filename, + dialog_input_result, + sizeof(dialog_input_result)); + switch (res) { + case 0: + if (!dialog_input_result[0]) + return; + supress_stdout(0); + res = conf_write(dialog_input_result); + supress_stdout(1); + if (!res) { + char buf[1024]; + sprintf(buf, "%s %s", + _("configuration file saved to: "), + dialog_input_result); + btn_dialog(main_window, + buf, 1, "<OK>"); + set_config_filename(dialog_input_result); + return; + } + btn_dialog(main_window, _("Can't create file! " + "Probably a nonexistent directory."), + 1, "<OK>"); + break; + case 1: + show_scroll_win(main_window, + _("Save Alternate Configuration"), + save_config_help); + break; + case KEY_EXIT: + return; + } + } +} + +void setup_windows(void) +{ + if (main_window != NULL) + delwin(main_window); + + /* set up the menu and menu window */ + main_window = newwin(LINES-2, COLS-2, 2, 1); + keypad(main_window, TRUE); + mwin_max_lines = LINES-6; + mwin_max_cols = COLS-6; + + /* panels order is from bottom to top */ + new_panel(main_window); +} + +int main(int ac, char **av) +{ + char *mode; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + conf_parse(av[1]); + conf_read(NULL); + + mode = getenv("NCONFIG_MODE"); + if (mode) { + if (!strcasecmp(mode, "single_menu")) + single_menu_mode = 1; + } + + /* Initialize curses */ + initscr(); + /* set color theme */ + set_colors(); + + cbreak(); + noecho(); + keypad(stdscr, TRUE); + curs_set(0); + + if (COLS < 75 || LINES < 20) { + endwin(); + printf("Your terminal should have at " + "least 20 lines and 75 columns\n"); + return 1; + } + + notimeout(stdscr, FALSE); + ESCDELAY = 1; + + /* set btns menu */ + curses_menu = new_menu(curses_menu_items); + menu_opts_off(curses_menu, O_SHOWDESC); + menu_opts_off(curses_menu, O_SHOWMATCH); + menu_opts_on(curses_menu, O_ONEVALUE); + menu_opts_on(curses_menu, O_NONCYCLIC); + set_menu_mark(curses_menu, " "); + set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); + set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); + set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); + + set_config_filename(conf_get_configname()); + setup_windows(); + + /* check for KEY_FUNC(1) */ + if (has_key(KEY_F(1)) == FALSE) { + show_scroll_win(main_window, + _("Instructions"), + _(menu_no_f_instructions)); + } + + + + /* do the work */ + while (!global_exit) { + conf(&rootmenu); + if (!global_exit && do_exit() == 0) + break; + } + /* ok, we are done */ + unpost_menu(curses_menu); + free_menu(curses_menu); + delwin(main_window); + clear(); + refresh(); + endwin(); + return 0; +} + diff --git a/package/config/nconf.gui.c b/package/config/nconf.gui.c new file mode 100644 index 000000000..a9d9344e1 --- /dev/null +++ b/package/config/nconf.gui.c @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? + * Released under the terms of the GNU GPL v2.0. + * + * Derived from menuconfig. + * + */ +#include "nconf.h" + +/* a list of all the different widgets we use */ +attributes_t attributes[ATTR_MAX+1] = {0}; + +/* available colors: + COLOR_BLACK 0 + COLOR_RED 1 + COLOR_GREEN 2 + COLOR_YELLOW 3 + COLOR_BLUE 4 + COLOR_MAGENTA 5 + COLOR_CYAN 6 + COLOR_WHITE 7 + */ +static void set_normal_colors(void) +{ + init_pair(NORMAL, -1, -1); + init_pair(MAIN_HEADING, COLOR_MAGENTA, -1); + + /* FORE is for the selected item */ + init_pair(MAIN_MENU_FORE, -1, -1); + /* BACK for all the rest */ + init_pair(MAIN_MENU_BACK, -1, -1); + init_pair(MAIN_MENU_GREY, -1, -1); + init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1); + init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1); + + init_pair(SCROLLWIN_TEXT, -1, -1); + init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1); + init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1); + + init_pair(DIALOG_TEXT, -1, -1); + init_pair(DIALOG_BOX, COLOR_YELLOW, -1); + init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1); + init_pair(DIALOG_MENU_FORE, COLOR_RED, -1); + + init_pair(INPUT_BOX, COLOR_YELLOW, -1); + init_pair(INPUT_HEADING, COLOR_GREEN, -1); + init_pair(INPUT_TEXT, -1, -1); + init_pair(INPUT_FIELD, -1, -1); + + init_pair(FUNCTION_HIGHLIGHT, -1, -1); + init_pair(FUNCTION_TEXT, COLOR_BLUE, -1); +} + +/* available attributes: + A_NORMAL Normal display (no highlight) + A_STANDOUT Best highlighting mode of the terminal. + A_UNDERLINE Underlining + A_REVERSE Reverse video + A_BLINK Blinking + A_DIM Half bright + A_BOLD Extra bright or bold + A_PROTECT Protected mode + A_INVIS Invisible or blank mode + A_ALTCHARSET Alternate character set + A_CHARTEXT Bit-mask to extract a character + COLOR_PAIR(n) Color-pair number n + */ +static void normal_color_theme(void) +{ + /* automatically add color... */ +#define mkattr(name, attr) do { \ +attributes[name] = attr | COLOR_PAIR(name); } while (0) + mkattr(NORMAL, NORMAL); + mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE); + + mkattr(MAIN_MENU_FORE, A_REVERSE); + mkattr(MAIN_MENU_BACK, A_NORMAL); + mkattr(MAIN_MENU_GREY, A_NORMAL); + mkattr(MAIN_MENU_HEADING, A_BOLD); + mkattr(MAIN_MENU_BOX, A_NORMAL); + + mkattr(SCROLLWIN_TEXT, A_NORMAL); + mkattr(SCROLLWIN_HEADING, A_BOLD); + mkattr(SCROLLWIN_BOX, A_BOLD); + + mkattr(DIALOG_TEXT, A_BOLD); + mkattr(DIALOG_BOX, A_BOLD); + mkattr(DIALOG_MENU_FORE, A_STANDOUT); + mkattr(DIALOG_MENU_BACK, A_NORMAL); + + mkattr(INPUT_BOX, A_NORMAL); + mkattr(INPUT_HEADING, A_BOLD); + mkattr(INPUT_TEXT, A_NORMAL); + mkattr(INPUT_FIELD, A_UNDERLINE); + + mkattr(FUNCTION_HIGHLIGHT, A_BOLD); + mkattr(FUNCTION_TEXT, A_REVERSE); +} + +static void no_colors_theme(void) +{ + /* automatically add highlight, no color */ +#define mkattrn(name, attr) { attributes[name] = attr; } + + mkattrn(NORMAL, NORMAL); + mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE); + + mkattrn(MAIN_MENU_FORE, A_STANDOUT); + mkattrn(MAIN_MENU_BACK, A_NORMAL); + mkattrn(MAIN_MENU_GREY, A_NORMAL); + mkattrn(MAIN_MENU_HEADING, A_BOLD); + mkattrn(MAIN_MENU_BOX, A_NORMAL); + + mkattrn(SCROLLWIN_TEXT, A_NORMAL); + mkattrn(SCROLLWIN_HEADING, A_BOLD); + mkattrn(SCROLLWIN_BOX, A_BOLD); + + mkattrn(DIALOG_TEXT, A_NORMAL); + mkattrn(DIALOG_BOX, A_BOLD); + mkattrn(DIALOG_MENU_FORE, A_STANDOUT); + mkattrn(DIALOG_MENU_BACK, A_NORMAL); + + mkattrn(INPUT_BOX, A_BOLD); + mkattrn(INPUT_HEADING, A_BOLD); + mkattrn(INPUT_TEXT, A_NORMAL); + mkattrn(INPUT_FIELD, A_UNDERLINE); + + mkattrn(FUNCTION_HIGHLIGHT, A_BOLD); + mkattrn(FUNCTION_TEXT, A_REVERSE); +} + +void set_colors() +{ + start_color(); + use_default_colors(); + set_normal_colors(); + if (has_colors()) { + normal_color_theme(); + } else { + /* give deafults */ + no_colors_theme(); + } +} + + +/* this changes the windows attributes !!! */ +void print_in_middle(WINDOW *win, + int starty, + int startx, + int width, + const char *string, + chtype color) +{ int length, x, y; + float temp; + + + if (win == NULL) + win = stdscr; + getyx(win, y, x); + if (startx != 0) + x = startx; + if (starty != 0) + y = starty; + if (width == 0) + width = 80; + + length = strlen(string); + temp = (width - length) / 2; + x = startx + (int)temp; + wattrset(win, color); + mvwprintw(win, y, x, "%s", string); + refresh(); +} + +int get_line_no(const char *text) +{ + int i; + int total = 1; + + if (!text) + return 0; + + for (i = 0; text[i] != '\0'; i++) + if (text[i] == '\n') + total++; + return total; +} + +const char *get_line(const char *text, int line_no) +{ + int i; + int lines = 0; + + if (!text) + return 0; + + for (i = 0; text[i] != '\0' && lines < line_no; i++) + if (text[i] == '\n') + lines++; + return text+i; +} + +int get_line_length(const char *line) +{ + int res = 0; + while (*line != '\0' && *line != '\n') { + line++; + res++; + } + return res; +} + +/* print all lines to the window. */ +void fill_window(WINDOW *win, const char *text) +{ + int x, y; + int total_lines = get_line_no(text); + int i; + + getmaxyx(win, y, x); + /* do not go over end of line */ + total_lines = min(total_lines, y); + for (i = 0; i < total_lines; i++) { + char tmp[x+10]; + const char *line = get_line(text, i); + int len = get_line_length(line); + strncpy(tmp, line, min(len, x)); + tmp[len] = '\0'; + mvwprintw(win, i, 0, "%s", tmp); + } +} + +/* get the message, and buttons. + * each button must be a char* + * return the selected button + * + * this dialog is used for 2 different things: + * 1) show a text box, no buttons. + * 2) show a dialog, with horizontal buttons + */ +int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) +{ + va_list ap; + char *btn; + int btns_width = 0; + int msg_lines = 0; + int msg_width = 0; + int total_width; + int win_rows = 0; + WINDOW *win; + WINDOW *msg_win; + WINDOW *menu_win; + MENU *menu; + ITEM *btns[btn_num+1]; + int i, x, y; + int res = -1; + + + va_start(ap, btn_num); + for (i = 0; i < btn_num; i++) { + btn = va_arg(ap, char *); + btns[i] = new_item(btn, ""); + btns_width += strlen(btn)+1; + } + va_end(ap); + btns[btn_num] = NULL; + + /* find the widest line of msg: */ + msg_lines = get_line_no(msg); + for (i = 0; i < msg_lines; i++) { + const char *line = get_line(msg, i); + int len = get_line_length(line); + if (msg_width < len) + msg_width = len; + } + + total_width = max(msg_width, btns_width); + /* place dialog in middle of screen */ + y = (LINES-(msg_lines+4))/2; + x = (COLS-(total_width+4))/2; + + + /* create the windows */ + if (btn_num > 0) + win_rows = msg_lines+4; + else + win_rows = msg_lines+2; + + win = newwin(win_rows, total_width+4, y, x); + keypad(win, TRUE); + menu_win = derwin(win, 1, btns_width, win_rows-2, + 1+(total_width+2-btns_width)/2); + menu = new_menu(btns); + msg_win = derwin(win, win_rows-2, msg_width, 1, + 1+(total_width+2-msg_width)/2); + + set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); + set_menu_back(menu, attributes[DIALOG_MENU_BACK]); + + wattrset(win, attributes[DIALOG_BOX]); + box(win, 0, 0); + + /* print message */ + wattrset(msg_win, attributes[DIALOG_TEXT]); + fill_window(msg_win, msg); + + set_menu_win(menu, win); + set_menu_sub(menu, menu_win); + set_menu_format(menu, 1, btn_num); + menu_opts_off(menu, O_SHOWDESC); + menu_opts_off(menu, O_SHOWMATCH); + menu_opts_on(menu, O_ONEVALUE); + menu_opts_on(menu, O_NONCYCLIC); + set_menu_mark(menu, ""); + post_menu(menu); + + + touchwin(win); + refresh_all_windows(main_window); + while ((res = wgetch(win))) { + switch (res) { + case KEY_LEFT: + menu_driver(menu, REQ_LEFT_ITEM); + break; + case KEY_RIGHT: + menu_driver(menu, REQ_RIGHT_ITEM); + break; + case 10: /* ENTER */ + case 27: /* ESCAPE */ + case ' ': + case KEY_F(F_BACK): + case KEY_F(F_EXIT): + break; + } + touchwin(win); + refresh_all_windows(main_window); + + if (res == 10 || res == ' ') { + res = item_index(current_item(menu)); + break; + } else if (res == 27 || res == KEY_F(F_BACK) || + res == KEY_F(F_EXIT)) { + res = KEY_EXIT; + break; + } + } + + unpost_menu(menu); + free_menu(menu); + for (i = 0; i < btn_num; i++) + free_item(btns[i]); + + delwin(win); + return res; +} + +int dialog_inputbox(WINDOW *main_window, + const char *title, const char *prompt, + const char *init, char *result, int result_len) +{ + int prompt_lines = 0; + int prompt_width = 0; + WINDOW *win; + WINDOW *prompt_win; + WINDOW *form_win; + PANEL *panel; + int i, x, y; + int res = -1; + int cursor_position = strlen(init); + + + /* find the widest line of msg: */ + prompt_lines = get_line_no(prompt); + for (i = 0; i < prompt_lines; i++) { + const char *line = get_line(prompt, i); + int len = get_line_length(line); + prompt_width = max(prompt_width, len); + } + + if (title) + prompt_width = max(prompt_width, strlen(title)); + + /* place dialog in middle of screen */ + y = (LINES-(prompt_lines+4))/2; + x = (COLS-(prompt_width+4))/2; + + strncpy(result, init, result_len); + + /* create the windows */ + win = newwin(prompt_lines+6, prompt_width+7, y, x); + prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); + form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); + keypad(form_win, TRUE); + + wattrset(form_win, attributes[INPUT_FIELD]); + + wattrset(win, attributes[INPUT_BOX]); + box(win, 0, 0); + wattrset(win, attributes[INPUT_HEADING]); + if (title) + mvwprintw(win, 0, 3, "%s", title); + + /* print message */ + wattrset(prompt_win, attributes[INPUT_TEXT]); + fill_window(prompt_win, prompt); + + mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); + mvwprintw(form_win, 0, 0, "%s", result); + + /* create panels */ + panel = new_panel(win); + + /* show the cursor */ + curs_set(1); + + touchwin(win); + refresh_all_windows(main_window); + while ((res = wgetch(form_win))) { + int len = strlen(result); + switch (res) { + case 10: /* ENTER */ + case 27: /* ESCAPE */ + case KEY_F(F_HELP): + case KEY_F(F_EXIT): + case KEY_F(F_BACK): + break; + case 127: + case KEY_BACKSPACE: + if (cursor_position > 0) { + memmove(&result[cursor_position-1], + &result[cursor_position], + len-cursor_position+1); + cursor_position--; + } + break; + case KEY_DC: + if (cursor_position >= 0 && cursor_position < len) { + memmove(&result[cursor_position], + &result[cursor_position+1], + len-cursor_position+1); + } + break; + case KEY_UP: + case KEY_RIGHT: + if (cursor_position < len && + cursor_position < min(result_len, prompt_width)) + cursor_position++; + break; + case KEY_DOWN: + case KEY_LEFT: + if (cursor_position > 0) + cursor_position--; + break; + default: + if ((isgraph(res) || isspace(res)) && + len-2 < result_len) { + /* insert the char at the proper position */ + memmove(&result[cursor_position+1], + &result[cursor_position], + len+1); + result[cursor_position] = res; + cursor_position++; + } else { + mvprintw(0, 0, "unknow key: %d\n", res); + } + break; + } + wmove(form_win, 0, 0); + wclrtoeol(form_win); + mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); + mvwprintw(form_win, 0, 0, "%s", result); + wmove(form_win, 0, cursor_position); + touchwin(win); + refresh_all_windows(main_window); + + if (res == 10) { + res = 0; + break; + } else if (res == 27 || res == KEY_F(F_BACK) || + res == KEY_F(F_EXIT)) { + res = KEY_EXIT; + break; + } else if (res == KEY_F(F_HELP)) { + res = 1; + break; + } + } + + /* hide the cursor */ + curs_set(0); + del_panel(panel); + delwin(prompt_win); + delwin(form_win); + delwin(win); + return res; +} + +/* refresh all windows in the correct order */ +void refresh_all_windows(WINDOW *main_window) +{ + update_panels(); + touchwin(main_window); + refresh(); +} + +/* layman's scrollable window... */ +void show_scroll_win(WINDOW *main_window, + const char *title, + const char *text) +{ + int res; + int total_lines = get_line_no(text); + int x, y; + int start_x = 0, start_y = 0; + int text_lines = 0, text_cols = 0; + int total_cols = 0; + int win_cols = 0; + int win_lines = 0; + int i = 0; + WINDOW *win; + WINDOW *pad; + PANEL *panel; + + /* find the widest line of msg: */ + total_lines = get_line_no(text); + for (i = 0; i < total_lines; i++) { + const char *line = get_line(text, i); + int len = get_line_length(line); + total_cols = max(total_cols, len+2); + } + + /* create the pad */ + pad = newpad(total_lines+10, total_cols+10); + wattrset(pad, attributes[SCROLLWIN_TEXT]); + fill_window(pad, text); + + win_lines = min(total_lines+4, LINES-2); + win_cols = min(total_cols+2, COLS-2); + text_lines = max(win_lines-4, 0); + text_cols = max(win_cols-2, 0); + + /* place window in middle of screen */ + y = (LINES-win_lines)/2; + x = (COLS-win_cols)/2; + + win = newwin(win_lines, win_cols, y, x); + keypad(win, TRUE); + /* show the help in the help window, and show the help panel */ + wattrset(win, attributes[SCROLLWIN_BOX]); + box(win, 0, 0); + wattrset(win, attributes[SCROLLWIN_HEADING]); + mvwprintw(win, 0, 3, " %s ", title); + panel = new_panel(win); + + /* handle scrolling */ + do { + + copywin(pad, win, start_y, start_x, 2, 2, text_lines, + text_cols, 0); + print_in_middle(win, + text_lines+2, + 0, + text_cols, + "<OK>", + attributes[DIALOG_MENU_FORE]); + wrefresh(win); + + res = wgetch(win); + switch (res) { + case KEY_NPAGE: + case ' ': + start_y += text_lines-2; + break; + case KEY_PPAGE: + start_y -= text_lines+2; + break; + case KEY_HOME: + start_y = 0; + break; + case KEY_END: + start_y = total_lines-text_lines; + break; + case KEY_DOWN: + case 'j': + start_y++; + break; + case KEY_UP: + case 'k': + start_y--; + break; + case KEY_LEFT: + case 'h': + start_x--; + break; + case KEY_RIGHT: + case 'l': + start_x++; + break; + } + if (res == 10 || res == 27 || res == 'q' + || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { + break; + } + if (start_y < 0) + start_y = 0; + if (start_y >= total_lines-text_lines) + start_y = total_lines-text_lines; + if (start_x < 0) + start_x = 0; + if (start_x >= total_cols-text_cols) + start_x = total_cols-text_cols; + } while (res); + + del_panel(panel); + delwin(win); + refresh_all_windows(main_window); +} diff --git a/package/config/nconf.h b/package/config/nconf.h new file mode 100644 index 000000000..fb4296666 --- /dev/null +++ b/package/config/nconf.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? + * Released under the terms of the GNU GPL v2.0. + * + * Derived from menuconfig. + * + */ + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <locale.h> +#include <curses.h> +#include <menu.h> +#include <panel.h> +#include <form.h> + +#include <stdio.h> +#include <time.h> +#include <sys/time.h> + +#include "ncurses.h" + +#define max(a, b) ({\ + typeof(a) _a = a;\ + typeof(b) _b = b;\ + _a > _b ? _a : _b; }) + +#define min(a, b) ({\ + typeof(a) _a = a;\ + typeof(b) _b = b;\ + _a < _b ? _a : _b; }) + +typedef enum { + NORMAL = 1, + MAIN_HEADING, + MAIN_MENU_BOX, + MAIN_MENU_FORE, + MAIN_MENU_BACK, + MAIN_MENU_GREY, + MAIN_MENU_HEADING, + SCROLLWIN_TEXT, + SCROLLWIN_HEADING, + SCROLLWIN_BOX, + DIALOG_TEXT, + DIALOG_MENU_FORE, + DIALOG_MENU_BACK, + DIALOG_BOX, + INPUT_BOX, + INPUT_HEADING, + INPUT_TEXT, + INPUT_FIELD, + FUNCTION_TEXT, + FUNCTION_HIGHLIGHT, + ATTR_MAX +} attributes_t; +extern attributes_t attributes[]; + +typedef enum { + F_HELP = 1, + F_SYMBOL = 2, + F_INSTS = 3, + F_CONF = 4, + F_BACK = 5, + F_SAVE = 6, + F_LOAD = 7, + F_EXIT = 8 +} function_key; + +void set_colors(void); + +/* this changes the windows attributes !!! */ +void print_in_middle(WINDOW *win, + int starty, + int startx, + int width, + const char *string, + chtype color); +int get_line_length(const char *line); +int get_line_no(const char *text); +const char *get_line(const char *text, int line_no); +void fill_window(WINDOW *win, const char *text); +int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...); +int dialog_inputbox(WINDOW *main_window, + const char *title, const char *prompt, + const char *init, char *result, int result_len); +void refresh_all_windows(WINDOW *main_window); +void show_scroll_win(WINDOW *main_window, + const char *title, + const char *text); diff --git a/package/config/patches/01-kconfig-kernel-to-buildroot.patch b/package/config/patches/01-kconfig-kernel-to-buildroot.patch new file mode 100644 index 000000000..4e4354a0c --- /dev/null +++ b/package/config/patches/01-kconfig-kernel-to-buildroot.patch @@ -0,0 +1,298 @@ +--- + conf.c | 12 ++++++------ + confdata.c | 12 ++++-------- + gconf.c | 4 ++-- + gconf.glade | 2 +- + mconf.c | 35 +++++++++++++++++------------------ + qconf.cc | 4 ++-- + zconf.tab.c_shipped | 2 +- + zconf.y | 2 +- + 8 files changed, 34 insertions(+), 39 deletions(-) + +Index: config.new/conf.c +=================================================================== +--- config.new.orig/conf.c ++++ config.new/conf.c +@@ -508,8 +508,8 @@ + name = conf_get_configname(); + if (stat(name, &tmpstat)) { + fprintf(stderr, _("***\n" +- "*** You have not yet configured your kernel!\n" +- "*** (missing kernel config file \"%s\")\n" ++ "*** You have not yet configured your Buildroot!\n" ++ "*** (missing .config file \"%s\")\n" + "***\n" + "*** Please run some configurator (e.g. \"make oldconfig\" or\n" + "*** \"make menuconfig\" or \"make xconfig\").\n" +@@ -571,7 +571,7 @@ + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, +- _("\n*** Kernel configuration requires explicit update.\n\n")); ++ _("\n*** Buildroot configuration requires explicit update.\n\n")); + return 1; + } + } +@@ -623,11 +623,11 @@ + * All other commands are only used to generate a config. + */ + if (conf_get_changed() && conf_write(NULL)) { +- fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); ++ fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n")); + exit(1); + } + if (conf_write_autoconf()) { +- fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); ++ fprintf(stderr, _("\n*** Error during update of the Buildroot configuration.\n\n")); + return 1; + } + } else if (input_mode == savedefconfig) { +@@ -638,7 +638,7 @@ + } + } else if (input_mode != listnewconfig) { + if (conf_write(NULL)) { +- fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); ++ fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n")); + exit(1); + } + } +Index: config.new/confdata.c +=================================================================== +--- config.new.orig/confdata.c ++++ config.new/confdata.c +@@ -579,7 +579,7 @@ + if (!out) + return 1; + +- sym = sym_lookup("KERNELVERSION", 0); ++ sym = sym_lookup("BR2_VERSION", 0); + sym_calc_value(sym); + time(&now); + env = getenv("KCONFIG_NOTIMESTAMP"); +@@ -588,10 +588,8 @@ + + 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) : ""); + +@@ -802,25 +800,23 @@ + return 1; + } + +- sym = sym_lookup("KERNELVERSION", 0); ++ sym = sym_lookup("BR2_VERSION", 0); + sym_calc_value(sym); + time(&now); + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" +- "# Linux kernel version: %s\n" + "# %s" + "#\n", +- sym_get_string_value(sym), ctime(&now)); ++ ctime(&now)); + fprintf(tristate, "#\n" + "# Automatically generated - do not edit\n" + "\n"); + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" +- " * Linux kernel version: %s\n" + " * %s" + " */\n" + "#define AUTOCONF_INCLUDED\n", +- sym_get_string_value(sym), ctime(&now)); ++ ctime(&now)); + + for_all_symbols(i, sym) { + sym_calc_value(sym); +Index: config.new/gconf.c +=================================================================== +--- config.new.orig/gconf.c ++++ config.new/gconf.c +@@ -210,8 +210,8 @@ + /*"style", PANGO_STYLE_OBLIQUE, */ + NULL); + +- sprintf(title, _("Linux Kernel v%s Configuration"), +- getenv("KERNELVERSION")); ++ sprintf(title, _("Buildroot v%s Configuration"), ++ getenv("BR2_VERSION")); + gtk_window_set_title(GTK_WINDOW(main_wnd), title); + + gtk_widget_show(main_wnd); +Index: config.new/gconf.glade +=================================================================== +--- config.new.orig/gconf.glade ++++ config.new/gconf.glade +@@ -5,7 +5,7 @@ + + <widget class="GtkWindow" id="window1"> + <property name="visible">True</property> +- <property name="title" translatable="yes">Gtk Kernel Configurator</property> ++ <property name="title" translatable="yes">Gtk Buildroot Configurator</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> +Index: config.new/mconf.c +=================================================================== +--- config.new.orig/mconf.c ++++ config.new/mconf.c +@@ -25,10 +25,9 @@ + static const char mconf_readme[] = N_( + "Overview\n" + "--------\n" +-"Some kernel features may be built directly into the kernel.\n" +-"Some may be made into loadable runtime modules. Some features\n" ++"Some features may be built directly into Buildroot. Some features\n" + "may be completely removed altogether. There are also certain\n" +-"kernel parameters which are not really features, but must be\n" ++"parameters which are not really features, but must be\n" + "entered in as decimal or hexadecimal numbers or possibly text.\n" + "\n" + "Menu items beginning with following braces represent features that\n" +@@ -117,7 +116,7 @@ + "-----------------------------\n" + "Menuconfig supports the use of alternate configuration files for\n" + "those who, for various reasons, find it necessary to switch\n" +-"between different kernel configurations.\n" ++"between different configurations.\n" + "\n" + "At the end of the main menu you will find two options. One is\n" + "for saving the current configuration to a file of your choosing.\n" +@@ -150,7 +149,7 @@ + "\n" + "Optional personality available\n" + "------------------------------\n" +-"If you prefer to have all of the kernel options listed in a single\n" ++"If you prefer to have all of the options listed in a single\n" + "menu, rather than the default multimenu hierarchy, run the menuconfig\n" + "with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" + "\n" +@@ -180,9 +179,9 @@ + "Arrow keys navigate the menu. " + "<Enter> selects submenus --->. " + "Highlighted letters are hotkeys. " +- "Pressing <Y> includes, <N> excludes, <M> modularizes features. " ++ "Pressing <Y> selectes a feature, while <N> will exclude a feature. " + "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " +- "Legend: [*] built-in [ ] excluded <M> module < > module capable"), ++ "Legend: [*] feature is selected [ ] feature is excluded"), + radiolist_instructions[] = N_( + "Use the arrow keys to navigate this window or " + "press the hotkey of the item you wish to select " +@@ -207,11 +206,11 @@ + "last retrieved. Leave blank to abort."), + load_config_help[] = N_( + "\n" +- "For various reasons, one may wish to keep several different kernel\n" ++ "For various reasons, one may wish to keep several different Buildroot\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" ++ "Buildroot'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" +@@ -221,7 +220,7 @@ + "as an alternate. Leave blank to abort."), + save_config_help[] = N_( + "\n" +- "For various reasons, one may wish to keep different kernel\n" ++ "For various reasons, one may wish to keep different Buildroot\n" + "configurations available on a single machine.\n" + "\n" + "Entering a file name here will allow you to later retrieve, modify\n" +@@ -292,10 +291,10 @@ + int size; + struct symbol *sym; + +- sym = sym_lookup("KERNELVERSION", 0); ++ sym = sym_lookup("BR2_VERSION", 0); + sym_calc_value(sym); + size = snprintf(menu_backtitle, sizeof(menu_backtitle), +- _("%s - Linux Kernel v%s Configuration"), ++ _("%s - buildroot v%s Configuration"), + config_filename, sym_get_string_value(sym)); + if (size >= sizeof(menu_backtitle)) + menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; +@@ -834,7 +833,7 @@ + if (conf_get_changed()) + res = dialog_yesno(NULL, + _("Do you wish to save your " +- "new kernel configuration?\n" ++ "new Buildroot configuration?\n" + "<ESC><ESC> to continue."), + 6, 60); + else +@@ -846,20 +845,20 @@ + case 0: + if (conf_write(filename)) { + fprintf(stderr, _("\n\n" +- "Error during writing of the kernel configuration.\n" +- "Your kernel configuration changes were NOT saved." ++ "Error during writing of the Buildroot configuration.\n" ++ "Your Buildroot configuration changes were NOT saved." + "\n\n")); + return 1; + } + case -1: + printf(_("\n\n" +- "*** End of Linux kernel configuration.\n" +- "*** Execute 'make' to build the kernel or try 'make help'." ++ "*** End of Buildroot configuration.\n" ++ "*** Execute 'make' to build Buildroot or try 'make help'." + "\n\n")); + break; + default: + fprintf(stderr, _("\n\n" +- "Your kernel configuration changes were NOT saved." ++ "Your Buildroot configuration changes were NOT saved." + "\n\n")); + } + +Index: config.new/qconf.cc +=================================================================== +--- config.new.orig/qconf.cc ++++ config.new/qconf.cc +@@ -1263,8 +1263,8 @@ + char title[256]; + + QDesktopWidget *d = configApp->desktop(); +- snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"), +- getenv("KERNELVERSION")); ++ snprintf(title, sizeof(title), _("Buildroot v%s Configuration"), ++ getenv("BR2_VERSION")); + setCaption(title); + + width = configSettings->readNumEntry("/window width", d->width() - 64); +Index: config.new/zconf.tab.c_shipped +=================================================================== +--- config.new.orig/zconf.tab.c_shipped ++++ config.new/zconf.tab.c_shipped +@@ -2224,7 +2224,7 @@ + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; +- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); ++ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL); + + #if YYDEBUG + if (getenv("ZCONF_DEBUG")) +Index: config.new/zconf.y +=================================================================== +--- config.new.orig/zconf.y ++++ config.new/zconf.y +@@ -479,7 +479,7 @@ + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; +- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); ++ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL); + + #if YYDEBUG + if (getenv("ZCONF_DEBUG")) diff --git a/package/config/patches/02-cpp-comments-to-c-comments.patch b/package/config/patches/02-cpp-comments-to-c-comments.patch new file mode 100644 index 000000000..a801319e3 --- /dev/null +++ b/package/config/patches/02-cpp-comments-to-c-comments.patch @@ -0,0 +1,178 @@ +--- + expr.c | 42 +++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +Index: config.clean/expr.c +=================================================================== +--- config.clean.orig/expr.c ++++ config.clean/expr.c +@@ -331,7 +331,7 @@ + e->right.expr = expr_trans_bool(e->right.expr); + break; + case E_UNEQUAL: +- // FOO!=n -> FOO ++ /* FOO!=n -> FOO */ + if (e->left.sym->type == S_TRISTATE) { + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; +@@ -380,19 +380,19 @@ + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { +- // (a='y') || (a='m') -> (a!='n') ++ /* (a='y') || (a='m') -> (a!='n') */ + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { +- // (a='y') || (a='n') -> (a!='m') ++ /* (a='y') || (a='n') -> (a!='m') */ + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { +- // (a='m') || (a='n') -> (a!='y') ++ /* (a='m') || (a='n') -> (a!='y') */ + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); + } + } +@@ -443,29 +443,29 @@ + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) +- // (a) && (a='y') -> (a='y') ++ /* (a) && (a='y') -> (a='y') */ + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) +- // (a) && (a!='n') -> (a) ++ /* (a) && (a!='n') -> (a) */ + return expr_alloc_symbol(sym1); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) +- // (a) && (a!='m') -> (a='y') ++ /* (a) && (a!='m') -> (a='y') */ + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { +- // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' ++ /* (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' */ + sym2 = e1->right.sym; + if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { +- // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' ++ /* (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' */ + sym2 = e2->right.sym; + if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) +@@ -474,19 +474,19 @@ + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) +- // (a!='y') && (a!='n') -> (a='m') ++ /* (a!='y') && (a!='n') -> (a='m') */ + return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) +- // (a!='y') && (a!='m') -> (a='n') ++ /* (a!='y') && (a!='m') -> (a='n') */ + return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) +- // (a!='m') && (a!='n') -> (a='m') ++ /* (a!='m') && (a!='n') -> (a='m') */ + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || +@@ -579,7 +579,7 @@ + switch (e1->type) { + case E_OR: + expr_eliminate_dups2(e1->type, &e1, &e1); +- // (FOO || BAR) && (!FOO && !BAR) -> n ++ /* (FOO || BAR) && (!FOO && !BAR) -> n */ + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_and(&tmp1, &tmp2); +@@ -594,7 +594,7 @@ + break; + case E_AND: + expr_eliminate_dups2(e1->type, &e1, &e1); +- // (FOO && BAR) || (!FOO || !BAR) -> y ++ /* (FOO && BAR) || (!FOO || !BAR) -> y */ + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_or(&tmp1, &tmp2); +@@ -703,7 +703,7 @@ + case E_NOT: + switch (e->left.expr->type) { + case E_NOT: +- // !!a -> a ++ /* !!a -> a */ + tmp = e->left.expr->left.expr; + free(e->left.expr); + free(e); +@@ -712,14 +712,14 @@ + break; + case E_EQUAL: + case E_UNEQUAL: +- // !a='x' -> a!='x' ++ /* !a='x' -> a!='x' */ + tmp = e->left.expr; + free(e); + e = tmp; + e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; + break; + case E_OR: +- // !(a || b) -> !a && !b ++ /* !(a || b) -> !a && !b */ + tmp = e->left.expr; + e->type = E_AND; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); +@@ -728,7 +728,7 @@ + e = expr_transform(e); + break; + case E_AND: +- // !(a && b) -> !a || !b ++ /* !(a && b) -> !a || !b */ + tmp = e->left.expr; + e->type = E_OR; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); +@@ -738,7 +738,7 @@ + break; + case E_SYMBOL: + if (e->left.expr->left.sym == &symbol_yes) { +- // !'y' -> 'n' ++ /* !'y' -> 'n' */ + tmp = e->left.expr; + free(e); + e = tmp; +@@ -747,7 +747,7 @@ + break; + } + if (e->left.expr->left.sym == &symbol_mod) { +- // !'m' -> 'm' ++ /* !'m' -> 'm' */ + tmp = e->left.expr; + free(e); + e = tmp; +@@ -756,7 +756,7 @@ + break; + } + if (e->left.expr->left.sym == &symbol_no) { +- // !'n' -> 'y' ++ /* !'n' -> 'y' */ + tmp = e->left.expr; + free(e); + e = tmp; diff --git a/package/config/patches/03-change-config-option-prefix.patch b/package/config/patches/03-change-config-option-prefix.patch new file mode 100644 index 000000000..5b76df33e --- /dev/null +++ b/package/config/patches/03-change-config-option-prefix.patch @@ -0,0 +1,164 @@ +--- + confdata.c | 49 +++++++++++++++++++++++-------------------------- + 1 file changed, 23 insertions(+), 26 deletions(-) + +Index: config.new/confdata.c +=================================================================== +--- config.new.orig/confdata.c ++++ config.new/confdata.c +@@ -11,6 +11,7 @@ + #include <string.h> + #include <time.h> + #include <unistd.h> ++#include <libgen.h> + + #define LKC_DIRECT_LINK + #include "lkc.h" +@@ -21,7 +22,7 @@ + static const char *conf_filename; + static int conf_lineno, conf_warnings, conf_unsaved; + +-const char conf_defname[] = "arch/$ARCH/defconfig"; ++const char conf_defname[] = ".defconfig"; + + static void conf_warning(const char *fmt, ...) + { +@@ -36,7 +37,7 @@ + + const char *conf_get_configname(void) + { +- char *name = getenv("KCONFIG_CONFIG"); ++ char *name = getenv("BUILDROOT_CONFIG"); + + return name ? name : ".config"; + } +@@ -222,22 +223,22 @@ + sym = NULL; + switch (line[0]) { + case '#': +- if (memcmp(line + 2, "CONFIG_", 7)) ++ if (line[1]!=' ') + continue; +- p = strchr(line + 9, ' '); ++ p = strchr(line + 2, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + if (def == S_DEF_USER) { +- sym = sym_find(line + 9); ++ sym = sym_find(line + 2); + if (!sym) { + sym_add_change_count(1); + break; + } + } else { +- sym = sym_lookup(line + 9, 0); ++ sym = sym_lookup(line + 2, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_BOOLEAN; + } +@@ -254,12 +255,8 @@ + ; + } + break; +- case 'C': +- if (memcmp(line, "CONFIG_", 7)) { +- conf_warning("unexpected data"); +- continue; +- } +- p = strchr(line + 7, '='); ++ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': ++ p = strchr(line, '='); + if (!p) + continue; + *p++ = 0; +@@ -270,13 +267,13 @@ + *p2 = 0; + } + if (def == S_DEF_USER) { +- sym = sym_find(line + 7); ++ sym = sym_find(line); + if (!sym) { + sym_add_change_count(1); + break; + } + } else { +- sym = sym_lookup(line + 7, 0); ++ sym = sym_lookup(line, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_OTHER; + } +@@ -405,9 +402,9 @@ + { + int l; + if (headerfile) +- fprintf(out, "#define CONFIG_%s \"", name); ++ fprintf(out, "#define %s \"", name); + else +- fprintf(out, "CONFIG_%s=\"", name); ++ fprintf(out, "%s=\"", name); + + while (1) { + l = strcspn(str, "\"\\"); +@@ -433,13 +430,13 @@ + switch (sym_get_tristate_value(sym)) { + case no: + if (write_no) +- fprintf(out, "# CONFIG_%s is not set\n", sym->name); ++ fprintf(out, "# %s is not set\n", sym->name); + break; + case mod: +- fprintf(out, "CONFIG_%s=m\n", sym->name); ++ fprintf(out, "%s=m\n", sym->name); + break; + case yes: +- fprintf(out, "CONFIG_%s=y\n", sym->name); ++ fprintf(out, "%s=y\n", sym->name); + break; + } + break; +@@ -449,7 +446,7 @@ + case S_HEX: + case S_INT: + str = sym_get_string_value(sym); +- fprintf(out, "CONFIG_%s=%s\n", sym->name, str); ++ fprintf(out, "%s=%s\n", sym->name, str); + break; + case S_OTHER: + case S_UNKNOWN: +@@ -834,14 +831,14 @@ + case no: + break; + case mod: +- fprintf(tristate, "CONFIG_%s=M\n", sym->name); +- fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); ++ fprintf(tristate, "%s=M\n", sym->name); ++ fprintf(out_h, "#define %s_MODULE 1\n", sym->name); + break; + case yes: + if (sym->type == S_TRISTATE) +- fprintf(tristate, "CONFIG_%s=Y\n", ++ fprintf(tristate, "%s=Y\n", + sym->name); +- fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); ++ fprintf(out_h, "#define %s 1\n", sym->name); + break; + } + break; +@@ -851,12 +848,12 @@ + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { +- fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); ++ fprintf(out_h, "#define %s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); +- fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); ++ fprintf(out_h, "#define %s %s\n", sym->name, str); + break; + default: + break; diff --git a/package/config/patches/05-really-clean-everything.patch b/package/config/patches/05-really-clean-everything.patch new file mode 100644 index 000000000..f8d8a39d2 --- /dev/null +++ b/package/config/patches/05-really-clean-everything.patch @@ -0,0 +1,29 @@ +--- + Makefile | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +Index: config.new/Makefile +=================================================================== +--- config.new.orig/Makefile ++++ config.new/Makefile +@@ -199,10 +199,16 @@ + 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 lex.zconf.c zconf.hash.c gconf.glade.h +-clean-files += mconf qconf gconf nconf +-clean-files += config.pot linux.pot ++clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ ++ .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h ++clean-files += config.pot linux.pot ++clean-files += conf $(conf-objs) ++clean-files += mconf $(mconf-objs) ++clean-files += nconf $(nconf-objs) ++clean-files += qconf qconf.o ++clean-files += gconf gconf.o ++clean-files += kconfig_load.o zconf.tab.o ++clean-files += $(kxgettext-objs) + + # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) + PHONY += $(obj)/dochecklxdialog diff --git a/package/config/patches/06-br-build-system-integration.patch b/package/config/patches/06-br-build-system-integration.patch new file mode 100644 index 000000000..128bbc02c --- /dev/null +++ b/package/config/patches/06-br-build-system-integration.patch @@ -0,0 +1,40 @@ +--- + Makefile | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +Index: config/Makefile +=================================================================== +--- config.orig/Makefile ++++ config/Makefile +@@ -177,18 +177,30 @@ + ifeq ($(MAKECMDGOALS),nconfig) + hostprogs-y += nconf + endif ++ifeq ($(findstring nconf,$(MAKECMDGOALS)),nconf) ++ hostprogs-y += nconf ++endif + + ifeq ($(MAKECMDGOALS),menuconfig) + hostprogs-y += mconf + endif ++ifeq ($(findstring mconf,$(MAKECMDGOALS)),mconf) ++ hostprogs-y += mconf ++endif + + ifeq ($(MAKECMDGOALS),xconfig) + qconf-target := 1 + endif ++ifeq ($(findstring qconf,$(MAKECMDGOALS)),qconf) ++ qconf-target := 1 ++endif ++ + ifeq ($(MAKECMDGOALS),gconfig) + gconf-target := 1 + endif +- ++ifeq ($(findstring gconf,$(MAKECMDGOALS)),gconf) ++ gconf-target := 1 ++endif + + ifeq ($(qconf-target),1) + qconf-cxxobjs := qconf.o diff --git a/package/config/patches/08-make-write-deps.patch b/package/config/patches/08-make-write-deps.patch new file mode 100644 index 000000000..b10413485 --- /dev/null +++ b/package/config/patches/08-make-write-deps.patch @@ -0,0 +1,139 @@ +--- + util.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 116 insertions(+), 1 deletion(-) + +Index: config.clean/util.c +=================================================================== +--- config.clean.orig/util.c ++++ config.clean/util.c +@@ -26,6 +26,121 @@ + return file; + } + ++static char* br2_symbol_printer(const char * const in) ++{ ++ ssize_t i, j, len = strlen(in); ++ char *ret; ++ if (len < 1) ++ return NULL; ++ ret = malloc(len); ++ if (!ret) { ++ printf("Out of memory!"); ++ exit(1); ++ } ++ memset(ret, 0, len); ++ i = j = 0; ++ if (strncmp("BR2_", in, 4) == 0) ++ i += 4; ++ if (strncmp("PACKAGE_", in + i, 8) == 0) ++ i += 8; ++ else if (strncmp("TARGET_", in + i, 7) == 0) ++ i += 7; ++ while (i <= len) ++ ret[j++] = tolower(in[i++]); ++ return ret; ++} ++ ++/* write dependencies of the infividual config-symbols */ ++static int write_make_deps(const char *name) ++{ ++ char *str; ++ char dir[PATH_MAX+1], buf[PATH_MAX+1], buf2[PATH_MAX+1]; ++ struct menu *menu; ++ struct symbol *sym; ++ struct property *prop, *p; ++ unsigned done; ++ const char * const name_tmp = "..make.deps.tmp"; ++ FILE *out; ++ if (!name) ++ name = ".auto.deps"; ++ ++ strcpy(dir, conf_get_configname()); ++ str = strrchr(dir, '/'); ++ if (str) ++ str[1] = 0; ++ else ++ dir[0] = 0; ++ ++ sprintf(buf, "%s%s", dir, name_tmp); ++ out = fopen(buf, "w"); ++ if (!out) ++ return 1; ++ fprintf(out, "# ATTENTION! This does not handle 'depends', just 'select'! \n" ++ "# See package/config/util.c write_make_deps()\n#\n"); ++ menu = &rootmenu;//rootmenu.list; ++ while (menu) { ++ sym = menu->sym; ++ if (!sym) { ++ if (!menu_is_visible(menu)) ++ goto next; ++ } else if (!(sym->flags & SYMBOL_CHOICE)) { ++ sym_calc_value(sym); ++ if (sym->type == S_BOOLEAN ++ && sym_get_tristate_value(sym) != no) { ++ done = 0; ++ for_all_prompts(sym, prop) { ++ struct expr *e; ++//printf("\nname=%s\n", sym->name); ++ for_all_properties(sym, p, P_SELECT) { ++ e = p->expr; ++ if (e && e->left.sym->name) { ++ if (!done) { ++ fprintf(out, "%s: $(BASE_TARGETS)", br2_symbol_printer(sym->name)); ++ done = 1; ++ } ++//printf("SELECTS %s\n",e->left.sym->name); ++ fprintf(out, " %s",br2_symbol_printer(e->left.sym->name)); ++ } ++ } ++ if (done) ++ fprintf(out, "\n"); ++#if 0 ++ e = sym->rev_dep.expr; ++ if (e && e->type == E_SYMBOL ++ && e->left.sym->name) { ++ fprintf(out, "%s: %s", br2_symbol_printer(e->left.sym->name), ++ br2_symbol_printer(sym->name)); ++printf("%s is Selected BY: %s", sym->name, e->left.sym->name); ++ } ++#endif ++ } ++ } ++ } ++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); ++ sprintf(buf2, "%s%s", dir, name); ++ rename(buf, buf2); ++ printf(_("#\n" ++ "# make dependencies written to %s\n" ++ "# ATTENTION buildroot devels!\n" ++ "# See top of this file before playing with this auto-preprequisites!\n" ++ "#\n"), name); ++ return 0; ++} ++ + /* write a dependency file as used by kbuild to track dependencies */ + int file_write_dep(const char *name) + { +@@ -68,7 +183,7 @@ + fprintf(out, "\n$(deps_config): ;\n"); + fclose(out); + rename("..config.tmp", name); +- return 0; ++ return write_make_deps(NULL); + } + + diff --git a/package/config/patches/09-implement-kconfig-probability.patch b/package/config/patches/09-implement-kconfig-probability.patch new file mode 100644 index 000000000..7561fbc3c --- /dev/null +++ b/package/config/patches/09-implement-kconfig-probability.patch @@ -0,0 +1,44 @@ +--- + confdata.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +Index: config/confdata.c +=================================================================== +--- config.orig/confdata.c ++++ config/confdata.c +@@ -977,7 +977,16 @@ + void conf_set_all_new_symbols(enum conf_def_mode mode) + { + struct symbol *sym, *csym; +- int i, cnt; ++ int i, cnt, prob = 50; ++ ++ if (mode == def_random) { ++ char *endp, *env = getenv("KCONFIG_PROBABILITY"); ++ if (env && *env) { ++ int tmp = (int)strtol(env, &endp, 10); ++ if (*endp == '\0' && tmp >= 0 && tmp <= 100) ++ prob = tmp; ++ } ++ } + + for_all_symbols(i, sym) { + if (sym_has_value(sym)) +@@ -996,8 +1005,15 @@ + sym->def[S_DEF_USER].tri = no; + break; + case def_random: +- cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2; +- sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt); ++ cnt = (rand() % 100) - (100 - prob); ++ if (cnt < 0) ++ sym->def[S_DEF_USER].tri = no; ++ else ++ if ((sym_get_type(sym) == S_TRISTATE) ++ && (cnt > prob/2)) ++ sym->def[S_DEF_USER].tri = mod; ++ else ++ sym->def[S_DEF_USER].tri = yes; + break; + default: + continue; diff --git a/package/config/patches/10-br-build-system.patch b/package/config/patches/10-br-build-system.patch new file mode 100644 index 000000000..85125e519 --- /dev/null +++ b/package/config/patches/10-br-build-system.patch @@ -0,0 +1,80 @@ +--- + Makefile.br | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + foo.h | 12 ++++++++++++ + 2 files changed, 65 insertions(+) + +Index: config/Makefile.br +=================================================================== +--- /dev/null ++++ config/Makefile.br +@@ -0,0 +1,53 @@ ++src := . ++top_srcdir=../../ ++top_builddir=../../ ++srctree := . ++obj ?= . ++ ++include Makefile ++#HOSTCFLAGS+=-Dinline="" -include foo.h ++-include $(obj)/.depend ++$(obj)/.depend: $(wildcard *.h *.c) ++ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) -MM *.c > $@ 2>/dev/null || : ++ ++__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) ++host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) ++host-cmulti := $(foreach m,$(__hostprogs),\ ++ $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) ++host-cxxmulti := $(foreach m,$(__hostprogs),\ ++ $(if $($(m)-cxxobjs),$(m),$(if $($(m)-objs),))) ++host-cobjs := $(addprefix $(obj)/,$(sort $(foreach m,$(__hostprogs),$($(m)-objs)))) ++host-cxxobjs := $(addprefix $(obj)/,$(sort $(foreach m,$(__hostprogs),$($(m)-cxxobjs)))) ++ ++HOST_EXTRACFLAGS += -I$(obj) ++ ++$(host-csingle): %: %.c ++ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $< $(HOST_LOADLIBES) -o $(obj)/$@ ++ ++$(host-cmulti): %: $(host-cobjs) $(host-cshlib) ++ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(addprefix $(obj)/,$($(@F)-objs)) $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) -o $(obj)/$@ ++ ++$(host-cxxmulti): %: $(host-cxxobjs) $(host-cobjs) $(host-cshlib) ++ $(HOSTCXX) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCXXFLAGS_$@) $(addprefix $(obj)/,$($(@F)-objs) $($(@F)-cxxobjs)) $(HOSTLOADLIBES_$(@F)) -o $(obj)/$@ ++ ++$(obj)/%.o: %.c ++ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) -c $< -o $@ ++ ++$(obj)/%.o: $(obj)/%.c ++ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) -c $< -o $@ ++ ++$(obj)/%.o: %.cc ++ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCXXFLAGS_$(@F)) -c $< -o $@ ++ ++$(obj)/%:: $(src)/%_shipped ++ $(Q)cat $< > $@ ++ ++clean: ++ $(Q)rm -f $(addprefix $(obj)/,$(clean-files)) ++distclean: clean ++ $(Q)rm -f $(addprefix $(obj)/,$(lxdialog) $(conf-objs) $(mconf-objs) $(kxgettext-objs) \ ++ $(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs) \ ++ mconf .depend) ++ ++FORCE: ++.PHONY: FORCE clean distclean +Index: config/foo.h +=================================================================== +--- /dev/null ++++ config/foo.h +@@ -0,0 +1,12 @@ ++#ifndef __KCONFIG_FOO_H ++#define __KCONFIG_FOO_H ++ ++#ifndef __APPLE__ ++#include <features.h> ++#endif ++#include <limits.h> ++ ++#ifndef PATH_MAX ++#define PATH_MAX 1024 ++#endif ++#endif /* __KCONFIG_FOO_H */ diff --git a/package/config/patches/11-use-mktemp-for-lxdialog.patch b/package/config/patches/11-use-mktemp-for-lxdialog.patch new file mode 100644 index 000000000..16fd8bf18 --- /dev/null +++ b/package/config/patches/11-use-mktemp-for-lxdialog.patch @@ -0,0 +1,17 @@ +--- + lxdialog/check-lxdialog.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: config.clean/lxdialog/check-lxdialog.sh +=================================================================== +--- config.clean.orig/lxdialog/check-lxdialog.sh ++++ config.clean/lxdialog/check-lxdialog.sh +@@ -31,7 +31,7 @@ + } + + # Temp file, try to clean up after us +-tmp=.lxdialog.tmp ++tmp=$(mktemp) + trap "rm -f $tmp" 0 1 2 3 15 + + # Check if we can link to ncurses diff --git a/package/config/patches/12-fix-glade-file-path.patch b/package/config/patches/12-fix-glade-file-path.patch new file mode 100644 index 000000000..10c7e9163 --- /dev/null +++ b/package/config/patches/12-fix-glade-file-path.patch @@ -0,0 +1,17 @@ +--- + gconf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: config.new/gconf.c +=================================================================== +--- config.new.orig/gconf.c ++++ config.new/gconf.c +@@ -1525,7 +1525,7 @@ + /* Determine GUI path */ + env = getenv(SRCTREE); + if (env) +- glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL); ++ glade_file = g_strconcat(env, "/package/config/gconf.glade", NULL); + else if (av[0][0] == '/') + glade_file = g_strconcat(av[0], ".glade", NULL); + else diff --git a/package/config/patches/14-support-out-of-tree-config.patch b/package/config/patches/14-support-out-of-tree-config.patch new file mode 100644 index 000000000..fb1cca1a8 --- /dev/null +++ b/package/config/patches/14-support-out-of-tree-config.patch @@ -0,0 +1,209 @@ +--- + conf.c | 1 + confdata.c | 65 +++++++++++++++++++++++++++++++++++++++++++++---------------- + util.c | 16 +++++++++++++-- + 3 files changed, 62 insertions(+), 20 deletions(-) + +Index: config/conf.c +=================================================================== +--- config.orig/conf.c ++++ config/conf.c +@@ -503,7 +503,6 @@ + } + name = av[optind]; + conf_parse(name); +- //zconfdump(stdout); + if (sync_kconfig) { + name = conf_get_configname(); + if (stat(name, &tmpstat)) { +Index: config/confdata.c +=================================================================== +--- config.orig/confdata.c ++++ config/confdata.c +@@ -44,9 +44,7 @@ + + const char *conf_get_autoconfig_name(void) + { +- char *name = getenv("KCONFIG_AUTOCONFIG"); +- +- return name ? name : "include/config/auto.conf"; ++ return getenv("KCONFIG_AUTOCONFIG"); + } + + static char *conf_expand_value(const char *in) +@@ -542,6 +540,9 @@ + int use_timestamp = 1; + char *env; + ++ if (!name) ++ name = conf_get_configname(); ++ + dirname[0] = 0; + if (name && name[0]) { + struct stat st; +@@ -656,6 +657,7 @@ + { + const char *name; + char path[128]; ++ char *opwd, *dir, *_name; + char *s, *d, c; + struct symbol *sym; + struct stat sb; +@@ -664,8 +666,20 @@ + name = conf_get_autoconfig_name(); + conf_read_simple(name, S_DEF_AUTO); + +- if (chdir("include/config")) +- return 1; ++ opwd = malloc(256); ++ _name = strdup(name); ++ if (opwd == NULL || _name == NULL) ++ return 1; ++ opwd = getcwd(opwd, 256); ++ dir = dirname(_name); ++ if (dir == NULL) { ++ res = 1; ++ goto err; ++ } ++ if (chdir(dir)) { ++ res = 1; ++ goto err; ++ } + + res = 0; + for_all_symbols(i, sym) { +@@ -758,9 +772,11 @@ + close(fd); + } + out: +- if (chdir("../..")) +- return 1; +- ++ if (chdir(opwd)) ++ res = 1; ++err: ++ free(opwd); ++ free(_name); + return res; + } + +@@ -772,25 +788,38 @@ + FILE *out, *tristate, *out_h; + time_t now; + int i; ++ char dir[PATH_MAX+1], buf[PATH_MAX+1]; ++ char *s; ++ ++ strcpy(dir, conf_get_configname()); ++ s = strrchr(dir, '/'); ++ if (s) ++ s[1] = 0; ++ else ++ dir[0] = 0; + + sym_clear_all_valid(); + +- file_write_dep("include/config/auto.conf.cmd"); ++ sprintf(buf, "%s.config.cmd", dir); ++ file_write_dep(buf); + + if (conf_split_config()) + return 1; + +- out = fopen(".tmpconfig", "w"); ++ sprintf(buf, "%s.tmpconfig", dir); ++ out = fopen(buf, "w"); + if (!out) + return 1; + +- tristate = fopen(".tmpconfig_tristate", "w"); ++ sprintf(buf, "%s.tmpconfig_tristate", dir); ++ tristate = fopen(buf, "w"); + if (!tristate) { + fclose(out); + return 1; + } + +- out_h = fopen(".tmpconfig.h", "w"); ++ sprintf(buf, "%s.tmpconfig.h", dir); ++ out_h = fopen(buf, "w"); + if (!out_h) { + fclose(out); + fclose(tristate); +@@ -811,8 +840,7 @@ + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " * %s" +- " */\n" +- "#define AUTOCONF_INCLUDED\n", ++ " */\n", + ctime(&now)); + + for_all_symbols(i, sym) { +@@ -866,19 +894,22 @@ + name = getenv("KCONFIG_AUTOHEADER"); + if (!name) + name = "include/generated/autoconf.h"; +- if (rename(".tmpconfig.h", name)) ++ sprintf(buf, "%s.tmpconfig.h", dir); ++ if (rename(buf, name)) + return 1; + name = getenv("KCONFIG_TRISTATE"); + if (!name) + name = "include/config/tristate.conf"; +- if (rename(".tmpconfig_tristate", name)) ++ sprintf(buf, "%s.tmpconfig_tristate", dir); ++ if (rename(buf, name)) + return 1; + name = conf_get_autoconfig_name(); + /* + * This must be the last step, kbuild has a dependency on auto.conf + * and this marks the successful completion of the previous steps. + */ +- if (rename(".tmpconfig", name)) ++ sprintf(buf, "%s.tmpconfig", dir); ++ if (rename(buf, name)) + return 1; + + return 0; +Index: config/util.c +=================================================================== +--- config.orig/util.c ++++ config/util.c +@@ -144,6 +144,8 @@ + /* write a dependency file as used by kbuild to track dependencies */ + int file_write_dep(const char *name) + { ++ char *str; ++ char buf[PATH_MAX+1], buf2[PATH_MAX+1], dir[PATH_MAX+1]; + struct symbol *sym, *env_sym; + struct expr *e; + struct file *file; +@@ -151,7 +153,16 @@ + + if (!name) + name = ".kconfig.d"; +- out = fopen("..config.tmp", "w"); ++ ++ strcpy(dir, conf_get_configname()); ++ str = strrchr(dir, '/'); ++ if (str) ++ str[1] = 0; ++ else ++ dir[0] = 0; ++ ++ sprintf(buf, "%s..config.tmp", dir); ++ out = fopen(buf, "w"); + if (!out) + return 1; + fprintf(out, "deps_config := \\\n"); +@@ -182,7 +193,8 @@ + + fprintf(out, "\n$(deps_config): ;\n"); + fclose(out); +- rename("..config.tmp", name); ++ sprintf(buf2, "%s%s", dir, name); ++ rename(buf, buf2); + return write_make_deps(NULL); + } + diff --git a/package/config/patches/series b/package/config/patches/series new file mode 100644 index 000000000..defdf5899 --- /dev/null +++ b/package/config/patches/series @@ -0,0 +1,11 @@ +01-kconfig-kernel-to-buildroot.patch +02-cpp-comments-to-c-comments.patch +03-change-config-option-prefix.patch +05-really-clean-everything.patch +06-br-build-system-integration.patch +08-make-write-deps.patch +09-implement-kconfig-probability.patch +10-br-build-system.patch +11-use-mktemp-for-lxdialog.patch +12-fix-glade-file-path.patch +14-support-out-of-tree-config.patch diff --git a/package/config/qconf.cc b/package/config/qconf.cc index 9af12a61a..bbda3c811 100644 --- a/package/config/qconf.cc +++ b/package/config/qconf.cc @@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok) { QValueList<int> result; QStringList entryList = readListEntry(key, ok); - if (ok) { - QStringList::Iterator it; - for (it = entryList.begin(); it != entryList.end(); ++it) - result.push_back((*it).toInt()); - } + QStringList::Iterator it; + + for (it = entryList.begin(); it != entryList.end(); ++it) + result.push_back((*it).toInt()); return result; } @@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void) case S_TRISTATE: char ch; - if (!sym_is_changable(sym) && !list->showAll) { + if (!sym_is_changable(sym) && list->optMode == normalOpt) { setPixmap(promptColIdx, 0); setText(noColIdx, QString::null); setText(modColIdx, QString::null); @@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name) symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), - showAll(false), showName(false), showRange(false), showData(false), + showName(false), showRange(false), showData(false), optMode(normalOpt), rootEntry(0), headerPopup(0) { int i; @@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name) if (name) { configSettings->beginGroup(name); - showAll = configSettings->readBoolEntry("/showAll", false); showName = configSettings->readBoolEntry("/showName", false); showRange = configSettings->readBoolEntry("/showRange", false); showData = configSettings->readBoolEntry("/showData", false); + optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false); configSettings->endGroup(); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); } @@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name) reinit(); } +bool ConfigList::menuSkip(struct menu *menu) +{ + if (optMode == normalOpt && menu_is_visible(menu)) + return false; + if (optMode == promptOpt && menu_has_prompt(menu)) + return false; + if (optMode == allOpt) + return false; + return true; +} + void ConfigList::reinit(void) { removeColumn(dataColIdx); @@ -380,7 +390,7 @@ void ConfigList::saveSettings(void) configSettings->writeEntry("/showName", showName); configSettings->writeEntry("/showRange", showRange); configSettings->writeEntry("/showData", showData); - configSettings->writeEntry("/showAll", showAll); + configSettings->writeEntry("/optionMode", (int)optMode); configSettings->endGroup(); } } @@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) } visible = menu_is_visible(child); - if (showAll || visible) { + if (!menuSkip(child)) { if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) @@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) e->ignore(); } -ConfigView* ConfigView::viewList; +ConfigView*ConfigView::viewList; +QAction *ConfigView::showNormalAction; +QAction *ConfigView::showAllAction; +QAction *ConfigView::showPromptAction; ConfigView::ConfigView(QWidget* parent, const char *name) : Parent(parent, name) @@ -860,13 +873,16 @@ ConfigView::~ConfigView(void) } } -void ConfigView::setShowAll(bool b) +void ConfigView::setOptionMode(QAction *act) { - if (list->showAll != b) { - list->showAll = b; - list->updateListAll(); - emit showAllChanged(b); - } + if (act == showNormalAction) + list->optMode = normalOpt; + else if (act == showAllAction) + list->optMode = allOpt; + else + list->optMode = promptOpt; + + list->updateListAll(); } void ConfigView::setShowName(bool b) @@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m) menuInfo(); } -void ConfigInfoView::setSource(const QString& name) -{ - const char *p = name.latin1(); - - menu = NULL; - sym = NULL; - - switch (p[0]) { - case 'm': - struct menu *m; - - if (sscanf(p, "m%p", &m) == 1 && menu != m) { - menu = m; - menuInfo(); - emit menuSelected(menu); - } - break; - case 's': - struct symbol *s; - - if (sscanf(p, "s%p", &s) == 1 && sym != s) { - sym = s; - symbolInfo(); - } - break; - } -} - void ConfigInfoView::symbolInfo(void) { QString str; @@ -1042,12 +1030,10 @@ void ConfigInfoView::menuInfo(void) if (showDebug()) debug = debug_info(sym); - help = menu_get_help(menu); - /* Gettextize if the help text not empty */ - if (help.isEmpty()) - help = print_filter(menu_get_help(menu)); - else - help = print_filter(_(menu_get_help(menu))); + struct gstr help_gstr = str_new(); + menu_get_ext_help(menu, &help_gstr); + help = print_filter(str_get(&help_gstr)); + str_free(&help_gstr); } else if (menu->prompt) { head += "<big><b>"; head += print_filter(_(menu->prompt->text)); @@ -1277,7 +1263,8 @@ ConfigMainWindow::ConfigMainWindow(void) char title[256]; QDesktopWidget *d = configApp->desktop(); - snprintf(title, sizeof(title), _("Buildroot Configuration")); + snprintf(title, sizeof(title), _("Buildroot v%s Configuration"), + getenv("BR2_VERSION")); setCaption(title); width = configSettings->readNumEntry("/window width", d->width() - 64); @@ -1350,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void) connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); showDataAction->setOn(configList->showData); - QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this); - showAllAction->setToggleAction(TRUE); - connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); - connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); - showAllAction->setOn(configList->showAll); + + QActionGroup *optGroup = new QActionGroup(this); + optGroup->setExclusive(TRUE); + connect(optGroup, SIGNAL(selected(QAction *)), configView, + SLOT(setOptionMode(QAction *))); + connect(optGroup, SIGNAL(selected(QAction *)), menuView, + SLOT(setOptionMode(QAction *))); + + configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup); + configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup); + configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup); + configView->showNormalAction->setToggleAction(TRUE); + configView->showNormalAction->setOn(configList->optMode == normalOpt); + configView->showAllAction->setToggleAction(TRUE); + configView->showAllAction->setOn(configList->optMode == allOpt); + configView->showPromptAction->setToggleAction(TRUE); + configView->showPromptAction->setOn(configList->optMode == promptOpt); + QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); showDebugAction->setToggleAction(TRUE); connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); @@ -1397,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void) showRangeAction->addTo(optionMenu); showDataAction->addTo(optionMenu); optionMenu->insertSeparator(); - showAllAction->addTo(optionMenu); + optGroup->addTo(optionMenu); + optionMenu->insertSeparator(); showDebugAction->addTo(optionMenu); // create help menu @@ -1492,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) ConfigList* list = NULL; ConfigItem* item; - if (!menu_is_visible(menu) && !configView->showAll()) + if (configList->menuSkip(menu)) return; switch (configList->mode) { @@ -1611,7 +1612,6 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) { if (!conf_get_changed()) { e->accept(); - conf_write_autoconf(); return; } QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning, @@ -1622,7 +1622,6 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) switch (mb.exec()) { case QMessageBox::Yes: conf_write(NULL); - conf_write_autoconf(); case QMessageBox::No: e->accept(); break; diff --git a/package/config/qconf.h b/package/config/qconf.h index b3b5657b6..636a74b23 100644 --- a/package/config/qconf.h +++ b/package/config/qconf.h @@ -44,6 +44,9 @@ enum colIdx { enum listMode { singleMode, menuMode, symbolMode, fullMode, listMode }; +enum optionMode { + normalOpt = 0, allOpt, promptOpt +}; class ConfigList : public QListView { Q_OBJECT @@ -115,6 +118,8 @@ public: void setAllOpen(bool open); void setParentMenu(void); + bool menuSkip(struct menu *); + template <class P> void updateMenuList(P*, struct menu*); @@ -124,8 +129,9 @@ public: QPixmap choiceYesPix, choiceNoPix; QPixmap menuPix, menuInvPix, menuBackPix, voidPix; - bool showAll, showName, showRange, showData; + bool showName, showRange, showData; enum listMode mode; + enum optionMode optMode; struct menu *rootEntry; QColorGroup disabledColorGroup; QColorGroup inactivedColorGroup; @@ -222,17 +228,15 @@ public: static void updateList(ConfigItem* item); static void updateListAll(void); - bool showAll(void) const { return list->showAll; } bool showName(void) const { return list->showName; } bool showRange(void) const { return list->showRange; } bool showData(void) const { return list->showData; } public slots: - void setShowAll(bool); void setShowName(bool); void setShowRange(bool); void setShowData(bool); + void setOptionMode(QAction *); signals: - void showAllChanged(bool); void showNameChanged(bool); void showRangeChanged(bool); void showDataChanged(bool); @@ -242,6 +246,10 @@ public: static ConfigView* viewList; ConfigView* nextView; + + static QAction *showNormalAction; + static QAction *showAllAction; + static QAction *showPromptAction; }; class ConfigInfoView : public QTextBrowser { @@ -254,7 +262,6 @@ public: public slots: void setInfo(struct menu *menu); void saveSettings(void); - void setSource(const QString& name); void setShowDebug(bool); signals: diff --git a/package/config/streamline_config.pl b/package/config/streamline_config.pl new file mode 100644 index 000000000..c70a27d92 --- /dev/null +++ b/package/config/streamline_config.pl @@ -0,0 +1,422 @@ +#!/usr/bin/perl -w +# +# Copywrite 2005-2009 - Steven Rostedt +# Licensed under the terms of the GNU GPL License version 2 +# +# It's simple enough to figure out how this works. +# If not, then you can ask me at stripconfig@goodmis.org +# +# What it does? +# +# If you have installed a Linux kernel from a distribution +# that turns on way too many modules than you need, and +# you only want the modules you use, then this program +# is perfect for you. +# +# It gives you the ability to turn off all the modules that are +# not loaded on your system. +# +# Howto: +# +# 1. Boot up the kernel that you want to stream line the config on. +# 2. Change directory to the directory holding the source of the +# kernel that you just booted. +# 3. Copy the configuraton file to this directory as .config +# 4. Have all your devices that you need modules for connected and +# operational (make sure that their corresponding modules are loaded) +# 5. Run this script redirecting the output to some other file +# like config_strip. +# 6. Back up your old config (if you want too). +# 7. copy the config_strip file to .config +# 8. Run "make oldconfig" +# +# Now your kernel is ready to be built with only the modules that +# are loaded. +# +# Here's what I did with my Debian distribution. +# +# cd /usr/src/linux-2.6.10 +# cp /boot/config-2.6.10-1-686-smp .config +# ~/bin/streamline_config > config_strip +# mv .config config_sav +# mv config_strip .config +# make oldconfig +# +my $config = ".config"; + +my $uname = `uname -r`; +chomp $uname; + +my @searchconfigs = ( + { + "file" => ".config", + "exec" => "cat", + }, + { + "file" => "/proc/config.gz", + "exec" => "zcat", + }, + { + "file" => "/boot/config-$uname", + "exec" => "cat", + }, + { + "file" => "/boot/vmlinuz-$uname", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "vmlinux", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "/lib/modules/$uname/kernel/kernel/configs.ko", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "kernel/configs.ko", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "kernel/configs.o", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, +); + +sub find_config { + foreach my $conf (@searchconfigs) { + my $file = $conf->{"file"}; + + next if ( ! -f "$file"); + + if (defined($conf->{"test"})) { + `$conf->{"test"} $conf->{"file"} 2>/dev/null`; + next if ($?); + } + + my $exec = $conf->{"exec"}; + + print STDERR "using config: '$file'\n"; + + open(CIN, "$exec $file |") || die "Failed to run $exec $file"; + return; + } + die "No config file found"; +} + +find_config; + +# Get the build source and top level Kconfig file (passed in) +my $ksource = $ARGV[0]; +my $kconfig = $ARGV[1]; +my $lsmod_file = $ARGV[2]; + +my @makefiles = `find $ksource -name Makefile 2>/dev/null`; +chomp @makefiles; + +my %depends; +my %selects; +my %prompts; +my %objects; +my $var; +my $cont = 0; +my $iflevel = 0; +my @ifdeps; + +# prevent recursion +my %read_kconfigs; + +sub read_kconfig { + my ($kconfig) = @_; + + my $state = "NONE"; + my $config; + my @kconfigs; + + open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig"; + while (<KIN>) { + chomp; + + # collect any Kconfig sources + if (/^source\s*"(.*)"/) { + $kconfigs[$#kconfigs+1] = $1; + } + + # configs found + if (/^\s*config\s+(\S+)\s*$/) { + $state = "NEW"; + $config = $1; + + for (my $i = 0; $i < $iflevel; $i++) { + if ($i) { + $depends{$config} .= " " . $ifdeps[$i]; + } else { + $depends{$config} = $ifdeps[$i]; + } + $state = "DEP"; + } + + # collect the depends for the config + } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { + $state = "DEP"; + $depends{$config} = $1; + } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { + $depends{$config} .= " " . $1; + + # Get the configs that select this config + } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { + if (defined($selects{$1})) { + $selects{$1} .= " " . $config; + } else { + $selects{$1} = $config; + } + + # configs without prompts must be selected + } elsif ($state ne "NONE" && /^\s*tristate\s\S/) { + # note if the config has a prompt + $prompt{$config} = 1; + + # Check for if statements + } elsif (/^if\s+(.*\S)\s*$/) { + my $deps = $1; + # remove beginning and ending non text + $deps =~ s/^[^a-zA-Z0-9_]*//; + $deps =~ s/[^a-zA-Z0-9_]*$//; + + my @deps = split /[^a-zA-Z0-9_]+/, $deps; + + $ifdeps[$iflevel++] = join ':', @deps; + + } elsif (/^endif/) { + + $iflevel-- if ($iflevel); + + # stop on "help" + } elsif (/^\s*help\s*$/) { + $state = "NONE"; + } + } + close(KIN); + + # read in any configs that were found. + foreach $kconfig (@kconfigs) { + if (!defined($read_kconfigs{$kconfig})) { + $read_kconfigs{$kconfig} = 1; + read_kconfig($kconfig); + } + } +} + +if ($kconfig) { + read_kconfig($kconfig); +} + +# Read all Makefiles to map the configs to the objects +foreach my $makefile (@makefiles) { + + open(MIN,$makefile) || die "Can't open $makefile"; + while (<MIN>) { + my $objs; + + # is this a line after a line with a backslash? + if ($cont && /(\S.*)$/) { + $objs = $1; + } + $cont = 0; + + # collect objects after obj-$(CONFIG_FOO_BAR) + if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { + $var = $1; + $objs = $2; + } + if (defined($objs)) { + # test if the line ends with a backslash + if ($objs =~ m,(.*)\\$,) { + $objs = $1; + $cont = 1; + } + + foreach my $obj (split /\s+/,$objs) { + $obj =~ s/-/_/g; + if ($obj =~ /(.*)\.o$/) { + # Objects may be enabled by more than one config. + # Store configs in an array. + my @arr; + + if (defined($objects{$1})) { + @arr = @{$objects{$1}}; + } + + $arr[$#arr+1] = $var; + + # The objects have a hash mapping to a reference + # of an array of configs. + $objects{$1} = \@arr; + } + } + } + } + close(MIN); +} + +my %modules; + +if (defined($lsmod_file)) { + if ( ! -f $lsmod_file) { + die "$lsmod_file not found"; + } + if ( -x $lsmod_file) { + # the file is executable, run it + open(LIN, "$lsmod_file|"); + } else { + # Just read the contents + open(LIN, "$lsmod_file"); + } +} else { + + # see what modules are loaded on this system + my $lsmod; + + foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { + if ( -x "$dir/lsmod" ) { + $lsmod = "$dir/lsmod"; + last; + } +} + if (!defined($lsmod)) { + # try just the path + $lsmod = "lsmod"; + } + + open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod"; +} + +while (<LIN>) { + next if (/^Module/); # Skip the first line. + if (/^(\S+)/) { + $modules{$1} = 1; + } +} +close (LIN); + +# add to the configs hash all configs that are needed to enable +# a loaded module. +my %configs; +foreach my $module (keys(%modules)) { + if (defined($objects{$module})) { + my @arr = @{$objects{$module}}; + foreach my $conf (@arr) { + $configs{$conf} = $module; + } + } else { + # Most likely, someone has a custom (binary?) module loaded. + print STDERR "$module config not found!!\n"; + } +} + +my $valid = "A-Za-z_0-9"; +my $repeat = 1; + +# +# Note, we do not care about operands (like: &&, ||, !) we want to add any +# config that is in the depend list of another config. This script does +# not enable configs that are not already enabled. If we come across a +# config A that depends on !B, we can still add B to the list of depends +# to keep on. If A was on in the original config, B would not have been +# and B would not be turned on by this script. +# +sub parse_config_dep_select +{ + my ($p) = @_; + + while ($p =~ /[$valid]/) { + + if ($p =~ /^[^$valid]*([$valid]+)/) { + my $conf = "CONFIG_" . $1; + + $p =~ s/^[^$valid]*[$valid]+//; + + if (!defined($configs{$conf})) { + # We must make sure that this config has its + # dependencies met. + $repeat = 1; # do again + $configs{$conf} = 1; + } + } else { + die "this should never happen"; + } + } +} + +while ($repeat) { + $repeat = 0; + + foreach my $config (keys %configs) { + $config =~ s/^CONFIG_//; + + if (defined($depends{$config})) { + # This config has dependencies. Make sure they are also included + parse_config_dep_select $depends{$config}; + } + + if (defined($prompt{$config}) || !defined($selects{$config})) { + next; + } + + # config has no prompt and must be selected. + parse_config_dep_select $selects{$config}; + } +} + +my %setconfigs; + +# Finally, read the .config file and turn off any module enabled that +# we could not find a reason to keep enabled. +while(<CIN>) { + + if (/CONFIG_IKCONFIG/) { + if (/# CONFIG_IKCONFIG is not set/) { + # enable IKCONFIG at least as a module + print "CONFIG_IKCONFIG=m\n"; + # don't ask about PROC + print "# CONFIG_IKCONFIG_PROC is not set\n"; + } else { + print; + } + next; + } + + if (/^(CONFIG.*)=(m|y)/) { + if (defined($configs{$1})) { + $setconfigs{$1} = $2; + } elsif ($2 eq "m") { + print "# $1 is not set\n"; + next; + } + } + print; +} +close(CIN); + +# Integrity check, make sure all modules that we want enabled do +# indeed have their configs set. +loop: +foreach my $module (keys(%modules)) { + if (defined($objects{$module})) { + my @arr = @{$objects{$module}}; + foreach my $conf (@arr) { + if (defined($setconfigs{$conf})) { + next loop; + } + } + print STDERR "module $module did not have configs"; + foreach my $conf (@arr) { + print STDERR " " , $conf; + } + print STDERR "\n"; + } +} diff --git a/package/config/symbol.c b/package/config/symbol.c index 18f3e5c33..e95718fea 100644 --- a/package/config/symbol.c +++ b/package/config/symbol.c @@ -36,7 +36,7 @@ tristate modules_val; struct expr *sym_env_list; -void sym_add_default(struct symbol *sym, const char *def) +static void sym_add_default(struct symbol *sym, const char *def) { struct property *prop = prop_alloc(P_DEFAULT, sym); @@ -125,7 +125,7 @@ struct property *sym_get_default_prop(struct symbol *sym) return NULL; } -struct property *sym_get_range_prop(struct symbol *sym) +static struct property *sym_get_range_prop(struct symbol *sym) { struct property *prop; @@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym) } if (sym_is_choice_value(sym)) return; + /* defaulting to "yes" if no explicit "depends on" are given */ + tri = yes; + if (sym->dir_dep.expr) + tri = expr_calc_value(sym->dir_dep.expr); + if (tri == mod) + tri = yes; + if (sym->dir_dep.tri != tri) { + sym->dir_dep.tri = tri; + sym_set_changed(sym); + } tri = no; if (sym->rev_dep.expr) tri = expr_calc_value(sym->rev_dep.expr); @@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym) } } -static struct symbol *sym_calc_choice(struct symbol *sym) +/* + * Find the default symbol for a choice. + * First try the default values for the choice symbol + * Next locate the first visible choice value + * Return NULL if none was found + */ +struct symbol *sym_choice_default(struct symbol *sym) { struct symbol *def_sym; struct property *prop; struct expr *e; - /* is the user choice visible? */ - def_sym = sym->def[S_DEF_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); - expr_list_for_each_sym(prop->expr, e, def_sym) { - sym_calc_visibility(def_sym); + expr_list_for_each_sym(prop->expr, e, def_sym) if (def_sym->visible != no) return def_sym; - } - /* no choice? reset tristate value */ - sym->curr.tri = no; + /* failed to locate any defaults */ return NULL; } +static struct symbol *sym_calc_choice(struct symbol *sym) +{ + struct symbol *def_sym; + struct property *prop; + struct expr *e; + + /* first calculate all choice values' visibilities */ + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) + sym_calc_visibility(def_sym); + + /* is the user choice visible? */ + def_sym = sym->def[S_DEF_USER].val; + if (def_sym && def_sym->visible != no) + return def_sym; + + def_sym = sym_choice_default(sym); + + if (def_sym == NULL) + /* no choice? reset tristate value */ + sym->curr.tri = no; + + return def_sym; +} + void sym_calc_value(struct symbol *sym) { struct symbol_value newval, oldval; @@ -321,6 +350,14 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: + if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { + fprintf(stderr, "warning: ("); + expr_fprint(sym->rev_dep.expr, stderr); + fprintf(stderr, ") selects %s which has unmet direct dependencies (", + sym->name); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) @@ -365,12 +402,13 @@ void sym_calc_value(struct symbol *sym) if (sym_is_choice(sym)) { struct symbol *choice_sym; - int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); prop = sym_get_choice_prop(sym); expr_list_for_each_sym(prop->expr, e, choice_sym) { - choice_sym->flags |= flags; - if (flags & SYMBOL_CHANGED) + if ((sym->flags & SYMBOL_WRITE) && + choice_sym->visible != no) + choice_sym->flags |= SYMBOL_WRITE; + if (sym->flags & SYMBOL_CHANGED) sym_set_changed(choice_sym); } } @@ -623,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) return true; } +/* + * Find the default value associated to a symbol. + * For tristate symbol handle the modules=n case + * in which case "m" becomes "y". + * If the symbol does not have any default then fallback + * to the fixed default values. + */ +const char *sym_get_string_default(struct symbol *sym) +{ + struct property *prop; + struct symbol *ds; + const char *str; + tristate val; + + sym_calc_visibility(sym); + sym_calc_value(modules_sym); + val = symbol_no.curr.tri; + str = symbol_empty.curr.val; + + /* If symbol has a default value look it up */ + prop = sym_get_default_prop(sym); + if (prop != NULL) { + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + /* The visibility imay limit the value from yes => mod */ + val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); + break; + default: + /* + * The following fails to handle the situation + * where a default value is further limited by + * the valid range. + */ + ds = prop_get_symbol(prop); + if (ds != NULL) { + sym_calc_value(ds); + str = (const char *)ds->curr.val; + } + } + } + + /* Handle select statements */ + val = EXPR_OR(val, sym->rev_dep.tri); + + /* transpose mod to yes if modules are not enabled */ + if (val == mod) + if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no) + val = yes; + + /* transpose mod to yes if type is bool */ + if (sym->type == S_BOOLEAN && val == mod) + val = yes; + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (val) { + case no: return "n"; + case mod: return "m"; + case yes: return "y"; + } + case S_INT: + case S_HEX: + return str; + case S_STRING: + return str; + case S_OTHER: + case S_UNKNOWN: + break; + } + return ""; +} + const char *sym_get_string_value(struct symbol *sym) { tristate val; @@ -651,12 +763,20 @@ bool sym_is_changable(struct symbol *sym) return sym->visible > sym->rev_dep.tri; } +static unsigned strhash(const char *s) +{ + /* fnv32 hash */ + unsigned hash = 2166136261U; + for (; *s; s++) + hash = (hash ^ *s) * 0x01000193; + return hash; +} + struct symbol *sym_lookup(const char *name, int flags) { struct symbol *symbol; - const char *ptr; char *new_name; - int hash = 0; + int hash; if (name) { if (name[0] && !name[1]) { @@ -666,12 +786,11 @@ struct symbol *sym_lookup(const char *name, int flags) case 'n': return &symbol_no; } } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; + hash = strhash(name) % SYMBOL_HASHSIZE; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && + if (symbol->name && + !strcmp(symbol->name, name) && (flags ? symbol->flags & flags : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) return symbol; @@ -679,7 +798,7 @@ struct symbol *sym_lookup(const char *name, int flags) new_name = strdup(name); } else { new_name = NULL; - hash = 256; + hash = 0; } symbol = malloc(sizeof(*symbol)); @@ -697,7 +816,6 @@ struct symbol *sym_lookup(const char *name, int flags) struct symbol *sym_find(const char *name) { struct symbol *symbol = NULL; - const char *ptr; int hash = 0; if (!name) @@ -710,12 +828,11 @@ struct symbol *sym_find(const char *name) case 'n': return &symbol_no; } } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; + hash = strhash(name) % SYMBOL_HASHSIZE; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && + if (symbol->name && + !strcmp(symbol->name, name) && !(symbol->flags & SYMBOL_CONST)) break; } @@ -750,6 +867,7 @@ struct symbol **sym_re_search(const char *pattern) return NULL; } } + sym_calc_value(sym); sym_arr[cnt++] = sym; } if (sym_arr) @@ -759,6 +877,110 @@ struct symbol **sym_re_search(const char *pattern) return sym_arr; } +/* + * When we check for recursive dependencies we use a stack to save + * current state so we can print out relevant info to user. + * The entries are located on the call stack so no need to free memory. + * Note inser() remove() must always match to properly clear the stack. + */ +static struct dep_stack { + struct dep_stack *prev, *next; + struct symbol *sym; + struct property *prop; + struct expr *expr; +} *check_top; + +static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) +{ + memset(stack, 0, sizeof(*stack)); + if (check_top) + check_top->next = stack; + stack->prev = check_top; + stack->sym = sym; + check_top = stack; +} + +static void dep_stack_remove(void) +{ + check_top = check_top->prev; + if (check_top) + check_top->next = NULL; +} + +/* + * Called when we have detected a recursive dependency. + * check_top point to the top of the stact so we use + * the ->prev pointer to locate the bottom of the stack. + */ +static void sym_check_print_recursive(struct symbol *last_sym) +{ + struct dep_stack *stack; + struct symbol *sym, *next_sym; + struct menu *menu = NULL; + struct property *prop; + struct dep_stack cv_stack; + + if (sym_is_choice_value(last_sym)) { + dep_stack_insert(&cv_stack, last_sym); + last_sym = prop_get_symbol(sym_get_choice_prop(last_sym)); + } + + for (stack = check_top; stack != NULL; stack = stack->prev) + if (stack->sym == last_sym) + break; + if (!stack) { + fprintf(stderr, "unexpected recursive dependency error\n"); + return; + } + + for (; stack; stack = stack->next) { + sym = stack->sym; + next_sym = stack->next ? stack->next->sym : last_sym; + prop = stack->prop; + + /* for choice values find the menu entry (used below) */ + if (sym_is_choice(sym) || sym_is_choice_value(sym)) { + for (prop = sym->prop; prop; prop = prop->next) { + menu = prop->menu; + if (prop->menu) + break; + } + } + if (stack->sym == last_sym) + fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", + prop->file->name, prop->lineno); + if (stack->expr) { + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "<choice>", + prop_get_type_name(prop->type), + next_sym->name ? next_sym->name : "<choice>"); + } else if (stack->prop) { + fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } else if (sym_is_choice(sym)) { + fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } else if (sym_is_choice_value(sym)) { + fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", + menu->file->name, menu->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } else { + fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", + prop->file->name, prop->lineno, + sym->name ? sym->name : "<choice>", + next_sym->name ? next_sym->name : "<choice>"); + } + } + + if (check_top == &cv_stack) + dep_stack_remove(); +} static struct symbol *sym_check_expr_deps(struct expr *e) { @@ -795,24 +1017,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) { struct symbol *sym2; struct property *prop; + struct dep_stack stack; + + dep_stack_insert(&stack, sym); sym2 = sym_check_expr_deps(sym->rev_dep.expr); if (sym2) - return sym2; + goto out; for (prop = sym->prop; prop; prop = prop->next) { if (prop->type == P_CHOICE || prop->type == P_SELECT) continue; + stack.prop = prop; sym2 = sym_check_expr_deps(prop->visible.expr); if (sym2) break; if (prop->type != P_DEFAULT || sym_is_choice(sym)) continue; + stack.expr = prop->expr; sym2 = sym_check_expr_deps(prop->expr); if (sym2) break; + stack.expr = NULL; } +out: + dep_stack_remove(); + return sym2; } @@ -821,6 +1052,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) struct symbol *sym, *sym2; struct property *prop; struct expr *e; + struct dep_stack stack; + + dep_stack_insert(&stack, choice); prop = sym_get_choice_prop(choice); expr_list_for_each_sym(prop->expr, e, sym) @@ -834,10 +1068,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) expr_list_for_each_sym(prop->expr, e, sym) { sym2 = sym_check_sym_deps(sym); - if (sym2) { - fprintf(stderr, " -> %s", sym->name); + if (sym2) break; - } } out: expr_list_for_each_sym(prop->expr, e, sym) @@ -847,6 +1079,8 @@ out: prop_get_symbol(sym_get_choice_prop(sym2)) == choice) sym2 = choice; + dep_stack_remove(); + return sym2; } @@ -856,18 +1090,20 @@ struct symbol *sym_check_deps(struct symbol *sym) struct property *prop; if (sym->flags & SYMBOL_CHECK) { - fprintf(stderr, "%s:%d:error: found recursive dependency: %s", - sym->prop->file->name, sym->prop->lineno, - sym->name ? sym->name : "<choice>"); + sym_check_print_recursive(sym); return sym; } if (sym->flags & SYMBOL_CHECKED) return NULL; if (sym_is_choice_value(sym)) { + struct dep_stack stack; + /* for choice groups start the check with main choice symbol */ + dep_stack_insert(&stack, sym); prop = sym_get_choice_prop(sym); sym2 = sym_check_deps(prop_get_symbol(prop)); + dep_stack_remove(); } else if (sym_is_choice(sym)) { sym2 = sym_check_choice_deps(sym); } else { @@ -876,14 +1112,8 @@ struct symbol *sym_check_deps(struct symbol *sym) sym->flags &= ~SYMBOL_CHECK; } - if (sym2) { - fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); - if (sym2 == sym) { - fprintf(stderr, "\n"); - zconfnerrs++; - sym2 = NULL; - } - } + if (sym2 && sym2 == sym) + sym2 = NULL; return sym2; } @@ -937,13 +1167,15 @@ const char *prop_get_type_name(enum prop_type type) return "select"; case P_RANGE: return "range"; + case P_SYMBOL: + return "symbol"; case P_UNKNOWN: break; } return "unknown"; } -void prop_add_env(const char *env) +static void prop_add_env(const char *env) { struct symbol *sym, *sym2; struct property *prop; diff --git a/package/config/util.c b/package/config/util.c index c3821407d..b15dbab33 100644 --- a/package/config/util.c +++ b/package/config/util.c @@ -199,12 +199,13 @@ int file_write_dep(const char *name) } -/* Allocate initial growable sting */ +/* Allocate initial growable string */ struct gstr str_new(void) { struct gstr gs; gs.s = malloc(sizeof(char) * 64); gs.len = 64; + gs.max_width = 0; strcpy(gs.s, "\0"); return gs; } @@ -215,6 +216,7 @@ struct gstr str_assign(const char *s) struct gstr gs; gs.s = strdup(s); gs.len = strlen(s) + 1; + gs.max_width = 0; return gs; } diff --git a/package/config/zconf.gperf b/package/config/zconf.gperf index 25ef5d01c..d8bc74249 100644 --- a/package/config/zconf.gperf +++ b/package/config/zconf.gperf @@ -9,6 +9,8 @@ struct kconf_id; +static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); + %% mainmenu, T_MAINMENU, TF_COMMAND menu, T_MENU, TF_COMMAND diff --git a/package/config/zconf.hash.c_shipped b/package/config/zconf.hash.c_shipped index 5c73d5133..c1748faf4 100644 --- a/package/config/zconf.hash.c_shipped +++ b/package/config/zconf.hash.c_shipped @@ -30,6 +30,8 @@ #endif struct kconf_id; + +static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); /* maximum key range = 47, duplicates = 0 */ #ifdef __GNUC__ diff --git a/package/config/zconf.l b/package/config/zconf.l index 21ff69c9a..d8f7236cb 100644 --- a/package/config/zconf.l +++ b/package/config/zconf.l @@ -39,7 +39,7 @@ static int last_ts, first_ts; static void zconf_endhelp(void); static void zconf_endfile(void); -void new_string(void) +static void new_string(void) { text = malloc(START_STRSIZE); text_asize = START_STRSIZE; @@ -47,7 +47,7 @@ void new_string(void) *text = 0; } -void append_string(const char *str, int size) +static void append_string(const char *str, int size) { int new_size = text_size + size + 1; if (new_size > text_asize) { @@ -61,7 +61,7 @@ void append_string(const char *str, int size) text[text_size] = 0; } -void alloc_string(const char *str, int size) +static void alloc_string(const char *str, int size) { text = malloc(size + 1); memcpy(text, str, size); diff --git a/package/config/zconf.tab.c_shipped b/package/config/zconf.tab.c_shipped index bb1e1da7c..73d8c1994 100644 --- a/package/config/zconf.tab.c_shipped +++ b/package/config/zconf.tab.c_shipped @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + 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. - + the Free Software Foundation, either version 3 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,94 +54,23 @@ /* Pure parsers. */ #define YYPURE 0 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ -#define yyparse zconfparse -#define yylex zconflex -#define yyerror zconferror -#define yylval zconflval -#define yychar zconfchar -#define yydebug zconfdebug -#define yynerrs zconfnerrs - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_MAINMENU = 258, - T_MENU = 259, - T_ENDMENU = 260, - T_SOURCE = 261, - T_CHOICE = 262, - T_ENDCHOICE = 263, - T_COMMENT = 264, - T_CONFIG = 265, - T_MENUCONFIG = 266, - T_HELP = 267, - T_HELPTEXT = 268, - T_IF = 269, - T_ENDIF = 270, - T_DEPENDS = 271, - T_OPTIONAL = 272, - T_PROMPT = 273, - T_TYPE = 274, - T_DEFAULT = 275, - T_SELECT = 276, - T_RANGE = 277, - T_OPTION = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 - }; -#endif -/* Tokens. */ -#define T_MAINMENU 258 -#define T_MENU 259 -#define T_ENDMENU 260 -#define T_SOURCE 261 -#define T_CHOICE 262 -#define T_ENDCHOICE 263 -#define T_COMMENT 264 -#define T_CONFIG 265 -#define T_MENUCONFIG 266 -#define T_HELP 267 -#define T_HELPTEXT 268 -#define T_IF 269 -#define T_ENDIF 270 -#define T_DEPENDS 271 -#define T_OPTIONAL 272 -#define T_PROMPT 273 -#define T_TYPE 274 -#define T_DEFAULT 275 -#define T_SELECT 276 -#define T_RANGE 277 -#define T_OPTION 278 -#define T_ON 279 -#define T_WORD 280 -#define T_WORD_QUOTE 281 -#define T_UNEQUAL 282 -#define T_CLOSE_PAREN 283 -#define T_OPEN_PAREN 284 -#define T_EOL 285 -#define T_OR 286 -#define T_AND 287 -#define T_EQUAL 288 -#define T_NOT 289 - - +#define yyparse zconfparse +#define yylex zconflex +#define yyerror zconferror +#define yylval zconflval +#define yychar zconfchar +#define yydebug zconfdebug +#define yynerrs zconfnerrs /* Copy the first part of user declarations. */ @@ -163,8 +91,6 @@ #define LKC_DIRECT_LINK #include "lkc.h" -#include "zconf.hash.c" - #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define PRINTD 0x0001 @@ -178,7 +104,7 @@ static void zconf_error(const char *err, ...); static void zconferror(const char *err); static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); -struct symbol *symbol_hash[257]; +struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; @@ -188,6 +114,7 @@ static struct menu *current_menu, *current_entry; #endif + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -206,31 +133,77 @@ static struct menu *current_menu, *current_entry; # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_MAINMENU = 258, + T_MENU = 259, + T_ENDMENU = 260, + T_SOURCE = 261, + T_CHOICE = 262, + T_ENDCHOICE = 263, + T_COMMENT = 264, + T_CONFIG = 265, + T_MENUCONFIG = 266, + T_HELP = 267, + T_HELPTEXT = 268, + T_IF = 269, + T_ENDIF = 270, + T_DEPENDS = 271, + T_OPTIONAL = 272, + T_PROMPT = 273, + T_TYPE = 274, + T_DEFAULT = 275, + T_SELECT = 276, + T_RANGE = 277, + T_OPTION = 278, + T_ON = 279, + T_WORD = 280, + T_WORD_QUOTE = 281, + T_UNEQUAL = 282, + T_CLOSE_PAREN = 283, + T_OPEN_PAREN = 284, + T_EOL = 285, + T_OR = 286, + T_AND = 287, + T_EQUAL = 288, + T_NOT = 289 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE - { + + char *string; struct file *file; struct symbol *symbol; struct expr *expr; struct menu *menu; struct kconf_id *id; -} -/* Line 187 of yacc.c. */ - YYSTYPE; + + +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif - /* Copy the second part of user declarations. */ -/* Line 216 of yacc.c. */ +/* Include zconf.hash.c here so it can see the token constants. */ +#include "zconf.hash.c" + #ifdef short @@ -306,14 +279,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -394,9 +367,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - }; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -430,12 +403,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -558,18 +531,18 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 104, 104, 106, 108, 109, 110, 111, 112, 113, - 114, 118, 122, 122, 122, 122, 122, 122, 122, 126, - 127, 128, 129, 130, 131, 135, 136, 142, 150, 156, - 164, 174, 176, 177, 178, 179, 180, 181, 184, 192, - 198, 208, 214, 220, 223, 225, 236, 237, 242, 251, - 256, 264, 267, 269, 270, 271, 272, 273, 276, 282, - 293, 299, 309, 311, 316, 324, 332, 335, 337, 338, - 339, 344, 351, 356, 364, 367, 369, 370, 371, 374, - 382, 389, 396, 402, 409, 411, 412, 413, 416, 424, - 426, 431, 432, 435, 436, 437, 441, 442, 445, 446, - 449, 450, 451, 452, 453, 454, 455, 458, 459, 462, - 463 + 0, 107, 107, 109, 111, 112, 113, 114, 115, 116, + 117, 121, 125, 125, 125, 125, 125, 125, 125, 129, + 130, 131, 132, 133, 134, 138, 139, 145, 153, 159, + 167, 177, 179, 180, 181, 182, 183, 184, 187, 195, + 201, 211, 217, 223, 226, 228, 239, 240, 245, 254, + 259, 267, 270, 272, 273, 274, 275, 276, 279, 285, + 296, 302, 312, 314, 319, 327, 335, 338, 340, 341, + 342, 347, 354, 359, 367, 370, 372, 373, 374, 377, + 385, 392, 399, 405, 412, 414, 415, 416, 419, 427, + 429, 434, 435, 438, 439, 440, 444, 445, 448, 449, + 452, 453, 454, 455, 456, 457, 458, 461, 462, 465, + 466 }; #endif @@ -985,17 +958,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -1029,11 +1005,11 @@ yy_reduce_print (yyvsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -1343,10 +1319,8 @@ yydestruct (yymsg, yytype, yyvaluep) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1362,11 +1336,10 @@ int yyparse (); #endif /* ! YYPARSE_PARAM */ - -/* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ @@ -1374,9 +1347,9 @@ int yynerrs; -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1400,66 +1373,68 @@ yyparse () #endif #endif { - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; @@ -1489,7 +1464,6 @@ yyparse () YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might @@ -1497,7 +1471,6 @@ yyparse () yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); yyss = yyss1; @@ -1520,9 +1493,8 @@ yyparse () (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -1533,7 +1505,6 @@ yyparse () yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -1543,6 +1514,9 @@ yyparse () YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -1551,16 +1525,16 @@ yyparse () yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1592,20 +1566,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -2029,7 +1999,6 @@ yyreduce: break; -/* Line 1267 of yacc.c. */ default: break; } @@ -2041,7 +2010,6 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2106,7 +2074,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -2123,7 +2091,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -2180,9 +2148,6 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; @@ -2207,7 +2172,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2218,7 +2183,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered @@ -2255,7 +2220,7 @@ void conf_parse(const char *name) zconf_initscan(name); sym_init(); - menu_init(); + _menu_init(); modules_sym = sym_lookup(NULL, 0); modules_sym->type = S_BOOLEAN; modules_sym->flags |= SYMBOL_AUTO; @@ -2284,7 +2249,7 @@ void conf_parse(const char *name) sym_set_change_count(1); } -const char *zconf_tokenname(int token) +static const char *zconf_tokenname(int token) { switch (token) { case T_MENU: return "menu"; @@ -2348,7 +2313,7 @@ static void zconferror(const char *err) #endif } -void print_quoted_string(FILE *out, const char *str) +static void print_quoted_string(FILE *out, const char *str) { const char *p; int len; @@ -2365,15 +2330,15 @@ void print_quoted_string(FILE *out, const char *str) putc('"', out); } -void print_symbol(FILE *out, struct menu *menu) +static 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"); + fprintf(out, "\nchoice\n"); else - fprintf(out, "config %s\n", sym->name); + fprintf(out, "\nconfig %s\n", sym->name); switch (sym->type) { case S_BOOLEAN: fputs(" boolean\n", out); @@ -2419,6 +2384,21 @@ void print_symbol(FILE *out, struct menu *menu) case P_CHOICE: fputs(" #choice value\n", out); break; + case P_SELECT: + fputs( " select ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_RANGE: + fputs( " range ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_MENU: + fputs( " menu ", out); + print_quoted_string(out, prop->text); + fputc('\n', out); + break; default: fprintf(out, " unknown prop %d!\n", prop->type); break; @@ -2430,7 +2410,6 @@ void print_symbol(FILE *out, struct menu *menu) menu->help[len] = 0; fprintf(out, " help\n%s\n", menu->help); } - fputc('\n', out); } void zconfdump(FILE *out) @@ -2463,7 +2442,6 @@ void zconfdump(FILE *out) expr_fprint(prop->visible.expr, out); fputc('\n', out); } - fputs("\n", out); } if (menu->list) diff --git a/package/config/zconf.y b/package/config/zconf.y index 62eee9cb8..956add165 100644 --- a/package/config/zconf.y +++ b/package/config/zconf.y @@ -14,8 +14,6 @@ #define LKC_DIRECT_LINK #include "lkc.h" -#include "zconf.hash.c" - #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define PRINTD 0x0001 @@ -29,7 +27,7 @@ static void zconf_error(const char *err, ...); static void zconferror(const char *err); static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); -struct symbol *symbol_hash[257]; +struct symbol *symbol_hash[SYMBOL_HASHSIZE]; static struct menu *current_menu, *current_entry; @@ -100,6 +98,11 @@ static struct menu *current_menu, *current_entry; menu_end_menu(); } if_entry menu_entry choice_entry +%{ +/* Include zconf.hash.c here so it can see the token constants. */ +#include "zconf.hash.c" +%} + %% input: stmt_list; @@ -472,7 +475,7 @@ void conf_parse(const char *name) zconf_initscan(name); sym_init(); - menu_init(); + _menu_init(); modules_sym = sym_lookup(NULL, 0); modules_sym->type = S_BOOLEAN; modules_sym->flags |= SYMBOL_AUTO; @@ -501,7 +504,7 @@ void conf_parse(const char *name) sym_set_change_count(1); } -const char *zconf_tokenname(int token) +static const char *zconf_tokenname(int token) { switch (token) { case T_MENU: return "menu"; @@ -565,7 +568,7 @@ static void zconferror(const char *err) #endif } -void print_quoted_string(FILE *out, const char *str) +static void print_quoted_string(FILE *out, const char *str) { const char *p; int len; @@ -582,15 +585,15 @@ void print_quoted_string(FILE *out, const char *str) putc('"', out); } -void print_symbol(FILE *out, struct menu *menu) +static 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"); + fprintf(out, "\nchoice\n"); else - fprintf(out, "config %s\n", sym->name); + fprintf(out, "\nconfig %s\n", sym->name); switch (sym->type) { case S_BOOLEAN: fputs(" boolean\n", out); @@ -636,6 +639,21 @@ void print_symbol(FILE *out, struct menu *menu) case P_CHOICE: fputs(" #choice value\n", out); break; + case P_SELECT: + fputs( " select ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_RANGE: + fputs( " range ", out); + expr_fprint(prop->expr, out); + fputc('\n', out); + break; + case P_MENU: + fputs( " menu ", out); + print_quoted_string(out, prop->text); + fputc('\n', out); + break; default: fprintf(out, " unknown prop %d!\n", prop->type); break; @@ -647,7 +665,6 @@ void print_symbol(FILE *out, struct menu *menu) menu->help[len] = 0; fprintf(out, " help\n%s\n", menu->help); } - fputc('\n', out); } void zconfdump(FILE *out) @@ -680,7 +697,6 @@ void zconfdump(FILE *out) expr_fprint(prop->visible.expr, out); fputc('\n', out); } - fputs("\n", out); } if (menu->list) |