support/kconfig: bump to kconfig from Linux 4.17-rc2

Signed-off-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
This commit is contained in:
Petr Vorel 2018-09-19 13:36:15 +02:00 committed by Thomas Petazzoni
parent 78dd830f15
commit 6eacea5ae0
48 changed files with 3557 additions and 3201 deletions

View File

@ -128,7 +128,7 @@ export BR2_VERSION_FULL := $(BR2_VERSION)$(shell $(TOPDIR)/support/scripts/setlo
# List of targets and target patterns for which .config doesn't need to be read in # List of targets and target patterns for which .config doesn't need to be read in
noconfig_targets := menuconfig nconfig gconfig xconfig config oldconfig randconfig \ noconfig_targets := menuconfig nconfig gconfig xconfig config oldconfig randconfig \
defconfig %_defconfig allyesconfig allnoconfig alldefconfig silentoldconfig release \ defconfig %_defconfig allyesconfig allnoconfig alldefconfig syncconfig release \
randpackageconfig allyespackageconfig allnopackageconfig \ randpackageconfig allyespackageconfig allnopackageconfig \
print-version olddefconfig distclean manual manual-% check-package print-version olddefconfig distclean manual manual-% check-package
@ -565,7 +565,7 @@ dirs: $(BUILD_DIR) $(STAGING_DIR) $(BASE_TARGET_DIR) \
$(HOST_DIR) $(HOST_DIR_SYMLINK) $(BINARIES_DIR) $(HOST_DIR) $(HOST_DIR_SYMLINK) $(BINARIES_DIR)
$(BUILD_DIR)/buildroot-config/auto.conf: $(BR2_CONFIG) $(BUILD_DIR)/buildroot-config/auto.conf: $(BR2_CONFIG)
$(MAKE1) $(EXTRAMAKEARGS) HOSTCC="$(HOSTCC_NOCCACHE)" HOSTCXX="$(HOSTCXX_NOCCACHE)" silentoldconfig $(MAKE1) $(EXTRAMAKEARGS) HOSTCC="$(HOSTCC_NOCCACHE)" HOSTCXX="$(HOSTCXX_NOCCACHE)" syncconfig
.PHONY: prepare .PHONY: prepare
prepare: $(BUILD_DIR)/buildroot-config/auto.conf prepare: $(BUILD_DIR)/buildroot-config/auto.conf
@ -933,7 +933,7 @@ randpackageconfig allyespackageconfig allnopackageconfig: $(BUILD_DIR)/buildroot
@rm -f $(CONFIG_DIR)/.config.nopkg @rm -f $(CONFIG_DIR)/.config.nopkg
@$(COMMON_CONFIG_ENV) $< --olddefconfig $(CONFIG_CONFIG_IN) >/dev/null @$(COMMON_CONFIG_ENV) $< --olddefconfig $(CONFIG_CONFIG_IN) >/dev/null
oldconfig silentoldconfig olddefconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig oldconfig syncconfig olddefconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig
@$(COMMON_CONFIG_ENV) $< --$@ $(CONFIG_CONFIG_IN) @$(COMMON_CONFIG_ENV) $< --$@ $(CONFIG_CONFIG_IN)
defconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig defconfig: $(BUILD_DIR)/buildroot-config/conf prepare-kconfig
@ -1029,8 +1029,8 @@ help:
@echo ' xconfig - interactive Qt-based configurator' @echo ' xconfig - interactive Qt-based configurator'
@echo ' gconfig - interactive GTK-based configurator' @echo ' gconfig - interactive GTK-based configurator'
@echo ' oldconfig - resolve any unresolved symbols in .config' @echo ' oldconfig - resolve any unresolved symbols in .config'
@echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' @echo ' syncconfig - Same as oldconfig, but quietly, additionally update deps'
@echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value' @echo ' olddefconfig - Same as syncconfig but sets new symbols to their default value'
@echo ' randconfig - New config with random answer to all options' @echo ' randconfig - New config with random answer to all options'
@echo ' defconfig - New config with default answer to all options;' @echo ' defconfig - New config with default answer to all options;'
@echo ' BR2_DEFCONFIG, if set on the command line, is used as input' @echo ' BR2_DEFCONFIG, if set on the command line, is used as input'

View File

@ -1,60 +1,70 @@
# SPDX-License-Identifier: GPL-2.0
# =========================================================================== # ===========================================================================
# Kernel configuration targets # Kernel configuration targets
# These targets are used from top-level makefile # These targets are used from top-level makefile
PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \
localmodconfig localyesconfig localmodconfig localyesconfig
# Easy method for doing a status message
kecho := :
quiet_kecho := echo
silent_kecho := :
kecho := $($(quiet)kecho)
ifdef KBUILD_KCONFIG ifdef KBUILD_KCONFIG
Kconfig := $(KBUILD_KCONFIG) Kconfig := $(KBUILD_KCONFIG)
else else
Kconfig := Kconfig Kconfig := Kconfig
endif endif
ifeq ($(quiet),silent_)
silent := -s
endif
# We need this, in case the user has it in its environment # We need this, in case the user has it in its environment
unexport CONFIG_ unexport CONFIG_
xconfig: $(obj)/qconf xconfig: $(obj)/qconf
$< $(Kconfig) $< $(silent) $(Kconfig)
gconfig: $(obj)/gconf gconfig: $(obj)/gconf
$< $(Kconfig) $< $(silent) $(Kconfig)
menuconfig: $(obj)/mconf menuconfig: $(obj)/mconf
$< $(Kconfig) $< $(silent) $(Kconfig)
config: $(obj)/conf config: $(obj)/conf
$< --oldaskconfig $(Kconfig) $< $(silent) --oldaskconfig $(Kconfig)
nconfig: $(obj)/nconf nconfig: $(obj)/nconf
$< $(Kconfig) $< $(silent) $(Kconfig)
oldconfig: $(obj)/conf # This has become an internal implementation detail and is now deprecated
$< --$@ $(Kconfig) # for external use.
syncconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
$< $(silent) --$@ $(Kconfig)
silentoldconfig: $(obj)/conf localyesconfig localmodconfig: $(obj)/conf
$(Q)mkdir -p include/generated $(Q)mkdir -p include/config include/generated
$< --$@ $(Kconfig) $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config
localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
$(Q)mkdir -p include/generated
$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
$(Q)if [ -f .config ]; then \ $(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \ cmp -s .tmp.config .config || \
(mv -f .config .config.old.1; \ (mv -f .config .config.old.1; \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
$(obj)/conf --silentoldconfig $(Kconfig); \ $< $(silent) --oldconfig $(Kconfig); \
mv -f .config.old.1 .config.old) \ mv -f .config.old.1 .config.old) \
else \ else \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
$(obj)/conf --silentoldconfig $(Kconfig); \ $< $(silent) --oldconfig $(Kconfig); \
fi fi
$(Q)rm -f .tmp.config $(Q)rm -f .tmp.config
# Create new linux.pot file # Create new linux.pot file
# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
$(Q)echo " GEN config.pot" $(Q)$(kecho) " GEN config.pot"
$(Q)xgettext --default-domain=linux \ $(Q)xgettext --default-domain=linux \
--add-comments --keyword=_ --keyword=N_ \ --add-comments --keyword=_ --keyword=N_ \
--from-code=UTF-8 \ --from-code=UTF-8 \
@ -65,56 +75,96 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
$(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \
$(srctree)/arch/*/um/Kconfig`; \ $(srctree)/arch/*/um/Kconfig`; \
do \ do \
echo " GEN $$i"; \ $(kecho) " GEN $$i"; \
$(obj)/kxgettext $$i \ $(obj)/kxgettext $$i \
>> $(obj)/config.pot; \ >> $(obj)/config.pot; \
done ) done )
$(Q)echo " GEN linux.pot" $(Q)$(kecho) " GEN linux.pot"
$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
--output $(obj)/linux.pot --output $(obj)/linux.pot
$(Q)rm -f $(obj)/config.pot $(Q)rm -f $(obj)/config.pot
PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig # These targets map 1:1 to the commandline options of 'conf'
simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
alldefconfig randconfig listnewconfig olddefconfig
PHONY += $(simple-targets)
allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf $(simple-targets): $(obj)/conf
$< --$@ $(Kconfig) $< $(silent) --$@ $(Kconfig)
PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig PHONY += oldnoconfig silentoldconfig savedefconfig defconfig
listnewconfig olddefconfig: $(obj)/conf
$< --$@ $(Kconfig)
# oldnoconfig is an alias of olddefconfig, because people already are dependent # oldnoconfig is an alias of olddefconfig, because people already are dependent
# on its behavior(sets new symbols to their default value but not 'n') with the # on its behavior (sets new symbols to their default value but not 'n') with the
# counter-intuitive name. # counter-intuitive name.
oldnoconfig: $(obj)/conf oldnoconfig: olddefconfig
$< --olddefconfig $(Kconfig) @echo " WARNING: \"oldnoconfig\" target will be removed after Linux 4.19"
@echo " Please use \"olddefconfig\" instead, which is an alias."
# We do not expect manual invokcation of "silentoldcofig" (or "syncconfig").
silentoldconfig: syncconfig
@echo " WARNING: \"silentoldconfig\" has been renamed to \"syncconfig\""
@echo " and is now an internal implementation detail."
@echo " What you want is probably \"oldconfig\"."
@echo " \"silentoldconfig\" will be removed after Linux 4.19"
savedefconfig: $(obj)/conf savedefconfig: $(obj)/conf
$< --$@=defconfig $(Kconfig) $< $(silent) --$@=defconfig $(Kconfig)
defconfig: $(obj)/conf defconfig: $(obj)/conf
ifeq ($(KBUILD_DEFCONFIG),) ifeq ($(KBUILD_DEFCONFIG),)
$< --defconfig $(Kconfig) $< $(silent) --defconfig $(Kconfig)
else else
@echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
else
@$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
$(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
endif
endif endif
%_defconfig: $(obj)/conf %_defconfig: $(obj)/conf
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
%.config: $(obj)/conf
$(if $(call configfiles),, $(error No configuration exists for this target on this architecture))
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles)
+$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
PHONY += kvmconfig
kvmconfig: kvm_guest.config
@:
PHONY += xenconfig
xenconfig: xen.config
@:
PHONY += tinyconfig
tinyconfig:
$(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
# CHECK: -o cache_dir=<path> working?
PHONY += testconfig
testconfig: $(obj)/conf
$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \
-o cache_dir=$(abspath $(obj)/tests/.cache) \
$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
clean-dirs += tests/.cache
# Help text used by make help # Help text used by make help
help: help:
@echo ' config - Update current config utilising a line-oriented program' @echo ' config - Update current config utilising a line-oriented program'
@echo ' nconfig - Update current config utilising a ncurses menu based program' @echo ' nconfig - Update current config utilising a ncurses menu based'
@echo ' program'
@echo ' menuconfig - Update current config utilising a 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 ' xconfig - Update current config utilising a Qt based front-end'
@echo ' gconfig - Update current config utilising a GTK 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 ' oldconfig - Update current config utilising a provided .config as base'
@echo ' localmodconfig - Update current config disabling modules not loaded' @echo ' localmodconfig - Update current config disabling modules not loaded'
@echo ' localyesconfig - Update current config converting local mods to core' @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 ' defconfig - New config with default from ARCH supplied defconfig'
@echo ' savedefconfig - Save current config as ./defconfig (minimal config)' @echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
@echo ' allnoconfig - New config where all options are answered with no' @echo ' allnoconfig - New config where all options are answered with no'
@ -123,7 +173,11 @@ help:
@echo ' alldefconfig - New config with all symbols set to default' @echo ' alldefconfig - New config with all symbols set to default'
@echo ' randconfig - New config with random answer to all options' @echo ' randconfig - New config with random answer to all options'
@echo ' listnewconfig - List new options' @echo ' listnewconfig - List new options'
@echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value' @echo ' olddefconfig - Same as oldconfig but sets new symbols to their'
@echo ' default value without prompting'
@echo ' kvmconfig - Enable additional options for kvm guest kernel support'
@echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support'
@echo ' tinyconfig - Configure the tiniest possible kernel'
# lxdialog stuff # lxdialog stuff
check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
@ -141,9 +195,9 @@ HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
# mconf: Used for the menuconfig target # mconf: Used for the menuconfig target
# Utilizes the lxdialog package # Utilizes the lxdialog package
# qconf: Used for the xconfig target # qconf: Used for the xconfig target
# Based on QT which needs to be installed to compile it # Based on Qt which needs to be installed to compile it
# gconf: Used for the gconfig target # gconf: Used for the gconfig target
# Based on GTK which needs to be installed to compile it # Based on GTK+ which needs to be installed to compile it
# object files used by all kconfig flavours # object files used by all kconfig flavours
lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
@ -174,11 +228,11 @@ endif
ifeq ($(MAKECMDGOALS),qconf) ifeq ($(MAKECMDGOALS),qconf)
qconf-target := 1 qconf-target := 1
endif endif
ifeq ($(MAKECMDGOALS),gconf) ifeq ($(MAKECMDGOALS),gconf)
gconf-target := 1 gconf-target := 1
endif endif
ifeq ($(qconf-target),1) ifeq ($(qconf-target),1)
hostprogs-y += qconf hostprogs-y += qconf
endif endif
@ -187,14 +241,14 @@ ifeq ($(gconf-target),1)
hostprogs-y += gconf hostprogs-y += gconf
endif endif
targets += zconf.lex.c
clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck
clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h clean-files += gconf.glade.h
clean-files += mconf qconf gconf nconf
clean-files += config.pot linux.pot clean-files += config.pot linux.pot
# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) # Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
PHONY += $(obj)/dochecklxdialog PHONY += $(obj)/dochecklxdialog
$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog $(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog
$(obj)/dochecklxdialog: $(obj)/dochecklxdialog:
$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf) $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
@ -202,14 +256,12 @@ always := dochecklxdialog
# Add environment specific flags # Add environment specific flags
HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
HOST_EXTRACXXFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCXX) $(HOSTCXXFLAGS))
# generated files seem to need this to find local include files # generated files seem to need this to find local include files
HOSTCFLAGS_zconf.lex.o := -I$(src) HOSTCFLAGS_zconf.lex.o := -I$(src)
HOSTCFLAGS_zconf.tab.o := -I$(src) HOSTCFLAGS_zconf.tab.o := -I$(src)
LEX_PREFIX_zconf := zconf
YACC_PREFIX_zconf := zconf
HOSTLOADLIBES_qconf = $(KC_QT_LIBS) HOSTLOADLIBES_qconf = $(KC_QT_LIBS)
HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS)
@ -225,67 +277,38 @@ HOSTLOADLIBES_nconf = $(shell \
|| echo "-lmenu -lpanel -lncurses" ) || echo "-lmenu -lpanel -lncurses" )
$(obj)/qconf.o: $(obj)/.tmp_qtcheck $(obj)/qconf.o: $(obj)/.tmp_qtcheck
ifeq ($(qconf-target),1) ifeq ($(MAKECMDGOALS),qconf)
$(obj)/.tmp_qtcheck: $(src)/Makefile $(obj)/.tmp_qtcheck: $(src)/Makefile
-include $(obj)/.tmp_qtcheck -include $(obj)/.tmp_qtcheck
# QT needs some extra effort... # Qt needs some extra effort...
$(obj)/.tmp_qtcheck: $(obj)/.tmp_qtcheck:
@set -e; echo " CHECK qt"; dir=""; pkg=""; \ @set -e; $(kecho) " CHECK qt"; \
if ! pkg-config --exists QtCore 2> /dev/null; then \ if pkg-config --exists Qt5Core; then \
echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \ cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
pkg-config --exists qt 2> /dev/null && pkg=qt; \ libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
if [ -n "$$pkg" ]; then \ elif pkg-config --exists QtCore; then \
cflags="\$$(shell pkg-config $$pkg --cflags)"; \ cflags=`pkg-config --cflags QtCore QtGui`; \
libs="\$$(shell pkg-config $$pkg --libs)"; \ libs=`pkg-config --libs QtCore QtGui`; \
moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ moc=`pkg-config --variable=moc_location QtCore`; \
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 >&2 "*"; \
echo >&2 "* Unable to find any QT installation. Please make sure that"; \
echo >&2 "* the QT4 or QT3 development package is correctly installed and"; \
echo >&2 "* either qmake can be found or install pkg-config or set"; \
echo >&2 "* the QTDIR environment variable to the correct location."; \
echo >&2 "*"; \
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; \
else \ else \
cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \ echo >&2 "*"; \
libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \ echo >&2 "* Could not find Qt via pkg-config."; \
moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \ echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
[ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \ echo >&2 "*"; \
exit 1; \
fi; \ fi; \
echo "KC_QT_CFLAGS=$$cflags" > $@; \ echo "KC_QT_CFLAGS=$$cflags" > $@; \
echo "KC_QT_LIBS=$$libs" >> $@; \ echo "KC_QT_LIBS=$$libs" >> $@; \
echo "KC_QT_MOC=$$moc" >> $@ echo "KC_QT_MOC=$$moc" >> $@
endif endif
ifeq ($(MAKECMDGOALS),gconf)
$(obj)/gconf.o: $(obj)/.tmp_gtkcheck $(obj)/gconf.o: $(obj)/.tmp_gtkcheck
ifeq ($(gconf-target),1)
-include $(obj)/.tmp_gtkcheck -include $(obj)/.tmp_gtkcheck
# GTK needs some extra effort, too... # GTK+ needs some extra effort, too...
$(obj)/.tmp_gtkcheck: $(obj)/.tmp_gtkcheck:
@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ @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 \ if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \
@ -306,15 +329,14 @@ $(obj)/.tmp_gtkcheck:
fi fi
endif endif
$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c $(obj)/zconf.tab.o: $(obj)/zconf.lex.c
$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/qconf.o: $(obj)/qconf.moc
$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck $(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck
$(KC_QT_MOC) -i $< -o $@ $(KC_QT_MOC) -i $< -o $@
# Extract gconf menu items for I18N support # Extract gconf menu items for i18n support
$(obj)/gconf.glade.h: $(obj)/gconf.glade $(obj)/gconf.glade.h: $(obj)/gconf.glade
$(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \
$(obj)/gconf.glade $(obj)/gconf.glade

View File

@ -1,9 +1,13 @@
This is a copy of the kconfig code in the kernel (currently 3.13-rc5) tweaked This is a copy of the kconfig code in the kernel (currently 4.17-rc2) tweaked
to suit Buildroot. to suit Buildroot.
To update: To update:
cp -r /usr/src/linux/scripts/kconfig support/kconfig.new cp -r /usr/src/linux/scripts/kconfig support/kconfig.new
cd support/kconfig.new cd support/kconfig.new
# zconf.lex.c and zconf.tab.c needs to be generated by 'make menuconfig'
mv zconf.lex.c zconf.lex.c_shipped
mv zconf.tab.c zconf.tab.c_shipped
rm -rf tests/
cp -a ../kconfig/patches ../kconfig/README.buildroot ../kconfig/.gitignore . cp -a ../kconfig/patches ../kconfig/README.buildroot ../kconfig/.gitignore .
quilt push -a quilt push -a
# Fix any conflict # Fix any conflict

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Needed for systems without gettext # Needed for systems without gettext
$* -x c -o /dev/null - > /dev/null 2>&1 << EOF $* -x c -o /dev/null - > /dev/null 2>&1 << EOF
#include <libintl.h> #include <libintl.h>
@ -11,4 +12,3 @@ EOF
if [ ! "$?" -eq "0" ]; then if [ ! "$?" -eq "0" ]; then
echo -DKBUILD_NO_NLS; echo -DKBUILD_NO_NLS;
fi fi

View File

@ -5,6 +5,7 @@
#include <locale.h> #include <locale.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -19,11 +20,10 @@
static void conf(struct menu *menu); static void conf(struct menu *menu);
static void check_conf(struct menu *menu); static void check_conf(struct menu *menu);
static void xfgets(char *str, int size, FILE *in);
enum input_mode { enum input_mode {
oldaskconfig, oldaskconfig,
silentoldconfig, syncconfig,
oldconfig, oldconfig,
allnoconfig, allnoconfig,
allyesconfig, allyesconfig,
@ -34,14 +34,14 @@ enum input_mode {
savedefconfig, savedefconfig,
listnewconfig, listnewconfig,
olddefconfig, olddefconfig,
} input_mode = oldaskconfig; };
static enum input_mode input_mode = oldaskconfig;
static int indent = 1; static int indent = 1;
static int tty_stdio; static int tty_stdio;
static int valid_stdin = 1;
static int sync_kconfig; static int sync_kconfig;
static int conf_cnt; static int conf_cnt;
static char line[128]; static char line[PATH_MAX];
static struct menu *rootEntry; static struct menu *rootEntry;
static void print_help(struct menu *menu) static void print_help(struct menu *menu)
@ -71,14 +71,14 @@ static void strip(char *str)
*p-- = 0; *p-- = 0;
} }
static void check_stdin(void) /* Helper function to facilitate fgets() by Jean Sacren. */
static void xfgets(char *str, int size, FILE *in)
{ {
if (!valid_stdin) { if (!fgets(str, size, in))
printf(_("aborted!\n\n")); fprintf(stderr, "\nError in reading or end of file.\n");
printf(_("Console input/output is redirected. "));
printf(_("Run 'make oldconfig' to update configuration.\n\n")); if (!tty_stdio)
exit(1); printf("%s", str);
}
} }
static int conf_askvalue(struct symbol *sym, const char *def) static int conf_askvalue(struct symbol *sym, const char *def)
@ -100,18 +100,15 @@ static int conf_askvalue(struct symbol *sym, const char *def)
switch (input_mode) { switch (input_mode) {
case oldconfig: case oldconfig:
case silentoldconfig: case syncconfig:
if (sym_has_value(sym)) { if (sym_has_value(sym)) {
printf("%s\n", def); printf("%s\n", def);
return 0; return 0;
} }
check_stdin();
/* fall through */ /* fall through */
case oldaskconfig: case oldaskconfig:
fflush(stdout); fflush(stdout);
xfgets(line, 128, stdin); xfgets(line, sizeof(line), stdin);
if (!tty_stdio)
printf("\n");
return 1; return 1;
default: default:
break; break;
@ -191,9 +188,7 @@ static int conf_sym(struct menu *menu)
printf("/m"); printf("/m");
if (oldval != yes && sym_tristate_within_range(sym, yes)) if (oldval != yes && sym_tristate_within_range(sym, yes))
printf("/y"); printf("/y");
if (menu_has_help(menu)) printf("/?] ");
printf("/?");
printf("] ");
if (!conf_askvalue(sym, sym_get_string_value(sym))) if (!conf_askvalue(sym, sym_get_string_value(sym)))
return 0; return 0;
strip(line); strip(line);
@ -295,23 +290,19 @@ static int conf_choice(struct menu *menu)
printf("[1]: 1\n"); printf("[1]: 1\n");
goto conf_childs; goto conf_childs;
} }
printf("[1-%d", cnt); printf("[1-%d?]: ", cnt);
if (menu_has_help(menu))
printf("?");
printf("]: ");
switch (input_mode) { switch (input_mode) {
case oldconfig: case oldconfig:
case silentoldconfig: case syncconfig:
if (!is_new) { if (!is_new) {
cnt = def; cnt = def;
printf("%d\n", cnt); printf("%d\n", cnt);
break; break;
} }
check_stdin();
/* fall through */ /* fall through */
case oldaskconfig: case oldaskconfig:
fflush(stdout); fflush(stdout);
xfgets(line, 128, stdin); xfgets(line, sizeof(line), stdin);
strip(line); strip(line);
if (line[0] == '?') { if (line[0] == '?') {
print_help(menu); print_help(menu);
@ -367,10 +358,11 @@ static void conf(struct menu *menu)
switch (prop->type) { switch (prop->type) {
case P_MENU: case P_MENU:
if ((input_mode == silentoldconfig || /*
input_mode == listnewconfig || * Except in oldaskconfig mode, we show only menus that
input_mode == olddefconfig) && * contain new symbols.
rootEntry != menu) { */
if (input_mode != oldaskconfig && rootEntry != menu) {
check_conf(menu); check_conf(menu);
return; return;
} }
@ -430,10 +422,20 @@ static void check_conf(struct menu *menu)
if (sym_is_changable(sym) || if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (input_mode == listnewconfig) { if (input_mode == listnewconfig) {
if (sym->name && !sym_is_choice_value(sym)) { if (sym->name) {
printf("%s%s\n", CONFIG_, sym->name); const char *str;
if (sym->type == S_STRING) {
str = sym_get_string_value(sym);
str = sym_escape_string_value(str);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
free((void *)str);
} else {
str = sym_get_string_value(sym);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
}
} }
} else if (input_mode != olddefconfig) { } else {
if (!conf_cnt++) if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n")); printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu); rootEntry = menu_get_parent_menu(menu);
@ -449,7 +451,7 @@ static void check_conf(struct menu *menu)
static struct option long_opts[] = { static struct option long_opts[] = {
{"oldaskconfig", no_argument, NULL, oldaskconfig}, {"oldaskconfig", no_argument, NULL, oldaskconfig},
{"oldconfig", no_argument, NULL, oldconfig}, {"oldconfig", no_argument, NULL, oldconfig},
{"silentoldconfig", no_argument, NULL, silentoldconfig}, {"syncconfig", no_argument, NULL, syncconfig},
{"defconfig", optional_argument, NULL, defconfig}, {"defconfig", optional_argument, NULL, defconfig},
{"savedefconfig", required_argument, NULL, savedefconfig}, {"savedefconfig", required_argument, NULL, savedefconfig},
{"allnoconfig", no_argument, NULL, allnoconfig}, {"allnoconfig", no_argument, NULL, allnoconfig},
@ -471,13 +473,14 @@ static struct option long_opts[] = {
static void conf_usage(const char *progname) static void conf_usage(const char *progname)
{ {
printf("Usage: %s [option] <kconfig-file>\n", progname); printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
printf("[option] is _one_ of the following:\n"); printf("[option] is _one_ of the following:\n");
printf(" --listnewconfig List new options\n"); printf(" --listnewconfig List new options\n");
printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
printf(" --oldconfig Update a configuration using a provided .config as base\n"); printf(" --oldconfig Update a configuration using a provided .config as base\n");
printf(" --silentoldconfig Same as oldconfig, but quietly, additionally update deps\n"); printf(" --syncconfig Similar to oldconfig but generates configuration in\n"
printf(" --olddefconfig Same as silentoldconfig but sets new symbols to their default value\n"); " include/{generated/,config/}\n");
printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n");
printf(" --oldnoconfig An alias of olddefconfig\n"); printf(" --oldnoconfig An alias of olddefconfig\n");
printf(" --defconfig <file> New config with default defined in <file>\n"); printf(" --defconfig <file> New config with default defined in <file>\n");
printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n"); printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
@ -499,12 +502,16 @@ int main(int ac, char **av)
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE); textdomain(PACKAGE);
tty_stdio = isatty(0) && isatty(1) && isatty(2); tty_stdio = isatty(0) && isatty(1);
while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
if (opt == 's') {
conf_set_message_callback(NULL);
continue;
}
input_mode = (enum input_mode)opt; input_mode = (enum input_mode)opt;
switch (opt) { switch (opt) {
case silentoldconfig: case syncconfig:
sync_kconfig = 1; sync_kconfig = 1;
break; break;
case defconfig: case defconfig:
@ -552,7 +559,7 @@ int main(int ac, char **av)
} }
} }
if (ac == optind) { if (ac == optind) {
printf(_("%s: Kconfig file missing\n"), av[0]); fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]);
conf_usage(progname); conf_usage(progname);
exit(1); exit(1);
} }
@ -576,14 +583,16 @@ int main(int ac, char **av)
if (!defconfig_file) if (!defconfig_file)
defconfig_file = conf_get_default_confname(); defconfig_file = conf_get_default_confname();
if (conf_read(defconfig_file)) { if (conf_read(defconfig_file)) {
printf(_("***\n" fprintf(stderr,
"*** Can't find default configuration \"%s\"!\n" _("***\n"
"***\n"), defconfig_file); "*** Can't find default configuration \"%s\"!\n"
"***\n"),
defconfig_file);
exit(1); exit(1);
} }
break; break;
case savedefconfig: case savedefconfig:
case silentoldconfig: case syncconfig:
case oldaskconfig: case oldaskconfig:
case oldconfig: case oldconfig:
case listnewconfig: case listnewconfig:
@ -636,7 +645,6 @@ int main(int ac, char **av)
return 1; return 1;
} }
} }
valid_stdin = tty_stdio;
} }
switch (input_mode) { switch (input_mode) {
@ -664,24 +672,24 @@ int main(int ac, char **av)
case oldaskconfig: case oldaskconfig:
rootEntry = &rootmenu; rootEntry = &rootmenu;
conf(&rootmenu); conf(&rootmenu);
input_mode = silentoldconfig; input_mode = oldconfig;
/* fall through */ /* fall through */
case oldconfig: case oldconfig:
case listnewconfig: case listnewconfig:
case olddefconfig: case syncconfig:
case silentoldconfig:
/* Update until a loop caused no more changes */ /* Update until a loop caused no more changes */
do { do {
conf_cnt = 0; conf_cnt = 0;
check_conf(&rootmenu); check_conf(&rootmenu);
} while (conf_cnt && } while (conf_cnt);
(input_mode != listnewconfig && break;
input_mode != olddefconfig)); case olddefconfig:
default:
break; break;
} }
if (sync_kconfig) { if (sync_kconfig) {
/* silentoldconfig is used during the build so we shall update autoconf. /* syncconfig is used during the build so we shall update autoconf.
* All other commands are only used to generate a config. * All other commands are only used to generate a config.
*/ */
if (conf_get_changed() && conf_write(NULL)) { if (conf_get_changed() && conf_write(NULL)) {
@ -695,7 +703,7 @@ int main(int ac, char **av)
} else if (input_mode == savedefconfig) { } else if (input_mode == savedefconfig) {
if (conf_write_defconfig(defconfig_file)) { if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
defconfig_file); defconfig_file);
return 1; return 1;
} }
} else if (input_mode != listnewconfig) { } else if (input_mode != listnewconfig) {
@ -706,12 +714,3 @@ int main(int ac, char **av)
} }
return 0; return 0;
} }
/*
* Helper function to facilitate fgets() by Jean Sacren.
*/
void xfgets(char *str, int size, FILE *in)
{
if (fgets(str, size, in) == NULL)
fprintf(stderr, "\nError in reading or end of file.\n");
}

View File

@ -17,6 +17,11 @@
#include "lkc.h" #include "lkc.h"
struct conf_printer {
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
void (*print_comment)(FILE *, const char *, void *);
};
static void conf_warning(const char *fmt, ...) static void conf_warning(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
@ -24,7 +29,7 @@ static void conf_message(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
static const char *conf_filename; static const char *conf_filename;
static int conf_lineno, conf_warnings, conf_unsaved; static int conf_lineno, conf_warnings;
const char conf_defname[] = ".defconfig"; const char conf_defname[] = ".defconfig";
@ -60,6 +65,7 @@ static void conf_message(const char *fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
if (conf_message_callback) if (conf_message_callback)
conf_message_callback(fmt, ap); conf_message_callback(fmt, ap);
va_end(ap);
} }
const char *conf_get_configname(void) const char *conf_get_configname(void)
@ -171,7 +177,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
case S_HEX: case S_HEX:
done: done:
if (sym_string_valid(sym, p)) { if (sym_string_valid(sym, p)) {
sym->def[def].val = strdup(p); sym->def[def].val = xstrdup(p);
sym->flags |= def_flags; sym->flags |= def_flags;
} else { } else {
if (def != S_DEF_AUTO) if (def != S_DEF_AUTO)
@ -194,7 +200,7 @@ static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
if (new_size > *n) { if (new_size > *n) {
new_size += LINE_GROWTH - 1; new_size += LINE_GROWTH - 1;
new_size *= 2; new_size *= 2;
nline = realloc(*lineptr, new_size); nline = xrealloc(*lineptr, new_size);
if (!nline) if (!nline)
return -1; return -1;
@ -260,11 +266,8 @@ int conf_read_simple(const char *name, int def)
if (in) if (in)
goto load; goto load;
sym_add_change_count(1); sym_add_change_count(1);
if (!sym_defconfig_list) { if (!sym_defconfig_list)
if (modules_sym)
sym_calc_value(modules_sym);
return 1; return 1;
}
for_all_defaults(sym_defconfig_list, prop) { for_all_defaults(sym_defconfig_list, prop) {
if (expr_calc_value(prop->visible.expr) == no || if (expr_calc_value(prop->visible.expr) == no ||
@ -286,7 +289,6 @@ load:
conf_filename = name; conf_filename = name;
conf_lineno = 0; conf_lineno = 0;
conf_warnings = 0; conf_warnings = 0;
conf_unsaved = 0;
def_flags = SYMBOL_DEF << def; def_flags = SYMBOL_DEF << def;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
@ -371,7 +373,9 @@ load:
continue; continue;
} else { } else {
if (line[0] != '\r' && line[0] != '\n') if (line[0] != '\r' && line[0] != '\n')
conf_warning("unexpected data"); conf_warning("unexpected data: %.*s",
(int)strcspn(line, "\r\n"), line);
continue; continue;
} }
setsym: setsym:
@ -397,21 +401,23 @@ setsym:
} }
free(line); free(line);
fclose(in); fclose(in);
if (modules_sym)
sym_calc_value(modules_sym);
return 0; return 0;
} }
int conf_read(const char *name) int conf_read(const char *name)
{ {
struct symbol *sym; struct symbol *sym;
int conf_unsaved = 0;
int i; int i;
sym_set_change_count(0); sym_set_change_count(0);
if (conf_read_simple(name, S_DEF_USER)) if (conf_read_simple(name, S_DEF_USER)) {
sym_calc_value(modules_sym);
return 1; return 1;
}
sym_calc_value(modules_sym);
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
sym_calc_value(sym); sym_calc_value(sym);
@ -846,6 +852,7 @@ static int conf_split_config(void)
name = conf_get_autoconfig_name(); name = conf_get_autoconfig_name();
conf_read_simple(name, S_DEF_AUTO); conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym);
opwd = malloc(256); opwd = malloc(256);
_name = strdup(name); _name = strdup(name);
@ -1149,7 +1156,7 @@ void set_all_choice_values(struct symbol *csym)
bool conf_set_all_new_symbols(enum conf_def_mode mode) bool conf_set_all_new_symbols(enum conf_def_mode mode)
{ {
struct symbol *sym, *csym; struct symbol *sym, *csym;
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y int i, cnt, pby, pty, ptm; /* pby: probability of bool = y
* pty: probability of tristate = y * pty: probability of tristate = y
* ptm: probability of tristate = m * ptm: probability of tristate = m
*/ */
@ -1211,7 +1218,10 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode)
sym->def[S_DEF_USER].tri = mod; sym->def[S_DEF_USER].tri = mod;
break; break;
case def_no: case def_no:
sym->def[S_DEF_USER].tri = no; if (sym->flags & SYMBOL_ALLNOCONFIG_Y)
sym->def[S_DEF_USER].tri = yes;
else
sym->def[S_DEF_USER].tri = no;
break; break;
case def_random: case def_random:
sym->def[S_DEF_USER].tri = no; sym->def[S_DEF_USER].tri = no;

View File

@ -11,6 +11,9 @@
#define DEBUG_EXPR 0 #define DEBUG_EXPR 0
static int expr_eq(struct expr *e1, struct expr *e2);
static struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_alloc_symbol(struct symbol *sym) struct expr *expr_alloc_symbol(struct symbol *sym)
{ {
struct expr *e = xcalloc(1, sizeof(*e)); struct expr *e = xcalloc(1, sizeof(*e));
@ -76,6 +79,10 @@ struct expr *expr_copy(const struct expr *org)
e->left.expr = expr_copy(org->left.expr); e->left.expr = expr_copy(org->left.expr);
break; break;
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
e->left.sym = org->left.sym; e->left.sym = org->left.sym;
e->right.sym = org->right.sym; e->right.sym = org->right.sym;
@ -87,7 +94,7 @@ struct expr *expr_copy(const struct expr *org)
e->right.expr = expr_copy(org->right.expr); e->right.expr = expr_copy(org->right.expr);
break; break;
default: default:
printf("can't copy type %d\n", e->type); fprintf(stderr, "can't copy type %d\n", e->type);
free(e); free(e);
e = NULL; e = NULL;
break; break;
@ -106,8 +113,12 @@ void expr_free(struct expr *e)
break; break;
case E_NOT: case E_NOT:
expr_free(e->left.expr); expr_free(e->left.expr);
return; break;
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
break; break;
case E_OR: case E_OR:
@ -116,7 +127,7 @@ void expr_free(struct expr *e)
expr_free(e->right.expr); expr_free(e->right.expr);
break; break;
default: default:
printf("how to free type %d?\n", e->type); fprintf(stderr, "how to free type %d?\n", e->type);
break; break;
} }
free(e); free(e);
@ -127,8 +138,18 @@ static int trans_count;
#define e1 (*ep1) #define e1 (*ep1)
#define e2 (*ep2) #define e2 (*ep2)
/*
* expr_eliminate_eq() helper.
*
* Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
* not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
* against all other leaves. Two equal leaves are both replaced with either 'y'
* or 'n' as appropriate for 'type', to be eliminated later.
*/
static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
{ {
/* Recurse down to leaves */
if (e1->type == type) { if (e1->type == type) {
__expr_eliminate_eq(type, &e1->left.expr, &e2); __expr_eliminate_eq(type, &e1->left.expr, &e2);
__expr_eliminate_eq(type, &e1->right.expr, &e2); __expr_eliminate_eq(type, &e1->right.expr, &e2);
@ -139,12 +160,18 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
__expr_eliminate_eq(type, &e1, &e2->right.expr); __expr_eliminate_eq(type, &e1, &e2->right.expr);
return; return;
} }
/* e1 and e2 are leaves. Compare them. */
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
e1->left.sym == e2->left.sym && e1->left.sym == e2->left.sym &&
(e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
return; return;
if (!expr_eq(e1, e2)) if (!expr_eq(e1, e2))
return; return;
/* e1 and e2 are equal leaves. Prepare them for elimination. */
trans_count++; trans_count++;
expr_free(e1); expr_free(e2); expr_free(e1); expr_free(e2);
switch (type) { switch (type) {
@ -161,6 +188,35 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
} }
} }
/*
* Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
* Example reductions:
*
* ep1: A && B -> ep1: y
* ep2: A && B && C -> ep2: C
*
* ep1: A || B -> ep1: n
* ep2: A || B || C -> ep2: C
*
* ep1: A && (B && FOO) -> ep1: FOO
* ep2: (BAR && B) && A -> ep2: BAR
*
* ep1: A && (B || C) -> ep1: y
* ep2: (C || B) && A -> ep2: y
*
* Comparisons are done between all operands at the same "level" of && or ||.
* For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
* following operands will be compared:
*
* - 'e1', 'e2 || e3', and 'e4 || e5', against each other
* - e2 against e3
* - e4 against e5
*
* Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
* '(e1 && e2) && e3' are both a single level.
*
* See __expr_eliminate_eq() as well.
*/
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
{ {
if (!e1 || !e2) if (!e1 || !e2)
@ -186,7 +242,13 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
#undef e1 #undef e1
#undef e2 #undef e2
int expr_eq(struct expr *e1, struct expr *e2) /*
* Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
* &&/|| expressions are considered equal if every operand in one expression
* equals some operand in the other (operands do not need to appear in the same
* order), recursively.
*/
static int expr_eq(struct expr *e1, struct expr *e2)
{ {
int res, old_count; int res, old_count;
@ -194,6 +256,10 @@ int expr_eq(struct expr *e1, struct expr *e2)
return 0; return 0;
switch (e1->type) { switch (e1->type) {
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
case E_SYMBOL: case E_SYMBOL:
@ -228,7 +294,18 @@ int expr_eq(struct expr *e1, struct expr *e2)
return 0; return 0;
} }
struct expr *expr_eliminate_yn(struct expr *e) /*
* Recursively performs the following simplifications in-place (as well as the
* corresponding simplifications with swapped operands):
*
* expr && n -> n
* expr && y -> expr
* expr || n -> expr
* expr || y -> y
*
* Returns the optimized expression.
*/
static struct expr *expr_eliminate_yn(struct expr *e)
{ {
struct expr *tmp; struct expr *tmp;
@ -501,12 +578,21 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
return NULL; return NULL;
} }
/*
* expr_eliminate_dups() helper.
*
* Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
* not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
* against all other leaves to look for simplifications.
*/
static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
{ {
#define e1 (*ep1) #define e1 (*ep1)
#define e2 (*ep2) #define e2 (*ep2)
struct expr *tmp; struct expr *tmp;
/* Recurse down to leaves */
if (e1->type == type) { if (e1->type == type) {
expr_eliminate_dups1(type, &e1->left.expr, &e2); expr_eliminate_dups1(type, &e1->left.expr, &e2);
expr_eliminate_dups1(type, &e1->right.expr, &e2); expr_eliminate_dups1(type, &e1->right.expr, &e2);
@ -517,6 +603,9 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
expr_eliminate_dups1(type, &e1, &e2->right.expr); expr_eliminate_dups1(type, &e1, &e2->right.expr);
return; return;
} }
/* e1 and e2 are leaves. Compare and process them. */
if (e1 == e2) if (e1 == e2)
return; return;
@ -553,62 +642,17 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
#undef e2 #undef e2
} }
static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) /*
{ * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
#define e1 (*ep1) * operands.
#define e2 (*ep2) *
struct expr *tmp, *tmp1, *tmp2; * Example simplifications:
*
if (e1->type == type) { * A || B || A -> A || B
expr_eliminate_dups2(type, &e1->left.expr, &e2); * A && B && A=y -> A=y && B
expr_eliminate_dups2(type, &e1->right.expr, &e2); *
return; * Returns the deduplicated expression.
} */
if (e2->type == type) {
expr_eliminate_dups2(type, &e1, &e2->left.expr);
expr_eliminate_dups2(type, &e1, &e2->right.expr);
}
if (e1 == e2)
return;
switch (e1->type) {
case E_OR:
expr_eliminate_dups2(e1->type, &e1, &e1);
// (FOO || BAR) && (!FOO && !BAR) -> n
tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
tmp2 = expr_copy(e2);
tmp = expr_extract_eq_and(&tmp1, &tmp2);
if (expr_is_yes(tmp1)) {
expr_free(e1);
e1 = expr_alloc_symbol(&symbol_no);
trans_count++;
}
expr_free(tmp2);
expr_free(tmp1);
expr_free(tmp);
break;
case E_AND:
expr_eliminate_dups2(e1->type, &e1, &e1);
// (FOO && BAR) || (!FOO || !BAR) -> y
tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
tmp2 = expr_copy(e2);
tmp = expr_extract_eq_or(&tmp1, &tmp2);
if (expr_is_no(tmp1)) {
expr_free(e1);
e1 = expr_alloc_symbol(&symbol_yes);
trans_count++;
}
expr_free(tmp2);
expr_free(tmp1);
expr_free(tmp);
break;
default:
;
}
#undef e1
#undef e2
}
struct expr *expr_eliminate_dups(struct expr *e) struct expr *expr_eliminate_dups(struct expr *e)
{ {
int oldcount; int oldcount;
@ -621,11 +665,11 @@ struct expr *expr_eliminate_dups(struct expr *e)
switch (e->type) { switch (e->type) {
case E_OR: case E_AND: case E_OR: case E_AND:
expr_eliminate_dups1(e->type, &e, &e); expr_eliminate_dups1(e->type, &e, &e);
expr_eliminate_dups2(e->type, &e, &e);
default: default:
; ;
} }
if (!trans_count) if (!trans_count)
/* No simplifications done in this pass. We're done */
break; break;
e = expr_eliminate_yn(e); e = expr_eliminate_yn(e);
} }
@ -633,6 +677,12 @@ struct expr *expr_eliminate_dups(struct expr *e)
return e; return e;
} }
/*
* Performs various simplifications involving logical operators and
* comparisons.
*
* Allocates and returns a new expression.
*/
struct expr *expr_transform(struct expr *e) struct expr *expr_transform(struct expr *e)
{ {
struct expr *tmp; struct expr *tmp;
@ -641,6 +691,10 @@ struct expr *expr_transform(struct expr *e)
return NULL; return NULL;
switch (e->type) { switch (e->type) {
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
case E_SYMBOL: case E_SYMBOL:
case E_LIST: case E_LIST:
@ -713,6 +767,22 @@ struct expr *expr_transform(struct expr *e)
e = tmp; e = tmp;
e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
break; break;
case E_LEQ:
case E_GEQ:
// !a<='x' -> a>'x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_LEQ ? E_GTH : E_LTH;
break;
case E_LTH:
case E_GTH:
// !a<'x' -> a>='x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
break;
case E_OR: case E_OR:
// !(a || b) -> !a && !b // !(a || b) -> !a && !b
tmp = e->left.expr; tmp = e->left.expr;
@ -783,6 +853,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
case E_SYMBOL: case E_SYMBOL:
return dep->left.sym == sym; return dep->left.sym == sym;
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
return dep->left.sym == sym || return dep->left.sym == sym ||
dep->right.sym == sym; dep->right.sym == sym;
@ -823,57 +897,20 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
return false; return false;
} }
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) /*
{ * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
struct expr *tmp = NULL; * expression 'e'.
expr_extract_eq(E_AND, &tmp, ep1, ep2); *
if (tmp) { * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
*ep1 = expr_eliminate_yn(*ep1); *
*ep2 = expr_eliminate_yn(*ep2); * A -> A!=n
} * !A -> A=n
return tmp; * A && B -> !(A=n || B=n)
} * A || B -> !(A=n && B=n)
* A && (B || C) -> !(A=n || (B=n && C=n))
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) *
{ * Allocates and returns a new expression.
struct expr *tmp = NULL; */
expr_extract_eq(E_OR, &tmp, ep1, ep2);
if (tmp) {
*ep1 = expr_eliminate_yn(*ep1);
*ep2 = expr_eliminate_yn(*ep2);
}
return tmp;
}
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
if (e1->type == type) {
expr_extract_eq(type, ep, &e1->left.expr, &e2);
expr_extract_eq(type, ep, &e1->right.expr, &e2);
return;
}
if (e2->type == type) {
expr_extract_eq(type, ep, ep1, &e2->left.expr);
expr_extract_eq(type, ep, ep1, &e2->right.expr);
return;
}
if (expr_eq(e1, e2)) {
*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
expr_free(e2);
if (type == E_AND) {
e1 = expr_alloc_symbol(&symbol_yes);
e2 = expr_alloc_symbol(&symbol_yes);
} else if (type == E_OR) {
e1 = expr_alloc_symbol(&symbol_no);
e2 = expr_alloc_symbol(&symbol_no);
}
}
#undef e1
#undef e2
}
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
{ {
struct expr *e1, *e2; struct expr *e1, *e2;
@ -908,6 +945,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
case E_NOT: case E_NOT:
return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
case E_UNEQUAL: case E_UNEQUAL:
case E_LTH:
case E_LEQ:
case E_GTH:
case E_GEQ:
case E_EQUAL: case E_EQUAL:
if (type == E_EQUAL) { if (type == E_EQUAL) {
if (sym == &symbol_yes) if (sym == &symbol_yes)
@ -935,10 +976,60 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
return NULL; return NULL;
} }
enum string_value_kind {
k_string,
k_signed,
k_unsigned,
k_invalid
};
union string_value {
unsigned long long u;
signed long long s;
};
static enum string_value_kind expr_parse_string(const char *str,
enum symbol_type type,
union string_value *val)
{
char *tail;
enum string_value_kind kind;
errno = 0;
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
val->s = !strcmp(str, "n") ? 0 :
!strcmp(str, "m") ? 1 :
!strcmp(str, "y") ? 2 : -1;
return k_signed;
case S_INT:
val->s = strtoll(str, &tail, 10);
kind = k_signed;
break;
case S_HEX:
val->u = strtoull(str, &tail, 16);
kind = k_unsigned;
break;
case S_STRING:
case S_UNKNOWN:
val->s = strtoll(str, &tail, 0);
kind = k_signed;
break;
default:
return k_invalid;
}
return !errno && !*tail && tail > str && isxdigit(tail[-1])
? kind : k_string;
}
tristate expr_calc_value(struct expr *e) tristate expr_calc_value(struct expr *e)
{ {
tristate val1, val2; tristate val1, val2;
const char *str1, *str2; const char *str1, *str2;
enum string_value_kind k1 = k_string, k2 = k_string;
union string_value lval = {}, rval = {};
int res;
if (!e) if (!e)
return yes; return yes;
@ -959,31 +1050,70 @@ tristate expr_calc_value(struct expr *e)
val1 = expr_calc_value(e->left.expr); val1 = expr_calc_value(e->left.expr);
return EXPR_NOT(val1); return EXPR_NOT(val1);
case E_EQUAL: case E_EQUAL:
sym_calc_value(e->left.sym); case E_GEQ:
sym_calc_value(e->right.sym); case E_GTH:
str1 = sym_get_string_value(e->left.sym); case E_LEQ:
str2 = sym_get_string_value(e->right.sym); case E_LTH:
return !strcmp(str1, str2) ? yes : no;
case E_UNEQUAL: case E_UNEQUAL:
sym_calc_value(e->left.sym); break;
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
return !strcmp(str1, str2) ? no : yes;
default: default:
printf("expr_calc_value: %d?\n", e->type); printf("expr_calc_value: %d?\n", e->type);
return no; return no;
} }
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
str1 = sym_get_string_value(e->left.sym);
str2 = sym_get_string_value(e->right.sym);
if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
k1 = expr_parse_string(str1, e->left.sym->type, &lval);
k2 = expr_parse_string(str2, e->right.sym->type, &rval);
}
if (k1 == k_string || k2 == k_string)
res = strcmp(str1, str2);
else if (k1 == k_invalid || k2 == k_invalid) {
if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
return no;
}
res = strcmp(str1, str2);
} else if (k1 == k_unsigned || k2 == k_unsigned)
res = (lval.u > rval.u) - (lval.u < rval.u);
else /* if (k1 == k_signed && k2 == k_signed) */
res = (lval.s > rval.s) - (lval.s < rval.s);
switch(e->type) {
case E_EQUAL:
return res ? no : yes;
case E_GEQ:
return res >= 0 ? yes : no;
case E_GTH:
return res > 0 ? yes : no;
case E_LEQ:
return res <= 0 ? yes : no;
case E_LTH:
return res < 0 ? yes : no;
case E_UNEQUAL:
return res ? yes : no;
default:
printf("expr_calc_value: relation %d?\n", e->type);
return no;
}
} }
int expr_compare_type(enum expr_type t1, enum expr_type t2) static int expr_compare_type(enum expr_type t1, enum expr_type t2)
{ {
#if 0
return 1;
#else
if (t1 == t2) if (t1 == t2)
return 0; return 0;
switch (t1) { switch (t1) {
case E_LEQ:
case E_LTH:
case E_GEQ:
case E_GTH:
if (t2 == E_EQUAL || t2 == E_UNEQUAL)
return 1;
case E_EQUAL: case E_EQUAL:
case E_UNEQUAL: case E_UNEQUAL:
if (t2 == E_NOT) if (t2 == E_NOT)
@ -1005,52 +1135,11 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
} }
printf("[%dgt%d?]", t1, t2); printf("[%dgt%d?]", t1, t2);
return 0; return 0;
#endif
} }
static inline struct expr * void expr_print(struct expr *e,
expr_get_leftmost_symbol(const struct expr *e) void (*fn)(void *, struct symbol *, const char *),
{ void *data, int prevtoken)
if (e == NULL)
return NULL;
while (e->type != E_SYMBOL)
e = e->left.expr;
return expr_copy(e);
}
/*
* Given expression `e1' and `e2', returns the leaf of the longest
* sub-expression of `e1' not containing 'e2.
*/
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
{
struct expr *ret;
switch (e1->type) {
case E_OR:
return expr_alloc_and(
expr_simplify_unmet_dep(e1->left.expr, e2),
expr_simplify_unmet_dep(e1->right.expr, e2));
case E_AND: {
struct expr *e;
e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
e = expr_eliminate_dups(e);
ret = (!expr_eq(e, e1)) ? e1 : NULL;
expr_free(e);
break;
}
default:
ret = e1;
break;
}
return expr_get_leftmost_symbol(ret);
}
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
{ {
if (!e) { if (!e) {
fn(data, NULL, "y"); fn(data, NULL, "y");
@ -1078,6 +1167,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
fn(data, NULL, "="); fn(data, NULL, "=");
fn(data, e->right.sym, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
break; break;
case E_LEQ:
case E_LTH:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
else
fn(data, NULL, "<choice>");
fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_GEQ:
case E_GTH:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
else
fn(data, NULL, "<choice>");
fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_UNEQUAL: case E_UNEQUAL:
if (e->left.sym->name) if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
@ -1166,3 +1273,33 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
{ {
expr_print(e, expr_print_gstr_helper, gs, E_NONE); expr_print(e, expr_print_gstr_helper, gs, E_NONE);
} }
/*
* Transform the top level "||" tokens into newlines and prepend each
* line with a minus. This makes expressions much easier to read.
* Suitable for reverse dependency expressions.
*/
static void expr_print_revdep(struct expr *e,
void (*fn)(void *, struct symbol *, const char *),
void *data, tristate pr_type, const char **title)
{
if (e->type == E_OR) {
expr_print_revdep(e->left.expr, fn, data, pr_type, title);
expr_print_revdep(e->right.expr, fn, data, pr_type, title);
} else if (expr_calc_value(e) == pr_type) {
if (*title) {
fn(data, NULL, *title);
*title = NULL;
}
fn(data, NULL, " - ");
expr_print(e, fn, data, E_NONE);
fn(data, NULL, "\n");
}
}
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
tristate pr_type, const char *title)
{
expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
}

View File

@ -29,7 +29,9 @@ typedef enum tristate {
} tristate; } tristate;
enum expr_type { enum expr_type {
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE E_NONE, E_OR, E_AND, E_NOT,
E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ,
E_LIST, E_SYMBOL, E_RANGE
}; };
union expr_data { union expr_data {
@ -72,17 +74,61 @@ enum {
S_DEF_COUNT S_DEF_COUNT
}; };
/*
* Represents a configuration symbol.
*
* Choices are represented as a special kind of symbol and have the
* SYMBOL_CHOICE bit set in 'flags'.
*/
struct symbol { struct symbol {
/* The next symbol in the same bucket in the symbol hash table */
struct symbol *next; struct symbol *next;
/* The name of the symbol, e.g. "FOO" for 'config FOO' */
char *name; char *name;
/* S_BOOLEAN, S_TRISTATE, ... */
enum symbol_type type; enum symbol_type type;
/*
* The calculated value of the symbol. The SYMBOL_VALID bit is set in
* 'flags' when this is up to date. Note that this value might differ
* from the user value set in e.g. a .config file, due to visibility.
*/
struct symbol_value curr; struct symbol_value curr;
/*
* Values for the symbol provided from outside. def[S_DEF_USER] holds
* the .config value.
*/
struct symbol_value def[S_DEF_COUNT]; struct symbol_value def[S_DEF_COUNT];
/*
* An upper bound on the tristate value the user can set for the symbol
* if it is a boolean or tristate. Calculated from prompt dependencies,
* which also inherit dependencies from enclosing menus, choices, and
* ifs. If 'n', the user value will be ignored.
*
* Symbols lacking prompts always have visibility 'n'.
*/
tristate visible; tristate visible;
/* SYMBOL_* flags */
int flags; int flags;
/* List of properties. See prop_type. */
struct property *prop; struct property *prop;
/* Dependencies from enclosing menus, choices, and ifs */
struct expr_value dir_dep; struct expr_value dir_dep;
/* Reverse dependencies through being selected by other symbols */
struct expr_value rev_dep; struct expr_value rev_dep;
/*
* "Weak" reverse dependencies through being implied by other symbols
*/
struct expr_value implied;
}; };
#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 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)
@ -109,6 +155,9 @@ struct symbol {
/* choice values need to be set before calculating this symbol value */ /* choice values need to be set before calculating this symbol value */
#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 #define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
/* Set symbol to y if allnoconfig; used for symbols that hide others */
#define SYMBOL_ALLNOCONFIG_Y 0x200000
#define SYMBOL_MAXLENGTH 256 #define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 9973 #define SYMBOL_HASHSIZE 9973
@ -127,10 +176,11 @@ enum prop_type {
P_UNKNOWN, P_UNKNOWN,
P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */
P_COMMENT, /* text associated with a comment */ P_COMMENT, /* text associated with a comment */
P_MENU, /* prompt associated with a menuconfig option */ P_MENU, /* prompt associated with a menu or menuconfig symbol */
P_DEFAULT, /* default y */ P_DEFAULT, /* default y */
P_CHOICE, /* choice value */ P_CHOICE, /* choice value */
P_SELECT, /* select BAR */ P_SELECT, /* select BAR */
P_IMPLY, /* imply BAR */
P_RANGE, /* range 7..100 (for a symbol) */ P_RANGE, /* range 7..100 (for a symbol) */
P_ENV, /* value from environment variable */ P_ENV, /* value from environment variable */
P_SYMBOL, /* where a symbol is defined */ P_SYMBOL, /* where a symbol is defined */
@ -159,22 +209,67 @@ struct property {
for (st = sym->prop; st; st = st->next) \ for (st = sym->prop; st; st = st->next) \
if (st->text) if (st->text)
/*
* Represents a node in the menu tree, as seen in e.g. menuconfig (though used
* for all front ends). Each symbol, menu, etc. defined in the Kconfig files
* gets a node. A symbol defined in multiple locations gets one node at each
* location.
*/
struct menu { struct menu {
/* The next menu node at the same level */
struct menu *next; struct menu *next;
/* The parent menu node, corresponding to e.g. a menu or choice */
struct menu *parent; struct menu *parent;
/* The first child menu node, for e.g. menus and choices */
struct menu *list; struct menu *list;
/*
* The symbol associated with the menu node. Choices are implemented as
* a special kind of symbol. NULL for menus, comments, and ifs.
*/
struct symbol *sym; struct symbol *sym;
/*
* The prompt associated with the node. This holds the prompt for a
* symbol as well as the text for a menu or comment, along with the
* type (P_PROMPT, P_MENU, etc.)
*/
struct property *prompt; struct property *prompt;
/*
* 'visible if' dependencies. If more than one is given, they will be
* ANDed together.
*/
struct expr *visibility; struct expr *visibility;
/*
* Ordinary dependencies from e.g. 'depends on' and 'if', ANDed
* together
*/
struct expr *dep; struct expr *dep;
/* MENU_* flags */
unsigned int flags; unsigned int flags;
/* Any help text associated with the node */
char *help; char *help;
/* The location where the menu node appears in the Kconfig files */
struct file *file; struct file *file;
int lineno; int lineno;
/* For use by front ends that need to store auxiliary data */
void *data; void *data;
}; };
/*
* Set on a menu node when the corresponding symbol changes state in some way.
* Can be checked by front ends.
*/
#define MENU_CHANGED 0x0001 #define MENU_CHANGED 0x0001
#define MENU_ROOT 0x0002 #define MENU_ROOT 0x0002
struct jump_key { struct jump_key {
@ -202,24 +297,20 @@ struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
struct expr *expr_copy(const struct expr *org); struct expr *expr_copy(const struct expr *org);
void expr_free(struct expr *e); void expr_free(struct expr *e);
int expr_eq(struct expr *e1, struct expr *e2);
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
tristate expr_calc_value(struct expr *e); tristate expr_calc_value(struct expr *e);
struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_trans_bool(struct expr *e); struct expr *expr_trans_bool(struct expr *e);
struct expr *expr_eliminate_dups(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e);
struct expr *expr_transform(struct expr *e); struct expr *expr_transform(struct expr *e);
int expr_contains_symbol(struct expr *dep, struct symbol *sym); int expr_contains_symbol(struct expr *dep, struct symbol *sym);
bool expr_depends_symbol(struct expr *dep, struct symbol *sym); bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
void expr_fprint(struct expr *e, FILE *out); void expr_fprint(struct expr *e, FILE *out);
struct gstr; /* forward */ struct gstr; /* forward */
void expr_gstr_print(struct expr *e, struct gstr *gs); void expr_gstr_print(struct expr *e, struct gstr *gs);
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
tristate pr_type, const char *title);
static inline int expr_is_yes(struct expr *e) static inline int expr_is_yes(struct expr *e)
{ {

View File

@ -169,14 +169,6 @@ void init_main_window(const gchar * glade_file)
style = gtk_widget_get_style(main_wnd); style = gtk_widget_get_style(main_wnd);
widget = glade_xml_get_widget(xml, "toolbar1"); widget = glade_xml_get_widget(xml, "toolbar1");
#if 0 /* Use stock Gtk icons instead */
replace_button_icon(xml, main_wnd->window, style,
"button1", (gchar **) xpm_back);
replace_button_icon(xml, main_wnd->window, style,
"button2", (gchar **) xpm_load);
replace_button_icon(xml, main_wnd->window, style,
"button3", (gchar **) xpm_save);
#endif
replace_button_icon(xml, main_wnd->window, style, replace_button_icon(xml, main_wnd->window, style,
"button4", (gchar **) xpm_single_view); "button4", (gchar **) xpm_single_view);
replace_button_icon(xml, main_wnd->window, style, replace_button_icon(xml, main_wnd->window, style,
@ -184,22 +176,6 @@ void init_main_window(const gchar * glade_file)
replace_button_icon(xml, main_wnd->window, style, replace_button_icon(xml, main_wnd->window, style,
"button6", (gchar **) xpm_tree_view); "button6", (gchar **) xpm_tree_view);
#if 0
switch (view_mode) {
case SINGLE_VIEW:
widget = glade_xml_get_widget(xml, "button4");
g_signal_emit_by_name(widget, "clicked");
break;
case SPLIT_VIEW:
widget = glade_xml_get_widget(xml, "button5");
g_signal_emit_by_name(widget, "clicked");
break;
case FULL_VIEW:
widget = glade_xml_get_widget(xml, "button6");
g_signal_emit_by_name(widget, "clicked");
break;
}
#endif
txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
"foreground", "red", "foreground", "red",
@ -938,7 +914,7 @@ on_treeview2_button_press_event(GtkWidget * widget,
current = menu; current = menu;
display_tree_part(); display_tree_part();
gtk_widget_set_sensitive(back_btn, TRUE); gtk_widget_set_sensitive(back_btn, TRUE);
} else if ((col == COL_OPTION)) { } else if (col == COL_OPTION) {
toggle_sym_value(menu); toggle_sym_value(menu);
gtk_tree_view_expand_row(view, path, TRUE); gtk_tree_view_expand_row(view, path, TRUE);
} }
@ -1404,7 +1380,7 @@ static void display_tree(struct menu *menu)
&& (tree == tree2)) && (tree == tree2))
continue; continue;
/* /*
if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
|| (view_mode == FULL_VIEW) || (view_mode == FULL_VIEW)
|| (view_mode == SPLIT_VIEW))*/ || (view_mode == SPLIT_VIEW))*/
@ -1498,9 +1474,12 @@ int main(int ac, char *av[])
case 'a': case 'a':
//showAll = 1; //showAll = 1;
break; break;
case 's':
conf_set_message_callback(NULL);
break;
case 'h': case 'h':
case '?': case '?':
printf("%s <config>\n", av[0]); printf("%s [-s] <config>\n", av[0]);
exit(0); exit(0);
} }
name = av[2]; name = av[2];

View File

@ -0,0 +1,53 @@
static struct kconf_id kconf_id_array[] = {
{ "mainmenu", T_MAINMENU, TF_COMMAND },
{ "menu", T_MENU, TF_COMMAND },
{ "endmenu", T_ENDMENU, TF_COMMAND },
{ "source", T_SOURCE, TF_COMMAND },
{ "choice", T_CHOICE, TF_COMMAND },
{ "endchoice", T_ENDCHOICE, TF_COMMAND },
{ "comment", T_COMMENT, TF_COMMAND },
{ "config", T_CONFIG, TF_COMMAND },
{ "menuconfig", T_MENUCONFIG, TF_COMMAND },
{ "help", T_HELP, TF_COMMAND },
{ "---help---", T_HELP, TF_COMMAND },
{ "if", T_IF, TF_COMMAND|TF_PARAM },
{ "endif", T_ENDIF, TF_COMMAND },
{ "depends", T_DEPENDS, TF_COMMAND },
{ "optional", T_OPTIONAL, TF_COMMAND },
{ "default", T_DEFAULT, TF_COMMAND, S_UNKNOWN },
{ "prompt", T_PROMPT, TF_COMMAND },
{ "tristate", T_TYPE, TF_COMMAND, S_TRISTATE },
{ "def_tristate", T_DEFAULT, TF_COMMAND, S_TRISTATE },
{ "bool", T_TYPE, TF_COMMAND, S_BOOLEAN },
{ "def_bool", T_DEFAULT, TF_COMMAND, S_BOOLEAN },
{ "int", T_TYPE, TF_COMMAND, S_INT },
{ "hex", T_TYPE, TF_COMMAND, S_HEX },
{ "string", T_TYPE, TF_COMMAND, S_STRING },
{ "select", T_SELECT, TF_COMMAND },
{ "imply", T_IMPLY, TF_COMMAND },
{ "range", T_RANGE, TF_COMMAND },
{ "visible", T_VISIBLE, TF_COMMAND },
{ "option", T_OPTION, TF_COMMAND },
{ "on", T_ON, TF_PARAM },
{ "modules", T_OPT_MODULES, TF_OPTION },
{ "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION },
{ "env", T_OPT_ENV, TF_OPTION },
{ "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION },
};
#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id))
static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len)
{
int i;
for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) {
struct kconf_id *id = kconf_id_array+i;
int l = strlen(id->name);
if (len == l && !memcmp(str, id->name, len))
return id;
}
return NULL;
}

View File

@ -101,7 +101,7 @@ static struct message *message__new(const char *msg, char *option,
if (self->files == NULL) if (self->files == NULL)
goto out_fail; goto out_fail;
self->msg = strdup(msg); self->msg = xstrdup(msg);
if (self->msg == NULL) if (self->msg == NULL)
goto out_fail_msg; goto out_fail_msg;

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LIST_H #ifndef LIST_H
#define LIST_H #define LIST_H
@ -34,7 +35,7 @@ struct list_head {
* list_entry - get the struct for this entry * list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer. * @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in. * @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct. * @member: the name of the list_head within the struct.
*/ */
#define list_entry(ptr, type, member) \ #define list_entry(ptr, type, member) \
container_of(ptr, type, member) container_of(ptr, type, member)
@ -43,7 +44,7 @@ struct list_head {
* list_for_each_entry - iterate over list of given type * list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor. * @pos: the type * to use as a loop cursor.
* @head: the head for your list. * @head: the head for your list.
* @member: the name of the list_struct within the struct. * @member: the name of the list_head within the struct.
*/ */
#define list_for_each_entry(pos, head, member) \ #define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \ for (pos = list_entry((head)->next, typeof(*pos), member); \
@ -55,7 +56,7 @@ struct list_head {
* @pos: the type * to use as a loop cursor. * @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage * @n: another type * to use as temporary storage
* @head: the head for your list. * @head: the head for your list.
* @member: the name of the list_struct within the struct. * @member: the name of the list_head within the struct.
*/ */
#define list_for_each_entry_safe(pos, n, head, member) \ #define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \ for (pos = list_entry((head)->next, typeof(*pos), member), \

View File

@ -21,9 +21,7 @@ static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c;
extern "C" { extern "C" {
#endif #endif
#define P(name,type,arg) extern type name arg
#include "lkc_proto.h" #include "lkc_proto.h"
#undef P
#define SRCTREE "srctree" #define SRCTREE "srctree"
@ -61,17 +59,16 @@ enum conf_def_mode {
#define T_OPT_MODULES 1 #define T_OPT_MODULES 1
#define T_OPT_DEFCONFIG_LIST 2 #define T_OPT_DEFCONFIG_LIST 2
#define T_OPT_ENV 3 #define T_OPT_ENV 3
#define T_OPT_ALLNOCONFIG_Y 4
struct kconf_id { struct kconf_id {
int name; const char *name;
int token; int token;
unsigned int flags; unsigned int flags;
enum symbol_type stype; enum symbol_type stype;
}; };
extern int zconfdebug; extern int yylineno;
int zconfparse(void);
void zconfdump(FILE *out); void zconfdump(FILE *out);
void zconf_starthelp(void); void zconf_starthelp(void);
FILE *zconf_fopen(const char *name); FILE *zconf_fopen(const char *name);
@ -89,11 +86,6 @@ void sym_add_change_count(int count);
bool conf_set_all_new_symbols(enum conf_def_mode mode); bool conf_set_all_new_symbols(enum conf_def_mode mode);
void set_all_choice_values(struct symbol *csym); void set_all_choice_values(struct symbol *csym);
struct conf_printer {
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
void (*print_comment)(FILE *, const char *, void *);
};
/* confdata.c and expr.c */ /* confdata.c and expr.c */
static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
{ {
@ -109,10 +101,8 @@ void menu_warn(struct menu *menu, const char *fmt, ...);
struct menu *menu_add_menu(void); struct menu *menu_add_menu(void);
void menu_end_menu(void); void menu_end_menu(void);
void menu_add_entry(struct symbol *sym); void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
void menu_add_dep(struct expr *dep); void menu_add_dep(struct expr *dep);
void menu_add_visibility(struct expr *dep); void menu_add_visibility(struct expr *dep);
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
@ -125,6 +115,8 @@ struct file *file_lookup(const char *name);
int file_write_dep(const char *name); int file_write_dep(const char *name);
void *xmalloc(size_t size); void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size); void *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *p, size_t size);
char *xstrdup(const char *s);
struct gstr { struct gstr {
size_t len; size_t len;
@ -136,7 +128,6 @@ struct gstr {
int max_width; int max_width;
}; };
struct gstr str_new(void); struct gstr str_new(void);
struct gstr str_assign(const char *s);
void str_free(struct gstr *gs); void str_free(struct gstr *gs);
void str_append(struct gstr *gs, const char *s); void str_append(struct gstr *gs, const char *s);
void str_printf(struct gstr *gs, const char *fmt, ...); void str_printf(struct gstr *gs, const char *fmt, ...);
@ -147,8 +138,6 @@ extern struct expr *sym_env_list;
void sym_init(void); void sym_init(void);
void sym_clear_all_valid(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); struct symbol *sym_choice_default(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym); const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym);

View File

@ -1,57 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <stdarg.h> #include <stdarg.h>
/* confdata.c */ /* confdata.c */
P(conf_parse,void,(const char *name)); void conf_parse(const char *name);
P(conf_read,int,(const char *name)); int conf_read(const char *name);
P(conf_read_simple,int,(const char *name, int)); int conf_read_simple(const char *name, int);
P(conf_write_defconfig,int,(const char *name)); int conf_write_defconfig(const char *name);
P(conf_write,int,(const char *name)); int conf_write(const char *name);
P(conf_write_autoconf,int,(void)); int conf_write_autoconf(void);
P(conf_get_changed,bool,(void)); bool conf_get_changed(void);
P(conf_set_changed_callback, void,(void (*fn)(void))); void conf_set_changed_callback(void (*fn)(void));
P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap));
/* menu.c */ /* menu.c */
P(rootmenu,struct menu,); extern struct menu rootmenu;
P(menu_is_empty, bool, (struct menu *menu)); bool menu_is_empty(struct menu *menu);
P(menu_is_visible, bool, (struct menu *menu)); bool menu_is_visible(struct menu *menu);
P(menu_has_prompt, bool, (struct menu *menu)); bool menu_has_prompt(struct menu *menu);
P(menu_get_prompt,const char *,(struct menu *menu)); const char * menu_get_prompt(struct menu *menu);
P(menu_get_root_menu,struct menu *,(struct menu *menu)); struct menu * menu_get_root_menu(struct menu *menu);
P(menu_get_parent_menu,struct menu *,(struct menu *menu)); struct menu * menu_get_parent_menu(struct menu *menu);
P(menu_has_help,bool,(struct menu *menu)); bool menu_has_help(struct menu *menu);
P(menu_get_help,const char *,(struct menu *menu)); const char * menu_get_help(struct menu *menu);
P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
*head)); void menu_get_ext_help(struct menu *menu, struct gstr *help);
P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head
*head));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
/* symbol.c */ /* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
P(sym_lookup,struct symbol *,(const char *name, int flags)); struct symbol * sym_lookup(const char *name, int flags);
P(sym_find,struct symbol *,(const char *name)); struct symbol * sym_find(const char *name);
P(sym_expand_string_value,const char *,(const char *in)); char *sym_expand_string_value(const char *in);
P(sym_escape_string_value, const char *,(const char *in)); const char * sym_escape_string_value(const char *in);
P(sym_re_search,struct symbol **,(const char *pattern)); struct symbol ** sym_re_search(const char *pattern);
P(sym_type_name,const char *,(enum symbol_type type)); const char * sym_type_name(enum symbol_type type);
P(sym_calc_value,void,(struct symbol *sym)); void sym_calc_value(struct symbol *sym);
P(sym_get_type,enum symbol_type,(struct symbol *sym)); enum symbol_type sym_get_type(struct symbol *sym);
P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); bool sym_tristate_within_range(struct symbol *sym,tristate tri);
P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); bool sym_set_tristate_value(struct symbol *sym,tristate tri);
P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); tristate sym_toggle_tristate_value(struct symbol *sym);
P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); bool sym_string_valid(struct symbol *sym, const char *newval);
P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); bool sym_string_within_range(struct symbol *sym, const char *str);
P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); bool sym_set_string_value(struct symbol *sym, const char *newval);
P(sym_is_changable,bool,(struct symbol *sym)); bool sym_is_changable(struct symbol *sym);
P(sym_get_choice_prop,struct property *,(struct symbol *sym)); struct property * sym_get_choice_prop(struct symbol *sym);
P(sym_get_default_prop,struct property *,(struct symbol *sym)); const char * sym_get_string_value(struct symbol *sym);
P(sym_get_string_value,const char *,(struct symbol *sym));
P(prop_get_type_name,const char *,(enum prop_type type)); const char * prop_get_type_name(enum prop_type type);
/* expr.c */ /* expr.c */
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken));

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Check ncurses compatibility # Check ncurses compatibility
# What library to link # What library to link
@ -54,7 +55,8 @@ EOF
echo " *** required header files." 1>&2 echo " *** required header files." 1>&2
echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
echo " *** " 1>&2 echo " *** " 1>&2
echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2
echo " *** depending on your distribution) and try again." 1>&2
echo " *** " 1>&2 echo " *** " 1>&2
exit 1 exit 1
fi fi

View File

@ -168,13 +168,13 @@ do_resize:
/* create new window for the list */ /* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1, list = subwin(dialog, list_height, list_width, y + box_y + 1,
x + box_x + 1); x + box_x + 1);
keypad(list, TRUE); keypad(list, TRUE);
/* draw a box around the list items */ /* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
dlg.menubox_border.atr, dlg.menubox.atr); dlg.menubox_border.atr, dlg.menubox.atr);
/* Find length of longest item in order to center checklist */ /* Find length of longest item in order to center checklist */
check_x = 0; check_x = 0;

View File

@ -170,7 +170,7 @@ char item_tag(void);
/* item list manipulation for lxdialog use */ /* item list manipulation for lxdialog use */
#define MAXITEMSTR 200 #define MAXITEMSTR 200
struct dialog_item { struct dialog_item {
char str[MAXITEMSTR]; /* promtp displayed */ char str[MAXITEMSTR]; /* prompt displayed */
char tag; char tag;
void *data; /* pointer to menu item - used by menubox+checklist */ void *data; /* pointer to menu item - used by menubox+checklist */
int selected; /* Set to 1 by dialog_*() function if selected. */ int selected; /* Set to 1 by dialog_*() function if selected. */

View File

@ -42,7 +42,7 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
* Display a dialog box for inputing a string * Display a dialog box for inputing a string
*/ */
int dialog_inputbox(const char *title, const char *prompt, int height, int width, int dialog_inputbox(const char *title, const char *prompt, int height, int width,
const char *init) const char *init)
{ {
int i, x, y, box_y, box_x, box_width; int i, x, y, box_y, box_x, box_width;
int input_x = 0, key = 0, button = -1; int input_x = 0, key = 0, button = -1;

View File

@ -64,7 +64,7 @@ static int menu_width, item_x;
* Print menu item * Print menu item
*/ */
static void do_print_item(WINDOW * win, const char *item, int line_y, static void do_print_item(WINDOW * win, const char *item, int line_y,
int selected, int hotkey) int selected, int hotkey)
{ {
int j; int j;
char *menu_item = malloc(menu_width + 1); char *menu_item = malloc(menu_width + 1);
@ -182,7 +182,7 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
* Display a menu for choosing among a number of options * Display a menu for choosing among a number of options
*/ */
int dialog_menu(const char *title, const char *prompt, int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll) const void *selected, int *s_scroll)
{ {
int i, j, x, y, box_x, box_y; int i, j, x, y, box_x, box_y;
int height, width, menu_height; int height, width, menu_height;

View File

@ -623,7 +623,7 @@ void item_make(const char *fmt, ...)
void item_add_str(const char *fmt, ...) void item_add_str(const char *fmt, ...)
{ {
va_list ap; va_list ap;
size_t avail; size_t avail;
avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);

View File

@ -246,7 +246,7 @@ search_help[] = N_(
" Selected by: BAR [=n]\n" " Selected by: BAR [=n]\n"
"-----------------------------------------------------------------\n" "-----------------------------------------------------------------\n"
"o The line 'Type:' shows the type of the configuration option for\n" "o The line 'Type:' shows the type of the configuration option for\n"
" this symbol (boolean, tristate, string, ...)\n" " this symbol (bool, tristate, string, ...)\n"
"o The line 'Prompt:' shows the text used in the menu structure for\n" "o The line 'Prompt:' shows the text used in the menu structure for\n"
" this symbol\n" " this symbol\n"
"o The 'Defined at' line tells at what file / line number the symbol\n" "o The 'Defined at' line tells at what file / line number the symbol\n"
@ -279,6 +279,7 @@ static int child_count;
static int single_menu_mode; static int single_menu_mode;
static int show_all_options; static int show_all_options;
static int save_and_exit; static int save_and_exit;
static int silent;
static void conf(struct menu *menu, struct menu *active_menu); static void conf(struct menu *menu, struct menu *active_menu);
static void conf_choice(struct menu *menu); static void conf_choice(struct menu *menu);
@ -299,7 +300,7 @@ static void set_config_filename(const char *config_filename)
int size; int size;
size = snprintf(menu_backtitle, sizeof(menu_backtitle), size = snprintf(menu_backtitle, sizeof(menu_backtitle),
"%s - %s", config_filename, rootmenu.prompt->text); "%s - %s", config_filename, rootmenu.prompt->text);
if (size >= sizeof(menu_backtitle)) if (size >= sizeof(menu_backtitle))
menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
set_dialog_backtitle(menu_backtitle); set_dialog_backtitle(menu_backtitle);
@ -330,10 +331,10 @@ static void set_subtitle(void)
list_for_each_entry(sp, &trail, entries) { list_for_each_entry(sp, &trail, entries) {
if (sp->text) { if (sp->text) {
if (pos) { if (pos) {
pos->next = xcalloc(sizeof(*pos), 1); pos->next = xcalloc(1, sizeof(*pos));
pos = pos->next; pos = pos->next;
} else { } else {
subtitles = pos = xcalloc(sizeof(*pos), 1); subtitles = pos = xcalloc(1, sizeof(*pos));
} }
pos->text = sp->text; pos->text = sp->text;
} }
@ -777,10 +778,12 @@ static void conf_message_callback(const char *fmt, va_list ap)
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];
vsnprintf(buf, sizeof(buf), fmt, ap); vsnprintf(buf, sizeof(buf), fmt, ap);
if (save_and_exit) if (save_and_exit) {
printf("%s", buf); if (!silent)
else printf("%s", buf);
} else {
show_textbox(NULL, buf, 6, 60); show_textbox(NULL, buf, 6, 60);
}
} }
static void show_help(struct menu *menu) static void show_help(struct menu *menu)
@ -977,16 +980,18 @@ static int handle_exit(void)
} }
/* fall through */ /* fall through */
case -1: case -1:
printf(_("\n\n" if (!silent)
"*** End of the configuration.\n" printf(_("\n\n"
"*** Execute 'make' to start the build or try 'make help'." "*** End of the configuration.\n"
"\n\n")); "*** Execute 'make' to start the build or try 'make help'."
"\n\n"));
res = 0; res = 0;
break; break;
default: default:
fprintf(stderr, _("\n\n" if (!silent)
"Your configuration changes were NOT saved." fprintf(stderr, _("\n\n"
"\n\n")); "Your configuration changes were NOT saved."
"\n\n"));
if (res != KEY_ESC) if (res != KEY_ESC)
res = 0; res = 0;
} }
@ -1010,6 +1015,12 @@ int main(int ac, char **av)
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
if (ac > 1 && strcmp(av[1], "-s") == 0) {
silent = 1;
/* Silence conf_read() until the real callback is set up */
conf_set_message_callback(NULL);
av++;
}
conf_parse(av[1]); conf_parse(av[1]);
conf_read(NULL); conf_read(NULL);
@ -1034,4 +1045,3 @@ int main(int ac, char **av)
return res; return res;
} }

View File

@ -62,13 +62,8 @@ void menu_add_entry(struct symbol *sym)
menu_add_symbol(P_SYMBOL, sym, NULL); menu_add_symbol(P_SYMBOL, sym, NULL);
} }
void menu_end_entry(void)
{
}
struct menu *menu_add_menu(void) struct menu *menu_add_menu(void)
{ {
menu_end_entry();
last_entry_ptr = &current_entry->list; last_entry_ptr = &current_entry->list;
return current_menu = current_entry; return current_menu = current_entry;
} }
@ -79,19 +74,23 @@ void menu_end_menu(void)
current_menu = current_menu->parent; current_menu = current_menu->parent;
} }
static struct expr *menu_check_dep(struct expr *e) /*
* Rewrites 'm' to 'm' && MODULES, so that it evaluates to 'n' when running
* without modules
*/
static struct expr *rewrite_m(struct expr *e)
{ {
if (!e) if (!e)
return e; return e;
switch (e->type) { switch (e->type) {
case E_NOT: case E_NOT:
e->left.expr = menu_check_dep(e->left.expr); e->left.expr = rewrite_m(e->left.expr);
break; break;
case E_OR: case E_OR:
case E_AND: case E_AND:
e->left.expr = menu_check_dep(e->left.expr); e->left.expr = rewrite_m(e->left.expr);
e->right.expr = menu_check_dep(e->right.expr); e->right.expr = rewrite_m(e->right.expr);
break; break;
case E_SYMBOL: case E_SYMBOL:
/* change 'm' into 'm' && MODULES */ /* change 'm' into 'm' && MODULES */
@ -106,7 +105,7 @@ static struct expr *menu_check_dep(struct expr *e)
void menu_add_dep(struct expr *dep) void menu_add_dep(struct expr *dep)
{ {
current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); current_entry->dep = expr_alloc_and(current_entry->dep, dep);
} }
void menu_set_type(int type) void menu_set_type(int type)
@ -125,13 +124,13 @@ void menu_set_type(int type)
sym_type_name(sym->type), sym_type_name(type)); sym_type_name(sym->type), sym_type_name(type));
} }
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
{ {
struct property *prop = prop_alloc(type, current_entry->sym); struct property *prop = prop_alloc(type, current_entry->sym);
prop->menu = current_entry; prop->menu = current_entry;
prop->expr = expr; prop->expr = expr;
prop->visible.expr = menu_check_dep(dep); prop->visible.expr = dep;
if (prompt) { if (prompt) {
if (isspace(*prompt)) { if (isspace(*prompt)) {
@ -213,10 +212,14 @@ void menu_add_option(int token, char *arg)
sym_defconfig_list = current_entry->sym; sym_defconfig_list = current_entry->sym;
else if (sym_defconfig_list != current_entry->sym) else if (sym_defconfig_list != current_entry->sym)
zconf_error("trying to redefine defconfig symbol"); zconf_error("trying to redefine defconfig symbol");
sym_defconfig_list->flags |= SYMBOL_AUTO;
break; break;
case T_OPT_ENV: case T_OPT_ENV:
prop_add_env(arg); prop_add_env(arg);
break; break;
case T_OPT_ALLNOCONFIG_Y:
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
break;
} }
} }
@ -230,6 +233,8 @@ static void sym_check_prop(struct symbol *sym)
{ {
struct property *prop; struct property *prop;
struct symbol *sym2; struct symbol *sym2;
char *use;
for (prop = sym->prop; prop; prop = prop->next) { for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) { switch (prop->type) {
case P_DEFAULT: case P_DEFAULT:
@ -247,25 +252,37 @@ static void sym_check_prop(struct symbol *sym)
"'%s': number is invalid", "'%s': number is invalid",
sym->name); sym->name);
} }
if (sym_is_choice(sym)) {
struct property *choice_prop =
sym_get_choice_prop(sym2);
if (!choice_prop ||
prop_get_symbol(choice_prop) != sym)
prop_warn(prop,
"choice default symbol '%s' is not contained in the choice",
sym2->name);
}
break; break;
case P_SELECT: case P_SELECT:
case P_IMPLY:
use = prop->type == P_SELECT ? "select" : "imply";
sym2 = prop_get_symbol(prop); sym2 = prop_get_symbol(prop);
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
prop_warn(prop, prop_warn(prop,
"config symbol '%s' uses select, but is " "config symbol '%s' uses %s, but is "
"not boolean or tristate", sym->name); "not bool or tristate", sym->name, use);
else if (sym2->type != S_UNKNOWN && else if (sym2->type != S_UNKNOWN &&
sym2->type != S_BOOLEAN && sym2->type != S_BOOLEAN &&
sym2->type != S_TRISTATE) sym2->type != S_TRISTATE)
prop_warn(prop, prop_warn(prop,
"'%s' has wrong type. 'select' only " "'%s' has wrong type. '%s' only "
"accept arguments of boolean and " "accept arguments of bool and "
"tristate type", sym2->name); "tristate type", sym2->name, use);
break; break;
case P_RANGE: case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX) if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed " prop_warn(prop, "range is only allowed "
"for int or hex symbols"); "for int or hex symbols");
if (!menu_validate_number(sym, prop->expr->left.sym) || if (!menu_validate_number(sym, prop->expr->left.sym) ||
!menu_validate_number(sym, prop->expr->right.sym)) !menu_validate_number(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid"); prop_warn(prop, "range is invalid");
@ -285,6 +302,11 @@ void menu_finalize(struct menu *parent)
sym = parent->sym; sym = parent->sym;
if (parent->list) { if (parent->list) {
/*
* This menu node has children. We (recursively) process them
* and propagate parent dependencies before moving on.
*/
if (sym && sym_is_choice(sym)) { if (sym && sym_is_choice(sym)) {
if (sym->type == S_UNKNOWN) { if (sym->type == S_UNKNOWN) {
/* find the first choice value to find out choice type */ /* find the first choice value to find out choice type */
@ -302,65 +324,169 @@ void menu_finalize(struct menu *parent)
if (menu->sym && menu->sym->type == S_UNKNOWN) if (menu->sym && menu->sym->type == S_UNKNOWN)
menu_set_type(sym->type); menu_set_type(sym->type);
} }
/*
* Use the choice itself as the parent dependency of
* the contained items. This turns the mode of the
* choice into an upper bound on the visibility of the
* choice value symbols.
*/
parentdep = expr_alloc_symbol(sym); parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt) } else if (parent->prompt)
/* Menu node for 'menu' */
parentdep = parent->prompt->visible.expr; parentdep = parent->prompt->visible.expr;
else else
/* Menu node for 'if' */
parentdep = parent->dep; parentdep = parent->dep;
/* For each child menu node... */
for (menu = parent->list; menu; menu = menu->next) { for (menu = parent->list; menu; menu = menu->next) {
basedep = expr_transform(menu->dep); /*
* Propagate parent dependencies to the child menu
* node, also rewriting and simplifying expressions
*/
basedep = rewrite_m(menu->dep);
basedep = expr_transform(basedep);
basedep = expr_alloc_and(expr_copy(parentdep), basedep); basedep = expr_alloc_and(expr_copy(parentdep), basedep);
basedep = expr_eliminate_dups(basedep); basedep = expr_eliminate_dups(basedep);
menu->dep = basedep; menu->dep = basedep;
if (menu->sym) if (menu->sym)
/*
* Note: For symbols, all prompts are included
* too in the symbol's own property list
*/
prop = menu->sym->prop; prop = menu->sym->prop;
else else
/*
* For non-symbol menu nodes, we just need to
* handle the prompt
*/
prop = menu->prompt; prop = menu->prompt;
/* For each property... */
for (; prop; prop = prop->next) { for (; prop; prop = prop->next) {
if (prop->menu != menu) if (prop->menu != menu)
/*
* Two possibilities:
*
* 1. The property lacks dependencies
* and so isn't location-specific,
* e.g. an 'option'
*
* 2. The property belongs to a symbol
* defined in multiple locations and
* is from some other location. It
* will be handled there in that
* case.
*
* Skip the property.
*/
continue; continue;
dep = expr_transform(prop->visible.expr);
/*
* Propagate parent dependencies to the
* property's condition, rewriting and
* simplifying expressions at the same time
*/
dep = rewrite_m(prop->visible.expr);
dep = expr_transform(dep);
dep = expr_alloc_and(expr_copy(basedep), dep); dep = expr_alloc_and(expr_copy(basedep), dep);
dep = expr_eliminate_dups(dep); dep = expr_eliminate_dups(dep);
if (menu->sym && menu->sym->type != S_TRISTATE) if (menu->sym && menu->sym->type != S_TRISTATE)
dep = expr_trans_bool(dep); dep = expr_trans_bool(dep);
prop->visible.expr = dep; prop->visible.expr = dep;
/*
* Handle selects and implies, which modify the
* dependencies of the selected/implied symbol
*/
if (prop->type == P_SELECT) { if (prop->type == P_SELECT) {
struct symbol *es = prop_get_symbol(prop); struct symbol *es = prop_get_symbol(prop);
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
} else if (prop->type == P_IMPLY) {
struct symbol *es = prop_get_symbol(prop);
es->implied.expr = expr_alloc_or(es->implied.expr,
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
} }
} }
} }
if (sym && sym_is_choice(sym))
expr_free(parentdep);
/*
* Recursively process children in the same fashion before
* moving on
*/
for (menu = parent->list; menu; menu = menu->next) for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu); menu_finalize(menu);
} else if (sym) { } else if (sym) {
/*
* Automatic submenu creation. If sym is a symbol and A, B, C,
* ... are consecutive items (symbols, menus, ifs, etc.) that
* all depend on sym, then the following menu structure is
* created:
*
* sym
* +-A
* +-B
* +-C
* ...
*
* This also works recursively, giving the following structure
* if A is a symbol and B depends on A:
*
* sym
* +-A
* | +-B
* +-C
* ...
*/
basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep)); basedep = expr_eliminate_dups(expr_transform(basedep));
/* Examine consecutive elements after sym */
last_menu = NULL; last_menu = NULL;
for (menu = parent->next; menu; menu = menu->next) { for (menu = parent->next; menu; menu = menu->next) {
dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
if (!expr_contains_symbol(dep, sym)) if (!expr_contains_symbol(dep, sym))
/* No dependency, quit */
break; break;
if (expr_depends_symbol(dep, sym)) if (expr_depends_symbol(dep, sym))
/* Absolute dependency, put in submenu */
goto next; goto next;
/*
* Also consider it a dependency on sym if our
* dependencies contain sym and are a "superset" of
* sym's dependencies, e.g. '(sym || Q) && R' when sym
* depends on R.
*
* Note that 'R' might be from an enclosing menu or if,
* making this a more common case than it might seem.
*/
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
dep = expr_eliminate_dups(expr_transform(dep)); dep = expr_eliminate_dups(expr_transform(dep));
dep2 = expr_copy(basedep); dep2 = expr_copy(basedep);
expr_eliminate_eq(&dep, &dep2); expr_eliminate_eq(&dep, &dep2);
expr_free(dep); expr_free(dep);
if (!expr_is_yes(dep2)) { if (!expr_is_yes(dep2)) {
/* Not superset, quit */
expr_free(dep2); expr_free(dep2);
break; break;
} }
/* Superset, put in submenu */
expr_free(dep2); expr_free(dep2);
next: next:
menu_finalize(menu); menu_finalize(menu);
menu->parent = parent; menu->parent = parent;
last_menu = menu; last_menu = menu;
} }
expr_free(basedep);
if (last_menu) { if (last_menu) {
parent->list = parent->next; parent->list = parent->next;
parent->next = last_menu->next; parent->next = last_menu->next;
@ -409,6 +535,35 @@ void menu_finalize(struct menu *parent)
*ep = expr_alloc_one(E_LIST, NULL); *ep = expr_alloc_one(E_LIST, NULL);
(*ep)->right.sym = menu->sym; (*ep)->right.sym = menu->sym;
} }
/*
* This code serves two purposes:
*
* (1) Flattening 'if' blocks, which do not specify a submenu
* and only add dependencies.
*
* (Automatic submenu creation might still create a submenu
* from an 'if' before this code runs.)
*
* (2) "Undoing" any automatic submenus created earlier below
* promptless symbols.
*
* Before:
*
* A
* if ... (or promptless symbol)
* +-B
* +-C
* D
*
* After:
*
* A
* if ... (or promptless symbol)
* B
* C
* D
*/
if (menu->list && (!menu->prompt || !menu->prompt->text)) { if (menu->list && (!menu->prompt || !menu->prompt->text)) {
for (last_menu = menu->list; ; last_menu = last_menu->next) { for (last_menu = menu->list; ; last_menu = last_menu->next) {
last_menu->parent = parent; last_menu->parent = parent;
@ -433,6 +588,15 @@ void menu_finalize(struct menu *parent)
sym->flags |= SYMBOL_WARNED; sym->flags |= SYMBOL_WARNED;
} }
/*
* For non-optional choices, add a reverse dependency (corresponding to
* a select) of '<visibility> && m'. This prevents the user from
* setting the choice mode to 'n' when the choice is visible.
*
* This would also work for non-choice symbols, but only non-optional
* choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented
* as a type of symbol.
*/
if (sym && !sym_is_optional(sym) && parent->prompt) { if (sym && !sym_is_optional(sym) && parent->prompt) {
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
expr_alloc_and(parent->prompt->visible.expr, expr_alloc_and(parent->prompt->visible.expr,
@ -474,7 +638,7 @@ bool menu_is_visible(struct menu *menu)
if (menu->visibility) { if (menu->visibility) {
if (expr_calc_value(menu->visibility) == no) if (expr_calc_value(menu->visibility) == no)
return no; return false;
} }
sym = menu->sym; sym = menu->sym;
@ -545,7 +709,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
{ {
int i, j; int i, j;
struct menu *submenu[8], *menu, *location = NULL; struct menu *submenu[8], *menu, *location = NULL;
struct jump_key *jump; struct jump_key *jump = NULL;
str_printf(r, _("Prompt: %s\n"), _(prop->text)); str_printf(r, _("Prompt: %s\n"), _(prop->text));
menu = prop->menu->parent; menu = prop->menu->parent;
@ -583,7 +747,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
str_printf(r, _(" Location:\n")); str_printf(r, _(" Location:\n"));
for (j = 4; --i >= 0; j += 2) { for (j = 4; --i >= 0; j += 2) {
menu = submenu[i]; menu = submenu[i];
if (head && location && menu == location) if (jump && menu == location)
jump->offset = strlen(r->s); jump->offset = strlen(r->s);
str_printf(r, "%*c-> %s", j, ' ', str_printf(r, "%*c-> %s", j, ' ',
_(menu_get_prompt(menu))); _(menu_get_prompt(menu)));
@ -609,13 +773,30 @@ static struct property *get_symbol_prop(struct symbol *sym)
return prop; return prop;
} }
static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
enum prop_type tok, const char *prefix)
{
bool hit = false;
struct property *prop;
for_all_properties(sym, prop, tok) {
if (!hit) {
str_append(r, prefix);
hit = true;
} else
str_printf(r, " && ");
expr_gstr_print(prop->expr, r);
}
if (hit)
str_append(r, "\n");
}
/* /*
* head is optional and may be NULL * head is optional and may be NULL
*/ */
void get_symbol_str(struct gstr *r, struct symbol *sym, static void get_symbol_str(struct gstr *r, struct symbol *sym,
struct list_head *head) struct list_head *head)
{ {
bool hit;
struct property *prop; struct property *prop;
if (sym && sym->name) { if (sym && sym->name) {
@ -645,22 +826,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym,
} }
} }
hit = false; get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
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) { if (sym->rev_dep.expr) {
str_append(r, _(" Selected by: ")); expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n");
expr_gstr_print(sym->rev_dep.expr, r); expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n");
str_append(r, "\n"); expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n");
} }
get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: "));
if (sym->implied.expr) {
expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n");
expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n");
expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n");
}
str_append(r, "\n\n"); str_append(r, "\n\n");
} }

View File

@ -32,11 +32,10 @@ usage() {
echo " -m only merge the fragments, do not execute the make command" echo " -m only merge the fragments, do not execute the make command"
echo " -n use allnoconfig instead of alldefconfig" echo " -n use allnoconfig instead of alldefconfig"
echo " -r list redundant entries when merging fragments" echo " -r list redundant entries when merging fragments"
echo " -O dir to put generated output files" echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead."
echo " -e colon-separated list of br2-external trees to use (optional)"
} }
MAKE=true RUNMAKE=true
ALLTARGET=alldefconfig ALLTARGET=alldefconfig
WARNREDUN=false WARNREDUN=false
OUTPUT=. OUTPUT=.
@ -49,7 +48,7 @@ while true; do
continue continue
;; ;;
"-m") "-m")
MAKE=false RUNMAKE=false
shift shift
continue continue
;; ;;
@ -72,55 +71,70 @@ while true; do
shift 2 shift 2
continue continue
;; ;;
"-e")
EXTERNAL_ARG="BR2_EXTERNAL=$2"
shift 2
continue
;;
*) *)
break break
;; ;;
esac esac
done done
if [ "$#" -lt 1 ] ; then
usage
exit
fi
if [ -z "$KCONFIG_CONFIG" ]; then
if [ "$OUTPUT" != . ]; then
KCONFIG_CONFIG=$(readlink -m -- "$OUTPUT/.config")
else
KCONFIG_CONFIG=.config
fi
fi
INITFILE=$1 INITFILE=$1
shift; shift;
if [ ! -r "$INITFILE" ]; then
echo "The base file '$INITFILE' does not exist. Exit." >&2
exit 1
fi
MERGE_LIST=$* MERGE_LIST=$*
SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p"
TMP_FILE=$(mktemp -t .tmp.config.XXXXXXXXXX) TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
echo "Using $INITFILE as base" echo "Using $INITFILE as base"
cat $INITFILE > $TMP_FILE cat $INITFILE > $TMP_FILE
# Merge files, printing warnings on overrided values # Merge files, printing warnings on overridden values
for MERGE_FILE in $MERGE_LIST ; do for MERGE_FILE in $MERGE_LIST ; do
echo "Merging $MERGE_FILE" echo "Merging $MERGE_FILE"
if [ ! -r "$MERGE_FILE" ]; then
echo "The merge file '$MERGE_FILE' does not exist. Exit." >&2
exit 1
fi
CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE)
for CFG in $CFG_LIST ; do for CFG in $CFG_LIST ; do
grep -q -w $CFG $TMP_FILE grep -q -w $CFG $TMP_FILE || continue
if [ $? -eq 0 ] ; then PREV_VAL=$(grep -w $CFG $TMP_FILE)
PREV_VAL=$(grep -w $CFG $TMP_FILE) NEW_VAL=$(grep -w $CFG $MERGE_FILE)
NEW_VAL=$(grep -w $CFG $MERGE_FILE) if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
echo Value of $CFG is redefined by fragment $MERGE_FILE: echo Value of $CFG is redefined by fragment $MERGE_FILE:
echo Previous value: $PREV_VAL echo Previous value: $PREV_VAL
echo New value: $NEW_VAL echo New value: $NEW_VAL
echo echo
elif [ "$WARNREDUN" = "true" ]; then elif [ "$WARNREDUN" = "true" ]; then
echo Value of $CFG is redundant by fragment $MERGE_FILE: echo Value of $CFG is redundant by fragment $MERGE_FILE:
fi
sed -i "/$CFG[ =]/d" $TMP_FILE
fi fi
sed -i "/$CFG[ =]/d" $TMP_FILE
done done
cat $MERGE_FILE >> $TMP_FILE cat $MERGE_FILE >> $TMP_FILE
done done
if [ "$MAKE" = "false" ]; then if [ "$RUNMAKE" = "false" ]; then
cp $TMP_FILE $OUTPUT/.config cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG"
echo "#" echo "#"
echo "# merged configuration written to $OUTPUT/.config (needs make)" echo "# merged configuration written to $KCONFIG_CONFIG (needs make)"
echo "#" echo "#"
clean_up clean_up
exit exit
@ -137,14 +151,14 @@ fi
# Use the merged file as the starting point for: # Use the merged file as the starting point for:
# alldefconfig: Fills in any missing symbols with Kconfig default # alldefconfig: Fills in any missing symbols with Kconfig default
# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set
make KCONFIG_ALLCONFIG=$TMP_FILE $EXTERNAL_ARG $OUTPUT_ARG $ALLTARGET make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
# Check all specified config values took (might have missed-dependency issues) # Check all specified config values took (might have missed-dependency issues)
for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
ACTUAL_VAL=$(grep -w -e "$CFG" $OUTPUT/.config) ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG")
if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
echo "Value requested for $CFG not in final .config" echo "Value requested for $CFG not in final .config"
echo "Requested value: $REQUESTED_VAL" echo "Requested value: $REQUESTED_VAL"

View File

@ -5,7 +5,9 @@
* Derived from menuconfig. * Derived from menuconfig.
* *
*/ */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
#endif
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -269,7 +271,7 @@ static struct mitem k_menu_items[MAX_MENU_ITEMS];
static int items_num; static int items_num;
static int global_exit; static int global_exit;
/* the currently selected button */ /* the currently selected button */
const char *current_instructions = menu_instructions; static const char *current_instructions = menu_instructions;
static char *dialog_input_result; static char *dialog_input_result;
static int dialog_input_result_len; static int dialog_input_result_len;
@ -303,7 +305,7 @@ struct function_keys {
}; };
static const int function_keys_num = 9; static const int function_keys_num = 9;
struct function_keys function_keys[] = { static struct function_keys function_keys[] = {
{ {
.key_str = "F1", .key_str = "F1",
.func = "Help", .func = "Help",
@ -506,7 +508,7 @@ static int get_mext_match(const char *match_str, match_f flag)
index = (index + items_num) % items_num; index = (index + items_num) % items_num;
while (true) { while (true) {
char *str = k_menu_items[index].str; char *str = k_menu_items[index].str;
if (strcasestr(str, match_str) != 0) if (strcasestr(str, match_str) != NULL)
return index; return index;
if (flag == FIND_NEXT_MATCH_UP || if (flag == FIND_NEXT_MATCH_UP ||
flag == MATCH_TINKER_PATTERN_UP) flag == MATCH_TINKER_PATTERN_UP)
@ -1065,7 +1067,7 @@ static int do_match(int key, struct match_state *state, int *ans)
static void conf(struct menu *menu) static void conf(struct menu *menu)
{ {
struct menu *submenu = 0; struct menu *submenu = NULL;
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
struct symbol *sym; struct symbol *sym;
int res; int res;
@ -1232,7 +1234,7 @@ static void show_help(struct menu *menu)
static void conf_choice(struct menu *menu) static void conf_choice(struct menu *menu)
{ {
const char *prompt = _(menu_get_prompt(menu)); const char *prompt = _(menu_get_prompt(menu));
struct menu *child = 0; struct menu *child = NULL;
struct symbol *active; struct symbol *active;
int selected_index = 0; int selected_index = 0;
int last_top_row = 0; int last_top_row = 0;
@ -1454,7 +1456,7 @@ static void conf_save(void)
} }
} }
void setup_windows(void) static void setup_windows(void)
{ {
int lines, columns; int lines, columns;
@ -1482,6 +1484,11 @@ int main(int ac, char **av)
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE); textdomain(PACKAGE);
if (ac > 1 && strcmp(av[1], "-s") == 0) {
/* Silence conf_read() until the real callback is set up */
conf_set_message_callback(NULL);
av++;
}
conf_parse(av[1]); conf_parse(av[1]);
conf_read(NULL); conf_read(NULL);
@ -1554,4 +1561,3 @@ int main(int ac, char **av)
endwin(); endwin();
return 0; return 0;
} }

View File

@ -6,6 +6,7 @@
* *
*/ */
#include "nconf.h" #include "nconf.h"
#include "lkc.h"
/* a list of all the different widgets we use */ /* a list of all the different widgets we use */
attributes_t attributes[ATTR_MAX+1] = {0}; attributes_t attributes[ATTR_MAX+1] = {0};
@ -129,7 +130,7 @@ static void no_colors_theme(void)
mkattrn(FUNCTION_TEXT, A_REVERSE); mkattrn(FUNCTION_TEXT, A_REVERSE);
} }
void set_colors() void set_colors(void)
{ {
start_color(); start_color();
use_default_colors(); use_default_colors();
@ -192,7 +193,7 @@ const char *get_line(const char *text, int line_no)
int lines = 0; int lines = 0;
if (!text) if (!text)
return 0; return NULL;
for (i = 0; text[i] != '\0' && lines < line_no; i++) for (i = 0; text[i] != '\0' && lines < line_no; i++)
if (text[i] == '\n') if (text[i] == '\n')
@ -364,15 +365,17 @@ int dialog_inputbox(WINDOW *main_window,
WINDOW *prompt_win; WINDOW *prompt_win;
WINDOW *form_win; WINDOW *form_win;
PANEL *panel; PANEL *panel;
int i, x, y; int i, x, y, lines, columns, win_lines, win_cols;
int res = -1; int res = -1;
int cursor_position = strlen(init); int cursor_position = strlen(init);
int cursor_form_win; int cursor_form_win;
char *result = *resultp; char *result = *resultp;
getmaxyx(stdscr, lines, columns);
if (strlen(init)+1 > *result_len) { if (strlen(init)+1 > *result_len) {
*result_len = strlen(init)+1; *result_len = strlen(init)+1;
*resultp = result = realloc(result, *result_len); *resultp = result = xrealloc(result, *result_len);
} }
/* find the widest line of msg: */ /* find the widest line of msg: */
@ -386,14 +389,19 @@ int dialog_inputbox(WINDOW *main_window,
if (title) if (title)
prompt_width = max(prompt_width, strlen(title)); prompt_width = max(prompt_width, strlen(title));
win_lines = min(prompt_lines+6, lines-2);
win_cols = min(prompt_width+7, columns-2);
prompt_lines = max(win_lines-6, 0);
prompt_width = max(win_cols-7, 0);
/* place dialog in middle of screen */ /* place dialog in middle of screen */
y = (getmaxy(stdscr)-(prompt_lines+4))/2; y = (lines-win_lines)/2;
x = (getmaxx(stdscr)-(prompt_width+4))/2; x = (columns-win_cols)/2;
strncpy(result, init, *result_len); strncpy(result, init, *result_len);
/* create the windows */ /* create the windows */
win = newwin(prompt_lines+6, prompt_width+7, y, x); win = newwin(win_lines, win_cols, y, x);
prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
keypad(form_win, TRUE); keypad(form_win, TRUE);

View File

@ -15,7 +15,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <locale.h> #include <locale.h>
#include <curses.h> #include <ncurses.h>
#include <menu.h> #include <menu.h>
#include <panel.h> #include <panel.h>
#include <form.h> #include <form.h>
@ -24,8 +24,6 @@
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include "ncurses.h"
#define max(a, b) ({\ #define max(a, b) ({\
typeof(a) _a = a;\ typeof(a) _a = a;\
typeof(b) _b = b;\ typeof(b) _b = b;\

View File

@ -8,8 +8,8 @@
Index: kconfig/gconf.glade Index: kconfig/gconf.glade
=================================================================== ===================================================================
--- kconfig.orig/gconf.glade 2013-12-27 22:14:32.395629843 +0100 --- kconfig.orig/gconf.glade
+++ kconfig/gconf.glade 2013-12-27 22:14:32.387630158 +0100 +++ kconfig/gconf.glade
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<widget class="GtkWindow" id="window1"> <widget class="GtkWindow" id="window1">
@ -21,9 +21,9 @@ Index: kconfig/gconf.glade
<property name="modal">False</property> <property name="modal">False</property>
Index: kconfig/mconf.c Index: kconfig/mconf.c
=================================================================== ===================================================================
--- kconfig.orig/mconf.c 2013-12-27 22:14:32.395629843 +0100 --- kconfig.orig/mconf.c
+++ kconfig/mconf.c 2013-12-27 22:14:42.179244153 +0100 +++ kconfig/mconf.c
@@ -176,9 +176,9 @@ @@ -176,9 +176,9 @@ menu_instructions[] = N_(
"Arrow keys navigate the menu. " "Arrow keys navigate the menu. "
"<Enter> selects submenus ---> (or empty submenus ----). " "<Enter> selects submenus ---> (or empty submenus ----). "
"Highlighted letters are hotkeys. " "Highlighted letters are hotkeys. "
@ -35,7 +35,7 @@ Index: kconfig/mconf.c
radiolist_instructions[] = N_( radiolist_instructions[] = N_(
"Use the arrow keys to navigate this window or " "Use the arrow keys to navigate this window or "
"press the hotkey of the item you wish to select " "press the hotkey of the item you wish to select "
@@ -959,7 +959,7 @@ @@ -962,7 +962,7 @@ static int handle_exit(void)
if (conf_get_changed()) if (conf_get_changed())
res = dialog_yesno(NULL, res = dialog_yesno(NULL,
_("Do you wish to save your new configuration?\n" _("Do you wish to save your new configuration?\n"
@ -46,44 +46,44 @@ Index: kconfig/mconf.c
res = -1; res = -1;
Index: kconfig/zconf.tab.c_shipped Index: kconfig/zconf.tab.c_shipped
=================================================================== ===================================================================
--- kconfig.orig/zconf.tab.c_shipped 2013-12-27 22:14:32.395629843 +0100 --- kconfig.orig/zconf.tab.c_shipped
+++ kconfig/zconf.tab.c_shipped 2013-12-27 22:14:32.391630000 +0100 +++ kconfig/zconf.tab.c_shipped
@@ -2297,7 +2297,7 @@ @@ -1515,7 +1515,7 @@
* later regardless of whether it comes from the 'prompt' in
* mainmenu_stmt or here
*/
- menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
+ menu_add_prompt(P_MENU, xstrdup("Buildroot Configuration"), NULL);
}
sym_init(); break;
_menu_init();
- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
+ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL);
if (getenv("ZCONF_DEBUG"))
zconfdebug = 1;
Index: kconfig/zconf.y Index: kconfig/zconf.y
=================================================================== ===================================================================
--- kconfig.orig/zconf.y 2013-12-27 22:14:32.395629843 +0100 --- kconfig.orig/zconf.y
+++ kconfig/zconf.y 2013-12-27 22:14:32.391630000 +0100 +++ kconfig/zconf.y
@@ -493,7 +493,7 @@ @@ -127,7 +127,7 @@ no_mainmenu_stmt: /* empty */
* later regardless of whether it comes from the 'prompt' in
* mainmenu_stmt or here
*/
- menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
+ menu_add_prompt(P_MENU, xstrdup("Buildroot Configuration"), NULL);
};
sym_init();
_menu_init();
- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
+ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL);
if (getenv("ZCONF_DEBUG"))
zconfdebug = 1;
Index: kconfig/confdata.c Index: kconfig/confdata.c
=================================================================== ===================================================================
--- kconfig.orig/confdata.c 2013-12-27 22:14:32.395629843 +0100 --- kconfig.orig/confdata.c
+++ kconfig/confdata.c 2013-12-27 22:14:32.391630000 +0100 +++ kconfig/confdata.c
@@ -25,7 +25,7 @@ @@ -30,7 +30,7 @@ static void conf_message(const char *fmt
static const char *conf_filename; static const char *conf_filename;
static int conf_lineno, conf_warnings, conf_unsaved; static int conf_lineno, conf_warnings;
-const char conf_defname[] = "arch/$ARCH/defconfig"; -const char conf_defname[] = "arch/$ARCH/defconfig";
+const char conf_defname[] = ".defconfig"; +const char conf_defname[] = ".defconfig";
static void conf_warning(const char *fmt, ...) static void conf_warning(const char *fmt, ...)
{ {
@@ -63,7 +63,7 @@ @@ -69,7 +69,7 @@ static void conf_message(const char *fmt
const char *conf_get_configname(void) const char *conf_get_configname(void)
{ {
@ -94,9 +94,9 @@ Index: kconfig/confdata.c
} }
Index: kconfig/qconf.cc Index: kconfig/qconf.cc
=================================================================== ===================================================================
--- kconfig.orig/qconf.cc 2013-12-27 22:12:15.825013567 +0100 --- kconfig.orig/qconf.cc
+++ kconfig/qconf.cc 2013-12-27 22:14:57.826627300 +0100 +++ kconfig/qconf.cc
@@ -70,7 +70,7 @@ @@ -55,7 +55,7 @@ static inline QString qgettext(const QSt
} }
ConfigSettings::ConfigSettings() ConfigSettings::ConfigSettings()

View File

@ -1,35 +1,74 @@
--- Index: kconfig/Makefile
Makefile | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: b/Makefile
=================================================================== ===================================================================
--- a/Makefile --- kconfig.orig/Makefile
+++ b/Makefile +++ kconfig/Makefile
@@ -159,11 +159,11 @@ @@ -211,7 +211,35 @@ qconf-cxxobjs := qconf.o
qconf-objs := zconf.tab.o
gconf-objs := gconf.o zconf.tab.o
hostprogs-y := conf -hostprogs-y := conf nconf mconf kxgettext qconf gconf
+hostprogs-y := conf
-ifeq ($(MAKECMDGOALS),nconfig) +
+ifeq ($(MAKECMDGOALS),nconf) +ifeq ($(MAKECMDGOALS),nconf)
hostprogs-y += nconf + hostprogs-y += nconf
endif +endif
+
-ifeq ($(MAKECMDGOALS),menuconfig)
+ifeq ($(MAKECMDGOALS),mconf) +ifeq ($(MAKECMDGOALS),mconf)
hostprogs-y += mconf + hostprogs-y += mconf
endif +endif
+
+ifeq ($(MAKECMDGOALS),update-po-config)
+ hostprogs-y += kxgettext
+endif
+
+ifeq ($(MAKECMDGOALS),qconf)
+ qconf-target := 1
+endif
+
+ifeq ($(MAKECMDGOALS),gconf)
+ gconf-target := 1
+endif
+
+ifeq ($(qconf-target),1)
+ hostprogs-y += qconf
+endif
+
+ifeq ($(gconf-target),1)
+ hostprogs-y += gconf
+endif
@@ -171,10 +171,10 @@ targets += zconf.lex.c
hostprogs-y += kxgettext clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck
endif @@ -243,7 +243,7 @@ HOSTLOADLIBES_nconf = $(shell \
|| echo "-lmenu -lpanel -lncurses" )
$(obj)/qconf.o: $(obj)/.tmp_qtcheck
-ifeq ($(MAKECMDGOALS),xconfig) -ifeq ($(MAKECMDGOALS),xconfig)
+ifeq ($(MAKECMDGOALS),qconf) +ifeq ($(MAKECMDGOALS),qconf)
qconf-target := 1 $(obj)/.tmp_qtcheck: $(src)/Makefile
endif -include $(obj)/.tmp_qtcheck
-ifeq ($(MAKECMDGOALS),gconfig)
+ifeq ($(MAKECMDGOALS),gconf) @@ -270,9 +276,8 @@
gconf-target := 1 echo "KC_QT_MOC=$$moc" >> $@
endif endif
+ifeq ($(MAKECMDGOALS),gconf)
$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
-
-ifeq ($(MAKECMDGOALS),gconfig)
-include $(obj)/.tmp_gtkcheck
# GTK+ needs some extra effort, too...
@@ -300,11 +305,8 @@
$(obj)/qconf.o: $(obj)/qconf.moc
-quiet_cmd_moc = MOC $@
- cmd_moc = $(KC_QT_MOC) -i $< -o $@
-
$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck
- $(call cmd,moc)
+ $(KC_QT_MOC) -i $< -o $@
# Extract gconf menu items for i18n support
$(obj)/gconf.glade.h: $(obj)/gconf.glade

View File

@ -3,10 +3,10 @@
foo.h | 12 ++++++++++++ foo.h | 12 ++++++++++++
2 files changed, 65 insertions(+) 2 files changed, 65 insertions(+)
Index: b/Makefile.br Index: kconfig/Makefile.br
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ b/Makefile.br +++ kconfig/Makefile.br
@@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
+src := . +src := .
+top_srcdir=../../ +top_srcdir=../../
@ -61,10 +61,10 @@ Index: b/Makefile.br
+ +
+FORCE: +FORCE:
+.PHONY: FORCE clean distclean +.PHONY: FORCE clean distclean
Index: b/foo.h Index: kconfig/foo.h
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ b/foo.h +++ kconfig/foo.h
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
+#ifndef __KCONFIG_FOO_H +#ifndef __KCONFIG_FOO_H
+#define __KCONFIG_FOO_H +#define __KCONFIG_FOO_H

View File

@ -2,11 +2,11 @@
lxdialog/check-lxdialog.sh | 2 +- lxdialog/check-lxdialog.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-) 1 file changed, 1 insertion(+), 1 deletion(-)
Index: b/lxdialog/check-lxdialog.sh Index: kconfig/lxdialog/check-lxdialog.sh
=================================================================== ===================================================================
--- a/lxdialog/check-lxdialog.sh --- kconfig.orig/lxdialog/check-lxdialog.sh
+++ b/lxdialog/check-lxdialog.sh +++ kconfig/lxdialog/check-lxdialog.sh
@@ -36,7 +36,7 @@ @@ -41,7 +41,7 @@ ccflags()
} }
# Temp file, try to clean up after us # Temp file, try to clean up after us

View File

@ -2,11 +2,11 @@
gconf.c | 2 +- gconf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-) 1 file changed, 1 insertion(+), 1 deletion(-)
Index: b/gconf.c Index: kconfig/gconf.c
=================================================================== ===================================================================
--- a/gconf.c --- kconfig.orig/gconf.c
+++ b/gconf.c +++ kconfig/gconf.c
@@ -1486,7 +1486,7 @@ @@ -1462,7 +1462,7 @@ int main(int ac, char *av[])
/* Determine GUI path */ /* Determine GUI path */
env = getenv(SRCTREE); env = getenv(SRCTREE);
if (env) if (env)

View File

@ -4,11 +4,11 @@
util.c | 16 +++++++++++++-- util.c | 16 +++++++++++++--
3 files changed, 61 insertions(+), 18 deletions(-) 3 files changed, 61 insertions(+), 18 deletions(-)
Index: b/conf.c Index: kconfig/conf.c
=================================================================== ===================================================================
--- a/conf.c --- kconfig.orig/conf.c
+++ b/conf.c +++ kconfig/conf.c
@@ -558,7 +558,6 @@ @@ -565,7 +565,6 @@ int main(int ac, char **av)
} }
name = av[optind]; name = av[optind];
conf_parse(name); conf_parse(name);
@ -16,10 +16,10 @@ Index: b/conf.c
if (sync_kconfig) { if (sync_kconfig) {
name = conf_get_configname(); name = conf_get_configname();
if (stat(name, &tmpstat)) { if (stat(name, &tmpstat)) {
Index: b/confdata.c Index: kconfig/confdata.c
=================================================================== ===================================================================
--- a/confdata.c --- kconfig.orig/confdata.c
+++ b/confdata.c +++ kconfig/confdata.c
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@ -28,7 +28,7 @@ Index: b/confdata.c
#include "lkc.h" #include "lkc.h"
@@ -70,9 +71,7 @@ @@ -76,9 +77,7 @@ const char *conf_get_configname(void)
const char *conf_get_autoconfig_name(void) const char *conf_get_autoconfig_name(void)
{ {
@ -39,7 +39,7 @@ Index: b/confdata.c
} }
static char *conf_expand_value(const char *in) static char *conf_expand_value(const char *in)
@@ -742,6 +741,9 @@ @@ -748,6 +747,9 @@ int conf_write(const char *name)
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
char *env; char *env;
@ -49,7 +49,7 @@ Index: b/confdata.c
dirname[0] = 0; dirname[0] = 0;
if (name && name[0]) { if (name && name[0]) {
struct stat st; struct stat st;
@@ -836,6 +838,7 @@ @@ -842,6 +844,7 @@ static int conf_split_config(void)
{ {
const char *name; const char *name;
char path[PATH_MAX+1]; char path[PATH_MAX+1];
@ -57,9 +57,9 @@ Index: b/confdata.c
char *s, *d, c; char *s, *d, c;
struct symbol *sym; struct symbol *sym;
struct stat sb; struct stat sb;
@@ -844,8 +847,20 @@ @@ -851,8 +854,20 @@ static int conf_split_config(void)
name = conf_get_autoconfig_name();
conf_read_simple(name, S_DEF_AUTO); conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym);
- if (chdir("include/config")) - if (chdir("include/config"))
- return 1; - return 1;
@ -80,7 +80,7 @@ Index: b/confdata.c
res = 0; res = 0;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
@@ -938,9 +953,11 @@ @@ -945,9 +960,11 @@ static int conf_split_config(void)
close(fd); close(fd);
} }
out: out:
@ -95,7 +95,7 @@ Index: b/confdata.c
return res; return res;
} }
@@ -950,25 +967,38 @@ @@ -957,25 +974,38 @@ int conf_write_autoconf(void)
const char *name; const char *name;
FILE *out, *tristate, *out_h; FILE *out, *tristate, *out_h;
int i; int i;
@ -138,7 +138,7 @@ Index: b/confdata.c
if (!out_h) { if (!out_h) {
fclose(out); fclose(out);
fclose(tristate); fclose(tristate);
@@ -1000,19 +1030,22 @@ @@ -1007,19 +1037,22 @@ int conf_write_autoconf(void)
name = getenv("KCONFIG_AUTOHEADER"); name = getenv("KCONFIG_AUTOHEADER");
if (!name) if (!name)
name = "include/generated/autoconf.h"; name = "include/generated/autoconf.h";
@ -164,11 +164,11 @@ Index: b/confdata.c
return 1; return 1;
return 0; return 0;
Index: b/util.c Index: kconfig/util.c
=================================================================== ===================================================================
--- a/util.c --- kconfig.orig/util.c
+++ b/util.c +++ kconfig/util.c
@@ -34,6 +34,8 @@ @@ -34,6 +34,8 @@ struct file *file_lookup(const char *nam
/* write a dependency file as used by kbuild to track dependencies */ /* write a dependency file as used by kbuild to track dependencies */
int file_write_dep(const char *name) int file_write_dep(const char *name)
{ {
@ -177,7 +177,7 @@ Index: b/util.c
struct symbol *sym, *env_sym; struct symbol *sym, *env_sym;
struct expr *e; struct expr *e;
struct file *file; struct file *file;
@@ -41,7 +43,16 @@ @@ -41,7 +43,16 @@ int file_write_dep(const char *name)
if (!name) if (!name)
name = ".kconfig.d"; name = ".kconfig.d";
@ -195,7 +195,7 @@ Index: b/util.c
if (!out) if (!out)
return 1; return 1;
fprintf(out, "deps_config := \\\n"); fprintf(out, "deps_config := \\\n");
@@ -72,7 +83,8 @@ @@ -72,7 +83,8 @@ int file_write_dep(const char *name)
fprintf(out, "\n$(deps_config): ;\n"); fprintf(out, "\n$(deps_config): ;\n");
fclose(out); fclose(out);

View File

@ -1,24 +0,0 @@
Fix the rule that generates the .moc file
The Linux kernel has a "cmd" make function, but we don't have it in
Buildroot, so we need to adjust this rule.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Index: b/Makefile
===================================================================
--- a/Makefile
+++ b/Makefile
@@ -309,11 +309,8 @@
$(obj)/qconf.o: $(obj)/qconf.moc
-quiet_cmd_moc = MOC $@
- cmd_moc = $(KC_QT_MOC) -i $< -o $@
-
$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck
- $(call cmd,moc)
+ $(KC_QT_MOC) -i $< -o $@
# Extract gconf menu items for I18N support
$(obj)/gconf.glade.h: $(obj)/gconf.glade

View File

@ -26,10 +26,10 @@ Date: Wed Nov 13 22:45:02 2013 +0100
--- ---
Note: I'll be running this upstream soonish. Note: I'll be running this upstream soonish.
diff --git a/support/kconfig/lxdialog/menubox.c b/support/kconfig/lxdialog/menubox.c Index: kconfig/lxdialog/menubox.c
index 48d382e..6fc7e78 100644 ===================================================================
--- a/lxdialog/menubox.c --- kconfig.orig/lxdialog/menubox.c
+++ b/lxdialog/menubox.c +++ kconfig/lxdialog/menubox.c
@@ -285,7 +285,7 @@ do_resize: @@ -285,7 +285,7 @@ do_resize:
if (key < 256 && isalpha(key)) if (key < 256 && isalpha(key))
key = tolower(key); key = tolower(key);

View File

@ -1,50 +0,0 @@
From be8af2d54a66911693eddc556e4f7a866670082b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= <bjorn.forsman@gmail.com>
Date: Sun, 14 Sep 2014 12:57:50 +0200
Subject: [PATCH] kconfig/lxdialog: get ncurses CFLAGS with pkg-config
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This makes "make menuconfig" also work on systems where ncurses is not
installed in a standard location (such as on NixOS).
This patch changes ccflags() so that it tries pkg-config first, and only
if pkg-config fails does it go back to the fallback/manual checks. This
is the same algorithm that ldflags() already uses.
Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com>
Signed-off-by: Michal Marek <mmarek@suse.cz>
---
[This patch is already applied upstream (is part of linux v3.18):
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=be8af2d54a66911693eddc556e4f7a866670082b
I'm adding this instead of doing a full upstream kconfig sync because
there was a conflict in one of the Buildroot kconfig patches (against
linux 3.18-rc1), which I was unable to resolve. Just drop this patch next time
Buildroot kconfig is synced against upstream.
]
scripts/kconfig/lxdialog/check-lxdialog.sh | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 9d2a4c5..5075ebf 100755
--- a/lxdialog/check-lxdialog.sh
+++ b/lxdialog/check-lxdialog.sh
@@ -21,7 +21,11 @@ ldflags()
# Where is ncurses.h?
ccflags()
{
- if [ -f /usr/include/ncursesw/curses.h ]; then
+ if pkg-config --cflags ncursesw 2>/dev/null; then
+ echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
+ elif pkg-config --cflags ncurses 2>/dev/null; then
+ echo '-DCURSES_LOC="<ncurses.h>"'
+ elif [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
echo ' -DNCURSES_WIDECHAR=1'
elif [ -f /usr/include/ncurses/ncurses.h ]; then
--
2.1.3

View File

@ -1,45 +0,0 @@
From 7285996aa0006d671bb01f0d35991d254b2b2b01 Mon Sep 17 00:00:00 2001
From: Brian Norris <computersforpeace@gmail.com>
Date: Wed, 4 Jun 2014 00:52:31 -0700
Subject: kconfig: nconfig: fix multi-byte UTF handling
Currently, Kconfig descriptions that use multi-byte UTF-8 characters
(such as MTD_NAND_CAFE) will have their menu entries dropped from the
'make nconfig' ncurses menu, and all subsequent entries in the same
window will be omitted. This seems to be due to the ncurses 'menu'
library, which does not traditionally handle UTF-8 >8-bit characters
properly.
The ncursesw library ('w' is for "wide") is written to handle these
UTF-8 characters, and is practically a drop-in replacement at the source
level. Use it by default, if available.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=43067
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Cc: "Yann E. MORIN" <yann.morin.1998@free.fr>
Cc: Martin Walch <walch.martin@web.de>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>
---
scripts/kconfig/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'scripts/kconfig/Makefile')
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index e7bf38e..c059385 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -191,7 +191,8 @@ HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
HOSTLOADLIBES_nconf = $(shell \
- pkg-config --libs menu panel ncurses 2>/dev/null \
+ pkg-config --libs menuw panelw ncursesw 2>/dev/null \
+ || pkg-config --libs menu panel ncurses 2>/dev/null \
|| echo "-lmenu -lpanel -lncurses" )
$(obj)/qconf.o: $(obj)/.tmp_qtcheck
--
cgit v1.1

View File

@ -4,7 +4,5 @@
11-use-mktemp-for-lxdialog.patch 11-use-mktemp-for-lxdialog.patch
12-fix-glade-file-path.patch 12-fix-glade-file-path.patch
14-support-out-of-tree-config.patch 14-support-out-of-tree-config.patch
15-fix-qconf-moc-rule.patch
16-fix-space-to-de-select-options.patch 16-fix-space-to-de-select-options.patch
17-kconfig-lxdialog-get-ncurses-CFLAGS-with-pkg-config.patch 17-backport-kecho.patch
18-kconfig-nconfig-fix-multi-byte-UTF-handling.patch

File diff suppressed because it is too large Load Diff

View File

@ -3,26 +3,18 @@
* Released under the terms of the GNU GPL v2.0. * Released under the terms of the GNU GPL v2.0.
*/ */
#if QT_VERSION < 0x040000 #include <QTextBrowser>
#include <qlistview.h> #include <QTreeWidget>
#else #include <QMainWindow>
#include <q3listview.h> #include <QHeaderView>
#endif
#include <qsettings.h> #include <qsettings.h>
#include <QPushButton>
#if QT_VERSION < 0x040000 #include <QSettings>
#define Q3ValueList QValueList #include <QLineEdit>
#define Q3PopupMenu QPopupMenu #include <QSplitter>
#define Q3ListView QListView #include <QCheckBox>
#define Q3ListViewItem QListViewItem #include <QDialog>
#define Q3VBox QVBox #include "expr.h"
#define Q3TextBrowser QTextBrowser
#define Q3MainWindow QMainWindow
#define Q3Action QAction
#define Q3ToolBar QToolBar
#define Q3ListViewItemIterator QListViewItemIterator
#define Q3FileDialog QFileDialog
#endif
class ConfigView; class ConfigView;
class ConfigList; class ConfigList;
@ -33,8 +25,8 @@ class ConfigMainWindow;
class ConfigSettings : public QSettings { class ConfigSettings : public QSettings {
public: public:
ConfigSettings(); ConfigSettings();
Q3ValueList<int> readSizes(const QString& key, bool *ok); QList<int> readSizes(const QString& key, bool *ok);
bool writeSizes(const QString& key, const Q3ValueList<int>& value); bool writeSizes(const QString& key, const QList<int>& value);
}; };
enum colIdx { enum colIdx {
@ -47,9 +39,9 @@ enum optionMode {
normalOpt = 0, allOpt, promptOpt normalOpt = 0, allOpt, promptOpt
}; };
class ConfigList : public Q3ListView { class ConfigList : public QTreeWidget {
Q_OBJECT Q_OBJECT
typedef class Q3ListView Parent; typedef class QTreeWidget Parent;
public: public:
ConfigList(ConfigView* p, const char *name = 0); ConfigList(ConfigView* p, const char *name = 0);
void reinit(void); void reinit(void);
@ -61,10 +53,10 @@ public:
protected: protected:
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
void contentsMousePressEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e);
void contentsMouseDoubleClickEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e); void focusInEvent(QFocusEvent *e);
void contextMenuEvent(QContextMenuEvent *e); void contextMenuEvent(QContextMenuEvent *e);
@ -95,32 +87,23 @@ public:
} }
ConfigItem* firstChild() const ConfigItem* firstChild() const
{ {
return (ConfigItem *)Parent::firstChild(); return (ConfigItem *)children().first();
} }
int mapIdx(colIdx idx) void addColumn(colIdx idx)
{ {
return colMap[idx]; showColumn(idx);
}
void addColumn(colIdx idx, const QString& label)
{
colMap[idx] = Parent::addColumn(label);
colRevMap[colMap[idx]] = idx;
} }
void removeColumn(colIdx idx) void removeColumn(colIdx idx)
{ {
int col = colMap[idx]; hideColumn(idx);
if (col >= 0) {
Parent::removeColumn(col);
colRevMap[col] = colMap[idx] = -1;
}
} }
void setAllOpen(bool open); void setAllOpen(bool open);
void setParentMenu(void); void setParentMenu(void);
bool menuSkip(struct menu *); bool menuSkip(struct menu *);
template <class P> void updateMenuList(ConfigItem *parent, struct menu*);
void updateMenuList(P*, struct menu*); void updateMenuList(ConfigList *parent, struct menu*);
bool updateAll; bool updateAll;
@ -132,30 +115,26 @@ public:
enum listMode mode; enum listMode mode;
enum optionMode optMode; enum optionMode optMode;
struct menu *rootEntry; struct menu *rootEntry;
QColorGroup disabledColorGroup; QPalette disabledColorGroup;
QColorGroup inactivedColorGroup; QPalette inactivedColorGroup;
Q3PopupMenu* headerPopup; QMenu* headerPopup;
private:
int colMap[colNr];
int colRevMap[colNr];
}; };
class ConfigItem : public Q3ListViewItem { class ConfigItem : public QTreeWidgetItem {
typedef class Q3ListViewItem Parent; typedef class QTreeWidgetItem Parent;
public: public:
ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v) ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), menu(m), visible(v), goParent(false) : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
{ {
init(); init();
} }
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), menu(m), visible(v), goParent(false) : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
{ {
init(); init();
} }
ConfigItem(Q3ListView *parent, ConfigItem *after, bool v) ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
: Parent(parent, after), menu(0), visible(v), goParent(true) : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
{ {
init(); init();
} }
@ -166,33 +145,43 @@ public:
void testUpdateMenu(bool v); void testUpdateMenu(bool v);
ConfigList* listView() const ConfigList* listView() const
{ {
return (ConfigList*)Parent::listView(); return (ConfigList*)Parent::treeWidget();
} }
ConfigItem* firstChild() const ConfigItem* firstChild() const
{ {
return (ConfigItem *)Parent::firstChild(); return (ConfigItem *)Parent::child(0);
} }
ConfigItem* nextSibling() const ConfigItem* nextSibling()
{ {
return (ConfigItem *)Parent::nextSibling(); ConfigItem *ret = NULL;
ConfigItem *_parent = (ConfigItem *)parent();
if(_parent) {
ret = (ConfigItem *)_parent->child(_parent->indexOfChild(this)+1);
} else {
QTreeWidget *_treeWidget = treeWidget();
ret = (ConfigItem *)_treeWidget->topLevelItem(_treeWidget->indexOfTopLevelItem(this)+1);
}
return ret;
} }
void setText(colIdx idx, const QString& text) void setText(colIdx idx, const QString& text)
{ {
Parent::setText(listView()->mapIdx(idx), text); Parent::setText(idx, text);
} }
QString text(colIdx idx) const QString text(colIdx idx) const
{ {
return Parent::text(listView()->mapIdx(idx)); return Parent::text(idx);
} }
void setPixmap(colIdx idx, const QPixmap& pm) void setPixmap(colIdx idx, const QIcon &icon)
{ {
Parent::setPixmap(listView()->mapIdx(idx), pm); Parent::setIcon(idx, icon);
} }
const QPixmap* pixmap(colIdx idx) const const QIcon pixmap(colIdx idx) const
{ {
return Parent::pixmap(listView()->mapIdx(idx)); return icon(idx);
} }
void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align); // TODO: Implement paintCell
ConfigItem* nextItem; ConfigItem* nextItem;
struct menu *menu; struct menu *menu;
@ -216,9 +205,9 @@ public:
ConfigItem *item; ConfigItem *item;
}; };
class ConfigView : public Q3VBox { class ConfigView : public QWidget {
Q_OBJECT Q_OBJECT
typedef class Q3VBox Parent; typedef class QWidget Parent;
public: public:
ConfigView(QWidget* parent, const char *name = 0); ConfigView(QWidget* parent, const char *name = 0);
~ConfigView(void); ~ConfigView(void);
@ -249,9 +238,9 @@ public:
static QAction *showPromptAction; static QAction *showPromptAction;
}; };
class ConfigInfoView : public Q3TextBrowser { class ConfigInfoView : public QTextBrowser {
Q_OBJECT Q_OBJECT
typedef class Q3TextBrowser Parent; typedef class QTextBrowser Parent;
public: public:
ConfigInfoView(QWidget* parent, const char *name = 0); ConfigInfoView(QWidget* parent, const char *name = 0);
bool showDebug(void) const { return _showDebug; } bool showDebug(void) const { return _showDebug; }
@ -271,8 +260,8 @@ protected:
QString debug_info(struct symbol *sym); QString debug_info(struct symbol *sym);
static QString print_filter(const QString &str); static QString print_filter(const QString &str);
static void expr_print_help(void *data, struct symbol *sym, const char *str); static void expr_print_help(void *data, struct symbol *sym, const char *str);
Q3PopupMenu* createPopupMenu(const QPoint& pos); QMenu *createStandardContextMenu(const QPoint & pos);
void contentsContextMenuEvent(QContextMenuEvent *e); void contextMenuEvent(QContextMenuEvent *e);
struct symbol *sym; struct symbol *sym;
struct menu *_menu; struct menu *_menu;
@ -299,10 +288,10 @@ protected:
struct symbol **result; struct symbol **result;
}; };
class ConfigMainWindow : public Q3MainWindow { class ConfigMainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
static Q3Action *saveAction; static QAction *saveAction;
static void conf_changed(void); static void conf_changed(void);
public: public:
ConfigMainWindow(void); ConfigMainWindow(void);
@ -331,8 +320,11 @@ protected:
ConfigView *configView; ConfigView *configView;
ConfigList *configList; ConfigList *configList;
ConfigInfoView *helpText; ConfigInfoView *helpText;
Q3ToolBar *toolBar; QToolBar *toolBar;
Q3Action *backAction; QAction *backAction;
QSplitter* split1; QAction *singleViewAction;
QSplitter* split2; QAction *splitViewAction;
QAction *fullViewAction;
QSplitter *split1;
QSplitter *split2;
}; };

56
support/kconfig/streamline_config.pl Normal file → Executable file
View File

@ -1,4 +1,4 @@
#!/usr/bin/perl -w #!/usr/bin/env perl
# #
# Copyright 2005-2009 - Steven Rostedt # Copyright 2005-2009 - Steven Rostedt
# Licensed under the terms of the GNU GPL License version 2 # Licensed under the terms of the GNU GPL License version 2
@ -42,6 +42,7 @@
# mv config_strip .config # mv config_strip .config
# make oldconfig # make oldconfig
# #
use warnings;
use strict; use strict;
use Getopt::Long; use Getopt::Long;
@ -137,7 +138,7 @@ my $ksource = ($ARGV[0] ? $ARGV[0] : '.');
my $kconfig = $ARGV[1]; my $kconfig = $ARGV[1];
my $lsmod_file = $ENV{'LSMOD'}; my $lsmod_file = $ENV{'LSMOD'};
my @makefiles = `find $ksource -name Makefile 2>/dev/null`; my @makefiles = `find $ksource -name Makefile -or -name Kbuild 2>/dev/null`;
chomp @makefiles; chomp @makefiles;
my %depends; my %depends;
@ -188,7 +189,7 @@ sub read_kconfig {
$cont = 0; $cont = 0;
# collect any Kconfig sources # collect any Kconfig sources
if (/^source\s*"(.*)"/) { if (/^source\s+"?([^"]+)/) {
my $kconfig = $1; my $kconfig = $1;
# prevent reading twice. # prevent reading twice.
if (!defined($read_kconfigs{$kconfig})) { if (!defined($read_kconfigs{$kconfig})) {
@ -219,6 +220,13 @@ sub read_kconfig {
$depends{$config} = $1; $depends{$config} = $1;
} elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) {
$depends{$config} .= " " . $1; $depends{$config} .= " " . $1;
} elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
my $dep = $3;
if ($dep !~ /^\s*(y|m|n)\s*$/) {
$dep =~ s/.*\sif\s+//;
$depends{$config} .= " " . $dep;
dprint "Added default depends $dep to $config\n";
}
# Get the configs that select this config # Get the configs that select this config
} elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
@ -230,7 +238,7 @@ sub read_kconfig {
} }
# configs without prompts must be selected # configs without prompts must be selected
} elsif ($state ne "NONE" && /^\s*tristate\s\S/) { } elsif ($state ne "NONE" && /^\s*(tristate\s+\S|prompt\b)/) {
# note if the config has a prompt # note if the config has a prompt
$prompts{$config} = 1; $prompts{$config} = 1;
@ -249,8 +257,8 @@ sub read_kconfig {
$iflevel-- if ($iflevel); $iflevel-- if ($iflevel);
# stop on "help" # stop on "help" and keywords that end a menu entry
} elsif (/^\s*help\s*$/) { } elsif (/^\s*(---)?help(---)?\s*$/ || /^(comment|choice|menu)\b/) {
$state = "NONE"; $state = "NONE";
} }
} }
@ -447,7 +455,7 @@ sub parse_config_depends
$p =~ s/^[^$valid]*[$valid]+//; $p =~ s/^[^$valid]*[$valid]+//;
# We only need to process if the depend config is a module # We only need to process if the depend config is a module
if (!defined($orig_configs{$conf}) || !$orig_configs{conf} eq "m") { if (!defined($orig_configs{$conf}) || $orig_configs{$conf} eq "y") {
next; next;
} }
@ -603,6 +611,40 @@ foreach my $line (@config_file) {
next; next;
} }
if (/CONFIG_MODULE_SIG_KEY="(.+)"/) {
my $orig_cert = $1;
my $default_cert = "certs/signing_key.pem";
# Check that the logic in this script still matches the one in Kconfig
if (!defined($depends{"MODULE_SIG_KEY"}) ||
$depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) {
print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ",
"update needed to ", __FILE__, " line ", __LINE__, "\n";
print;
} elsif ($orig_cert ne $default_cert && ! -f $orig_cert) {
print STDERR "Module signature verification enabled but ",
"module signing key \"$orig_cert\" not found. Resetting ",
"signing key to default value.\n";
print "CONFIG_MODULE_SIG_KEY=\"$default_cert\"\n";
} else {
print;
}
next;
}
if (/CONFIG_SYSTEM_TRUSTED_KEYS="(.+)"/) {
my $orig_keys = $1;
if (! -f $orig_keys) {
print STDERR "System keyring enabled but keys \"$orig_keys\" ",
"not found. Resetting keys to default value.\n";
print "CONFIG_SYSTEM_TRUSTED_KEYS=\"\"\n";
} else {
print;
}
next;
}
if (/^(CONFIG.*)=(m|y)/) { if (/^(CONFIG.*)=(m|y)/) {
if (defined($configs{$1})) { if (defined($configs{$1})) {
if ($localyesconfig) { if ($localyesconfig) {

View File

@ -77,7 +77,7 @@ const char *sym_type_name(enum symbol_type type)
{ {
switch (type) { switch (type) {
case S_BOOLEAN: case S_BOOLEAN:
return "boolean"; return "bool";
case S_TRISTATE: case S_TRISTATE:
return "tristate"; return "tristate";
case S_INT: case S_INT:
@ -112,7 +112,7 @@ struct property *sym_get_env_prop(struct symbol *sym)
return NULL; return NULL;
} }
struct property *sym_get_default_prop(struct symbol *sym) static struct property *sym_get_default_prop(struct symbol *sym)
{ {
struct property *prop; struct property *prop;
@ -183,18 +183,52 @@ static void sym_validate_range(struct symbol *sym)
sprintf(str, "%lld", val2); sprintf(str, "%lld", val2);
else else
sprintf(str, "0x%llx", val2); sprintf(str, "0x%llx", val2);
sym->curr.val = strdup(str); sym->curr.val = xstrdup(str);
}
static void sym_set_changed(struct symbol *sym)
{
struct property *prop;
sym->flags |= SYMBOL_CHANGED;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu)
prop->menu->flags |= MENU_CHANGED;
}
}
static void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym_set_changed(sym);
} }
static void sym_calc_visibility(struct symbol *sym) static void sym_calc_visibility(struct symbol *sym)
{ {
struct property *prop; struct property *prop;
struct symbol *choice_sym = NULL;
tristate tri; tristate tri;
/* any prompt visible? */ /* any prompt visible? */
tri = no; tri = no;
if (sym_is_choice_value(sym))
choice_sym = prop_get_symbol(sym_get_choice_prop(sym));
for_all_prompts(sym, prop) { for_all_prompts(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr); prop->visible.tri = expr_calc_value(prop->visible.expr);
/*
* Tristate choice_values with visibility 'mod' are
* not visible if the corresponding choice's value is
* 'yes'.
*/
if (choice_sym && sym->type == S_TRISTATE &&
prop->visible.tri == mod && choice_sym->curr.tri == yes)
prop->visible.tri = no;
tri = EXPR_OR(tri, prop->visible.tri); tri = EXPR_OR(tri, prop->visible.tri);
} }
if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
@ -209,7 +243,7 @@ static void sym_calc_visibility(struct symbol *sym)
tri = yes; tri = yes;
if (sym->dir_dep.expr) if (sym->dir_dep.expr)
tri = expr_calc_value(sym->dir_dep.expr); tri = expr_calc_value(sym->dir_dep.expr);
if (tri == mod) if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
tri = yes; tri = yes;
if (sym->dir_dep.tri != tri) { if (sym->dir_dep.tri != tri) {
sym->dir_dep.tri = tri; sym->dir_dep.tri = tri;
@ -224,6 +258,15 @@ static void sym_calc_visibility(struct symbol *sym)
sym->rev_dep.tri = tri; sym->rev_dep.tri = tri;
sym_set_changed(sym); sym_set_changed(sym);
} }
tri = no;
if (sym->implied.expr && sym->dir_dep.tri != no)
tri = expr_calc_value(sym->implied.expr);
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
tri = yes;
if (sym->implied.tri != tri) {
sym->implied.tri = tri;
sym_set_changed(sym);
}
} }
/* /*
@ -290,6 +333,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
return def_sym; return def_sym;
} }
static void sym_warn_unmet_dep(struct symbol *sym)
{
struct gstr gs = str_new();
str_printf(&gs,
"\nWARNING: unmet direct dependencies detected for %s\n",
sym->name);
str_printf(&gs,
" Depends on [%c]: ",
sym->dir_dep.tri == mod ? 'm' : 'n');
expr_gstr_print(sym->dir_dep.expr, &gs);
str_printf(&gs, "\n");
expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
" Selected by [y]:\n");
expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
" Selected by [m]:\n");
fputs(str_get(&gs), stderr);
}
void sym_calc_value(struct symbol *sym) void sym_calc_value(struct symbol *sym)
{ {
struct symbol_value newval, oldval; struct symbol_value newval, oldval;
@ -328,11 +392,13 @@ void sym_calc_value(struct symbol *sym)
sym->curr.tri = no; sym->curr.tri = no;
return; return;
} }
if (!sym_is_choice_value(sym)) sym->flags &= ~SYMBOL_WRITE;
sym->flags &= ~SYMBOL_WRITE;
sym_calc_visibility(sym); sym_calc_visibility(sym);
if (sym->visible != no)
sym->flags |= SYMBOL_WRITE;
/* set default if recursively called */ /* set default if recursively called */
sym->curr = newval; sym->curr = newval;
@ -347,7 +413,6 @@ void sym_calc_value(struct symbol *sym)
/* if the symbol is visible use the user value /* if the symbol is visible use the user value
* if available, otherwise try the default value * if available, otherwise try the default value
*/ */
sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) { if (sym_has_value(sym)) {
newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
sym->visible); sym->visible);
@ -359,38 +424,31 @@ void sym_calc_value(struct symbol *sym)
if (!sym_is_choice(sym)) { if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym); prop = sym_get_default_prop(sym);
if (prop) { if (prop) {
sym->flags |= SYMBOL_WRITE;
newval.tri = EXPR_AND(expr_calc_value(prop->expr), newval.tri = EXPR_AND(expr_calc_value(prop->expr),
prop->visible.tri); prop->visible.tri);
if (newval.tri != no)
sym->flags |= SYMBOL_WRITE;
}
if (sym->implied.tri != no) {
sym->flags |= SYMBOL_WRITE;
newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
} }
} }
calc_newval: calc_newval:
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { if (sym->dir_dep.tri < sym->rev_dep.tri)
struct expr *e; sym_warn_unmet_dep(sym);
e = expr_simplify_unmet_dep(sym->rev_dep.expr,
sym->dir_dep.expr);
fprintf(stderr, "warning: (");
expr_fprint(e, stderr);
fprintf(stderr, ") selects %s which has unmet direct dependencies (",
sym->name);
expr_fprint(sym->dir_dep.expr, stderr);
fprintf(stderr, ")\n");
expr_free(e);
}
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
} }
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) if (newval.tri == mod &&
(sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes))
newval.tri = yes; newval.tri = yes;
break; break;
case S_STRING: case S_STRING:
case S_HEX: case S_HEX:
case S_INT: case S_INT:
if (sym->visible != no) { if (sym->visible != no && sym_has_value(sym)) {
sym->flags |= SYMBOL_WRITE; newval.val = sym->def[S_DEF_USER].val;
if (sym_has_value(sym)) { break;
newval.val = sym->def[S_DEF_USER].val;
break;
}
} }
prop = sym_get_default_prop(sym); prop = sym_get_default_prop(sym);
if (prop) { if (prop) {
@ -447,28 +505,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym) for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID; sym->flags &= ~SYMBOL_VALID;
sym_add_change_count(1); sym_add_change_count(1);
if (modules_sym) sym_calc_value(modules_sym);
sym_calc_value(modules_sym);
}
void sym_set_changed(struct symbol *sym)
{
struct property *prop;
sym->flags |= SYMBOL_CHANGED;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu)
prop->menu->flags |= MENU_CHANGED;
}
}
void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym_set_changed(sym);
} }
bool sym_tristate_within_range(struct symbol *sym, tristate val) bool sym_tristate_within_range(struct symbol *sym, tristate val)
@ -485,6 +522,8 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
return false; return false;
if (sym->visible <= sym->rev_dep.tri) if (sym->visible <= sym->rev_dep.tri)
return false; return false;
if (sym->implied.tri == yes && val == mod)
return false;
if (sym_is_choice_value(sym) && sym->visible == yes) if (sym_is_choice_value(sym) && sym->visible == yes)
return val == yes; return val == yes;
return val >= sym->rev_dep.tri && val <= sym->visible; return val >= sym->rev_dep.tri && val <= sym->visible;
@ -737,6 +776,10 @@ const char *sym_get_string_default(struct symbol *sym)
if (sym->type == S_BOOLEAN && val == mod) if (sym->type == S_BOOLEAN && val == mod)
val = yes; val = yes;
/* adjust the default value if this symbol is implied by another */
if (val < sym->implied.tri)
val = sym->implied.tri;
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
@ -818,7 +861,7 @@ struct symbol *sym_lookup(const char *name, int flags)
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
return symbol; return symbol;
} }
new_name = strdup(name); new_name = xstrdup(name);
} else { } else {
new_name = NULL; new_name = NULL;
hash = 0; hash = 0;
@ -868,12 +911,16 @@ struct symbol *sym_find(const char *name)
* name to be expanded shall be prefixed by a '$'. Unknown symbol expands to * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
* the empty string. * the empty string.
*/ */
const char *sym_expand_string_value(const char *in) char *sym_expand_string_value(const char *in)
{ {
const char *src; const char *src;
char *res; char *res;
size_t reslen; size_t reslen;
/*
* Note: 'in' might come from a token that's about to be
* freed, so make sure to always allocate a new string
*/
reslen = strlen(in) + 1; reslen = strlen(in) + 1;
res = xmalloc(reslen); res = xmalloc(reslen);
res[0] = '\0'; res[0] = '\0';
@ -901,7 +948,7 @@ const char *sym_expand_string_value(const char *in)
newlen = strlen(res) + strlen(symval) + strlen(src) + 1; newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
if (newlen > reslen) { if (newlen > reslen) {
reslen = newlen; reslen = newlen;
res = realloc(res, reslen); res = xrealloc(res, reslen);
} }
strcat(res, symval); strcat(res, symval);
@ -1028,7 +1075,7 @@ struct symbol **sym_re_search(const char *pattern)
} }
if (sym_match_arr) { if (sym_match_arr) {
qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp); qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
sym_arr = malloc((cnt+1) * sizeof(struct symbol)); sym_arr = malloc((cnt+1) * sizeof(struct symbol *));
if (!sym_arr) if (!sym_arr)
goto sym_re_search_free; goto sym_re_search_free;
for (i = 0; i < cnt; i++) for (i = 0; i < cnt; i++)
@ -1117,6 +1164,7 @@ static void sym_check_print_recursive(struct symbol *last_sym)
if (stack->sym == last_sym) if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno); prop->file->name, prop->lineno);
if (stack->expr) { if (stack->expr) {
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
prop->file->name, prop->lineno, prop->file->name, prop->lineno,
@ -1146,6 +1194,11 @@ static void sym_check_print_recursive(struct symbol *last_sym)
} }
} }
fprintf(stderr,
"For a resolution refer to Documentation/kbuild/kconfig-language.txt\n"
"subsection \"Kconfig recursive dependency limitations\"\n"
"\n");
if (check_top == &cv_stack) if (check_top == &cv_stack)
dep_stack_remove(); dep_stack_remove();
} }
@ -1166,6 +1219,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
case E_NOT: case E_NOT:
return sym_check_expr_deps(e->left.expr); return sym_check_expr_deps(e->left.expr);
case E_EQUAL: case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL: case E_UNEQUAL:
sym = sym_check_deps(e->left.sym); sym = sym_check_deps(e->left.sym);
if (sym) if (sym)
@ -1176,7 +1233,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
default: default:
break; break;
} }
printf("Oops! How to check %d?\n", e->type); fprintf(stderr, "Oops! How to check %d?\n", e->type);
return NULL; return NULL;
} }
@ -1333,6 +1390,8 @@ const char *prop_get_type_name(enum prop_type type)
return "choice"; return "choice";
case P_SELECT: case P_SELECT:
return "select"; return "select";
case P_IMPLY:
return "imply";
case P_RANGE: case P_RANGE:
return "range"; return "range";
case P_SYMBOL: case P_SYMBOL:

View File

@ -14,11 +14,11 @@
struct file *file_lookup(const char *name) struct file *file_lookup(const char *name)
{ {
struct file *file; struct file *file;
const char *file_name = sym_expand_string_value(name); char *file_name = sym_expand_string_value(name);
for (file = file_list; file; file = file->next) { for (file = file_list; file; file = file->next) {
if (!strcmp(name, file->name)) { if (!strcmp(name, file->name)) {
free((void *)file_name); free(file_name);
return file; return file;
} }
} }
@ -100,16 +100,6 @@ struct gstr str_new(void)
return gs; return gs;
} }
/* Allocate and assign growable string */
struct gstr str_assign(const char *s)
{
struct gstr gs;
gs.s = strdup(s);
gs.len = strlen(s) + 1;
gs.max_width = 0;
return gs;
}
/* Free storage for growable string */ /* Free storage for growable string */
void str_free(struct gstr *gs) void str_free(struct gstr *gs)
{ {
@ -126,7 +116,7 @@ void str_append(struct gstr *gs, const char *s)
if (s) { if (s) {
l = strlen(gs->s) + strlen(s) + 1; l = strlen(gs->s) + strlen(s) + 1;
if (l > gs->len) { if (l > gs->len) {
gs->s = realloc(gs->s, l); gs->s = xrealloc(gs->s, l);
gs->len = l; gs->len = l;
} }
strcat(gs->s, s); strcat(gs->s, s);
@ -168,4 +158,22 @@ void *xcalloc(size_t nmemb, size_t size)
exit(1); exit(1);
} }
void *xrealloc(void *p, size_t size)
{
p = realloc(p, size);
if (p)
return p;
fprintf(stderr, "Out of memory.\n");
exit(1);
}
char *xstrdup(const char *s)
{
char *p;
p = strdup(s);
if (p)
return p;
fprintf(stderr, "Out of memory.\n");
exit(1);
}

View File

@ -1,47 +0,0 @@
%language=ANSI-C
%define hash-function-name kconf_id_hash
%define lookup-function-name kconf_id_lookup
%define string-pool-name kconf_id_strings
%compare-strncmp
%enum
%pic
%struct-type
struct kconf_id;
static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
%%
mainmenu, T_MAINMENU, TF_COMMAND
menu, T_MENU, TF_COMMAND
endmenu, T_ENDMENU, TF_COMMAND
source, T_SOURCE, TF_COMMAND
choice, T_CHOICE, TF_COMMAND
endchoice, T_ENDCHOICE, TF_COMMAND
comment, T_COMMENT, TF_COMMAND
config, T_CONFIG, TF_COMMAND
menuconfig, T_MENUCONFIG, TF_COMMAND
help, T_HELP, TF_COMMAND
if, T_IF, TF_COMMAND|TF_PARAM
endif, T_ENDIF, TF_COMMAND
depends, T_DEPENDS, TF_COMMAND
optional, T_OPTIONAL, TF_COMMAND
default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
prompt, T_PROMPT, TF_COMMAND
tristate, T_TYPE, TF_COMMAND, S_TRISTATE
def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
bool, T_TYPE, TF_COMMAND, S_BOOLEAN
boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
int, T_TYPE, TF_COMMAND, S_INT
hex, T_TYPE, TF_COMMAND, S_HEX
string, T_TYPE, TF_COMMAND, S_STRING
select, T_SELECT, TF_COMMAND
range, T_RANGE, TF_COMMAND
visible, T_VISIBLE, TF_COMMAND
option, T_OPTION, TF_COMMAND
on, T_ON, TF_PARAM
modules, T_OPT_MODULES, TF_OPTION
defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
env, T_OPT_ENV, TF_OPTION
%%

View File

@ -1,286 +0,0 @@
/* ANSI-C code produced by gperf version 3.0.4 */
/* Command-line: gperf -t --output-file scripts/kconfig/zconf.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/kconfig/zconf.gperf */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 10 "scripts/kconfig/zconf.gperf"
struct kconf_id;
static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
/* maximum key range = 71, duplicates = 0 */
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
kconf_id_hash (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 25, 25,
0, 0, 0, 5, 0, 0, 73, 73, 5, 0,
10, 5, 45, 73, 20, 20, 0, 15, 15, 73,
20, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73
};
register int hval = len;
switch (hval)
{
default:
hval += asso_values[(unsigned char)str[2]];
/*FALLTHROUGH*/
case 2:
case 1:
hval += asso_values[(unsigned char)str[0]];
break;
}
return hval + asso_values[(unsigned char)str[len - 1]];
}
struct kconf_id_strings_t
{
char kconf_id_strings_str2[sizeof("if")];
char kconf_id_strings_str3[sizeof("int")];
char kconf_id_strings_str5[sizeof("endif")];
char kconf_id_strings_str7[sizeof("default")];
char kconf_id_strings_str8[sizeof("tristate")];
char kconf_id_strings_str9[sizeof("endchoice")];
char kconf_id_strings_str12[sizeof("def_tristate")];
char kconf_id_strings_str13[sizeof("def_bool")];
char kconf_id_strings_str14[sizeof("defconfig_list")];
char kconf_id_strings_str17[sizeof("on")];
char kconf_id_strings_str18[sizeof("optional")];
char kconf_id_strings_str21[sizeof("option")];
char kconf_id_strings_str22[sizeof("endmenu")];
char kconf_id_strings_str23[sizeof("mainmenu")];
char kconf_id_strings_str25[sizeof("menuconfig")];
char kconf_id_strings_str27[sizeof("modules")];
char kconf_id_strings_str29[sizeof("menu")];
char kconf_id_strings_str31[sizeof("select")];
char kconf_id_strings_str32[sizeof("comment")];
char kconf_id_strings_str33[sizeof("env")];
char kconf_id_strings_str35[sizeof("range")];
char kconf_id_strings_str36[sizeof("choice")];
char kconf_id_strings_str39[sizeof("bool")];
char kconf_id_strings_str41[sizeof("source")];
char kconf_id_strings_str42[sizeof("visible")];
char kconf_id_strings_str43[sizeof("hex")];
char kconf_id_strings_str46[sizeof("config")];
char kconf_id_strings_str47[sizeof("boolean")];
char kconf_id_strings_str51[sizeof("string")];
char kconf_id_strings_str54[sizeof("help")];
char kconf_id_strings_str56[sizeof("prompt")];
char kconf_id_strings_str72[sizeof("depends")];
};
static const struct kconf_id_strings_t kconf_id_strings_contents =
{
"if",
"int",
"endif",
"default",
"tristate",
"endchoice",
"def_tristate",
"def_bool",
"defconfig_list",
"on",
"optional",
"option",
"endmenu",
"mainmenu",
"menuconfig",
"modules",
"menu",
"select",
"comment",
"env",
"range",
"choice",
"bool",
"source",
"visible",
"hex",
"config",
"boolean",
"string",
"help",
"prompt",
"depends"
};
#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
#ifdef __GNUC__
__inline
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const struct kconf_id *
kconf_id_lookup (register const char *str, register unsigned int len)
{
enum
{
TOTAL_KEYWORDS = 32,
MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 14,
MIN_HASH_VALUE = 2,
MAX_HASH_VALUE = 72
};
static const struct kconf_id wordlist[] =
{
{-1}, {-1},
#line 25 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM},
#line 36 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
{-1},
#line 26 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
{-1},
#line 29 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
#line 31 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
#line 20 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
{-1}, {-1},
#line 32 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE},
#line 35 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
#line 45 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION},
{-1}, {-1},
#line 43 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM},
#line 28 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND},
{-1}, {-1},
#line 42 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND},
#line 17 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND},
#line 15 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_MAINMENU, TF_COMMAND},
{-1},
#line 23 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND},
{-1},
#line 44 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
{-1},
#line 16 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
{-1},
#line 39 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
#line 21 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
#line 46 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION},
{-1},
#line 40 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND},
#line 19 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND},
{-1}, {-1},
#line 33 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_TYPE, TF_COMMAND, S_BOOLEAN},
{-1},
#line 18 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND},
#line 41 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND},
#line 37 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX},
{-1}, {-1},
#line 22 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND},
#line 34 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
{-1}, {-1}, {-1},
#line 38 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING},
{-1}, {-1},
#line 24 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str54, T_HELP, TF_COMMAND},
{-1},
#line 30 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str56, T_PROMPT, TF_COMMAND},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1},
#line 27 "scripts/kconfig/zconf.gperf"
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str72, T_DEPENDS, TF_COMMAND}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = kconf_id_hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register int o = wordlist[key].name;
if (o >= 0)
{
register const char *s = o + kconf_id_strings;
if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
return &wordlist[key];
}
}
}
return 0;
}
#line 47 "scripts/kconfig/zconf.gperf"

View File

@ -1,5 +1,5 @@
%option nostdinit noyywrap never-interactive full ecs %option nostdinit noyywrap never-interactive full ecs
%option 8bit nodefault perf-report perf-report %option 8bit nodefault yylineno
%option noinput %option noinput
%x COMMAND HELP STRING PARAM %x COMMAND HELP STRING PARAM
%{ %{
@ -27,8 +27,8 @@ static char *text;
static int text_size, text_asize; static int text_size, text_asize;
struct buffer { struct buffer {
struct buffer *parent; struct buffer *parent;
YY_BUFFER_STATE state; YY_BUFFER_STATE state;
}; };
struct buffer *current_buf; struct buffer *current_buf;
@ -52,7 +52,7 @@ static void append_string(const char *str, int size)
if (new_size > text_asize) { if (new_size > text_asize) {
new_size += START_STRSIZE - 1; new_size += START_STRSIZE - 1;
new_size &= -START_STRSIZE; new_size &= -START_STRSIZE;
text = realloc(text, new_size); text = xrealloc(text, new_size);
text_asize = new_size; text_asize = new_size;
} }
memcpy(text + text_size, str, size); memcpy(text + text_size, str, size);
@ -66,9 +66,16 @@ static void alloc_string(const char *str, int size)
memcpy(text, str, size); memcpy(text, str, size);
text[size] = 0; text[size] = 0;
} }
static void warn_ignored_character(char chr)
{
fprintf(stderr,
"%s:%d:warning: ignoring unsupported character '%c'\n",
zconf_curname(), zconf_lineno(), chr);
}
%} %}
n [A-Za-z0-9_] n [A-Za-z0-9_-]
%% %%
int str = 0; int str = 0;
@ -76,7 +83,6 @@ n [A-Za-z0-9_]
[ \t]*#.*\n | [ \t]*#.*\n |
[ \t]*\n { [ \t]*\n {
current_file->lineno++;
return T_EOL; return T_EOL;
} }
[ \t]*#.* [ \t]*#.*
@ -97,19 +103,18 @@ n [A-Za-z0-9_]
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
BEGIN(PARAM); BEGIN(PARAM);
current_pos.file = current_file; current_pos.file = current_file;
current_pos.lineno = current_file->lineno; current_pos.lineno = yylineno;
if (id && id->flags & TF_COMMAND) { if (id && id->flags & TF_COMMAND) {
zconflval.id = id; yylval.id = id;
return id->token; return id->token;
} }
alloc_string(yytext, yyleng); alloc_string(yytext, yyleng);
zconflval.string = text; yylval.string = text;
return T_WORD; return T_WORD;
} }
. . warn_ignored_character(*yytext);
\n { \n {
BEGIN(INITIAL); BEGIN(INITIAL);
current_file->lineno++;
return T_EOL; return T_EOL;
} }
} }
@ -122,26 +127,30 @@ n [A-Za-z0-9_]
"!" return T_NOT; "!" return T_NOT;
"=" return T_EQUAL; "=" return T_EQUAL;
"!=" return T_UNEQUAL; "!=" return T_UNEQUAL;
"<=" return T_LESS_EQUAL;
">=" return T_GREATER_EQUAL;
"<" return T_LESS;
">" return T_GREATER;
\"|\' { \"|\' {
str = yytext[0]; str = yytext[0];
new_string(); new_string();
BEGIN(STRING); BEGIN(STRING);
} }
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL; \n BEGIN(INITIAL); return T_EOL;
--- /* ignore */ ({n}|[/.])+ {
({n}|[-/.])+ {
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
if (id && id->flags & TF_PARAM) { if (id && id->flags & TF_PARAM) {
zconflval.id = id; yylval.id = id;
return id->token; return id->token;
} }
alloc_string(yytext, yyleng); alloc_string(yytext, yyleng);
zconflval.string = text; yylval.string = text;
return T_WORD; return T_WORD;
} }
#.* /* comment */ #.* /* comment */
\\\n current_file->lineno++; \\\n ;
. [[:blank:]]+
. warn_ignored_character(*yytext);
<<EOF>> { <<EOF>> {
BEGIN(INITIAL); BEGIN(INITIAL);
} }
@ -150,7 +159,7 @@ n [A-Za-z0-9_]
<STRING>{ <STRING>{
[^'"\\\n]+/\n { [^'"\\\n]+/\n {
append_string(yytext, yyleng); append_string(yytext, yyleng);
zconflval.string = text; yylval.string = text;
return T_WORD_QUOTE; return T_WORD_QUOTE;
} }
[^'"\\\n]+ { [^'"\\\n]+ {
@ -158,7 +167,7 @@ n [A-Za-z0-9_]
} }
\\.?/\n { \\.?/\n {
append_string(yytext + 1, yyleng - 1); append_string(yytext + 1, yyleng - 1);
zconflval.string = text; yylval.string = text;
return T_WORD_QUOTE; return T_WORD_QUOTE;
} }
\\.? { \\.? {
@ -167,14 +176,15 @@ n [A-Za-z0-9_]
\'|\" { \'|\" {
if (str == yytext[0]) { if (str == yytext[0]) {
BEGIN(PARAM); BEGIN(PARAM);
zconflval.string = text; yylval.string = text;
return T_WORD_QUOTE; return T_WORD_QUOTE;
} else } else
append_string(yytext, 1); append_string(yytext, 1);
} }
\n { \n {
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); fprintf(stderr,
current_file->lineno++; "%s:%d:warning: multi-line strings not supported\n",
zconf_curname(), zconf_lineno());
BEGIN(INITIAL); BEGIN(INITIAL);
return T_EOL; return T_EOL;
} }
@ -207,12 +217,10 @@ n [A-Za-z0-9_]
} }
} }
[ \t]*\n/[^ \t\n] { [ \t]*\n/[^ \t\n] {
current_file->lineno++;
zconf_endhelp(); zconf_endhelp();
return T_HELPTEXT; return T_HELPTEXT;
} }
[ \t]*\n { [ \t]*\n {
current_file->lineno++;
append_string("\n", 1); append_string("\n", 1);
} }
[^ \t\n].* { [^ \t\n].* {
@ -250,7 +258,7 @@ void zconf_starthelp(void)
static void zconf_endhelp(void) static void zconf_endhelp(void)
{ {
zconflval.string = text; yylval.string = text;
BEGIN(INITIAL); BEGIN(INITIAL);
} }
@ -283,7 +291,7 @@ void zconf_initscan(const char *name)
{ {
yyin = zconf_fopen(name); yyin = zconf_fopen(name);
if (!yyin) { if (!yyin) {
printf("can't find file %s\n", name); fprintf(stderr, "can't find file %s\n", name);
exit(1); exit(1);
} }
@ -291,7 +299,7 @@ void zconf_initscan(const char *name)
memset(current_buf, 0, sizeof(*current_buf)); memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name); current_file = file_lookup(name);
current_file->lineno = 1; yylineno = 1;
} }
void zconf_nextfile(const char *name) void zconf_nextfile(const char *name)
@ -304,35 +312,34 @@ void zconf_nextfile(const char *name)
current_buf->state = YY_CURRENT_BUFFER; current_buf->state = YY_CURRENT_BUFFER;
yyin = zconf_fopen(file->name); yyin = zconf_fopen(file->name);
if (!yyin) { if (!yyin) {
printf("%s:%d: can't open file \"%s\"\n", fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
zconf_curname(), zconf_lineno(), file->name); zconf_curname(), zconf_lineno(), file->name);
exit(1); exit(1);
} }
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf; buf->parent = current_buf;
current_buf = buf; current_buf = buf;
for (iter = current_file->parent; iter; iter = iter->parent ) { current_file->lineno = yylineno;
if (!strcmp(current_file->name,iter->name) ) { file->parent = current_file;
printf("%s:%d: recursive inclusion detected. "
"Inclusion path:\n current file : '%s'\n", for (iter = current_file; iter; iter = iter->parent) {
zconf_curname(), zconf_lineno(), if (!strcmp(iter->name, file->name)) {
zconf_curname()); fprintf(stderr,
iter = current_file->parent; "Recursive inclusion detected.\n"
while (iter && \ "Inclusion path:\n"
strcmp(iter->name,current_file->name)) { " current file : %s\n", file->name);
printf(" included from: '%s:%d'\n", iter = file;
iter->name, iter->lineno-1); do {
iter = iter->parent; iter = iter->parent;
} fprintf(stderr, " included from: %s:%d\n",
if (iter) iter->name, iter->lineno - 1);
printf(" included from: '%s:%d'\n", } while (strcmp(iter->name, file->name));
iter->name, iter->lineno+1);
exit(1); exit(1);
} }
} }
file->lineno = 1;
file->parent = current_file; yylineno = 1;
current_file = file; current_file = file;
} }
@ -341,6 +348,8 @@ static void zconf_endfile(void)
struct buffer *parent; struct buffer *parent;
current_file = current_file->parent; current_file = current_file->parent;
if (current_file)
yylineno = current_file->lineno;
parent = current_buf->parent; parent = current_buf->parent;
if (parent) { if (parent) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,10 +20,10 @@
int cdebug = PRINTD; int cdebug = PRINTD;
extern int zconflex(void); int yylex(void);
static void yyerror(const char *err);
static void zconfprint(const char *err, ...); static void zconfprint(const char *err, ...);
static void zconf_error(const char *err, ...); static void zconf_error(const char *err, ...);
static void zconferror(const char *err);
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[SYMBOL_HASHSIZE]; struct symbol *symbol_hash[SYMBOL_HASHSIZE];
@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry; static struct menu *current_menu, *current_entry;
%} %}
%expect 30 %expect 32
%union %union
{ {
@ -62,6 +62,7 @@ static struct menu *current_menu, *current_entry;
%token <id>T_TYPE %token <id>T_TYPE
%token <id>T_DEFAULT %token <id>T_DEFAULT
%token <id>T_SELECT %token <id>T_SELECT
%token <id>T_IMPLY
%token <id>T_RANGE %token <id>T_RANGE
%token <id>T_VISIBLE %token <id>T_VISIBLE
%token <id>T_OPTION %token <id>T_OPTION
@ -69,6 +70,10 @@ static struct menu *current_menu, *current_entry;
%token <string> T_WORD %token <string> T_WORD
%token <string> T_WORD_QUOTE %token <string> T_WORD_QUOTE
%token T_UNEQUAL %token T_UNEQUAL
%token T_LESS
%token T_LESS_EQUAL
%token T_GREATER
%token T_GREATER_EQUAL
%token T_CLOSE_PAREN %token T_CLOSE_PAREN
%token T_OPEN_PAREN %token T_OPEN_PAREN
%token T_EOL %token T_EOL
@ -76,9 +81,11 @@ static struct menu *current_menu, *current_entry;
%left T_OR %left T_OR
%left T_AND %left T_AND
%left T_EQUAL T_UNEQUAL %left T_EQUAL T_UNEQUAL
%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
%nonassoc T_NOT %nonassoc T_NOT
%type <string> prompt %type <string> prompt
%type <symbol> nonconst_symbol
%type <symbol> symbol %type <symbol> symbol
%type <expr> expr %type <expr> expr
%type <expr> if_expr %type <expr> if_expr
@ -95,14 +102,34 @@ static struct menu *current_menu, *current_entry;
} if_entry menu_entry choice_entry } if_entry menu_entry choice_entry
%{ %{
/* Include zconf.hash.c here so it can see the token constants. */ /* Include kconf_id.c here so it can see the token constants. */
#include "zconf.hash.c" #include "kconf_id.c"
%} %}
%% %%
input: nl start | start; input: nl start | start;
start: mainmenu_stmt stmt_list | stmt_list; start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list;
/* mainmenu entry */
mainmenu_stmt: T_MAINMENU prompt nl
{
menu_add_prompt(P_MENU, $2, NULL);
};
/* Default main menu, if there's no mainmenu entry */
no_mainmenu_stmt: /* empty */
{
/*
* Hack: Keep the main menu title on the heap so we can safely free it
* later regardless of whether it comes from the 'prompt' in
* mainmenu_stmt or here
*/
menu_add_prompt(P_MENU, xstrdup("Buildroot Configuration"), NULL);
};
stmt_list: stmt_list:
/* empty */ /* empty */
@ -113,13 +140,13 @@ stmt_list:
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
| stmt_list option_name error T_EOL | stmt_list option_name error T_EOL
{ {
zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); zconf_error("unexpected option \"%s\"", $2->name);
} }
| stmt_list error T_EOL { zconf_error("invalid statement"); } | stmt_list error T_EOL { zconf_error("invalid statement"); }
; ;
option_name: option_name:
T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
; ;
common_stmt: common_stmt:
@ -139,26 +166,23 @@ option_error:
/* config/menuconfig entry */ /* config/menuconfig entry */
config_entry_start: T_CONFIG T_WORD T_EOL config_entry_start: T_CONFIG nonconst_symbol T_EOL
{ {
struct symbol *sym = sym_lookup($2, 0); $2->flags |= SYMBOL_OPTIONAL;
sym->flags |= SYMBOL_OPTIONAL; menu_add_entry($2);
menu_add_entry(sym); printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
}; };
config_stmt: config_entry_start config_option_list config_stmt: config_entry_start config_option_list
{ {
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
}; };
menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
{ {
struct symbol *sym = sym_lookup($2, 0); $2->flags |= SYMBOL_OPTIONAL;
sym->flags |= SYMBOL_OPTIONAL; menu_add_entry($2);
menu_add_entry(sym); printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
}; };
menuconfig_stmt: menuconfig_entry_start config_option_list menuconfig_stmt: menuconfig_entry_start config_option_list
@ -167,7 +191,6 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
current_entry->prompt->type = P_MENU; current_entry->prompt->type = P_MENU;
else else
zconfprint("warning: menuconfig statement without prompt"); zconfprint("warning: menuconfig statement without prompt");
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
}; };
@ -205,12 +228,18 @@ config_option: T_DEFAULT expr if_expr T_EOL
$1->stype); $1->stype);
}; };
config_option: T_SELECT T_WORD if_expr T_EOL config_option: T_SELECT nonconst_symbol if_expr T_EOL
{ {
menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); menu_add_symbol(P_SELECT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
}; };
config_option: T_IMPLY nonconst_symbol if_expr T_EOL
{
menu_add_symbol(P_IMPLY, $2, $3);
printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
};
config_option: T_RANGE symbol symbol if_expr T_EOL config_option: T_RANGE symbol symbol if_expr T_EOL
{ {
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
@ -225,8 +254,10 @@ symbol_option_list:
| symbol_option_list T_WORD symbol_option_arg | symbol_option_list T_WORD symbol_option_arg
{ {
const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); const struct kconf_id *id = kconf_id_lookup($2, strlen($2));
if (id && id->flags & TF_OPTION) if (id && id->flags & TF_OPTION) {
menu_add_option(id->token, $3); menu_add_option(id->token, $3);
free($3);
}
else else
zconfprint("warning: ignoring unknown option %s", $2); zconfprint("warning: ignoring unknown option %s", $2);
free($2); free($2);
@ -245,6 +276,7 @@ choice: T_CHOICE word_opt T_EOL
sym->flags |= SYMBOL_AUTO; sym->flags |= SYMBOL_AUTO;
menu_add_entry(sym); menu_add_entry(sym);
menu_add_expr(P_CHOICE, NULL, NULL); menu_add_expr(P_CHOICE, NULL, NULL);
free($2);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
}; };
@ -296,10 +328,10 @@ choice_option: T_OPTIONAL T_EOL
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
}; };
choice_option: T_DEFAULT T_WORD if_expr T_EOL choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
{ {
if ($1->stype == S_UNKNOWN) { if ($1->stype == S_UNKNOWN) {
menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); menu_add_symbol(P_DEFAULT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", printd(DEBUG_PARSE, "%s:%d:default\n",
zconf_curname(), zconf_lineno()); zconf_curname(), zconf_lineno());
} else } else
@ -339,13 +371,6 @@ if_block:
| if_block choice_stmt | if_block choice_stmt
; ;
/* mainmenu entry */
mainmenu_stmt: T_MAINMENU prompt nl
{
menu_add_prompt(P_MENU, $2, NULL);
};
/* menu entry */ /* menu entry */
menu: T_MENU prompt T_EOL menu: T_MENU prompt T_EOL
@ -382,6 +407,7 @@ source_stmt: T_SOURCE prompt T_EOL
{ {
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
zconf_nextfile($2); zconf_nextfile($2);
free($2);
}; };
/* comment entry */ /* comment entry */
@ -394,9 +420,7 @@ comment: T_COMMENT prompt T_EOL
}; };
comment_stmt: comment depends_list comment_stmt: comment depends_list
{ ;
menu_end_entry();
};
/* help option */ /* help option */
@ -408,6 +432,17 @@ help_start: T_HELP T_EOL
help: help_start T_HELPTEXT help: help_start T_HELPTEXT
{ {
if (current_entry->help) {
free(current_entry->help);
zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used",
current_entry->sym->name ?: "<choice>");
}
/* Is the help text empty or all whitespace? */
if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
zconfprint("warning: '%s' defined with blank help text",
current_entry->sym->name ?: "<choice>");
current_entry->help = $2; current_entry->help = $2;
}; };
@ -467,6 +502,10 @@ if_expr: /* empty */ { $$ = NULL; }
; ;
expr: symbol { $$ = expr_alloc_symbol($1); } expr: symbol { $$ = expr_alloc_symbol($1); }
| symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); }
| symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); }
| symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); }
| symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); }
| symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
| symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
| T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
@ -475,7 +514,10 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
; ;
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } /* For symbol definitions, selects, etc., where quotes are not accepted */
nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); };
symbol: nonconst_symbol
| T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
; ;
@ -486,6 +528,7 @@ word_opt: /* empty */ { $$ = NULL; }
void conf_parse(const char *name) void conf_parse(const char *name)
{ {
const char *tmp;
struct symbol *sym; struct symbol *sym;
int i; int i;
@ -493,25 +536,26 @@ void conf_parse(const char *name)
sym_init(); sym_init();
_menu_init(); _menu_init();
rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL);
if (getenv("ZCONF_DEBUG")) if (getenv("ZCONF_DEBUG"))
zconfdebug = 1; yydebug = 1;
zconfparse(); yyparse();
if (zconfnerrs) if (yynerrs)
exit(1); exit(1);
if (!modules_sym) if (!modules_sym)
modules_sym = sym_find( "n" ); modules_sym = sym_find( "n" );
tmp = rootmenu.prompt->text;
rootmenu.prompt->text = _(rootmenu.prompt->text); rootmenu.prompt->text = _(rootmenu.prompt->text);
rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
free((char*)tmp);
menu_finalize(&rootmenu); menu_finalize(&rootmenu);
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
if (sym_check_deps(sym)) if (sym_check_deps(sym))
zconfnerrs++; yynerrs++;
} }
if (zconfnerrs) if (yynerrs)
exit(1); exit(1);
sym_set_change_count(1); sym_set_change_count(1);
} }
@ -535,17 +579,17 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok
{ {
if (id->token != endtoken) { if (id->token != endtoken) {
zconf_error("unexpected '%s' within %s block", zconf_error("unexpected '%s' within %s block",
kconf_id_strings + id->name, zconf_tokenname(starttoken)); id->name, zconf_tokenname(starttoken));
zconfnerrs++; yynerrs++;
return false; return false;
} }
if (current_menu->file != current_file) { if (current_menu->file != current_file) {
zconf_error("'%s' in different file than '%s'", zconf_error("'%s' in different file than '%s'",
kconf_id_strings + id->name, zconf_tokenname(starttoken)); id->name, zconf_tokenname(starttoken));
fprintf(stderr, "%s:%d: location of the '%s'\n", fprintf(stderr, "%s:%d: location of the '%s'\n",
current_menu->file->name, current_menu->lineno, current_menu->file->name, current_menu->lineno,
zconf_tokenname(starttoken)); zconf_tokenname(starttoken));
zconfnerrs++; yynerrs++;
return false; return false;
} }
return true; return true;
@ -566,7 +610,7 @@ static void zconf_error(const char *err, ...)
{ {
va_list ap; va_list ap;
zconfnerrs++; yynerrs++;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err); va_start(ap, err);
vfprintf(stderr, err, ap); vfprintf(stderr, err, ap);
@ -574,7 +618,7 @@ static void zconf_error(const char *err, ...)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
static void zconferror(const char *err) static void yyerror(const char *err)
{ {
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
} }
@ -607,7 +651,7 @@ static void print_symbol(FILE *out, struct menu *menu)
fprintf(out, "\nconfig %s\n", sym->name); fprintf(out, "\nconfig %s\n", sym->name);
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
fputs(" boolean\n", out); fputs(" bool\n", out);
break; break;
case S_TRISTATE: case S_TRISTATE:
fputs(" tristate\n", out); fputs(" tristate\n", out);
@ -655,6 +699,11 @@ static void print_symbol(FILE *out, struct menu *menu)
expr_fprint(prop->expr, out); expr_fprint(prop->expr, out);
fputc('\n', out); fputc('\n', out);
break; break;
case P_IMPLY:
fputs( " imply ", out);
expr_fprint(prop->expr, out);
fputc('\n', out);
break;
case P_RANGE: case P_RANGE:
fputs( " range ", out); fputs( " range ", out);
expr_fprint(prop->expr, out); expr_fprint(prop->expr, out);