util/kconfig: Uprev to Linux 5.13's kconfig
This was originally several commits that had to be squashed into one because the intermediate states weren't able to build coreboot: - one to remove everything that wasn't our own code, leaving only regex.[ch], toada.c, description.md and Makefile.inc. - one to copy in Linux 5.13's scripts/kconfig and adapt Makefile.inc to make the original Makefile work again. - adapt abuild to use olddefconfig, simplifying matters. - apply patches in util/kconfig/patches. - Some more adaptations to the libpayload build system. The patches are now in util/kconfig/patches/, reverse applying them should lead to a util/kconfig/ tree that contains exactly the Linux version + our own 5 files. Change-Id: Ia0e8fe4e9022b278f34ab113a433ef4d45e5c355 Signed-off-by: Patrick Georgi <pgeorgi@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37152 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
This commit is contained in:
		| @@ -55,10 +55,6 @@ command line. | |||||||
| - savedefconfig - Creates a ‘defconfig’ file, stripping out all of the symbols | - savedefconfig - Creates a ‘defconfig’ file, stripping out all of the symbols | ||||||
|   that were left as default values.  This is very useful for debugging, and is |   that were left as default values.  This is very useful for debugging, and is | ||||||
|   how config files should be saved. |   how config files should be saved. | ||||||
| - silentoldconfig - This evaluates the .config file the same way that the |  | ||||||
|   oldconfig target does, but does not print out each question as it is |  | ||||||
|   evaluated.  It still stops to query the user if an option with no answer in |  | ||||||
|   the .config file is found. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ### Targets not typically used in coreboot | ### Targets not typically used in coreboot | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @@ -37,7 +37,7 @@ KCONFIG_AUTOADS := $(obj)/cb-config.ads | |||||||
| KCONFIG_AUTOHEADER := $(obj)/config.h | KCONFIG_AUTOHEADER := $(obj)/config.h | ||||||
| KCONFIG_AUTOCONFIG := $(obj)/auto.conf | KCONFIG_AUTOCONFIG := $(obj)/auto.conf | ||||||
| KCONFIG_DEPENDENCIES := $(obj)/auto.conf.cmd | KCONFIG_DEPENDENCIES := $(obj)/auto.conf.cmd | ||||||
| KCONFIG_SPLITCONFIG := $(obj)/config | KCONFIG_SPLITCONFIG := $(obj)/config/ | ||||||
| KCONFIG_TRISTATE := $(obj)/tristate.conf | KCONFIG_TRISTATE := $(obj)/tristate.conf | ||||||
| KCONFIG_NEGATIVES := 1 | KCONFIG_NEGATIVES := 1 | ||||||
| KCONFIG_STRICT := 1 | KCONFIG_STRICT := 1 | ||||||
| @@ -196,7 +196,8 @@ real-all: real-target | |||||||
| .DELETE_ON_ERROR: | .DELETE_ON_ERROR: | ||||||
|  |  | ||||||
| $(KCONFIG_AUTOHEADER): $(KCONFIG_CONFIG) $(objutil)/kconfig/conf | $(KCONFIG_AUTOHEADER): $(KCONFIG_CONFIG) $(objutil)/kconfig/conf | ||||||
| 	+$(MAKE) oldconfig | 	$(MAKE) olddefconfig | ||||||
|  | 	$(MAKE) syncconfig | ||||||
|  |  | ||||||
| $(KCONFIG_AUTOCONFIG): $(KCONFIG_AUTOHEADER) | $(KCONFIG_AUTOCONFIG): $(KCONFIG_AUTOHEADER) | ||||||
| 	true | 	true | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ export KCONFIG_SPLITCONFIG	:= $(obj)/config | |||||||
| export KCONFIG_TRISTATE		:= $(obj)/tristate.conf | export KCONFIG_TRISTATE		:= $(obj)/tristate.conf | ||||||
| export KCONFIG_CONFIG		:= $(CURDIR)/.config | export KCONFIG_CONFIG		:= $(CURDIR)/.config | ||||||
| export KCONFIG_NEGATIVES	:= 1 | export KCONFIG_NEGATIVES	:= 1 | ||||||
| export Kconfig			:= Kconfig | export KBUILD_KCONFIG		:= Kconfig | ||||||
|  |  | ||||||
| CONFIG_SHELL := sh | CONFIG_SHELL := sh | ||||||
| KBUILD_DEFCONFIG := configs/defconfig | KBUILD_DEFCONFIG := configs/defconfig | ||||||
| @@ -70,7 +70,7 @@ $(obj)/config.h: | |||||||
|  |  | ||||||
| $(shell mkdir -p $(objk)/lxdialog $(KCONFIG_SPLITCONFIG)) | $(shell mkdir -p $(objk)/lxdialog $(KCONFIG_SPLITCONFIG)) | ||||||
|  |  | ||||||
| include $(srck)/Makefile | include $(srck)/Makefile.inc | ||||||
|  |  | ||||||
| .PHONY: $(PHONY) prepare all real-all defaultbuild | .PHONY: $(PHONY) prepare all real-all defaultbuild | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,10 +43,10 @@ export objk := $(objutil)/lp_kconfig | |||||||
| export KCONFIG_AUTOHEADER := $(obj)/config.h | export KCONFIG_AUTOHEADER := $(obj)/config.h | ||||||
| export KCONFIG_AUTOCONFIG := $(obj)/auto.conf | export KCONFIG_AUTOCONFIG := $(obj)/auto.conf | ||||||
| export KCONFIG_DEPENDENCIES := $(obj)/auto.conf.cmd | export KCONFIG_DEPENDENCIES := $(obj)/auto.conf.cmd | ||||||
| export KCONFIG_SPLITCONFIG := $(obj)/config | export KCONFIG_SPLITCONFIG := $(obj)/config/ | ||||||
| export KCONFIG_TRISTATE := $(obj)/tristate.conf | export KCONFIG_TRISTATE := $(obj)/tristate.conf | ||||||
| export KCONFIG_NEGATIVES := 1 | export KCONFIG_NEGATIVES := 1 | ||||||
| export Kconfig := Kconfig | export KBUILD_KCONFIG := Kconfig | ||||||
| export CONFIG_ := CONFIG_LP_ | export CONFIG_ := CONFIG_LP_ | ||||||
|  |  | ||||||
| # directory containing the toplevel Makefile.inc | # directory containing the toplevel Makefile.inc | ||||||
| @@ -88,7 +88,7 @@ endif | |||||||
|  |  | ||||||
| # This include must come _before_ the pattern rules below! | # This include must come _before_ the pattern rules below! | ||||||
| # Order _does_ matter for pattern rules. | # Order _does_ matter for pattern rules. | ||||||
| include $(srck)/Makefile | include $(srck)/Makefile.inc | ||||||
|  |  | ||||||
| include $(HAVE_DOTCONFIG) | include $(HAVE_DOTCONFIG) | ||||||
|  |  | ||||||
| @@ -202,7 +202,8 @@ endif | |||||||
| .SECONDEXPANSION: | .SECONDEXPANSION: | ||||||
|  |  | ||||||
| $(KCONFIG_AUTOHEADER): $(KCONFIG_CONFIG) | $(KCONFIG_AUTOHEADER): $(KCONFIG_CONFIG) | ||||||
| 	$(MAKE) oldconfig | 	$(MAKE) CONFIG_=CONFIG_LP_ olddefconfig | ||||||
|  | 	$(MAKE) CONFIG_=CONFIG_LP_ syncconfig | ||||||
|  |  | ||||||
| # Add a new class of source/object files to the build system | # Add a new class of source/object files to the build system | ||||||
| add-class= \ | add-class= \ | ||||||
|   | |||||||
| @@ -119,6 +119,7 @@ $(obj)/%.S.o: %.S $(LIBPAYLOAD_CONFIG_H) $(DEFAULT_DEPS) | |||||||
|  |  | ||||||
| LIBPAYLOAD_OPTS := obj="$(LIBPAYLOAD_OBJ)" | LIBPAYLOAD_OPTS := obj="$(LIBPAYLOAD_OBJ)" | ||||||
| LIBPAYLOAD_OPTS += DOTCONFIG="$(LIBPAYLOAD_DOTCONFIG)" | LIBPAYLOAD_OPTS += DOTCONFIG="$(LIBPAYLOAD_DOTCONFIG)" | ||||||
|  | LIBPAYLOAD_OPTS += CONFIG_=CONFIG_LP_ | ||||||
| LIBPAYLOAD_OPTS += $(if $(CCACHE),CONFIG_LP_CCACHE=y) | LIBPAYLOAD_OPTS += $(if $(CCACHE),CONFIG_LP_CCACHE=y) | ||||||
|  |  | ||||||
| defconfig: lp-defconfig | defconfig: lp-defconfig | ||||||
|   | |||||||
| @@ -169,8 +169,8 @@ $(TEST_KCONFIG_AUTOHEADER): TEST_KCONFIG_FLAGS:= DOTCONFIG=$(TEST_DOTCONFIG) \ | |||||||
|  |  | ||||||
| $(TEST_KCONFIG_AUTOHEADER): $(TEST_DOTCONFIG) $(objutil)/kconfig/conf | $(TEST_KCONFIG_AUTOHEADER): $(TEST_DOTCONFIG) $(objutil)/kconfig/conf | ||||||
| 	mkdir -p $(dir $@) | 	mkdir -p $(dir $@) | ||||||
| 	+$(MAKE) $(TEST_KCONFIG_FLAGS) olddefconfig | 	$(MAKE) $(TEST_KCONFIG_FLAGS) olddefconfig | ||||||
| 	+$(MAKE) $(TEST_KCONFIG_FLAGS) silentoldconfig | 	$(MAKE) $(TEST_KCONFIG_FLAGS) syncconfig | ||||||
|  |  | ||||||
| $(TEST_KCONFIG_AUTOCONFIG): $(TEST_KCONFIG_AUTOHEADER) | $(TEST_KCONFIG_AUTOCONFIG): $(TEST_KCONFIG_AUTOHEADER) | ||||||
| 	true | 	true | ||||||
|   | |||||||
| @@ -281,7 +281,7 @@ function update_config | |||||||
| 	# shellcheck disable=SC2059 | 	# shellcheck disable=SC2059 | ||||||
| 	printf "$configoptions" >> "${config_file}" | 	printf "$configoptions" >> "${config_file}" | ||||||
|  |  | ||||||
| 	yes "" 2>/dev/null | $MAKE oldconfig "$verboseopt" "DOTCONFIG=${config_file}" "obj=${build_dir}" "objutil=$TARGET/sharedutils" &> "${build_dir}/config.log" ; \ | 	$MAKE olddefconfig "$verboseopt" "DOTCONFIG=${config_file}" "obj=${build_dir}" "objutil=$TARGET/sharedutils" &> "${build_dir}/config.log" ; \ | ||||||
| 		CONFIG_OK=$? | 		CONFIG_OK=$? | ||||||
| 	if [ $CONFIG_OK -eq 0 ]; then | 	if [ $CONFIG_OK -eq 0 ]; then | ||||||
| 		$MAKE savedefconfig "$verboseopt" DEFCONFIG="${defconfig_file}" DOTCONFIG="${config_file}" obj="${build_dir}" objutil="$TARGET/sharedutils" &>> "${build_dir}/config.log" | 		$MAKE savedefconfig "$verboseopt" DEFCONFIG="${defconfig_file}" DOTCONFIG="${config_file}" obj="${build_dir}" objutil="$TARGET/sharedutils" &>> "${build_dir}/config.log" | ||||||
| @@ -316,7 +316,7 @@ function create_buildenv | |||||||
| 	echo "OBJUTIL=\$(BUILD)/sharedutils" >> "$MAKEFILE" | 	echo "OBJUTIL=\$(BUILD)/sharedutils" >> "$MAKEFILE" | ||||||
| 	echo "all:" >> "$MAKEFILE" | 	echo "all:" >> "$MAKEFILE" | ||||||
| 	echo "	@cp -a config.h config.h.bak" >> "$MAKEFILE" | 	echo "	@cp -a config.h config.h.bak" >> "$MAKEFILE" | ||||||
| 	echo "	@cd \$(TOP); \$(MAKE) oldconfig DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)" >> "$MAKEFILE" | 	echo "	@cd \$(TOP); \$(MAKE) olddefconfig DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)" >> "$MAKEFILE" | ||||||
| 	echo "	@tail -n+6 config.h > config.new; tail -n+6 config.h.bak > config.old" >> "$MAKEFILE" | 	echo "	@tail -n+6 config.h > config.new; tail -n+6 config.h.bak > config.old" >> "$MAKEFILE" | ||||||
| 	echo "	@cmp -s config.new config.old && cp -a config.h.bak config.h || echo \"Config file changed\"" >> "$MAKEFILE" | 	echo "	@cmp -s config.new config.old && cp -a config.h.bak config.h || echo \"Config file changed\"" >> "$MAKEFILE" | ||||||
| 	echo "	@rm config.h.bak config.new config.old" >> "$MAKEFILE" | 	echo "	@rm config.h.bak config.new config.old" >> "$MAKEFILE" | ||||||
| @@ -788,7 +788,7 @@ fi | |||||||
|  |  | ||||||
| # Generate a single xcompile for all boards | # Generate a single xcompile for all boards | ||||||
| export xcompile="${TARGET}/xcompile" | export xcompile="${TARGET}/xcompile" | ||||||
| $MAKE -C"${ROOT}" UPDATED_SUBMODULES=1 "${xcompile}" || exit 1 | $MAKE -C"${ROOT}" obj="$TARGET/temp" objutil="$TARGET/sharedutils" UPDATED_SUBMODULES=1 "${xcompile}" || exit 1 | ||||||
|  |  | ||||||
| customizing=$(echo "$customizing" | cut -c3-) | customizing=$(echo "$customizing" | cut -c3-) | ||||||
| if [ "$customizing" = "" ]; then | if [ "$customizing" = "" ]; then | ||||||
| @@ -838,9 +838,7 @@ build_targets() | |||||||
| 	# seed shared utils | 	# seed shared utils | ||||||
| 	TMPCFG=$(mktemp) | 	TMPCFG=$(mktemp) | ||||||
| 	printf "%s" "$configoptions" > "$TMPCFG" | 	printf "%s" "$configoptions" > "$TMPCFG" | ||||||
| 	$MAKE -j "$cpus" DOTCONFIG="$TMPCFG" obj="$TARGET/temp" objutil="$TARGET/sharedutils" allnoconfig | 	$MAKE -j "$cpus" DOTCONFIG="$TMPCFG" obj="$TARGET/temp" objutil="$TARGET/sharedutils" olddefconfig 2>/dev/null | ||||||
| 	printf "%s" "$configoptions" >> "$TMPCFG" |  | ||||||
| 	yes "" 2>/dev/null | $MAKE -j "$cpus" DOTCONFIG="$TMPCFG" obj="$TARGET/temp" objutil="$TARGET/sharedutils" oldconfig |  | ||||||
| 	BUILDPREFIX= | 	BUILDPREFIX= | ||||||
| 	if [ "$scanbuild" = "true" ]; then | 	if [ "$scanbuild" = "true" ]; then | ||||||
| 		scanbuild_out=$TARGET/sharedutils-scanbuild | 		scanbuild_out=$TARGET/sharedutils-scanbuild | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								util/kconfig/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								util/kconfig/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  | /conf | ||||||
|  | /[gmnq]conf | ||||||
|  | /[gmnq]conf-cfg | ||||||
|  | /qconf-moc.cc | ||||||
| @@ -1,377 +1,213 @@ | |||||||
|  | # 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 | ||||||
|  |  | ||||||
| export LC_ALL=C | ifdef KBUILD_KCONFIG | ||||||
| export LANG=C | Kconfig := $(KBUILD_KCONFIG) | ||||||
|  | else | ||||||
|  | Kconfig := Kconfig | ||||||
|  | endif | ||||||
|  |  | ||||||
| DEFCONFIG?=defconfig | ifndef KBUILD_DEFCONFIG | ||||||
|  | KBUILD_DEFCONFIG := defconfig | ||||||
|  | endif | ||||||
|  |  | ||||||
| PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ | ifeq ($(quiet),silent_) | ||||||
| 	localmodconfig localyesconfig | silent := -s | ||||||
|  | endif | ||||||
|  |  | ||||||
| xconfig: $(objk)/qconf | export KCONFIG_DEFCONFIG_LIST := | ||||||
| 	$< $(Kconfig) | ifndef cross_compiling | ||||||
|  | kernel-release := $(shell uname -r) | ||||||
|  | KCONFIG_DEFCONFIG_LIST += \ | ||||||
|  | 	/lib/modules/$(kernel-release)/.config \ | ||||||
|  | 	/etc/kernel-config \ | ||||||
|  | 	/boot/config-$(kernel-release) | ||||||
|  | endif | ||||||
|  | KCONFIG_DEFCONFIG_LIST += arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) | ||||||
|  |  | ||||||
| gconfig: $(objk)/gconf | # We need this, in case the user has it in its environment | ||||||
| 	cp -f $(srck)/gconf.glade $(objk)/gconf.glade | unexport CONFIG_ | ||||||
| 	$< $(Kconfig) |  | ||||||
|  |  | ||||||
| menuconfig: $(objk)/mconf | config-prog	:= conf | ||||||
| 	$< $(Kconfig) | menuconfig-prog	:= mconf | ||||||
|  | nconfig-prog	:= nconf | ||||||
|  | gconfig-prog	:= gconf | ||||||
|  | xconfig-prog	:= qconf | ||||||
|  |  | ||||||
| config: $(objk)/conf | define config_rule | ||||||
| 	$< --oldaskconfig $(Kconfig) | PHONY += $(1) | ||||||
|  | $(1): $(obj)/$($(1)-prog) | ||||||
|  | 	$(Q)$$< $(silent) $(Kconfig) | ||||||
|  |  | ||||||
| nconfig: $(objk)/nconf | PHONY += build_$(1) | ||||||
| 	$< $(Kconfig) | build_$(1): $(obj)/$($(1)-prog) | ||||||
|  | endef | ||||||
|  |  | ||||||
| # Disable strict mode because oldconfig is typically used to clean up | $(foreach c, config menuconfig nconfig gconfig xconfig, $(eval $(call config_rule,$(c)))) | ||||||
| # templates and the like. The second invocation should already have sane data. |  | ||||||
| oldconfig: $(objk)/conf |  | ||||||
| 	KCONFIG_STRICT= $< --$@ $(Kconfig) |  | ||||||
| 	$< --silentoldconfig $(Kconfig) |  | ||||||
|  |  | ||||||
| silentoldconfig: $(objk)/conf | PHONY += localmodconfig localyesconfig | ||||||
| 	$< --$@ $(Kconfig) | localyesconfig localmodconfig: $(obj)/conf | ||||||
|  | 	$(Q)$(PERL) $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config | ||||||
| # --- UNUSED, ignore ---------------------------------------------------------- | 	$(Q)if [ -f .config ]; then 				\ | ||||||
| localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf | 		cmp -s .tmp.config .config ||			\ | ||||||
| 	$(Q)mkdir -p include/generated | 		(mv -f .config .config.old.1;			\ | ||||||
| 	$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config | 		 mv -f .tmp.config .config;			\ | ||||||
| 	$(Q)if [ -f .config ]; then 					\ | 		 $< $(silent) --oldconfig $(Kconfig);		\ | ||||||
| 			cmp -s .tmp.config .config ||			\ | 		 mv -f .config.old.1 .config.old)		\ | ||||||
| 			(mv -f .config .config.old.1;			\ | 	else							\ | ||||||
| 			 mv -f .tmp.config .config;			\ | 		mv -f .tmp.config .config;			\ | ||||||
| 			 $(obj)/conf --silentoldconfig $(Kconfig);	\ | 		$< $(silent) --oldconfig $(Kconfig);		\ | ||||||
| 			 mv -f .config.old.1 .config.old)		\ |  | ||||||
| 	else								\ |  | ||||||
| 			mv -f .tmp.config .config;			\ |  | ||||||
| 			$(obj)/conf --silentoldconfig $(Kconfig);	\ |  | ||||||
| 	fi | 	fi | ||||||
| 	$(Q)rm -f .tmp.config | 	$(Q)rm -f .tmp.config | ||||||
|  |  | ||||||
| # Create new linux.pot file | # These targets map 1:1 to the commandline options of 'conf' | ||||||
| # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files | # | ||||||
| update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h | # Note: | ||||||
| 	$(Q)echo "  GEN     config.pot" | #  syncconfig has become an internal implementation detail and is now | ||||||
| 	$(Q)xgettext --default-domain=linux                         \ | #  deprecated for external use | ||||||
| 	    --add-comments --keyword=_ --keyword=N_                 \ | simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ | ||||||
| 	    --from-code=UTF-8                                       \ | 	alldefconfig randconfig listnewconfig olddefconfig syncconfig \ | ||||||
| 	    --files-from=$(srctree)/scripts/kconfig/POTFILES.in     \ | 	helpnewconfig yes2modconfig mod2yesconfig | ||||||
| 	    --directory=$(srctree) --directory=$(objtree)           \ |  | ||||||
| 	    --output $(obj)/config.pot |  | ||||||
| 	$(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot |  | ||||||
| 	$(Q)(for i in `ls $(srctree)/arch/*/Kconfig      \ |  | ||||||
| 	    $(srctree)/arch/*/um/Kconfig`;               \ |  | ||||||
| 	    do                                           \ |  | ||||||
| 		echo "  GEN     $$i";                    \ |  | ||||||
| 		$(obj)/kxgettext $$i                     \ |  | ||||||
| 		     >> $(obj)/config.pot;               \ |  | ||||||
| 	    done ) |  | ||||||
| 	$(Q)echo "  GEN     linux.pot" |  | ||||||
| 	$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ |  | ||||||
| 	    --output $(obj)/linux.pot |  | ||||||
| 	$(Q)rm -f $(obj)/config.pot |  | ||||||
| # --- UNUSED, ignore ---------------------------------------------------------- |  | ||||||
|  |  | ||||||
| PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig savedefconfig | PHONY += $(simple-targets) | ||||||
|  |  | ||||||
| allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(objk)/conf | $(simple-targets): $(obj)/conf | ||||||
| 	$< --$@ $(Kconfig) | 	$(Q)$< $(silent) --$@ $(Kconfig) | ||||||
|  |  | ||||||
| savedefconfig: $(objk)/conf | PHONY += savedefconfig defconfig | ||||||
| 	$< --$@=$(DEFCONFIG) $(Kconfig) |  | ||||||
|  |  | ||||||
| defconfig: $(objk)/conf | savedefconfig: $(obj)/conf | ||||||
| ifeq ($(KBUILD_DEFCONFIG),) | 	$(Q)$< $(silent) --$@=defconfig $(Kconfig) | ||||||
| 	$< --defconfig $(Kconfig) |  | ||||||
|  | defconfig: $(obj)/conf | ||||||
|  | ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) | ||||||
|  | 	@$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" | ||||||
|  | 	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) | ||||||
| else | else | ||||||
| 	@echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" | 	@$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" | ||||||
| 	$< --defconfig=$(KBUILD_DEFCONFIG) $(Kconfig) | 	$(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) | ||||||
| endif | endif | ||||||
|  |  | ||||||
| olddefconfig: $(objk)/conf | %_defconfig: $(obj)/conf | ||||||
| 	$< --olddefconfig $(Kconfig) | 	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) | ||||||
|  |  | ||||||
| %_defconfig: $(objk)/conf | configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@) | ||||||
| 	$< --defconfig=configs/$@ $(Kconfig) |  | ||||||
|  | %.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)$(MAKE) -f $(srctree)/Makefile olddefconfig | ||||||
|  |  | ||||||
|  | PHONY += tinyconfig | ||||||
|  | tinyconfig: | ||||||
|  | 	$(Q)KCONFIG_ALLCONFIG=kernel/configs/tiny-base.config $(MAKE) -f $(srctree)/Makefile allnoconfig | ||||||
|  | 	$(Q)$(MAKE) -f $(srctree)/Makefile tiny.config | ||||||
|  |  | ||||||
|  | # CHECK: -o cache_dir=<path> working? | ||||||
|  | PHONY += testconfig | ||||||
|  | testconfig: $(obj)/conf | ||||||
|  | 	$(Q)$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ | ||||||
|  | 	-o cache_dir=$(abspath $(obj)/tests/.cache) \ | ||||||
|  | 	$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) | ||||||
|  | clean-files += tests/.cache | ||||||
|  |  | ||||||
| # Help text used by make help | # Help text used by make help | ||||||
| help_kconfig help:: | help: | ||||||
| 	@echo  '*** Kconfig Targets ***' |  | ||||||
| 	@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 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  '  olddefconfig    - Same as oldconfig, but with default answer to all new options' | 	@echo  '  localmodconfig  - Update current config disabling modules not loaded' | ||||||
| 	#@echo  '  localmodconfig  - Update current config disabling modules not loaded' | 	@echo  '                    except those preserved by LMC_KEEP environment variable' | ||||||
| 	#@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  '                    except those preserved by LMC_KEEP environment variable' | ||||||
| 	@echo  '  defconfig	  - New config with default answer to all options' | 	@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' | ||||||
| 	#@echo  '  allyesconfig	  - New config where all options are accepted with yes' | 	@echo  '  allyesconfig	  - New config where all options are accepted with yes' | ||||||
| 	#@echo  '  allmodconfig	  - New config selecting modules when possible' | 	@echo  '  allmodconfig	  - New config selecting modules when possible' | ||||||
| 	#@echo  '  randconfig	  - New config with random answer to all options' | 	@echo  '  alldefconfig    - New config with all symbols set to default' | ||||||
| 	@echo | 	@echo  '  randconfig	  - New config with random answer to all options' | ||||||
|  | 	@echo  '  yes2modconfig	  - Change answers from yes to mod if possible' | ||||||
| # lxdialog stuff | 	@echo  '  mod2yesconfig	  - Change answers from mod to yes if possible' | ||||||
| check-lxdialog  := $(srck)/lxdialog/check-lxdialog.sh | 	@echo  '  listnewconfig   - List new options' | ||||||
|  | 	@echo  '  helpnewconfig   - List new options and help text' | ||||||
| # Use recursively expanded variables so we do not call gcc unless | 	@echo  '  olddefconfig	  - Same as oldconfig but sets new symbols to their' | ||||||
| # we really need to do so. (Do not call gcc as part of make mrproper) | 	@echo  '                    default value without prompting' | ||||||
| HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ | 	@echo  '  tinyconfig	  - Configure the tiniest possible kernel' | ||||||
|                     -DLOCALE | 	@echo  '  testconfig	  - Run Kconfig unit tests (requires python3 and pytest)' | ||||||
| HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) \ |  | ||||||
|                     -ldflags $(HOSTCC)) -ltinfo |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # =========================================================================== | # =========================================================================== | ||||||
| # Shared Makefile for the various kconfig executables: |  | ||||||
| # conf:	  Used for defconfig, oldconfig and related targets |  | ||||||
| # nconf:  Used for the nconfig target. |  | ||||||
| #         Utilizes ncurses |  | ||||||
| # mconf:  Used for the menuconfig target |  | ||||||
| #         Utilizes the lxdialog package |  | ||||||
| # qconf:  Used for the xconfig target |  | ||||||
| #         Based on QT which needs to be installed to compile it |  | ||||||
| # gconf:  Used for the gconfig target |  | ||||||
| #         Based on GTK which needs to be installed to compile it |  | ||||||
| # object files used by all kconfig flavours | # object files used by all kconfig flavours | ||||||
|  | common-objs	:= confdata.o expr.o lexer.lex.o menu.o parser.tab.o \ | ||||||
|  | 		   preprocess.o symbol.o util.o | ||||||
|  |  | ||||||
| lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o | $(obj)/lexer.lex.o: $(obj)/parser.tab.h | ||||||
| lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o | HOSTCFLAGS_lexer.lex.o	:= -I $(srctree)/$(src) | ||||||
|  | HOSTCFLAGS_parser.tab.o	:= -I $(srctree)/$(src) | ||||||
|  |  | ||||||
| conf-objs	:= conf.o  zconf.tab.o $(regex-objs) | # conf: Used for defconfig, oldconfig and related targets | ||||||
| mconf-objs     := mconf.o zconf.tab.o $(lxdialog) $(regex-objs) | hostprogs	+= conf | ||||||
| nconf-objs     := nconf.o zconf.tab.o nconf.gui.o | conf-objs	:= conf.o $(common-objs) | ||||||
| kxgettext-objs	:= kxgettext.o zconf.tab.o |  | ||||||
| qconf-cxxobjs	:= qconf.o |  | ||||||
| qconf-objs	:= zconf.tab.o |  | ||||||
| gconf-objs	:= gconf.o zconf.tab.o |  | ||||||
|  |  | ||||||
| hostprogs-y := conf | # nconf: Used for the nconfig target based on ncurses | ||||||
|  | hostprogs	+= nconf | ||||||
|  | nconf-objs	:= nconf.o nconf.gui.o $(common-objs) | ||||||
|  |  | ||||||
| ifeq ($(MAKECMDGOALS),nconfig) | HOSTLDLIBS_nconf	= $(shell . $(obj)/nconf-cfg && echo $$libs) | ||||||
| 	hostprogs-y += nconf | HOSTCFLAGS_nconf.o	= $(shell . $(obj)/nconf-cfg && echo $$cflags) | ||||||
| endif | HOSTCFLAGS_nconf.gui.o	= $(shell . $(obj)/nconf-cfg && echo $$cflags) | ||||||
|  |  | ||||||
| ifeq ($(MAKECMDGOALS),menuconfig) | $(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/nconf-cfg | ||||||
| 	hostprogs-y += mconf |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| ifeq ($(MAKECMDGOALS),update-po-config) | # mconf: Used for the menuconfig target based on lxdialog | ||||||
| 	hostprogs-y += kxgettext | hostprogs	+= mconf | ||||||
| endif | lxdialog	:= $(addprefix lxdialog/, \ | ||||||
|  | 		     checklist.o inputbox.o menubox.o textbox.o util.o yesno.o) | ||||||
|  | mconf-objs	:= mconf.o $(lxdialog) $(common-objs) | ||||||
|  |  | ||||||
| ifeq ($(MAKECMDGOALS),xconfig) | HOSTLDLIBS_mconf = $(shell . $(obj)/mconf-cfg && echo $$libs) | ||||||
| 	qconf-target := 1 | $(foreach f, mconf.o $(lxdialog), \ | ||||||
| endif |   $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/mconf-cfg && echo $$$$cflags))) | ||||||
| ifeq ($(MAKECMDGOALS),gconfig) |  | ||||||
| 	gconf-target := 1 |  | ||||||
| endif |  | ||||||
|  |  | ||||||
|  | $(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg | ||||||
|  |  | ||||||
| ifeq ($(qconf-target),1) | # qconf: Used for the xconfig target based on Qt | ||||||
| 	hostprogs-y += qconf | hostprogs	+= qconf | ||||||
| endif | qconf-cxxobjs	:= qconf.o qconf-moc.o | ||||||
|  | qconf-objs	:= images.o $(common-objs) | ||||||
|  |  | ||||||
| ifeq ($(gconf-target),1) | HOSTLDLIBS_qconf	= $(shell . $(obj)/qconf-cfg && echo $$libs) | ||||||
| 	hostprogs-y += gconf | HOSTCXXFLAGS_qconf.o	= $(shell . $(obj)/qconf-cfg && echo $$cflags) | ||||||
| endif | HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags) | ||||||
|  |  | ||||||
| clean-files	:= qconf.moc .tmp_qtcheck .tmp_gtkcheck | $(obj)/qconf.o: $(obj)/qconf-cfg | ||||||
| clean-files	+= zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h |  | ||||||
| clean-files     += mconf qconf gconf nconf |  | ||||||
| clean-files     += config.pot linux.pot |  | ||||||
|  |  | ||||||
| # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) | quiet_cmd_moc = MOC     $@ | ||||||
| PHONY += $(objk)/dochecklxdialog |       cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@ | ||||||
| $(addprefix $(obj)/,$(lxdialog)): $(objk)/dochecklxdialog |  | ||||||
| $(objk)/dochecklxdialog: |  | ||||||
| 	$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) |  | ||||||
|  |  | ||||||
| always := dochecklxdialog | $(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE | ||||||
|  | 	$(call if_changed,moc) | ||||||
|  |  | ||||||
| # Add environment specific flags | targets += qconf-moc.cc | ||||||
| HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srck)/check.sh $(HOSTCC) $(HOSTCFLAGS)) |  | ||||||
|  |  | ||||||
| # generated files seem to need this to find local include files | # gconf: Used for the gconfig target based on GTK+ | ||||||
| HOSTCFLAGS_zconf.lex.o	:= -I$(src) | hostprogs	+= gconf | ||||||
| HOSTCFLAGS_zconf.tab.o	:= -I$(src) | gconf-objs	:= gconf.o images.o $(common-objs) | ||||||
|  |  | ||||||
| LEX_PREFIX_zconf	:= zconf | HOSTLDLIBS_gconf    = $(shell . $(obj)/gconf-cfg && echo $$libs) | ||||||
| YACC_PREFIX_zconf	:= zconf | HOSTCFLAGS_gconf.o  = $(shell . $(obj)/gconf-cfg && echo $$cflags) | ||||||
|  |  | ||||||
| HOSTLOADLIBES_qconf	= $(KC_QT_LIBS) -ldl | $(obj)/gconf.o: $(obj)/gconf-cfg | ||||||
| HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS) |  | ||||||
|  |  | ||||||
| HOSTLOADLIBES_gconf	= `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` | # check if necessary packages are available, and configure build flags | ||||||
| HOSTCFLAGS_gconf.o	= `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ | filechk_conf_cfg = $(CONFIG_SHELL) $< | ||||||
|                           -Wno-missing-prototypes |  | ||||||
|  |  | ||||||
| HOSTLOADLIBES_mconf   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) | $(obj)/%conf-cfg: $(src)/%conf-cfg.sh FORCE | ||||||
|  | 	$(call filechk,conf_cfg) | ||||||
|  |  | ||||||
| HOSTLOADLIBES_nconf	= $(shell \ | clean-files += *conf-cfg | ||||||
| 				pkg-config --libs menu panel ncurses 2>/dev/null \ |  | ||||||
| 				|| echo "-lmenu -lpanel -lncurses"  ) |  | ||||||
|  |  | ||||||
| $(objk)/qconf.o: $(objk)/.tmp_qtcheck |  | ||||||
|  |  | ||||||
| ifeq ($(qconf-target),1) |  | ||||||
| $(objk)/.tmp_qtcheck: $(srck)/Makefile |  | ||||||
| -include $(objk)/.tmp_qtcheck |  | ||||||
|  |  | ||||||
| # QT needs some extra effort... |  | ||||||
| $(objk)/.tmp_qtcheck: |  | ||||||
| 	@set -e; echo "  CHECK   qt"; dir=""; pkg=""; \ |  | ||||||
| 	if pkg-config --exists Qt5Core; then \ |  | ||||||
| 	  cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \ |  | ||||||
| 	  libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \ |  | ||||||
| 	  moc=`pkg-config --variable=host_bins Qt5Core`/moc; \ |  | ||||||
| 	elif pkg-config --exists QtCore; then \ |  | ||||||
| 	  cflags=`pkg-config --cflags QtCore QtGui`; \ |  | ||||||
| 	  libs=`pkg-config --libs QtCore QtGui`; \ |  | ||||||
| 	  moc=`pkg-config --variable=moc_location QtCore`; \ |  | ||||||
| 	else \ |  | ||||||
| 	  echo >&2 "*"; \ |  | ||||||
| 	  echo >&2 "* Could not find Qt via pkg-config."; \ |  | ||||||
| 	  echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \ |  | ||||||
| 	  echo >&2 "*"; \ |  | ||||||
| 	  exit 1; \ |  | ||||||
| 	fi; \ |  | ||||||
| 	echo "KC_QT_CFLAGS=$$cflags" > $@; \ |  | ||||||
| 	echo "KC_QT_LIBS=$$libs" >> $@; \ |  | ||||||
| 	echo "KC_QT_MOC=$$moc" >> $@ |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| $(objk)/gconf.o: $(objk)/.tmp_gtkcheck |  | ||||||
|  |  | ||||||
| ifeq ($(gconf-target),1) |  | ||||||
| -include $(objk)/.tmp_gtkcheck |  | ||||||
|  |  | ||||||
| # GTK needs some extra effort, too... |  | ||||||
| $(objk)/.tmp_gtkcheck: |  | ||||||
| 	@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then		\ |  | ||||||
| 		if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then			\ |  | ||||||
| 			touch $@;								\ |  | ||||||
| 		else									\ |  | ||||||
| 			echo >&2 "*"; 							\ |  | ||||||
| 			echo >&2 "* GTK+ is present but version >= 2.0.0 is required.";	\ |  | ||||||
| 			echo >&2 "*";							\ |  | ||||||
| 			false;								\ |  | ||||||
| 		fi									\ |  | ||||||
| 	else										\ |  | ||||||
| 		echo >&2 "*"; 								\ |  | ||||||
| 		echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; 	\ |  | ||||||
| 		echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; 	\ |  | ||||||
| 		echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; 		\ |  | ||||||
| 		echo >&2 "*"; 								\ |  | ||||||
| 		false;									\ |  | ||||||
| 	fi |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| # --- UNUSED, ignore ---------------------------------------------------------- |  | ||||||
| ifdef UNUSED |  | ||||||
| $(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c |  | ||||||
|  |  | ||||||
| $(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h |  | ||||||
|  |  | ||||||
| $(obj)/gconf.o: $(obj)/lkc_defs.h |  | ||||||
|  |  | ||||||
| $(obj)/%.moc: $(srck)/%.h |  | ||||||
| 	$(KC_QT_MOC) -i $< -o $@ |  | ||||||
|  |  | ||||||
| $(obj)/lkc_defs.h: $(src)/lkc_proto.h |  | ||||||
| 	sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' |  | ||||||
|  |  | ||||||
| # Extract gconf menu items for I18N support |  | ||||||
| $(obj)/gconf.glade.h: $(obj)/gconf.glade |  | ||||||
| 	intltool-extract --type=gettext/glade $(obj)/gconf.glade |  | ||||||
| endif |  | ||||||
| # --- UNUSED, ignore ---------------------------------------------------------- |  | ||||||
|  |  | ||||||
| ### |  | ||||||
| # The following requires flex/bison/gperf |  | ||||||
| # By default we use the _shipped versions, uncomment the following line if |  | ||||||
| # you are modifying the flex/bison src. |  | ||||||
| # LKC_GENPARSER := 1 |  | ||||||
|  |  | ||||||
| ifdef LKC_GENPARSER |  | ||||||
|  |  | ||||||
| # --- UNUSED, ignore ---------------------------------------------------------- |  | ||||||
| $(obj)/zconf.tab.c: $(src)/zconf.y |  | ||||||
| $(obj)/zconf.lex.c: $(src)/zconf.l |  | ||||||
| $(obj)/zconf.hash.c: $(src)/zconf.gperf |  | ||||||
|  |  | ||||||
| %.tab.c: %.y |  | ||||||
| 	bison -t -l -b $* -p $(notdir $*) $< |  | ||||||
|  |  | ||||||
| %.tab.c_shipped: %.tab.c |  | ||||||
| 	cp $< $@ |  | ||||||
|  |  | ||||||
| %.lex.c: %.l |  | ||||||
| 	flex -L -P$(notdir $*) -o$@ $< |  | ||||||
|  |  | ||||||
| %.lex.c_shipped: %.lex.c |  | ||||||
| 	cp $< $@ |  | ||||||
|  |  | ||||||
| %.hash.c: %.gperf |  | ||||||
| 	gperf < $< > $@ |  | ||||||
| 	cp $@ $@_shipped |  | ||||||
| # --- UNUSED, ignore ---------------------------------------------------------- |  | ||||||
|  |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| $(objk)/qconf: $(patsubst %,$(objk)/%,$(qconf-cxxobjs)) \ |  | ||||||
| 	       $(patsubst %,$(objk)/%,$(qconf-objs)) |  | ||||||
| 	$(HOSTCXX) $(HOSTCXXFLAGS) -o $@ $^ $(HOSTLOADLIBES_qconf) |  | ||||||
| $(objk)/gconf: $(patsubst %,$(objk)/%,$(gconf-objs)) |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $^ $(HOSTLOADLIBES_gconf) |  | ||||||
| $(objk)/mconf: $(patsubst %,$(objk)/%,$(mconf-objs)) |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $^ -o $@ $(HOST_LOADLIBES) |  | ||||||
| $(objk)/nconf: $(patsubst %,$(objk)/%,$(nconf-objs)) |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $^ $(HOSTLOADLIBES_nconf) |  | ||||||
| $(objk)/conf: $(patsubst %,$(objk)/%,$(conf-objs)) |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -o $@ $^ |  | ||||||
|  |  | ||||||
| $(objk)/mconf.o: $(srck)/mconf.c |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $< |  | ||||||
| $(objk)/nconf.o: $(srck)/nconf.c |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $< |  | ||||||
| $(objk)/nconf.gui.o: $(srck)/nconf.gui.c |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $< |  | ||||||
| $(objk)/conf.o: $(srck)/conf.c |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $< |  | ||||||
|  |  | ||||||
| $(objk)/zconf.tab.o: $(objk)/zconf.tab.c $(objk)/zconf.lex.c \ |  | ||||||
| 		     $(objk)/zconf.hash.c |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $(objk)/zconf.tab.c |  | ||||||
| $(objk)/qconf.o: $(srck)/qconf.cc $(objk)/qconf.moc $(objk)/lkc_defs.h |  | ||||||
| 	$(HOSTCXX) $(HOSTCXXFLAGS) $(HOSTCXXFLAGS_qconf.o) -c -o $@ $< |  | ||||||
| $(objk)/gconf.o: $(srck)/gconf.c $(objk)/lkc_defs.h |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTCFLAGS_gconf.o) -c -o $@ $< |  | ||||||
| $(objk)/%.moc: $(srck)/%.h |  | ||||||
| 	$(KC_QT_MOC) -i $< -o $@ |  | ||||||
| $(objk)/lkc_defs.h: $(srck)/lkc_proto.h |  | ||||||
| 	sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' |  | ||||||
|  |  | ||||||
| $(objk)/zconf.lex.c: $(srck)/zconf.lex.c_shipped |  | ||||||
| 	cp $< $@ |  | ||||||
| $(objk)/zconf.hash.c: $(srck)/zconf.hash.c_shipped |  | ||||||
| 	cp $< $@ |  | ||||||
| $(objk)/zconf.tab.c: $(srck)/zconf.tab.c_shipped |  | ||||||
| 	cp $< $@ |  | ||||||
|  |  | ||||||
| $(objk)/lxdialog/lxdialog: $(objk)/dochecklxdialog \ |  | ||||||
| 			   $(patsubst %,$(objk)/lxdialog/%,$(lxdialog)) |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ |  | ||||||
| 		$(patsubst %,$(objk)/lxdialog/%,$(lxdialog)) $(HOST_LOADLIBES) -o $@ |  | ||||||
| $(objk)/lxdialog/%.o: $(srck)/lxdialog/%.c |  | ||||||
| 	$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $^ -c -o $@ |  | ||||||
|  |  | ||||||
| $(objk)/%.o: HOSTCFLAGS+=-I$(srck) -I$(objk) |  | ||||||
| $(objk)/%.o: HOSTCXXFLAGS+=-I$(srck) -I$(objk) |  | ||||||
|   | |||||||
| @@ -1,12 +1,69 @@ | |||||||
| # SPDX-License-Identifier: GPL-2.0-or-later | # SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
| # Early configuration of coreboot specific changes | # Early coreboot specific configuration | ||||||
| Kconfig ?= src/Kconfig | KBUILD_KCONFIG ?= src/Kconfig | ||||||
|  |  | ||||||
| # Include verbatim Makefile | export LC_ALL=C | ||||||
| include $(dir $(lastword $(MAKEFILE_LIST)))Makefile | export LANG=C | ||||||
|  |  | ||||||
| # Extend Linux kconfig build rules | # Include original Makefile, with just enough edits to work for us | ||||||
|  | $(objk)/Makefile.real: $(dir $(lastword $(MAKEFILE_LIST)))Makefile | ||||||
|  | 	mkdir -p $(objk) | ||||||
|  | 	sed \ | ||||||
|  | 		-e "s,\$$(obj),\$$(objk),g" \ | ||||||
|  | 		-e "s,\$$(src),\$$(srck),g" \ | ||||||
|  | 		-e "s,^help:,help_kconfig help::," \ | ||||||
|  | 		-e "s,^%.config:,__disable__&," \ | ||||||
|  | 		-e "s,^savedefconfig:,__disable__&," \ | ||||||
|  | 		-e "s,\$$(srctree)/arch/\$$(SRCARCH)/configs/\$$(KBUILD_DEFCONFIG),\$$(KBUILD_DEFCONFIG)," \ | ||||||
|  | 		-e "s,--defconfig=arch/\$$(SRCARCH)/configs/\$$(KBUILD_DEFCONFIG),--defconfig=\$$(KBUILD_DEFCONFIG)," \ | ||||||
|  | 		-e "/^unexport CONFIG_$$/d" \ | ||||||
|  | 		$< > $@.tmp | ||||||
|  | 	mv $@.tmp $@ | ||||||
|  |  | ||||||
|  | kecho := echo | ||||||
|  |  | ||||||
|  | -include $(objk)/Makefile.real | ||||||
|  |  | ||||||
|  | # Fill in Linux kconfig build rules to work | ||||||
|  |  | ||||||
|  | oldconfig: KCONFIG_STRICT= | ||||||
|  |  | ||||||
|  | savedefconfig: $(objk)/conf | ||||||
|  | 	cp $(DOTCONFIG) $(DEFCONFIG) | ||||||
|  | 	$< --savedefconfig=$(DEFCONFIG) $(KBUILD_KCONFIG) | ||||||
|  |  | ||||||
|  | FORCE: | ||||||
|  |  | ||||||
|  | filechk=$< > $@ | ||||||
|  |  | ||||||
|  | $(objk)/%.o: $(srck)/%.c | ||||||
|  | 	$(HOSTCC) -I $(srck) -I $(objk) -c $(HOSTCFLAGS_$(notdir $@)) -o $@ $< | ||||||
|  |  | ||||||
|  | $(objk)/%.o: $(srck)/%.cc | ||||||
|  | 	$(HOSTCXX) -I $(srck) -I $(objk) -c $(HOSTCXXFLAGS_$(notdir $@)) -o $@ $< | ||||||
|  |  | ||||||
|  | $(objk)/%.o: $(objk)/%.c | ||||||
|  | 	$(HOSTCC) -I $(srck) -I $(objk) -c -o $@ $< | ||||||
|  |  | ||||||
|  | $(objk)/%.moc: $(srck)/%.h | $(objk)/qconf-cfg | ||||||
|  | 	$(call cmd_moc) | ||||||
|  |  | ||||||
|  | define hostprogs_template | ||||||
|  | # $1 entry in hostprogs | ||||||
|  | $(objk)/$(1): $$(foreach _o,$$($(1)-objs) $$($(1)-cxxobjs),$(objk)/$$(_o)) | $(wildcard $(objk)/$(1)-cfg) | ||||||
|  | 	$$(HOSTCXX) -o $$@ $$^ $$(HOSTLDLIBS_$(1)) | ||||||
|  | endef | ||||||
|  |  | ||||||
|  | $(foreach prog,$(hostprogs),$(eval $(call hostprogs_template,$(prog)))) | ||||||
|  |  | ||||||
|  | $(objk)/parser.tab.h: | $(objk)/parser.tab.c | ||||||
|  | $(objk)/%.tab.h: | $(objk)/%.tab.c | ||||||
|  | $(objk)/%.tab.c: $(srck)/%.y | ||||||
|  | 	bison -t -l --defines=$(objk)/$*.tab.h -b $(objk)/$* $< | ||||||
|  |  | ||||||
|  | $(objk)/%.lex.c: $(srck)/%.l | ||||||
|  | 	flex -L -o$@ $< | ||||||
|  |  | ||||||
| # Support mingw by shipping our own regex implementation | # Support mingw by shipping our own regex implementation | ||||||
| _OS=$(shell uname -s |cut -c-7) | _OS=$(shell uname -s |cut -c-7) | ||||||
|   | |||||||
| @@ -1,12 +0,0 @@ | |||||||
| scripts/kconfig/lxdialog/checklist.c |  | ||||||
| scripts/kconfig/lxdialog/inputbox.c |  | ||||||
| scripts/kconfig/lxdialog/menubox.c |  | ||||||
| scripts/kconfig/lxdialog/textbox.c |  | ||||||
| scripts/kconfig/lxdialog/util.c |  | ||||||
| scripts/kconfig/lxdialog/yesno.c |  | ||||||
| scripts/kconfig/mconf.c |  | ||||||
| scripts/kconfig/conf.c |  | ||||||
| scripts/kconfig/confdata.c |  | ||||||
| scripts/kconfig/gconf.c |  | ||||||
| scripts/kconfig/gconf.glade.h |  | ||||||
| scripts/kconfig/qconf.cc |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| #!/usr/bin/env sh |  | ||||||
| # Needed for systems without gettext |  | ||||||
| $* -x c -o /dev/null - > /dev/null 2>&1 << EOF |  | ||||||
| #include <libintl.h> |  | ||||||
| int main() |  | ||||||
| { |  | ||||||
| 	gettext(""); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| EOF |  | ||||||
| if [ ! "$?" -eq "0"  ]; then |  | ||||||
| 	echo -DKBUILD_NO_NLS; |  | ||||||
| fi |  | ||||||
| @@ -1,17 +1,16 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #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> | ||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <getopt.h> | #include <getopt.h> | ||||||
| #include <sys/stat.h> |  | ||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
|  |  | ||||||
| @@ -21,11 +20,10 @@ int kconfig_warnings = 0; | |||||||
|  |  | ||||||
| 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, | ||||||
| @@ -35,15 +33,18 @@ enum input_mode { | |||||||
| 	defconfig, | 	defconfig, | ||||||
| 	savedefconfig, | 	savedefconfig, | ||||||
| 	listnewconfig, | 	listnewconfig, | ||||||
|  | 	helpnewconfig, | ||||||
| 	olddefconfig, | 	olddefconfig, | ||||||
| } input_mode = oldaskconfig; | 	yes2modconfig, | ||||||
|  | 	mod2yesconfig, | ||||||
|  | }; | ||||||
|  | static enum input_mode input_mode = oldaskconfig; | ||||||
|  | static int input_mode_opt; | ||||||
| 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) | ||||||
| @@ -73,27 +74,260 @@ 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 void set_randconfig_seed(void) | ||||||
|  | { | ||||||
|  | 	unsigned int seed; | ||||||
|  | 	char *env; | ||||||
|  | 	bool seed_set = false; | ||||||
|  |  | ||||||
|  | 	env = getenv("KCONFIG_SEED"); | ||||||
|  | 	if (env && *env) { | ||||||
|  | 		char *endp; | ||||||
|  |  | ||||||
|  | 		seed = strtol(env, &endp, 0); | ||||||
|  | 		if (*endp == '\0') | ||||||
|  | 			seed_set = true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (!seed_set) { | ||||||
|  | 		struct timeval now; | ||||||
|  |  | ||||||
|  | 		/* | ||||||
|  | 		 * Use microseconds derived seed, compensate for systems where it may | ||||||
|  | 		 * be zero. | ||||||
|  | 		 */ | ||||||
|  | 		gettimeofday(&now, NULL); | ||||||
|  | 		seed = (now.tv_sec + 1) * (now.tv_usec + 1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	printf("KCONFIG_SEED=0x%X\n", seed); | ||||||
|  | 	srand(seed); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static bool randomize_choice_values(struct symbol *csym) | ||||||
|  | { | ||||||
|  | 	struct property *prop; | ||||||
|  | 	struct symbol *sym; | ||||||
|  | 	struct expr *e; | ||||||
|  | 	int cnt, def; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * If choice is mod then we may have more items selected | ||||||
|  | 	 * and if no then no-one. | ||||||
|  | 	 * In both cases stop. | ||||||
|  | 	 */ | ||||||
|  | 	if (csym->curr.tri != yes) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	prop = sym_get_choice_prop(csym); | ||||||
|  |  | ||||||
|  | 	/* count entries in choice block */ | ||||||
|  | 	cnt = 0; | ||||||
|  | 	expr_list_for_each_sym(prop->expr, e, sym) | ||||||
|  | 		cnt++; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * find a random value and set it to yes, | ||||||
|  | 	 * set the rest to no so we have only one set | ||||||
|  | 	 */ | ||||||
|  | 	def = rand() % cnt; | ||||||
|  |  | ||||||
|  | 	cnt = 0; | ||||||
|  | 	expr_list_for_each_sym(prop->expr, e, sym) { | ||||||
|  | 		if (def == cnt++) { | ||||||
|  | 			sym->def[S_DEF_USER].tri = yes; | ||||||
|  | 			csym->def[S_DEF_USER].val = sym; | ||||||
|  | 		} else { | ||||||
|  | 			sym->def[S_DEF_USER].tri = no; | ||||||
|  | 		} | ||||||
|  | 		sym->flags |= SYMBOL_DEF_USER; | ||||||
|  | 		/* clear VALID to get value calculated */ | ||||||
|  | 		sym->flags &= ~SYMBOL_VALID; | ||||||
|  | 	} | ||||||
|  | 	csym->flags |= SYMBOL_DEF_USER; | ||||||
|  | 	/* clear VALID to get value calculated */ | ||||||
|  | 	csym->flags &= ~SYMBOL_VALID; | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum conf_def_mode { | ||||||
|  | 	def_default, | ||||||
|  | 	def_yes, | ||||||
|  | 	def_mod, | ||||||
|  | 	def_y2m, | ||||||
|  | 	def_m2y, | ||||||
|  | 	def_no, | ||||||
|  | 	def_random | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static bool conf_set_all_new_symbols(enum conf_def_mode mode) | ||||||
|  | { | ||||||
|  | 	struct symbol *sym, *csym; | ||||||
|  | 	int i, cnt; | ||||||
|  | 	/* | ||||||
|  | 	 * can't go as the default in switch-case below, otherwise gcc whines | ||||||
|  | 	 * about -Wmaybe-uninitialized | ||||||
|  | 	 */ | ||||||
|  | 	int pby = 50; /* probability of bool     = y */ | ||||||
|  | 	int pty = 33; /* probability of tristate = y */ | ||||||
|  | 	int ptm = 33; /* probability of tristate = m */ | ||||||
|  | 	bool has_changed = false; | ||||||
|  |  | ||||||
|  | 	if (mode == def_random) { | ||||||
|  | 		int n, p[3]; | ||||||
|  | 		char *env = getenv("KCONFIG_PROBABILITY"); | ||||||
|  |  | ||||||
|  | 		n = 0; | ||||||
|  | 		while (env && *env) { | ||||||
|  | 			char *endp; | ||||||
|  | 			int tmp = strtol(env, &endp, 10); | ||||||
|  |  | ||||||
|  | 			if (tmp >= 0 && tmp <= 100) { | ||||||
|  | 				p[n++] = tmp; | ||||||
|  | 			} else { | ||||||
|  | 				errno = ERANGE; | ||||||
|  | 				perror("KCONFIG_PROBABILITY"); | ||||||
|  | 				exit(1); | ||||||
|  | 			} | ||||||
|  | 			env = (*endp == ':') ? endp + 1 : endp; | ||||||
|  | 			if (n >= 3) | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 		switch (n) { | ||||||
|  | 		case 1: | ||||||
|  | 			pby = p[0]; | ||||||
|  | 			ptm = pby / 2; | ||||||
|  | 			pty = pby - ptm; | ||||||
|  | 			break; | ||||||
|  | 		case 2: | ||||||
|  | 			pty = p[0]; | ||||||
|  | 			ptm = p[1]; | ||||||
|  | 			pby = pty + ptm; | ||||||
|  | 			break; | ||||||
|  | 		case 3: | ||||||
|  | 			pby = p[0]; | ||||||
|  | 			pty = p[1]; | ||||||
|  | 			ptm = p[2]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (pty + ptm > 100) { | ||||||
|  | 			errno = ERANGE; | ||||||
|  | 			perror("KCONFIG_PROBABILITY"); | ||||||
|  | 			exit(1); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for_all_symbols(i, sym) { | ||||||
|  | 		if (sym_has_value(sym) || sym->flags & SYMBOL_VALID) | ||||||
|  | 			continue; | ||||||
|  | 		switch (sym_get_type(sym)) { | ||||||
|  | 		case S_BOOLEAN: | ||||||
|  | 		case S_TRISTATE: | ||||||
|  | 			has_changed = true; | ||||||
|  | 			switch (mode) { | ||||||
|  | 			case def_yes: | ||||||
|  | 				sym->def[S_DEF_USER].tri = yes; | ||||||
|  | 				break; | ||||||
|  | 			case def_mod: | ||||||
|  | 				sym->def[S_DEF_USER].tri = mod; | ||||||
|  | 				break; | ||||||
|  | 			case def_no: | ||||||
|  | 				sym->def[S_DEF_USER].tri = no; | ||||||
|  | 				break; | ||||||
|  | 			case def_random: | ||||||
|  | 				sym->def[S_DEF_USER].tri = no; | ||||||
|  | 				cnt = rand() % 100; | ||||||
|  | 				if (sym->type == S_TRISTATE) { | ||||||
|  | 					if (cnt < pty) | ||||||
|  | 						sym->def[S_DEF_USER].tri = yes; | ||||||
|  | 					else if (cnt < pty + ptm) | ||||||
|  | 						sym->def[S_DEF_USER].tri = mod; | ||||||
|  | 				} else if (cnt < pby) | ||||||
|  | 					sym->def[S_DEF_USER].tri = yes; | ||||||
|  | 				break; | ||||||
|  | 			default: | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (!(sym_is_choice(sym) && mode == def_random)) | ||||||
|  | 				sym->flags |= SYMBOL_DEF_USER; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sym_clear_all_valid(); | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * We have different type of choice blocks. | ||||||
|  | 	 * If curr.tri equals to mod then we can select several | ||||||
|  | 	 * choice symbols in one block. | ||||||
|  | 	 * In this case we do nothing. | ||||||
|  | 	 * If curr.tri equals yes then only one symbol can be | ||||||
|  | 	 * selected in a choice block and we set it to yes, | ||||||
|  | 	 * and the rest to no. | ||||||
|  | 	 */ | ||||||
|  | 	if (mode != def_random) { | ||||||
|  | 		for_all_symbols(i, csym) { | ||||||
|  | 			if ((sym_is_choice(csym) && !sym_has_value(csym)) || | ||||||
|  | 			    sym_is_choice_value(csym)) | ||||||
|  | 				csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for_all_symbols(i, csym) { | ||||||
|  | 		if (sym_has_value(csym) || !sym_is_choice(csym)) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		sym_calc_value(csym); | ||||||
|  | 		if (mode == def_random) | ||||||
|  | 			has_changed |= randomize_choice_values(csym); | ||||||
|  | 		else { | ||||||
|  | 			set_all_choice_values(csym); | ||||||
|  | 			has_changed = true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return has_changed; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void conf_rewrite_mod_or_yes(enum conf_def_mode mode) | ||||||
|  | { | ||||||
|  | 	struct symbol *sym; | ||||||
|  | 	int i; | ||||||
|  | 	tristate old_val = (mode == def_y2m) ? yes : mod; | ||||||
|  | 	tristate new_val = (mode == def_y2m) ? mod : yes; | ||||||
|  |  | ||||||
|  | 	for_all_symbols(i, sym) { | ||||||
|  | 		if (sym_get_type(sym) == S_TRISTATE && | ||||||
|  | 		    sym->def[S_DEF_USER].tri == old_val) | ||||||
|  | 			sym->def[S_DEF_USER].tri = new_val; | ||||||
|  | 	} | ||||||
|  | 	sym_clear_all_valid(); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int conf_askvalue(struct symbol *sym, const char *def) | static int conf_askvalue(struct symbol *sym, const char *def) | ||||||
| { | { | ||||||
| 	enum symbol_type type = sym_get_type(sym); |  | ||||||
|  |  | ||||||
| 	if (!sym_has_value(sym)) | 	if (!sym_has_value(sym)) | ||||||
| 		printf(_("(NEW) ")); | 		printf("(NEW) "); | ||||||
|  |  | ||||||
| 	line[0] = '\n'; | 	line[0] = '\n'; | ||||||
| 	line[1] = 0; | 	line[1] = 0; | ||||||
|  |  | ||||||
| 	if (!sym_is_changable(sym)) { | 	if (!sym_is_changeable(sym)) { | ||||||
| 		printf("%s\n", def); | 		printf("%s\n", def); | ||||||
| 		line[0] = '\n'; | 		line[0] = '\n'; | ||||||
| 		line[1] = 0; | 		line[1] = 0; | ||||||
| @@ -102,33 +336,18 @@ 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: |  | ||||||
| 		fflush(stdout); |  | ||||||
| 		xfgets(line, 128, stdin); |  | ||||||
| 		if (!tty_stdio) |  | ||||||
| 			printf("\n"); |  | ||||||
| 		return 1; |  | ||||||
| 	default: | 	default: | ||||||
|  | 		fflush(stdout); | ||||||
|  | 		xfgets(line, sizeof(line), stdin); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch (type) { |  | ||||||
| 	case S_INT: |  | ||||||
| 	case S_HEX: |  | ||||||
| 	case S_STRING: |  | ||||||
| 		printf("%s\n", def); |  | ||||||
| 		return 1; |  | ||||||
| 	default: |  | ||||||
| 		; |  | ||||||
| 	} |  | ||||||
| 	printf("%s", line); |  | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -138,10 +357,10 @@ static int conf_string(struct menu *menu) | |||||||
| 	const char *def; | 	const char *def; | ||||||
|  |  | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); | 		printf("%*s%s ", indent - 1, "", menu->prompt->text); | ||||||
| 		printf("(%s) ", sym->name); | 		printf("(%s) ", sym->name); | ||||||
| 		def = sym_get_string_value(sym); | 		def = sym_get_string_value(sym); | ||||||
| 		if (sym_get_string_value(sym)) | 		if (def) | ||||||
| 			printf("[%s] ", def); | 			printf("[%s] ", def); | ||||||
| 		if (!conf_askvalue(sym, def)) | 		if (!conf_askvalue(sym, def)) | ||||||
| 			return 0; | 			return 0; | ||||||
| @@ -171,7 +390,7 @@ static int conf_sym(struct menu *menu) | |||||||
| 	tristate oldval, newval; | 	tristate oldval, newval; | ||||||
|  |  | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); | 		printf("%*s%s ", indent - 1, "", menu->prompt->text); | ||||||
| 		if (sym->name) | 		if (sym->name) | ||||||
| 			printf("(%s) ", sym->name); | 			printf("(%s) ", sym->name); | ||||||
| 		putchar('['); | 		putchar('['); | ||||||
| @@ -193,9 +412,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); | ||||||
| @@ -242,7 +459,7 @@ static int conf_choice(struct menu *menu) | |||||||
|  |  | ||||||
| 	sym = menu->sym; | 	sym = menu->sym; | ||||||
| 	is_new = !sym_has_value(sym); | 	is_new = !sym_has_value(sym); | ||||||
| 	if (sym_is_changable(sym)) { | 	if (sym_is_changeable(sym)) { | ||||||
| 		conf_sym(menu); | 		conf_sym(menu); | ||||||
| 		sym_calc_value(sym); | 		sym_calc_value(sym); | ||||||
| 		switch (sym_get_tristate_value(sym)) { | 		switch (sym_get_tristate_value(sym)) { | ||||||
| @@ -258,7 +475,7 @@ static int conf_choice(struct menu *menu) | |||||||
| 		case no: | 		case no: | ||||||
| 			return 1; | 			return 1; | ||||||
| 		case mod: | 		case mod: | ||||||
| 			printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); | 			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); | ||||||
| 			return 0; | 			return 0; | ||||||
| 		case yes: | 		case yes: | ||||||
| 			break; | 			break; | ||||||
| @@ -268,7 +485,7 @@ static int conf_choice(struct menu *menu) | |||||||
| 	while (1) { | 	while (1) { | ||||||
| 		int cnt, def; | 		int cnt, def; | ||||||
|  |  | ||||||
| 		printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); | 		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); | ||||||
| 		def_sym = sym_get_choice_value(sym); | 		def_sym = sym_get_choice_value(sym); | ||||||
| 		cnt = def = 0; | 		cnt = def = 0; | ||||||
| 		line[0] = 0; | 		line[0] = 0; | ||||||
| @@ -276,7 +493,7 @@ static int conf_choice(struct menu *menu) | |||||||
| 			if (!menu_is_visible(child)) | 			if (!menu_is_visible(child)) | ||||||
| 				continue; | 				continue; | ||||||
| 			if (!child->sym) { | 			if (!child->sym) { | ||||||
| 				printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); | 				printf("%*c %s\n", indent, '*', menu_get_prompt(child)); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			cnt++; | 			cnt++; | ||||||
| @@ -285,35 +502,31 @@ static int conf_choice(struct menu *menu) | |||||||
| 				printf("%*c", indent, '>'); | 				printf("%*c", indent, '>'); | ||||||
| 			} else | 			} else | ||||||
| 				printf("%*c", indent, ' '); | 				printf("%*c", indent, ' '); | ||||||
| 			printf(" %d. %s", cnt, _(menu_get_prompt(child))); | 			printf(" %d. %s", cnt, menu_get_prompt(child)); | ||||||
| 			if (child->sym->name) | 			if (child->sym->name) | ||||||
| 				printf(" (%s)", child->sym->name); | 				printf(" (%s)", child->sym->name); | ||||||
| 			if (!sym_has_value(child->sym)) | 			if (!sym_has_value(child->sym)) | ||||||
| 				printf(_(" (NEW)")); | 				printf(" (NEW)"); | ||||||
| 			printf("\n"); | 			printf("\n"); | ||||||
| 		} | 		} | ||||||
| 		printf(_("%*schoice"), indent - 1, ""); | 		printf("%*schoice", indent - 1, ""); | ||||||
| 		if (cnt == 1) { | 		if (cnt == 1) { | ||||||
| 			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); | ||||||
| @@ -369,10 +582,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; | ||||||
| 			} | 			} | ||||||
| @@ -382,7 +596,7 @@ static void conf(struct menu *menu) | |||||||
| 			if (prompt) | 			if (prompt) | ||||||
| 				printf("%*c\n%*c %s\n%*c\n", | 				printf("%*c\n%*c %s\n%*c\n", | ||||||
| 					indent, '*', | 					indent, '*', | ||||||
| 					indent, '*', _(prompt), | 					indent, '*', prompt, | ||||||
| 					indent, '*'); | 					indent, '*'); | ||||||
| 		default: | 		default: | ||||||
| 			; | 			; | ||||||
| @@ -428,19 +642,37 @@ static void check_conf(struct menu *menu) | |||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	sym = menu->sym; | 	sym = menu->sym; | ||||||
| 	if (sym && !sym_has_value(sym)) { | 	if (sym && !sym_has_value(sym) && | ||||||
| 		if (sym_is_changable(sym) || | 	    (sym_is_changeable(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 (sym->name && !sym_is_choice_value(sym)) { | 		switch (input_mode) { | ||||||
| 					printf("%s%s\n", CONFIG_, sym->name); | 		case listnewconfig: | ||||||
|  | 			if (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) { |  | ||||||
| 				if (!conf_cnt++) |  | ||||||
| 					printf(_("*\n* Restart config...\n*\n")); |  | ||||||
| 				rootEntry = menu_get_parent_menu(menu); |  | ||||||
| 				conf(rootEntry); |  | ||||||
| 			} | 			} | ||||||
|  | 			break; | ||||||
|  | 		case helpnewconfig: | ||||||
|  | 			printf("-----\n"); | ||||||
|  | 			print_help(menu); | ||||||
|  | 			printf("-----\n"); | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			if (!conf_cnt++) | ||||||
|  | 				printf("*\n* Restart config...\n*\n"); | ||||||
|  | 			rootEntry = menu_get_parent_menu(menu); | ||||||
|  | 			conf(rootEntry); | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -449,38 +681,42 @@ static void check_conf(struct menu *menu) | |||||||
| } | } | ||||||
|  |  | ||||||
| static struct option long_opts[] = { | static struct option long_opts[] = { | ||||||
| 	{"oldaskconfig",    no_argument,       NULL, oldaskconfig}, | 	{"help",          no_argument,       NULL,            'h'}, | ||||||
| 	{"oldconfig",       no_argument,       NULL, oldconfig}, | 	{"silent",        no_argument,       NULL,            's'}, | ||||||
| 	{"silentoldconfig", no_argument,       NULL, silentoldconfig}, | 	{"oldaskconfig",  no_argument,       &input_mode_opt, oldaskconfig}, | ||||||
| 	{"defconfig",       optional_argument, NULL, defconfig}, | 	{"oldconfig",     no_argument,       &input_mode_opt, oldconfig}, | ||||||
| 	{"savedefconfig",   required_argument, NULL, savedefconfig}, | 	{"syncconfig",    no_argument,       &input_mode_opt, syncconfig}, | ||||||
| 	{"allnoconfig",     no_argument,       NULL, allnoconfig}, | 	{"defconfig",     required_argument, &input_mode_opt, defconfig}, | ||||||
| 	{"allyesconfig",    no_argument,       NULL, allyesconfig}, | 	{"savedefconfig", required_argument, &input_mode_opt, savedefconfig}, | ||||||
| 	{"allmodconfig",    no_argument,       NULL, allmodconfig}, | 	{"allnoconfig",   no_argument,       &input_mode_opt, allnoconfig}, | ||||||
| 	{"alldefconfig",    no_argument,       NULL, alldefconfig}, | 	{"allyesconfig",  no_argument,       &input_mode_opt, allyesconfig}, | ||||||
| 	{"randconfig",      no_argument,       NULL, randconfig}, | 	{"allmodconfig",  no_argument,       &input_mode_opt, allmodconfig}, | ||||||
| 	{"listnewconfig",   no_argument,       NULL, listnewconfig}, | 	{"alldefconfig",  no_argument,       &input_mode_opt, alldefconfig}, | ||||||
| 	{"olddefconfig",    no_argument,       NULL, olddefconfig}, | 	{"randconfig",    no_argument,       &input_mode_opt, randconfig}, | ||||||
| 	/* | 	{"listnewconfig", no_argument,       &input_mode_opt, listnewconfig}, | ||||||
| 	 * oldnoconfig is an alias of olddefconfig, because people already | 	{"helpnewconfig", no_argument,       &input_mode_opt, helpnewconfig}, | ||||||
| 	 * are dependent on its behavior(sets new symbols to their default | 	{"olddefconfig",  no_argument,       &input_mode_opt, olddefconfig}, | ||||||
| 	 * value but not 'n') with the counter-intuitive name. | 	{"yes2modconfig", no_argument,       &input_mode_opt, yes2modconfig}, | ||||||
| 	 */ | 	{"mod2yesconfig", no_argument,       &input_mode_opt, mod2yesconfig}, | ||||||
| 	{"oldnoconfig",     no_argument,       NULL, olddefconfig}, |  | ||||||
| 	{NULL, 0, NULL, 0} | 	{NULL, 0, NULL, 0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void conf_usage(const char *progname) | static void conf_usage(const char *progname) | ||||||
| { | { | ||||||
|  | 	printf("Usage: %s [options] <kconfig-file>\n", progname); | ||||||
| 	printf("Usage: %s [option] <kconfig-file>\n", progname); | 	printf("\n"); | ||||||
| 	printf("[option] is _one_ of the following:\n"); | 	printf("Generic options:\n"); | ||||||
|  | 	printf("  -h, --help              Print this message and exit.\n"); | ||||||
|  | 	printf("  -s, --silent            Do not print log.\n"); | ||||||
|  | 	printf("\n"); | ||||||
|  | 	printf("Mode options:\n"); | ||||||
| 	printf("  --listnewconfig         List new options\n"); | 	printf("  --listnewconfig         List new options\n"); | ||||||
|  | 	printf("  --helpnewconfig         List new options and help text\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("  --oldnoconfig           An alias of olddefconfig\n"); | 	printf("  --olddefconfig          Same as oldconfig but sets new symbols to their default value\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"); | ||||||
| 	printf("  --allnoconfig           New config where all options are answered with no\n"); | 	printf("  --allnoconfig           New config where all options are answered with no\n"); | ||||||
| @@ -488,6 +724,9 @@ static void conf_usage(const char *progname) | |||||||
| 	printf("  --allmodconfig          New config where all options are answered with mod\n"); | 	printf("  --allmodconfig          New config where all options are answered with mod\n"); | ||||||
| 	printf("  --alldefconfig          New config with all symbols set to default\n"); | 	printf("  --alldefconfig          New config with all symbols set to default\n"); | ||||||
| 	printf("  --randconfig            New config with random answer to all options\n"); | 	printf("  --randconfig            New config with random answer to all options\n"); | ||||||
|  | 	printf("  --yes2modconfig         Change answers from yes to mod if possible\n"); | ||||||
|  | 	printf("  --mod2yesconfig         Change answers from mod to yes if possible\n"); | ||||||
|  | 	printf("  (If none of the above is given, --oldaskconfig is the default)\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| int main(int ac, char **av) | int main(int ac, char **av) | ||||||
| @@ -496,102 +735,73 @@ int main(int ac, char **av) | |||||||
| 	int opt; | 	int opt; | ||||||
| 	const char *name, *defconfig_file = NULL /* gcc uninit */; | 	const char *name, *defconfig_file = NULL /* gcc uninit */; | ||||||
| 	char *env; | 	char *env; | ||||||
| 	struct stat tmpstat; | 	int no_conf_write = 0; | ||||||
|  |  | ||||||
| 	setlocale(LC_ALL, ""); | 	tty_stdio = isatty(0) && isatty(1); | ||||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); |  | ||||||
| 	textdomain(PACKAGE); |  | ||||||
|  |  | ||||||
| 	tty_stdio = isatty(0) && isatty(1) && isatty(2); | 	while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) { | ||||||
|  |  | ||||||
| 	while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) { |  | ||||||
| 		input_mode = (enum input_mode)opt; |  | ||||||
| 		switch (opt) { | 		switch (opt) { | ||||||
| 		case silentoldconfig: | 		case 'h': | ||||||
| 			sync_kconfig = 1; |  | ||||||
| 			break; |  | ||||||
| 		case defconfig: |  | ||||||
| 		case savedefconfig: |  | ||||||
| 			defconfig_file = optarg; |  | ||||||
| 			break; |  | ||||||
| 		case randconfig: |  | ||||||
| 		{ |  | ||||||
| 			struct timeval now; |  | ||||||
| 			unsigned int seed; |  | ||||||
| 			char *seed_env; |  | ||||||
|  |  | ||||||
| 			/* |  | ||||||
| 			 * Use microseconds derived seed, |  | ||||||
| 			 * compensate for systems where it may be zero |  | ||||||
| 			 */ |  | ||||||
| 			gettimeofday(&now, NULL); |  | ||||||
| 			seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); |  | ||||||
|  |  | ||||||
| 			seed_env = getenv("KCONFIG_SEED"); |  | ||||||
| 			if( seed_env && *seed_env ) { |  | ||||||
| 				char *endp; |  | ||||||
| 				int tmp = (int)strtol(seed_env, &endp, 0); |  | ||||||
| 				if (*endp == '\0') { |  | ||||||
| 					seed = tmp; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed ); |  | ||||||
| 			srand(seed); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case oldaskconfig: |  | ||||||
| 		case oldconfig: |  | ||||||
| 		case allnoconfig: |  | ||||||
| 		case allyesconfig: |  | ||||||
| 		case allmodconfig: |  | ||||||
| 		case alldefconfig: |  | ||||||
| 		case listnewconfig: |  | ||||||
| 		case olddefconfig: |  | ||||||
| 			break; |  | ||||||
| 		case '?': |  | ||||||
| 			conf_usage(progname); | 			conf_usage(progname); | ||||||
| 			exit(1); | 			exit(1); | ||||||
| 			break; | 			break; | ||||||
|  | 		case 's': | ||||||
|  | 			conf_set_message_callback(NULL); | ||||||
|  | 			break; | ||||||
|  | 		case 0: | ||||||
|  | 			input_mode = input_mode_opt; | ||||||
|  | 			switch (input_mode) { | ||||||
|  | 			case syncconfig: | ||||||
|  | 				/* | ||||||
|  | 				 * syncconfig is invoked during the build stage. | ||||||
|  | 				 * Suppress distracting | ||||||
|  | 				 *   "configuration written to ..." | ||||||
|  | 				 */ | ||||||
|  | 				conf_set_message_callback(NULL); | ||||||
|  | 				sync_kconfig = 1; | ||||||
|  | 				break; | ||||||
|  | 			case defconfig: | ||||||
|  | 			case savedefconfig: | ||||||
|  | 				defconfig_file = optarg; | ||||||
|  | 				break; | ||||||
|  | 			case randconfig: | ||||||
|  | 				set_randconfig_seed(); | ||||||
|  | 				break; | ||||||
|  | 			default: | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		default: | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	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); | ||||||
| 	} | 	} | ||||||
| 	name = av[optind]; | 	conf_parse(av[optind]); | ||||||
| 	conf_parse(name); |  | ||||||
| 	//zconfdump(stdout); | 	//zconfdump(stdout); | ||||||
| 	if (sync_kconfig) { |  | ||||||
| 		name = conf_get_configname(); |  | ||||||
| 		if (stat(name, &tmpstat)) { |  | ||||||
| 			fprintf(stderr, _("***\n" |  | ||||||
| 				"*** Configuration file \"%s\" not found!\n" |  | ||||||
| 				"***\n" |  | ||||||
| 				"*** Please run some configurator (e.g. \"make oldconfig\" or\n" |  | ||||||
| 				"*** \"make menuconfig\" or \"make xconfig\").\n" |  | ||||||
| 				"***\n"), name); |  | ||||||
| 			exit(1); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	switch (input_mode) { | 	switch (input_mode) { | ||||||
| 	case defconfig: | 	case defconfig: | ||||||
| 		if (!defconfig_file) |  | ||||||
| 			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: | ||||||
|  | 	case helpnewconfig: | ||||||
| 	case olddefconfig: | 	case olddefconfig: | ||||||
|  | 	case yes2modconfig: | ||||||
|  | 	case mod2yesconfig: | ||||||
| 		conf_read(NULL); | 		conf_read(NULL); | ||||||
| 		break; | 		break; | ||||||
| 	case allnoconfig: | 	case allnoconfig: | ||||||
| @@ -605,7 +815,7 @@ int main(int ac, char **av) | |||||||
| 		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { | 		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { | ||||||
| 			if (conf_read_simple(name, S_DEF_USER)) { | 			if (conf_read_simple(name, S_DEF_USER)) { | ||||||
| 				fprintf(stderr, | 				fprintf(stderr, | ||||||
| 					_("*** Can't read seed configuration \"%s\"!\n"), | 					"*** Can't read seed configuration \"%s\"!\n", | ||||||
| 					name); | 					name); | ||||||
| 				exit(1); | 				exit(1); | ||||||
| 			} | 			} | ||||||
| @@ -622,7 +832,7 @@ int main(int ac, char **av) | |||||||
| 		if (conf_read_simple(name, S_DEF_USER) && | 		if (conf_read_simple(name, S_DEF_USER) && | ||||||
| 		    conf_read_simple("all.config", S_DEF_USER)) { | 		    conf_read_simple("all.config", S_DEF_USER)) { | ||||||
| 			fprintf(stderr, | 			fprintf(stderr, | ||||||
| 				_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), | 				"*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n", | ||||||
| 				name); | 				name); | ||||||
| 			exit(1); | 			exit(1); | ||||||
| 		} | 		} | ||||||
| @@ -631,16 +841,23 @@ int main(int ac, char **av) | |||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	env = getenv("KCONFIG_STRICT"); | ||||||
|  | 	if (env && *env && kconfig_warnings) { | ||||||
|  | 		fprintf(stderr, "\n*** ERROR: %d warnings encountered, and " | ||||||
|  | 			"warnings are errors.\n\n", kconfig_warnings); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (sync_kconfig) { | 	if (sync_kconfig) { | ||||||
| 		if (conf_get_changed()) { | 		name = getenv("KCONFIG_NOSILENTUPDATE"); | ||||||
| 			name = getenv("KCONFIG_NOSILENTUPDATE"); | 		if (name && *name) { | ||||||
| 			if (name && *name) { | 			if (conf_get_changed()) { | ||||||
| 				fprintf(stderr, | 				fprintf(stderr, | ||||||
| 					_("\n*** The configuration requires explicit update.\n\n")); | 					"\n*** The configuration requires explicit update.\n\n"); | ||||||
| 				return 1; | 				return 1; | ||||||
| 			} | 			} | ||||||
|  | 			no_conf_write = 1; | ||||||
| 		} | 		} | ||||||
| 		valid_stdin = tty_stdio; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch (input_mode) { | 	switch (input_mode) { | ||||||
| @@ -665,64 +882,58 @@ int main(int ac, char **av) | |||||||
| 		break; | 		break; | ||||||
| 	case savedefconfig: | 	case savedefconfig: | ||||||
| 		break; | 		break; | ||||||
|  | 	case yes2modconfig: | ||||||
|  | 		conf_rewrite_mod_or_yes(def_y2m); | ||||||
|  | 		break; | ||||||
|  | 	case mod2yesconfig: | ||||||
|  | 		conf_rewrite_mod_or_yes(def_m2y); | ||||||
|  | 		break; | ||||||
| 	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 helpnewconfig: | ||||||
| 	case silentoldconfig: | 	case syncconfig: | ||||||
| 		/* 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; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	env = getenv("KCONFIG_STRICT"); | 	if (input_mode == savedefconfig) { | ||||||
| 	if (env && *env && kconfig_warnings) { |  | ||||||
| 		fprintf(stderr, _("\n*** ERROR: %d warnings encountered, and " |  | ||||||
| 			"warnings are errors.\n\n"), kconfig_warnings); |  | ||||||
| 		exit(1); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (sync_kconfig) { |  | ||||||
| 		/* silentoldconfig is used during the build so we shall update autoconf. |  | ||||||
| 		 * All other commands are only used to generate a config. |  | ||||||
| 		 */ |  | ||||||
| 		if (conf_get_changed() && conf_write(NULL)) { |  | ||||||
| 			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); |  | ||||||
| 			exit(1); |  | ||||||
| 		} |  | ||||||
| 		if (conf_write_autoconf()) { |  | ||||||
| 			fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); |  | ||||||
| 			return 1; |  | ||||||
| 		} |  | ||||||
| 	} 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 && input_mode != helpnewconfig) { | ||||||
| 		if (conf_write(NULL)) { | 		if (!no_conf_write && conf_write(NULL)) { | ||||||
| 			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); | 			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); | ||||||
| 			exit(1); | 			exit(1); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		/* | ||||||
|  | 		 * Create auto.conf if it does not exist. | ||||||
|  | 		 * This prevents GNU Make 4.1 or older from emitting | ||||||
|  | 		 * "include/config/auto.conf: No such file or directory" | ||||||
|  | 		 * in the top-level Makefile | ||||||
|  | 		 * | ||||||
|  | 		 * syncconfig always creates or updates auto.conf because it is | ||||||
|  | 		 * used during the build. | ||||||
|  | 		 */ | ||||||
|  | 		if (conf_write_autoconf(sync_kconfig) && sync_kconfig) { | ||||||
|  | 			fprintf(stderr, | ||||||
|  | 				"\n*** Error during sync of the configuration.\n\n"); | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	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"); |  | ||||||
| } |  | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,8 +1,10 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #include <ctype.h> | ||||||
|  | #include <errno.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| @@ -11,6 +13,8 @@ | |||||||
|  |  | ||||||
| #define DEBUG_EXPR	0 | #define DEBUG_EXPR	0 | ||||||
|  |  | ||||||
|  | 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 +80,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 +95,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 +114,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 +128,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 +139,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 +161,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 +189,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,14 +243,31 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) | |||||||
| #undef e1 | #undef e1 | ||||||
| #undef e2 | #undef 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. | ||||||
|  |  */ | ||||||
| int expr_eq(struct expr *e1, struct expr *e2) | int expr_eq(struct expr *e1, struct expr *e2) | ||||||
| { | { | ||||||
| 	int res, old_count; | 	int res, old_count; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * A NULL expr is taken to be yes, but there's also a different way to | ||||||
|  | 	 * represent yes. expr_is_yes() checks for either representation. | ||||||
|  | 	 */ | ||||||
|  | 	if (!e1 || !e2) | ||||||
|  | 		return expr_is_yes(e1) && expr_is_yes(e2); | ||||||
|  |  | ||||||
| 	if (e1->type != e2->type) | 	if (e1->type != e2->type) | ||||||
| 		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 +302,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 +586,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 +611,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 +650,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 +673,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 +685,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 +699,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 +775,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 +861,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 +905,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 +953,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 +984,56 @@ 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, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | 	default: | ||||||
|  | 		val->s = strtoll(str, &tail, 0); | ||||||
|  | 		kind = k_signed; | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 	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 +1054,64 @@ 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_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 +1133,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 +1165,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 +1271,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); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef EXPR_H | #ifndef EXPR_H | ||||||
| @@ -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 { | ||||||
| @@ -60,7 +62,7 @@ struct symbol_value { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| enum symbol_type { | enum symbol_type { | ||||||
| 	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER | 	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* enum values are used as index to symbol.def[] */ | /* enum values are used as index to symbol.def[] */ | ||||||
| @@ -72,20 +74,64 @@ 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) | ||||||
|  |  | ||||||
| #define SYMBOL_CONST      0x0001  /* symbol is const */ | #define SYMBOL_CONST      0x0001  /* symbol is const */ | ||||||
| #define SYMBOL_CHECK      0x0008  /* used during dependency checking */ | #define SYMBOL_CHECK      0x0008  /* used during dependency checking */ | ||||||
| @@ -95,7 +141,8 @@ struct symbol { | |||||||
| #define SYMBOL_OPTIONAL   0x0100  /* choice is optional - values can be 'n' */ | #define SYMBOL_OPTIONAL   0x0100  /* choice is optional - values can be 'n' */ | ||||||
| #define SYMBOL_WRITE      0x0200  /* write symbol to file (KCONFIG_CONFIG) */ | #define SYMBOL_WRITE      0x0200  /* write symbol to file (KCONFIG_CONFIG) */ | ||||||
| #define SYMBOL_CHANGED    0x0400  /* ? */ | #define SYMBOL_CHANGED    0x0400  /* ? */ | ||||||
| #define SYMBOL_AUTO       0x1000  /* value from environment variable */ | #define SYMBOL_WRITTEN    0x0800  /* track info to avoid double-write to .config */ | ||||||
|  | #define SYMBOL_NO_WRITE   0x1000  /* Symbol for internal use only; it will not be written */ | ||||||
| #define SYMBOL_CHECKED    0x2000  /* used during dependency checking */ | #define SYMBOL_CHECKED    0x2000  /* used during dependency checking */ | ||||||
| #define SYMBOL_WARNED     0x8000  /* warning has been issued */ | #define SYMBOL_WARNED     0x8000  /* warning has been issued */ | ||||||
|  |  | ||||||
| @@ -109,9 +156,6 @@ 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 | ||||||
|  |  | ||||||
| @@ -125,23 +169,25 @@ struct symbol { | |||||||
|  * config BAZ |  * config BAZ | ||||||
|  *         int "BAZ Value" |  *         int "BAZ Value" | ||||||
|  *         range 1..255 |  *         range 1..255 | ||||||
|  |  * | ||||||
|  |  * Please, also check parser.y:print_symbol() when modifying the | ||||||
|  |  * list of property types! | ||||||
|  */ |  */ | ||||||
| enum prop_type { | 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_SYMBOL,   /* where a symbol is defined */ | 	P_SYMBOL,   /* where a symbol is defined */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct property { | struct property { | ||||||
| 	struct property *next;     /* next property - null if last */ | 	struct property *next;     /* next property - null if last */ | ||||||
| 	struct symbol *sym;        /* the symbol for which the property is associated */ |  | ||||||
| 	enum prop_type type;       /* type of property */ | 	enum prop_type type;       /* type of property */ | ||||||
| 	const char *text;          /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ | 	const char *text;          /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ | ||||||
| 	struct expr_value visible; | 	struct expr_value visible; | ||||||
| @@ -162,22 +208,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 { | ||||||
| @@ -187,15 +278,12 @@ struct jump_key { | |||||||
| 	int index; | 	int index; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define JUMP_NB			9 |  | ||||||
|  |  | ||||||
| extern struct file *file_list; | extern struct file *file_list; | ||||||
| extern struct file *current_file; | extern struct file *current_file; | ||||||
| struct file *lookup_file(const char *name); | struct file *lookup_file(const char *name); | ||||||
|  |  | ||||||
| extern struct symbol symbol_yes, symbol_no, symbol_mod; | extern struct symbol symbol_yes, symbol_no, symbol_mod; | ||||||
| extern struct symbol *modules_sym; | extern struct symbol *modules_sym; | ||||||
| extern struct symbol *sym_defconfig_list; |  | ||||||
| extern int cdebug; | extern int cdebug; | ||||||
| struct expr *expr_alloc_symbol(struct symbol *sym); | struct expr *expr_alloc_symbol(struct symbol *sym); | ||||||
| struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); | struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); | ||||||
| @@ -205,24 +293,21 @@ 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); | ||||||
|  | int expr_eq(struct expr *e1, struct expr *e2); | ||||||
| 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) | ||||||
| { | { | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								util/kconfig/gconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								util/kconfig/gconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # SPDX-License-Identifier: GPL-2.0 | ||||||
|  |  | ||||||
|  | PKG="gtk+-2.0 gmodule-2.0 libglade-2.0" | ||||||
|  |  | ||||||
|  | if [ -z "$(command -v pkg-config)" ]; then | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it." | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if ! pkg-config --exists $PKG; then | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	echo >&2 "* Unable to find the GTK+ installation. Please make sure that" | ||||||
|  | 	echo >&2 "* the GTK+ 2.0 development package is correctly installed." | ||||||
|  | 	echo >&2 "* You need $PKG" | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	echo >&2 "* GTK+ is present but version >= 2.0.0 is required." | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo cflags=\"$(pkg-config --cflags $PKG)\" | ||||||
|  | echo libs=\"$(pkg-config --libs $PKG)\" | ||||||
| @@ -1,18 +1,11 @@ | |||||||
| /* Hey EMACS -*- linux-c -*- */ | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * |  | ||||||
|  * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info> |  * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifdef HAVE_CONFIG_H |  | ||||||
| #  include <config.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include "lkc.h" | #include "lkc.h" | ||||||
| #include "images.c" | #include "images.h" | ||||||
|  |  | ||||||
| #include <glade/glade.h> | #include <glade/glade.h> | ||||||
| #include <gtk/gtk.h> | #include <gtk/gtk.h> | ||||||
| @@ -21,13 +14,12 @@ | |||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <strings.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
|  |  | ||||||
| //#define DEBUG | //#define DEBUG | ||||||
|  |  | ||||||
| int kconfig_warnings = 0; |  | ||||||
|  |  | ||||||
| enum { | enum { | ||||||
| 	SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW | 	SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW | ||||||
| }; | }; | ||||||
| @@ -80,8 +72,8 @@ static gchar **fill_row(struct menu *menu); | |||||||
| static void conf_changed(void); | static void conf_changed(void); | ||||||
|  |  | ||||||
| /* Helping/Debugging Functions */ | /* Helping/Debugging Functions */ | ||||||
|  | #ifdef DEBUG | ||||||
| const char *dbg_sym_flags(int val) | static const char *dbg_sym_flags(int val) | ||||||
| { | { | ||||||
| 	static char buf[256]; | 	static char buf[256]; | ||||||
|  |  | ||||||
| @@ -103,16 +95,17 @@ const char *dbg_sym_flags(int val) | |||||||
| 		strcat(buf, "write/"); | 		strcat(buf, "write/"); | ||||||
| 	if (val & SYMBOL_CHANGED) | 	if (val & SYMBOL_CHANGED) | ||||||
| 		strcat(buf, "changed/"); | 		strcat(buf, "changed/"); | ||||||
| 	if (val & SYMBOL_AUTO) | 	if (val & SYMBOL_NO_WRITE) | ||||||
| 		strcat(buf, "auto/"); | 		strcat(buf, "no_write/"); | ||||||
|  |  | ||||||
| 	buf[strlen(buf) - 1] = '\0'; | 	buf[strlen(buf) - 1] = '\0'; | ||||||
|  |  | ||||||
| 	return buf; | 	return buf; | ||||||
| } | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| void replace_button_icon(GladeXML * xml, GdkDrawable * window, | static void replace_button_icon(GladeXML *xml, GdkDrawable *window, | ||||||
| 			 GtkStyle * style, gchar * btn_name, gchar ** xpm) | 				GtkStyle *style, gchar *btn_name, gchar **xpm) | ||||||
| { | { | ||||||
| 	GdkPixmap *pixmap; | 	GdkPixmap *pixmap; | ||||||
| 	GdkBitmap *mask; | 	GdkBitmap *mask; | ||||||
| @@ -130,7 +123,7 @@ void replace_button_icon(GladeXML * xml, GdkDrawable * window, | |||||||
| } | } | ||||||
|  |  | ||||||
| /* Main Window Initialization */ | /* Main Window Initialization */ | ||||||
| void init_main_window(const gchar * glade_file) | static void init_main_window(const gchar *glade_file) | ||||||
| { | { | ||||||
| 	GladeXML *xml; | 	GladeXML *xml; | ||||||
| 	GtkWidget *widget; | 	GtkWidget *widget; | ||||||
| @@ -139,7 +132,7 @@ void init_main_window(const gchar * glade_file) | |||||||
|  |  | ||||||
| 	xml = glade_xml_new(glade_file, "window1", NULL); | 	xml = glade_xml_new(glade_file, "window1", NULL); | ||||||
| 	if (!xml) | 	if (!xml) | ||||||
| 		g_error(_("GUI loading failed !\n")); | 		g_error("GUI loading failed !\n"); | ||||||
| 	glade_xml_signal_autoconnect(xml); | 	glade_xml_signal_autoconnect(xml); | ||||||
|  |  | ||||||
| 	main_wnd = glade_xml_get_widget(xml, "window1"); | 	main_wnd = glade_xml_get_widget(xml, "window1"); | ||||||
| @@ -171,14 +164,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, | ||||||
| @@ -186,22 +171,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", | ||||||
| @@ -216,7 +185,7 @@ void init_main_window(const gchar * glade_file) | |||||||
| 	gtk_widget_show(main_wnd); | 	gtk_widget_show(main_wnd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void init_tree_model(void) | static void init_tree_model(void) | ||||||
| { | { | ||||||
| 	gint i; | 	gint i; | ||||||
|  |  | ||||||
| @@ -246,7 +215,7 @@ void init_tree_model(void) | |||||||
| 	model1 = GTK_TREE_MODEL(tree1); | 	model1 = GTK_TREE_MODEL(tree1); | ||||||
| } | } | ||||||
|  |  | ||||||
| void init_left_tree(void) | static void init_left_tree(void) | ||||||
| { | { | ||||||
| 	GtkTreeView *view = GTK_TREE_VIEW(tree1_w); | 	GtkTreeView *view = GTK_TREE_VIEW(tree1_w); | ||||||
| 	GtkCellRenderer *renderer; | 	GtkCellRenderer *renderer; | ||||||
| @@ -259,7 +228,7 @@ void init_left_tree(void) | |||||||
|  |  | ||||||
| 	column = gtk_tree_view_column_new(); | 	column = gtk_tree_view_column_new(); | ||||||
| 	gtk_tree_view_append_column(view, column); | 	gtk_tree_view_append_column(view, column); | ||||||
| 	gtk_tree_view_column_set_title(column, _("Options")); | 	gtk_tree_view_column_set_title(column, "Options"); | ||||||
|  |  | ||||||
| 	renderer = gtk_cell_renderer_toggle_new(); | 	renderer = gtk_cell_renderer_toggle_new(); | ||||||
| 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | ||||||
| @@ -288,7 +257,7 @@ static void renderer_edited(GtkCellRendererText * cell, | |||||||
| 			    const gchar * path_string, | 			    const gchar * path_string, | ||||||
| 			    const gchar * new_text, gpointer user_data); | 			    const gchar * new_text, gpointer user_data); | ||||||
|  |  | ||||||
| void init_right_tree(void) | static void init_right_tree(void) | ||||||
| { | { | ||||||
| 	GtkTreeView *view = GTK_TREE_VIEW(tree2_w); | 	GtkTreeView *view = GTK_TREE_VIEW(tree2_w); | ||||||
| 	GtkCellRenderer *renderer; | 	GtkCellRenderer *renderer; | ||||||
| @@ -302,7 +271,7 @@ void init_right_tree(void) | |||||||
|  |  | ||||||
| 	column = gtk_tree_view_column_new(); | 	column = gtk_tree_view_column_new(); | ||||||
| 	gtk_tree_view_append_column(view, column); | 	gtk_tree_view_append_column(view, column); | ||||||
| 	gtk_tree_view_column_set_title(column, _("Options")); | 	gtk_tree_view_column_set_title(column, "Options"); | ||||||
|  |  | ||||||
| 	renderer = gtk_cell_renderer_pixbuf_new(); | 	renderer = gtk_cell_renderer_pixbuf_new(); | ||||||
| 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | ||||||
| @@ -331,7 +300,7 @@ void init_right_tree(void) | |||||||
|  |  | ||||||
| 	renderer = gtk_cell_renderer_text_new(); | 	renderer = gtk_cell_renderer_text_new(); | ||||||
| 	gtk_tree_view_insert_column_with_attributes(view, -1, | 	gtk_tree_view_insert_column_with_attributes(view, -1, | ||||||
| 						    _("Name"), renderer, | 						    "Name", renderer, | ||||||
| 						    "text", COL_NAME, | 						    "text", COL_NAME, | ||||||
| 						    "foreground-gdk", | 						    "foreground-gdk", | ||||||
| 						    COL_COLOR, NULL); | 						    COL_COLOR, NULL); | ||||||
| @@ -355,7 +324,7 @@ void init_right_tree(void) | |||||||
| 						    COL_COLOR, NULL); | 						    COL_COLOR, NULL); | ||||||
| 	renderer = gtk_cell_renderer_text_new(); | 	renderer = gtk_cell_renderer_text_new(); | ||||||
| 	gtk_tree_view_insert_column_with_attributes(view, -1, | 	gtk_tree_view_insert_column_with_attributes(view, -1, | ||||||
| 						    _("Value"), renderer, | 						    "Value", renderer, | ||||||
| 						    "text", COL_VALUE, | 						    "text", COL_VALUE, | ||||||
| 						    "editable", | 						    "editable", | ||||||
| 						    COL_EDIT, | 						    COL_EDIT, | ||||||
| @@ -394,7 +363,7 @@ static void text_insert_help(struct menu *menu) | |||||||
| { | { | ||||||
| 	GtkTextBuffer *buffer; | 	GtkTextBuffer *buffer; | ||||||
| 	GtkTextIter start, end; | 	GtkTextIter start, end; | ||||||
| 	const char *prompt = _(menu_get_prompt(menu)); | 	const char *prompt = menu_get_prompt(menu); | ||||||
| 	struct gstr help = str_new(); | 	struct gstr help = str_new(); | ||||||
|  |  | ||||||
| 	menu_get_ext_help(menu, &help); | 	menu_get_ext_help(menu, &help); | ||||||
| @@ -448,7 +417,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, | |||||||
| 	if (!conf_get_changed()) | 	if (!conf_get_changed()) | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
|  |  | ||||||
| 	dialog = gtk_dialog_new_with_buttons(_("Warning !"), | 	dialog = gtk_dialog_new_with_buttons("Warning !", | ||||||
| 					     GTK_WINDOW(main_wnd), | 					     GTK_WINDOW(main_wnd), | ||||||
| 					     (GtkDialogFlags) | 					     (GtkDialogFlags) | ||||||
| 					     (GTK_DIALOG_MODAL | | 					     (GTK_DIALOG_MODAL | | ||||||
| @@ -462,7 +431,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, | |||||||
| 	gtk_dialog_set_default_response(GTK_DIALOG(dialog), | 	gtk_dialog_set_default_response(GTK_DIALOG(dialog), | ||||||
| 					GTK_RESPONSE_CANCEL); | 					GTK_RESPONSE_CANCEL); | ||||||
|  |  | ||||||
| 	label = gtk_label_new(_("\nSave configuration ?\n")); | 	label = gtk_label_new("\nSave configuration ?\n"); | ||||||
| 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); | 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); | ||||||
| 	gtk_widget_show(label); | 	gtk_widget_show(label); | ||||||
|  |  | ||||||
| @@ -522,7 +491,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data) | |||||||
| 					     (user_data)); | 					     (user_data)); | ||||||
|  |  | ||||||
| 	if (conf_read(fn)) | 	if (conf_read(fn)) | ||||||
| 		text_insert_msg(_("Error"), _("Unable to load configuration !")); | 		text_insert_msg("Error", "Unable to load configuration !"); | ||||||
| 	else | 	else | ||||||
| 		display_tree(&rootmenu); | 		display_tree(&rootmenu); | ||||||
| } | } | ||||||
| @@ -531,7 +500,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||||||
| { | { | ||||||
| 	GtkWidget *fs; | 	GtkWidget *fs; | ||||||
|  |  | ||||||
| 	fs = gtk_file_selection_new(_("Load file...")); | 	fs = gtk_file_selection_new("Load file..."); | ||||||
| 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), | 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), | ||||||
| 			 "clicked", | 			 "clicked", | ||||||
| 			 G_CALLBACK(load_filename), (gpointer) fs); | 			 G_CALLBACK(load_filename), (gpointer) fs); | ||||||
| @@ -550,7 +519,8 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||||||
| void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) | void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) | ||||||
| { | { | ||||||
| 	if (conf_write(NULL)) | 	if (conf_write(NULL)) | ||||||
| 		text_insert_msg(_("Error"), _("Unable to save configuration !")); | 		text_insert_msg("Error", "Unable to save configuration !"); | ||||||
|  | 	conf_write_autoconf(0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -563,7 +533,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data) | |||||||
| 					     (user_data)); | 					     (user_data)); | ||||||
|  |  | ||||||
| 	if (conf_write(fn)) | 	if (conf_write(fn)) | ||||||
| 		text_insert_msg(_("Error"), _("Unable to save configuration !")); | 		text_insert_msg("Error", "Unable to save configuration !"); | ||||||
|  |  | ||||||
| 	gtk_widget_destroy(GTK_WIDGET(user_data)); | 	gtk_widget_destroy(GTK_WIDGET(user_data)); | ||||||
| } | } | ||||||
| @@ -572,7 +542,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||||||
| { | { | ||||||
| 	GtkWidget *fs; | 	GtkWidget *fs; | ||||||
|  |  | ||||||
| 	fs = gtk_file_selection_new(_("Save file as...")); | 	fs = gtk_file_selection_new("Save file as..."); | ||||||
| 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), | 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), | ||||||
| 			 "clicked", | 			 "clicked", | ||||||
| 			 G_CALLBACK(store_filename), (gpointer) fs); | 			 G_CALLBACK(store_filename), (gpointer) fs); | ||||||
| @@ -665,7 +635,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) | |||||||
| void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) | void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) | ||||||
| { | { | ||||||
| 	GtkWidget *dialog; | 	GtkWidget *dialog; | ||||||
| 	const gchar *intro_text = _( | 	const gchar *intro_text = | ||||||
| 	    "Welcome to gkc, the GTK+ graphical configuration tool\n" | 	    "Welcome to gkc, the GTK+ graphical configuration tool\n" | ||||||
| 	    "For each option, a blank box indicates the feature is disabled, a\n" | 	    "For each option, a blank box indicates the feature is disabled, a\n" | ||||||
| 	    "check indicates it is enabled, and a dot indicates that it is to\n" | 	    "check indicates it is enabled, and a dot indicates that it is to\n" | ||||||
| @@ -680,7 +650,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||||||
| 	    "option.\n" | 	    "option.\n" | ||||||
| 	    "\n" | 	    "\n" | ||||||
| 	    "Toggling Show Debug Info under the Options menu will show \n" | 	    "Toggling Show Debug Info under the Options menu will show \n" | ||||||
| 	    "the dependencies, which you can then match by examining other options."); | 	    "the dependencies, which you can then match by examining other options."; | ||||||
|  |  | ||||||
| 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | ||||||
| 					GTK_DIALOG_DESTROY_WITH_PARENT, | 					GTK_DIALOG_DESTROY_WITH_PARENT, | ||||||
| @@ -697,8 +667,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||||||
| { | { | ||||||
| 	GtkWidget *dialog; | 	GtkWidget *dialog; | ||||||
| 	const gchar *about_text = | 	const gchar *about_text = | ||||||
| 	    _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" | 	    "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" | ||||||
| 	      "Based on the source code from Roman Zippel.\n"); | 	      "Based on the source code from Roman Zippel.\n"; | ||||||
|  |  | ||||||
| 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | ||||||
| 					GTK_DIALOG_DESTROY_WITH_PARENT, | 					GTK_DIALOG_DESTROY_WITH_PARENT, | ||||||
| @@ -715,9 +685,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||||||
| { | { | ||||||
| 	GtkWidget *dialog; | 	GtkWidget *dialog; | ||||||
| 	const gchar *license_text = | 	const gchar *license_text = | ||||||
| 	    _("gkc is released under the terms of the GNU GPL v2.\n" | 	    "gkc is released under the terms of the GNU GPL v2.\n" | ||||||
| 	      "For more information, please see the source code or\n" | 	      "For more information, please see the source code or\n" | ||||||
| 	      "visit http://www.fsf.org/licenses/licenses.html\n"); | 	      "visit http://www.fsf.org/licenses/licenses.html\n"; | ||||||
|  |  | ||||||
| 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | ||||||
| 					GTK_DIALOG_DESTROY_WITH_PARENT, | 					GTK_DIALOG_DESTROY_WITH_PARENT, | ||||||
| @@ -940,7 +910,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); | ||||||
| 		} | 		} | ||||||
| @@ -1074,8 +1044,13 @@ static gchar **fill_row(struct menu *menu) | |||||||
| 		g_free(row[i]); | 		g_free(row[i]); | ||||||
| 	bzero(row, sizeof(row)); | 	bzero(row, sizeof(row)); | ||||||
|  |  | ||||||
|  | 	ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||||||
|  |  | ||||||
| 	row[COL_OPTION] = | 	row[COL_OPTION] = | ||||||
| 	    g_strdup_printf("%s %s", _(menu_get_prompt(menu)), | 	    g_strdup_printf("%s %s %s %s", | ||||||
|  | 			    ptype == P_COMMENT ? "***" : "", | ||||||
|  | 			    menu_get_prompt(menu), | ||||||
|  | 			    ptype == P_COMMENT ? "***" : "", | ||||||
| 			    sym && !sym_has_value(sym) ? "(NEW)" : ""); | 			    sym && !sym_has_value(sym) ? "(NEW)" : ""); | ||||||
|  |  | ||||||
| 	if (opt_mode == OPT_ALL && !menu_is_visible(menu)) | 	if (opt_mode == OPT_ALL && !menu_is_visible(menu)) | ||||||
| @@ -1086,7 +1061,6 @@ static gchar **fill_row(struct menu *menu) | |||||||
| 	else | 	else | ||||||
| 		row[COL_COLOR] = g_strdup("Black"); | 		row[COL_COLOR] = g_strdup("Black"); | ||||||
|  |  | ||||||
| 	ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; |  | ||||||
| 	switch (ptype) { | 	switch (ptype) { | ||||||
| 	case P_MENU: | 	case P_MENU: | ||||||
| 		row[COL_PIXBUF] = (gchar *) xpm_menu; | 		row[COL_PIXBUF] = (gchar *) xpm_menu; | ||||||
| @@ -1128,7 +1102,7 @@ static gchar **fill_row(struct menu *menu) | |||||||
|  |  | ||||||
| 		if (def_menu) | 		if (def_menu) | ||||||
| 			row[COL_VALUE] = | 			row[COL_VALUE] = | ||||||
| 			    g_strdup(_(menu_get_prompt(def_menu))); | 			    g_strdup(menu_get_prompt(def_menu)); | ||||||
| 	} | 	} | ||||||
| 	if (sym->flags & SYMBOL_CHOICEVAL) | 	if (sym->flags & SYMBOL_CHOICEVAL) | ||||||
| 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); | 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); | ||||||
| @@ -1237,8 +1211,8 @@ static GtkTreeIter found; | |||||||
| /* | /* | ||||||
|  * Find a menu in the GtkTree starting at parent. |  * Find a menu in the GtkTree starting at parent. | ||||||
|  */ |  */ | ||||||
| GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, | static GtkTreeIter *gtktree_iter_find_node(GtkTreeIter *parent, | ||||||
| 				    struct menu *tofind) | 					   struct menu *tofind) | ||||||
| { | { | ||||||
| 	GtkTreeIter iter; | 	GtkTreeIter iter; | ||||||
| 	GtkTreeIter *child = &iter; | 	GtkTreeIter *child = &iter; | ||||||
| @@ -1449,7 +1423,7 @@ static void display_list(void) | |||||||
| 	tree = tree2; | 	tree = tree2; | ||||||
| } | } | ||||||
|  |  | ||||||
| void fixup_rootmenu(struct menu *menu) | static void fixup_rootmenu(struct menu *menu) | ||||||
| { | { | ||||||
| 	struct menu *child; | 	struct menu *child; | ||||||
| 	static int menu_cnt = 0; | 	static int menu_cnt = 0; | ||||||
| @@ -1473,18 +1447,11 @@ int main(int ac, char *av[]) | |||||||
| 	char *env; | 	char *env; | ||||||
| 	gchar *glade_file; | 	gchar *glade_file; | ||||||
|  |  | ||||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); |  | ||||||
| 	bind_textdomain_codeset(PACKAGE, "UTF-8"); |  | ||||||
| 	textdomain(PACKAGE); |  | ||||||
|  |  | ||||||
| 	/* GTK stuffs */ | 	/* GTK stuffs */ | ||||||
| 	gtk_set_locale(); | 	gtk_set_locale(); | ||||||
| 	gtk_init(&ac, &av); | 	gtk_init(&ac, &av); | ||||||
| 	glade_init(); | 	glade_init(); | ||||||
|  |  | ||||||
| 	//add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); |  | ||||||
| 	//add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); |  | ||||||
|  |  | ||||||
| 	/* Determine GUI path */ | 	/* Determine GUI path */ | ||||||
| 	env = getenv(SRCTREE); | 	env = getenv(SRCTREE); | ||||||
| 	if (env) | 	if (env) | ||||||
| @@ -1500,9 +1467,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]; | ||||||
|   | |||||||
| @@ -1,9 +1,11 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| static const char *xpm_load[] = { | #include "images.h" | ||||||
|  |  | ||||||
|  | const char * const xpm_load[] = { | ||||||
| "22 22 5 1", | "22 22 5 1", | ||||||
| ". c None", | ". c None", | ||||||
| "# c #000000", | "# c #000000", | ||||||
| @@ -33,7 +35,7 @@ static const char *xpm_load[] = { | |||||||
| "###############.......", | "###############.......", | ||||||
| "......................"}; | "......................"}; | ||||||
|  |  | ||||||
| static const char *xpm_save[] = { | const char * const xpm_save[] = { | ||||||
| "22 22 5 1", | "22 22 5 1", | ||||||
| ". c None", | ". c None", | ||||||
| "# c #000000", | "# c #000000", | ||||||
| @@ -63,7 +65,7 @@ static const char *xpm_save[] = { | |||||||
| "..##################..", | "..##################..", | ||||||
| "......................"}; | "......................"}; | ||||||
|  |  | ||||||
| static const char *xpm_back[] = { | const char * const xpm_back[] = { | ||||||
| "22 22 3 1", | "22 22 3 1", | ||||||
| ". c None", | ". c None", | ||||||
| "# c #000083", | "# c #000083", | ||||||
| @@ -91,7 +93,7 @@ static const char *xpm_back[] = { | |||||||
| "......................", | "......................", | ||||||
| "......................"}; | "......................"}; | ||||||
|  |  | ||||||
| static const char *xpm_tree_view[] = { | const char * const xpm_tree_view[] = { | ||||||
| "22 22 2 1", | "22 22 2 1", | ||||||
| ". c None", | ". c None", | ||||||
| "# c #000000", | "# c #000000", | ||||||
| @@ -118,7 +120,7 @@ static const char *xpm_tree_view[] = { | |||||||
| "......................", | "......................", | ||||||
| "......................"}; | "......................"}; | ||||||
|  |  | ||||||
| static const char *xpm_single_view[] = { | const char * const xpm_single_view[] = { | ||||||
| "22 22 2 1", | "22 22 2 1", | ||||||
| ". c None", | ". c None", | ||||||
| "# c #000000", | "# c #000000", | ||||||
| @@ -145,7 +147,7 @@ static const char *xpm_single_view[] = { | |||||||
| "......................", | "......................", | ||||||
| "......................"}; | "......................"}; | ||||||
|  |  | ||||||
| static const char *xpm_split_view[] = { | const char * const xpm_split_view[] = { | ||||||
| "22 22 2 1", | "22 22 2 1", | ||||||
| ". c None", | ". c None", | ||||||
| "# c #000000", | "# c #000000", | ||||||
| @@ -172,7 +174,7 @@ static const char *xpm_split_view[] = { | |||||||
| "......................", | "......................", | ||||||
| "......................"}; | "......................"}; | ||||||
|  |  | ||||||
| static const char *xpm_symbol_no[] = { | const char * const xpm_symbol_no[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -189,7 +191,7 @@ static const char *xpm_symbol_no[] = { | |||||||
| " .......... ", | " .......... ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_symbol_mod[] = { | const char * const xpm_symbol_mod[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -206,7 +208,7 @@ static const char *xpm_symbol_mod[] = { | |||||||
| " .......... ", | " .......... ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_symbol_yes[] = { | const char * const xpm_symbol_yes[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -223,7 +225,7 @@ static const char *xpm_symbol_yes[] = { | |||||||
| " .......... ", | " .......... ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_choice_no[] = { | const char * const xpm_choice_no[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -240,7 +242,7 @@ static const char *xpm_choice_no[] = { | |||||||
| "    ....    ", | "    ....    ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_choice_yes[] = { | const char * const xpm_choice_yes[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -257,7 +259,7 @@ static const char *xpm_choice_yes[] = { | |||||||
| "    ....    ", | "    ....    ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_menu[] = { | const char * const xpm_menu[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -274,7 +276,7 @@ static const char *xpm_menu[] = { | |||||||
| " .......... ", | " .......... ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_menu_inv[] = { | const char * const xpm_menu_inv[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -291,7 +293,7 @@ static const char *xpm_menu_inv[] = { | |||||||
| " .......... ", | " .......... ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_menuback[] = { | const char * const xpm_menuback[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
| @@ -308,7 +310,7 @@ static const char *xpm_menuback[] = { | |||||||
| " .......... ", | " .......... ", | ||||||
| "            "}; | "            "}; | ||||||
|  |  | ||||||
| static const char *xpm_void[] = { | const char * const xpm_void[] = { | ||||||
| "12 12 2 1", | "12 12 2 1", | ||||||
| "  c white", | "  c white", | ||||||
| ". c black", | ". c black", | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								util/kconfig/images.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								util/kconfig/images.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
|  | /* | ||||||
|  |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef IMAGES_H | ||||||
|  | #define IMAGES_H | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | extern const char * const xpm_load[]; | ||||||
|  | extern const char * const xpm_save[]; | ||||||
|  | extern const char * const xpm_back[]; | ||||||
|  | extern const char * const xpm_tree_view[]; | ||||||
|  | extern const char * const xpm_single_view[]; | ||||||
|  | extern const char * const xpm_split_view[]; | ||||||
|  | extern const char * const xpm_symbol_no[]; | ||||||
|  | extern const char * const xpm_symbol_mod[]; | ||||||
|  | extern const char * const xpm_symbol_yes[]; | ||||||
|  | extern const char * const xpm_choice_no[]; | ||||||
|  | extern const char * const xpm_choice_yes[]; | ||||||
|  | extern const char * const xpm_menu[]; | ||||||
|  | extern const char * const xpm_menu_inv[]; | ||||||
|  | extern const char * const xpm_menuback[]; | ||||||
|  | extern const char * const xpm_void[]; | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif /* IMAGES_H */ | ||||||
							
								
								
									
										9
									
								
								util/kconfig/internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								util/kconfig/internal.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0-only */ | ||||||
|  | #ifndef INTERNAL_H | ||||||
|  | #define INTERNAL_H | ||||||
|  |  | ||||||
|  | struct menu; | ||||||
|  |  | ||||||
|  | extern struct menu *current_menu, *current_entry; | ||||||
|  |  | ||||||
|  | #endif /* INTERNAL_H */ | ||||||
| @@ -1,235 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005 |  | ||||||
|  * |  | ||||||
|  * Released under the terms of the GNU GPL v2.0 |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #include "lkc.h" |  | ||||||
|  |  | ||||||
| static char *escape(const char* text, char *bf, int len) |  | ||||||
| { |  | ||||||
| 	char *bfp = bf; |  | ||||||
| 	int multiline = strchr(text, '\n') != NULL; |  | ||||||
| 	int eol = 0; |  | ||||||
| 	int textlen = strlen(text); |  | ||||||
|  |  | ||||||
| 	if ((textlen > 0) && (text[textlen-1] == '\n')) |  | ||||||
| 		eol = 1; |  | ||||||
|  |  | ||||||
| 	*bfp++ = '"'; |  | ||||||
| 	--len; |  | ||||||
|  |  | ||||||
| 	if (multiline) { |  | ||||||
| 		*bfp++ = '"'; |  | ||||||
| 		*bfp++ = '\n'; |  | ||||||
| 		*bfp++ = '"'; |  | ||||||
| 		len -= 3; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	while (*text != '\0' && len > 1) { |  | ||||||
| 		if (*text == '"') |  | ||||||
| 			*bfp++ = '\\'; |  | ||||||
| 		else if (*text == '\n') { |  | ||||||
| 			*bfp++ = '\\'; |  | ||||||
| 			*bfp++ = 'n'; |  | ||||||
| 			*bfp++ = '"'; |  | ||||||
| 			*bfp++ = '\n'; |  | ||||||
| 			*bfp++ = '"'; |  | ||||||
| 			len -= 5; |  | ||||||
| 			++text; |  | ||||||
| 			goto next; |  | ||||||
| 		} |  | ||||||
| 		else if (*text == '\\') { |  | ||||||
| 			*bfp++ = '\\'; |  | ||||||
| 			len--; |  | ||||||
| 		} |  | ||||||
| 		*bfp++ = *text++; |  | ||||||
| next: |  | ||||||
| 		--len; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (multiline && eol) |  | ||||||
| 		bfp -= 3; |  | ||||||
|  |  | ||||||
| 	*bfp++ = '"'; |  | ||||||
| 	*bfp = '\0'; |  | ||||||
|  |  | ||||||
| 	return bf; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct file_line { |  | ||||||
| 	struct file_line *next; |  | ||||||
| 	const char *file; |  | ||||||
| 	int lineno; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct file_line *file_line__new(const char *file, int lineno) |  | ||||||
| { |  | ||||||
| 	struct file_line *self = malloc(sizeof(*self)); |  | ||||||
|  |  | ||||||
| 	if (self == NULL) |  | ||||||
| 		goto out; |  | ||||||
|  |  | ||||||
| 	self->file   = file; |  | ||||||
| 	self->lineno = lineno; |  | ||||||
| 	self->next   = NULL; |  | ||||||
| out: |  | ||||||
| 	return self; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct message { |  | ||||||
| 	const char	 *msg; |  | ||||||
| 	const char	 *option; |  | ||||||
| 	struct message	 *next; |  | ||||||
| 	struct file_line *files; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct message *message__list; |  | ||||||
|  |  | ||||||
| static struct message *message__new(const char *msg, char *option, |  | ||||||
| 				    const char *file, int lineno) |  | ||||||
| { |  | ||||||
| 	struct message *self = malloc(sizeof(*self)); |  | ||||||
|  |  | ||||||
| 	if (self == NULL) |  | ||||||
| 		goto out; |  | ||||||
|  |  | ||||||
| 	self->files = file_line__new(file, lineno); |  | ||||||
| 	if (self->files == NULL) |  | ||||||
| 		goto out_fail; |  | ||||||
|  |  | ||||||
| 	self->msg = strdup(msg); |  | ||||||
| 	if (self->msg == NULL) |  | ||||||
| 		goto out_fail_msg; |  | ||||||
|  |  | ||||||
| 	self->option = option; |  | ||||||
| 	self->next = NULL; |  | ||||||
| out: |  | ||||||
| 	return self; |  | ||||||
| out_fail_msg: |  | ||||||
| 	free(self->files); |  | ||||||
| out_fail: |  | ||||||
| 	free(self); |  | ||||||
| 	self = NULL; |  | ||||||
| 	goto out; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static struct message *mesage__find(const char *msg) |  | ||||||
| { |  | ||||||
| 	struct message *m = message__list; |  | ||||||
|  |  | ||||||
| 	while (m != NULL) { |  | ||||||
| 		if (strcmp(m->msg, msg) == 0) |  | ||||||
| 			break; |  | ||||||
| 		m = m->next; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return m; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int message__add_file_line(struct message *self, const char *file, |  | ||||||
| 				  int lineno) |  | ||||||
| { |  | ||||||
| 	int rc = -1; |  | ||||||
| 	struct file_line *fl = file_line__new(file, lineno); |  | ||||||
|  |  | ||||||
| 	if (fl == NULL) |  | ||||||
| 		goto out; |  | ||||||
|  |  | ||||||
| 	fl->next    = self->files; |  | ||||||
| 	self->files = fl; |  | ||||||
| 	rc = 0; |  | ||||||
| out: |  | ||||||
| 	return rc; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int message__add(const char *msg, char *option, const char *file, |  | ||||||
| 			int lineno) |  | ||||||
| { |  | ||||||
| 	int rc = 0; |  | ||||||
| 	char bf[16384]; |  | ||||||
| 	char *escaped = escape(msg, bf, sizeof(bf)); |  | ||||||
| 	struct message *m = mesage__find(escaped); |  | ||||||
|  |  | ||||||
| 	if (m != NULL) |  | ||||||
| 		rc = message__add_file_line(m, file, lineno); |  | ||||||
| 	else { |  | ||||||
| 		m = message__new(escaped, option, file, lineno); |  | ||||||
|  |  | ||||||
| 		if (m != NULL) { |  | ||||||
| 			m->next	      = message__list; |  | ||||||
| 			message__list = m; |  | ||||||
| 		} else |  | ||||||
| 			rc = -1; |  | ||||||
| 	} |  | ||||||
| 	return rc; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void menu_build_message_list(struct menu *menu) |  | ||||||
| { |  | ||||||
| 	struct menu *child; |  | ||||||
|  |  | ||||||
| 	message__add(menu_get_prompt(menu), NULL, |  | ||||||
| 		     menu->file == NULL ? "Root Menu" : menu->file->name, |  | ||||||
| 		     menu->lineno); |  | ||||||
|  |  | ||||||
| 	if (menu->sym != NULL && menu_has_help(menu)) |  | ||||||
| 		message__add(menu_get_help(menu), menu->sym->name, |  | ||||||
| 			     menu->file == NULL ? "Root Menu" : menu->file->name, |  | ||||||
| 			     menu->lineno); |  | ||||||
|  |  | ||||||
| 	for (child = menu->list; child != NULL; child = child->next) |  | ||||||
| 		if (child->prompt != NULL) |  | ||||||
| 			menu_build_message_list(child); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void message__print_file_lineno(struct message *self) |  | ||||||
| { |  | ||||||
| 	struct file_line *fl = self->files; |  | ||||||
|  |  | ||||||
| 	putchar('\n'); |  | ||||||
| 	if (self->option != NULL) |  | ||||||
| 		printf("# %s:00000\n", self->option); |  | ||||||
|  |  | ||||||
| 	printf("#: %s:%d", fl->file, fl->lineno); |  | ||||||
| 	fl = fl->next; |  | ||||||
|  |  | ||||||
| 	while (fl != NULL) { |  | ||||||
| 		printf(", %s:%d", fl->file, fl->lineno); |  | ||||||
| 		fl = fl->next; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	putchar('\n'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void message__print_gettext_msgid_msgstr(struct message *self) |  | ||||||
| { |  | ||||||
| 	message__print_file_lineno(self); |  | ||||||
|  |  | ||||||
| 	printf("msgid %s\n" |  | ||||||
| 	       "msgstr \"\"\n", self->msg); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void menu__xgettext(void) |  | ||||||
| { |  | ||||||
| 	struct message *m = message__list; |  | ||||||
|  |  | ||||||
| 	while (m != NULL) { |  | ||||||
| 		/* skip empty lines ("") */ |  | ||||||
| 		if (strlen(m->msg) > sizeof("\"\"")) |  | ||||||
| 			message__print_gettext_msgid_msgstr(m); |  | ||||||
| 		m = m->next; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int main(int ac, char **av) |  | ||||||
| { |  | ||||||
| 	conf_parse(av[1]); |  | ||||||
|  |  | ||||||
| 	menu_build_message_list(menu_get_root_menu(NULL)); |  | ||||||
| 	menu__xgettext(); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
							
								
								
									
										494
									
								
								util/kconfig/lexer.l
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										494
									
								
								util/kconfig/lexer.l
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,494 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
|  | /* | ||||||
|  |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  |  */ | ||||||
|  | %option nostdinit noyywrap never-interactive full ecs | ||||||
|  | %option 8bit nodefault yylineno | ||||||
|  | %x ASSIGN_VAL HELP STRING | ||||||
|  | %{ | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <glob.h> | ||||||
|  | #include <limits.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "lkc.h" | ||||||
|  | #include "parser.tab.h" | ||||||
|  |  | ||||||
|  | #define YY_DECL		static int yylex1(void) | ||||||
|  |  | ||||||
|  | #define START_STRSIZE	16 | ||||||
|  |  | ||||||
|  | static struct { | ||||||
|  | 	struct file *file; | ||||||
|  | 	int lineno; | ||||||
|  | } current_pos; | ||||||
|  |  | ||||||
|  | static int prev_prev_token = T_EOL; | ||||||
|  | static int prev_token = T_EOL; | ||||||
|  | static char *text; | ||||||
|  | static int text_size, text_asize; | ||||||
|  |  | ||||||
|  | struct buffer { | ||||||
|  | 	struct buffer *parent; | ||||||
|  | 	YY_BUFFER_STATE state; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static struct buffer *current_buf; | ||||||
|  |  | ||||||
|  | static int last_ts, first_ts; | ||||||
|  |  | ||||||
|  | static char *expand_token(const char *in, size_t n); | ||||||
|  | static void append_expanded_string(const char *in); | ||||||
|  | static void zconf_endhelp(void); | ||||||
|  | static void zconf_endfile(void); | ||||||
|  |  | ||||||
|  | static void new_string(void) | ||||||
|  | { | ||||||
|  | 	text = xmalloc(START_STRSIZE); | ||||||
|  | 	text_asize = START_STRSIZE; | ||||||
|  | 	text_size = 0; | ||||||
|  | 	*text = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void append_string(const char *str, int size) | ||||||
|  | { | ||||||
|  | 	int new_size = text_size + size + 1; | ||||||
|  | 	if (new_size > text_asize) { | ||||||
|  | 		new_size += START_STRSIZE - 1; | ||||||
|  | 		new_size &= -START_STRSIZE; | ||||||
|  | 		text = xrealloc(text, new_size); | ||||||
|  | 		text_asize = new_size; | ||||||
|  | 	} | ||||||
|  | 	memcpy(text + text_size, str, size); | ||||||
|  | 	text_size += size; | ||||||
|  | 	text[text_size] = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void alloc_string(const char *str, int size) | ||||||
|  | { | ||||||
|  | 	text = xmalloc(size + 1); | ||||||
|  | 	memcpy(text, str, size); | ||||||
|  | 	text[size] = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void warn_ignored_character(char chr) | ||||||
|  | { | ||||||
|  | 	fprintf(stderr, | ||||||
|  | 	        "%s:%d:warning: ignoring unsupported character '%c'\n", | ||||||
|  | 	        current_file->name, yylineno, chr); | ||||||
|  | } | ||||||
|  | %} | ||||||
|  |  | ||||||
|  | n	[A-Za-z0-9_-] | ||||||
|  |  | ||||||
|  | %% | ||||||
|  | 	int str = 0; | ||||||
|  | 	int ts, i; | ||||||
|  |  | ||||||
|  | #.*			/* ignore comment */ | ||||||
|  | [ \t]*			/* whitespaces */ | ||||||
|  | \\\n			/* escaped new line */ | ||||||
|  | \n			return T_EOL; | ||||||
|  | "bool"			return T_BOOL; | ||||||
|  | "choice"		return T_CHOICE; | ||||||
|  | "comment"		return T_COMMENT; | ||||||
|  | "config"		return T_CONFIG; | ||||||
|  | "def_bool"		return T_DEF_BOOL; | ||||||
|  | "def_tristate"		return T_DEF_TRISTATE; | ||||||
|  | "default"		return T_DEFAULT; | ||||||
|  | "depends"		return T_DEPENDS; | ||||||
|  | "endchoice"		return T_ENDCHOICE; | ||||||
|  | "endif"			return T_ENDIF; | ||||||
|  | "endmenu"		return T_ENDMENU; | ||||||
|  | "help"			return T_HELP; | ||||||
|  | "hex"			return T_HEX; | ||||||
|  | "if"			return T_IF; | ||||||
|  | "imply"			return T_IMPLY; | ||||||
|  | "int"			return T_INT; | ||||||
|  | "mainmenu"		return T_MAINMENU; | ||||||
|  | "menu"			return T_MENU; | ||||||
|  | "menuconfig"		return T_MENUCONFIG; | ||||||
|  | "modules"		return T_MODULES; | ||||||
|  | "on"			return T_ON; | ||||||
|  | "optional"		return T_OPTIONAL; | ||||||
|  | "prompt"		return T_PROMPT; | ||||||
|  | "range"			return T_RANGE; | ||||||
|  | "select"		return T_SELECT; | ||||||
|  | "source"		return T_SOURCE; | ||||||
|  | "string"		return T_STRING; | ||||||
|  | "tristate"		return T_TRISTATE; | ||||||
|  | "visible"		return T_VISIBLE; | ||||||
|  | "||"			return T_OR; | ||||||
|  | "&&"			return T_AND; | ||||||
|  | "="			return T_EQUAL; | ||||||
|  | "!="			return T_UNEQUAL; | ||||||
|  | "<"			return T_LESS; | ||||||
|  | "<="			return T_LESS_EQUAL; | ||||||
|  | ">"			return T_GREATER; | ||||||
|  | ">="			return T_GREATER_EQUAL; | ||||||
|  | "!"			return T_NOT; | ||||||
|  | "("			return T_OPEN_PAREN; | ||||||
|  | ")"			return T_CLOSE_PAREN; | ||||||
|  | ":="			return T_COLON_EQUAL; | ||||||
|  | "+="			return T_PLUS_EQUAL; | ||||||
|  | \"|\'			{ | ||||||
|  | 				str = yytext[0]; | ||||||
|  | 				new_string(); | ||||||
|  | 				BEGIN(STRING); | ||||||
|  | 			} | ||||||
|  | {n}+			{ | ||||||
|  | 				alloc_string(yytext, yyleng); | ||||||
|  | 				yylval.string = text; | ||||||
|  | 				return T_WORD; | ||||||
|  | 			} | ||||||
|  | ({n}|$)+		{ | ||||||
|  | 				/* this token includes at least one '$' */ | ||||||
|  | 				yylval.string = expand_token(yytext, yyleng); | ||||||
|  | 				if (strlen(yylval.string)) | ||||||
|  | 					return T_WORD; | ||||||
|  | 				free(yylval.string); | ||||||
|  | 			} | ||||||
|  | .			warn_ignored_character(*yytext); | ||||||
|  |  | ||||||
|  | <ASSIGN_VAL>{ | ||||||
|  | 	[^[:blank:]\n]+.*	{ | ||||||
|  | 		alloc_string(yytext, yyleng); | ||||||
|  | 		yylval.string = text; | ||||||
|  | 		return T_ASSIGN_VAL; | ||||||
|  | 	} | ||||||
|  | 	\n	{ BEGIN(INITIAL); return T_EOL; } | ||||||
|  | 	. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | <STRING>{ | ||||||
|  | 	"$".*	append_expanded_string(yytext); | ||||||
|  | 	[^$'"\\\n]+	{ | ||||||
|  | 		append_string(yytext, yyleng); | ||||||
|  | 	} | ||||||
|  | 	\\.?	{ | ||||||
|  | 		append_string(yytext + 1, yyleng - 1); | ||||||
|  | 	} | ||||||
|  | 	\'|\"	{ | ||||||
|  | 		if (str == yytext[0]) { | ||||||
|  | 			BEGIN(INITIAL); | ||||||
|  | 			yylval.string = text; | ||||||
|  | 			return T_WORD_QUOTE; | ||||||
|  | 		} else | ||||||
|  | 			append_string(yytext, 1); | ||||||
|  | 	} | ||||||
|  | 	\n	{ | ||||||
|  | 		fprintf(stderr, | ||||||
|  | 			"%s:%d:warning: multi-line strings not supported\n", | ||||||
|  | 			zconf_curname(), zconf_lineno()); | ||||||
|  | 		unput('\n'); | ||||||
|  | 		BEGIN(INITIAL); | ||||||
|  | 		yylval.string = text; | ||||||
|  | 		return T_WORD_QUOTE; | ||||||
|  | 	} | ||||||
|  | 	<<EOF>>	{ | ||||||
|  | 		BEGIN(INITIAL); | ||||||
|  | 		yylval.string = text; | ||||||
|  | 		return T_WORD_QUOTE; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | <HELP>{ | ||||||
|  | 	[ \t]+	{ | ||||||
|  | 		ts = 0; | ||||||
|  | 		for (i = 0; i < yyleng; i++) { | ||||||
|  | 			if (yytext[i] == '\t') | ||||||
|  | 				ts = (ts & ~7) + 8; | ||||||
|  | 			else | ||||||
|  | 				ts++; | ||||||
|  | 		} | ||||||
|  | 		last_ts = ts; | ||||||
|  | 		if (first_ts) { | ||||||
|  | 			if (ts < first_ts) { | ||||||
|  | 				zconf_endhelp(); | ||||||
|  | 				return T_HELPTEXT; | ||||||
|  | 			} | ||||||
|  | 			ts -= first_ts; | ||||||
|  | 			while (ts > 8) { | ||||||
|  | 				append_string("        ", 8); | ||||||
|  | 				ts -= 8; | ||||||
|  | 			} | ||||||
|  | 			append_string("        ", ts); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	[ \t]*\n/[^ \t\n] { | ||||||
|  | 		zconf_endhelp(); | ||||||
|  | 		return T_HELPTEXT; | ||||||
|  | 	} | ||||||
|  | 	[ \t]*\n	{ | ||||||
|  | 		append_string("\n", 1); | ||||||
|  | 	} | ||||||
|  | 	[^ \t\n].* { | ||||||
|  | 		while (yyleng) { | ||||||
|  | 			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) | ||||||
|  | 				break; | ||||||
|  | 			yyleng--; | ||||||
|  | 		} | ||||||
|  | 		append_string(yytext, yyleng); | ||||||
|  | 		if (!first_ts) | ||||||
|  | 			first_ts = last_ts; | ||||||
|  | 	} | ||||||
|  | 	<<EOF>>	{ | ||||||
|  | 		zconf_endhelp(); | ||||||
|  | 		return T_HELPTEXT; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | <<EOF>>	{ | ||||||
|  | 	BEGIN(INITIAL); | ||||||
|  |  | ||||||
|  | 	if (prev_token != T_EOL && prev_token != T_HELPTEXT) | ||||||
|  | 		fprintf(stderr, "%s:%d:warning: no new line at end of file\n", | ||||||
|  | 			current_file->name, yylineno); | ||||||
|  |  | ||||||
|  | 	if (current_file) { | ||||||
|  | 		zconf_endfile(); | ||||||
|  | 		return T_EOL; | ||||||
|  | 	} | ||||||
|  | 	fclose(yyin); | ||||||
|  | 	yyterminate(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | %% | ||||||
|  |  | ||||||
|  | /* second stage lexer */ | ||||||
|  | int yylex(void) | ||||||
|  | { | ||||||
|  | 	int token; | ||||||
|  |  | ||||||
|  | repeat: | ||||||
|  | 	token = yylex1(); | ||||||
|  |  | ||||||
|  | 	if (prev_token == T_EOL || prev_token == T_HELPTEXT) { | ||||||
|  | 		if (token == T_EOL) { | ||||||
|  | 			/* Do not pass unneeded T_EOL to the parser. */ | ||||||
|  | 			goto repeat; | ||||||
|  | 		} else { | ||||||
|  | 			/* | ||||||
|  | 			 * For the parser, update file/lineno at the first token | ||||||
|  | 			 * of each statement. Generally, \n is a statement | ||||||
|  | 			 * terminator in Kconfig, but it is not always true | ||||||
|  | 			 * because \n could be escaped by a backslash. | ||||||
|  | 			 */ | ||||||
|  | 			current_pos.file = current_file; | ||||||
|  | 			current_pos.lineno = yylineno; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (prev_prev_token == T_EOL && prev_token == T_WORD && | ||||||
|  | 	    (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL)) | ||||||
|  | 		BEGIN(ASSIGN_VAL); | ||||||
|  |  | ||||||
|  | 	prev_prev_token = prev_token; | ||||||
|  | 	prev_token = token; | ||||||
|  |  | ||||||
|  | 	return token; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *expand_token(const char *in, size_t n) | ||||||
|  | { | ||||||
|  | 	char *out; | ||||||
|  | 	int c; | ||||||
|  | 	char c2; | ||||||
|  | 	const char *rest, *end; | ||||||
|  |  | ||||||
|  | 	new_string(); | ||||||
|  | 	append_string(in, n); | ||||||
|  |  | ||||||
|  | 	/* get the whole line because we do not know the end of token. */ | ||||||
|  | 	while ((c = input()) != EOF) { | ||||||
|  | 		if (c == '\n') { | ||||||
|  | 			unput(c); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		c2 = c; | ||||||
|  | 		append_string(&c2, 1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rest = text; | ||||||
|  | 	out = expand_one_token(&rest); | ||||||
|  |  | ||||||
|  | 	/* push back unused characters to the input stream */ | ||||||
|  | 	end = rest + strlen(rest); | ||||||
|  | 	while (end > rest) | ||||||
|  | 		unput(*--end); | ||||||
|  |  | ||||||
|  | 	free(text); | ||||||
|  |  | ||||||
|  | 	return out; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void append_expanded_string(const char *str) | ||||||
|  | { | ||||||
|  | 	const char *end; | ||||||
|  | 	char *res; | ||||||
|  |  | ||||||
|  | 	str++; | ||||||
|  |  | ||||||
|  | 	res = expand_dollar(&str); | ||||||
|  |  | ||||||
|  | 	/* push back unused characters to the input stream */ | ||||||
|  | 	end = str + strlen(str); | ||||||
|  | 	while (end > str) | ||||||
|  | 		unput(*--end); | ||||||
|  |  | ||||||
|  | 	append_string(res, strlen(res)); | ||||||
|  |  | ||||||
|  | 	free(res); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zconf_starthelp(void) | ||||||
|  | { | ||||||
|  | 	new_string(); | ||||||
|  | 	last_ts = first_ts = 0; | ||||||
|  | 	BEGIN(HELP); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void zconf_endhelp(void) | ||||||
|  | { | ||||||
|  | 	yylval.string = text; | ||||||
|  | 	BEGIN(INITIAL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Try to open specified file with following names: | ||||||
|  |  * ./name | ||||||
|  |  * $(srctree)/name | ||||||
|  |  * The latter is used when srctree is separate from objtree | ||||||
|  |  * when compiling the kernel. | ||||||
|  |  * Return NULL if file is not found. | ||||||
|  |  */ | ||||||
|  | FILE *zconf_fopen(const char *name) | ||||||
|  | { | ||||||
|  | 	char *env, fullname[PATH_MAX+1]; | ||||||
|  | 	FILE *f; | ||||||
|  |  | ||||||
|  | 	f = fopen(name, "r"); | ||||||
|  | 	if (!f && name != NULL && name[0] != '/') { | ||||||
|  | 		env = getenv(SRCTREE); | ||||||
|  | 		if (env) { | ||||||
|  | 			snprintf(fullname, sizeof(fullname), | ||||||
|  | 				 "%s/%s", env, name); | ||||||
|  | 			f = fopen(fullname, "r"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return f; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zconf_initscan(const char *name) | ||||||
|  | { | ||||||
|  | 	yyin = zconf_fopen(name); | ||||||
|  | 	if (!yyin) { | ||||||
|  | 		fprintf(stderr, "can't find file %s\n", name); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	current_buf = xmalloc(sizeof(*current_buf)); | ||||||
|  | 	memset(current_buf, 0, sizeof(*current_buf)); | ||||||
|  |  | ||||||
|  | 	current_file = file_lookup(name); | ||||||
|  | 	yylineno = 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zconf_nextfile(const char *name) | ||||||
|  | { | ||||||
|  | 	struct file *iter; | ||||||
|  | 	struct file *file = file_lookup(name); | ||||||
|  | 	struct buffer *buf = xmalloc(sizeof(*buf)); | ||||||
|  | 	memset(buf, 0, sizeof(*buf)); | ||||||
|  |  | ||||||
|  | 	current_buf->state = YY_CURRENT_BUFFER; | ||||||
|  | 	yyin = zconf_fopen(file->name); | ||||||
|  | 	if (!yyin) { | ||||||
|  | 		fprintf(stderr, "%s:%d: can't open file \"%s\"\n", | ||||||
|  | 			zconf_curname(), zconf_lineno(), file->name); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); | ||||||
|  | 	buf->parent = current_buf; | ||||||
|  | 	current_buf = buf; | ||||||
|  |  | ||||||
|  | 	current_file->lineno = yylineno; | ||||||
|  | 	file->parent = current_file; | ||||||
|  |  | ||||||
|  | 	for (iter = current_file; iter; iter = iter->parent) { | ||||||
|  | 		if (!strcmp(iter->name, file->name)) { | ||||||
|  | 			fprintf(stderr, | ||||||
|  | 				"Recursive inclusion detected.\n" | ||||||
|  | 				"Inclusion path:\n" | ||||||
|  | 				"  current file : %s\n", file->name); | ||||||
|  | 			iter = file; | ||||||
|  | 			do { | ||||||
|  | 				iter = iter->parent; | ||||||
|  | 				fprintf(stderr, "  included from: %s:%d\n", | ||||||
|  | 					iter->name, iter->lineno - 1); | ||||||
|  | 			} while (strcmp(iter->name, file->name)); | ||||||
|  | 			exit(1); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	yylineno = 1; | ||||||
|  | 	current_file = file; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zconf_nextfiles(const char *wildcard) | ||||||
|  | { | ||||||
|  | 	glob_t g; | ||||||
|  | 	char **w; | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	if (glob(wildcard, 0, NULL, &g) != 0) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	if (g.gl_pathv == NULL) { | ||||||
|  | 		globfree(&g); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* working through files backwards, since | ||||||
|  | 	 * we're first pushing them on a stack | ||||||
|  | 	 * before actually handling them. | ||||||
|  | 	 */ | ||||||
|  | 	for (i = g.gl_pathc; i > 0; i--) { | ||||||
|  | 		w = &g.gl_pathv[i - 1]; | ||||||
|  | 		zconf_nextfile(*w); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	globfree(&g); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void zconf_endfile(void) | ||||||
|  | { | ||||||
|  | 	struct buffer *parent; | ||||||
|  |  | ||||||
|  | 	current_file = current_file->parent; | ||||||
|  | 	if (current_file) | ||||||
|  | 		yylineno = current_file->lineno; | ||||||
|  |  | ||||||
|  | 	parent = current_buf->parent; | ||||||
|  | 	if (parent) { | ||||||
|  | 		fclose(yyin); | ||||||
|  | 		yy_delete_buffer(YY_CURRENT_BUFFER); | ||||||
|  | 		yy_switch_to_buffer(parent->state); | ||||||
|  | 	} | ||||||
|  | 	free(current_buf); | ||||||
|  | 	current_buf = parent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int zconf_lineno(void) | ||||||
|  | { | ||||||
|  | 	return current_pos.lineno; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const char *zconf_curname(void) | ||||||
|  | { | ||||||
|  | 	return current_pos.file ? current_pos.file->name : "<none>"; | ||||||
|  | } | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| #ifndef LIST_H | #ifndef LIST_H | ||||||
| #define LIST_H | #define LIST_H | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,41 +1,25 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef LKC_H | #ifndef LKC_H | ||||||
| #define LKC_H | #define LKC_H | ||||||
|  |  | ||||||
| #include "expr.h" | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
| #ifndef KBUILD_NO_NLS | #include "expr.h" | ||||||
| # include <libintl.h> |  | ||||||
| #else |  | ||||||
| static inline const char *gettext(const char *txt) { return txt; } |  | ||||||
| static inline void textdomain(const char *domainname) {} |  | ||||||
| static inline void bindtextdomain(const char *name, const char *dir) {} |  | ||||||
| static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| 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" | ||||||
|  |  | ||||||
| #ifndef PACKAGE |  | ||||||
| #define PACKAGE "linux" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #define LOCALEDIR "/usr/share/locale" |  | ||||||
|  |  | ||||||
| #define _(text) gettext(text) |  | ||||||
| #define N_(text) (text) |  | ||||||
|  |  | ||||||
| #ifndef CONFIG_ | #ifndef CONFIG_ | ||||||
| #define CONFIG_ "CONFIG_" | #define CONFIG_ "CONFIG_" | ||||||
| #endif | #endif | ||||||
| @@ -46,33 +30,7 @@ static inline const char *CONFIG_prefix(void) | |||||||
| #undef CONFIG_ | #undef CONFIG_ | ||||||
| #define CONFIG_ CONFIG_prefix() | #define CONFIG_ CONFIG_prefix() | ||||||
|  |  | ||||||
| #define TF_COMMAND	0x0001 | extern int yylineno; | ||||||
| #define TF_PARAM	0x0002 |  | ||||||
| #define TF_OPTION	0x0004 |  | ||||||
|  |  | ||||||
| enum conf_def_mode { |  | ||||||
| 	def_default, |  | ||||||
| 	def_yes, |  | ||||||
| 	def_mod, |  | ||||||
| 	def_no, |  | ||||||
| 	def_random |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #define T_OPT_MODULES		1 |  | ||||||
| #define T_OPT_DEFCONFIG_LIST	2 |  | ||||||
| #define T_OPT_ENV		3 |  | ||||||
| #define T_OPT_ALLNOCONFIG_Y	4 |  | ||||||
|  |  | ||||||
| struct kconf_id { |  | ||||||
| 	int name; |  | ||||||
| 	int token; |  | ||||||
| 	unsigned int flags; |  | ||||||
| 	enum symbol_type stype; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| extern int zconfdebug; |  | ||||||
|  |  | ||||||
| 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); | ||||||
| @@ -87,18 +45,8 @@ extern int kconfig_warnings; | |||||||
|  |  | ||||||
| /* confdata.c */ | /* confdata.c */ | ||||||
| const char *conf_get_configname(void); | const char *conf_get_configname(void); | ||||||
| const char *conf_get_autoconfig_name(void); |  | ||||||
| char *conf_get_default_confname(void); |  | ||||||
| void sym_set_change_count(int count); |  | ||||||
| void sym_add_change_count(int count); |  | ||||||
| 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) | ||||||
| { | { | ||||||
| @@ -108,28 +56,16 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) | |||||||
| 		fprintf(stderr, "Error in writing or end of file.\n"); | 		fprintf(stderr, "Error in writing or end of file.\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* menu.c */ |  | ||||||
| void _menu_init(void); |  | ||||||
| void menu_warn(struct menu *menu, const char *fmt, ...); |  | ||||||
| struct menu *menu_add_menu(void); |  | ||||||
| void menu_end_menu(void); |  | ||||||
| void menu_add_entry(struct symbol *sym); |  | ||||||
| void menu_end_entry(void); |  | ||||||
| void menu_add_dep(struct expr *dep); |  | ||||||
| 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); |  | ||||||
| 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_option(int token, char *arg); |  | ||||||
| void menu_finalize(struct menu *parent); |  | ||||||
| void menu_set_type(int type); |  | ||||||
|  |  | ||||||
| /* util.c */ | /* util.c */ | ||||||
| struct file *file_lookup(const char *name); | struct file *file_lookup(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); | ||||||
|  | char *xstrndup(const char *s, size_t n); | ||||||
|  |  | ||||||
|  | /* lexer.l */ | ||||||
|  | int yylex(void); | ||||||
|  |  | ||||||
| struct gstr { | struct gstr { | ||||||
| 	size_t len; | 	size_t len; | ||||||
| @@ -141,25 +77,45 @@ 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, ...); | ||||||
| const char *str_get(struct gstr *gs); | const char *str_get(struct gstr *gs); | ||||||
|  |  | ||||||
| /* symbol.c */ | /* menu.c */ | ||||||
| extern struct expr *sym_env_list; | void _menu_init(void); | ||||||
|  | void menu_warn(struct menu *menu, const char *fmt, ...); | ||||||
|  | struct menu *menu_add_menu(void); | ||||||
|  | void menu_end_menu(void); | ||||||
|  | void menu_add_entry(struct symbol *sym); | ||||||
|  | void menu_add_dep(struct expr *dep); | ||||||
|  | void menu_add_visibility(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_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); | ||||||
|  | void menu_finalize(struct menu *parent); | ||||||
|  | void menu_set_type(int type); | ||||||
|  |  | ||||||
| void sym_init(void); | extern struct menu rootmenu; | ||||||
|  |  | ||||||
|  | bool menu_is_empty(struct menu *menu); | ||||||
|  | bool menu_is_visible(struct menu *menu); | ||||||
|  | bool menu_has_prompt(struct menu *menu); | ||||||
|  | const char *menu_get_prompt(struct menu *menu); | ||||||
|  | struct menu *menu_get_root_menu(struct menu *menu); | ||||||
|  | struct menu *menu_get_parent_menu(struct menu *menu); | ||||||
|  | bool menu_has_help(struct menu *menu); | ||||||
|  | const char *menu_get_help(struct menu *menu); | ||||||
|  | struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); | ||||||
|  | void menu_get_ext_help(struct menu *menu, struct gstr *help); | ||||||
|  |  | ||||||
|  | /* symbol.c */ | ||||||
| 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); | ||||||
|  | struct property *sym_get_range_prop(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); | ||||||
| struct property *prop_alloc(enum prop_type type, struct symbol *sym); |  | ||||||
| struct symbol *prop_get_symbol(struct property *prop); | struct symbol *prop_get_symbol(struct property *prop); | ||||||
| struct property *sym_get_env_prop(struct symbol *sym); |  | ||||||
|  |  | ||||||
| static inline tristate sym_get_tristate_value(struct symbol *sym) | static inline tristate sym_get_tristate_value(struct symbol *sym) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -1,57 +1,52 @@ | |||||||
|  | /* 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(int overwrite); | ||||||
| P(conf_get_changed,bool,(void)); | void conf_set_changed(bool val); | ||||||
| P(conf_set_changed_callback, void,(void (*fn)(void))); | bool conf_get_changed(void); | ||||||
| P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap))); | void conf_set_changed_callback(void (*fn)(void)); | ||||||
|  | void conf_set_message_callback(void (*fn)(const char *s)); | ||||||
| /* menu.c */ |  | ||||||
| P(rootmenu,struct menu,); |  | ||||||
|  |  | ||||||
| P(menu_is_empty, bool, (struct menu *menu)); |  | ||||||
| P(menu_is_visible, bool, (struct menu *menu)); |  | ||||||
| P(menu_has_prompt, bool, (struct menu *menu)); |  | ||||||
| P(menu_get_prompt,const char *,(struct menu *menu)); |  | ||||||
| P(menu_get_root_menu,struct menu *,(struct menu *menu)); |  | ||||||
| P(menu_get_parent_menu,struct menu *,(struct menu *menu)); |  | ||||||
| P(menu_has_help,bool,(struct menu *menu)); |  | ||||||
| P(menu_get_help,const char *,(struct menu *menu)); |  | ||||||
| P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head |  | ||||||
| 			 *head)); |  | ||||||
| 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)); | const char * sym_escape_string_value(const char *in); | ||||||
| P(sym_escape_string_value, const char *,(const char *in)); | struct symbol ** sym_re_search(const char *pattern); | ||||||
| P(sym_re_search,struct symbol **,(const char *pattern)); | const char * sym_type_name(enum symbol_type type); | ||||||
| P(sym_type_name,const char *,(enum symbol_type type)); | void sym_calc_value(struct symbol *sym); | ||||||
| P(sym_calc_value,void,(struct symbol *sym)); | enum symbol_type sym_get_type(struct symbol *sym); | ||||||
| P(sym_get_type,enum symbol_type,(struct symbol *sym)); | bool sym_tristate_within_range(struct symbol *sym,tristate tri); | ||||||
| P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); | bool sym_set_tristate_value(struct symbol *sym,tristate tri); | ||||||
| P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); | tristate sym_toggle_tristate_value(struct symbol *sym); | ||||||
| P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); | bool sym_string_valid(struct symbol *sym, const char *newval); | ||||||
| P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); | bool sym_string_within_range(struct symbol *sym, const char *str); | ||||||
| P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); | bool sym_set_string_value(struct symbol *sym, const char *newval); | ||||||
| P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); | bool sym_is_changeable(struct symbol *sym); | ||||||
| P(sym_is_changable,bool,(struct symbol *sym)); | struct property * sym_get_choice_prop(struct symbol *sym); | ||||||
| P(sym_get_choice_prop,struct property *,(struct symbol *sym)); | const char * sym_get_string_value(struct symbol *sym); | ||||||
| P(sym_get_default_prop,struct property *,(struct symbol *sym)); |  | ||||||
| P(sym_get_string_value,const char *,(struct symbol *sym)); |  | ||||||
|  |  | ||||||
| P(prop_get_type_name,const char *,(enum prop_type type)); | const char * prop_get_type_name(enum prop_type type); | ||||||
|  |  | ||||||
|  | /* preprocess.c */ | ||||||
|  | enum variable_flavor { | ||||||
|  | 	VAR_SIMPLE, | ||||||
|  | 	VAR_RECURSIVE, | ||||||
|  | 	VAR_APPEND, | ||||||
|  | }; | ||||||
|  | void env_write_dep(FILE *f, const char *auto_conf_name); | ||||||
|  | void variable_add(const char *name, const char *value, | ||||||
|  | 		  enum variable_flavor flavor); | ||||||
|  | void variable_all_del(void); | ||||||
|  | char *expand_dollar(const char **str); | ||||||
|  | char *expand_one_token(const char **str); | ||||||
|  |  | ||||||
| /* 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)); |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								util/kconfig/lxdialog/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								util/kconfig/lxdialog/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +0,0 @@ | |||||||
| # |  | ||||||
| # Generated files |  | ||||||
| # |  | ||||||
| lxdialog |  | ||||||
| @@ -1,91 +0,0 @@ | |||||||
| #!/usr/bin/env sh |  | ||||||
| # Check ncurses compatibility |  | ||||||
|  |  | ||||||
| # What library to link |  | ||||||
| ldflags() |  | ||||||
| { |  | ||||||
| 	pkg-config --libs ncursesw 2>/dev/null && exit |  | ||||||
| 	pkg-config --libs ncurses 2>/dev/null && exit |  | ||||||
| 	for ext in so a dll.a dylib ; do |  | ||||||
| 		for lib in ncursesw ncurses curses pdcursesw pdcurses; do |  | ||||||
| 			$cc -print-file-name=lib${lib}.${ext} | grep -q / |  | ||||||
| 			if [ $? -eq 0 ]; then |  | ||||||
| 				echo "-l${lib}" |  | ||||||
| 				exit |  | ||||||
| 			fi |  | ||||||
| 		done |  | ||||||
| 	done |  | ||||||
| 	exit 1 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # Where is ncurses.h? |  | ||||||
| ccflags() |  | ||||||
| { |  | ||||||
| 	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 |  | ||||||
| 		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' |  | ||||||
| 	elif [ -f /usr/include/ncurses/curses.h ]; then |  | ||||||
| 		echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"' |  | ||||||
| 	elif [ -f /usr/include/ncurses.h ]; then |  | ||||||
| 		echo '-DCURSES_LOC="<ncurses.h>"' |  | ||||||
| 	else |  | ||||||
| 		echo '-DCURSES_LOC="<curses.h>"' |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # Temp file, try to clean up after us |  | ||||||
| tmp=.lxdialog.tmp |  | ||||||
| trap "rm -f $tmp" 0 1 2 3 15 |  | ||||||
|  |  | ||||||
| # Check if we can link to ncurses |  | ||||||
| check() { |  | ||||||
|         $cc -x c - -o $tmp 2>/dev/null <<'EOF' |  | ||||||
| #include CURSES_LOC |  | ||||||
| main() {} |  | ||||||
| EOF |  | ||||||
| 	if [ $? != 0 ]; then |  | ||||||
| 	    echo " *** Unable to find the ncurses libraries or the"       1>&2 |  | ||||||
| 	    echo " *** required header files."                            1>&2 |  | ||||||
| 	    echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 |  | ||||||
| 	    echo " *** "                                                  1>&2 |  | ||||||
| 	    echo " *** Install ncurses (ncurses-devel) and try again."    1>&2 |  | ||||||
| 	    echo " *** "                                                  1>&2 |  | ||||||
| 	    exit 1 |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| usage() { |  | ||||||
| 	printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if [ $# -eq 0 ]; then |  | ||||||
| 	usage |  | ||||||
| 	exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| cc="" |  | ||||||
| case "$1" in |  | ||||||
| 	"-check") |  | ||||||
| 		shift |  | ||||||
| 		cc="$@" |  | ||||||
| 		check |  | ||||||
| 		;; |  | ||||||
| 	"-ccflags") |  | ||||||
| 		ccflags |  | ||||||
| 		;; |  | ||||||
| 	"-ldflags") |  | ||||||
| 		shift |  | ||||||
| 		cc="$@" |  | ||||||
| 		ldflags |  | ||||||
| 		;; |  | ||||||
| 	"*") |  | ||||||
| 		usage |  | ||||||
| 		exit 1 |  | ||||||
| 		;; |  | ||||||
| esac |  | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
| /* | /* | ||||||
|  *  checklist.c -- implements the checklist box |  *  checklist.c -- implements the checklist box | ||||||
|  * |  * | ||||||
| @@ -5,20 +6,6 @@ | |||||||
|  *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension |  *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension | ||||||
|  *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two |  *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two | ||||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "dialog.h" | #include "dialog.h" | ||||||
| @@ -103,8 +90,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | |||||||
| 	int x = width / 2 - 11; | 	int x = width / 2 - 11; | ||||||
| 	int y = height - 2; | 	int y = height - 2; | ||||||
|  |  | ||||||
| 	print_button(dialog, gettext("Select"), y, x, selected == 0); | 	print_button(dialog, "Select", y, x, selected == 0); | ||||||
| 	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); | 	print_button(dialog, " Help ", y, x + 14, selected == 1); | ||||||
|  |  | ||||||
| 	wmove(dialog, y, x + 1 + 14 * selected); | 	wmove(dialog, y, x + 1 + 14 * selected); | ||||||
| 	wrefresh(dialog); | 	wrefresh(dialog); | ||||||
|   | |||||||
| @@ -1,21 +1,8 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0+ */ | ||||||
| /* | /* | ||||||
|  *  dialog.h -- common declarations for all dialog modules |  *  dialog.h -- common declarations for all dialog modules | ||||||
|  * |  * | ||||||
|  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| @@ -26,16 +13,10 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  |  | ||||||
| #ifndef KBUILD_NO_NLS |  | ||||||
| # include <libintl.h> |  | ||||||
| #else |  | ||||||
| # define gettext(Msgid) ((const char *) (Msgid)) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifdef __sun__ | #ifdef __sun__ | ||||||
| #define CURS_MACROS | #define CURS_MACROS | ||||||
| #endif | #endif | ||||||
| #include CURSES_LOC | #include <ncurses.h> | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Colors in ncurses 1.9.9e do not work properly since foreground and |  * Colors in ncurses 1.9.9e do not work properly since foreground and | ||||||
|   | |||||||
| @@ -1,22 +1,9 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
| /* | /* | ||||||
|  *  inputbox.c -- implements the input box |  *  inputbox.c -- implements the input box | ||||||
|  * |  * | ||||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "dialog.h" | #include "dialog.h" | ||||||
| @@ -31,8 +18,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | |||||||
| 	int x = width / 2 - 11; | 	int x = width / 2 - 11; | ||||||
| 	int y = height - 2; | 	int y = height - 2; | ||||||
|  |  | ||||||
| 	print_button(dialog, gettext("  Ok  "), y, x, selected == 0); | 	print_button(dialog, "  Ok  ", y, x, selected == 0); | ||||||
| 	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); | 	print_button(dialog, " Help ", y, x + 14, selected == 1); | ||||||
|  |  | ||||||
| 	wmove(dialog, y, x + 1 + 14 * selected); | 	wmove(dialog, y, x + 1 + 14 * selected); | ||||||
| 	wrefresh(dialog); | 	wrefresh(dialog); | ||||||
| @@ -126,7 +113,8 @@ do_resize: | |||||||
| 			case KEY_DOWN: | 			case KEY_DOWN: | ||||||
| 				break; | 				break; | ||||||
| 			case KEY_BACKSPACE: | 			case KEY_BACKSPACE: | ||||||
| 			case 127: | 			case 8:   /* ^H */ | ||||||
|  | 			case 127: /* ^? */ | ||||||
| 				if (pos) { | 				if (pos) { | ||||||
| 					wattrset(dialog, dlg.inputbox.atr); | 					wattrset(dialog, dlg.inputbox.atr); | ||||||
| 					if (input_x == 0) { | 					if (input_x == 0) { | ||||||
|   | |||||||
| @@ -1,22 +1,9 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
| /* | /* | ||||||
|  *  menubox.c -- implements the menu box |  *  menubox.c -- implements the menu box | ||||||
|  * |  * | ||||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) |  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -157,11 +144,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected) | |||||||
| 	int x = width / 2 - 28; | 	int x = width / 2 - 28; | ||||||
| 	int y = height - 2; | 	int y = height - 2; | ||||||
|  |  | ||||||
| 	print_button(win, gettext("Select"), y, x, selected == 0); | 	print_button(win, "Select", y, x, selected == 0); | ||||||
| 	print_button(win, gettext(" Exit "), y, x + 12, selected == 1); | 	print_button(win, " Exit ", y, x + 12, selected == 1); | ||||||
| 	print_button(win, gettext(" Help "), y, x + 24, selected == 2); | 	print_button(win, " Help ", y, x + 24, selected == 2); | ||||||
| 	print_button(win, gettext(" Save "), y, x + 36, selected == 3); | 	print_button(win, " Save ", y, x + 36, selected == 3); | ||||||
| 	print_button(win, gettext(" Load "), y, x + 48, selected == 4); | 	print_button(win, " Load ", y, x + 48, selected == 4); | ||||||
|  |  | ||||||
| 	wmove(win, y, x + 1 + 12 * selected); | 	wmove(win, y, x + 1 + 12 * selected); | ||||||
| 	wrefresh(win); | 	wrefresh(win); | ||||||
|   | |||||||
| @@ -1,22 +1,9 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
| /* | /* | ||||||
|  *  textbox.c -- implements the text box |  *  textbox.c -- implements the text box | ||||||
|  * |  * | ||||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "dialog.h" | #include "dialog.h" | ||||||
| @@ -129,7 +116,7 @@ do_resize: | |||||||
|  |  | ||||||
| 	print_title(dialog, title, width); | 	print_title(dialog, title, width); | ||||||
|  |  | ||||||
| 	print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); | 	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE); | ||||||
| 	wnoutrefresh(dialog); | 	wnoutrefresh(dialog); | ||||||
| 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */ | 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,22 +1,9 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
| /* | /* | ||||||
|  *  util.c |  *  util.c | ||||||
|  * |  * | ||||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| @@ -376,7 +363,7 @@ void print_title(WINDOW *dialog, const char *title, int width) | |||||||
| /* | /* | ||||||
|  * Print a string of text in a window, automatically wrap around to the |  * Print a string of text in a window, automatically wrap around to the | ||||||
|  * next line if the string is too long to fit on one line. Newline |  * next line if the string is too long to fit on one line. Newline | ||||||
|  * characters '\n' are propperly processed.  We start on a new line |  * characters '\n' are properly processed.  We start on a new line | ||||||
|  * if there is no room for at least 4 nonblanks following a double-space. |  * if there is no room for at least 4 nonblanks following a double-space. | ||||||
|  */ |  */ | ||||||
| void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) | void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) | ||||||
| @@ -554,7 +541,7 @@ int first_alpha(const char *string, const char *exempt) | |||||||
|  * lxdialog suggest <ESC> <ESC> which is correctly translated to two |  * lxdialog suggest <ESC> <ESC> which is correctly translated to two | ||||||
|  * times esc. But then we need to ignore the second esc to avoid stepping |  * times esc. But then we need to ignore the second esc to avoid stepping | ||||||
|  * out one menu too much. Filter away all escaped key sequences since |  * out one menu too much. Filter away all escaped key sequences since | ||||||
|  * keypad(FALSE) turn off ncurses support for escape sequences - and thats |  * keypad(FALSE) turn off ncurses support for escape sequences - and that's | ||||||
|  * needed to make notimeout() do as expected. |  * needed to make notimeout() do as expected. | ||||||
|  */ |  */ | ||||||
| int on_key_esc(WINDOW *win) | int on_key_esc(WINDOW *win) | ||||||
|   | |||||||
| @@ -1,22 +1,9 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0+ | ||||||
| /* | /* | ||||||
|  *  yesno.c -- implements the yes/no box |  *  yesno.c -- implements the yes/no box | ||||||
|  * |  * | ||||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||||
|  * |  | ||||||
|  *  This program is free software; you can redistribute it and/or |  | ||||||
|  *  modify it under the terms of the GNU General Public License |  | ||||||
|  *  as published by the Free Software Foundation; either version 2 |  | ||||||
|  *  of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  This program is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with this program; if not, write to the Free Software |  | ||||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include "dialog.h" | #include "dialog.h" | ||||||
| @@ -29,8 +16,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | |||||||
| 	int x = width / 2 - 10; | 	int x = width / 2 - 10; | ||||||
| 	int y = height - 2; | 	int y = height - 2; | ||||||
|  |  | ||||||
| 	print_button(dialog, gettext(" Yes "), y, x, selected == 0); | 	print_button(dialog, " Yes ", y, x, selected == 0); | ||||||
| 	print_button(dialog, gettext("  No  "), y, x + 13, selected == 1); | 	print_button(dialog, "  No  ", y, x + 13, selected == 1); | ||||||
|  |  | ||||||
| 	wmove(dialog, y, x + 1 + 13 * selected); | 	wmove(dialog, y, x + 1 + 13 * selected); | ||||||
| 	wrefresh(dialog); | 	wrefresh(dialog); | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								util/kconfig/mconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										52
									
								
								util/kconfig/mconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # SPDX-License-Identifier: GPL-2.0 | ||||||
|  |  | ||||||
|  | PKG="ncursesw" | ||||||
|  | PKG2="ncurses" | ||||||
|  |  | ||||||
|  | if [ -n "$(command -v pkg-config)" ]; then | ||||||
|  | 	if pkg-config --exists $PKG; then | ||||||
|  | 		echo cflags=\"$(pkg-config --cflags $PKG)\" | ||||||
|  | 		echo libs=\"$(pkg-config --libs $PKG)\" | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if pkg-config --exists $PKG2; then | ||||||
|  | 		echo cflags=\"$(pkg-config --cflags $PKG2)\" | ||||||
|  | 		echo libs=\"$(pkg-config --libs $PKG2)\" | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Check the default paths in case pkg-config is not installed. | ||||||
|  | # (Even if it is installed, some distributions such as openSUSE cannot | ||||||
|  | # find ncurses by pkg-config.) | ||||||
|  | if [ -f /usr/include/ncursesw/ncurses.h ]; then | ||||||
|  | 	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\" | ||||||
|  | 	echo libs=\"-lncursesw\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [ -f /usr/include/ncurses/ncurses.h ]; then | ||||||
|  | 	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\" | ||||||
|  | 	echo libs=\"-lncurses\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # As a final fallback before giving up, check if $HOSTCC knows of a default | ||||||
|  | # ncurses installation (e.g. from a vendor-specific sysroot). | ||||||
|  | if echo '#include <ncurses.h>' | ${HOSTCC} -E - >/dev/null 2>&1; then | ||||||
|  | 	echo cflags=\"-D_GNU_SOURCE\" | ||||||
|  | 	echo libs=\"-lncurses\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo >&2 "*" | ||||||
|  | echo >&2 "* Unable to find the ncurses package." | ||||||
|  | echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" | ||||||
|  | echo >&2 "* depending on your distribution)." | ||||||
|  | echo >&2 "*" | ||||||
|  | echo >&2 "* You may also need to install pkg-config to find the" | ||||||
|  | echo >&2 "* ncurses installed in a non-default location." | ||||||
|  | echo >&2 "*" | ||||||
|  | exit 1 | ||||||
| @@ -1,6 +1,6 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  * |  * | ||||||
|  * Introduced single menu mode (show all sub-menus in one large tree). |  * Introduced single menu mode (show all sub-menus in one large tree). | ||||||
|  * 2002-11-06 Petr Baudis <pasky@ucw.cz> |  * 2002-11-06 Petr Baudis <pasky@ucw.cz> | ||||||
| @@ -15,16 +15,18 @@ | |||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <strings.h> | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <locale.h> |  | ||||||
|  |  | ||||||
| #include "lkc.h" | #include "lkc.h" | ||||||
| #include "lxdialog/dialog.h" | #include "lxdialog/dialog.h" | ||||||
|  |  | ||||||
|  | #define JUMP_NB			9 | ||||||
|  |  | ||||||
| int kconfig_warnings = 0; | int kconfig_warnings = 0; | ||||||
|  |  | ||||||
| static const char mconf_readme[] = N_( | static const char mconf_readme[] = | ||||||
| "Overview\n" | "Overview\n" | ||||||
| "--------\n" | "--------\n" | ||||||
| "This interface lets you select features and parameters for the build.\n" | "This interface lets you select features and parameters for the build.\n" | ||||||
| @@ -173,37 +175,37 @@ static const char mconf_readme[] = N_( | |||||||
| " blackbg    => selects a color scheme with black background\n" | " blackbg    => selects a color scheme with black background\n" | ||||||
| " classic    => theme with blue background. The classic look\n" | " classic    => theme with blue background. The classic look\n" | ||||||
| " bluetitle  => an LCD friendly version of classic. (default)\n" | " bluetitle  => an LCD friendly version of classic. (default)\n" | ||||||
| "\n"), | "\n", | ||||||
| menu_instructions[] = N_( | menu_instructions[] = | ||||||
| 	"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.  " | ||||||
| 	"Pressing <Y> includes, <N> excludes, <M> modularizes features.  " | 	"Pressing <Y> includes, <N> excludes, <M> modularizes features.  " | ||||||
| 	"Press <Esc><Esc> to exit, <?> for Help, </> for Search.  " | 	"Press <Esc><Esc> to exit, <?> for Help, </> for Search.  " | ||||||
| 	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"), | 	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable", | ||||||
| radiolist_instructions[] = N_( | radiolist_instructions[] = | ||||||
| 	"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 " | ||||||
| 	"followed by the <SPACE BAR>. " | 	"followed by the <SPACE BAR>. " | ||||||
| 	"Press <?> for additional information about this option."), | 	"Press <?> for additional information about this option.", | ||||||
| inputbox_instructions_int[] = N_( | inputbox_instructions_int[] = | ||||||
| 	"Please enter a decimal value. " | 	"Please enter a decimal value. " | ||||||
| 	"Fractions will not be accepted.  " | 	"Fractions will not be accepted.  " | ||||||
| 	"Use the <TAB> key to move from the input field to the buttons below it."), | 	"Use the <TAB> key to move from the input field to the buttons below it.", | ||||||
| inputbox_instructions_hex[] = N_( | inputbox_instructions_hex[] = | ||||||
| 	"Please enter a hexadecimal value. " | 	"Please enter a hexadecimal value. " | ||||||
| 	"Use the <TAB> key to move from the input field to the buttons below it."), | 	"Use the <TAB> key to move from the input field to the buttons below it.", | ||||||
| inputbox_instructions_string[] = N_( | inputbox_instructions_string[] = | ||||||
| 	"Please enter a string value. " | 	"Please enter a string value. " | ||||||
| 	"Use the <TAB> key to move from the input field to the buttons below it."), | 	"Use the <TAB> key to move from the input field to the buttons below it.", | ||||||
| setmod_text[] = N_( | setmod_text[] = | ||||||
| 	"This feature depends on another which has been configured as a module.\n" | 	"This feature depends on another which has been configured as a module.\n" | ||||||
| 	"As a result, this feature will be built as a module."), | 	"As a result, this feature will be built as a module.", | ||||||
| load_config_text[] = N_( | load_config_text[] = | ||||||
| 	"Enter the name of the configuration file you wish to load.  " | 	"Enter the name of the configuration file you wish to load.  " | ||||||
| 	"Accept the name shown to restore the configuration you " | 	"Accept the name shown to restore the configuration you " | ||||||
| 	"last retrieved.  Leave blank to abort."), | 	"last retrieved.  Leave blank to abort.", | ||||||
| load_config_help[] = N_( | load_config_help[] = | ||||||
| 	"\n" | 	"\n" | ||||||
| 	"For various reasons, one may wish to keep several different\n" | 	"For various reasons, one may wish to keep several different\n" | ||||||
| 	"configurations available on a single machine.\n" | 	"configurations available on a single machine.\n" | ||||||
| @@ -213,11 +215,11 @@ load_config_help[] = N_( | |||||||
| 	"configuration.\n" | 	"configuration.\n" | ||||||
| 	"\n" | 	"\n" | ||||||
| 	"If you are uncertain, then you have probably never used alternate\n" | 	"If you are uncertain, then you have probably never used alternate\n" | ||||||
| 	"configuration files. You should therefore leave this blank to abort.\n"), | 	"configuration files. You should therefore leave this blank to abort.\n", | ||||||
| save_config_text[] = N_( | save_config_text[] = | ||||||
| 	"Enter a filename to which this configuration should be saved " | 	"Enter a filename to which this configuration should be saved " | ||||||
| 	"as an alternate.  Leave blank to abort."), | 	"as an alternate.  Leave blank to abort.", | ||||||
| save_config_help[] = N_( | save_config_help[] = | ||||||
| 	"\n" | 	"\n" | ||||||
| 	"For various reasons, one may wish to keep different configurations\n" | 	"For various reasons, one may wish to keep different configurations\n" | ||||||
| 	"available on a single machine.\n" | 	"available on a single machine.\n" | ||||||
| @@ -227,8 +229,8 @@ save_config_help[] = N_( | |||||||
| 	"configuration options you have selected at that time.\n" | 	"configuration options you have selected at that time.\n" | ||||||
| 	"\n" | 	"\n" | ||||||
| 	"If you are uncertain what all this means then you should probably\n" | 	"If you are uncertain what all this means then you should probably\n" | ||||||
| 	"leave this blank.\n"), | 	"leave this blank.\n", | ||||||
| search_help[] = N_( | search_help[] = | ||||||
| 	"\n" | 	"\n" | ||||||
| 	"Search for symbols and display their relations.\n" | 	"Search for symbols and display their relations.\n" | ||||||
| 	"Regular expressions are allowed.\n" | 	"Regular expressions are allowed.\n" | ||||||
| @@ -248,7 +250,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" | ||||||
| @@ -273,7 +275,7 @@ search_help[] = N_( | |||||||
| 	"Examples: USB	=> find all symbols containing USB\n" | 	"Examples: USB	=> find all symbols containing USB\n" | ||||||
| 	"          ^USB => find all symbols starting with USB\n" | 	"          ^USB => find all symbols starting with USB\n" | ||||||
| 	"          USB$ => find all symbols ending with USB\n" | 	"          USB$ => find all symbols ending with USB\n" | ||||||
| 	"\n"); | 	"\n"; | ||||||
|  |  | ||||||
| static int indent; | static int indent; | ||||||
| static struct menu *current_menu; | static struct menu *current_menu; | ||||||
| @@ -281,6 +283,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); | ||||||
| @@ -298,17 +301,12 @@ static char filename[PATH_MAX+1]; | |||||||
| static void set_config_filename(const char *config_filename) | static void set_config_filename(const char *config_filename) | ||||||
| { | { | ||||||
| 	static char menu_backtitle[PATH_MAX+128]; | 	static char menu_backtitle[PATH_MAX+128]; | ||||||
| 	int size; |  | ||||||
|  |  | ||||||
| 	size = snprintf(menu_backtitle, sizeof(menu_backtitle), | 	snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", | ||||||
| 			"%s - %s", config_filename, rootmenu.prompt->text); | 		 config_filename, rootmenu.prompt->text); | ||||||
| 	if (size >= sizeof(menu_backtitle)) |  | ||||||
| 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; |  | ||||||
| 	set_dialog_backtitle(menu_backtitle); | 	set_dialog_backtitle(menu_backtitle); | ||||||
|  |  | ||||||
| 	size = snprintf(filename, sizeof(filename), "%s", config_filename); | 	snprintf(filename, sizeof(filename), "%s", config_filename); | ||||||
| 	if (size >= sizeof(filename)) |  | ||||||
| 		filename[sizeof(filename)-1] = '\0'; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| struct subtitle_part { | struct subtitle_part { | ||||||
| @@ -401,19 +399,19 @@ static void search_conf(void) | |||||||
| 	struct subtitle_part stpart; | 	struct subtitle_part stpart; | ||||||
|  |  | ||||||
| 	title = str_new(); | 	title = str_new(); | ||||||
| 	str_printf( &title, _("Enter (sub)string or regexp to search for " | 	str_printf( &title, "Enter (sub)string or regexp to search for " | ||||||
| 			      "(with or without \"%s\")"), CONFIG_); | 			      "(with or without \"%s\")", CONFIG_); | ||||||
|  |  | ||||||
| again: | again: | ||||||
| 	dialog_clear(); | 	dialog_clear(); | ||||||
| 	dres = dialog_inputbox(_("Search Configuration Parameter"), | 	dres = dialog_inputbox("Search Configuration Parameter", | ||||||
| 			      str_get(&title), | 			      str_get(&title), | ||||||
| 			      10, 75, ""); | 			      10, 75, ""); | ||||||
| 	switch (dres) { | 	switch (dres) { | ||||||
| 	case 0: | 	case 0: | ||||||
| 		break; | 		break; | ||||||
| 	case 1: | 	case 1: | ||||||
| 		show_helptext(_("Search Configuration"), search_help); | 		show_helptext("Search Configuration", search_help); | ||||||
| 		goto again; | 		goto again; | ||||||
| 	default: | 	default: | ||||||
| 		str_free(&title); | 		str_free(&title); | ||||||
| @@ -444,7 +442,7 @@ again: | |||||||
|  |  | ||||||
| 		res = get_relations_str(sym_arr, &head); | 		res = get_relations_str(sym_arr, &head); | ||||||
| 		set_subtitle(); | 		set_subtitle(); | ||||||
| 		dres = show_textbox_ext(_("Search Results"), (char *) | 		dres = show_textbox_ext("Search Results", (char *) | ||||||
| 					str_get(&res), 0, 0, keys, &vscroll, | 					str_get(&res), 0, 0, keys, &vscroll, | ||||||
| 					&hscroll, &update_text, (void *) | 					&hscroll, &update_text, (void *) | ||||||
| 					&data); | 					&data); | ||||||
| @@ -492,7 +490,6 @@ static void build_conf(struct menu *menu) | |||||||
| 			switch (prop->type) { | 			switch (prop->type) { | ||||||
| 			case P_MENU: | 			case P_MENU: | ||||||
| 				child_count++; | 				child_count++; | ||||||
| 				prompt = _(prompt); |  | ||||||
| 				if (single_menu_mode) { | 				if (single_menu_mode) { | ||||||
| 					item_make("%s%*c%s", | 					item_make("%s%*c%s", | ||||||
| 						  menu->data ? "-->" : "++>", | 						  menu->data ? "-->" : "++>", | ||||||
| @@ -509,7 +506,7 @@ static void build_conf(struct menu *menu) | |||||||
| 			case P_COMMENT: | 			case P_COMMENT: | ||||||
| 				if (prompt) { | 				if (prompt) { | ||||||
| 					child_count++; | 					child_count++; | ||||||
| 					item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt)); | 					item_make("   %*c*** %s ***", indent + 1, ' ', prompt); | ||||||
| 					item_set_tag(':'); | 					item_set_tag(':'); | ||||||
| 					item_set_data(menu); | 					item_set_data(menu); | ||||||
| 				} | 				} | ||||||
| @@ -517,7 +514,7 @@ static void build_conf(struct menu *menu) | |||||||
| 			default: | 			default: | ||||||
| 				if (prompt) { | 				if (prompt) { | ||||||
| 					child_count++; | 					child_count++; | ||||||
| 					item_make("---%*c%s", indent + 1, ' ', _(prompt)); | 					item_make("---%*c%s", indent + 1, ' ', prompt); | ||||||
| 					item_set_tag(':'); | 					item_set_tag(':'); | ||||||
| 					item_set_data(menu); | 					item_set_data(menu); | ||||||
| 				} | 				} | ||||||
| @@ -539,7 +536,7 @@ static void build_conf(struct menu *menu) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		val = sym_get_tristate_value(sym); | 		val = sym_get_tristate_value(sym); | ||||||
| 		if (sym_is_changable(sym)) { | 		if (sym_is_changeable(sym)) { | ||||||
| 			switch (type) { | 			switch (type) { | ||||||
| 			case S_BOOLEAN: | 			case S_BOOLEAN: | ||||||
| 				item_make("[%c]", val == no ? ' ' : '*'); | 				item_make("[%c]", val == no ? ' ' : '*'); | ||||||
| @@ -561,10 +558,10 @@ static void build_conf(struct menu *menu) | |||||||
| 			item_set_data(menu); | 			item_set_data(menu); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); | 		item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); | ||||||
| 		if (val == yes) { | 		if (val == yes) { | ||||||
| 			if (def_menu) { | 			if (def_menu) { | ||||||
| 				item_add_str(" (%s)", _(menu_get_prompt(def_menu))); | 				item_add_str(" (%s)", menu_get_prompt(def_menu)); | ||||||
| 				item_add_str("  --->"); | 				item_add_str("  --->"); | ||||||
| 				if (def_menu->list) { | 				if (def_menu->list) { | ||||||
| 					indent += 2; | 					indent += 2; | ||||||
| @@ -576,7 +573,7 @@ static void build_conf(struct menu *menu) | |||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if (menu == current_menu) { | 		if (menu == current_menu) { | ||||||
| 			item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); | 			item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); | ||||||
| 			item_set_tag(':'); | 			item_set_tag(':'); | ||||||
| 			item_set_data(menu); | 			item_set_data(menu); | ||||||
| 			goto conf_childs; | 			goto conf_childs; | ||||||
| @@ -590,7 +587,7 @@ static void build_conf(struct menu *menu) | |||||||
| 		} else { | 		} else { | ||||||
| 			switch (type) { | 			switch (type) { | ||||||
| 			case S_BOOLEAN: | 			case S_BOOLEAN: | ||||||
| 				if (sym_is_changable(sym)) | 				if (sym_is_changeable(sym)) | ||||||
| 					item_make("[%c]", val == no ? ' ' : '*'); | 					item_make("[%c]", val == no ? ' ' : '*'); | ||||||
| 				else | 				else | ||||||
| 					item_make("-%c-", val == no ? ' ' : '*'); | 					item_make("-%c-", val == no ? ' ' : '*'); | ||||||
| @@ -603,7 +600,7 @@ static void build_conf(struct menu *menu) | |||||||
| 				case mod: ch = 'M'; break; | 				case mod: ch = 'M'; break; | ||||||
| 				default:  ch = ' '; break; | 				default:  ch = ' '; break; | ||||||
| 				} | 				} | ||||||
| 				if (sym_is_changable(sym)) { | 				if (sym_is_changeable(sym)) { | ||||||
| 					if (sym->rev_dep.tri == mod) | 					if (sym->rev_dep.tri == mod) | ||||||
| 						item_make("{%c}", ch); | 						item_make("{%c}", ch); | ||||||
| 					else | 					else | ||||||
| @@ -619,17 +616,17 @@ static void build_conf(struct menu *menu) | |||||||
| 				tmp = indent - tmp + 4; | 				tmp = indent - tmp + 4; | ||||||
| 				if (tmp < 0) | 				if (tmp < 0) | ||||||
| 					tmp = 0; | 					tmp = 0; | ||||||
| 				item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), | 				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), | ||||||
| 					     (sym_has_value(sym) || !sym_is_changable(sym)) ? | 					     (sym_has_value(sym) || !sym_is_changeable(sym)) ? | ||||||
| 					     "" : _(" (NEW)")); | 					     "" : " (NEW)"); | ||||||
| 				item_set_tag('s'); | 				item_set_tag('s'); | ||||||
| 				item_set_data(menu); | 				item_set_data(menu); | ||||||
| 				goto conf_childs; | 				goto conf_childs; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), | 		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), | ||||||
| 			  (sym_has_value(sym) || !sym_is_changable(sym)) ? | 			  (sym_has_value(sym) || !sym_is_changeable(sym)) ? | ||||||
| 			  "" : _(" (NEW)")); | 			  "" : " (NEW)"); | ||||||
| 		if (menu->prompt->type == P_MENU) { | 		if (menu->prompt->type == P_MENU) { | ||||||
| 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->"); | 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->"); | ||||||
| 			return; | 			return; | ||||||
| @@ -666,8 +663,8 @@ static void conf(struct menu *menu, struct menu *active_menu) | |||||||
| 			break; | 			break; | ||||||
| 		set_subtitle(); | 		set_subtitle(); | ||||||
| 		dialog_clear(); | 		dialog_clear(); | ||||||
| 		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), | 		res = dialog_menu(prompt ? prompt : "Main Menu", | ||||||
| 				  _(menu_instructions), | 				  menu_instructions, | ||||||
| 				  active_menu, &s_scroll); | 				  active_menu, &s_scroll); | ||||||
| 		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) | 		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) | ||||||
| 			break; | 			break; | ||||||
| @@ -709,7 +706,7 @@ static void conf(struct menu *menu, struct menu *active_menu) | |||||||
| 				show_help(submenu); | 				show_help(submenu); | ||||||
| 			else { | 			else { | ||||||
| 				reset_subtitle(); | 				reset_subtitle(); | ||||||
| 				show_helptext(_("README"), _(mconf_readme)); | 				show_helptext("README", mconf_readme); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		case 3: | 		case 3: | ||||||
| @@ -774,15 +771,14 @@ static void show_helptext(const char *title, const char *text) | |||||||
| 	show_textbox(title, text, 0, 0); | 	show_textbox(title, text, 0, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void conf_message_callback(const char *fmt, va_list ap) | static void conf_message_callback(const char *s) | ||||||
| { | { | ||||||
| 	char buf[PATH_MAX+1]; | 	if (save_and_exit) { | ||||||
|  | 		if (!silent) | ||||||
| 	vsnprintf(buf, sizeof(buf), fmt, ap); | 			printf("%s", s); | ||||||
| 	if (save_and_exit) | 	} else { | ||||||
| 		printf("%s", buf); | 		show_textbox(NULL, s, 6, 60); | ||||||
| 	else | 	} | ||||||
| 		show_textbox(NULL, buf, 6, 60); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void show_help(struct menu *menu) | static void show_help(struct menu *menu) | ||||||
| @@ -792,13 +788,13 @@ static void show_help(struct menu *menu) | |||||||
| 	help.max_width = getmaxx(stdscr) - 10; | 	help.max_width = getmaxx(stdscr) - 10; | ||||||
| 	menu_get_ext_help(menu, &help); | 	menu_get_ext_help(menu, &help); | ||||||
|  |  | ||||||
| 	show_helptext(_(menu_get_prompt(menu)), str_get(&help)); | 	show_helptext(menu_get_prompt(menu), str_get(&help)); | ||||||
| 	str_free(&help); | 	str_free(&help); | ||||||
| } | } | ||||||
|  |  | ||||||
| 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; | 	struct menu *child; | ||||||
| 	struct symbol *active; | 	struct symbol *active; | ||||||
|  |  | ||||||
| @@ -813,9 +809,9 @@ static void conf_choice(struct menu *menu) | |||||||
| 			if (!menu_is_visible(child)) | 			if (!menu_is_visible(child)) | ||||||
| 				continue; | 				continue; | ||||||
| 			if (child->sym) | 			if (child->sym) | ||||||
| 				item_make("%s", _(menu_get_prompt(child))); | 				item_make("%s", menu_get_prompt(child)); | ||||||
| 			else { | 			else { | ||||||
| 				item_make("*** %s ***", _(menu_get_prompt(child))); | 				item_make("*** %s ***", menu_get_prompt(child)); | ||||||
| 				item_set_tag(':'); | 				item_set_tag(':'); | ||||||
| 			} | 			} | ||||||
| 			item_set_data(child); | 			item_set_data(child); | ||||||
| @@ -825,8 +821,8 @@ static void conf_choice(struct menu *menu) | |||||||
| 				item_set_tag('X'); | 				item_set_tag('X'); | ||||||
| 		} | 		} | ||||||
| 		dialog_clear(); | 		dialog_clear(); | ||||||
| 		res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), | 		res = dialog_checklist(prompt ? prompt : "Main Menu", | ||||||
| 					_(radiolist_instructions), | 					radiolist_instructions, | ||||||
| 					MENUBOX_HEIGTH_MIN, | 					MENUBOX_HEIGTH_MIN, | ||||||
| 					MENUBOX_WIDTH_MIN, | 					MENUBOX_WIDTH_MIN, | ||||||
| 					CHECKLIST_HEIGTH_MIN); | 					CHECKLIST_HEIGTH_MIN); | ||||||
| @@ -867,26 +863,26 @@ static void conf_string(struct menu *menu) | |||||||
|  |  | ||||||
| 		switch (sym_get_type(menu->sym)) { | 		switch (sym_get_type(menu->sym)) { | ||||||
| 		case S_INT: | 		case S_INT: | ||||||
| 			heading = _(inputbox_instructions_int); | 			heading = inputbox_instructions_int; | ||||||
| 			break; | 			break; | ||||||
| 		case S_HEX: | 		case S_HEX: | ||||||
| 			heading = _(inputbox_instructions_hex); | 			heading = inputbox_instructions_hex; | ||||||
| 			break; | 			break; | ||||||
| 		case S_STRING: | 		case S_STRING: | ||||||
| 			heading = _(inputbox_instructions_string); | 			heading = inputbox_instructions_string; | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			heading = _("Internal mconf error!"); | 			heading = "Internal mconf error!"; | ||||||
| 		} | 		} | ||||||
| 		dialog_clear(); | 		dialog_clear(); | ||||||
| 		res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), | 		res = dialog_inputbox(prompt ? prompt : "Main Menu", | ||||||
| 				      heading, 10, 75, | 				      heading, 10, 75, | ||||||
| 				      sym_get_string_value(menu->sym)); | 				      sym_get_string_value(menu->sym)); | ||||||
| 		switch (res) { | 		switch (res) { | ||||||
| 		case 0: | 		case 0: | ||||||
| 			if (sym_set_string_value(menu->sym, dialog_input_result)) | 			if (sym_set_string_value(menu->sym, dialog_input_result)) | ||||||
| 				return; | 				return; | ||||||
| 			show_textbox(NULL, _("You have made an invalid entry."), 5, 43); | 			show_textbox(NULL, "You have made an invalid entry.", 5, 43); | ||||||
| 			break; | 			break; | ||||||
| 		case 1: | 		case 1: | ||||||
| 			show_help(menu); | 			show_help(menu); | ||||||
| @@ -911,13 +907,13 @@ static void conf_load(void) | |||||||
| 				return; | 				return; | ||||||
| 			if (!conf_read(dialog_input_result)) { | 			if (!conf_read(dialog_input_result)) { | ||||||
| 				set_config_filename(dialog_input_result); | 				set_config_filename(dialog_input_result); | ||||||
| 				sym_set_change_count(1); | 				conf_set_changed(true); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			show_textbox(NULL, _("File does not exist!"), 5, 38); | 			show_textbox(NULL, "File does not exist!", 5, 38); | ||||||
| 			break; | 			break; | ||||||
| 		case 1: | 		case 1: | ||||||
| 			show_helptext(_("Load Alternate Configuration"), load_config_help); | 			show_helptext("Load Alternate Configuration", load_config_help); | ||||||
| 			break; | 			break; | ||||||
| 		case KEY_ESC: | 		case KEY_ESC: | ||||||
| 			return; | 			return; | ||||||
| @@ -940,10 +936,10 @@ static void conf_save(void) | |||||||
| 				set_config_filename(dialog_input_result); | 				set_config_filename(dialog_input_result); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60); | 			show_textbox(NULL, "Can't create file!", 5, 60); | ||||||
| 			break; | 			break; | ||||||
| 		case 1: | 		case 1: | ||||||
| 			show_helptext(_("Save Alternate Configuration"), save_config_help); | 			show_helptext("Save Alternate Configuration", save_config_help); | ||||||
| 			break; | 			break; | ||||||
| 		case KEY_ESC: | 		case KEY_ESC: | ||||||
| 			return; | 			return; | ||||||
| @@ -961,8 +957,8 @@ static int handle_exit(void) | |||||||
| 	dialog_clear(); | 	dialog_clear(); | ||||||
| 	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" | ||||||
| 				     "(Press <ESC><ESC> to continue configuration.)"), | 				     "(Press <ESC><ESC> to continue kernel configuration.)", | ||||||
| 				   6, 60); | 				   6, 60); | ||||||
| 	else | 	else | ||||||
| 		res = -1; | 		res = -1; | ||||||
| @@ -971,32 +967,35 @@ static int handle_exit(void) | |||||||
|  |  | ||||||
| 	env = getenv("KCONFIG_STRICT"); | 	env = getenv("KCONFIG_STRICT"); | ||||||
| 	if (env && *env && kconfig_warnings) { | 	if (env && *env && kconfig_warnings) { | ||||||
| 		fprintf(stderr, _("\n*** ERROR: %d warnings encountered, and " | 		fprintf(stderr, "\n*** ERROR: %d warnings encountered, and " | ||||||
| 			"warnings are errors.\n\n"), kconfig_warnings); | 			"warnings are errors.\n\n", kconfig_warnings); | ||||||
| 		res = 2; | 		res = 2; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch (res) { | 	switch (res) { | ||||||
| 	case 0: | 	case 0: | ||||||
| 		if (conf_write(filename)) { | 		if (conf_write(filename)) { | ||||||
| 			fprintf(stderr, _("\n\n" | 			fprintf(stderr, "\n\n" | ||||||
| 					  "Error while writing of the configuration.\n" | 					  "Error while writing of the configuration.\n" | ||||||
| 					  "Your configuration changes were NOT saved." | 					  "Your configuration changes were NOT saved." | ||||||
| 					  "\n\n")); | 					  "\n\n"); | ||||||
| 			return 1; | 			return 1; | ||||||
| 		} | 		} | ||||||
|  | 		conf_write_autoconf(0); | ||||||
| 		/* 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; | ||||||
| 	} | 	} | ||||||
| @@ -1014,12 +1013,14 @@ int main(int ac, char **av) | |||||||
| 	char *mode; | 	char *mode; | ||||||
| 	int res; | 	int res; | ||||||
|  |  | ||||||
| 	setlocale(LC_ALL, ""); |  | ||||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); |  | ||||||
| 	textdomain(PACKAGE); |  | ||||||
|  |  | ||||||
| 	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); | ||||||
|  |  | ||||||
| @@ -1030,8 +1031,8 @@ int main(int ac, char **av) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (init_dialog(NULL)) { | 	if (init_dialog(NULL)) { | ||||||
| 		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); | 		fprintf(stderr, "Your display is too small to run Menuconfig!\n"); | ||||||
| 		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); | 		fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| @@ -9,6 +9,7 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| #include "lkc.h" | #include "lkc.h" | ||||||
|  | #include "internal.h" | ||||||
|  |  | ||||||
| static const char nohelp_text[] = "There is no help available for this option."; | static const char nohelp_text[] = "There is no help available for this option."; | ||||||
|  |  | ||||||
| @@ -62,15 +63,11 @@ 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 = ¤t_entry->list; | 	last_entry_ptr = ¤t_entry->list; | ||||||
| 	return current_menu = current_entry; | 	current_menu = current_entry; | ||||||
|  | 	return current_menu; | ||||||
| } | } | ||||||
|  |  | ||||||
| void menu_end_menu(void) | void menu_end_menu(void) | ||||||
| @@ -79,19 +76,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 +107,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,59 +126,74 @@ 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, struct expr *expr, | ||||||
|  | 				      struct expr *dep) | ||||||
| { | { | ||||||
| 	struct property *prop = prop_alloc(type, current_entry->sym); | 	struct property *prop; | ||||||
|  |  | ||||||
|  | 	prop = xmalloc(sizeof(*prop)); | ||||||
|  | 	memset(prop, 0, sizeof(*prop)); | ||||||
|  | 	prop->type = type; | ||||||
|  | 	prop->file = current_file; | ||||||
|  | 	prop->lineno = zconf_lineno(); | ||||||
| 	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) { | 	/* append property to the prop list of symbol */ | ||||||
| 		if (isspace(*prompt)) { | 	if (current_entry->sym) { | ||||||
| 			prop_warn(prop, "leading whitespace ignored"); | 		struct property **propp; | ||||||
| 			while (isspace(*prompt)) |  | ||||||
| 				prompt++; |  | ||||||
| 		} |  | ||||||
| 		if (current_entry->prompt && current_entry != &rootmenu) |  | ||||||
| 			prop_warn(prop, "prompt redefined"); |  | ||||||
|  |  | ||||||
| 		/* Apply all upper menus' visibilities to actual prompts. */ | 		for (propp = ¤t_entry->sym->prop; | ||||||
| 		if(type == P_PROMPT) { | 		     *propp; | ||||||
| 			struct menu *menu = current_entry; | 		     propp = &(*propp)->next) | ||||||
|  | 			; | ||||||
| 			while ((menu = menu->parent) != NULL) { | 		*propp = prop; | ||||||
| 				struct expr *dup_expr; |  | ||||||
|  |  | ||||||
| 				if (!menu->visibility) |  | ||||||
| 					continue; |  | ||||||
| 				/* |  | ||||||
| 				 * Do not add a reference to the |  | ||||||
| 				 * menu's visibility expression but |  | ||||||
| 				 * use a copy of it.  Otherwise the |  | ||||||
| 				 * expression reduction functions |  | ||||||
| 				 * will modify expressions that have |  | ||||||
| 				 * multiple references which can |  | ||||||
| 				 * cause unwanted side effects. |  | ||||||
| 				 */ |  | ||||||
| 				dup_expr = expr_copy(menu->visibility); |  | ||||||
|  |  | ||||||
| 				prop->visible.expr |  | ||||||
| 					= expr_alloc_and(prop->visible.expr, |  | ||||||
| 							 dup_expr); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		current_entry->prompt = prop; |  | ||||||
| 	} | 	} | ||||||
| 	prop->text = prompt; |  | ||||||
|  |  | ||||||
| 	return prop; | 	return prop; | ||||||
| } | } | ||||||
|  |  | ||||||
| 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) | ||||||
| { | { | ||||||
| 	return menu_add_prop(type, prompt, NULL, dep); | 	struct property *prop = menu_add_prop(type, NULL, dep); | ||||||
|  |  | ||||||
|  | 	if (isspace(*prompt)) { | ||||||
|  | 		prop_warn(prop, "leading whitespace ignored"); | ||||||
|  | 		while (isspace(*prompt)) | ||||||
|  | 			prompt++; | ||||||
|  | 	} | ||||||
|  | 	if (current_entry->prompt) | ||||||
|  | 		prop_warn(prop, "prompt redefined"); | ||||||
|  |  | ||||||
|  | 	/* Apply all upper menus' visibilities to actual prompts. */ | ||||||
|  | 	if (type == P_PROMPT) { | ||||||
|  | 		struct menu *menu = current_entry; | ||||||
|  |  | ||||||
|  | 		while ((menu = menu->parent) != NULL) { | ||||||
|  | 			struct expr *dup_expr; | ||||||
|  |  | ||||||
|  | 			if (!menu->visibility) | ||||||
|  | 				continue; | ||||||
|  | 			/* | ||||||
|  | 			 * Do not add a reference to the menu's visibility | ||||||
|  | 			 * expression but use a copy of it. Otherwise the | ||||||
|  | 			 * expression reduction functions will modify | ||||||
|  | 			 * expressions that have multiple references which | ||||||
|  | 			 * can cause unwanted side effects. | ||||||
|  | 			 */ | ||||||
|  | 			dup_expr = expr_copy(menu->visibility); | ||||||
|  |  | ||||||
|  | 			prop->visible.expr = expr_alloc_and(prop->visible.expr, | ||||||
|  | 							    dup_expr); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	current_entry->prompt = prop; | ||||||
|  | 	prop->text = prompt; | ||||||
|  |  | ||||||
|  | 	return prop; | ||||||
| } | } | ||||||
|  |  | ||||||
| void menu_add_visibility(struct expr *expr) | void menu_add_visibility(struct expr *expr) | ||||||
| @@ -188,39 +204,12 @@ void menu_add_visibility(struct expr *expr) | |||||||
|  |  | ||||||
| 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) | ||||||
| { | { | ||||||
| 	menu_add_prop(type, NULL, expr, dep); | 	menu_add_prop(type, 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) | ||||||
| { | { | ||||||
| 	menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); | 	menu_add_prop(type, expr_alloc_symbol(sym), dep); | ||||||
| } |  | ||||||
|  |  | ||||||
| void menu_add_option(int token, char *arg) |  | ||||||
| { |  | ||||||
| 	switch (token) { |  | ||||||
| 	case T_OPT_MODULES: |  | ||||||
| 		if (modules_sym) |  | ||||||
| 			zconf_error("symbol '%s' redefines option 'modules'" |  | ||||||
| 				    " already defined by symbol '%s'", |  | ||||||
| 				    current_entry->sym->name, |  | ||||||
| 				    modules_sym->name |  | ||||||
| 				    ); |  | ||||||
| 		modules_sym = current_entry->sym; |  | ||||||
| 		break; |  | ||||||
| 	case T_OPT_DEFCONFIG_LIST: |  | ||||||
| 		if (!sym_defconfig_list) |  | ||||||
| 			sym_defconfig_list = current_entry->sym; |  | ||||||
| 		else if (sym_defconfig_list != current_entry->sym) |  | ||||||
| 			zconf_error("trying to redefine defconfig symbol"); |  | ||||||
| 		break; |  | ||||||
| 	case T_OPT_ENV: |  | ||||||
| 		prop_add_env(arg); |  | ||||||
| 		break; |  | ||||||
| 	case T_OPT_ALLNOCONFIG_Y: |  | ||||||
| 		current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static int menu_validate_number(struct symbol *sym, struct symbol *sym2) | static int menu_validate_number(struct symbol *sym, struct symbol *sym2) | ||||||
| @@ -233,6 +222,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: | ||||||
| @@ -250,20 +241,32 @@ 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) | ||||||
| @@ -288,6 +291,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 */ | ||||||
| @@ -305,65 +313,167 @@ 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); | ||||||
| 			} | 			} | ||||||
| 			parentdep = expr_alloc_symbol(sym); |  | ||||||
| 		} else if (parent->prompt) |  | ||||||
| 			parentdep = parent->prompt->visible.expr; |  | ||||||
| 		else |  | ||||||
| 			parentdep = parent->dep; |  | ||||||
|  |  | ||||||
|  | 			/* | ||||||
|  | 			 * 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); | ||||||
|  | 		} else { | ||||||
|  | 			/* Menu node for 'menu', 'if' */ | ||||||
|  | 			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; | ||||||
| @@ -412,6 +522,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; | ||||||
| @@ -436,6 +575,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, | ||||||
| @@ -477,7 +625,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; | ||||||
| @@ -543,6 +691,21 @@ const char *menu_get_help(struct menu *menu) | |||||||
| 		return ""; | 		return ""; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void get_def_str(struct gstr *r, struct menu *menu) | ||||||
|  | { | ||||||
|  | 	str_printf(r, "Defined at %s:%d\n", | ||||||
|  | 		   menu->file->name, menu->lineno); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix) | ||||||
|  | { | ||||||
|  | 	if (!expr_is_yes(expr)) { | ||||||
|  | 		str_append(r, prefix); | ||||||
|  | 		expr_gstr_print(expr, r); | ||||||
|  | 		str_append(r, "\n"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| static void get_prompt_str(struct gstr *r, struct property *prop, | static void get_prompt_str(struct gstr *r, struct property *prop, | ||||||
| 			   struct list_head *head) | 			   struct list_head *head) | ||||||
| { | { | ||||||
| @@ -550,7 +713,20 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | |||||||
| 	struct menu *submenu[8], *menu, *location = NULL; | 	struct menu *submenu[8], *menu, *location = NULL; | ||||||
| 	struct jump_key *jump = NULL; | 	struct jump_key *jump = NULL; | ||||||
|  |  | ||||||
| 	str_printf(r, _("Prompt: %s\n"), _(prop->text)); | 	str_printf(r, "  Prompt: %s\n", prop->text); | ||||||
|  |  | ||||||
|  | 	get_dep_str(r, prop->menu->dep, "  Depends on: "); | ||||||
|  | 	/* | ||||||
|  | 	 * Most prompts in Linux have visibility that exactly matches their | ||||||
|  | 	 * dependencies. For these, we print only the dependencies to improve | ||||||
|  | 	 * readability. However, prompts with inline "if" expressions and | ||||||
|  | 	 * prompts with a parent that has a "visible if" expression have | ||||||
|  | 	 * differing dependencies and visibility. In these rare cases, we | ||||||
|  | 	 * print both. | ||||||
|  | 	 */ | ||||||
|  | 	if (!expr_eq(prop->menu->dep, prop->visible.expr)) | ||||||
|  | 		get_dep_str(r, prop->visible.expr, "  Visible if: "); | ||||||
|  |  | ||||||
| 	menu = prop->menu->parent; | 	menu = prop->menu->parent; | ||||||
| 	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { | 	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { | ||||||
| 		bool accessible = menu_is_visible(menu); | 		bool accessible = menu_is_visible(menu); | ||||||
| @@ -583,16 +759,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (i > 0) { | 	if (i > 0) { | ||||||
| 		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 (jump && 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)); | ||||||
| 			if (menu->sym) { | 			if (menu->sym) { | ||||||
| 				str_printf(r, " (%s [=%s])", menu->sym->name ? | 				str_printf(r, " (%s [=%s])", menu->sym->name ? | ||||||
| 					menu->sym->name : _("<choice>"), | 					menu->sym->name : "<choice>", | ||||||
| 					sym_get_string_value(menu->sym)); | 					sym_get_string_value(menu->sym)); | ||||||
| 			} | 			} | ||||||
| 			str_append(r, "\n"); | 			str_append(r, "\n"); | ||||||
| @@ -600,25 +776,30 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | static void get_symbol_props_str(struct gstr *r, struct symbol *sym, | ||||||
|  * get property of type P_SYMBOL | 				 enum prop_type tok, const char *prefix) | ||||||
|  */ |  | ||||||
| static struct property *get_symbol_prop(struct symbol *sym) |  | ||||||
| { | { | ||||||
| 	struct property *prop = NULL; | 	bool hit = false; | ||||||
|  | 	struct property *prop; | ||||||
|  |  | ||||||
| 	for_all_properties(sym, prop, P_SYMBOL) | 	for_all_properties(sym, prop, tok) { | ||||||
| 		break; | 		if (!hit) { | ||||||
| 	return prop; | 			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) { | ||||||
| @@ -634,36 +815,36 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	for_all_prompts(sym, prop) |  | ||||||
| 		get_prompt_str(r, prop, head); |  | ||||||
|  |  | ||||||
| 	prop = get_symbol_prop(sym); | 	/* Print the definitions with prompts before the ones without */ | ||||||
| 	if (prop) { | 	for_all_properties(sym, prop, P_SYMBOL) { | ||||||
| 		str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name, | 		if (prop->menu->prompt) { | ||||||
| 			prop->menu->lineno); | 			get_def_str(r, prop->menu); | ||||||
| 		if (!expr_is_yes(prop->visible.expr)) { | 			get_prompt_str(r, prop->menu->prompt, head); | ||||||
| 			str_append(r, _("  Depends on: ")); |  | ||||||
| 			expr_gstr_print(prop->visible.expr, r); |  | ||||||
| 			str_append(r, "\n"); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	hit = false; | 	for_all_properties(sym, prop, P_SYMBOL) { | ||||||
| 	for_all_properties(sym, prop, P_SELECT) { | 		if (!prop->menu->prompt) { | ||||||
| 		if (!hit) { | 			get_def_str(r, prop->menu); | ||||||
| 			str_append(r, "  Selects: "); | 			get_dep_str(r, prop->menu->dep, "  Depends on: "); | ||||||
| 			hit = true; | 		} | ||||||
| 		} else |  | ||||||
| 			str_printf(r, " && "); |  | ||||||
| 		expr_gstr_print(prop->expr, r); |  | ||||||
| 	} | 	} | ||||||
| 	if (hit) |  | ||||||
| 		str_append(r, "\n"); | 	get_symbol_props_str(r, sym, P_SELECT, "Selects: "); | ||||||
| 	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"); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -676,7 +857,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) | |||||||
| 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++) | 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++) | ||||||
| 		get_symbol_str(&res, sym, head); | 		get_symbol_str(&res, sym, head); | ||||||
| 	if (!i) | 	if (!i) | ||||||
| 		str_append(&res, _("No matches found.\n")); | 		str_append(&res, "No matches found.\n"); | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -691,7 +872,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help) | |||||||
| 			str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); | 			str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); | ||||||
| 		help_text = menu_get_help(menu); | 		help_text = menu_get_help(menu); | ||||||
| 	} | 	} | ||||||
| 	str_printf(help, "%s\n", _(help_text)); | 	str_printf(help, "%s\n", help_text); | ||||||
| 	if (sym) | 	if (sym) | ||||||
| 		get_symbol_str(help, sym, NULL); | 		get_symbol_str(help, sym, NULL); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										189
									
								
								util/kconfig/merge_config.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										189
									
								
								util/kconfig/merge_config.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,189 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # SPDX-License-Identifier: GPL-2.0 | ||||||
|  | # | ||||||
|  | #  merge_config.sh - Takes a list of config fragment values, and merges | ||||||
|  | #  them one by one. Provides warnings on overridden values, and specified | ||||||
|  | #  values that did not make it to the resulting .config file (due to missed | ||||||
|  | #  dependencies or config symbol removal). | ||||||
|  | # | ||||||
|  | #  Portions reused from kconf_check and generate_cfg: | ||||||
|  | #  http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/kconf_check | ||||||
|  | #  http://git.yoctoproject.org/cgit/cgit.cgi/yocto-kernel-tools/tree/tools/generate_cfg | ||||||
|  | # | ||||||
|  | #  Copyright (c) 2009-2010 Wind River Systems, Inc. | ||||||
|  | #  Copyright 2011 Linaro | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | clean_up() { | ||||||
|  | 	rm -f $TMP_FILE | ||||||
|  | 	rm -f $MERGE_FILE | ||||||
|  | } | ||||||
|  |  | ||||||
|  | usage() { | ||||||
|  | 	echo "Usage: $0 [OPTIONS] [CONFIG [...]]" | ||||||
|  | 	echo "  -h    display this help text" | ||||||
|  | 	echo "  -m    only merge the fragments, do not execute the make command" | ||||||
|  | 	echo "  -n    use allnoconfig instead of alldefconfig" | ||||||
|  | 	echo "  -r    list redundant entries when merging fragments" | ||||||
|  | 	echo "  -y    make builtin have precedence over modules" | ||||||
|  | 	echo "  -O    dir to put generated output files.  Consider setting \$KCONFIG_CONFIG instead." | ||||||
|  | 	echo | ||||||
|  | 	echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with \$CONFIG_ environment variable." | ||||||
|  | } | ||||||
|  |  | ||||||
|  | RUNMAKE=true | ||||||
|  | ALLTARGET=alldefconfig | ||||||
|  | WARNREDUN=false | ||||||
|  | BUILTIN=false | ||||||
|  | OUTPUT=. | ||||||
|  | CONFIG_PREFIX=${CONFIG_-CONFIG_} | ||||||
|  |  | ||||||
|  | while true; do | ||||||
|  | 	case $1 in | ||||||
|  | 	"-n") | ||||||
|  | 		ALLTARGET=allnoconfig | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 		;; | ||||||
|  | 	"-m") | ||||||
|  | 		RUNMAKE=false | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 		;; | ||||||
|  | 	"-h") | ||||||
|  | 		usage | ||||||
|  | 		exit | ||||||
|  | 		;; | ||||||
|  | 	"-r") | ||||||
|  | 		WARNREDUN=true | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 		;; | ||||||
|  | 	"-y") | ||||||
|  | 		BUILTIN=true | ||||||
|  | 		shift | ||||||
|  | 		continue | ||||||
|  | 		;; | ||||||
|  | 	"-O") | ||||||
|  | 		if [ -d $2 ];then | ||||||
|  | 			OUTPUT=$(echo $2 | sed 's/\/*$//') | ||||||
|  | 		else | ||||||
|  | 			echo "output directory $2 does not exist" 1>&2 | ||||||
|  | 			exit 1 | ||||||
|  | 		fi | ||||||
|  | 		shift 2 | ||||||
|  | 		continue | ||||||
|  | 		;; | ||||||
|  | 	*) | ||||||
|  | 		break | ||||||
|  | 		;; | ||||||
|  | 	esac | ||||||
|  | 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 | ||||||
|  | shift; | ||||||
|  |  | ||||||
|  | if [ ! -r "$INITFILE" ]; then | ||||||
|  | 	echo "The base file '$INITFILE' does not exist.  Exit." >&2 | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | MERGE_LIST=$* | ||||||
|  | SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" | ||||||
|  | SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" | ||||||
|  |  | ||||||
|  | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) | ||||||
|  | MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) | ||||||
|  |  | ||||||
|  | echo "Using $INITFILE as base" | ||||||
|  |  | ||||||
|  | trap clean_up EXIT | ||||||
|  |  | ||||||
|  | cat $INITFILE > $TMP_FILE | ||||||
|  |  | ||||||
|  | # Merge files, printing warnings on overridden values | ||||||
|  | for ORIG_MERGE_FILE in $MERGE_LIST ; do | ||||||
|  | 	echo "Merging $ORIG_MERGE_FILE" | ||||||
|  | 	if [ ! -r "$ORIG_MERGE_FILE" ]; then | ||||||
|  | 		echo "The merge file '$ORIG_MERGE_FILE' does not exist.  Exit." >&2 | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | 	cat $ORIG_MERGE_FILE > $MERGE_FILE | ||||||
|  | 	CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) | ||||||
|  |  | ||||||
|  | 	for CFG in $CFG_LIST ; do | ||||||
|  | 		grep -q -w $CFG $TMP_FILE || continue | ||||||
|  | 		PREV_VAL=$(grep -w $CFG $TMP_FILE) | ||||||
|  | 		NEW_VAL=$(grep -w $CFG $MERGE_FILE) | ||||||
|  | 		BUILTIN_FLAG=false | ||||||
|  | 		if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then | ||||||
|  | 			echo Previous  value: $PREV_VAL | ||||||
|  | 			echo New value:       $NEW_VAL | ||||||
|  | 			echo -y passed, will not demote y to m | ||||||
|  | 			echo | ||||||
|  | 			BUILTIN_FLAG=true | ||||||
|  | 		elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then | ||||||
|  | 			echo Value of $CFG is redefined by fragment $ORIG_MERGE_FILE: | ||||||
|  | 			echo Previous  value: $PREV_VAL | ||||||
|  | 			echo New value:       $NEW_VAL | ||||||
|  | 			echo | ||||||
|  | 		elif [ "$WARNREDUN" = "true" ]; then | ||||||
|  | 			echo Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: | ||||||
|  | 		fi | ||||||
|  | 		if [ "$BUILTIN_FLAG" = "false" ]; then | ||||||
|  | 			sed -i "/$CFG[ =]/d" $TMP_FILE | ||||||
|  | 		else | ||||||
|  | 			sed -i "/$CFG[ =]/d" $MERGE_FILE | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  | 	cat $MERGE_FILE >> $TMP_FILE | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [ "$RUNMAKE" = "false" ]; then | ||||||
|  | 	cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG" | ||||||
|  | 	echo "#" | ||||||
|  | 	echo "# merged configuration written to $KCONFIG_CONFIG (needs make)" | ||||||
|  | 	echo "#" | ||||||
|  | 	exit | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # If we have an output dir, setup the O= argument, otherwise leave | ||||||
|  | # it blank, since O=. will create an unnecessary ./source softlink | ||||||
|  | OUTPUT_ARG="" | ||||||
|  | if [ "$OUTPUT" != "." ] ; then | ||||||
|  | 	OUTPUT_ARG="O=$OUTPUT" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Use the merged file as the starting point for: | ||||||
|  | # alldefconfig: Fills in any missing symbols with Kconfig default | ||||||
|  | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set | ||||||
|  | make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Check all specified config values took (might have missed-dependency issues) | ||||||
|  | for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do | ||||||
|  |  | ||||||
|  | 	REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) | ||||||
|  | 	ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) | ||||||
|  | 	if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then | ||||||
|  | 		echo "Value requested for $CFG not in final .config" | ||||||
|  | 		echo "Requested value:  $REQUESTED_VAL" | ||||||
|  | 		echo "Actual value:     $ACTUAL_VAL" | ||||||
|  | 		echo "" | ||||||
|  | 	fi | ||||||
|  | done | ||||||
							
								
								
									
										50
									
								
								util/kconfig/nconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								util/kconfig/nconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # SPDX-License-Identifier: GPL-2.0 | ||||||
|  |  | ||||||
|  | PKG="ncursesw menuw panelw" | ||||||
|  | PKG2="ncurses menu panel" | ||||||
|  |  | ||||||
|  | if [ -n "$(command -v pkg-config)" ]; then | ||||||
|  | 	if pkg-config --exists $PKG; then | ||||||
|  | 		echo cflags=\"$(pkg-config --cflags $PKG)\" | ||||||
|  | 		echo libs=\"$(pkg-config --libs $PKG)\" | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if pkg-config --exists $PKG2; then | ||||||
|  | 		echo cflags=\"$(pkg-config --cflags $PKG2)\" | ||||||
|  | 		echo libs=\"$(pkg-config --libs $PKG2)\" | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Check the default paths in case pkg-config is not installed. | ||||||
|  | # (Even if it is installed, some distributions such as openSUSE cannot | ||||||
|  | # find ncurses by pkg-config.) | ||||||
|  | if [ -f /usr/include/ncursesw/ncurses.h ]; then | ||||||
|  | 	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\" | ||||||
|  | 	echo libs=\"-lncursesw -lmenuw -lpanelw\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [ -f /usr/include/ncurses/ncurses.h ]; then | ||||||
|  | 	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\" | ||||||
|  | 	echo libs=\"-lncurses -lmenu -lpanel\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [ -f /usr/include/ncurses.h ]; then | ||||||
|  | 	echo cflags=\"-D_GNU_SOURCE\" | ||||||
|  | 	echo libs=\"-lncurses -lmenu -lpanel\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo >&2 "*" | ||||||
|  | echo >&2 "* Unable to find the ncurses package." | ||||||
|  | echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" | ||||||
|  | echo >&2 "* depending on your distribution)." | ||||||
|  | echo >&2 "*" | ||||||
|  | echo >&2 "* You may also need to install pkg-config to find the" | ||||||
|  | echo >&2 "* ncurses installed in a non-default location." | ||||||
|  | echo >&2 "*" | ||||||
|  | exit 1 | ||||||
| @@ -1,14 +1,14 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? |  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  * |  * | ||||||
|  * Derived from menuconfig. |  * Derived from menuconfig. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| #ifndef _GNU_SOURCE | #ifndef _GNU_SOURCE | ||||||
| #define _GNU_SOURCE | #define _GNU_SOURCE | ||||||
| #endif | #endif | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <strings.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  |  | ||||||
| #include "lkc.h" | #include "lkc.h" | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|  |  | ||||||
| int kconfig_warnings = 0; | int kconfig_warnings = 0; | ||||||
|  |  | ||||||
| static const char nconf_global_help[] = N_( | static const char nconf_global_help[] = | ||||||
| "Help windows\n" | "Help windows\n" | ||||||
| "------------\n" | "------------\n" | ||||||
| "o  Global help:  Unless in a data entry window, pressing <F1> will give \n" | "o  Global help:  Unless in a data entry window, pressing <F1> will give \n" | ||||||
| @@ -132,8 +132,8 @@ static const char nconf_global_help[] = N_( | |||||||
| "\n" | "\n" | ||||||
| "Note that this mode can eventually be a little more CPU expensive than\n" | "Note that this mode can eventually be a little more CPU expensive than\n" | ||||||
| "the default mode, especially with a larger number of unfolded submenus.\n" | "the default mode, especially with a larger number of unfolded submenus.\n" | ||||||
| "\n"), | "\n", | ||||||
| menu_no_f_instructions[] = N_( | menu_no_f_instructions[] = | ||||||
| "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n" | "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n" | ||||||
| "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" | "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" | ||||||
| "\n" | "\n" | ||||||
| @@ -149,8 +149,8 @@ menu_no_f_instructions[] = N_( | |||||||
| "You do not have function keys support.\n" | "You do not have function keys support.\n" | ||||||
| "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n" | "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n" | ||||||
| "For verbose global help use key <1>.\n" | "For verbose global help use key <1>.\n" | ||||||
| "For help related to the current menu entry press <?> or <h>.\n"), | "For help related to the current menu entry press <?> or <h>.\n", | ||||||
| menu_instructions[] = N_( | menu_instructions[] = | ||||||
| "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n" | "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n" | ||||||
| "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" | "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" | ||||||
| "\n" | "\n" | ||||||
| @@ -165,30 +165,30 @@ menu_instructions[] = N_( | |||||||
| "\n" | "\n" | ||||||
| "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n" | "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n" | ||||||
| "For verbose global help press <F1>.\n" | "For verbose global help press <F1>.\n" | ||||||
| "For help related to the current menu entry press <?> or <h>.\n"), | "For help related to the current menu entry press <?> or <h>.\n", | ||||||
| radiolist_instructions[] = N_( | radiolist_instructions[] = | ||||||
| "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n" | "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n" | ||||||
| "with <Space>.\n" | "with <Space>.\n" | ||||||
| "For help related to the current entry press <?> or <h>.\n" | "For help related to the current entry press <?> or <h>.\n" | ||||||
| "For global help press <F1>.\n"), | "For global help press <F1>.\n", | ||||||
| inputbox_instructions_int[] = N_( | inputbox_instructions_int[] = | ||||||
| "Please enter a decimal value.\n" | "Please enter a decimal value.\n" | ||||||
| "Fractions will not be accepted.\n" | "Fractions will not be accepted.\n" | ||||||
| "Press <Enter> to apply, <Esc> to cancel."), | "Press <Enter> to apply, <Esc> to cancel.", | ||||||
| inputbox_instructions_hex[] = N_( | inputbox_instructions_hex[] = | ||||||
| "Please enter a hexadecimal value.\n" | "Please enter a hexadecimal value.\n" | ||||||
| "Press <Enter> to apply, <Esc> to cancel."), | "Press <Enter> to apply, <Esc> to cancel.", | ||||||
| inputbox_instructions_string[] = N_( | inputbox_instructions_string[] = | ||||||
| "Please enter a string value.\n" | "Please enter a string value.\n" | ||||||
| "Press <Enter> to apply, <Esc> to cancel."), | "Press <Enter> to apply, <Esc> to cancel.", | ||||||
| setmod_text[] = N_( | setmod_text[] = | ||||||
| "This feature depends on another feature which has been configured as a\n" | "This feature depends on another feature which has been configured as a\n" | ||||||
| "module.  As a result, the current feature will be built as a module too."), | "module.  As a result, the current feature will be built as a module too.", | ||||||
| load_config_text[] = N_( | load_config_text[] = | ||||||
| "Enter the name of the configuration file you wish to load.\n" | "Enter the name of the configuration file you wish to load.\n" | ||||||
| "Accept the name shown to restore the configuration you last\n" | "Accept the name shown to restore the configuration you last\n" | ||||||
| "retrieved.  Leave empty to abort."), | "retrieved.  Leave empty to abort.", | ||||||
| load_config_help[] = N_( | load_config_help[] = | ||||||
| "For various reasons, one may wish to keep several different\n" | "For various reasons, one may wish to keep several different\n" | ||||||
| "configurations available on a single machine.\n" | "configurations available on a single machine.\n" | ||||||
| "\n" | "\n" | ||||||
| @@ -196,11 +196,11 @@ load_config_help[] = N_( | |||||||
| "default one, entering its name here will allow you to load and modify\n" | "default one, entering its name here will allow you to load and modify\n" | ||||||
| "that configuration.\n" | "that configuration.\n" | ||||||
| "\n" | "\n" | ||||||
| "Leave empty to abort.\n"), | "Leave empty to abort.\n", | ||||||
| save_config_text[] = N_( | save_config_text[] = | ||||||
| "Enter a filename to which this configuration should be saved\n" | "Enter a filename to which this configuration should be saved\n" | ||||||
| "as an alternate.  Leave empty to abort."), | "as an alternate.  Leave empty to abort.", | ||||||
| save_config_help[] = N_( | save_config_help[] = | ||||||
| "For various reasons, one may wish to keep several different\n" | "For various reasons, one may wish to keep several different\n" | ||||||
| "configurations available on a single machine.\n" | "configurations available on a single machine.\n" | ||||||
| "\n" | "\n" | ||||||
| @@ -208,8 +208,8 @@ save_config_help[] = N_( | |||||||
| "and use the current configuration as an alternate to whatever\n" | "and use the current configuration as an alternate to whatever\n" | ||||||
| "configuration options you have selected at that time.\n" | "configuration options you have selected at that time.\n" | ||||||
| "\n" | "\n" | ||||||
| "Leave empty to abort.\n"), | "Leave empty to abort.\n", | ||||||
| search_help[] = N_( | search_help[] = | ||||||
| "Search for symbols (configuration variable names CONFIG_*) and display\n" | "Search for symbols (configuration variable names CONFIG_*) and display\n" | ||||||
| "their relations.  Regular expressions are supported.\n" | "their relations.  Regular expressions are supported.\n" | ||||||
| "Example:  Search for \"^FOO\".\n" | "Example:  Search for \"^FOO\".\n" | ||||||
| @@ -246,7 +246,7 @@ search_help[] = N_( | |||||||
| "USB  => find all symbols containing USB\n" | "USB  => find all symbols containing USB\n" | ||||||
| "^USB => find all symbols starting with USB\n" | "^USB => find all symbols starting with USB\n" | ||||||
| "USB$ => find all symbols ending with USB\n" | "USB$ => find all symbols ending with USB\n" | ||||||
| "\n"); | "\n"; | ||||||
|  |  | ||||||
| struct mitem { | struct mitem { | ||||||
| 	char str[256]; | 	char str[256]; | ||||||
| @@ -270,10 +270,10 @@ static int mwin_max_cols; | |||||||
| static MENU *curses_menu; | static MENU *curses_menu; | ||||||
| static ITEM *curses_menu_items[MAX_MENU_ITEMS]; | static ITEM *curses_menu_items[MAX_MENU_ITEMS]; | ||||||
| static struct mitem k_menu_items[MAX_MENU_ITEMS]; | static struct mitem k_menu_items[MAX_MENU_ITEMS]; | ||||||
| static int items_num; | static unsigned 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; | ||||||
| @@ -307,7 +307,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", | ||||||
| @@ -372,25 +372,25 @@ static void print_function_line(void) | |||||||
| 	int lines = getmaxy(stdscr); | 	int lines = getmaxy(stdscr); | ||||||
|  |  | ||||||
| 	for (i = 0; i < function_keys_num; i++) { | 	for (i = 0; i < function_keys_num; i++) { | ||||||
| 		(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); | 		wattrset(main_window, attr_function_highlight); | ||||||
| 		mvwprintw(main_window, lines-3, offset, | 		mvwprintw(main_window, lines-3, offset, | ||||||
| 				"%s", | 				"%s", | ||||||
| 				function_keys[i].key_str); | 				function_keys[i].key_str); | ||||||
| 		(void) wattrset(main_window, attributes[FUNCTION_TEXT]); | 		wattrset(main_window, attr_function_text); | ||||||
| 		offset += strlen(function_keys[i].key_str); | 		offset += strlen(function_keys[i].key_str); | ||||||
| 		mvwprintw(main_window, lines-3, | 		mvwprintw(main_window, lines-3, | ||||||
| 				offset, "%s", | 				offset, "%s", | ||||||
| 				function_keys[i].func); | 				function_keys[i].func); | ||||||
| 		offset += strlen(function_keys[i].func) + skip; | 		offset += strlen(function_keys[i].func) + skip; | ||||||
| 	} | 	} | ||||||
| 	(void) wattrset(main_window, attributes[NORMAL]); | 	wattrset(main_window, attr_normal); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* help */ | /* help */ | ||||||
| static void handle_f1(int *key, struct menu *current_item) | static void handle_f1(int *key, struct menu *current_item) | ||||||
| { | { | ||||||
| 	show_scroll_win(main_window, | 	show_scroll_win(main_window, | ||||||
| 			_("Global help"), _(nconf_global_help)); | 			"Global help", nconf_global_help); | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -405,8 +405,8 @@ static void handle_f2(int *key, struct menu *current_item) | |||||||
| static void handle_f3(int *key, struct menu *current_item) | static void handle_f3(int *key, struct menu *current_item) | ||||||
| { | { | ||||||
| 	show_scroll_win(main_window, | 	show_scroll_win(main_window, | ||||||
| 			_("Short help"), | 			"Short help", | ||||||
| 			_(current_instructions)); | 			current_instructions); | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -414,7 +414,7 @@ static void handle_f3(int *key, struct menu *current_item) | |||||||
| static void handle_f4(int *key, struct menu *current_item) | static void handle_f4(int *key, struct menu *current_item) | ||||||
| { | { | ||||||
| 	int res = btn_dialog(main_window, | 	int res = btn_dialog(main_window, | ||||||
| 			_("Show all symbols?"), | 			"Show all symbols?", | ||||||
| 			2, | 			2, | ||||||
| 			"   <Show All>   ", | 			"   <Show All>   ", | ||||||
| 			"<Don't show all>"); | 			"<Don't show all>"); | ||||||
| @@ -498,19 +498,23 @@ typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, | |||||||
| /* return the index of the matched item, or -1 if no such item exists */ | /* return the index of the matched item, or -1 if no such item exists */ | ||||||
| static int get_mext_match(const char *match_str, match_f flag) | static int get_mext_match(const char *match_str, match_f flag) | ||||||
| { | { | ||||||
| 	int match_start = item_index(current_item(curses_menu)); | 	int match_start, index; | ||||||
| 	int index; |  | ||||||
|  | 	/* Do not search if the menu is empty (i.e. items_num == 0) */ | ||||||
|  | 	match_start = item_index(current_item(curses_menu)); | ||||||
|  | 	if (match_start == ERR) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
| 	if (flag == FIND_NEXT_MATCH_DOWN) | 	if (flag == FIND_NEXT_MATCH_DOWN) | ||||||
| 		++match_start; | 		++match_start; | ||||||
| 	else if (flag == FIND_NEXT_MATCH_UP) | 	else if (flag == FIND_NEXT_MATCH_UP) | ||||||
| 		--match_start; | 		--match_start; | ||||||
|  |  | ||||||
|  | 	match_start = (match_start + items_num) % items_num; | ||||||
| 	index = match_start; | 	index = match_start; | ||||||
| 	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) | ||||||
| @@ -629,19 +633,12 @@ static int item_is_tag(char tag) | |||||||
|  |  | ||||||
| static char filename[PATH_MAX+1]; | static char filename[PATH_MAX+1]; | ||||||
| static char menu_backtitle[PATH_MAX+128]; | static char menu_backtitle[PATH_MAX+128]; | ||||||
| static const char *set_config_filename(const char *config_filename) | static void set_config_filename(const char *config_filename) | ||||||
| { | { | ||||||
| 	int size; | 	snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", | ||||||
|  | 		 config_filename, rootmenu.prompt->text); | ||||||
|  |  | ||||||
| 	size = snprintf(menu_backtitle, sizeof(menu_backtitle), | 	snprintf(filename, sizeof(filename), "%s", config_filename); | ||||||
| 			"%s - %s", config_filename, rootmenu.prompt->text); |  | ||||||
| 	if (size >= sizeof(menu_backtitle)) |  | ||||||
| 		menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; |  | ||||||
|  |  | ||||||
| 	size = snprintf(filename, sizeof(filename), "%s", config_filename); |  | ||||||
| 	if (size >= sizeof(filename)) |  | ||||||
| 		filename[sizeof(filename)-1] = '\0'; |  | ||||||
| 	return menu_backtitle; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* return = 0 means we are successful. | /* return = 0 means we are successful. | ||||||
| @@ -657,8 +654,8 @@ static int do_exit(void) | |||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	res = btn_dialog(main_window, | 	res = btn_dialog(main_window, | ||||||
| 			_("Do you wish to save your new configuration?\n" | 			"Do you wish to save your new configuration?\n" | ||||||
| 				"<ESC> to cancel and resume nconfig."), | 				"<ESC> to cancel and resume nconfig.", | ||||||
| 			2, | 			2, | ||||||
| 			"   <save>   ", | 			"   <save>   ", | ||||||
| 			"<don't save>"); | 			"<don't save>"); | ||||||
| @@ -670,7 +667,7 @@ static int do_exit(void) | |||||||
| 	env = getenv("KCONFIG_STRICT"); | 	env = getenv("KCONFIG_STRICT"); | ||||||
| 	if (env && *env && kconfig_warnings) { | 	if (env && *env && kconfig_warnings) { | ||||||
| 		btn_dialog(main_window, | 		btn_dialog(main_window, | ||||||
| 			_("\nWarnings encountered, and warnings are errors.\n\n"), | 			"\nWarnings encountered, and warnings are errors.\n\n", | ||||||
| 			1, | 			1, | ||||||
| 			"<OK>"); | 			"<OK>"); | ||||||
| 		res = 2; | 		res = 2; | ||||||
| @@ -683,15 +680,16 @@ static int do_exit(void) | |||||||
| 		if (res) | 		if (res) | ||||||
| 			btn_dialog( | 			btn_dialog( | ||||||
| 				main_window, | 				main_window, | ||||||
| 				_("Error during writing of configuration.\n" | 				"Error during writing of configuration.\n" | ||||||
| 				  "Your configuration changes were NOT saved."), | 				  "Your configuration changes were NOT saved.", | ||||||
| 				  1, | 				  1, | ||||||
| 				  "<OK>"); | 				  "<OK>"); | ||||||
|  | 		conf_write_autoconf(0); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		btn_dialog( | 		btn_dialog( | ||||||
| 			main_window, | 			main_window, | ||||||
| 			_("Your configuration changes were NOT saved."), | 			"Your configuration changes were NOT saved.", | ||||||
| 			1, | 			1, | ||||||
| 			"<OK>"); | 			"<OK>"); | ||||||
| 		break; | 		break; | ||||||
| @@ -710,12 +708,12 @@ static void search_conf(void) | |||||||
| 	int dres; | 	int dres; | ||||||
|  |  | ||||||
| 	title = str_new(); | 	title = str_new(); | ||||||
| 	str_printf( &title, _("Enter (sub)string or regexp to search for " | 	str_printf( &title, "Enter (sub)string or regexp to search for " | ||||||
| 			      "(with or without \"%s\")"), CONFIG_); | 			      "(with or without \"%s\")", CONFIG_); | ||||||
|  |  | ||||||
| again: | again: | ||||||
| 	dres = dialog_inputbox(main_window, | 	dres = dialog_inputbox(main_window, | ||||||
| 			_("Search Configuration Parameter"), | 			"Search Configuration Parameter", | ||||||
| 			str_get(&title), | 			str_get(&title), | ||||||
| 			"", &dialog_input_result, &dialog_input_result_len); | 			"", &dialog_input_result, &dialog_input_result_len); | ||||||
| 	switch (dres) { | 	switch (dres) { | ||||||
| @@ -723,7 +721,7 @@ again: | |||||||
| 		break; | 		break; | ||||||
| 	case 1: | 	case 1: | ||||||
| 		show_scroll_win(main_window, | 		show_scroll_win(main_window, | ||||||
| 				_("Search Configuration"), search_help); | 				"Search Configuration", search_help); | ||||||
| 		goto again; | 		goto again; | ||||||
| 	default: | 	default: | ||||||
| 		str_free(&title); | 		str_free(&title); | ||||||
| @@ -739,7 +737,7 @@ again: | |||||||
| 	res = get_relations_str(sym_arr, NULL); | 	res = get_relations_str(sym_arr, NULL); | ||||||
| 	free(sym_arr); | 	free(sym_arr); | ||||||
| 	show_scroll_win(main_window, | 	show_scroll_win(main_window, | ||||||
| 			_("Search Results"), str_get(&res)); | 			"Search Results", str_get(&res)); | ||||||
| 	str_free(&res); | 	str_free(&res); | ||||||
| 	str_free(&title); | 	str_free(&title); | ||||||
| } | } | ||||||
| @@ -767,7 +765,6 @@ static void build_conf(struct menu *menu) | |||||||
| 			switch (ptype) { | 			switch (ptype) { | ||||||
| 			case P_MENU: | 			case P_MENU: | ||||||
| 				child_count++; | 				child_count++; | ||||||
| 				prompt = _(prompt); |  | ||||||
| 				if (single_menu_mode) { | 				if (single_menu_mode) { | ||||||
| 					item_make(menu, 'm', | 					item_make(menu, 'm', | ||||||
| 						"%s%*c%s", | 						"%s%*c%s", | ||||||
| @@ -788,7 +785,7 @@ static void build_conf(struct menu *menu) | |||||||
| 					item_make(menu, ':', | 					item_make(menu, ':', | ||||||
| 						"   %*c*** %s ***", | 						"   %*c*** %s ***", | ||||||
| 						indent + 1, ' ', | 						indent + 1, ' ', | ||||||
| 						_(prompt)); | 						prompt); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			default: | 			default: | ||||||
| @@ -796,7 +793,7 @@ static void build_conf(struct menu *menu) | |||||||
| 					child_count++; | 					child_count++; | ||||||
| 					item_make(menu, ':', "---%*c%s", | 					item_make(menu, ':', "---%*c%s", | ||||||
| 						indent + 1, ' ', | 						indent + 1, ' ', | ||||||
| 						_(prompt)); | 						prompt); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else | 		} else | ||||||
| @@ -816,7 +813,7 @@ static void build_conf(struct menu *menu) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		val = sym_get_tristate_value(sym); | 		val = sym_get_tristate_value(sym); | ||||||
| 		if (sym_is_changable(sym)) { | 		if (sym_is_changeable(sym)) { | ||||||
| 			switch (type) { | 			switch (type) { | ||||||
| 			case S_BOOLEAN: | 			case S_BOOLEAN: | ||||||
| 				item_make(menu, 't', "[%c]", | 				item_make(menu, 't', "[%c]", | ||||||
| @@ -842,11 +839,11 @@ static void build_conf(struct menu *menu) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		item_add_str("%*c%s", indent + 1, | 		item_add_str("%*c%s", indent + 1, | ||||||
| 				' ', _(menu_get_prompt(menu))); | 				' ', menu_get_prompt(menu)); | ||||||
| 		if (val == yes) { | 		if (val == yes) { | ||||||
| 			if (def_menu) { | 			if (def_menu) { | ||||||
| 				item_add_str(" (%s)", | 				item_add_str(" (%s)", | ||||||
| 					_(menu_get_prompt(def_menu))); | 					menu_get_prompt(def_menu)); | ||||||
| 				item_add_str("  --->"); | 				item_add_str("  --->"); | ||||||
| 				if (def_menu->list) { | 				if (def_menu->list) { | ||||||
| 					indent += 2; | 					indent += 2; | ||||||
| @@ -860,7 +857,7 @@ static void build_conf(struct menu *menu) | |||||||
| 		if (menu == current_menu) { | 		if (menu == current_menu) { | ||||||
| 			item_make(menu, ':', | 			item_make(menu, ':', | ||||||
| 				"---%*c%s", indent + 1, | 				"---%*c%s", indent + 1, | ||||||
| 				' ', _(menu_get_prompt(menu))); | 				' ', menu_get_prompt(menu)); | ||||||
| 			goto conf_childs; | 			goto conf_childs; | ||||||
| 		} | 		} | ||||||
| 		child_count++; | 		child_count++; | ||||||
| @@ -870,7 +867,7 @@ static void build_conf(struct menu *menu) | |||||||
| 		} else { | 		} else { | ||||||
| 			switch (type) { | 			switch (type) { | ||||||
| 			case S_BOOLEAN: | 			case S_BOOLEAN: | ||||||
| 				if (sym_is_changable(sym)) | 				if (sym_is_changeable(sym)) | ||||||
| 					item_make(menu, 't', "[%c]", | 					item_make(menu, 't', "[%c]", | ||||||
| 						val == no ? ' ' : '*'); | 						val == no ? ' ' : '*'); | ||||||
| 				else | 				else | ||||||
| @@ -889,7 +886,7 @@ static void build_conf(struct menu *menu) | |||||||
| 					ch = ' '; | 					ch = ' '; | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 				if (sym_is_changable(sym)) { | 				if (sym_is_changeable(sym)) { | ||||||
| 					if (sym->rev_dep.tri == mod) | 					if (sym->rev_dep.tri == mod) | ||||||
| 						item_make(menu, | 						item_make(menu, | ||||||
| 							't', "{%c}", ch); | 							't', "{%c}", ch); | ||||||
| @@ -907,17 +904,17 @@ static void build_conf(struct menu *menu) | |||||||
| 				if (tmp < 0) | 				if (tmp < 0) | ||||||
| 					tmp = 0; | 					tmp = 0; | ||||||
| 				item_add_str("%*c%s%s", tmp, ' ', | 				item_add_str("%*c%s%s", tmp, ' ', | ||||||
| 						_(menu_get_prompt(menu)), | 						menu_get_prompt(menu), | ||||||
| 						(sym_has_value(sym) || | 						(sym_has_value(sym) || | ||||||
| 						 !sym_is_changable(sym)) ? "" : | 						 !sym_is_changeable(sym)) ? "" : | ||||||
| 						_(" (NEW)")); | 						" (NEW)"); | ||||||
| 				goto conf_childs; | 				goto conf_childs; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		item_add_str("%*c%s%s", indent + 1, ' ', | 		item_add_str("%*c%s%s", indent + 1, ' ', | ||||||
| 				_(menu_get_prompt(menu)), | 				menu_get_prompt(menu), | ||||||
| 				(sym_has_value(sym) || !sym_is_changable(sym)) ? | 				(sym_has_value(sym) || !sym_is_changeable(sym)) ? | ||||||
| 				"" : _(" (NEW)")); | 				"" : " (NEW)"); | ||||||
| 		if (menu->prompt && menu->prompt->type == P_MENU) { | 		if (menu->prompt && menu->prompt->type == P_MENU) { | ||||||
| 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->"); | 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->"); | ||||||
| 			return; | 			return; | ||||||
| @@ -969,16 +966,15 @@ static void show_menu(const char *prompt, const char *instructions, | |||||||
| 	current_instructions = instructions; | 	current_instructions = instructions; | ||||||
|  |  | ||||||
| 	clear(); | 	clear(); | ||||||
| 	(void) wattrset(main_window, attributes[NORMAL]); | 	print_in_middle(stdscr, 1, getmaxx(stdscr), | ||||||
| 	print_in_middle(stdscr, 1, 0, getmaxx(stdscr), |  | ||||||
| 			menu_backtitle, | 			menu_backtitle, | ||||||
| 			attributes[MAIN_HEADING]); | 			attr_main_heading); | ||||||
|  |  | ||||||
| 	(void) wattrset(main_window, attributes[MAIN_MENU_BOX]); | 	wattrset(main_window, attr_main_menu_box); | ||||||
| 	box(main_window, 0, 0); | 	box(main_window, 0, 0); | ||||||
| 	(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]); | 	wattrset(main_window, attr_main_menu_heading); | ||||||
| 	mvwprintw(main_window, 0, 3, " %s ", prompt); | 	mvwprintw(main_window, 0, 3, " %s ", prompt); | ||||||
| 	(void) wattrset(main_window, attributes[NORMAL]); | 	wattrset(main_window, attr_normal); | ||||||
|  |  | ||||||
| 	set_menu_items(curses_menu, curses_menu_items); | 	set_menu_items(curses_menu, curses_menu_items); | ||||||
|  |  | ||||||
| @@ -1061,7 +1057,7 @@ static int do_match(int key, struct match_state *state, int *ans) | |||||||
| 		state->match_direction = FIND_NEXT_MATCH_UP; | 		state->match_direction = FIND_NEXT_MATCH_UP; | ||||||
| 		*ans = get_mext_match(state->pattern, | 		*ans = get_mext_match(state->pattern, | ||||||
| 				state->match_direction); | 				state->match_direction); | ||||||
| 	} else if (key == KEY_BACKSPACE || key == 127) { | 	} else if (key == KEY_BACKSPACE || key == 8 || key == 127) { | ||||||
| 		state->pattern[strlen(state->pattern)-1] = '\0'; | 		state->pattern[strlen(state->pattern)-1] = '\0'; | ||||||
| 		adj_match_dir(&state->match_direction); | 		adj_match_dir(&state->match_direction); | ||||||
| 	} else | 	} else | ||||||
| @@ -1081,7 +1077,6 @@ 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 = NULL; | 	struct menu *submenu = NULL; | ||||||
| 	const char *prompt = menu_get_prompt(menu); |  | ||||||
| 	struct symbol *sym; | 	struct symbol *sym; | ||||||
| 	int res; | 	int res; | ||||||
| 	int current_index = 0; | 	int current_index = 0; | ||||||
| @@ -1099,9 +1094,8 @@ static void conf(struct menu *menu) | |||||||
| 		if (!child_count) | 		if (!child_count) | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		show_menu(prompt ? _(prompt) : _("Main Menu"), | 		show_menu(menu_get_prompt(menu), menu_instructions, | ||||||
| 				_(menu_instructions), | 			  current_index, &last_top_row); | ||||||
| 				current_index, &last_top_row); |  | ||||||
| 		keypad((menu_win(curses_menu)), TRUE); | 		keypad((menu_win(curses_menu)), TRUE); | ||||||
| 		while (!global_exit) { | 		while (!global_exit) { | ||||||
| 			if (match_state.in_search) { | 			if (match_state.in_search) { | ||||||
| @@ -1223,12 +1217,9 @@ static void conf(struct menu *menu) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| static void conf_message_callback(const char *fmt, va_list ap) | static void conf_message_callback(const char *s) | ||||||
| { | { | ||||||
| 	char buf[1024]; | 	btn_dialog(main_window, s, 1, "<OK>"); | ||||||
|  |  | ||||||
| 	vsnprintf(buf, sizeof(buf), fmt, ap); |  | ||||||
| 	btn_dialog(main_window, buf, 1, "<OK>"); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void show_help(struct menu *menu) | static void show_help(struct menu *menu) | ||||||
| @@ -1240,13 +1231,13 @@ static void show_help(struct menu *menu) | |||||||
|  |  | ||||||
| 	help = str_new(); | 	help = str_new(); | ||||||
| 	menu_get_ext_help(menu, &help); | 	menu_get_ext_help(menu, &help); | ||||||
| 	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); | 	show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help)); | ||||||
| 	str_free(&help); | 	str_free(&help); | ||||||
| } | } | ||||||
|  |  | ||||||
| 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 = NULL; | 	struct menu *child = NULL; | ||||||
| 	struct symbol *active; | 	struct symbol *active; | ||||||
| 	int selected_index = 0; | 	int selected_index = 0; | ||||||
| @@ -1269,13 +1260,13 @@ static void conf_choice(struct menu *menu) | |||||||
|  |  | ||||||
| 			if (child->sym == sym_get_choice_value(menu->sym)) | 			if (child->sym == sym_get_choice_value(menu->sym)) | ||||||
| 				item_make(child, ':', "<X> %s", | 				item_make(child, ':', "<X> %s", | ||||||
| 						_(menu_get_prompt(child))); | 						menu_get_prompt(child)); | ||||||
| 			else if (child->sym) | 			else if (child->sym) | ||||||
| 				item_make(child, ':', "    %s", | 				item_make(child, ':', "    %s", | ||||||
| 						_(menu_get_prompt(child))); | 						menu_get_prompt(child)); | ||||||
| 			else | 			else | ||||||
| 				item_make(child, ':', "*** %s ***", | 				item_make(child, ':', "*** %s ***", | ||||||
| 						_(menu_get_prompt(child))); | 						menu_get_prompt(child)); | ||||||
|  |  | ||||||
| 			if (child->sym == active){ | 			if (child->sym == active){ | ||||||
| 				last_top_row = top_row(curses_menu); | 				last_top_row = top_row(curses_menu); | ||||||
| @@ -1283,8 +1274,8 @@ static void conf_choice(struct menu *menu) | |||||||
| 			} | 			} | ||||||
| 			i++; | 			i++; | ||||||
| 		} | 		} | ||||||
| 		show_menu(prompt ? _(prompt) : _("Choice Menu"), | 		show_menu(prompt ? prompt : "Choice Menu", | ||||||
| 				_(radiolist_instructions), | 				radiolist_instructions, | ||||||
| 				selected_index, | 				selected_index, | ||||||
| 				&last_top_row); | 				&last_top_row); | ||||||
| 		while (!global_exit) { | 		while (!global_exit) { | ||||||
| @@ -1371,19 +1362,19 @@ static void conf_string(struct menu *menu) | |||||||
|  |  | ||||||
| 		switch (sym_get_type(menu->sym)) { | 		switch (sym_get_type(menu->sym)) { | ||||||
| 		case S_INT: | 		case S_INT: | ||||||
| 			heading = _(inputbox_instructions_int); | 			heading = inputbox_instructions_int; | ||||||
| 			break; | 			break; | ||||||
| 		case S_HEX: | 		case S_HEX: | ||||||
| 			heading = _(inputbox_instructions_hex); | 			heading = inputbox_instructions_hex; | ||||||
| 			break; | 			break; | ||||||
| 		case S_STRING: | 		case S_STRING: | ||||||
| 			heading = _(inputbox_instructions_string); | 			heading = inputbox_instructions_string; | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			heading = _("Internal nconf error!"); | 			heading = "Internal nconf error!"; | ||||||
| 		} | 		} | ||||||
| 		res = dialog_inputbox(main_window, | 		res = dialog_inputbox(main_window, | ||||||
| 				prompt ? _(prompt) : _("Main Menu"), | 				prompt ? prompt : "Main Menu", | ||||||
| 				heading, | 				heading, | ||||||
| 				sym_get_string_value(menu->sym), | 				sym_get_string_value(menu->sym), | ||||||
| 				&dialog_input_result, | 				&dialog_input_result, | ||||||
| @@ -1394,7 +1385,7 @@ static void conf_string(struct menu *menu) | |||||||
| 						dialog_input_result)) | 						dialog_input_result)) | ||||||
| 				return; | 				return; | ||||||
| 			btn_dialog(main_window, | 			btn_dialog(main_window, | ||||||
| 				_("You have made an invalid entry."), 0); | 				"You have made an invalid entry.", 0); | ||||||
| 			break; | 			break; | ||||||
| 		case 1: | 		case 1: | ||||||
| 			show_help(menu); | 			show_help(menu); | ||||||
| @@ -1420,14 +1411,14 @@ static void conf_load(void) | |||||||
| 				return; | 				return; | ||||||
| 			if (!conf_read(dialog_input_result)) { | 			if (!conf_read(dialog_input_result)) { | ||||||
| 				set_config_filename(dialog_input_result); | 				set_config_filename(dialog_input_result); | ||||||
| 				sym_set_change_count(1); | 				conf_set_changed(true); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			btn_dialog(main_window, _("File does not exist!"), 0); | 			btn_dialog(main_window, "File does not exist!", 0); | ||||||
| 			break; | 			break; | ||||||
| 		case 1: | 		case 1: | ||||||
| 			show_scroll_win(main_window, | 			show_scroll_win(main_window, | ||||||
| 					_("Load Alternate Configuration"), | 					"Load Alternate Configuration", | ||||||
| 					load_config_help); | 					load_config_help); | ||||||
| 			break; | 			break; | ||||||
| 		case KEY_EXIT: | 		case KEY_EXIT: | ||||||
| @@ -1454,13 +1445,12 @@ static void conf_save(void) | |||||||
| 				set_config_filename(dialog_input_result); | 				set_config_filename(dialog_input_result); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			btn_dialog(main_window, _("Can't create file! " | 			btn_dialog(main_window, "Can't create file!", | ||||||
| 				"Probably a nonexistent directory."), |  | ||||||
| 				1, "<OK>"); | 				1, "<OK>"); | ||||||
| 			break; | 			break; | ||||||
| 		case 1: | 		case 1: | ||||||
| 			show_scroll_win(main_window, | 			show_scroll_win(main_window, | ||||||
| 				_("Save Alternate Configuration"), | 				"Save Alternate Configuration", | ||||||
| 				save_config_help); | 				save_config_help); | ||||||
| 			break; | 			break; | ||||||
| 		case KEY_EXIT: | 		case KEY_EXIT: | ||||||
| @@ -1469,7 +1459,7 @@ static void conf_save(void) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void setup_windows(void) | static void setup_windows(void) | ||||||
| { | { | ||||||
| 	int lines, columns; | 	int lines, columns; | ||||||
|  |  | ||||||
| @@ -1493,10 +1483,11 @@ int main(int ac, char **av) | |||||||
| 	int lines, columns; | 	int lines, columns; | ||||||
| 	char *mode; | 	char *mode; | ||||||
|  |  | ||||||
| 	setlocale(LC_ALL, ""); | 	if (ac > 1 && strcmp(av[1], "-s") == 0) { | ||||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); | 		/* Silence conf_read() until the real callback is set up */ | ||||||
| 	textdomain(PACKAGE); | 		conf_set_message_callback(NULL); | ||||||
|  | 		av++; | ||||||
|  | 	} | ||||||
| 	conf_parse(av[1]); | 	conf_parse(av[1]); | ||||||
| 	conf_read(NULL); | 	conf_read(NULL); | ||||||
|  |  | ||||||
| @@ -1539,9 +1530,9 @@ int main(int ac, char **av) | |||||||
| 	menu_opts_on(curses_menu, O_NONCYCLIC); | 	menu_opts_on(curses_menu, O_NONCYCLIC); | ||||||
| 	menu_opts_on(curses_menu, O_IGNORECASE); | 	menu_opts_on(curses_menu, O_IGNORECASE); | ||||||
| 	set_menu_mark(curses_menu, " "); | 	set_menu_mark(curses_menu, " "); | ||||||
| 	set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); | 	set_menu_fore(curses_menu, attr_main_menu_fore); | ||||||
| 	set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); | 	set_menu_back(curses_menu, attr_main_menu_back); | ||||||
| 	set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); | 	set_menu_grey(curses_menu, attr_main_menu_grey); | ||||||
|  |  | ||||||
| 	set_config_filename(conf_get_configname()); | 	set_config_filename(conf_get_configname()); | ||||||
| 	setup_windows(); | 	setup_windows(); | ||||||
| @@ -1549,8 +1540,8 @@ int main(int ac, char **av) | |||||||
| 	/* check for KEY_FUNC(1) */ | 	/* check for KEY_FUNC(1) */ | ||||||
| 	if (has_key(KEY_F(1)) == FALSE) { | 	if (has_key(KEY_F(1)) == FALSE) { | ||||||
| 		show_scroll_win(main_window, | 		show_scroll_win(main_window, | ||||||
| 				_("Instructions"), | 				"Instructions", | ||||||
| 				_(menu_no_f_instructions)); | 				menu_no_f_instructions); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	conf_set_message_callback(conf_message_callback); | 	conf_set_message_callback(conf_message_callback); | ||||||
|   | |||||||
| @@ -1,175 +1,126 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? |  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  * |  * | ||||||
|  * Derived from menuconfig. |  * Derived from menuconfig. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| #include "nconf.h" | #include "nconf.h" | ||||||
|  | #include "lkc.h" | ||||||
|  |  | ||||||
| /* a list of all the different widgets we use */ | int attr_normal; | ||||||
| attributes_t attributes[ATTR_MAX+1] = {0}; | int attr_main_heading; | ||||||
|  | int attr_main_menu_box; | ||||||
|  | int attr_main_menu_fore; | ||||||
|  | int attr_main_menu_back; | ||||||
|  | int attr_main_menu_grey; | ||||||
|  | int attr_main_menu_heading; | ||||||
|  | int attr_scrollwin_text; | ||||||
|  | int attr_scrollwin_heading; | ||||||
|  | int attr_scrollwin_box; | ||||||
|  | int attr_dialog_text; | ||||||
|  | int attr_dialog_menu_fore; | ||||||
|  | int attr_dialog_menu_back; | ||||||
|  | int attr_dialog_box; | ||||||
|  | int attr_input_box; | ||||||
|  | int attr_input_heading; | ||||||
|  | int attr_input_text; | ||||||
|  | int attr_input_field; | ||||||
|  | int attr_function_text; | ||||||
|  | int attr_function_highlight; | ||||||
|  |  | ||||||
| /* available colors: | #define COLOR_ATTR(_at, _fg, _bg, _hl) \ | ||||||
|    COLOR_BLACK   0 | 	{ .attr = &(_at), .has_color = true, .color_fg = _fg, .color_bg = _bg, .highlight = _hl } | ||||||
|    COLOR_RED     1 | #define NO_COLOR_ATTR(_at, _hl) \ | ||||||
|    COLOR_GREEN   2 | 	{ .attr = &(_at), .has_color = false, .highlight = _hl } | ||||||
|    COLOR_YELLOW  3 | #define COLOR_DEFAULT		-1 | ||||||
|    COLOR_BLUE    4 |  | ||||||
|    COLOR_MAGENTA 5 | struct nconf_attr_param { | ||||||
|    COLOR_CYAN    6 | 	int *attr; | ||||||
|    COLOR_WHITE   7 | 	bool has_color; | ||||||
|    */ | 	int color_fg; | ||||||
| static void set_normal_colors(void) | 	int color_bg; | ||||||
|  | 	int highlight; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const struct nconf_attr_param color_theme_params[] = { | ||||||
|  | 	COLOR_ATTR(attr_normal,			COLOR_DEFAULT,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_main_heading,		COLOR_MAGENTA,	COLOR_DEFAULT,	A_BOLD | A_UNDERLINE), | ||||||
|  | 	COLOR_ATTR(attr_main_menu_box,		COLOR_YELLOW,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_main_menu_fore,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_REVERSE), | ||||||
|  | 	COLOR_ATTR(attr_main_menu_back,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_main_menu_grey,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_main_menu_heading,	COLOR_GREEN,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	COLOR_ATTR(attr_scrollwin_text,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_scrollwin_heading,	COLOR_GREEN,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	COLOR_ATTR(attr_scrollwin_box,		COLOR_YELLOW,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	COLOR_ATTR(attr_dialog_text,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	COLOR_ATTR(attr_dialog_menu_fore,	COLOR_RED,	COLOR_DEFAULT,	A_STANDOUT), | ||||||
|  | 	COLOR_ATTR(attr_dialog_menu_back,	COLOR_YELLOW,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_dialog_box,		COLOR_YELLOW,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	COLOR_ATTR(attr_input_box,		COLOR_YELLOW,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_input_heading,		COLOR_GREEN,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	COLOR_ATTR(attr_input_text,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_NORMAL), | ||||||
|  | 	COLOR_ATTR(attr_input_field,		COLOR_DEFAULT,	COLOR_DEFAULT,	A_UNDERLINE), | ||||||
|  | 	COLOR_ATTR(attr_function_text,		COLOR_YELLOW,	COLOR_DEFAULT,	A_REVERSE), | ||||||
|  | 	COLOR_ATTR(attr_function_highlight,	COLOR_DEFAULT,	COLOR_DEFAULT,	A_BOLD), | ||||||
|  | 	{ /* sentinel */ } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const struct nconf_attr_param no_color_theme_params[] = { | ||||||
|  | 	NO_COLOR_ATTR(attr_normal,		A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_main_heading,	A_BOLD | A_UNDERLINE), | ||||||
|  | 	NO_COLOR_ATTR(attr_main_menu_box,	A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_main_menu_fore,	A_STANDOUT), | ||||||
|  | 	NO_COLOR_ATTR(attr_main_menu_back,	A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_main_menu_grey,	A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_main_menu_heading,	A_BOLD), | ||||||
|  | 	NO_COLOR_ATTR(attr_scrollwin_text,	A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_scrollwin_heading,	A_BOLD), | ||||||
|  | 	NO_COLOR_ATTR(attr_scrollwin_box,	A_BOLD), | ||||||
|  | 	NO_COLOR_ATTR(attr_dialog_text,		A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_dialog_menu_fore,	A_STANDOUT), | ||||||
|  | 	NO_COLOR_ATTR(attr_dialog_menu_back,	A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_dialog_box,		A_BOLD), | ||||||
|  | 	NO_COLOR_ATTR(attr_input_box,		A_BOLD), | ||||||
|  | 	NO_COLOR_ATTR(attr_input_heading,	A_BOLD), | ||||||
|  | 	NO_COLOR_ATTR(attr_input_text,		A_NORMAL), | ||||||
|  | 	NO_COLOR_ATTR(attr_input_field,		A_UNDERLINE), | ||||||
|  | 	NO_COLOR_ATTR(attr_function_text,	A_REVERSE), | ||||||
|  | 	NO_COLOR_ATTR(attr_function_highlight,	A_BOLD), | ||||||
|  | 	{ /* sentinel */ } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void set_colors(void) | ||||||
| { | { | ||||||
| 	init_pair(NORMAL, -1, -1); | 	const struct nconf_attr_param *p; | ||||||
| 	init_pair(MAIN_HEADING, COLOR_MAGENTA, -1); | 	int pair = 0; | ||||||
|  |  | ||||||
| 	/* FORE is for the selected item */ |  | ||||||
| 	init_pair(MAIN_MENU_FORE, -1, -1); |  | ||||||
| 	/* BACK for all the rest */ |  | ||||||
| 	init_pair(MAIN_MENU_BACK, -1, -1); |  | ||||||
| 	init_pair(MAIN_MENU_GREY, -1, -1); |  | ||||||
| 	init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1); |  | ||||||
| 	init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1); |  | ||||||
|  |  | ||||||
| 	init_pair(SCROLLWIN_TEXT, -1, -1); |  | ||||||
| 	init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1); |  | ||||||
| 	init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1); |  | ||||||
|  |  | ||||||
| 	init_pair(DIALOG_TEXT, -1, -1); |  | ||||||
| 	init_pair(DIALOG_BOX, COLOR_YELLOW, -1); |  | ||||||
| 	init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1); |  | ||||||
| 	init_pair(DIALOG_MENU_FORE, COLOR_RED, -1); |  | ||||||
|  |  | ||||||
| 	init_pair(INPUT_BOX, COLOR_YELLOW, -1); |  | ||||||
| 	init_pair(INPUT_HEADING, COLOR_GREEN, -1); |  | ||||||
| 	init_pair(INPUT_TEXT, -1, -1); |  | ||||||
| 	init_pair(INPUT_FIELD, -1, -1); |  | ||||||
|  |  | ||||||
| 	init_pair(FUNCTION_HIGHLIGHT, -1, -1); |  | ||||||
| 	init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* available attributes: |  | ||||||
|    A_NORMAL        Normal display (no highlight) |  | ||||||
|    A_STANDOUT      Best highlighting mode of the terminal. |  | ||||||
|    A_UNDERLINE     Underlining |  | ||||||
|    A_REVERSE       Reverse video |  | ||||||
|    A_BLINK         Blinking |  | ||||||
|    A_DIM           Half bright |  | ||||||
|    A_BOLD          Extra bright or bold |  | ||||||
|    A_PROTECT       Protected mode |  | ||||||
|    A_INVIS         Invisible or blank mode |  | ||||||
|    A_ALTCHARSET    Alternate character set |  | ||||||
|    A_CHARTEXT      Bit-mask to extract a character |  | ||||||
|    COLOR_PAIR(n)   Color-pair number n |  | ||||||
|    */ |  | ||||||
| static void normal_color_theme(void) |  | ||||||
| { |  | ||||||
| 	/* automatically add color... */ |  | ||||||
| #define mkattr(name, attr) do { \ |  | ||||||
| attributes[name] = attr | COLOR_PAIR(name); } while (0) |  | ||||||
| 	mkattr(NORMAL, NORMAL); |  | ||||||
| 	mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE); |  | ||||||
|  |  | ||||||
| 	mkattr(MAIN_MENU_FORE, A_REVERSE); |  | ||||||
| 	mkattr(MAIN_MENU_BACK, A_NORMAL); |  | ||||||
| 	mkattr(MAIN_MENU_GREY, A_NORMAL); |  | ||||||
| 	mkattr(MAIN_MENU_HEADING, A_BOLD); |  | ||||||
| 	mkattr(MAIN_MENU_BOX, A_NORMAL); |  | ||||||
|  |  | ||||||
| 	mkattr(SCROLLWIN_TEXT, A_NORMAL); |  | ||||||
| 	mkattr(SCROLLWIN_HEADING, A_BOLD); |  | ||||||
| 	mkattr(SCROLLWIN_BOX, A_BOLD); |  | ||||||
|  |  | ||||||
| 	mkattr(DIALOG_TEXT, A_BOLD); |  | ||||||
| 	mkattr(DIALOG_BOX, A_BOLD); |  | ||||||
| 	mkattr(DIALOG_MENU_FORE, A_STANDOUT); |  | ||||||
| 	mkattr(DIALOG_MENU_BACK, A_NORMAL); |  | ||||||
|  |  | ||||||
| 	mkattr(INPUT_BOX, A_NORMAL); |  | ||||||
| 	mkattr(INPUT_HEADING, A_BOLD); |  | ||||||
| 	mkattr(INPUT_TEXT, A_NORMAL); |  | ||||||
| 	mkattr(INPUT_FIELD, A_UNDERLINE); |  | ||||||
|  |  | ||||||
| 	mkattr(FUNCTION_HIGHLIGHT, A_BOLD); |  | ||||||
| 	mkattr(FUNCTION_TEXT, A_REVERSE); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void no_colors_theme(void) |  | ||||||
| { |  | ||||||
| 	/* automatically add highlight, no color */ |  | ||||||
| #define mkattrn(name, attr) { attributes[name] = attr; } |  | ||||||
|  |  | ||||||
| 	mkattrn(NORMAL, NORMAL); |  | ||||||
| 	mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE); |  | ||||||
|  |  | ||||||
| 	mkattrn(MAIN_MENU_FORE, A_STANDOUT); |  | ||||||
| 	mkattrn(MAIN_MENU_BACK, A_NORMAL); |  | ||||||
| 	mkattrn(MAIN_MENU_GREY, A_NORMAL); |  | ||||||
| 	mkattrn(MAIN_MENU_HEADING, A_BOLD); |  | ||||||
| 	mkattrn(MAIN_MENU_BOX, A_NORMAL); |  | ||||||
|  |  | ||||||
| 	mkattrn(SCROLLWIN_TEXT, A_NORMAL); |  | ||||||
| 	mkattrn(SCROLLWIN_HEADING, A_BOLD); |  | ||||||
| 	mkattrn(SCROLLWIN_BOX, A_BOLD); |  | ||||||
|  |  | ||||||
| 	mkattrn(DIALOG_TEXT, A_NORMAL); |  | ||||||
| 	mkattrn(DIALOG_BOX, A_BOLD); |  | ||||||
| 	mkattrn(DIALOG_MENU_FORE, A_STANDOUT); |  | ||||||
| 	mkattrn(DIALOG_MENU_BACK, A_NORMAL); |  | ||||||
|  |  | ||||||
| 	mkattrn(INPUT_BOX, A_BOLD); |  | ||||||
| 	mkattrn(INPUT_HEADING, A_BOLD); |  | ||||||
| 	mkattrn(INPUT_TEXT, A_NORMAL); |  | ||||||
| 	mkattrn(INPUT_FIELD, A_UNDERLINE); |  | ||||||
|  |  | ||||||
| 	mkattrn(FUNCTION_HIGHLIGHT, A_BOLD); |  | ||||||
| 	mkattrn(FUNCTION_TEXT, A_REVERSE); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void set_colors() |  | ||||||
| { |  | ||||||
| 	start_color(); |  | ||||||
| 	use_default_colors(); |  | ||||||
| 	set_normal_colors(); |  | ||||||
| 	if (has_colors()) { | 	if (has_colors()) { | ||||||
| 		normal_color_theme(); | 		start_color(); | ||||||
|  | 		use_default_colors(); | ||||||
|  | 		p = color_theme_params; | ||||||
| 	} else { | 	} else { | ||||||
| 		/* give defaults */ | 		p = no_color_theme_params; | ||||||
| 		no_colors_theme(); | 	} | ||||||
|  |  | ||||||
|  | 	for (; p->attr; p++) { | ||||||
|  | 		int attr = p->highlight; | ||||||
|  |  | ||||||
|  | 		if (p->has_color) { | ||||||
|  | 			pair++; | ||||||
|  | 			init_pair(pair, p->color_fg, p->color_bg); | ||||||
|  | 			attr |= COLOR_PAIR(pair); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		*p->attr = attr; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* this changes the windows attributes !!! */ | /* this changes the windows attributes !!! */ | ||||||
| void print_in_middle(WINDOW *win, | void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs) | ||||||
| 		int starty, | { | ||||||
| 		int startx, | 	wattrset(win, attrs); | ||||||
| 		int width, | 	mvwprintw(win, y, (width - strlen(str)) / 2, "%s", str); | ||||||
| 		const char *string, |  | ||||||
| 		chtype color) |  | ||||||
| {      int length, x, y; |  | ||||||
| 	float temp; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (win == NULL) |  | ||||||
| 		win = stdscr; |  | ||||||
| 	getyx(win, y, x); |  | ||||||
| 	if (startx != 0) |  | ||||||
| 		x = startx; |  | ||||||
| 	if (starty != 0) |  | ||||||
| 		y = starty; |  | ||||||
| 	if (width == 0) |  | ||||||
| 		width = 80; |  | ||||||
|  |  | ||||||
| 	length = strlen(string); |  | ||||||
| 	temp = (width - length) / 2; |  | ||||||
| 	x = startx + (int)temp; |  | ||||||
| 	(void) wattrset(win, color); |  | ||||||
| 	mvwprintw(win, y, x, "%s", string); |  | ||||||
| 	refresh(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int get_line_no(const char *text) | int get_line_no(const char *text) | ||||||
| @@ -192,7 +143,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') | ||||||
| @@ -294,14 +245,14 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) | |||||||
| 	msg_win = derwin(win, win_rows-2, msg_width, 1, | 	msg_win = derwin(win, win_rows-2, msg_width, 1, | ||||||
| 			1+(total_width+2-msg_width)/2); | 			1+(total_width+2-msg_width)/2); | ||||||
|  |  | ||||||
| 	set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); | 	set_menu_fore(menu, attr_dialog_menu_fore); | ||||||
| 	set_menu_back(menu, attributes[DIALOG_MENU_BACK]); | 	set_menu_back(menu, attr_dialog_menu_back); | ||||||
|  |  | ||||||
| 	(void) wattrset(win, attributes[DIALOG_BOX]); | 	wattrset(win, attr_dialog_box); | ||||||
| 	box(win, 0, 0); | 	box(win, 0, 0); | ||||||
|  |  | ||||||
| 	/* print message */ | 	/* print message */ | ||||||
| 	(void) wattrset(msg_win, attributes[DIALOG_TEXT]); | 	wattrset(msg_win, attr_dialog_text); | ||||||
| 	fill_window(msg_win, msg); | 	fill_window(msg_win, msg); | ||||||
|  |  | ||||||
| 	set_menu_win(menu, win); | 	set_menu_win(menu, win); | ||||||
| @@ -364,15 +315,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,28 +339,33 @@ 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); | ||||||
|  |  | ||||||
| 	(void) wattrset(form_win, attributes[INPUT_FIELD]); | 	wattrset(form_win, attr_input_field); | ||||||
|  |  | ||||||
| 	(void) wattrset(win, attributes[INPUT_BOX]); | 	wattrset(win, attr_input_box); | ||||||
| 	box(win, 0, 0); | 	box(win, 0, 0); | ||||||
| 	(void) wattrset(win, attributes[INPUT_HEADING]); | 	wattrset(win, attr_input_heading); | ||||||
| 	if (title) | 	if (title) | ||||||
| 		mvwprintw(win, 0, 3, "%s", title); | 		mvwprintw(win, 0, 3, "%s", title); | ||||||
|  |  | ||||||
| 	/* print message */ | 	/* print message */ | ||||||
| 	(void) wattrset(prompt_win, attributes[INPUT_TEXT]); | 	wattrset(prompt_win, attr_input_text); | ||||||
| 	fill_window(prompt_win, prompt); | 	fill_window(prompt_win, prompt); | ||||||
|  |  | ||||||
| 	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); | 	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); | ||||||
| @@ -432,7 +390,8 @@ int dialog_inputbox(WINDOW *main_window, | |||||||
| 		case KEY_F(F_EXIT): | 		case KEY_F(F_EXIT): | ||||||
| 		case KEY_F(F_BACK): | 		case KEY_F(F_BACK): | ||||||
| 			break; | 			break; | ||||||
| 		case 127: | 		case 8:   /* ^H */ | ||||||
|  | 		case 127: /* ^? */ | ||||||
| 		case KEY_BACKSPACE: | 		case KEY_BACKSPACE: | ||||||
| 			if (cursor_position > 0) { | 			if (cursor_position > 0) { | ||||||
| 				memmove(&result[cursor_position-1], | 				memmove(&result[cursor_position-1], | ||||||
| @@ -568,7 +527,7 @@ void show_scroll_win(WINDOW *main_window, | |||||||
|  |  | ||||||
| 	/* create the pad */ | 	/* create the pad */ | ||||||
| 	pad = newpad(total_lines+10, total_cols+10); | 	pad = newpad(total_lines+10, total_cols+10); | ||||||
| 	(void) wattrset(pad, attributes[SCROLLWIN_TEXT]); | 	wattrset(pad, attr_scrollwin_text); | ||||||
| 	fill_window(pad, text); | 	fill_window(pad, text); | ||||||
|  |  | ||||||
| 	win_lines = min(total_lines+4, lines-2); | 	win_lines = min(total_lines+4, lines-2); | ||||||
| @@ -583,9 +542,9 @@ void show_scroll_win(WINDOW *main_window, | |||||||
| 	win = newwin(win_lines, win_cols, y, x); | 	win = newwin(win_lines, win_cols, y, x); | ||||||
| 	keypad(win, TRUE); | 	keypad(win, TRUE); | ||||||
| 	/* show the help in the help window, and show the help panel */ | 	/* show the help in the help window, and show the help panel */ | ||||||
| 	(void) wattrset(win, attributes[SCROLLWIN_BOX]); | 	wattrset(win, attr_scrollwin_box); | ||||||
| 	box(win, 0, 0); | 	box(win, 0, 0); | ||||||
| 	(void) wattrset(win, attributes[SCROLLWIN_HEADING]); | 	wattrset(win, attr_scrollwin_heading); | ||||||
| 	mvwprintw(win, 0, 3, " %s ", title); | 	mvwprintw(win, 0, 3, " %s ", title); | ||||||
| 	panel = new_panel(win); | 	panel = new_panel(win); | ||||||
|  |  | ||||||
| @@ -596,10 +555,9 @@ void show_scroll_win(WINDOW *main_window, | |||||||
| 				text_cols, 0); | 				text_cols, 0); | ||||||
| 		print_in_middle(win, | 		print_in_middle(win, | ||||||
| 				text_lines+2, | 				text_lines+2, | ||||||
| 				0, |  | ||||||
| 				text_cols, | 				text_cols, | ||||||
| 				"<OK>", | 				"<OK>", | ||||||
| 				attributes[DIALOG_MENU_FORE]); | 				attr_dialog_menu_fore); | ||||||
| 		wrefresh(win); | 		wrefresh(win); | ||||||
|  |  | ||||||
| 		res = wgetch(win); | 		res = wgetch(win); | ||||||
|   | |||||||
| @@ -1,9 +1,8 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? |  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  * |  * | ||||||
|  * Derived from menuconfig. |  * Derived from menuconfig. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| @@ -14,8 +13,7 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <locale.h> | #include <ncurses.h> | ||||||
| #include <curses.h> |  | ||||||
| #include <menu.h> | #include <menu.h> | ||||||
| #include <panel.h> | #include <panel.h> | ||||||
| #include <form.h> | #include <form.h> | ||||||
| @@ -24,8 +22,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;\ | ||||||
| @@ -36,30 +32,26 @@ | |||||||
| 		typeof(b) _b = b;\ | 		typeof(b) _b = b;\ | ||||||
| 		_a < _b ? _a : _b; }) | 		_a < _b ? _a : _b; }) | ||||||
|  |  | ||||||
| typedef enum { | extern int attr_normal; | ||||||
| 	NORMAL = 1, | extern int attr_main_heading; | ||||||
| 	MAIN_HEADING, | extern int attr_main_menu_box; | ||||||
| 	MAIN_MENU_BOX, | extern int attr_main_menu_fore; | ||||||
| 	MAIN_MENU_FORE, | extern int attr_main_menu_back; | ||||||
| 	MAIN_MENU_BACK, | extern int attr_main_menu_grey; | ||||||
| 	MAIN_MENU_GREY, | extern int attr_main_menu_heading; | ||||||
| 	MAIN_MENU_HEADING, | extern int attr_scrollwin_text; | ||||||
| 	SCROLLWIN_TEXT, | extern int attr_scrollwin_heading; | ||||||
| 	SCROLLWIN_HEADING, | extern int attr_scrollwin_box; | ||||||
| 	SCROLLWIN_BOX, | extern int attr_dialog_text; | ||||||
| 	DIALOG_TEXT, | extern int attr_dialog_menu_fore; | ||||||
| 	DIALOG_MENU_FORE, | extern int attr_dialog_menu_back; | ||||||
| 	DIALOG_MENU_BACK, | extern int attr_dialog_box; | ||||||
| 	DIALOG_BOX, | extern int attr_input_box; | ||||||
| 	INPUT_BOX, | extern int attr_input_heading; | ||||||
| 	INPUT_HEADING, | extern int attr_input_text; | ||||||
| 	INPUT_TEXT, | extern int attr_input_field; | ||||||
| 	INPUT_FIELD, | extern int attr_function_text; | ||||||
| 	FUNCTION_TEXT, | extern int attr_function_highlight; | ||||||
| 	FUNCTION_HIGHLIGHT, |  | ||||||
| 	ATTR_MAX |  | ||||||
| } attributes_t; |  | ||||||
| extern attributes_t attributes[]; |  | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
| 	F_HELP = 1, | 	F_HELP = 1, | ||||||
| @@ -76,12 +68,7 @@ typedef enum { | |||||||
| void set_colors(void); | void set_colors(void); | ||||||
|  |  | ||||||
| /* this changes the windows attributes !!! */ | /* this changes the windows attributes !!! */ | ||||||
| void print_in_middle(WINDOW *win, | void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs); | ||||||
| 		int starty, |  | ||||||
| 		int startx, |  | ||||||
| 		int width, |  | ||||||
| 		const char *string, |  | ||||||
| 		chtype color); |  | ||||||
| int get_line_length(const char *line); | int get_line_length(const char *line); | ||||||
| int get_line_no(const char *text); | int get_line_no(const char *text); | ||||||
| const char *get_line(const char *text, int line_no); | const char *get_line(const char *text, int line_no); | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| %{ | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  | %{ | ||||||
| 
 | 
 | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| @@ -12,6 +12,7 @@ | |||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| #include "lkc.h" | #include "lkc.h" | ||||||
|  | #include "internal.h" | ||||||
| 
 | 
 | ||||||
| #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) | #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) | ||||||
| 
 | 
 | ||||||
| @@ -20,72 +21,82 @@ | |||||||
| 
 | 
 | ||||||
| int cdebug = PRINTD; | int cdebug = PRINTD; | ||||||
| 
 | 
 | ||||||
| extern int zconflex(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 char *tokenname, | ||||||
| static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); | 			   const char *expected_tokenname); | ||||||
| 
 | 
 | ||||||
| struct symbol *symbol_hash[SYMBOL_HASHSIZE]; | struct symbol *symbol_hash[SYMBOL_HASHSIZE]; | ||||||
| 
 | 
 | ||||||
| static struct menu *current_menu, *current_entry; | struct menu *current_menu, *current_entry; | ||||||
| 
 | 
 | ||||||
| %} | %} | ||||||
| %expect 30 |  | ||||||
| 
 | 
 | ||||||
| %union | %union | ||||||
| { | { | ||||||
| 	char *string; | 	char *string; | ||||||
| 	struct file *file; |  | ||||||
| 	struct symbol *symbol; | 	struct symbol *symbol; | ||||||
| 	struct expr *expr; | 	struct expr *expr; | ||||||
| 	struct menu *menu; | 	struct menu *menu; | ||||||
| 	const struct kconf_id *id; | 	enum symbol_type type; | ||||||
|  | 	enum variable_flavor flavor; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| %token <id>T_MAINMENU |  | ||||||
| %token <id>T_MENU |  | ||||||
| %token <id>T_ENDMENU |  | ||||||
| %token <id>T_SOURCE |  | ||||||
| %token <id>T_CHOICE |  | ||||||
| %token <id>T_ENDCHOICE |  | ||||||
| %token <id>T_COMMENT |  | ||||||
| %token <id>T_CONFIG |  | ||||||
| %token <id>T_MENUCONFIG |  | ||||||
| %token <id>T_HELP |  | ||||||
| %token <string> T_HELPTEXT | %token <string> T_HELPTEXT | ||||||
| %token <id>T_IF |  | ||||||
| %token <id>T_ENDIF |  | ||||||
| %token <id>T_DEPENDS |  | ||||||
| %token <id>T_OPTIONAL |  | ||||||
| %token <id>T_PROMPT |  | ||||||
| %token <id>T_TYPE |  | ||||||
| %token <id>T_DEFAULT |  | ||||||
| %token <id>T_SELECT |  | ||||||
| %token <id>T_RANGE |  | ||||||
| %token <id>T_VISIBLE |  | ||||||
| %token <id>T_OPTION |  | ||||||
| %token <id>T_ON |  | ||||||
| %token <string> T_WORD | %token <string> T_WORD | ||||||
| %token <string> T_WORD_QUOTE | %token <string> T_WORD_QUOTE | ||||||
| %token T_UNEQUAL | %token T_BOOL | ||||||
|  | %token T_CHOICE | ||||||
| %token T_CLOSE_PAREN | %token T_CLOSE_PAREN | ||||||
|  | %token T_COLON_EQUAL | ||||||
|  | %token T_COMMENT | ||||||
|  | %token T_CONFIG | ||||||
|  | %token T_DEFAULT | ||||||
|  | %token T_DEF_BOOL | ||||||
|  | %token T_DEF_TRISTATE | ||||||
|  | %token T_DEPENDS | ||||||
|  | %token T_ENDCHOICE | ||||||
|  | %token T_ENDIF | ||||||
|  | %token T_ENDMENU | ||||||
|  | %token T_HELP | ||||||
|  | %token T_HEX | ||||||
|  | %token T_IF | ||||||
|  | %token T_IMPLY | ||||||
|  | %token T_INT | ||||||
|  | %token T_MAINMENU | ||||||
|  | %token T_MENU | ||||||
|  | %token T_MENUCONFIG | ||||||
|  | %token T_MODULES | ||||||
|  | %token T_ON | ||||||
| %token T_OPEN_PAREN | %token T_OPEN_PAREN | ||||||
|  | %token T_OPTIONAL | ||||||
|  | %token T_PLUS_EQUAL | ||||||
|  | %token T_PROMPT | ||||||
|  | %token T_RANGE | ||||||
|  | %token T_SELECT | ||||||
|  | %token T_SOURCE | ||||||
|  | %token T_STRING | ||||||
|  | %token T_TRISTATE | ||||||
|  | %token T_VISIBLE | ||||||
| %token T_EOL | %token T_EOL | ||||||
|  | %token <string> T_ASSIGN_VAL | ||||||
| 
 | 
 | ||||||
| %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 <symbol> nonconst_symbol | ||||||
| %type <symbol> symbol | %type <symbol> symbol | ||||||
|  | %type <type> type logic_type default | ||||||
| %type <expr> expr | %type <expr> expr | ||||||
| %type <expr> if_expr | %type <expr> if_expr | ||||||
| %type <id> end | %type <string> end | ||||||
| %type <id> option_name |  | ||||||
| %type <menu> if_entry menu_entry choice_entry | %type <menu> if_entry menu_entry choice_entry | ||||||
| %type <string> symbol_option_arg word_opt | %type <string> word_opt assign_val | ||||||
|  | %type <flavor> assign_op | ||||||
| 
 | 
 | ||||||
| %destructor { | %destructor { | ||||||
| 	fprintf(stderr, "%s:%d: missing end statement for this entry\n", | 	fprintf(stderr, "%s:%d: missing end statement for this entry\n", | ||||||
| @@ -94,71 +105,58 @@ static struct menu *current_menu, *current_entry; | |||||||
| 		menu_end_menu(); | 		menu_end_menu(); | ||||||
| } 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 "zconf.hash.c" |  | ||||||
| %} |  | ||||||
| 
 |  | ||||||
| %% | %% | ||||||
| input: nl start | start; | input: mainmenu_stmt stmt_list | stmt_list; | ||||||
| 
 | 
 | ||||||
| start: mainmenu_stmt stmt_list | stmt_list; | /* mainmenu entry */ | ||||||
|  | 
 | ||||||
|  | mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL | ||||||
|  | { | ||||||
|  | 	menu_add_prompt(P_MENU, $2, NULL); | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| stmt_list: | stmt_list: | ||||||
| 	  /* empty */ | 	  /* empty */ | ||||||
| 	| stmt_list common_stmt | 	| stmt_list assignment_stmt | ||||||
| 	| stmt_list choice_stmt | 	| stmt_list choice_stmt | ||||||
|  | 	| stmt_list comment_stmt | ||||||
|  | 	| stmt_list config_stmt | ||||||
|  | 	| stmt_list if_stmt | ||||||
| 	| stmt_list menu_stmt | 	| stmt_list menu_stmt | ||||||
| 	| stmt_list end			{ zconf_error("unexpected end statement"); } | 	| stmt_list menuconfig_stmt | ||||||
|  | 	| stmt_list source_stmt | ||||||
| 	| 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 |  | ||||||
| { |  | ||||||
| 	zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); |  | ||||||
| } |  | ||||||
| 	| stmt_list error T_EOL		{ zconf_error("invalid statement"); } | 	| stmt_list error T_EOL		{ zconf_error("invalid statement"); } | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| option_name: | stmt_list_in_choice: | ||||||
| 	T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE | 	  /* empty */ | ||||||
|  | 	| stmt_list_in_choice comment_stmt | ||||||
|  | 	| stmt_list_in_choice config_stmt | ||||||
|  | 	| stmt_list_in_choice if_stmt_in_choice | ||||||
|  | 	| stmt_list_in_choice source_stmt | ||||||
|  | 	| stmt_list_in_choice error T_EOL	{ zconf_error("invalid statement"); } | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| common_stmt: |  | ||||||
| 	  T_EOL |  | ||||||
| 	| if_stmt |  | ||||||
| 	| comment_stmt |  | ||||||
| 	| config_stmt |  | ||||||
| 	| menuconfig_stmt |  | ||||||
| 	| source_stmt |  | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| option_error: |  | ||||||
| 	  T_WORD error T_EOL		{ zconf_error("unknown option \"%s\"", $1); } |  | ||||||
| 	| error T_EOL			{ zconf_error("invalid option"); } |  | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /* 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,84 +165,75 @@ 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()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| config_option_list: | config_option_list: | ||||||
| 	  /* empty */ | 	  /* empty */ | ||||||
| 	| config_option_list config_option | 	| config_option_list config_option | ||||||
| 	| config_option_list symbol_option |  | ||||||
| 	| config_option_list depends | 	| config_option_list depends | ||||||
| 	| config_option_list help | 	| config_option_list help | ||||||
| 	| config_option_list option_error |  | ||||||
| 	| config_option_list T_EOL |  | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| config_option: T_TYPE prompt_stmt_opt T_EOL | config_option: type prompt_stmt_opt T_EOL | ||||||
| { | { | ||||||
| 	menu_set_type($1->stype); | 	menu_set_type($1); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:type(%u)\n", | 	printd(DEBUG_PARSE, "%s:%d:type(%u)\n", | ||||||
| 		zconf_curname(), zconf_lineno(), | 		zconf_curname(), zconf_lineno(), | ||||||
| 		$1->stype); | 		$1); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| config_option: T_PROMPT prompt if_expr T_EOL | config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL | ||||||
| { | { | ||||||
| 	menu_add_prompt(P_PROMPT, $2, $3); | 	menu_add_prompt(P_PROMPT, $2, $3); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); | 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| config_option: T_DEFAULT expr if_expr T_EOL | config_option: default expr if_expr T_EOL | ||||||
| { | { | ||||||
| 	menu_add_expr(P_DEFAULT, $2, $3); | 	menu_add_expr(P_DEFAULT, $2, $3); | ||||||
| 	if ($1->stype != S_UNKNOWN) | 	if ($1 != S_UNKNOWN) | ||||||
| 		menu_set_type($1->stype); | 		menu_set_type($1); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:default(%u)\n", | 	printd(DEBUG_PARSE, "%s:%d:default(%u)\n", | ||||||
| 		zconf_curname(), zconf_lineno(), | 		zconf_curname(), zconf_lineno(), | ||||||
| 		$1->stype); | 		$1); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 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); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); | 	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| symbol_option: T_OPTION symbol_option_list T_EOL | config_option: T_MODULES T_EOL | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| symbol_option_list: |  | ||||||
| 	  /* empty */ |  | ||||||
| 	| symbol_option_list T_WORD symbol_option_arg |  | ||||||
| { | { | ||||||
| 	const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); | 	if (modules_sym) | ||||||
| 	if (id && id->flags & TF_OPTION) | 		zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'", | ||||||
| 		menu_add_option(id->token, $3); | 			    current_entry->sym->name, modules_sym->name); | ||||||
| 	else | 	modules_sym = current_entry->sym; | ||||||
| 		zconfprint("warning: ignoring unknown option %s", $2); |  | ||||||
| 	free($2); |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| symbol_option_arg: |  | ||||||
| 	  /* empty */		{ $$ = NULL; } |  | ||||||
| 	| T_EQUAL prompt	{ $$ = $2; } |  | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| /* choice entry */ | /* choice entry */ | ||||||
| 
 | 
 | ||||||
| choice: T_CHOICE word_opt T_EOL | choice: T_CHOICE word_opt T_EOL | ||||||
| { | { | ||||||
| 	struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); | 	struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); | ||||||
| 	sym->flags |= SYMBOL_AUTO; | 	sym->flags |= SYMBOL_NO_WRITE; | ||||||
| 	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()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @@ -255,13 +244,13 @@ choice_entry: choice choice_option_list | |||||||
| 
 | 
 | ||||||
| choice_end: end | choice_end: end | ||||||
| { | { | ||||||
| 	if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { | 	if (zconf_endtoken($1, "choice")) { | ||||||
| 		menu_end_menu(); | 		menu_end_menu(); | ||||||
| 		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); | 		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| choice_stmt: choice_entry choice_block choice_end | choice_stmt: choice_entry stmt_list_in_choice choice_end | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| choice_option_list: | choice_option_list: | ||||||
| @@ -269,25 +258,19 @@ choice_option_list: | |||||||
| 	| choice_option_list choice_option | 	| choice_option_list choice_option | ||||||
| 	| choice_option_list depends | 	| choice_option_list depends | ||||||
| 	| choice_option_list help | 	| choice_option_list help | ||||||
| 	| choice_option_list T_EOL |  | ||||||
| 	| choice_option_list option_error |  | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| choice_option: T_PROMPT prompt if_expr T_EOL | choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL | ||||||
| { | { | ||||||
| 	menu_add_prompt(P_PROMPT, $2, $3); | 	menu_add_prompt(P_PROMPT, $2, $3); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); | 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| choice_option: T_TYPE prompt_stmt_opt T_EOL | choice_option: logic_type prompt_stmt_opt T_EOL | ||||||
| { | { | ||||||
| 	if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { | 	menu_set_type($1); | ||||||
| 		menu_set_type($1->stype); | 	printd(DEBUG_PARSE, "%s:%d:type(%u)\n", | ||||||
| 		printd(DEBUG_PARSE, "%s:%d:type(%u)\n", | 	       zconf_curname(), zconf_lineno(), $1); | ||||||
| 			zconf_curname(), zconf_lineno(), |  | ||||||
| 			$1->stype); |  | ||||||
| 	} else |  | ||||||
| 		YYERROR; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| choice_option: T_OPTIONAL T_EOL | choice_option: T_OPTIONAL T_EOL | ||||||
| @@ -296,24 +279,31 @@ 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) { | 	menu_add_symbol(P_DEFAULT, $2, $3); | ||||||
| 		menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); | 	printd(DEBUG_PARSE, "%s:%d:default\n", | ||||||
| 		printd(DEBUG_PARSE, "%s:%d:default\n", | 	       zconf_curname(), zconf_lineno()); | ||||||
| 			zconf_curname(), zconf_lineno()); |  | ||||||
| 	} else |  | ||||||
| 		YYERROR; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| choice_block: | type: | ||||||
| 	  /* empty */ | 	  logic_type | ||||||
| 	| choice_block common_stmt | 	| T_INT			{ $$ = S_INT; } | ||||||
| ; | 	| T_HEX			{ $$ = S_HEX; } | ||||||
|  | 	| T_STRING		{ $$ = S_STRING; } | ||||||
|  | 
 | ||||||
|  | logic_type: | ||||||
|  | 	  T_BOOL		{ $$ = S_BOOLEAN; } | ||||||
|  | 	| T_TRISTATE		{ $$ = S_TRISTATE; } | ||||||
|  | 
 | ||||||
|  | default: | ||||||
|  | 	  T_DEFAULT		{ $$ = S_UNKNOWN; } | ||||||
|  | 	| T_DEF_BOOL		{ $$ = S_BOOLEAN; } | ||||||
|  | 	| T_DEF_TRISTATE	{ $$ = S_TRISTATE; } | ||||||
| 
 | 
 | ||||||
| /* if entry */ | /* if entry */ | ||||||
| 
 | 
 | ||||||
| if_entry: T_IF expr nl | if_entry: T_IF expr T_EOL | ||||||
| { | { | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); | 	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); | ||||||
| 	menu_add_entry(NULL); | 	menu_add_entry(NULL); | ||||||
| @@ -323,80 +313,72 @@ if_entry: T_IF expr nl | |||||||
| 
 | 
 | ||||||
| if_end: end | if_end: end | ||||||
| { | { | ||||||
| 	if (zconf_endtoken($1, T_IF, T_ENDIF)) { | 	if (zconf_endtoken($1, "if")) { | ||||||
| 		menu_end_menu(); | 		menu_end_menu(); | ||||||
| 		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); | 		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| if_stmt: if_entry if_block if_end | if_stmt: if_entry stmt_list if_end | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| if_block: | if_stmt_in_choice: if_entry stmt_list_in_choice if_end | ||||||
| 	  /* empty */ |  | ||||||
| 	| if_block common_stmt |  | ||||||
| 	| if_block menu_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 T_WORD_QUOTE T_EOL | ||||||
| { | { | ||||||
| 	menu_add_entry(NULL); | 	menu_add_entry(NULL); | ||||||
| 	menu_add_prompt(P_MENU, $2, NULL); | 	menu_add_prompt(P_MENU, $2, NULL); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); | 	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| menu_entry: menu visibility_list depends_list | menu_entry: menu menu_option_list | ||||||
| { | { | ||||||
| 	$$ = menu_add_menu(); | 	$$ = menu_add_menu(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| menu_end: end | menu_end: end | ||||||
| { | { | ||||||
| 	if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { | 	if (zconf_endtoken($1, "menu")) { | ||||||
| 		menu_end_menu(); | 		menu_end_menu(); | ||||||
| 		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); | 		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| menu_stmt: menu_entry menu_block menu_end | menu_stmt: menu_entry stmt_list menu_end | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| menu_block: | menu_option_list: | ||||||
| 	  /* empty */ | 	  /* empty */ | ||||||
| 	| menu_block common_stmt | 	| menu_option_list visible | ||||||
| 	| menu_block menu_stmt | 	| menu_option_list depends | ||||||
| 	| menu_block choice_stmt |  | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| source_stmt: T_SOURCE prompt T_EOL | source_stmt: T_SOURCE T_WORD_QUOTE 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_nextfiles($2); | 	zconf_nextfiles($2); | ||||||
|  | 	free($2); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* comment entry */ | /* comment entry */ | ||||||
| 
 | 
 | ||||||
| comment: T_COMMENT prompt T_EOL | comment: T_COMMENT T_WORD_QUOTE T_EOL | ||||||
| { | { | ||||||
| 	menu_add_entry(NULL); | 	menu_add_entry(NULL); | ||||||
| 	menu_add_prompt(P_COMMENT, $2, NULL); | 	menu_add_prompt(P_COMMENT, $2, NULL); | ||||||
| 	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); | 	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| comment_stmt: comment depends_list | comment_stmt: comment comment_option_list | ||||||
| { | ; | ||||||
| 	menu_end_entry(); | 
 | ||||||
| }; | comment_option_list: | ||||||
|  | 	  /* empty */ | ||||||
|  | 	| comment_option_list depends | ||||||
|  | ; | ||||||
| 
 | 
 | ||||||
| /* help option */ | /* help option */ | ||||||
| 
 | 
 | ||||||
| @@ -408,18 +390,22 @@ 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; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* depends option */ | /* depends option */ | ||||||
| 
 | 
 | ||||||
| depends_list: |  | ||||||
| 	  /* empty */ |  | ||||||
| 	| depends_list depends |  | ||||||
| 	| depends_list T_EOL |  | ||||||
| 	| depends_list option_error |  | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| depends: T_DEPENDS T_ON expr T_EOL | depends: T_DEPENDS T_ON expr T_EOL | ||||||
| { | { | ||||||
| 	menu_add_dep($3); | 	menu_add_dep($3); | ||||||
| @@ -427,14 +413,7 @@ depends: T_DEPENDS T_ON expr T_EOL | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* visibility option */ | /* visibility option */ | ||||||
| 
 | visible: T_VISIBLE if_expr T_EOL | ||||||
| visibility_list: |  | ||||||
| 	  /* empty */ |  | ||||||
| 	| visibility_list visible |  | ||||||
| 	| visibility_list T_EOL |  | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| visible: T_VISIBLE if_expr |  | ||||||
| { | { | ||||||
| 	menu_add_visibility($2); | 	menu_add_visibility($2); | ||||||
| }; | }; | ||||||
| @@ -443,23 +422,14 @@ visible: T_VISIBLE if_expr | |||||||
| 
 | 
 | ||||||
| prompt_stmt_opt: | prompt_stmt_opt: | ||||||
| 	  /* empty */ | 	  /* empty */ | ||||||
| 	| prompt if_expr | 	| T_WORD_QUOTE if_expr | ||||||
| { | { | ||||||
| 	menu_add_prompt(P_PROMPT, $1, $2); | 	menu_add_prompt(P_PROMPT, $1, $2); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| prompt:	  T_WORD | end:	  T_ENDMENU T_EOL	{ $$ = "menu"; } | ||||||
| 	| T_WORD_QUOTE | 	| T_ENDCHOICE T_EOL	{ $$ = "choice"; } | ||||||
| ; | 	| T_ENDIF T_EOL		{ $$ = "if"; } | ||||||
| 
 |  | ||||||
| end:	  T_ENDMENU T_EOL	{ $$ = $1; } |  | ||||||
| 	| T_ENDCHOICE T_EOL	{ $$ = $1; } |  | ||||||
| 	| T_ENDIF T_EOL		{ $$ = $1; } |  | ||||||
| ; |  | ||||||
| 
 |  | ||||||
| nl: |  | ||||||
| 	  T_EOL |  | ||||||
| 	| nl T_EOL |  | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| if_expr:  /* empty */			{ $$ = NULL; } | if_expr:  /* empty */			{ $$ = NULL; } | ||||||
| @@ -467,6 +437,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,13 +449,31 @@ 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); } | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| word_opt: /* empty */			{ $$ = NULL; } | word_opt: /* empty */			{ $$ = NULL; } | ||||||
| 	| T_WORD | 	| T_WORD | ||||||
| 
 | 
 | ||||||
|  | /* assignment statement */ | ||||||
|  | 
 | ||||||
|  | assignment_stmt:  T_WORD assign_op assign_val T_EOL	{ variable_add($1, $3, $2); free($1); free($3); } | ||||||
|  | 
 | ||||||
|  | assign_op: | ||||||
|  | 	  T_EQUAL	{ $$ = VAR_RECURSIVE; } | ||||||
|  | 	| T_COLON_EQUAL	{ $$ = VAR_SIMPLE; } | ||||||
|  | 	| T_PLUS_EQUAL	{ $$ = VAR_APPEND; } | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | assign_val: | ||||||
|  | 	/* empty */		{ $$ = xstrdup(""); }; | ||||||
|  | 	| T_ASSIGN_VAL | ||||||
|  | ; | ||||||
|  | 
 | ||||||
| %% | %% | ||||||
| 
 | 
 | ||||||
| void conf_parse(const char *name) | void conf_parse(const char *name) | ||||||
| @@ -491,61 +483,51 @@ void conf_parse(const char *name) | |||||||
| 
 | 
 | ||||||
| 	zconf_initscan(name); | 	zconf_initscan(name); | ||||||
| 
 | 
 | ||||||
| 	sym_init(); |  | ||||||
| 	_menu_init(); | 	_menu_init(); | ||||||
| 	rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); |  | ||||||
| 
 | 
 | ||||||
| 	if (getenv("ZCONF_DEBUG")) | 	if (getenv("ZCONF_DEBUG")) | ||||||
| 		zconfdebug = 1; | 		yydebug = 1; | ||||||
| 	zconfparse(); | 	yyparse(); | ||||||
| 	if (zconfnerrs) | 
 | ||||||
|  | 	/* Variables are expanded in the parse phase. We can free them here. */ | ||||||
|  | 	variable_all_del(); | ||||||
|  | 
 | ||||||
|  | 	if (yynerrs) | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	if (!modules_sym) | 	if (!modules_sym) | ||||||
| 		modules_sym = sym_find( "n" ); | 		modules_sym = sym_find( "n" ); | ||||||
| 
 | 
 | ||||||
| 	rootmenu.prompt->text = _(rootmenu.prompt->text); | 	if (!menu_has_prompt(&rootmenu)) { | ||||||
| 	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); | 		current_entry = &rootmenu; | ||||||
|  | 		menu_add_prompt(P_MENU, "Main menu", NULL); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	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); | 	conf_set_changed(true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char *zconf_tokenname(int token) | static bool zconf_endtoken(const char *tokenname, | ||||||
|  | 			   const char *expected_tokenname) | ||||||
| { | { | ||||||
| 	switch (token) { | 	if (strcmp(tokenname, expected_tokenname)) { | ||||||
| 	case T_MENU:		return "menu"; |  | ||||||
| 	case T_ENDMENU:		return "endmenu"; |  | ||||||
| 	case T_CHOICE:		return "choice"; |  | ||||||
| 	case T_ENDCHOICE:	return "endchoice"; |  | ||||||
| 	case T_IF:		return "if"; |  | ||||||
| 	case T_ENDIF:		return "endif"; |  | ||||||
| 	case T_DEPENDS:		return "depends"; |  | ||||||
| 	case T_VISIBLE:		return "visible"; |  | ||||||
| 	} |  | ||||||
| 	return "<token>"; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int 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)); | 			    tokenname, expected_tokenname); | ||||||
| 		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)); | 			    tokenname, expected_tokenname); | ||||||
| 		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)); | 			expected_tokenname); | ||||||
| 		zconfnerrs++; | 		yynerrs++; | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 	return true; | 	return true; | ||||||
| @@ -566,7 +548,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 +556,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 +589,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 +637,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); | ||||||
| @@ -665,6 +652,10 @@ static void print_symbol(FILE *out, struct menu *menu) | |||||||
| 			print_quoted_string(out, prop->text); | 			print_quoted_string(out, prop->text); | ||||||
| 			fputc('\n', out); | 			fputc('\n', out); | ||||||
| 			break; | 			break; | ||||||
|  | 		case P_SYMBOL: | ||||||
|  | 			fputs( "  symbol ", out); | ||||||
|  | 			fprintf(out, "%s\n", prop->menu->sym->name); | ||||||
|  | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			fprintf(out, "  unknown prop %d!\n", prop->type); | 			fprintf(out, "  unknown prop %d!\n", prop->type); | ||||||
| 			break; | 			break; | ||||||
| @@ -724,10 +715,3 @@ void zconfdump(FILE *out) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #include "zconf.lex.c" |  | ||||||
| #include "util.c" |  | ||||||
| #include "confdata.c" |  | ||||||
| #include "expr.c" |  | ||||||
| #include "symbol.c" |  | ||||||
| #include "menu.c" |  | ||||||
| @@ -0,0 +1,43 @@ | |||||||
|  | From c822f47921feb53b97f48f3aa8d1e843f5099c63 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Stefan Reinauer <stefan.reinauer@coreboot.org> | ||||||
|  | Date: Fri, 17 Jul 2015 17:26:48 -0700 | ||||||
|  | Subject: [PATCH] Kconfig: Add KCONFIG_STRICT mode | ||||||
|  |  | ||||||
|  | This is basically a -Werror mode for Kconfig. When exporting | ||||||
|  | KCONFIG_STRICT in the Makefile, warnings in Kconfig will produce | ||||||
|  | errors instead. | ||||||
|  |  | ||||||
|  | This will make it easier to spot unclean Kconfig files, settings | ||||||
|  | and dependencies. | ||||||
|  |  | ||||||
|  | Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> | ||||||
|  | --- | ||||||
|  |  util/kconfig/confdata.c | 8 ++++++++ | ||||||
|  |  1 file changed, 8 insertions(+) | ||||||
|  |  | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -439,6 +439,7 @@ load: | ||||||
|  |  			if (def == S_DEF_USER) { | ||||||
|  |  				sym = sym_find(line + 2 + strlen(CONFIG_)); | ||||||
|  |  				if (!sym) { | ||||||
|  | +					conf_warning("trying to assign non-existent symbol %s", line + strlen(CONFIG_)); | ||||||
|  |  					conf_set_changed(true); | ||||||
|  |  					continue; | ||||||
|  |  				} | ||||||
|  | @@ -521,6 +522,13 @@ load: | ||||||
|  |  	} | ||||||
|  |  	free(line); | ||||||
|  |  	fclose(in); | ||||||
|  | + | ||||||
|  | +	name = getenv("KCONFIG_STRICT"); | ||||||
|  | +	if (name && *name && conf_warnings) { | ||||||
|  | +		fprintf(stderr, "\nERROR: %d warnings encountered, and warnings are errors.\n\n", conf_warnings); | ||||||
|  | +		return 1; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,69 @@ | |||||||
|  | From 20df4491aa88eb4a7f97090fbc4ff53f81926861 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Martin Roth <martinroth@google.com> | ||||||
|  | Date: Wed, 21 Sep 2016 14:27:26 -0600 | ||||||
|  | Subject: [PATCH] Kconfig: Change symbol override from warning to notice | ||||||
|  |  | ||||||
|  | Overriding symbols within a .config is pretty common when doing | ||||||
|  | automated builds with various different options.  The warning | ||||||
|  | text makes it sound like this is an issue, so change it to say | ||||||
|  | 'notice' instead.  We could get rid of it completely, but it's | ||||||
|  | not a bad thing to know that we have two copies of the same symbol | ||||||
|  | in the .config. | ||||||
|  |  | ||||||
|  | BUG=chrome-os-partner:54059 | ||||||
|  | TEST=copy a disabled kconfig option to the end and set it to y. | ||||||
|  | See notice text instead of warning. | ||||||
|  |  | ||||||
|  | Signed-off-by: Martin Roth <martinroth@google.com> | ||||||
|  | --- | ||||||
|  |  util/kconfig/confdata.c | 16 +++++++++++++--- | ||||||
|  |  1 file changed, 13 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -184,6 +184,16 @@ static void conf_warning(const char *fmt | ||||||
|  |  	conf_warnings++; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void conf_notice(const char *fmt, ...) | ||||||
|  | +{ | ||||||
|  | +	va_list ap; | ||||||
|  | +	va_start(ap, fmt); | ||||||
|  | +	fprintf(stderr, "%s:%d:notice: ", conf_filename, conf_lineno); | ||||||
|  | +	vfprintf(stderr, fmt, ap); | ||||||
|  | +	fprintf(stderr, "\n"); | ||||||
|  | +	va_end(ap); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static void conf_default_message_callback(const char *s) | ||||||
|  |  { | ||||||
|  |  	printf("#\n# "); | ||||||
|  | @@ -449,7 +459,7 @@ load: | ||||||
|  |  					sym->type = S_BOOLEAN; | ||||||
|  |  			} | ||||||
|  |  			if (sym->flags & def_flags) { | ||||||
|  | -				conf_warning("override: reassigning to symbol %s", sym->name); | ||||||
|  | +				conf_notice("override: reassigning to symbol %s", sym->name); | ||||||
|  |  			} | ||||||
|  |  			switch (sym->type) { | ||||||
|  |  			case S_BOOLEAN: | ||||||
|  | @@ -488,7 +498,7 @@ load: | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			if (sym->flags & def_flags) { | ||||||
|  | -				conf_warning("override: reassigning to symbol %s", sym->name); | ||||||
|  | +				conf_notice("override: reassigning to symbol %s", sym->name); | ||||||
|  |  			} | ||||||
|  |  			if (conf_set_sym_val(sym, def, def_flags, p)) | ||||||
|  |  				continue; | ||||||
|  | @@ -513,7 +523,7 @@ load: | ||||||
|  |  				break; | ||||||
|  |  			case yes: | ||||||
|  |  				if (cs->def[def].tri != no) | ||||||
|  | -					conf_warning("override: %s changes choice state", sym->name); | ||||||
|  | +					conf_notice("override: %s changes choice state", sym->name); | ||||||
|  |  				cs->def[def].val = sym; | ||||||
|  |  				break; | ||||||
|  |  			} | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | From 887ae0ac3dc53fc73488a4dbc1fbf36fa620ce8b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Martin Roth <martinroth@google.com> | ||||||
|  | Date: Tue, 6 Dec 2016 14:28:44 -0700 | ||||||
|  | Subject: [PATCH] util/kconfig/conf.c: Fix newline in error printf | ||||||
|  |  | ||||||
|  | For some reason the \n in the defconfig save error was not escaped. | ||||||
|  |  | ||||||
|  | Signed-off-by: Martin Roth <martinroth@google.com> | ||||||
|  | --- | ||||||
|  |  util/kconfig/conf.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | Index: kconfig/conf.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/conf.c | ||||||
|  | +++ kconfig/conf.c | ||||||
|  | @@ -900,7 +900,7 @@ int main(int ac, char **av) | ||||||
|  |   | ||||||
|  |  	if (input_mode == savedefconfig) { | ||||||
|  |  		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); | ||||||
|  |  			return 1; | ||||||
|  |  		} | ||||||
| @@ -0,0 +1,46 @@ | |||||||
|  | From e8287a030fc8fcec7404aa6731aef21a48035786 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Elyes HAOUAS <ehaouas@noos.fr> | ||||||
|  | Date: Tue, 5 Jun 2018 08:41:29 +0200 | ||||||
|  | Subject: [PATCH] {src,util}: Use NULL instead of 0 for pointer | ||||||
|  |  | ||||||
|  | Signed-off-by: Elyes HAOUAS <ehaouas@noos.fr> | ||||||
|  | --- | ||||||
|  |  util/kconfig/lxdialog/util.c | 2 +- | ||||||
|  |  util/kconfig/qconf.h         | 8 ++++---- | ||||||
|  |  2 files changed, 5 insertions(+), 5 deletions(-) | ||||||
|  |  | ||||||
|  | Index: kconfig/lxdialog/util.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/lxdialog/util.c | ||||||
|  | +++ kconfig/lxdialog/util.c | ||||||
|  | @@ -370,7 +370,7 @@ void print_autowrap(WINDOW * win, const | ||||||
|  |  { | ||||||
|  |  	int newl, cur_x, cur_y; | ||||||
|  |  	int prompt_len, room, wlen; | ||||||
|  | -	char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0; | ||||||
|  | +	char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = NULL; | ||||||
|  |   | ||||||
|  |  	strcpy(tempstr, prompt); | ||||||
|  |   | ||||||
|  | Index: kconfig/qconf.h | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/qconf.h | ||||||
|  | +++ kconfig/qconf.h | ||||||
|  | @@ -42,7 +42,7 @@ class ConfigList : public QTreeWidget { | ||||||
|  |  	Q_OBJECT | ||||||
|  |  	typedef class QTreeWidget Parent; | ||||||
|  |  public: | ||||||
|  | -	ConfigList(QWidget *parent, const char *name = 0); | ||||||
|  | +	ConfigList(QWidget *parent, const char *name = NULL); | ||||||
|  |  	~ConfigList(); | ||||||
|  |  	void reinit(void); | ||||||
|  |  	ConfigItem* findConfigItem(struct menu *); | ||||||
|  | @@ -188,7 +188,7 @@ class ConfigInfoView : public QTextBrows | ||||||
|  |  	typedef class QTextBrowser Parent; | ||||||
|  |  	QMenu *contextMenu; | ||||||
|  |  public: | ||||||
|  | -	ConfigInfoView(QWidget* parent, const char *name = 0); | ||||||
|  | +	ConfigInfoView(QWidget* parent, const char *name = NULL); | ||||||
|  |  	bool showDebug(void) const { return _showDebug; } | ||||||
|  |   | ||||||
|  |  public slots: | ||||||
| @@ -0,0 +1,37 @@ | |||||||
|  | From 2796443d5a2194400e56e6762e0f748ed0f0470c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Martin Roth <martinroth@google.com> | ||||||
|  | Date: Wed, 10 Feb 2016 16:06:00 -0700 | ||||||
|  | Subject: [PATCH] util/kconfig: Ignore extra symbols in configs instead of | ||||||
|  |  failing | ||||||
|  |  | ||||||
|  | When updating an old .config file that has a symbol that has been | ||||||
|  | removed from the current Kconfig tree, kconfig will generate a warning | ||||||
|  | and fail to save the updated file.  This is incredibly annoying, and | ||||||
|  | not the goal when trying to eliminate Kconfig warnings. | ||||||
|  |  | ||||||
|  | Instead of generating a warning, just print a message that it's being | ||||||
|  | ignored.  This will remove the offending symbol, while allowing the | ||||||
|  | updated config file to be saved. | ||||||
|  |  | ||||||
|  | Split the change from 1 line to 3 lines to keep it at 80 characters. | ||||||
|  |  | ||||||
|  | Signed-off-by: Martin Roth <martinroth@google.com> | ||||||
|  | --- | ||||||
|  |  util/kconfig/confdata.c | 4 +++- | ||||||
|  |  1 file changed, 3 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -449,7 +449,9 @@ load: | ||||||
|  |  			if (def == S_DEF_USER) { | ||||||
|  |  				sym = sym_find(line + 2 + strlen(CONFIG_)); | ||||||
|  |  				if (!sym) { | ||||||
|  | -					conf_warning("trying to assign non-existent symbol %s", line + strlen(CONFIG_)); | ||||||
|  | +					conf_message( | ||||||
|  | +						"ignoring nonexistent symbol %s", | ||||||
|  | +						line + 2 + strlen(CONFIG_)); | ||||||
|  |  					conf_set_changed(true); | ||||||
|  |  					continue; | ||||||
|  |  				} | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | From d470f1069744c3e6ef2e928217c1a4a23a87efa2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: zbao <fishbaozi@gmail.com> | ||||||
|  | Date: Sat, 26 Sep 2015 06:20:53 -0400 | ||||||
|  | Subject: [PATCH] util/kconfig: Set parameter of mkdir to only one for mingw. | ||||||
|  |  | ||||||
|  | The second parameter is to set file permissions for the directory, which | ||||||
|  | is not needed in mingw. | ||||||
|  |  | ||||||
|  | Signed-off-by: Zheng Bao <fishbaozi@gmail.com> | ||||||
|  | --- | ||||||
|  |  util/kconfig/confdata.c | 4 ++++ | ||||||
|  |  1 file changed, 4 insertions(+) | ||||||
|  |  | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -164,6 +164,10 @@ struct conf_printer { | ||||||
|  |  	void (*print_comment)(FILE *, const char *, void *); | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +#ifdef __MINGW32__ | ||||||
|  | +#define mkdir(_n,_p) mkdir((_n)) | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  static void conf_warning(const char *fmt, ...) | ||||||
|  |  	__attribute__ ((format (printf, 1, 2))); | ||||||
|  |   | ||||||
| @@ -0,0 +1,189 @@ | |||||||
|  | From af6c23be63d14860c8c1f0d9fcbc020f7c11d84d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Stefan Reinauer <reinauer@chromium.org> | ||||||
|  | Date: Thu, 20 Aug 2015 11:19:34 -0700 | ||||||
|  | Subject: [PATCH] kconfig: Allow KCONFIG_STRICT outside of confdata.c | ||||||
|  |  | ||||||
|  | To catch dependency errors in symbol.c (such as the ones | ||||||
|  | fixed by I51b4ee326f082c6a656a813ee5772e9c34f5c343) we need | ||||||
|  | to check for global kconfig warnings before saving config | ||||||
|  | files. | ||||||
|  |  | ||||||
|  | This patch will produce errors for wrong dependencies and | ||||||
|  | add catching of errors to conf, nconf and mconf. Sorry, | ||||||
|  | gconf users, you will have to wait. | ||||||
|  |  | ||||||
|  | Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> | ||||||
|  | --- | ||||||
|  |  util/kconfig/conf.c     | 10 ++++++++++ | ||||||
|  |  util/kconfig/confdata.c |  6 +----- | ||||||
|  |  util/kconfig/lkc.h      |  3 +++ | ||||||
|  |  util/kconfig/mconf.c    | 10 ++++++++++ | ||||||
|  |  util/kconfig/nconf.c    | 13 +++++++++++++ | ||||||
|  |  util/kconfig/qconf.cc   |  2 ++ | ||||||
|  |  util/kconfig/symbol.c   |  1 + | ||||||
|  |  7 files changed, 40 insertions(+), 5 deletions(-) | ||||||
|  |  | ||||||
|  | Index: kconfig/conf.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/conf.c | ||||||
|  | +++ kconfig/conf.c | ||||||
|  | @@ -16,6 +16,8 @@ | ||||||
|  |   | ||||||
|  |  #include "lkc.h" | ||||||
|  |   | ||||||
|  | +int kconfig_warnings = 0; | ||||||
|  | + | ||||||
|  |  static void conf(struct menu *menu); | ||||||
|  |  static void check_conf(struct menu *menu); | ||||||
|  |   | ||||||
|  | @@ -732,6 +734,7 @@ int main(int ac, char **av) | ||||||
|  |  	const char *progname = av[0]; | ||||||
|  |  	int opt; | ||||||
|  |  	const char *name, *defconfig_file = NULL /* gcc uninit */; | ||||||
|  | +	char *env; | ||||||
|  |  	int no_conf_write = 0; | ||||||
|  |   | ||||||
|  |  	tty_stdio = isatty(0) && isatty(1); | ||||||
|  | @@ -838,6 +841,13 @@ int main(int ac, char **av) | ||||||
|  |  		break; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	env = getenv("KCONFIG_STRICT"); | ||||||
|  | +	if (env && *env && kconfig_warnings) { | ||||||
|  | +		fprintf(stderr, "\n*** ERROR: %d warnings encountered, and " | ||||||
|  | +			"warnings are errors.\n\n", kconfig_warnings); | ||||||
|  | +		exit(1); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	if (sync_kconfig) { | ||||||
|  |  		name = getenv("KCONFIG_NOSILENTUPDATE"); | ||||||
|  |  		if (name && *name) { | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -539,11 +539,7 @@ load: | ||||||
|  |  	free(line); | ||||||
|  |  	fclose(in); | ||||||
|  |   | ||||||
|  | -	name = getenv("KCONFIG_STRICT"); | ||||||
|  | -	if (name && *name && conf_warnings) { | ||||||
|  | -		fprintf(stderr, "\nERROR: %d warnings encountered, and warnings are errors.\n\n", conf_warnings); | ||||||
|  | -		return 1; | ||||||
|  | -	} | ||||||
|  | +	kconfig_warnings += conf_warnings; | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | Index: kconfig/lkc.h | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/lkc.h | ||||||
|  | +++ kconfig/lkc.h | ||||||
|  | @@ -39,6 +39,9 @@ void zconf_nextfile(const char *name); | ||||||
|  |  int zconf_lineno(void); | ||||||
|  |  const char *zconf_curname(void); | ||||||
|  |   | ||||||
|  | +/* conf.c */ | ||||||
|  | +extern int kconfig_warnings; | ||||||
|  | + | ||||||
|  |  /* confdata.c */ | ||||||
|  |  const char *conf_get_configname(void); | ||||||
|  |  void set_all_choice_values(struct symbol *csym); | ||||||
|  | Index: kconfig/mconf.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/mconf.c | ||||||
|  | +++ kconfig/mconf.c | ||||||
|  | @@ -24,6 +24,8 @@ | ||||||
|  |   | ||||||
|  |  #define JUMP_NB			9 | ||||||
|  |   | ||||||
|  | +int kconfig_warnings = 0; | ||||||
|  | + | ||||||
|  |  static const char mconf_readme[] = | ||||||
|  |  "Overview\n" | ||||||
|  |  "--------\n" | ||||||
|  | @@ -948,6 +950,7 @@ static void conf_save(void) | ||||||
|  |  static int handle_exit(void) | ||||||
|  |  { | ||||||
|  |  	int res; | ||||||
|  | +	char *env; | ||||||
|  |   | ||||||
|  |  	save_and_exit = 1; | ||||||
|  |  	reset_subtitle(); | ||||||
|  | @@ -962,6 +965,13 @@ static int handle_exit(void) | ||||||
|  |   | ||||||
|  |  	end_dialog(saved_x, saved_y); | ||||||
|  |   | ||||||
|  | +	env = getenv("KCONFIG_STRICT"); | ||||||
|  | +	if (env && *env && kconfig_warnings) { | ||||||
|  | +		fprintf(stderr, "\n*** ERROR: %d warnings encountered, and " | ||||||
|  | +			"warnings are errors.\n\n", kconfig_warnings); | ||||||
|  | +		res = 2; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	switch (res) { | ||||||
|  |  	case 0: | ||||||
|  |  		if (conf_write(filename)) { | ||||||
|  | Index: kconfig/nconf.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/nconf.c | ||||||
|  | +++ kconfig/nconf.c | ||||||
|  | @@ -15,6 +15,8 @@ | ||||||
|  |  #include "nconf.h" | ||||||
|  |  #include <ctype.h> | ||||||
|  |   | ||||||
|  | +int kconfig_warnings = 0; | ||||||
|  | + | ||||||
|  |  static const char nconf_global_help[] = | ||||||
|  |  "Help windows\n" | ||||||
|  |  "------------\n" | ||||||
|  | @@ -645,6 +647,8 @@ static void set_config_filename(const ch | ||||||
|  |  static int do_exit(void) | ||||||
|  |  { | ||||||
|  |  	int res; | ||||||
|  | +	char *env; | ||||||
|  | + | ||||||
|  |  	if (!conf_get_changed()) { | ||||||
|  |  		global_exit = 1; | ||||||
|  |  		return 0; | ||||||
|  | @@ -660,6 +664,15 @@ static int do_exit(void) | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	env = getenv("KCONFIG_STRICT"); | ||||||
|  | +	if (env && *env && kconfig_warnings) { | ||||||
|  | +		btn_dialog(main_window, | ||||||
|  | +			"\nWarnings encountered, and warnings are errors.\n\n", | ||||||
|  | +			1, | ||||||
|  | +			"<OK>"); | ||||||
|  | +		res = 2; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	/* if we got here, the user really wants to exit */ | ||||||
|  |  	switch (res) { | ||||||
|  |  	case 0: | ||||||
|  | Index: kconfig/qconf.cc | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/qconf.cc | ||||||
|  | +++ kconfig/qconf.cc | ||||||
|  | @@ -26,6 +26,8 @@ | ||||||
|  |  #include "images.h" | ||||||
|  |   | ||||||
|  |   | ||||||
|  | +int kconfig_warnings = 0; | ||||||
|  | + | ||||||
|  |  static QApplication *configApp; | ||||||
|  |  static ConfigSettings *configSettings; | ||||||
|  |   | ||||||
|  | Index: kconfig/symbol.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/symbol.c | ||||||
|  | +++ kconfig/symbol.c | ||||||
|  | @@ -319,6 +319,7 @@ static void sym_warn_unmet_dep(struct sy | ||||||
|  |  			       "  Selected by [m]:\n"); | ||||||
|  |   | ||||||
|  |  	fputs(str_get(&gs), stderr); | ||||||
|  | +	kconfig_warnings++; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void sym_calc_value(struct symbol *sym) | ||||||
| @@ -0,0 +1,94 @@ | |||||||
|  | From 5e2355bf017b3347b29126a0eeb866558334f704 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Stefan Reinauer <stefan.reinauer@coreboot.org> | ||||||
|  | Date: Fri, 3 Apr 2015 20:01:38 +0200 | ||||||
|  | Subject: [PATCH] kconfig: Add wildcard support for "source" | ||||||
|  |  | ||||||
|  | Kconfig's include directive "source" does not support | ||||||
|  | wildcards (e.g. source src/mainboard/*/Kconfig) which | ||||||
|  | makes automatic inclusion of all boards a tedious task | ||||||
|  | and prevents us from implementing "drop in" boards. | ||||||
|  |  | ||||||
|  | In our Makefile.inc files we already include mainboard | ||||||
|  | directories per wildcard, so let's add the infrastructure | ||||||
|  | to do the same with Kconfig. | ||||||
|  |  | ||||||
|  | v2: change from wordexp to glob for better portability. | ||||||
|  |  | ||||||
|  | Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> | ||||||
|  | Signed-off-by: Patrick Georgi <pgeorgi@google.com> | ||||||
|  | --- | ||||||
|  |  util/kconfig/lexer.l  | 27 +++++++++++++++++++++++++++ | ||||||
|  |  util/kconfig/lkc.h    |  1 + | ||||||
|  |  util/kconfig/parser.y |  2 +- | ||||||
|  |  3 files changed, 29 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | Index: kconfig/lexer.l | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/lexer.l | ||||||
|  | +++ kconfig/lexer.l | ||||||
|  | @@ -8,6 +8,7 @@ | ||||||
|  |  %{ | ||||||
|  |   | ||||||
|  |  #include <assert.h> | ||||||
|  | +#include <glob.h> | ||||||
|  |  #include <limits.h> | ||||||
|  |  #include <stdio.h> | ||||||
|  |  #include <stdlib.h> | ||||||
|  | @@ -438,6 +439,32 @@ void zconf_nextfile(const char *name) | ||||||
|  |  	current_file = file; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void zconf_nextfiles(const char *wildcard) | ||||||
|  | +{ | ||||||
|  | +	glob_t g; | ||||||
|  | +	char **w; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	if (glob(wildcard, 0, NULL, &g) != 0) { | ||||||
|  | +		return; | ||||||
|  | +	} | ||||||
|  | +	if (g.gl_pathv == NULL) { | ||||||
|  | +		globfree(&g); | ||||||
|  | +		return; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* working through files backwards, since | ||||||
|  | +	 * we're first pushing them on a stack | ||||||
|  | +	 * before actually handling them. | ||||||
|  | +	 */ | ||||||
|  | +	for (i = g.gl_pathc; i > 0; i--) { | ||||||
|  | +		w = &g.gl_pathv[i - 1]; | ||||||
|  | +		zconf_nextfile(*w); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	globfree(&g); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static void zconf_endfile(void) | ||||||
|  |  { | ||||||
|  |  	struct buffer *parent; | ||||||
|  | Index: kconfig/lkc.h | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/lkc.h | ||||||
|  | +++ kconfig/lkc.h | ||||||
|  | @@ -36,6 +36,7 @@ void zconf_starthelp(void); | ||||||
|  |  FILE *zconf_fopen(const char *name); | ||||||
|  |  void zconf_initscan(const char *name); | ||||||
|  |  void zconf_nextfile(const char *name); | ||||||
|  | +void zconf_nextfiles(const char *name); | ||||||
|  |  int zconf_lineno(void); | ||||||
|  |  const char *zconf_curname(void); | ||||||
|  |   | ||||||
|  | Index: kconfig/parser.y | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/parser.y | ||||||
|  | +++ kconfig/parser.y | ||||||
|  | @@ -358,7 +358,7 @@ menu_option_list: | ||||||
|  |  source_stmt: T_SOURCE T_WORD_QUOTE T_EOL | ||||||
|  |  { | ||||||
|  |  	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); | ||||||
|  | -	zconf_nextfile($2); | ||||||
|  | +	zconf_nextfiles($2); | ||||||
|  |  	free($2); | ||||||
|  |  }; | ||||||
|  |   | ||||||
| @@ -0,0 +1,93 @@ | |||||||
|  | commit ab0cc6067d5a00182e89fbec82b942eb3d803204 | ||||||
|  | Author: Patrick Georgi <pgeorgi@google.com> | ||||||
|  | Date:   Fri Nov 22 22:08:15 2019 +0100 | ||||||
|  |  | ||||||
|  |     util/kconfig: Allow emitting false booleans into kconfig output | ||||||
|  |  | ||||||
|  |     This is controlled by an environment variable so the same tool is | ||||||
|  |     useful in different contexts. | ||||||
|  |  | ||||||
|  |     Change-Id: I9e62b05e45709f1539e455e2eed37308609be15e | ||||||
|  |     Signed-off-by: Patrick Georgi <pgeorgi@google.com> | ||||||
|  |  | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -687,6 +687,9 @@ header_print_symbol(FILE *fp, struct sym | ||||||
|  |   | ||||||
|  |  		switch (*value) { | ||||||
|  |  		case 'n': | ||||||
|  | +			if (getenv("KCONFIG_NEGATIVES") != NULL) | ||||||
|  | +				fprintf(fp, "#define %s%s%s 0\n", | ||||||
|  | +				    CONFIG_, sym->name, suffix); | ||||||
|  |  			break; | ||||||
|  |  		case 'm': | ||||||
|  |  			suffix = "_MODULE"; | ||||||
|  | @@ -702,14 +705,28 @@ header_print_symbol(FILE *fp, struct sym | ||||||
|  |   | ||||||
|  |  		if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) | ||||||
|  |  			prefix = "0x"; | ||||||
|  | +		if (value[0] == '\0') { | ||||||
|  | +			/* | ||||||
|  | +			 * prefix is reset to remain closer to the older | ||||||
|  | +			 * coreboot patch. No need to keep this once kconfig | ||||||
|  | +			 * is fully upreved | ||||||
|  | +			 */ | ||||||
|  | +			prefix = ""; | ||||||
|  | +			value = "0"; | ||||||
|  | +		} | ||||||
|  |  		fprintf(fp, "#define %s%s %s%s\n", | ||||||
|  |  		    CONFIG_, sym->name, prefix, value); | ||||||
|  |  		break; | ||||||
|  |  	} | ||||||
|  |  	case S_STRING: | ||||||
|  | +		if (value[0] == '\0') | ||||||
|  | +			break; | ||||||
|  | +		if (!(sym->flags & SYMBOL_WRITE)) | ||||||
|  | +			break; | ||||||
|  | +		/* fall through */ | ||||||
|  |  	case S_INT: | ||||||
|  |  		fprintf(fp, "#define %s%s %s\n", | ||||||
|  | -		    CONFIG_, sym->name, value); | ||||||
|  | +		    CONFIG_, sym->name, value[0]?value:"0"); | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		break; | ||||||
|  | @@ -1080,6 +1097,7 @@ int conf_write_autoconf(int overwrite) | ||||||
|  |  	const char *autoconf_name = conf_get_autoconfig_name(); | ||||||
|  |  	FILE *out, *out_h; | ||||||
|  |  	int i; | ||||||
|  | +	int print_negatives = getenv("KCONFIG_NEGATIVES") != NULL; | ||||||
|  |   | ||||||
|  |  	if (!overwrite && is_present(autoconf_name)) | ||||||
|  |  		return 0; | ||||||
|  | @@ -1104,11 +1122,13 @@ int conf_write_autoconf(int overwrite) | ||||||
|  |   | ||||||
|  |  	for_all_symbols(i, sym) { | ||||||
|  |  		sym_calc_value(sym); | ||||||
|  | -		if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | ||||||
|  | +		if (!(sym->flags & SYMBOL_WRITE) && !print_negatives) | ||||||
|  | +			continue; | ||||||
|  | +		if (!sym->name) | ||||||
|  |  			continue; | ||||||
|  |   | ||||||
|  |  		/* write symbols to auto.conf and autoconf.h */ | ||||||
|  | -		conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); | ||||||
|  | +		conf_write_symbol(out, sym, &kconfig_printer_cb, print_negatives?NULL:(void *)1); | ||||||
|  |  		conf_write_symbol(out_h, sym, &header_printer_cb, NULL); | ||||||
|  |  	} | ||||||
|  |  	fclose(out); | ||||||
|  | Index: kconfig/symbol.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/symbol.c | ||||||
|  | +++ kconfig/symbol.c | ||||||
|  | @@ -757,7 +757,7 @@ const char *sym_get_string_default(struc | ||||||
|  |  		} | ||||||
|  |  	case S_INT: | ||||||
|  |  	case S_HEX: | ||||||
|  | -		return str; | ||||||
|  | +		return "0"; | ||||||
|  |  	case S_STRING: | ||||||
|  |  		return str; | ||||||
|  |  	case S_UNKNOWN: | ||||||
							
								
								
									
										16
									
								
								util/kconfig/patches/0010-reenable-source-in-choice.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								util/kconfig/patches/0010-reenable-source-in-choice.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | Kconfig 5.8 (since commit 09d5873e4d1f70202314b5fe40160f9b14b9d2d0) | ||||||
|  | blocks using the source statement within choice but that's a pattern we | ||||||
|  | use intensively. Re-enable it. | ||||||
|  |  | ||||||
|  | Index: kconfig/parser.y | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/parser.y | ||||||
|  | +++ kconfig/parser.y | ||||||
|  | @@ -134,6 +134,7 @@ stmt_list_in_choice: | ||||||
|  |  	| stmt_list_in_choice comment_stmt | ||||||
|  |  	| stmt_list_in_choice config_stmt | ||||||
|  |  	| stmt_list_in_choice if_stmt_in_choice | ||||||
|  | +	| stmt_list_in_choice source_stmt | ||||||
|  |  	| stmt_list_in_choice error T_EOL	{ zconf_error("invalid statement"); } | ||||||
|  |  ; | ||||||
|  |   | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -241,6 +241,13 @@ static const char *conf_get_autoconfig_n | ||||||
|  |  	return name ? name : "include/config/auto.conf"; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static const char *conf_get_autobase_name(void) | ||||||
|  | +{ | ||||||
|  | +	char *name = getenv("KCONFIG_SPLITCONFIG"); | ||||||
|  | + | ||||||
|  | +	return name ? name : "include/config/"; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | ||||||
|  |  { | ||||||
|  |  	char *p2; | ||||||
|  | @@ -1024,7 +1031,7 @@ static int conf_touch_deps(void) | ||||||
|  |  	struct symbol *sym; | ||||||
|  |  	int res, i; | ||||||
|  |   | ||||||
|  | -	strcpy(depfile_path, "include/config/"); | ||||||
|  | +	strcpy(depfile_path, conf_get_autobase_name()); | ||||||
|  |  	depfile_prefix_len = strlen(depfile_path); | ||||||
|  |   | ||||||
|  |  	name = conf_get_autoconfig_name(); | ||||||
|  | @@ -1102,7 +1109,10 @@ int conf_write_autoconf(int overwrite) | ||||||
|  |  	if (!overwrite && is_present(autoconf_name)) | ||||||
|  |  		return 0; | ||||||
|  |   | ||||||
|  | -	conf_write_dep("include/config/auto.conf.cmd"); | ||||||
|  | +	char autoconfcmd_path[PATH_MAX]; | ||||||
|  | +	snprintf(autoconfcmd_path, sizeof(autoconfcmd_path), "%s%s", | ||||||
|  | +		conf_get_autobase_name(), "auto.conf.cmd"); | ||||||
|  | +	conf_write_dep(autoconfcmd_path); | ||||||
|  |   | ||||||
|  |  	if (conf_touch_deps()) | ||||||
|  |  		return 1; | ||||||
							
								
								
									
										124
									
								
								util/kconfig/patches/0012-safer-tmpfiles.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								util/kconfig/patches/0012-safer-tmpfiles.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | commit 7b2deddbb0ef350e189fe42c025b07c943aedc4c | ||||||
|  | Author: Raul E Rangel <rrangel@chromium.org> | ||||||
|  | Date:   Thu Jul 25 15:49:52 2019 -0600 | ||||||
|  |  | ||||||
|  |     Kconfig: Write tmp files into same directory as target files | ||||||
|  |  | ||||||
|  |     This removes the need for COREBOOT_BUILD_DIR in Kconfig. Since the | ||||||
|  |     original files will be replaced with the tmp file, the parent directory | ||||||
|  |     already needs to be writable. | ||||||
|  |  | ||||||
|  |     Before this change, the tmp files would be created in the CWD (src) if | ||||||
|  |     COREBOOT_BUILD_DIR was not specified. | ||||||
|  |  | ||||||
|  |     BUG=b:112267918 | ||||||
|  |     TEST=emerge-grunt coreboot and verified no tmp files were created in the | ||||||
|  |     src directory. | ||||||
|  |  | ||||||
|  |     Change-Id: Icdaf2ff3dd1ec98813b75ef55b96e38e1ca19ec7 | ||||||
|  |     Signed-off-by: Raul E Rangel <rrangel@chromium.org> | ||||||
|  |     Reviewed-on: https://review.coreboot.org/c/coreboot/+/34244 | ||||||
|  |     Reviewed-by: Martin Roth <martinroth@google.com> | ||||||
|  |     Tested-by: build bot (Jenkins) <no-reply@coreboot.org> | ||||||
|  |  | ||||||
|  | Index: kconfig/confdata.c | ||||||
|  | =================================================================== | ||||||
|  | --- kconfig.orig/confdata.c | ||||||
|  | +++ kconfig/confdata.c | ||||||
|  | @@ -880,6 +880,16 @@ next_menu: | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | + | ||||||
|  | +static int conf_mktemp(const char *path, char *tmpfile) | ||||||
|  | +{ | ||||||
|  | +	if (snprintf(tmpfile, PATH_MAX, "%s.tmp.XXXXXX", path) >= PATH_MAX) { | ||||||
|  | +		errno = EOVERFLOW; | ||||||
|  | +		return -1; | ||||||
|  | +	} | ||||||
|  | +	return mkstemp(tmpfile); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  int conf_write(const char *name) | ||||||
|  |  { | ||||||
|  |  	FILE *out; | ||||||
|  | @@ -1001,7 +1011,14 @@ static int conf_write_dep(const char *na | ||||||
|  |  	struct file *file; | ||||||
|  |  	FILE *out; | ||||||
|  |   | ||||||
|  | -	out = fopen("..config.tmp", "w"); | ||||||
|  | +	if (make_parent_dir(name)) | ||||||
|  | +		return 1; | ||||||
|  | +	char filename[PATH_MAX]; | ||||||
|  | +	int fd = conf_mktemp(name, filename); | ||||||
|  | +	if (fd == -1) | ||||||
|  | +		return 1; | ||||||
|  | + | ||||||
|  | +	out = fdopen(fd, "w"); | ||||||
|  |  	if (!out) | ||||||
|  |  		return 1; | ||||||
|  |  	fprintf(out, "deps_config := \\\n"); | ||||||
|  | @@ -1019,9 +1036,7 @@ static int conf_write_dep(const char *na | ||||||
|  |  	fprintf(out, "\n$(deps_config): ;\n"); | ||||||
|  |  	fclose(out); | ||||||
|  |   | ||||||
|  | -	if (make_parent_dir(name)) | ||||||
|  | -		return 1; | ||||||
|  | -	rename("..config.tmp", name); | ||||||
|  | +	rename(filename, name); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1117,11 +1132,26 @@ int conf_write_autoconf(int overwrite) | ||||||
|  |  	if (conf_touch_deps()) | ||||||
|  |  		return 1; | ||||||
|  |   | ||||||
|  | -	out = fopen(".tmpconfig", "w"); | ||||||
|  | +	if (make_parent_dir(autoconf_name)) | ||||||
|  | +		return 1; | ||||||
|  | +	char filename[PATH_MAX]; | ||||||
|  | +	int fd = conf_mktemp(autoconf_name, filename); | ||||||
|  | +	if (fd == -1) | ||||||
|  | +		return 1; | ||||||
|  | +	out = fdopen(fd, "w"); | ||||||
|  |  	if (!out) | ||||||
|  |  		return 1; | ||||||
|  |   | ||||||
|  | -	out_h = fopen(".tmpconfig.h", "w"); | ||||||
|  | +	name = getenv("KCONFIG_AUTOHEADER"); | ||||||
|  | +	if (!name) | ||||||
|  | +		name = "include/generated/autoconf.h"; | ||||||
|  | +	if (make_parent_dir(name)) | ||||||
|  | +		return 1; | ||||||
|  | +	char filename_h[PATH_MAX]; | ||||||
|  | +	int fd_h = conf_mktemp(name, filename_h); | ||||||
|  | +	if (fd_h == -1) | ||||||
|  | +		return 1; | ||||||
|  | +	out_h = fdopen(fd_h, "w"); | ||||||
|  |  	if (!out_h) { | ||||||
|  |  		fclose(out); | ||||||
|  |  		return 1; | ||||||
|  | @@ -1144,21 +1174,14 @@ int conf_write_autoconf(int overwrite) | ||||||
|  |  	fclose(out); | ||||||
|  |  	fclose(out_h); | ||||||
|  |   | ||||||
|  | -	name = getenv("KCONFIG_AUTOHEADER"); | ||||||
|  | -	if (!name) | ||||||
|  | -		name = "include/generated/autoconf.h"; | ||||||
|  | -	if (make_parent_dir(name)) | ||||||
|  | -		return 1; | ||||||
|  | -	if (rename(".tmpconfig.h", name)) | ||||||
|  | +	if (rename(filename_h, name)) | ||||||
|  |  		return 1; | ||||||
|  |   | ||||||
|  | -	if (make_parent_dir(autoconf_name)) | ||||||
|  | -		return 1; | ||||||
|  |  	/* | ||||||
|  |  	 * This must be the last step, kbuild has a dependency on auto.conf | ||||||
|  |  	 * and this marks the successful completion of the previous steps. | ||||||
|  |  	 */ | ||||||
|  | -	if (rename(".tmpconfig", autoconf_name)) | ||||||
|  | +	if (rename(filename, autoconf_name)) | ||||||
|  |  		return 1; | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
							
								
								
									
										12
									
								
								util/kconfig/patches/series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								util/kconfig/patches/series
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | 0001-Kconfig-Add-KCONFIG_STRICT-mode.patch | ||||||
|  | 0002-Kconfig-Change-symbol-override-from-warning-to-notic.patch | ||||||
|  | 0003-util-kconfig-conf.c-Fix-newline-in-error-printf.patch | ||||||
|  | 0004-src-util-Use-NULL-instead-of-0-for-pointer.patch | ||||||
|  | 0005-util-kconfig-Ignore-extra-symbols-in-configs-instead.patch | ||||||
|  | 0006-util-kconfig-Set-parameter-of-mkdir-to-only-one-for-.patch | ||||||
|  | 0007-kconfig-Allow-KCONFIG_STRICT-outside-of-confdata.c.patch | ||||||
|  | 0008-kconfig-Add-wildcard-support-for-source.patch | ||||||
|  | 0009-util-kconfig-Allow-emitting-false-booleans-into-kconfig-output.patch | ||||||
|  | 0010-reenable-source-in-choice.patch | ||||||
|  | 0011-remove-include-config-hardcodes.patch | ||||||
|  | 0012-safer-tmpfiles.patch | ||||||
							
								
								
									
										574
									
								
								util/kconfig/preprocess.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										574
									
								
								util/kconfig/preprocess.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,574 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
|  | // | ||||||
|  | // Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com> | ||||||
|  |  | ||||||
|  | #include <ctype.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "list.h" | ||||||
|  | #include "lkc.h" | ||||||
|  |  | ||||||
|  | #define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0])) | ||||||
|  |  | ||||||
|  | static char *expand_string_with_args(const char *in, int argc, char *argv[]); | ||||||
|  | static char *expand_string(const char *in); | ||||||
|  |  | ||||||
|  | static void __attribute__((noreturn)) pperror(const char *format, ...) | ||||||
|  | { | ||||||
|  | 	va_list ap; | ||||||
|  |  | ||||||
|  | 	fprintf(stderr, "%s:%d: ", current_file->name, yylineno); | ||||||
|  | 	va_start(ap, format); | ||||||
|  | 	vfprintf(stderr, format, ap); | ||||||
|  | 	va_end(ap); | ||||||
|  | 	fprintf(stderr, "\n"); | ||||||
|  |  | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Environment variables | ||||||
|  |  */ | ||||||
|  | static LIST_HEAD(env_list); | ||||||
|  |  | ||||||
|  | struct env { | ||||||
|  | 	char *name; | ||||||
|  | 	char *value; | ||||||
|  | 	struct list_head node; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void env_add(const char *name, const char *value) | ||||||
|  | { | ||||||
|  | 	struct env *e; | ||||||
|  |  | ||||||
|  | 	e = xmalloc(sizeof(*e)); | ||||||
|  | 	e->name = xstrdup(name); | ||||||
|  | 	e->value = xstrdup(value); | ||||||
|  |  | ||||||
|  | 	list_add_tail(&e->node, &env_list); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void env_del(struct env *e) | ||||||
|  | { | ||||||
|  | 	list_del(&e->node); | ||||||
|  | 	free(e->name); | ||||||
|  | 	free(e->value); | ||||||
|  | 	free(e); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* The returned pointer must be freed when done */ | ||||||
|  | static char *env_expand(const char *name) | ||||||
|  | { | ||||||
|  | 	struct env *e; | ||||||
|  | 	const char *value; | ||||||
|  |  | ||||||
|  | 	if (!*name) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	list_for_each_entry(e, &env_list, node) { | ||||||
|  | 		if (!strcmp(name, e->name)) | ||||||
|  | 			return xstrdup(e->value); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	value = getenv(name); | ||||||
|  | 	if (!value) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * We need to remember all referenced environment variables. | ||||||
|  | 	 * They will be written out to include/config/auto.conf.cmd | ||||||
|  | 	 */ | ||||||
|  | 	env_add(name, value); | ||||||
|  |  | ||||||
|  | 	return xstrdup(value); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void env_write_dep(FILE *f, const char *autoconfig_name) | ||||||
|  | { | ||||||
|  | 	struct env *e, *tmp; | ||||||
|  |  | ||||||
|  | 	list_for_each_entry_safe(e, tmp, &env_list, node) { | ||||||
|  | 		fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value); | ||||||
|  | 		fprintf(f, "%s: FORCE\n", autoconfig_name); | ||||||
|  | 		fprintf(f, "endif\n"); | ||||||
|  | 		env_del(e); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Built-in functions | ||||||
|  |  */ | ||||||
|  | struct function { | ||||||
|  | 	const char *name; | ||||||
|  | 	unsigned int min_args; | ||||||
|  | 	unsigned int max_args; | ||||||
|  | 	char *(*func)(int argc, char *argv[]); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static char *do_error_if(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	if (!strcmp(argv[0], "y")) | ||||||
|  | 		pperror("%s", argv[1]); | ||||||
|  |  | ||||||
|  | 	return xstrdup(""); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *do_filename(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	return xstrdup(current_file->name); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *do_info(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	printf("%s\n", argv[0]); | ||||||
|  |  | ||||||
|  | 	return xstrdup(""); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *do_lineno(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	char buf[16]; | ||||||
|  |  | ||||||
|  | 	sprintf(buf, "%d", yylineno); | ||||||
|  |  | ||||||
|  | 	return xstrdup(buf); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *do_shell(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	FILE *p; | ||||||
|  | 	char buf[256]; | ||||||
|  | 	char *cmd; | ||||||
|  | 	size_t nread; | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	cmd = argv[0]; | ||||||
|  |  | ||||||
|  | 	p = popen(cmd, "r"); | ||||||
|  | 	if (!p) { | ||||||
|  | 		perror(cmd); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	nread = fread(buf, 1, sizeof(buf), p); | ||||||
|  | 	if (nread == sizeof(buf)) | ||||||
|  | 		nread--; | ||||||
|  |  | ||||||
|  | 	/* remove trailing new lines */ | ||||||
|  | 	while (nread > 0 && buf[nread - 1] == '\n') | ||||||
|  | 		nread--; | ||||||
|  |  | ||||||
|  | 	buf[nread] = 0; | ||||||
|  |  | ||||||
|  | 	/* replace a new line with a space */ | ||||||
|  | 	for (i = 0; i < nread; i++) { | ||||||
|  | 		if (buf[i] == '\n') | ||||||
|  | 			buf[i] = ' '; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (pclose(p) == -1) { | ||||||
|  | 		perror(cmd); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return xstrdup(buf); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *do_warning_if(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	if (!strcmp(argv[0], "y")) | ||||||
|  | 		fprintf(stderr, "%s:%d: %s\n", | ||||||
|  | 			current_file->name, yylineno, argv[1]); | ||||||
|  |  | ||||||
|  | 	return xstrdup(""); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const struct function function_table[] = { | ||||||
|  | 	/* Name		MIN	MAX	Function */ | ||||||
|  | 	{ "error-if",	2,	2,	do_error_if }, | ||||||
|  | 	{ "filename",	0,	0,	do_filename }, | ||||||
|  | 	{ "info",	1,	1,	do_info }, | ||||||
|  | 	{ "lineno",	0,	0,	do_lineno }, | ||||||
|  | 	{ "shell",	1,	1,	do_shell }, | ||||||
|  | 	{ "warning-if",	2,	2,	do_warning_if }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #define FUNCTION_MAX_ARGS		16 | ||||||
|  |  | ||||||
|  | static char *function_expand(const char *name, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	const struct function *f; | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < ARRAY_SIZE(function_table); i++) { | ||||||
|  | 		f = &function_table[i]; | ||||||
|  | 		if (strcmp(f->name, name)) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (argc < f->min_args) | ||||||
|  | 			pperror("too few function arguments passed to '%s'", | ||||||
|  | 				name); | ||||||
|  |  | ||||||
|  | 		if (argc > f->max_args) | ||||||
|  | 			pperror("too many function arguments passed to '%s'", | ||||||
|  | 				name); | ||||||
|  |  | ||||||
|  | 		return f->func(argc, argv); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Variables (and user-defined functions) | ||||||
|  |  */ | ||||||
|  | static LIST_HEAD(variable_list); | ||||||
|  |  | ||||||
|  | struct variable { | ||||||
|  | 	char *name; | ||||||
|  | 	char *value; | ||||||
|  | 	enum variable_flavor flavor; | ||||||
|  | 	int exp_count; | ||||||
|  | 	struct list_head node; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static struct variable *variable_lookup(const char *name) | ||||||
|  | { | ||||||
|  | 	struct variable *v; | ||||||
|  |  | ||||||
|  | 	list_for_each_entry(v, &variable_list, node) { | ||||||
|  | 		if (!strcmp(name, v->name)) | ||||||
|  | 			return v; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *variable_expand(const char *name, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	struct variable *v; | ||||||
|  | 	char *res; | ||||||
|  |  | ||||||
|  | 	v = variable_lookup(name); | ||||||
|  | 	if (!v) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	if (argc == 0 && v->exp_count) | ||||||
|  | 		pperror("Recursive variable '%s' references itself (eventually)", | ||||||
|  | 			name); | ||||||
|  |  | ||||||
|  | 	if (v->exp_count > 1000) | ||||||
|  | 		pperror("Too deep recursive expansion"); | ||||||
|  |  | ||||||
|  | 	v->exp_count++; | ||||||
|  |  | ||||||
|  | 	if (v->flavor == VAR_RECURSIVE) | ||||||
|  | 		res = expand_string_with_args(v->value, argc, argv); | ||||||
|  | 	else | ||||||
|  | 		res = xstrdup(v->value); | ||||||
|  |  | ||||||
|  | 	v->exp_count--; | ||||||
|  |  | ||||||
|  | 	return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void variable_add(const char *name, const char *value, | ||||||
|  | 		  enum variable_flavor flavor) | ||||||
|  | { | ||||||
|  | 	struct variable *v; | ||||||
|  | 	char *new_value; | ||||||
|  | 	bool append = false; | ||||||
|  |  | ||||||
|  | 	v = variable_lookup(name); | ||||||
|  | 	if (v) { | ||||||
|  | 		/* For defined variables, += inherits the existing flavor */ | ||||||
|  | 		if (flavor == VAR_APPEND) { | ||||||
|  | 			flavor = v->flavor; | ||||||
|  | 			append = true; | ||||||
|  | 		} else { | ||||||
|  | 			free(v->value); | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		/* For undefined variables, += assumes the recursive flavor */ | ||||||
|  | 		if (flavor == VAR_APPEND) | ||||||
|  | 			flavor = VAR_RECURSIVE; | ||||||
|  |  | ||||||
|  | 		v = xmalloc(sizeof(*v)); | ||||||
|  | 		v->name = xstrdup(name); | ||||||
|  | 		v->exp_count = 0; | ||||||
|  | 		list_add_tail(&v->node, &variable_list); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	v->flavor = flavor; | ||||||
|  |  | ||||||
|  | 	if (flavor == VAR_SIMPLE) | ||||||
|  | 		new_value = expand_string(value); | ||||||
|  | 	else | ||||||
|  | 		new_value = xstrdup(value); | ||||||
|  |  | ||||||
|  | 	if (append) { | ||||||
|  | 		v->value = xrealloc(v->value, | ||||||
|  | 				    strlen(v->value) + strlen(new_value) + 2); | ||||||
|  | 		strcat(v->value, " "); | ||||||
|  | 		strcat(v->value, new_value); | ||||||
|  | 		free(new_value); | ||||||
|  | 	} else { | ||||||
|  | 		v->value = new_value; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void variable_del(struct variable *v) | ||||||
|  | { | ||||||
|  | 	list_del(&v->node); | ||||||
|  | 	free(v->name); | ||||||
|  | 	free(v->value); | ||||||
|  | 	free(v); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void variable_all_del(void) | ||||||
|  | { | ||||||
|  | 	struct variable *v, *tmp; | ||||||
|  |  | ||||||
|  | 	list_for_each_entry_safe(v, tmp, &variable_list, node) | ||||||
|  | 		variable_del(v); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Evaluate a clause with arguments.  argc/argv are arguments from the upper | ||||||
|  |  * function call. | ||||||
|  |  * | ||||||
|  |  * Returned string must be freed when done | ||||||
|  |  */ | ||||||
|  | static char *eval_clause(const char *str, size_t len, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	char *tmp, *name, *res, *endptr, *prev, *p; | ||||||
|  | 	int new_argc = 0; | ||||||
|  | 	char *new_argv[FUNCTION_MAX_ARGS]; | ||||||
|  | 	int nest = 0; | ||||||
|  | 	int i; | ||||||
|  | 	unsigned long n; | ||||||
|  |  | ||||||
|  | 	tmp = xstrndup(str, len); | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * If variable name is '1', '2', etc.  It is generally an argument | ||||||
|  | 	 * from a user-function call (i.e. local-scope variable).  If not | ||||||
|  | 	 * available, then look-up global-scope variables. | ||||||
|  | 	 */ | ||||||
|  | 	n = strtoul(tmp, &endptr, 10); | ||||||
|  | 	if (!*endptr && n > 0 && n <= argc) { | ||||||
|  | 		res = xstrdup(argv[n - 1]); | ||||||
|  | 		goto free_tmp; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	prev = p = tmp; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * Split into tokens | ||||||
|  | 	 * The function name and arguments are separated by a comma. | ||||||
|  | 	 * For example, if the function call is like this: | ||||||
|  | 	 *   $(foo,$(x),$(y)) | ||||||
|  | 	 * | ||||||
|  | 	 * The input string for this helper should be: | ||||||
|  | 	 *   foo,$(x),$(y) | ||||||
|  | 	 * | ||||||
|  | 	 * and split into: | ||||||
|  | 	 *   new_argv[0] = 'foo' | ||||||
|  | 	 *   new_argv[1] = '$(x)' | ||||||
|  | 	 *   new_argv[2] = '$(y)' | ||||||
|  | 	 */ | ||||||
|  | 	while (*p) { | ||||||
|  | 		if (nest == 0 && *p == ',') { | ||||||
|  | 			*p = 0; | ||||||
|  | 			if (new_argc >= FUNCTION_MAX_ARGS) | ||||||
|  | 				pperror("too many function arguments"); | ||||||
|  | 			new_argv[new_argc++] = prev; | ||||||
|  | 			prev = p + 1; | ||||||
|  | 		} else if (*p == '(') { | ||||||
|  | 			nest++; | ||||||
|  | 		} else if (*p == ')') { | ||||||
|  | 			nest--; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		p++; | ||||||
|  | 	} | ||||||
|  | 	new_argv[new_argc++] = prev; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * Shift arguments | ||||||
|  | 	 * new_argv[0] represents a function name or a variable name.  Put it | ||||||
|  | 	 * into 'name', then shift the rest of the arguments.  This simplifies | ||||||
|  | 	 * 'const' handling. | ||||||
|  | 	 */ | ||||||
|  | 	name = expand_string_with_args(new_argv[0], argc, argv); | ||||||
|  | 	new_argc--; | ||||||
|  | 	for (i = 0; i < new_argc; i++) | ||||||
|  | 		new_argv[i] = expand_string_with_args(new_argv[i + 1], | ||||||
|  | 						      argc, argv); | ||||||
|  |  | ||||||
|  | 	/* Search for variables */ | ||||||
|  | 	res = variable_expand(name, new_argc, new_argv); | ||||||
|  | 	if (res) | ||||||
|  | 		goto free; | ||||||
|  |  | ||||||
|  | 	/* Look for built-in functions */ | ||||||
|  | 	res = function_expand(name, new_argc, new_argv); | ||||||
|  | 	if (res) | ||||||
|  | 		goto free; | ||||||
|  |  | ||||||
|  | 	/* Last, try environment variable */ | ||||||
|  | 	if (new_argc == 0) { | ||||||
|  | 		res = env_expand(name); | ||||||
|  | 		if (res) | ||||||
|  | 			goto free; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	res = xstrdup(""); | ||||||
|  | free: | ||||||
|  | 	for (i = 0; i < new_argc; i++) | ||||||
|  | 		free(new_argv[i]); | ||||||
|  | 	free(name); | ||||||
|  | free_tmp: | ||||||
|  | 	free(tmp); | ||||||
|  |  | ||||||
|  | 	return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Expand a string that follows '$' | ||||||
|  |  * | ||||||
|  |  * For example, if the input string is | ||||||
|  |  *     ($(FOO)$($(BAR)))$(BAZ) | ||||||
|  |  * this helper evaluates | ||||||
|  |  *     $($(FOO)$($(BAR))) | ||||||
|  |  * and returns a new string containing the expansion (note that the string is | ||||||
|  |  * recursively expanded), also advancing 'str' to point to the next character | ||||||
|  |  * after the corresponding closing parenthesis, in this case, *str will be | ||||||
|  |  *     $(BAR) | ||||||
|  |  */ | ||||||
|  | static char *expand_dollar_with_args(const char **str, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	const char *p = *str; | ||||||
|  | 	const char *q; | ||||||
|  | 	int nest = 0; | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	 * In Kconfig, variable/function references always start with "$(". | ||||||
|  | 	 * Neither single-letter variables as in $A nor curly braces as in ${CC} | ||||||
|  | 	 * are supported.  '$' not followed by '(' loses its special meaning. | ||||||
|  | 	 */ | ||||||
|  | 	if (*p != '(') { | ||||||
|  | 		*str = p; | ||||||
|  | 		return xstrdup("$"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	p++; | ||||||
|  | 	q = p; | ||||||
|  | 	while (*q) { | ||||||
|  | 		if (*q == '(') { | ||||||
|  | 			nest++; | ||||||
|  | 		} else if (*q == ')') { | ||||||
|  | 			if (nest-- == 0) | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 		q++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!*q) | ||||||
|  | 		pperror("unterminated reference to '%s': missing ')'", p); | ||||||
|  |  | ||||||
|  | 	/* Advance 'str' to after the expanded initial portion of the string */ | ||||||
|  | 	*str = q + 1; | ||||||
|  |  | ||||||
|  | 	return eval_clause(p, q - p, argc, argv); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char *expand_dollar(const char **str) | ||||||
|  | { | ||||||
|  | 	return expand_dollar_with_args(str, 0, NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *__expand_string(const char **str, bool (*is_end)(char c), | ||||||
|  | 			     int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	const char *in, *p; | ||||||
|  | 	char *expansion, *out; | ||||||
|  | 	size_t in_len, out_len; | ||||||
|  |  | ||||||
|  | 	out = xmalloc(1); | ||||||
|  | 	*out = 0; | ||||||
|  | 	out_len = 1; | ||||||
|  |  | ||||||
|  | 	p = in = *str; | ||||||
|  |  | ||||||
|  | 	while (1) { | ||||||
|  | 		if (*p == '$') { | ||||||
|  | 			in_len = p - in; | ||||||
|  | 			p++; | ||||||
|  | 			expansion = expand_dollar_with_args(&p, argc, argv); | ||||||
|  | 			out_len += in_len + strlen(expansion); | ||||||
|  | 			out = xrealloc(out, out_len); | ||||||
|  | 			strncat(out, in, in_len); | ||||||
|  | 			strcat(out, expansion); | ||||||
|  | 			free(expansion); | ||||||
|  | 			in = p; | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (is_end(*p)) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		p++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	in_len = p - in; | ||||||
|  | 	out_len += in_len; | ||||||
|  | 	out = xrealloc(out, out_len); | ||||||
|  | 	strncat(out, in, in_len); | ||||||
|  |  | ||||||
|  | 	/* Advance 'str' to the end character */ | ||||||
|  | 	*str = p; | ||||||
|  |  | ||||||
|  | 	return out; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static bool is_end_of_str(char c) | ||||||
|  | { | ||||||
|  | 	return !c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Expand variables and functions in the given string.  Undefined variables | ||||||
|  |  * expand to an empty string. | ||||||
|  |  * The returned string must be freed when done. | ||||||
|  |  */ | ||||||
|  | static char *expand_string_with_args(const char *in, int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	return __expand_string(&in, is_end_of_str, argc, argv); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *expand_string(const char *in) | ||||||
|  | { | ||||||
|  | 	return expand_string_with_args(in, 0, NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static bool is_end_of_token(char c) | ||||||
|  | { | ||||||
|  | 	return !(isalnum(c) || c == '_' || c == '-'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Expand variables in a token.  The parsing stops when a token separater | ||||||
|  |  * (in most cases, it is a whitespace) is encountered.  'str' is updated to | ||||||
|  |  * point to the next character. | ||||||
|  |  * | ||||||
|  |  * The returned string must be freed when done. | ||||||
|  |  */ | ||||||
|  | char *expand_one_token(const char **str) | ||||||
|  | { | ||||||
|  | 	return __expand_string(str, is_end_of_token, 0, NULL); | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								util/kconfig/qconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								util/kconfig/qconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # SPDX-License-Identifier: GPL-2.0 | ||||||
|  |  | ||||||
|  | PKG="Qt5Core Qt5Gui Qt5Widgets" | ||||||
|  |  | ||||||
|  | if [ -z "$(command -v pkg-config)" ]; then | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it." | ||||||
|  | 	echo >&2 "*" | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if pkg-config --exists $PKG; then | ||||||
|  | 	echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags $PKG)\" | ||||||
|  | 	echo libs=\"$(pkg-config --libs $PKG)\" | ||||||
|  | 	echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" | ||||||
|  | 	exit 0 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo >&2 "*" | ||||||
|  | echo >&2 "* Could not find Qt5 via pkg-config." | ||||||
|  | echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH" | ||||||
|  | echo >&2 "*" | ||||||
|  | exit 1 | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,25 +1,24 @@ | |||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <QTextBrowser> |  | ||||||
| #include <QTreeWidget> |  | ||||||
| #include <QMainWindow> |  | ||||||
| #include <QHeaderView> |  | ||||||
| #include <qsettings.h> |  | ||||||
| #include <QPushButton> |  | ||||||
| #include <QSettings> |  | ||||||
| #include <QLineEdit> |  | ||||||
| #include <QSplitter> |  | ||||||
| #include <QCheckBox> | #include <QCheckBox> | ||||||
| #include <QDialog> | #include <QDialog> | ||||||
|  | #include <QHeaderView> | ||||||
|  | #include <QLineEdit> | ||||||
|  | #include <QMainWindow> | ||||||
|  | #include <QPushButton> | ||||||
|  | #include <QSettings> | ||||||
|  | #include <QSplitter> | ||||||
|  | #include <QStyledItemDelegate> | ||||||
|  | #include <QTextBrowser> | ||||||
|  | #include <QTreeWidget> | ||||||
|  |  | ||||||
| #include "expr.h" | #include "expr.h" | ||||||
|  |  | ||||||
| class ConfigView; |  | ||||||
| class ConfigList; | class ConfigList; | ||||||
| class ConfigItem; | class ConfigItem; | ||||||
| class ConfigLineEdit; |  | ||||||
| class ConfigMainWindow; | class ConfigMainWindow; | ||||||
|  |  | ||||||
| class ConfigSettings : public QSettings { | class ConfigSettings : public QSettings { | ||||||
| @@ -30,7 +29,7 @@ public: | |||||||
| }; | }; | ||||||
|  |  | ||||||
| enum colIdx { | enum colIdx { | ||||||
| 	promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr | 	promptColIdx, nameColIdx, dataColIdx | ||||||
| }; | }; | ||||||
| enum listMode { | enum listMode { | ||||||
| 	singleMode, menuMode, symbolMode, fullMode, listMode | 	singleMode, menuMode, symbolMode, fullMode, listMode | ||||||
| @@ -43,13 +42,16 @@ class ConfigList : public QTreeWidget { | |||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
| 	typedef class QTreeWidget Parent; | 	typedef class QTreeWidget Parent; | ||||||
| public: | public: | ||||||
| 	ConfigList(ConfigView* p, const char *name = NULL); | 	ConfigList(QWidget *parent, const char *name = NULL); | ||||||
|  | 	~ConfigList(); | ||||||
| 	void reinit(void); | 	void reinit(void); | ||||||
| 	ConfigView* parent(void) const |  | ||||||
| 	{ |  | ||||||
| 		return (ConfigView*)Parent::parent(); |  | ||||||
| 	} |  | ||||||
| 	ConfigItem* findConfigItem(struct menu *); | 	ConfigItem* findConfigItem(struct menu *); | ||||||
|  | 	void setSelected(QTreeWidgetItem *item, bool enable) { | ||||||
|  | 		for (int i = 0; i < selectedItems().size(); i++) | ||||||
|  | 			selectedItems().at(i)->setSelected(false); | ||||||
|  |  | ||||||
|  | 		item->setSelected(enable); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
| 	void keyPressEvent(QKeyEvent *e); | 	void keyPressEvent(QKeyEvent *e); | ||||||
| @@ -63,61 +65,52 @@ protected: | |||||||
| public slots: | public slots: | ||||||
| 	void setRootMenu(struct menu *menu); | 	void setRootMenu(struct menu *menu); | ||||||
|  |  | ||||||
| 	void updateList(ConfigItem *item); | 	void updateList(); | ||||||
| 	void setValue(ConfigItem* item, tristate val); | 	void setValue(ConfigItem* item, tristate val); | ||||||
| 	void changeValue(ConfigItem* item); | 	void changeValue(ConfigItem* item); | ||||||
| 	void updateSelection(void); | 	void updateSelection(void); | ||||||
| 	void saveSettings(void); | 	void saveSettings(void); | ||||||
|  | 	void setOptionMode(QAction *action); | ||||||
|  | 	void setShowName(bool on); | ||||||
|  |  | ||||||
| signals: | signals: | ||||||
| 	void menuChanged(struct menu *menu); | 	void menuChanged(struct menu *menu); | ||||||
| 	void menuSelected(struct menu *menu); | 	void menuSelected(struct menu *menu); | ||||||
|  | 	void itemSelected(struct menu *menu); | ||||||
| 	void parentSelected(void); | 	void parentSelected(void); | ||||||
| 	void gotFocus(struct menu *); | 	void gotFocus(struct menu *); | ||||||
|  | 	void showNameChanged(bool on); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	void updateListAll(void) | 	void updateListAll(void) | ||||||
| 	{ | 	{ | ||||||
| 		updateAll = true; | 		updateAll = true; | ||||||
| 		updateList(NULL); | 		updateList(); | ||||||
| 		updateAll = false; | 		updateAll = false; | ||||||
| 	} | 	} | ||||||
| 	ConfigList* listView() |  | ||||||
| 	{ |  | ||||||
| 		return this; |  | ||||||
| 	} |  | ||||||
| 	ConfigItem* firstChild() const |  | ||||||
| 	{ |  | ||||||
| 		return (ConfigItem *)children().first(); |  | ||||||
| 	} |  | ||||||
| 	void addColumn(colIdx idx) |  | ||||||
| 	{ |  | ||||||
| 		showColumn(idx); |  | ||||||
| 	} |  | ||||||
| 	void removeColumn(colIdx idx) |  | ||||||
| 	{ |  | ||||||
| 		hideColumn(idx); |  | ||||||
| 	} |  | ||||||
| 	void setAllOpen(bool open); | 	void setAllOpen(bool open); | ||||||
| 	void setParentMenu(void); | 	void setParentMenu(void); | ||||||
|  |  | ||||||
| 	bool menuSkip(struct menu *); | 	bool menuSkip(struct menu *); | ||||||
|  |  | ||||||
| 	void updateMenuList(ConfigItem *parent, struct menu*); | 	void updateMenuList(ConfigItem *parent, struct menu*); | ||||||
| 	void updateMenuList(ConfigList *parent, struct menu*); | 	void updateMenuList(struct menu *menu); | ||||||
|  |  | ||||||
| 	bool updateAll; | 	bool updateAll; | ||||||
|  |  | ||||||
| 	QPixmap symbolYesPix, symbolModPix, symbolNoPix; | 	bool showName; | ||||||
| 	QPixmap choiceYesPix, choiceNoPix; |  | ||||||
| 	QPixmap menuPix, menuInvPix, menuBackPix, voidPix; |  | ||||||
|  |  | ||||||
| 	bool showName, showRange, showData; |  | ||||||
| 	enum listMode mode; | 	enum listMode mode; | ||||||
| 	enum optionMode optMode; | 	enum optionMode optMode; | ||||||
| 	struct menu *rootEntry; | 	struct menu *rootEntry; | ||||||
| 	QPalette disabledColorGroup; | 	QPalette disabledColorGroup; | ||||||
| 	QPalette inactivedColorGroup; | 	QPalette inactivedColorGroup; | ||||||
| 	QMenu* headerPopup; | 	QMenu* headerPopup; | ||||||
|  |  | ||||||
|  | 	static QList<ConfigList *> allLists; | ||||||
|  | 	static void updateListForAll(); | ||||||
|  | 	static void updateListAllForAll(); | ||||||
|  |  | ||||||
|  | 	static QAction *showNormalAction, *showAllAction, *showPromptAction; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class ConfigItem : public QTreeWidgetItem { | class ConfigItem : public QTreeWidgetItem { | ||||||
| @@ -140,7 +133,6 @@ public: | |||||||
| 	} | 	} | ||||||
| 	~ConfigItem(void); | 	~ConfigItem(void); | ||||||
| 	void init(void); | 	void init(void); | ||||||
| 	void okRename(int col); |  | ||||||
| 	void updateMenu(void); | 	void updateMenu(void); | ||||||
| 	void testUpdateMenu(bool v); | 	void testUpdateMenu(bool v); | ||||||
| 	ConfigList* listView() const | 	ConfigList* listView() const | ||||||
| @@ -165,82 +157,36 @@ public: | |||||||
|  |  | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 	void setText(colIdx idx, const QString& text) |  | ||||||
| 	{ |  | ||||||
| 		Parent::setText(idx, text); |  | ||||||
| 	} |  | ||||||
| 	QString text(colIdx idx) const |  | ||||||
| 	{ |  | ||||||
| 		return Parent::text(idx); |  | ||||||
| 	} |  | ||||||
| 	void setPixmap(colIdx idx, const QIcon &icon) |  | ||||||
| 	{ |  | ||||||
| 		Parent::setIcon(idx, icon); |  | ||||||
| 	} |  | ||||||
| 	const QIcon pixmap(colIdx idx) const |  | ||||||
| 	{ |  | ||||||
| 		return icon(idx); |  | ||||||
| 	} |  | ||||||
| 	// TODO: Implement paintCell | 	// TODO: Implement paintCell | ||||||
|  |  | ||||||
| 	ConfigItem* nextItem; | 	ConfigItem* nextItem; | ||||||
| 	struct menu *menu; | 	struct menu *menu; | ||||||
| 	bool visible; | 	bool visible; | ||||||
| 	bool goParent; | 	bool goParent; | ||||||
|  |  | ||||||
|  | 	static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon; | ||||||
|  | 	static QIcon choiceYesIcon, choiceNoIcon; | ||||||
|  | 	static QIcon menuIcon, menubackIcon; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class ConfigLineEdit : public QLineEdit { | class ConfigItemDelegate : public QStyledItemDelegate | ||||||
| 	Q_OBJECT | { | ||||||
| 	typedef class QLineEdit Parent; | private: | ||||||
|  | 	struct menu *menu; | ||||||
| public: | public: | ||||||
| 	ConfigLineEdit(ConfigView* parent); | 	ConfigItemDelegate(QObject *parent = nullptr) | ||||||
| 	ConfigView* parent(void) const | 		: QStyledItemDelegate(parent) {} | ||||||
| 	{ | 	QWidget *createEditor(QWidget *parent, | ||||||
| 		return (ConfigView*)Parent::parent(); | 			      const QStyleOptionViewItem &option, | ||||||
| 	} | 			      const QModelIndex &index) const override; | ||||||
| 	void show(ConfigItem *i); | 	void setModelData(QWidget *editor, QAbstractItemModel *model, | ||||||
| 	void keyPressEvent(QKeyEvent *e); | 			  const QModelIndex &index) const override; | ||||||
|  |  | ||||||
| public: |  | ||||||
| 	ConfigItem *item; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class ConfigView : public QWidget { |  | ||||||
| 	Q_OBJECT |  | ||||||
| 	typedef class QWidget Parent; |  | ||||||
| public: |  | ||||||
| 	ConfigView(QWidget* parent, const char *name = NULL); |  | ||||||
| 	~ConfigView(void); |  | ||||||
| 	static void updateList(ConfigItem* item); |  | ||||||
| 	static void updateListAll(void); |  | ||||||
|  |  | ||||||
| 	bool showName(void) const { return list->showName; } |  | ||||||
| 	bool showRange(void) const { return list->showRange; } |  | ||||||
| 	bool showData(void) const { return list->showData; } |  | ||||||
| public slots: |  | ||||||
| 	void setShowName(bool); |  | ||||||
| 	void setShowRange(bool); |  | ||||||
| 	void setShowData(bool); |  | ||||||
| 	void setOptionMode(QAction *); |  | ||||||
| signals: |  | ||||||
| 	void showNameChanged(bool); |  | ||||||
| 	void showRangeChanged(bool); |  | ||||||
| 	void showDataChanged(bool); |  | ||||||
| public: |  | ||||||
| 	ConfigList* list; |  | ||||||
| 	ConfigLineEdit* lineEdit; |  | ||||||
|  |  | ||||||
| 	static ConfigView* viewList; |  | ||||||
| 	ConfigView* nextView; |  | ||||||
|  |  | ||||||
| 	static QAction *showNormalAction; |  | ||||||
| 	static QAction *showAllAction; |  | ||||||
| 	static QAction *showPromptAction; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class ConfigInfoView : public QTextBrowser { | class ConfigInfoView : public QTextBrowser { | ||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
| 	typedef class QTextBrowser Parent; | 	typedef class QTextBrowser Parent; | ||||||
|  | 	QMenu *contextMenu; | ||||||
| public: | public: | ||||||
| 	ConfigInfoView(QWidget* parent, const char *name = NULL); | 	ConfigInfoView(QWidget* parent, const char *name = NULL); | ||||||
| 	bool showDebug(void) const { return _showDebug; } | 	bool showDebug(void) const { return _showDebug; } | ||||||
| @@ -249,6 +195,7 @@ public slots: | |||||||
| 	void setInfo(struct menu *menu); | 	void setInfo(struct menu *menu); | ||||||
| 	void saveSettings(void); | 	void saveSettings(void); | ||||||
| 	void setShowDebug(bool); | 	void setShowDebug(bool); | ||||||
|  | 	void clicked (const QUrl &url); | ||||||
|  |  | ||||||
| signals: | signals: | ||||||
| 	void showDebugChanged(bool); | 	void showDebugChanged(bool); | ||||||
| @@ -260,8 +207,7 @@ 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); | ||||||
| 	QMenu *createStandardContextMenu(const QPoint & pos); | 	void contextMenuEvent(QContextMenuEvent *event); | ||||||
| 	void contextMenuEvent(QContextMenuEvent *e); |  | ||||||
|  |  | ||||||
| 	struct symbol *sym; | 	struct symbol *sym; | ||||||
| 	struct menu *_menu; | 	struct menu *_menu; | ||||||
| @@ -272,7 +218,7 @@ class ConfigSearchWindow : public QDialog { | |||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
| 	typedef class QDialog Parent; | 	typedef class QDialog Parent; | ||||||
| public: | public: | ||||||
| 	ConfigSearchWindow(ConfigMainWindow* parent, const char *name = NULL); | 	ConfigSearchWindow(ConfigMainWindow *parent); | ||||||
|  |  | ||||||
| public slots: | public slots: | ||||||
| 	void saveSettings(void); | 	void saveSettings(void); | ||||||
| @@ -282,7 +228,7 @@ protected: | |||||||
| 	QLineEdit* editField; | 	QLineEdit* editField; | ||||||
| 	QPushButton* searchButton; | 	QPushButton* searchButton; | ||||||
| 	QSplitter* split; | 	QSplitter* split; | ||||||
| 	ConfigView* list; | 	ConfigList *list; | ||||||
| 	ConfigInfoView* info; | 	ConfigInfoView* info; | ||||||
|  |  | ||||||
| 	struct symbol **result; | 	struct symbol **result; | ||||||
| @@ -291,12 +237,14 @@ protected: | |||||||
| class ConfigMainWindow : public QMainWindow { | class ConfigMainWindow : public QMainWindow { | ||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
|  |  | ||||||
|  | 	char *configname; | ||||||
| 	static QAction *saveAction; | 	static QAction *saveAction; | ||||||
| 	static void conf_changed(void); | 	static void conf_changed(void); | ||||||
| public: | public: | ||||||
| 	ConfigMainWindow(void); | 	ConfigMainWindow(void); | ||||||
| public slots: | public slots: | ||||||
| 	void changeMenu(struct menu *); | 	void changeMenu(struct menu *); | ||||||
|  | 	void changeItens(struct menu *); | ||||||
| 	void setMenuLink(struct menu *); | 	void setMenuLink(struct menu *); | ||||||
| 	void listFocusChanged(void); | 	void listFocusChanged(void); | ||||||
| 	void goBack(void); | 	void goBack(void); | ||||||
| @@ -315,12 +263,9 @@ protected: | |||||||
| 	void closeEvent(QCloseEvent *e); | 	void closeEvent(QCloseEvent *e); | ||||||
|  |  | ||||||
| 	ConfigSearchWindow *searchWindow; | 	ConfigSearchWindow *searchWindow; | ||||||
| 	ConfigView *menuView; |  | ||||||
| 	ConfigList *menuList; | 	ConfigList *menuList; | ||||||
| 	ConfigView *configView; |  | ||||||
| 	ConfigList *configList; | 	ConfigList *configList; | ||||||
| 	ConfigInfoView *helpText; | 	ConfigInfoView *helpText; | ||||||
| 	QToolBar *toolBar; |  | ||||||
| 	QAction *backAction; | 	QAction *backAction; | ||||||
| 	QAction *singleViewAction; | 	QAction *singleViewAction; | ||||||
| 	QAction *splitViewAction; | 	QAction *splitViewAction; | ||||||
|   | |||||||
							
								
								
									
										704
									
								
								util/kconfig/streamline_config.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										704
									
								
								util/kconfig/streamline_config.pl
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,704 @@ | |||||||
|  | #!/usr/bin/env perl | ||||||
|  | # SPDX-License-Identifier: GPL-2.0 | ||||||
|  | # | ||||||
|  | # Copyright 2005-2009 - Steven Rostedt | ||||||
|  | # | ||||||
|  | #  It's simple enough to figure out how this works. | ||||||
|  | #  If not, then you can ask me at stripconfig@goodmis.org | ||||||
|  | # | ||||||
|  | # What it does? | ||||||
|  | # | ||||||
|  | #   If you have installed a Linux kernel from a distribution | ||||||
|  | #   that turns on way too many modules than you need, and | ||||||
|  | #   you only want the modules you use, then this program | ||||||
|  | #   is perfect for you. | ||||||
|  | # | ||||||
|  | #   It gives you the ability to turn off all the modules that are | ||||||
|  | #   not loaded on your system. | ||||||
|  | # | ||||||
|  | # Howto: | ||||||
|  | # | ||||||
|  | #  1. Boot up the kernel that you want to stream line the config on. | ||||||
|  | #  2. Change directory to the directory holding the source of the | ||||||
|  | #       kernel that you just booted. | ||||||
|  | #  3. Copy the configuration file to this directory as .config | ||||||
|  | #  4. Have all your devices that you need modules for connected and | ||||||
|  | #      operational (make sure that their corresponding modules are loaded) | ||||||
|  | #  5. Run this script redirecting the output to some other file | ||||||
|  | #       like config_strip. | ||||||
|  | #  6. Back up your old config (if you want too). | ||||||
|  | #  7. copy the config_strip file to .config | ||||||
|  | #  8. Run "make oldconfig" | ||||||
|  | # | ||||||
|  | #  Now your kernel is ready to be built with only the modules that | ||||||
|  | #  are loaded. | ||||||
|  | # | ||||||
|  | # Here's what I did with my Debian distribution. | ||||||
|  | # | ||||||
|  | #    cd /usr/src/linux-2.6.10 | ||||||
|  | #    cp /boot/config-2.6.10-1-686-smp .config | ||||||
|  | #    ~/bin/streamline_config > config_strip | ||||||
|  | #    mv .config config_sav | ||||||
|  | #    mv config_strip .config | ||||||
|  | #    make oldconfig | ||||||
|  | # | ||||||
|  | use warnings; | ||||||
|  | use strict; | ||||||
|  | use Getopt::Long; | ||||||
|  |  | ||||||
|  | # set the environment variable LOCALMODCONFIG_DEBUG to get | ||||||
|  | # debug output. | ||||||
|  | my $debugprint = 0; | ||||||
|  | $debugprint = 1 if (defined($ENV{LOCALMODCONFIG_DEBUG})); | ||||||
|  |  | ||||||
|  | sub dprint { | ||||||
|  |     return if (!$debugprint); | ||||||
|  |     print STDERR @_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | my $uname = `uname -r`; | ||||||
|  | chomp $uname; | ||||||
|  |  | ||||||
|  | my @searchconfigs = ( | ||||||
|  | 	{ | ||||||
|  | 	    "file" => ".config", | ||||||
|  | 	    "exec" => "cat", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "/proc/config.gz", | ||||||
|  | 	    "exec" => "zcat", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "/boot/config-$uname", | ||||||
|  | 	    "exec" => "cat", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "/boot/vmlinuz-$uname", | ||||||
|  | 	    "exec" => "scripts/extract-ikconfig", | ||||||
|  | 	    "test" => "scripts/extract-ikconfig", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "vmlinux", | ||||||
|  | 	    "exec" => "scripts/extract-ikconfig", | ||||||
|  | 	    "test" => "scripts/extract-ikconfig", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "/lib/modules/$uname/kernel/kernel/configs.ko", | ||||||
|  | 	    "exec" => "scripts/extract-ikconfig", | ||||||
|  | 	    "test" => "scripts/extract-ikconfig", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "kernel/configs.ko", | ||||||
|  | 	    "exec" => "scripts/extract-ikconfig", | ||||||
|  | 	    "test" => "scripts/extract-ikconfig", | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 	    "file" => "kernel/configs.o", | ||||||
|  | 	    "exec" => "scripts/extract-ikconfig", | ||||||
|  | 	    "test" => "scripts/extract-ikconfig", | ||||||
|  | 	}, | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | sub read_config { | ||||||
|  |     foreach my $conf (@searchconfigs) { | ||||||
|  | 	my $file = $conf->{"file"}; | ||||||
|  |  | ||||||
|  | 	next if ( ! -f "$file"); | ||||||
|  |  | ||||||
|  | 	if (defined($conf->{"test"})) { | ||||||
|  | 	    `$conf->{"test"} $conf->{"file"} 2>/dev/null`; | ||||||
|  | 	    next if ($?); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	my $exec = $conf->{"exec"}; | ||||||
|  |  | ||||||
|  | 	print STDERR "using config: '$file'\n"; | ||||||
|  |  | ||||||
|  | 	open(my $infile, '-|', "$exec $file") || die "Failed to run $exec $file"; | ||||||
|  | 	my @x = <$infile>; | ||||||
|  | 	close $infile; | ||||||
|  | 	return @x; | ||||||
|  |     } | ||||||
|  |     die "No config file found"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | my @config_file = read_config; | ||||||
|  |  | ||||||
|  | # Parse options | ||||||
|  | my $localmodconfig = 0; | ||||||
|  | my $localyesconfig = 0; | ||||||
|  |  | ||||||
|  | GetOptions("localmodconfig" => \$localmodconfig, | ||||||
|  | 	   "localyesconfig" => \$localyesconfig); | ||||||
|  |  | ||||||
|  | # Get the build source and top level Kconfig file (passed in) | ||||||
|  | my $ksource = ($ARGV[0] ? $ARGV[0] : '.'); | ||||||
|  | my $kconfig = $ARGV[1]; | ||||||
|  | my $lsmod_file = $ENV{'LSMOD'}; | ||||||
|  |  | ||||||
|  | my @makefiles = `find $ksource -name Makefile -or -name Kbuild 2>/dev/null`; | ||||||
|  | chomp @makefiles; | ||||||
|  |  | ||||||
|  | my %depends; | ||||||
|  | my %selects; | ||||||
|  | my %prompts; | ||||||
|  | my %objects; | ||||||
|  | my %config2kfile; | ||||||
|  | my $var; | ||||||
|  | my $iflevel = 0; | ||||||
|  | my @ifdeps; | ||||||
|  |  | ||||||
|  | # prevent recursion | ||||||
|  | my %read_kconfigs; | ||||||
|  |  | ||||||
|  | sub read_kconfig { | ||||||
|  |     my ($kconfig) = @_; | ||||||
|  |  | ||||||
|  |     my $state = "NONE"; | ||||||
|  |     my $config; | ||||||
|  |  | ||||||
|  |     my $cont = 0; | ||||||
|  |     my $line; | ||||||
|  |  | ||||||
|  |     my $source = "$ksource/$kconfig"; | ||||||
|  |     my $last_source = ""; | ||||||
|  |  | ||||||
|  |     # Check for any environment variables used | ||||||
|  |     while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) { | ||||||
|  | 	my $env = $1; | ||||||
|  | 	$last_source = $source; | ||||||
|  | 	$source =~ s/\$\($env\)/$ENV{$env}/; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     open(my $kinfile, '<', $source) || die "Can't open $kconfig"; | ||||||
|  |     while (<$kinfile>) { | ||||||
|  | 	chomp; | ||||||
|  |  | ||||||
|  | 	# Make sure that lines ending with \ continue | ||||||
|  | 	if ($cont) { | ||||||
|  | 	    $_ = $line . " " . $_; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (s/\\$//) { | ||||||
|  | 	    $cont = 1; | ||||||
|  | 	    $line = $_; | ||||||
|  | 	    next; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$cont = 0; | ||||||
|  |  | ||||||
|  | 	# collect any Kconfig sources | ||||||
|  | 	if (/^source\s+"?([^"]+)/) { | ||||||
|  | 	    my $kconfig = $1; | ||||||
|  | 	    # prevent reading twice. | ||||||
|  | 	    if (!defined($read_kconfigs{$kconfig})) { | ||||||
|  | 		$read_kconfigs{$kconfig} = 1; | ||||||
|  | 		read_kconfig($kconfig); | ||||||
|  | 	    } | ||||||
|  | 	    next; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	# configs found | ||||||
|  | 	if (/^\s*(menu)?config\s+(\S+)\s*$/) { | ||||||
|  | 	    $state = "NEW"; | ||||||
|  | 	    $config = $2; | ||||||
|  | 	    $config2kfile{"CONFIG_$config"} = $kconfig; | ||||||
|  |  | ||||||
|  | 	    # Add depends for 'if' nesting | ||||||
|  | 	    for (my $i = 0; $i < $iflevel; $i++) { | ||||||
|  | 		if ($i) { | ||||||
|  | 		    $depends{$config} .= " " . $ifdeps[$i]; | ||||||
|  | 		} else { | ||||||
|  | 		    $depends{$config} = $ifdeps[$i]; | ||||||
|  | 		} | ||||||
|  | 		$state = "DEP"; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	# collect the depends for the config | ||||||
|  | 	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { | ||||||
|  | 	    $state = "DEP"; | ||||||
|  | 	    $depends{$config} = $1; | ||||||
|  | 	} elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { | ||||||
|  | 	    $depends{$config} .= " " . $1; | ||||||
|  | 	} 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 | ||||||
|  | 	} elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { | ||||||
|  | 	    my $conf = $1; | ||||||
|  | 	    if (defined($selects{$conf})) { | ||||||
|  | 		$selects{$conf} .= " " . $config; | ||||||
|  | 	    } else { | ||||||
|  | 		$selects{$conf} = $config; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	# configs without prompts must be selected | ||||||
|  | 	} elsif ($state ne "NONE" && /^\s*(tristate\s+\S|prompt\b)/) { | ||||||
|  | 	    # note if the config has a prompt | ||||||
|  | 	    $prompts{$config} = 1; | ||||||
|  |  | ||||||
|  | 	# Check for if statements | ||||||
|  | 	} elsif (/^if\s+(.*\S)\s*$/) { | ||||||
|  | 	    my $deps = $1; | ||||||
|  | 	    # remove beginning and ending non text | ||||||
|  | 	    $deps =~ s/^[^a-zA-Z0-9_]*//; | ||||||
|  | 	    $deps =~ s/[^a-zA-Z0-9_]*$//; | ||||||
|  |  | ||||||
|  | 	    my @deps = split /[^a-zA-Z0-9_]+/, $deps; | ||||||
|  |  | ||||||
|  | 	    $ifdeps[$iflevel++] = join ':', @deps; | ||||||
|  |  | ||||||
|  | 	} elsif (/^endif/) { | ||||||
|  |  | ||||||
|  | 	    $iflevel-- if ($iflevel); | ||||||
|  |  | ||||||
|  | 	# stop on "help" and keywords that end a menu entry | ||||||
|  | 	} elsif (/^\s*(---)?help(---)?\s*$/ || /^(comment|choice|menu)\b/) { | ||||||
|  | 	    $state = "NONE"; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     close($kinfile); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if ($kconfig) { | ||||||
|  |     read_kconfig($kconfig); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Makefiles can use variables to define their dependencies | ||||||
|  | sub convert_vars { | ||||||
|  |     my ($line, %vars) = @_; | ||||||
|  |  | ||||||
|  |     my $process = ""; | ||||||
|  |  | ||||||
|  |     while ($line =~ s/^(.*?)(\$\((.*?)\))//) { | ||||||
|  | 	my $start = $1; | ||||||
|  | 	my $variable = $2; | ||||||
|  | 	my $var = $3; | ||||||
|  |  | ||||||
|  | 	if (defined($vars{$var})) { | ||||||
|  | 	    $process .= $start . $vars{$var}; | ||||||
|  | 	} else { | ||||||
|  | 	    $process .= $start . $variable; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $process .= $line; | ||||||
|  |  | ||||||
|  |     return $process; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Read all Makefiles to map the configs to the objects | ||||||
|  | foreach my $makefile (@makefiles) { | ||||||
|  |  | ||||||
|  |     my $line = ""; | ||||||
|  |     my %make_vars; | ||||||
|  |  | ||||||
|  |     open(my $infile, '<', $makefile) || die "Can't open $makefile"; | ||||||
|  |     while (<$infile>) { | ||||||
|  | 	# if this line ends with a backslash, continue | ||||||
|  | 	chomp; | ||||||
|  | 	if (/^(.*)\\$/) { | ||||||
|  | 	    $line .= $1; | ||||||
|  | 	    next; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	$line .= $_; | ||||||
|  | 	$_ = $line; | ||||||
|  | 	$line = ""; | ||||||
|  |  | ||||||
|  | 	my $objs; | ||||||
|  |  | ||||||
|  | 	# Convert variables in a line (could define configs) | ||||||
|  | 	$_ = convert_vars($_, %make_vars); | ||||||
|  |  | ||||||
|  | 	# collect objects after obj-$(CONFIG_FOO_BAR) | ||||||
|  | 	if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { | ||||||
|  | 	    $var = $1; | ||||||
|  | 	    $objs = $2; | ||||||
|  |  | ||||||
|  | 	# check if variables are set | ||||||
|  | 	} elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { | ||||||
|  | 	    $make_vars{$1} = $2; | ||||||
|  | 	} | ||||||
|  | 	if (defined($objs)) { | ||||||
|  | 	    foreach my $obj (split /\s+/,$objs) { | ||||||
|  | 		$obj =~ s/-/_/g; | ||||||
|  | 		if ($obj =~ /(.*)\.o$/) { | ||||||
|  | 		    # Objects may be enabled by more than one config. | ||||||
|  | 		    # Store configs in an array. | ||||||
|  | 		    my @arr; | ||||||
|  |  | ||||||
|  | 		    if (defined($objects{$1})) { | ||||||
|  | 			@arr = @{$objects{$1}}; | ||||||
|  | 		    } | ||||||
|  |  | ||||||
|  | 		    $arr[$#arr+1] = $var; | ||||||
|  |  | ||||||
|  | 		    # The objects have a hash mapping to a reference | ||||||
|  | 		    # of an array of configs. | ||||||
|  | 		    $objects{$1} = \@arr; | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     close($infile); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | my %modules; | ||||||
|  | my $linfile; | ||||||
|  |  | ||||||
|  | if (defined($lsmod_file)) { | ||||||
|  |     if ( ! -f $lsmod_file) { | ||||||
|  | 	if ( -f $ENV{'objtree'}."/".$lsmod_file) { | ||||||
|  | 	    $lsmod_file = $ENV{'objtree'}."/".$lsmod_file; | ||||||
|  | 	} else { | ||||||
|  | 		die "$lsmod_file not found"; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     my $otype = ( -x $lsmod_file) ? '-|' : '<'; | ||||||
|  |     open($linfile, $otype, $lsmod_file); | ||||||
|  |  | ||||||
|  | } else { | ||||||
|  |  | ||||||
|  |     # see what modules are loaded on this system | ||||||
|  |     my $lsmod; | ||||||
|  |  | ||||||
|  |     foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { | ||||||
|  | 	if ( -x "$dir/lsmod" ) { | ||||||
|  | 	    $lsmod = "$dir/lsmod"; | ||||||
|  | 	    last; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     if (!defined($lsmod)) { | ||||||
|  | 	# try just the path | ||||||
|  | 	$lsmod = "lsmod"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     open($linfile, '-|', $lsmod) || die "Can not call lsmod with $lsmod"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | while (<$linfile>) { | ||||||
|  | 	next if (/^Module/);  # Skip the first line. | ||||||
|  | 	if (/^(\S+)/) { | ||||||
|  | 		$modules{$1} = 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | close ($linfile); | ||||||
|  |  | ||||||
|  | # add to the configs hash all configs that are needed to enable | ||||||
|  | # a loaded module. This is a direct obj-${CONFIG_FOO} += bar.o | ||||||
|  | # where we know we need bar.o so we add FOO to the list. | ||||||
|  | my %configs; | ||||||
|  | foreach my $module (keys(%modules)) { | ||||||
|  |     if (defined($objects{$module})) { | ||||||
|  | 	my @arr = @{$objects{$module}}; | ||||||
|  | 	foreach my $conf (@arr) { | ||||||
|  | 	    $configs{$conf} = $module; | ||||||
|  | 	    dprint "$conf added by direct ($module)\n"; | ||||||
|  | 	    if ($debugprint) { | ||||||
|  | 		my $c=$conf; | ||||||
|  | 		$c =~ s/^CONFIG_//; | ||||||
|  | 		if (defined($depends{$c})) { | ||||||
|  | 		    dprint " deps = $depends{$c}\n"; | ||||||
|  | 		} else { | ||||||
|  | 		    dprint " no deps\n"; | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |     } else { | ||||||
|  | 	# Most likely, someone has a custom (binary?) module loaded. | ||||||
|  | 	print STDERR "$module config not found!!\n"; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Read the current config, and see what is enabled. We want to | ||||||
|  | # ignore configs that we would not enable anyway. | ||||||
|  |  | ||||||
|  | my %orig_configs; | ||||||
|  | my $valid = "A-Za-z_0-9"; | ||||||
|  |  | ||||||
|  | foreach my $line (@config_file) { | ||||||
|  |     $_ = $line; | ||||||
|  |  | ||||||
|  |     if (/(CONFIG_[$valid]*)=(m|y)/) { | ||||||
|  | 	$orig_configs{$1} = $2; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | my $repeat = 1; | ||||||
|  |  | ||||||
|  | my $depconfig; | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # Note, we do not care about operands (like: &&, ||, !) we want to add any | ||||||
|  | # config that is in the depend list of another config. This script does | ||||||
|  | # not enable configs that are not already enabled. If we come across a | ||||||
|  | # config A that depends on !B, we can still add B to the list of depends | ||||||
|  | # to keep on. If A was on in the original config, B would not have been | ||||||
|  | # and B would not be turned on by this script. | ||||||
|  | # | ||||||
|  | sub parse_config_depends | ||||||
|  | { | ||||||
|  |     my ($p) = @_; | ||||||
|  |  | ||||||
|  |     while ($p =~ /[$valid]/) { | ||||||
|  |  | ||||||
|  | 	if ($p =~ /^[^$valid]*([$valid]+)/) { | ||||||
|  | 	    my $conf = "CONFIG_" . $1; | ||||||
|  |  | ||||||
|  | 	    $p =~ s/^[^$valid]*[$valid]+//; | ||||||
|  |  | ||||||
|  | 	    # We only need to process if the depend config is a module | ||||||
|  | 	    if (!defined($orig_configs{$conf}) || $orig_configs{$conf} eq "y") { | ||||||
|  | 		next; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	    if (!defined($configs{$conf})) { | ||||||
|  | 		# We must make sure that this config has its | ||||||
|  | 		# dependencies met. | ||||||
|  | 		$repeat = 1; # do again | ||||||
|  | 		dprint "$conf selected by depend $depconfig\n"; | ||||||
|  | 		$configs{$conf} = 1; | ||||||
|  | 	    } | ||||||
|  | 	} else { | ||||||
|  | 	    die "this should never happen"; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Select is treated a bit differently than depends. We call this | ||||||
|  | # when a config has no prompt and requires another config to be | ||||||
|  | # selected. We use to just select all configs that selected this | ||||||
|  | # config, but found that that can balloon into enabling hundreds | ||||||
|  | # of configs that we do not care about. | ||||||
|  | # | ||||||
|  | # The idea is we look at all the configs that select it. If one | ||||||
|  | # is already in our list of configs to enable, then there's nothing | ||||||
|  | # else to do. If there isn't, we pick the first config that was | ||||||
|  | # enabled in the original config and use that. | ||||||
|  | sub parse_config_selects | ||||||
|  | { | ||||||
|  |     my ($config, $p) = @_; | ||||||
|  |  | ||||||
|  |     my $next_config; | ||||||
|  |  | ||||||
|  |     while ($p =~ /[$valid]/) { | ||||||
|  |  | ||||||
|  | 	if ($p =~ /^[^$valid]*([$valid]+)/) { | ||||||
|  | 	    my $conf = "CONFIG_" . $1; | ||||||
|  |  | ||||||
|  | 	    $p =~ s/^[^$valid]*[$valid]+//; | ||||||
|  |  | ||||||
|  | 	    # Make sure that this config exists in the current .config file | ||||||
|  | 	    if (!defined($orig_configs{$conf})) { | ||||||
|  | 		dprint "$conf not set for $config select\n"; | ||||||
|  | 		next; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	    # Check if something other than a module selects this config | ||||||
|  | 	    if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") { | ||||||
|  | 		dprint "$conf (non module) selects config, we are good\n"; | ||||||
|  | 		# we are good with this | ||||||
|  | 		return; | ||||||
|  | 	    } | ||||||
|  | 	    if (defined($configs{$conf})) { | ||||||
|  | 		dprint "$conf selects $config so we are good\n"; | ||||||
|  | 		# A set config selects this config, we are good | ||||||
|  | 		return; | ||||||
|  | 	    } | ||||||
|  | 	    # Set this config to be selected | ||||||
|  | 	    if (!defined($next_config)) { | ||||||
|  | 		$next_config = $conf; | ||||||
|  | 	    } | ||||||
|  | 	} else { | ||||||
|  | 	    die "this should never happen"; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     # If no possible config selected this, then something happened. | ||||||
|  |     if (!defined($next_config)) { | ||||||
|  | 	print STDERR "WARNING: $config is required, but nothing in the\n"; | ||||||
|  | 	print STDERR "  current config selects it.\n"; | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     # If we are here, then we found no config that is set and | ||||||
|  |     # selects this config. Repeat. | ||||||
|  |     $repeat = 1; | ||||||
|  |     # Make this config need to be selected | ||||||
|  |     $configs{$next_config} = 1; | ||||||
|  |     dprint "$next_config selected by select $config\n"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | my %process_selects; | ||||||
|  |  | ||||||
|  | # loop through all configs, select their dependencies. | ||||||
|  | sub loop_depend { | ||||||
|  |     $repeat = 1; | ||||||
|  |  | ||||||
|  |     while ($repeat) { | ||||||
|  | 	$repeat = 0; | ||||||
|  |  | ||||||
|  |       forloop: | ||||||
|  | 	foreach my $config (keys %configs) { | ||||||
|  |  | ||||||
|  | 	    # If this config is not a module, we do not need to process it | ||||||
|  | 	    if (defined($orig_configs{$config}) && $orig_configs{$config} ne "m") { | ||||||
|  | 		next forloop; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	    $config =~ s/^CONFIG_//; | ||||||
|  | 	    $depconfig = $config; | ||||||
|  |  | ||||||
|  | 	    if (defined($depends{$config})) { | ||||||
|  | 		# This config has dependencies. Make sure they are also included | ||||||
|  | 		parse_config_depends $depends{$config}; | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	    # If the config has no prompt, then we need to check if a config | ||||||
|  | 	    # that is enabled selected it. Or if we need to enable one. | ||||||
|  | 	    if (!defined($prompts{$config}) && defined($selects{$config})) { | ||||||
|  | 		$process_selects{$config} = 1; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub loop_select { | ||||||
|  |  | ||||||
|  |     foreach my $config (keys %process_selects) { | ||||||
|  | 	$config =~ s/^CONFIG_//; | ||||||
|  |  | ||||||
|  | 	dprint "Process select $config\n"; | ||||||
|  |  | ||||||
|  | 	# config has no prompt and must be selected. | ||||||
|  | 	parse_config_selects $config, $selects{$config}; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | while ($repeat) { | ||||||
|  |     # Get the first set of configs and their dependencies. | ||||||
|  |     loop_depend; | ||||||
|  |  | ||||||
|  |     $repeat = 0; | ||||||
|  |  | ||||||
|  |     # Now we need to see if we have to check selects; | ||||||
|  |     loop_select; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | my %setconfigs; | ||||||
|  | my @preserved_kconfigs; | ||||||
|  | if (defined($ENV{'LMC_KEEP'})) { | ||||||
|  | 	@preserved_kconfigs = split(/:/,$ENV{LMC_KEEP}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub in_preserved_kconfigs { | ||||||
|  |     my $kconfig = $config2kfile{$_[0]}; | ||||||
|  |     if (!defined($kconfig)) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |     foreach my $excl (@preserved_kconfigs) { | ||||||
|  |         if($kconfig =~ /^$excl/) { | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Finally, read the .config file and turn off any module enabled that | ||||||
|  | # we could not find a reason to keep enabled. | ||||||
|  | foreach my $line (@config_file) { | ||||||
|  |     $_ = $line; | ||||||
|  |  | ||||||
|  |     if (/CONFIG_IKCONFIG/) { | ||||||
|  | 	if (/# CONFIG_IKCONFIG is not set/) { | ||||||
|  | 	    # enable IKCONFIG at least as a module | ||||||
|  | 	    print "CONFIG_IKCONFIG=m\n"; | ||||||
|  | 	    # don't ask about PROC | ||||||
|  | 	    print "# CONFIG_IKCONFIG_PROC is not set\n"; | ||||||
|  | 	} else { | ||||||
|  | 	    print; | ||||||
|  | 	} | ||||||
|  | 	next; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (/CONFIG_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 (in_preserved_kconfigs($1)) { | ||||||
|  |             dprint "Preserve config $1"; | ||||||
|  |             print; | ||||||
|  |             next; | ||||||
|  |         } | ||||||
|  | 	if (defined($configs{$1})) { | ||||||
|  | 	    if ($localyesconfig) { | ||||||
|  | 	        $setconfigs{$1} = 'y'; | ||||||
|  | 		print "$1=y\n"; | ||||||
|  | 		next; | ||||||
|  | 	    } else { | ||||||
|  | 	        $setconfigs{$1} = $2; | ||||||
|  | 	    } | ||||||
|  | 	} elsif ($2 eq "m") { | ||||||
|  | 	    print "# $1 is not set\n"; | ||||||
|  | 	    next; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     print; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # Integrity check, make sure all modules that we want enabled do | ||||||
|  | # indeed have their configs set. | ||||||
|  | loop: | ||||||
|  | foreach my $module (keys(%modules)) { | ||||||
|  |     if (defined($objects{$module})) { | ||||||
|  | 	my @arr = @{$objects{$module}}; | ||||||
|  | 	foreach my $conf (@arr) { | ||||||
|  | 	    if (defined($setconfigs{$conf})) { | ||||||
|  | 		next loop; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  | 	print STDERR "module $module did not have configs"; | ||||||
|  | 	foreach my $conf (@arr) { | ||||||
|  | 	    print STDERR " " , $conf; | ||||||
|  | 	} | ||||||
|  | 	print STDERR "\n"; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,15 +1,13 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #include <sys/types.h> | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <regex.h> | #include <regex.h> | ||||||
| #ifndef __MINGW32__ |  | ||||||
| #include <sys/utsname.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "lkc.h" | #include "lkc.h" | ||||||
|  |  | ||||||
| @@ -17,58 +15,28 @@ struct symbol symbol_yes = { | |||||||
| 	.name = "y", | 	.name = "y", | ||||||
| 	.curr = { "y", yes }, | 	.curr = { "y", yes }, | ||||||
| 	.flags = SYMBOL_CONST|SYMBOL_VALID, | 	.flags = SYMBOL_CONST|SYMBOL_VALID, | ||||||
| }, symbol_mod = { | }; | ||||||
|  |  | ||||||
|  | struct symbol symbol_mod = { | ||||||
| 	.name = "m", | 	.name = "m", | ||||||
| 	.curr = { "m", mod }, | 	.curr = { "m", mod }, | ||||||
| 	.flags = SYMBOL_CONST|SYMBOL_VALID, | 	.flags = SYMBOL_CONST|SYMBOL_VALID, | ||||||
| }, symbol_no = { | }; | ||||||
|  |  | ||||||
|  | struct symbol symbol_no = { | ||||||
| 	.name = "n", | 	.name = "n", | ||||||
| 	.curr = { "n", no }, | 	.curr = { "n", no }, | ||||||
| 	.flags = SYMBOL_CONST|SYMBOL_VALID, | 	.flags = SYMBOL_CONST|SYMBOL_VALID, | ||||||
| }, symbol_empty = { | }; | ||||||
|  |  | ||||||
|  | static struct symbol symbol_empty = { | ||||||
| 	.name = "", | 	.name = "", | ||||||
| 	.curr = { "", no }, | 	.curr = { "", no }, | ||||||
| 	.flags = SYMBOL_VALID, | 	.flags = SYMBOL_VALID, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct symbol *sym_defconfig_list; |  | ||||||
| struct symbol *modules_sym; | struct symbol *modules_sym; | ||||||
| tristate modules_val; | static tristate modules_val; | ||||||
|  |  | ||||||
| struct expr *sym_env_list; |  | ||||||
|  |  | ||||||
| static void sym_add_default(struct symbol *sym, const char *def) |  | ||||||
| { |  | ||||||
| 	struct property *prop = prop_alloc(P_DEFAULT, sym); |  | ||||||
|  |  | ||||||
| 	prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void sym_init(void) |  | ||||||
| { |  | ||||||
| 	struct symbol *sym; |  | ||||||
| #ifndef __MINGW32__ |  | ||||||
| 	struct utsname uts; |  | ||||||
| #endif |  | ||||||
| 	static bool inited = false; |  | ||||||
|  |  | ||||||
| 	if (inited) |  | ||||||
| 		return; |  | ||||||
| 	inited = true; |  | ||||||
|  |  | ||||||
| #ifndef __MINGW32__ |  | ||||||
| 	uname(&uts); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	sym = sym_lookup("UNAME_RELEASE", 0); |  | ||||||
| 	sym->type = S_STRING; |  | ||||||
| 	sym->flags |= SYMBOL_AUTO; |  | ||||||
| #ifndef __MINGW32__ |  | ||||||
| 	sym_add_default(sym, uts.release); |  | ||||||
| #else |  | ||||||
| 	sym_add_default(sym, "mingw-unknown"); |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
|  |  | ||||||
| enum symbol_type sym_get_type(struct symbol *sym) | enum symbol_type sym_get_type(struct symbol *sym) | ||||||
| { | { | ||||||
| @@ -87,7 +55,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: | ||||||
| @@ -98,8 +66,6 @@ const char *sym_type_name(enum symbol_type type) | |||||||
| 		return "string"; | 		return "string"; | ||||||
| 	case S_UNKNOWN: | 	case S_UNKNOWN: | ||||||
| 		return "unknown"; | 		return "unknown"; | ||||||
| 	case S_OTHER: |  | ||||||
| 		break; |  | ||||||
| 	} | 	} | ||||||
| 	return "???"; | 	return "???"; | ||||||
| } | } | ||||||
| @@ -113,16 +79,7 @@ struct property *sym_get_choice_prop(struct symbol *sym) | |||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct property *sym_get_env_prop(struct symbol *sym) | static struct property *sym_get_default_prop(struct symbol *sym) | ||||||
| { |  | ||||||
| 	struct property *prop; |  | ||||||
|  |  | ||||||
| 	for_all_properties(sym, prop, P_ENV) |  | ||||||
| 		return prop; |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct property *sym_get_default_prop(struct symbol *sym) |  | ||||||
| { | { | ||||||
| 	struct property *prop; | 	struct property *prop; | ||||||
|  |  | ||||||
| @@ -134,7 +91,7 @@ struct property *sym_get_default_prop(struct symbol *sym) | |||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| static struct property *sym_get_range_prop(struct symbol *sym) | struct property *sym_get_range_prop(struct symbol *sym) | ||||||
| { | { | ||||||
| 	struct property *prop; | 	struct property *prop; | ||||||
|  |  | ||||||
| @@ -193,18 +150,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)) | ||||||
| @@ -219,7 +210,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; | ||||||
| @@ -234,6 +225,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) | ||||||
|  | 		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); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -300,6 +300,28 @@ 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); | ||||||
|  | 	kconfig_warnings++; | ||||||
|  | } | ||||||
|  |  | ||||||
| void sym_calc_value(struct symbol *sym) | void sym_calc_value(struct symbol *sym) | ||||||
| { | { | ||||||
| 	struct symbol_value newval, oldval; | 	struct symbol_value newval, oldval; | ||||||
| @@ -338,11 +360,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; | ||||||
|  |  | ||||||
| @@ -357,7 +381,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); | ||||||
| @@ -369,25 +392,21 @@ 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); | ||||||
|  | 					newval.tri = EXPR_AND(newval.tri, | ||||||
|  | 							      sym->dir_dep.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"); |  | ||||||
| 				kconfig_warnings++; |  | ||||||
| 				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) | ||||||
| @@ -396,12 +415,9 @@ void sym_calc_value(struct symbol *sym) | |||||||
| 	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) { | ||||||
| @@ -443,7 +459,7 @@ void sym_calc_value(struct symbol *sym) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (sym->flags & SYMBOL_AUTO) | 	if (sym->flags & SYMBOL_NO_WRITE) | ||||||
| 		sym->flags &= ~SYMBOL_WRITE; | 		sym->flags &= ~SYMBOL_WRITE; | ||||||
|  |  | ||||||
| 	if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) | 	if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) | ||||||
| @@ -457,29 +473,8 @@ 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); | 	conf_set_changed(true); | ||||||
| 	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) | ||||||
| @@ -748,6 +743,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: | ||||||
| @@ -758,10 +757,9 @@ const char *sym_get_string_default(struct symbol *sym) | |||||||
| 		} | 		} | ||||||
| 	case S_INT: | 	case S_INT: | ||||||
| 	case S_HEX: | 	case S_HEX: | ||||||
| 		return str; | 		return "0"; | ||||||
| 	case S_STRING: | 	case S_STRING: | ||||||
| 		return str; | 		return str; | ||||||
| 	case S_OTHER: |  | ||||||
| 	case S_UNKNOWN: | 	case S_UNKNOWN: | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| @@ -792,7 +790,7 @@ const char *sym_get_string_value(struct symbol *sym) | |||||||
| 	return (const char *)sym->curr.val; | 	return (const char *)sym->curr.val; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool sym_is_changable(struct symbol *sym) | bool sym_is_changeable(struct symbol *sym) | ||||||
| { | { | ||||||
| 	return sym->visible > sym->rev_dep.tri; | 	return sym->visible > sym->rev_dep.tri; | ||||||
| } | } | ||||||
| @@ -829,7 +827,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; | ||||||
| @@ -839,7 +837,7 @@ struct symbol *sym_lookup(const char *name, int flags) | |||||||
| 	memset(symbol, 0, sizeof(*symbol)); | 	memset(symbol, 0, sizeof(*symbol)); | ||||||
| 	symbol->name = new_name; | 	symbol->name = new_name; | ||||||
| 	symbol->type = S_UNKNOWN; | 	symbol->type = S_UNKNOWN; | ||||||
| 	symbol->flags |= flags; | 	symbol->flags = flags; | ||||||
|  |  | ||||||
| 	symbol->next = symbol_hash[hash]; | 	symbol->next = symbol_hash[hash]; | ||||||
| 	symbol_hash[hash] = symbol; | 	symbol_hash[hash] = symbol; | ||||||
| @@ -874,55 +872,6 @@ struct symbol *sym_find(const char *name) | |||||||
| 	return symbol; | 	return symbol; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Expand symbol's names embedded in the string given in argument. Symbols' |  | ||||||
|  * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to |  | ||||||
|  * the empty string. |  | ||||||
|  */ |  | ||||||
| const char *sym_expand_string_value(const char *in) |  | ||||||
| { |  | ||||||
| 	const char *src; |  | ||||||
| 	char *res; |  | ||||||
| 	size_t reslen; |  | ||||||
|  |  | ||||||
| 	reslen = strlen(in) + 1; |  | ||||||
| 	res = xmalloc(reslen); |  | ||||||
| 	res[0] = '\0'; |  | ||||||
|  |  | ||||||
| 	while ((src = strchr(in, '$'))) { |  | ||||||
| 		char *p, name[SYMBOL_MAXLENGTH]; |  | ||||||
| 		const char *symval = ""; |  | ||||||
| 		struct symbol *sym; |  | ||||||
| 		size_t newlen; |  | ||||||
|  |  | ||||||
| 		strncat(res, in, src - in); |  | ||||||
| 		src++; |  | ||||||
|  |  | ||||||
| 		p = name; |  | ||||||
| 		while (isalnum(*src) || *src == '_') |  | ||||||
| 			*p++ = *src++; |  | ||||||
| 		*p = '\0'; |  | ||||||
|  |  | ||||||
| 		sym = sym_find(name); |  | ||||||
| 		if (sym != NULL) { |  | ||||||
| 			sym_calc_value(sym); |  | ||||||
| 			symval = sym_get_string_value(sym); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		newlen = strlen(res) + strlen(symval) + strlen(src) + 1; |  | ||||||
| 		if (newlen > reslen) { |  | ||||||
| 			reslen = newlen; |  | ||||||
| 			res = realloc(res, reslen); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		strcat(res, symval); |  | ||||||
| 		in = src; |  | ||||||
| 	} |  | ||||||
| 	strcat(res, in); |  | ||||||
|  |  | ||||||
| 	return res; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const char *sym_escape_string_value(const char *in) | const char *sym_escape_string_value(const char *in) | ||||||
| { | { | ||||||
| 	const char *p; | 	const char *p; | ||||||
| @@ -1039,7 +988,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++) | ||||||
| @@ -1064,7 +1013,7 @@ static struct dep_stack { | |||||||
| 	struct dep_stack *prev, *next; | 	struct dep_stack *prev, *next; | ||||||
| 	struct symbol *sym; | 	struct symbol *sym; | ||||||
| 	struct property *prop; | 	struct property *prop; | ||||||
| 	struct expr *expr; | 	struct expr **expr; | ||||||
| } *check_top; | } *check_top; | ||||||
|  |  | ||||||
| static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) | static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) | ||||||
| @@ -1128,18 +1077,8 @@ 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) { |  | ||||||
| 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", | 		if (sym_is_choice(sym)) { | ||||||
| 				prop->file->name, prop->lineno, |  | ||||||
| 				sym->name ? sym->name : "<choice>", |  | ||||||
| 				prop_get_type_name(prop->type), |  | ||||||
| 				next_sym->name ? next_sym->name : "<choice>"); |  | ||||||
| 		} else if (stack->prop) { |  | ||||||
| 			fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", |  | ||||||
| 				prop->file->name, prop->lineno, |  | ||||||
| 				sym->name ? sym->name : "<choice>", |  | ||||||
| 				next_sym->name ? next_sym->name : "<choice>"); |  | ||||||
| 		} else if (sym_is_choice(sym)) { |  | ||||||
| 			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", | 			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", | ||||||
| 				menu->file->name, menu->lineno, | 				menu->file->name, menu->lineno, | ||||||
| 				sym->name ? sym->name : "<choice>", | 				sym->name ? sym->name : "<choice>", | ||||||
| @@ -1149,14 +1088,41 @@ static void sym_check_print_recursive(struct symbol *last_sym) | |||||||
| 				menu->file->name, menu->lineno, | 				menu->file->name, menu->lineno, | ||||||
| 				sym->name ? sym->name : "<choice>", | 				sym->name ? sym->name : "<choice>", | ||||||
| 				next_sym->name ? next_sym->name : "<choice>"); | 				next_sym->name ? next_sym->name : "<choice>"); | ||||||
| 		} else { | 		} else if (stack->expr == &sym->dir_dep.expr) { | ||||||
|  | 			fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", | ||||||
|  | 				prop->file->name, prop->lineno, | ||||||
|  | 				sym->name ? sym->name : "<choice>", | ||||||
|  | 				next_sym->name ? next_sym->name : "<choice>"); | ||||||
|  | 		} else if (stack->expr == &sym->rev_dep.expr) { | ||||||
| 			fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", | 			fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", | ||||||
| 				prop->file->name, prop->lineno, | 				prop->file->name, prop->lineno, | ||||||
| 				sym->name ? sym->name : "<choice>", | 				sym->name ? sym->name : "<choice>", | ||||||
| 				next_sym->name ? next_sym->name : "<choice>"); | 				next_sym->name ? next_sym->name : "<choice>"); | ||||||
|  | 		} else if (stack->expr == &sym->implied.expr) { | ||||||
|  | 			fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", | ||||||
|  | 				prop->file->name, prop->lineno, | ||||||
|  | 				sym->name ? sym->name : "<choice>", | ||||||
|  | 				next_sym->name ? next_sym->name : "<choice>"); | ||||||
|  | 		} else if (stack->expr) { | ||||||
|  | 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", | ||||||
|  | 				prop->file->name, prop->lineno, | ||||||
|  | 				sym->name ? sym->name : "<choice>", | ||||||
|  | 				prop_get_type_name(prop->type), | ||||||
|  | 				next_sym->name ? next_sym->name : "<choice>"); | ||||||
|  | 		} else { | ||||||
|  | 			fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", | ||||||
|  | 				prop->file->name, prop->lineno, | ||||||
|  | 				sym->name ? sym->name : "<choice>", | ||||||
|  | 				prop_get_type_name(prop->type), | ||||||
|  | 				next_sym->name ? next_sym->name : "<choice>"); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	fprintf(stderr, | ||||||
|  | 		"For a resolution refer to Documentation/kbuild/kconfig-language.rst\n" | ||||||
|  | 		"subsection \"Kconfig recursive dependency limitations\"\n" | ||||||
|  | 		"\n"); | ||||||
|  |  | ||||||
| 	if (check_top == &cv_stack) | 	if (check_top == &cv_stack) | ||||||
| 		dep_stack_remove(); | 		dep_stack_remove(); | ||||||
| } | } | ||||||
| @@ -1177,6 +1143,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) | ||||||
| @@ -1187,7 +1157,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; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1200,12 +1170,26 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) | |||||||
|  |  | ||||||
| 	dep_stack_insert(&stack, sym); | 	dep_stack_insert(&stack, sym); | ||||||
|  |  | ||||||
|  | 	stack.expr = &sym->dir_dep.expr; | ||||||
|  | 	sym2 = sym_check_expr_deps(sym->dir_dep.expr); | ||||||
|  | 	if (sym2) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	stack.expr = &sym->rev_dep.expr; | ||||||
| 	sym2 = sym_check_expr_deps(sym->rev_dep.expr); | 	sym2 = sym_check_expr_deps(sym->rev_dep.expr); | ||||||
| 	if (sym2) | 	if (sym2) | ||||||
| 		goto out; | 		goto out; | ||||||
|  |  | ||||||
|  | 	stack.expr = &sym->implied.expr; | ||||||
|  | 	sym2 = sym_check_expr_deps(sym->implied.expr); | ||||||
|  | 	if (sym2) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	stack.expr = NULL; | ||||||
|  |  | ||||||
| 	for (prop = sym->prop; prop; prop = prop->next) { | 	for (prop = sym->prop; prop; prop = prop->next) { | ||||||
| 		if (prop->type == P_CHOICE || prop->type == P_SELECT) | 		if (prop->type == P_CHOICE || prop->type == P_SELECT || | ||||||
|  | 		    prop->type == P_IMPLY) | ||||||
| 			continue; | 			continue; | ||||||
| 		stack.prop = prop; | 		stack.prop = prop; | ||||||
| 		sym2 = sym_check_expr_deps(prop->visible.expr); | 		sym2 = sym_check_expr_deps(prop->visible.expr); | ||||||
| @@ -1213,7 +1197,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) | |||||||
| 			break; | 			break; | ||||||
| 		if (prop->type != P_DEFAULT || sym_is_choice(sym)) | 		if (prop->type != P_DEFAULT || sym_is_choice(sym)) | ||||||
| 			continue; | 			continue; | ||||||
| 		stack.expr = prop->expr; | 		stack.expr = &prop->expr; | ||||||
| 		sym2 = sym_check_expr_deps(prop->expr); | 		sym2 = sym_check_expr_deps(prop->expr); | ||||||
| 		if (sym2) | 		if (sym2) | ||||||
| 			break; | 			break; | ||||||
| @@ -1291,34 +1275,9 @@ struct symbol *sym_check_deps(struct symbol *sym) | |||||||
| 		sym->flags &= ~SYMBOL_CHECK; | 		sym->flags &= ~SYMBOL_CHECK; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (sym2 && sym2 == sym) |  | ||||||
| 		sym2 = NULL; |  | ||||||
|  |  | ||||||
| 	return sym2; | 	return sym2; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct property *prop_alloc(enum prop_type type, struct symbol *sym) |  | ||||||
| { |  | ||||||
| 	struct property *prop; |  | ||||||
| 	struct property **propp; |  | ||||||
|  |  | ||||||
| 	prop = xmalloc(sizeof(*prop)); |  | ||||||
| 	memset(prop, 0, sizeof(*prop)); |  | ||||||
| 	prop->type = type; |  | ||||||
| 	prop->sym = sym; |  | ||||||
| 	prop->file = current_file; |  | ||||||
| 	prop->lineno = zconf_lineno(); |  | ||||||
|  |  | ||||||
| 	/* append property to the prop list of symbol */ |  | ||||||
| 	if (sym) { |  | ||||||
| 		for (propp = &sym->prop; *propp; propp = &(*propp)->next) |  | ||||||
| 			; |  | ||||||
| 		*propp = prop; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return prop; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct symbol *prop_get_symbol(struct property *prop) | struct symbol *prop_get_symbol(struct property *prop) | ||||||
| { | { | ||||||
| 	if (prop->expr && (prop->expr->type == E_SYMBOL || | 	if (prop->expr && (prop->expr->type == E_SYMBOL || | ||||||
| @@ -1332,8 +1291,6 @@ const char *prop_get_type_name(enum prop_type type) | |||||||
| 	switch (type) { | 	switch (type) { | ||||||
| 	case P_PROMPT: | 	case P_PROMPT: | ||||||
| 		return "prompt"; | 		return "prompt"; | ||||||
| 	case P_ENV: |  | ||||||
| 		return "env"; |  | ||||||
| 	case P_COMMENT: | 	case P_COMMENT: | ||||||
| 		return "comment"; | 		return "comment"; | ||||||
| 	case P_MENU: | 	case P_MENU: | ||||||
| @@ -1344,6 +1301,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: | ||||||
| @@ -1353,32 +1312,3 @@ const char *prop_get_type_name(enum prop_type type) | |||||||
| 	} | 	} | ||||||
| 	return "unknown"; | 	return "unknown"; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void prop_add_env(const char *env) |  | ||||||
| { |  | ||||||
| 	struct symbol *sym, *sym2; |  | ||||||
| 	struct property *prop; |  | ||||||
| 	char *p; |  | ||||||
|  |  | ||||||
| 	sym = current_entry->sym; |  | ||||||
| 	sym->flags |= SYMBOL_AUTO; |  | ||||||
| 	for_all_properties(sym, prop, P_ENV) { |  | ||||||
| 		sym2 = prop_get_symbol(prop); |  | ||||||
| 		if (strcmp(sym2->name, env)) |  | ||||||
| 			menu_warn(current_entry, "redefining environment symbol from %s", |  | ||||||
| 				  sym2->name); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	prop = prop_alloc(P_ENV, sym); |  | ||||||
| 	prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); |  | ||||||
|  |  | ||||||
| 	sym_env_list = expr_alloc_one(E_LIST, sym_env_list); |  | ||||||
| 	sym_env_list->right.sym = sym; |  | ||||||
|  |  | ||||||
| 	p = getenv(env); |  | ||||||
| 	if (p) |  | ||||||
| 		sym_add_default(sym, p); |  | ||||||
| 	else |  | ||||||
| 		menu_warn(current_entry, "environment variable %s undefined", env); |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org> |  * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org> | ||||||
|  * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org> |  * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org> | ||||||
|  * |  | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| @@ -14,73 +13,21 @@ | |||||||
| 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); |  | ||||||
|  |  | ||||||
| 	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); |  | ||||||
| 			return file; | 			return file; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	file = xmalloc(sizeof(*file)); | 	file = xmalloc(sizeof(*file)); | ||||||
| 	memset(file, 0, sizeof(*file)); | 	memset(file, 0, sizeof(*file)); | ||||||
| 	file->name = file_name; | 	file->name = xstrdup(name); | ||||||
| 	file->next = file_list; | 	file->next = file_list; | ||||||
| 	file_list = file; | 	file_list = file; | ||||||
| 	return file; | 	return file; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* write a dependency file as used by kbuild to track dependencies */ |  | ||||||
| int file_write_dep(const char *name) |  | ||||||
| { |  | ||||||
| 	struct symbol *sym, *env_sym; |  | ||||||
| 	struct expr *e; |  | ||||||
| 	struct file *file; |  | ||||||
| 	FILE *out; |  | ||||||
| 	int i; |  | ||||||
|  |  | ||||||
| 	if (!name) |  | ||||||
| 		name = ".kconfig.d"; |  | ||||||
| 	char *config_tmp_name = strdup("..config.tmp.XXXXXX"); |  | ||||||
| 	if ((i = mkstemp(config_tmp_name)) == -1) |  | ||||||
| 		return 1; |  | ||||||
| 	out = fdopen(i, "w"); |  | ||||||
| 	if (!out) |  | ||||||
| 		return 1; |  | ||||||
| 	fprintf(out, "deps_config := \\\n"); |  | ||||||
| 	for (file = file_list; file; file = file->next) { |  | ||||||
| 		if (file->next) |  | ||||||
| 			fprintf(out, "\t%s \\\n", file->name); |  | ||||||
| 		else |  | ||||||
| 			fprintf(out, "\t%s\n", file->name); |  | ||||||
| 	} |  | ||||||
| 	fprintf(out, "\n%s: \\\n" |  | ||||||
| 		     "\t$(deps_config)\n\n", conf_get_autoconfig_name()); |  | ||||||
|  |  | ||||||
| 	expr_list_for_each_sym(sym_env_list, e, sym) { |  | ||||||
| 		struct property *prop; |  | ||||||
| 		const char *value; |  | ||||||
|  |  | ||||||
| 		prop = sym_get_env_prop(sym); |  | ||||||
| 		env_sym = prop_get_symbol(prop); |  | ||||||
| 		if (!env_sym) |  | ||||||
| 			continue; |  | ||||||
| 		value = getenv(env_sym->name); |  | ||||||
| 		if (!value) |  | ||||||
| 			value = ""; |  | ||||||
| 		fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value); |  | ||||||
| 		fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name()); |  | ||||||
| 		fprintf(out, "endif\n"); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	fprintf(out, "\n$(deps_config): ;\n"); |  | ||||||
| 	fclose(out); |  | ||||||
| 	rename(config_tmp_name, name); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* Allocate initial growable string */ | /* Allocate initial growable string */ | ||||||
| struct gstr str_new(void) | struct gstr str_new(void) | ||||||
| { | { | ||||||
| @@ -92,16 +39,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) | ||||||
| { | { | ||||||
| @@ -118,7 +55,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); | ||||||
| @@ -159,3 +96,34 @@ void *xcalloc(size_t nmemb, size_t size) | |||||||
| 	fprintf(stderr, "Out of memory.\n"); | 	fprintf(stderr, "Out of memory.\n"); | ||||||
| 	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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char *xstrndup(const char *s, size_t n) | ||||||
|  | { | ||||||
|  | 	char *p; | ||||||
|  |  | ||||||
|  | 	p = strndup(s, n); | ||||||
|  | 	if (p) | ||||||
|  | 		return p; | ||||||
|  | 	fprintf(stderr, "Out of memory.\n"); | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,48 +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 |  | ||||||
| allnoconfig_y,	T_OPT_ALLNOCONFIG_Y,TF_OPTION |  | ||||||
| %% |  | ||||||
| @@ -1,288 +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,  5, 25, 25, |  | ||||||
|        0,  0,  0,  5,  0,  0, 73, 73,  5,  0, |  | ||||||
|       10,  5, 45, 73, 20, 20,  0, 15, 15, 73, |  | ||||||
|       20,  5, 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_str28[sizeof("allnoconfig_y")]; |  | ||||||
|     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", |  | ||||||
|     "allnoconfig_y", |  | ||||||
|     "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 = 33, |  | ||||||
|       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}, |  | ||||||
| #line 47 "scripts/kconfig/zconf.gperf" |  | ||||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,	T_OPT_ALLNOCONFIG_Y,TF_OPTION}, |  | ||||||
| #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 48 "scripts/kconfig/zconf.gperf" |  | ||||||
| @@ -1,391 +0,0 @@ | |||||||
| %option nostdinit noyywrap never-interactive full ecs |  | ||||||
| %option 8bit nodefault perf-report perf-report |  | ||||||
| %option noinput |  | ||||||
| %x COMMAND HELP STRING PARAM |  | ||||||
| %{ |  | ||||||
| /* |  | ||||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> |  | ||||||
|  * Released under the terms of the GNU GPL v2.0. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <glob.h> |  | ||||||
| #include <limits.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> |  | ||||||
| #include <unistd.h> |  | ||||||
|  |  | ||||||
| #include "lkc.h" |  | ||||||
|  |  | ||||||
| #define START_STRSIZE	16 |  | ||||||
|  |  | ||||||
| static struct { |  | ||||||
| 	struct file *file; |  | ||||||
| 	int lineno; |  | ||||||
| } current_pos; |  | ||||||
|  |  | ||||||
| static char *text; |  | ||||||
| static int text_size, text_asize; |  | ||||||
|  |  | ||||||
| struct buffer { |  | ||||||
| 	struct buffer *parent; |  | ||||||
| 	YY_BUFFER_STATE state; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct buffer *current_buf; |  | ||||||
|  |  | ||||||
| static int last_ts, first_ts; |  | ||||||
|  |  | ||||||
| static void zconf_endhelp(void); |  | ||||||
| static void zconf_endfile(void); |  | ||||||
|  |  | ||||||
| static void new_string(void) |  | ||||||
| { |  | ||||||
| 	text = xmalloc(START_STRSIZE); |  | ||||||
| 	text_asize = START_STRSIZE; |  | ||||||
| 	text_size = 0; |  | ||||||
| 	*text = 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void append_string(const char *str, int size) |  | ||||||
| { |  | ||||||
| 	int new_size = text_size + size + 1; |  | ||||||
| 	if (new_size > text_asize) { |  | ||||||
| 		new_size += START_STRSIZE - 1; |  | ||||||
| 		new_size &= -START_STRSIZE; |  | ||||||
| 		text = realloc(text, new_size); |  | ||||||
| 		text_asize = new_size; |  | ||||||
| 	} |  | ||||||
| 	memcpy(text + text_size, str, size); |  | ||||||
| 	text_size += size; |  | ||||||
| 	text[text_size] = 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void alloc_string(const char *str, int size) |  | ||||||
| { |  | ||||||
| 	text = xmalloc(size + 1); |  | ||||||
| 	memcpy(text, str, size); |  | ||||||
| 	text[size] = 0; |  | ||||||
| } |  | ||||||
| %} |  | ||||||
|  |  | ||||||
| n	[A-Za-z0-9_] |  | ||||||
|  |  | ||||||
| %% |  | ||||||
| 	int str = 0; |  | ||||||
| 	int ts, i; |  | ||||||
|  |  | ||||||
| [ \t]*#.*\n	| |  | ||||||
| [ \t]*\n	{ |  | ||||||
| 	current_file->lineno++; |  | ||||||
| 	return T_EOL; |  | ||||||
| } |  | ||||||
| [ \t]*#.* |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [ \t]+	{ |  | ||||||
| 	BEGIN(COMMAND); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .	{ |  | ||||||
| 	unput(yytext[0]); |  | ||||||
| 	BEGIN(COMMAND); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| <COMMAND>{ |  | ||||||
| 	{n}+	{ |  | ||||||
| 		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); |  | ||||||
| 		BEGIN(PARAM); |  | ||||||
| 		current_pos.file = current_file; |  | ||||||
| 		current_pos.lineno = current_file->lineno; |  | ||||||
| 		if (id && id->flags & TF_COMMAND) { |  | ||||||
| 			zconflval.id = id; |  | ||||||
| 			return id->token; |  | ||||||
| 		} |  | ||||||
| 		alloc_string(yytext, yyleng); |  | ||||||
| 		zconflval.string = text; |  | ||||||
| 		return T_WORD; |  | ||||||
| 	} |  | ||||||
| 	. |  | ||||||
| 	\n	{ |  | ||||||
| 		BEGIN(INITIAL); |  | ||||||
| 		current_file->lineno++; |  | ||||||
| 		return T_EOL; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| <PARAM>{ |  | ||||||
| 	"&&"	return T_AND; |  | ||||||
| 	"||"	return T_OR; |  | ||||||
| 	"("	return T_OPEN_PAREN; |  | ||||||
| 	")"	return T_CLOSE_PAREN; |  | ||||||
| 	"!"	return T_NOT; |  | ||||||
| 	"="	return T_EQUAL; |  | ||||||
| 	"!="	return T_UNEQUAL; |  | ||||||
| 	\"|\'	{ |  | ||||||
| 		str = yytext[0]; |  | ||||||
| 		new_string(); |  | ||||||
| 		BEGIN(STRING); |  | ||||||
| 	} |  | ||||||
| 	\n	BEGIN(INITIAL); current_file->lineno++; return T_EOL; |  | ||||||
| 	---	/* ignore */ |  | ||||||
| 	({n}|[-/.])+	{ |  | ||||||
| 		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); |  | ||||||
| 		if (id && id->flags & TF_PARAM) { |  | ||||||
| 			zconflval.id = id; |  | ||||||
| 			return id->token; |  | ||||||
| 		} |  | ||||||
| 		alloc_string(yytext, yyleng); |  | ||||||
| 		zconflval.string = text; |  | ||||||
| 		return T_WORD; |  | ||||||
| 	} |  | ||||||
| 	#.*	/* comment */ |  | ||||||
| 	\\\n	current_file->lineno++; |  | ||||||
| 	. |  | ||||||
| 	<<EOF>> { |  | ||||||
| 		BEGIN(INITIAL); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| <STRING>{ |  | ||||||
| 	[^'"\\\n]+/\n	{ |  | ||||||
| 		append_string(yytext, yyleng); |  | ||||||
| 		zconflval.string = text; |  | ||||||
| 		return T_WORD_QUOTE; |  | ||||||
| 	} |  | ||||||
| 	[^'"\\\n]+	{ |  | ||||||
| 		append_string(yytext, yyleng); |  | ||||||
| 	} |  | ||||||
| 	\\.?/\n	{ |  | ||||||
| 		append_string(yytext + 1, yyleng - 1); |  | ||||||
| 		zconflval.string = text; |  | ||||||
| 		return T_WORD_QUOTE; |  | ||||||
| 	} |  | ||||||
| 	\\.?	{ |  | ||||||
| 		append_string(yytext + 1, yyleng - 1); |  | ||||||
| 	} |  | ||||||
| 	\'|\"	{ |  | ||||||
| 		if (str == yytext[0]) { |  | ||||||
| 			BEGIN(PARAM); |  | ||||||
| 			zconflval.string = text; |  | ||||||
| 			return T_WORD_QUOTE; |  | ||||||
| 		} else |  | ||||||
| 			append_string(yytext, 1); |  | ||||||
| 	} |  | ||||||
| 	\n	{ |  | ||||||
| 		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); |  | ||||||
| 		current_file->lineno++; |  | ||||||
| 		BEGIN(INITIAL); |  | ||||||
| 		return T_EOL; |  | ||||||
| 	} |  | ||||||
| 	<<EOF>>	{ |  | ||||||
| 		BEGIN(INITIAL); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| <HELP>{ |  | ||||||
| 	[ \t]+	{ |  | ||||||
| 		ts = 0; |  | ||||||
| 		for (i = 0; i < yyleng; i++) { |  | ||||||
| 			if (yytext[i] == '\t') |  | ||||||
| 				ts = (ts & ~7) + 8; |  | ||||||
| 			else |  | ||||||
| 				ts++; |  | ||||||
| 		} |  | ||||||
| 		last_ts = ts; |  | ||||||
| 		if (first_ts) { |  | ||||||
| 			if (ts < first_ts) { |  | ||||||
| 				zconf_endhelp(); |  | ||||||
| 				return T_HELPTEXT; |  | ||||||
| 			} |  | ||||||
| 			ts -= first_ts; |  | ||||||
| 			while (ts > 8) { |  | ||||||
| 				append_string("        ", 8); |  | ||||||
| 				ts -= 8; |  | ||||||
| 			} |  | ||||||
| 			append_string("        ", ts); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	[ \t]*\n/[^ \t\n] { |  | ||||||
| 		current_file->lineno++; |  | ||||||
| 		zconf_endhelp(); |  | ||||||
| 		return T_HELPTEXT; |  | ||||||
| 	} |  | ||||||
| 	[ \t]*\n	{ |  | ||||||
| 		current_file->lineno++; |  | ||||||
| 		append_string("\n", 1); |  | ||||||
| 	} |  | ||||||
| 	[^ \t\n].* { |  | ||||||
| 		while (yyleng) { |  | ||||||
| 			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) |  | ||||||
| 				break; |  | ||||||
| 			yyleng--; |  | ||||||
| 		} |  | ||||||
| 		append_string(yytext, yyleng); |  | ||||||
| 		if (!first_ts) |  | ||||||
| 			first_ts = last_ts; |  | ||||||
| 	} |  | ||||||
| 	<<EOF>>	{ |  | ||||||
| 		zconf_endhelp(); |  | ||||||
| 		return T_HELPTEXT; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| <<EOF>>	{ |  | ||||||
| 	if (current_file) { |  | ||||||
| 		zconf_endfile(); |  | ||||||
| 		return T_EOL; |  | ||||||
| 	} |  | ||||||
| 	fclose(yyin); |  | ||||||
| 	yyterminate(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| %% |  | ||||||
| void zconf_starthelp(void) |  | ||||||
| { |  | ||||||
| 	new_string(); |  | ||||||
| 	last_ts = first_ts = 0; |  | ||||||
| 	BEGIN(HELP); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void zconf_endhelp(void) |  | ||||||
| { |  | ||||||
| 	zconflval.string = text; |  | ||||||
| 	BEGIN(INITIAL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Try to open specified file with following names: |  | ||||||
|  * ./name |  | ||||||
|  * $(srctree)/name |  | ||||||
|  * The latter is used when srctree is separate from objtree |  | ||||||
|  * when compiling the kernel. |  | ||||||
|  * Return NULL if file is not found. |  | ||||||
|  */ |  | ||||||
| FILE *zconf_fopen(const char *name) |  | ||||||
| { |  | ||||||
| 	char *env, fullname[PATH_MAX+1]; |  | ||||||
| 	FILE *f; |  | ||||||
|  |  | ||||||
| 	f = fopen(name, "r"); |  | ||||||
| 	if (!f && name != NULL && name[0] != '/') { |  | ||||||
| 		env = getenv(SRCTREE); |  | ||||||
| 		if (env) { |  | ||||||
| 			snprintf(fullname, sizeof(fullname), |  | ||||||
| 					"%s/%s", env, name); |  | ||||||
| 			f = fopen(fullname, "r"); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return f; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void zconf_initscan(const char *name) |  | ||||||
| { |  | ||||||
| 	yyin = zconf_fopen(name); |  | ||||||
| 	if (!yyin) { |  | ||||||
| 		printf("can't find file %s\n", name); |  | ||||||
| 		exit(1); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	current_buf = xmalloc(sizeof(*current_buf)); |  | ||||||
| 	memset(current_buf, 0, sizeof(*current_buf)); |  | ||||||
|  |  | ||||||
| 	current_file = file_lookup(name); |  | ||||||
| 	current_file->lineno = 1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void zconf_nextfile(const char *name) |  | ||||||
| { |  | ||||||
| 	struct file *iter; |  | ||||||
| 	struct file *file = file_lookup(name); |  | ||||||
| 	struct buffer *buf = xmalloc(sizeof(*buf)); |  | ||||||
| 	memset(buf, 0, sizeof(*buf)); |  | ||||||
|  |  | ||||||
| 	current_buf->state = YY_CURRENT_BUFFER; |  | ||||||
| 	yyin = zconf_fopen(file->name); |  | ||||||
| 	if (!yyin) { |  | ||||||
| 		printf("%s:%d: can't open file \"%s\"\n", |  | ||||||
| 		    zconf_curname(), zconf_lineno(), file->name); |  | ||||||
| 		exit(1); |  | ||||||
| 	} |  | ||||||
| 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); |  | ||||||
| 	buf->parent = current_buf; |  | ||||||
| 	current_buf = buf; |  | ||||||
|  |  | ||||||
| 	for (iter = current_file->parent; iter; iter = iter->parent ) { |  | ||||||
| 		if (!strcmp(current_file->name,iter->name) ) { |  | ||||||
| 			printf("%s:%d: recursive inclusion detected. " |  | ||||||
| 			       "Inclusion path:\n  current file : '%s'\n", |  | ||||||
| 			       zconf_curname(), zconf_lineno(), |  | ||||||
| 			       zconf_curname()); |  | ||||||
| 			iter = current_file->parent; |  | ||||||
| 			while (iter && \ |  | ||||||
| 			       strcmp(iter->name,current_file->name)) { |  | ||||||
| 				printf("  included from: '%s:%d'\n", |  | ||||||
| 				       iter->name, iter->lineno-1); |  | ||||||
| 				iter = iter->parent; |  | ||||||
| 			} |  | ||||||
| 			if (iter) |  | ||||||
| 				printf("  included from: '%s:%d'\n", |  | ||||||
| 				       iter->name, iter->lineno+1); |  | ||||||
| 			exit(1); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	file->lineno = 1; |  | ||||||
| 	file->parent = current_file; |  | ||||||
| 	current_file = file; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void zconf_nextfiles(const char *wildcard) |  | ||||||
| { |  | ||||||
| 	glob_t g = {0}; |  | ||||||
| 	char **w; |  | ||||||
| 	int i; |  | ||||||
|  |  | ||||||
| 	if (glob(wildcard, 0, NULL, &g) != 0) { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 	if (g.gl_pathv == NULL) { |  | ||||||
| 		globfree(&g); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* working through files backwards, since |  | ||||||
| 	 * we're first pushing them on a stack |  | ||||||
| 	 * before actually handling them. |  | ||||||
| 	 */ |  | ||||||
| 	for (i = g.gl_pathc; i > 0; i--) { |  | ||||||
| 		w = &g.gl_pathv[i - 1]; |  | ||||||
| 		zconf_nextfile(*w); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	globfree(&g); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void zconf_endfile(void) |  | ||||||
| { |  | ||||||
| 	struct buffer *parent; |  | ||||||
|  |  | ||||||
| 	current_file = current_file->parent; |  | ||||||
|  |  | ||||||
| 	parent = current_buf->parent; |  | ||||||
| 	if (parent) { |  | ||||||
| 		fclose(yyin); |  | ||||||
| 		yy_delete_buffer(YY_CURRENT_BUFFER); |  | ||||||
| 		yy_switch_to_buffer(parent->state); |  | ||||||
| 	} |  | ||||||
| 	free(current_buf); |  | ||||||
| 	current_buf = parent; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int zconf_lineno(void) |  | ||||||
| { |  | ||||||
| 	return current_pos.lineno; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const char *zconf_curname(void) |  | ||||||
| { |  | ||||||
| 	return current_pos.file ? current_pos.file->name : "<none>"; |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user