mirror of
				https://github.com/optim-enterprises-bv/openwrt-ipq.git
				synced 2025-10-31 18:28:28 +00:00 
			
		
		
		
	build: scripts/config - update to kconfig-v5.6
Major changes include: - Much more readable reverse dependencies separated in groups - Improved recursive dependency report - More readable .config files: add comments to signal end of menus - More warnings for incorrect Config.in entries, such as a 'choice' default not contained in the 'choice' - Hability to properly display pseudographics with non-latin locales - Recursive dependencies are now treated as errors - this should make it harder for them to creep in. Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
This commit is contained in:
		 Eneas U de Queiroz
					Eneas U de Queiroz
				
			
				
					committed by
					
						 Petr Štetiar
						Petr Štetiar
					
				
			
			
				
	
			
			
			 Petr Štetiar
						Petr Štetiar
					
				
			
						parent
						
							8636a17214
						
					
				
				
					commit
					dcf3e63a35
				
			
							
								
								
									
										29
									
								
								scripts/config/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								scripts/config/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,15 +1,14 @@ | ||||
| *.o | ||||
| conf* | ||||
| !conf*.c | ||||
| !conf*.h | ||||
| mconf* | ||||
| !mconf*.c | ||||
| !mconf*.h | ||||
| mconf_check | ||||
| *.*.c | ||||
| qconf* | ||||
| qconf*.moc | ||||
| !qconf*.cc | ||||
| !qconf*.h | ||||
| !images*.c | ||||
| .tmp_qtcheck | ||||
| # | ||||
| # Generated files | ||||
| # | ||||
| *.moc | ||||
| *conf-cfg | ||||
|  | ||||
| # | ||||
| # configuration programs | ||||
| # | ||||
| conf | ||||
| mconf | ||||
| nconf | ||||
| qconf | ||||
| gconf | ||||
|   | ||||
| @@ -1,102 +1,124 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0 | ||||
| # =========================================================================== | ||||
| # OpenWrt configuration targets | ||||
| # These targets are used from top-level makefile | ||||
|  | ||||
| .PHONY: clean all | ||||
| all: conf mconf | ||||
| clean: | ||||
| 	rm -f *.o lxdialog/*.o *.moc $(clean-files) conf mconf qconf | ||||
|  | ||||
| clean-files	:= | ||||
|  | ||||
| # =========================================================================== | ||||
| # Shared Makefile for the various kconfig executables: | ||||
| # conf:	  Used for defconfig, oldconfig and related targets | ||||
| # mconf:  Used for the mconfig target. | ||||
| #         Utilizes the lxdialog package | ||||
| # qconf:  Used for the xconfig target | ||||
| #         Based on Qt which needs to be installed to compile it | ||||
| # Variables needed by the upstream Makefile | ||||
|  | ||||
| # Avoids displaying 'UPD mconf-cfg' in an otherwise quiet make menuconfig | ||||
| kecho:=true | ||||
|  | ||||
| CONFIG_SHELL:=$(SHELL) | ||||
| srctree:=. | ||||
| src:=. | ||||
| obj:=. | ||||
| Q:=$(if $V,,@) | ||||
| cmd = $(cmd_$(1)) | ||||
| dot-target = $(dir $@).$(notdir $@) | ||||
|  | ||||
| # taken from ../Kbuild.include | ||||
| define filechk | ||||
| 	$(Q)set -e;						\ | ||||
| 	mkdir -p $(dir $@);					\ | ||||
| 	trap "rm -f $(dot-target).tmp" EXIT;			\ | ||||
| 	{ $(filechk_$(1)); } > $(dot-target).tmp;		\ | ||||
| 	if [ ! -r $@ ] || ! cmp -s $@ $(dot-target).tmp; then	\ | ||||
| 		$(kecho) '  UPD     $@';			\ | ||||
| 		mv -f $(dot-target).tmp $@;			\ | ||||
| 	fi | ||||
| endef | ||||
|  | ||||
| ### Stripped down upstream Makefile follows: | ||||
| # =========================================================================== | ||||
| # object files used by all kconfig flavours | ||||
| common-objs	:= confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \ | ||||
| 		   symbol.o util.o | ||||
|  | ||||
| $(obj)/lexer.lex.o: $(obj)/parser.tab.h | ||||
| HOSTCFLAGS_lexer.lex.o	:= -I $(srctree)/$(src) | ||||
| HOSTCFLAGS_parser.tab.o	:= -I $(srctree)/$(src) | ||||
|  | ||||
| # Platform specific fixes | ||||
| # | ||||
| # FreeBSD | ||||
| # conf: Used for defconfig, oldconfig and related targets | ||||
| hostprogs-y	+= conf | ||||
| conf-objs	:= conf.o $(common-objs) | ||||
|  | ||||
| check_lxdialog = $(shell $(SHELL) $(CURDIR)/lxdialog/check-lxdialog.sh -$(1)) | ||||
| export CFLAGS += -DKBUILD_NO_NLS -I. $(call check_lxdialog,ccflags) | ||||
| export CXXFLAGS += -DKBUILD_NO_NLS | ||||
| # mconf: Used for the menuconfig target based on lxdialog | ||||
| hostprogs-y	+= mconf | ||||
| lxdialog	:= $(addprefix lxdialog/, \ | ||||
| 		     checklist.o inputbox.o menubox.o textbox.o util.o yesno.o) | ||||
| mconf-objs	:= mconf.o $(lxdialog) $(common-objs) | ||||
|  | ||||
| conf-objs	:= conf.o zconf.tab.o | ||||
| mconf-objs	:= mconf.o zconf.tab.o | ||||
| HOSTLDLIBS_mconf = $(shell . $(obj)/mconf-cfg && echo $$libs) | ||||
| $(foreach f, mconf.o $(lxdialog), \ | ||||
|   $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/mconf-cfg && echo $$$$cflags))) | ||||
|  | ||||
| $(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg | ||||
|  | ||||
| # qconf: Used for the xconfig target based on Qt | ||||
| hostprogs-y	+= qconf | ||||
| qconf-cxxobjs	:= qconf.o | ||||
| qconf-objs	:= zconf.tab.o | ||||
| qconf-objs	:= images.o $(common-objs) | ||||
|  | ||||
| lxdialog-objs := \ | ||||
| 	lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o \ | ||||
| 	lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o | ||||
| HOSTLDLIBS_qconf	= $(shell . $(obj)/qconf-cfg && echo $$libs) | ||||
| HOSTCXXFLAGS_qconf.o	= $(shell . $(obj)/qconf-cfg && echo $$cflags) | ||||
|  | ||||
| clean-files	:= zconf.tab.c zconf.lex.c zconf.hash.c | ||||
| # Remove qconf junk files | ||||
| clean-files	+= $(qconf-cxxobjs) qconf.moc .tmp_qtcheck qconf | ||||
| $(obj)/qconf.o: $(obj)/qconf-cfg $(obj)/qconf.moc | ||||
|  | ||||
| all: conf mconf | ||||
| quiet_cmd_moc = MOC     $@ | ||||
|       cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) -i $< -o $@ | ||||
|  | ||||
| conf: $(conf-objs) | ||||
| mconf: $(mconf-objs) $(lxdialog-objs) | ||||
| 	$(CC) -o $@ $^ $(call check_lxdialog,ldflags $(CC)) | ||||
| qconf: $(qconf-cxxobjs) $(qconf-objs) | ||||
| 	$(CXX) -o $@ $^ $(HOSTLOADLIBES_qconf) | ||||
| $(obj)/%.moc: $(src)/%.h $(obj)/qconf-cfg | ||||
| 	$(call cmd,moc) | ||||
|  | ||||
| clean: | ||||
| 	rm -f *.o lxdialog/*.o $(clean-files) conf mconf | ||||
| # check if necessary packages are available, and configure build flags | ||||
| filechk_conf_cfg = $(CONFIG_SHELL) $< | ||||
|  | ||||
| zconf.tab.o: zconf.lex.c zconf.hash.c confdata.c | ||||
| $(obj)/%conf-cfg: $(src)/%conf-cfg.sh FORCE | ||||
| 	$(call filechk,conf_cfg) | ||||
|  | ||||
| kconfig_load.o: lkc_defs.h | ||||
| clean-files += *conf-cfg | ||||
|  | ||||
| zconf.tab.c: zconf.y $(wildcard zconf.tab.c_shipped) | ||||
| zconf.lex.c: zconf.l $(wildcard zconf.lex.c_shipped) | ||||
| zconf.hash.c: zconf.gperf $(wildcard zconf.hash.c_shipped) | ||||
| # =========================================================================== | ||||
| # OpenWrt rules and final adjustments that need to be made after reading the | ||||
| # full upstream Makefile | ||||
|  | ||||
| %.tab.c: %.y | ||||
| 	cp $@_shipped $@ || bison -l -b $* -p $(notdir $*) $< | ||||
| FORCE: | ||||
|  | ||||
| ifdef BUILD_SHIPPED_FILES | ||||
| shipped-files := lexer.lex.c parser.tab.c parser.tab.h | ||||
| clean-files += $(shipped-files) | ||||
|  | ||||
| .SECONDARY: $(shipped-files) | ||||
|  | ||||
| %.tab.c %.tab.h: %.y | ||||
| 	bison -l -d -b $* $< | ||||
|  | ||||
| %.lex.c: %.l | ||||
| 	cp $@_shipped $@ || flex -L -P$(notdir $*) -o$@ $< | ||||
|  | ||||
| %.hash.c: %.gperf | ||||
| 	cp $@_shipped $@ || gperf < $< > $@ | ||||
|  | ||||
| ifeq ($(MAKECMDGOALS),qconf) | ||||
| qconf.o: .tmp_qtcheck | ||||
| .tmp_qtcheck: Makefile | ||||
| -include .tmp_qtcheck | ||||
|  | ||||
| # Qt needs some extra effort... | ||||
| .tmp_qtcheck: | ||||
| 	@set -e; echo "  CHECK   qt"; \ | ||||
| 	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" >> $@ | ||||
| 	flex -L -o$@ $< | ||||
| endif | ||||
|  | ||||
| #Define compiler flags to build qconf | ||||
| HOSTLOADLIBES_qconf	= $(KC_QT_LIBS) | ||||
| HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS) | ||||
| $(foreach f, mconf.o $(lxdialog), \ | ||||
|   $(eval $f: CFLAGS+=$$(HOSTCFLAGS_$f))) | ||||
|  | ||||
| qconf.o: qconf.moc | ||||
| qconf.o: CXXFLAGS+=$(HOSTCXXFLAGS_qconf.o) | ||||
| $(obj)/lexer.lex.o: CFLAGS += $(HOSTCFLAGS_lexer.lex.o) | ||||
| $(obj)/parser.tab.o: CFLAGS += $(HOSTCFLAGS_parser.tab.o) | ||||
| $(obj)/qconf.o: CXXFLAGS+=$(HOSTCXXFLAGS_qconf.o) | ||||
|  | ||||
| moc = $(KC_QT_MOC) -i $< -o $@ | ||||
| conf: $(conf-objs) | ||||
|  | ||||
| %.moc: %.h .tmp_qtcheck | ||||
| 	$(call moc) | ||||
| # The *conf-cfg file is used (then filtered out) as the first prerequisite to | ||||
| # avoid sourcing it before the script is built, when trying to compute CFLAGS | ||||
| # for the actual first prerequisite.  This avoids errors like: | ||||
| # '/bin/sh: ./mconf-cfg: No such file or directory' | ||||
| mconf: mconf-cfg $(mconf-objs) | ||||
| 	$(CC) -o $@ $(filter-out mconf-cfg,$^) $(HOSTLDLIBS_mconf) | ||||
|  | ||||
| qconf: qconf-cfg $(qconf-cxxobjs) $(qconf-objs) | ||||
| 	$(CXX) -o $@ $(filter-out qconf-cfg,$^) $(HOSTLDLIBS_qconf) | ||||
|   | ||||
| @@ -1,2 +1,24 @@ | ||||
| These files were taken from the Linux 3.9 Kernel | ||||
| Configuration System and modified for the OpenWrt Buildroot. | ||||
| These files were taken from the Linux Kernel Configuration System at commit | ||||
| 089b7d890f972f6b649fedc9259f6b93a18fb970 (Feb 4, 2020) and modified for the | ||||
| OpenWrt Buildroot: | ||||
|  - removed nconf, gconf, tests and kernel configuration targets | ||||
|  - adjusted the Makefile to compile outside the kernel | ||||
|  - always use default file when running make all{no,mod,yes}config | ||||
|  - added a 'reset' command to reset config when the target changes | ||||
|  - allow config reading from & writing to a different file | ||||
|  - allow 'source' command to use globs to include multiple files | ||||
|  - don't write auto.conf and other files under include/ directory | ||||
|  - reverted a commit to allow use of '/' & '.' in unquoted config symbols. | ||||
|    There are too many of those in OpenWrt right now. | ||||
|  - reverted a commit that was issuing a warning when there were more than | ||||
|    one help text.  This is used in a few packages to use different texts | ||||
|    for the menuconfig help, and the ipkg package description. | ||||
|  - reverted an upstream change that avoids writing symbols that are not | ||||
|    visible to .config, which breaks OpenWrt busybox's '.config' generation | ||||
|    logic. | ||||
|  - use pre-built *.lex.c *.tab.[ch] files by default, to avoid depending on | ||||
|    flex & bison.  Rebuild/remove these files only if running make with | ||||
|    BUILD_SHIPPED_FILES defined | ||||
|  | ||||
| For a full list of changes, see the repository at: | ||||
| https://github.com/cotequeiroz/linux/commits/openwrt/scripts/kconfig | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * 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 <limits.h> | ||||
| #include <stdio.h> | ||||
| @@ -20,11 +19,10 @@ | ||||
|  | ||||
| static void conf(struct menu *menu); | ||||
| static void check_conf(struct menu *menu); | ||||
| static void xfgets(char *str, int size, FILE *in); | ||||
|  | ||||
| enum input_mode { | ||||
| 	oldaskconfig, | ||||
| 	silentoldconfig, | ||||
| 	syncconfig, | ||||
| 	oldconfig, | ||||
| 	allnoconfig, | ||||
| 	allyesconfig, | ||||
| @@ -34,12 +32,15 @@ enum input_mode { | ||||
| 	defconfig, | ||||
| 	savedefconfig, | ||||
| 	listnewconfig, | ||||
| 	helpnewconfig, | ||||
| 	olddefconfig, | ||||
| } input_mode = oldaskconfig; | ||||
| 	yes2modconfig, | ||||
| 	mod2yesconfig, | ||||
| }; | ||||
| static enum input_mode input_mode = oldaskconfig; | ||||
|  | ||||
| static int indent = 1; | ||||
| static int tty_stdio; | ||||
| static int valid_stdin = 1; | ||||
| static int sync_kconfig; | ||||
| static int conf_cnt; | ||||
| static char line[PATH_MAX]; | ||||
| @@ -72,14 +73,14 @@ static void strip(char *str) | ||||
| 		*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) { | ||||
| 	        printf("%s",_("aborted!\n\n")); | ||||
| 		printf("%s",_("Console input/output is redirected. ")); | ||||
| 		printf("%s",_("Run 'make oldconfig' to update configuration.\n\n")); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	if (!fgets(str, size, in)) | ||||
| 		fprintf(stderr, "\nError in reading or end of file.\n"); | ||||
|  | ||||
| 	if (!tty_stdio) | ||||
| 		printf("%s", str); | ||||
| } | ||||
|  | ||||
| static int conf_askvalue(struct symbol *sym, const char *def) | ||||
| @@ -87,12 +88,12 @@ static int conf_askvalue(struct symbol *sym, const char *def) | ||||
| 	enum symbol_type type = sym_get_type(sym); | ||||
|  | ||||
| 	if (!sym_has_value(sym)) | ||||
| 	        printf("%s",_("(NEW) ")); | ||||
| 		printf("(NEW) "); | ||||
|  | ||||
| 	line[0] = '\n'; | ||||
| 	line[1] = 0; | ||||
|  | ||||
| 	if (!sym_is_changable(sym)) { | ||||
| 	if (!sym_is_changeable(sym)) { | ||||
| 		printf("%s\n", def); | ||||
| 		line[0] = '\n'; | ||||
| 		line[1] = 0; | ||||
| @@ -101,18 +102,15 @@ static int conf_askvalue(struct symbol *sym, const char *def) | ||||
|  | ||||
| 	switch (input_mode) { | ||||
| 	case oldconfig: | ||||
| 	case silentoldconfig: | ||||
| 	case syncconfig: | ||||
| 		if (sym_has_value(sym)) { | ||||
| 			printf("%s\n", def); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		check_stdin(); | ||||
| 		/* fall through */ | ||||
| 	case oldaskconfig: | ||||
| 		fflush(stdout); | ||||
| 		xfgets(line, sizeof(line), stdin); | ||||
| 		if (!tty_stdio) | ||||
| 			printf("\n"); | ||||
| 		return 1; | ||||
| 	default: | ||||
| 		break; | ||||
| @@ -137,7 +135,7 @@ static int conf_string(struct menu *menu) | ||||
| 	const char *def; | ||||
|  | ||||
| 	while (1) { | ||||
| 		printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); | ||||
| 		printf("%*s%s ", indent - 1, "", menu->prompt->text); | ||||
| 		printf("(%s) ", sym->name); | ||||
| 		def = sym_get_string_value(sym); | ||||
| 		if (sym_get_string_value(sym)) | ||||
| @@ -170,7 +168,7 @@ static int conf_sym(struct menu *menu) | ||||
| 	tristate oldval, newval; | ||||
|  | ||||
| 	while (1) { | ||||
| 		printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); | ||||
| 		printf("%*s%s ", indent - 1, "", menu->prompt->text); | ||||
| 		if (sym->name) | ||||
| 			printf("(%s) ", sym->name); | ||||
| 		putchar('['); | ||||
| @@ -192,9 +190,7 @@ static int conf_sym(struct menu *menu) | ||||
| 			printf("/m"); | ||||
| 		if (oldval != yes && sym_tristate_within_range(sym, yes)) | ||||
| 			printf("/y"); | ||||
| 		if (menu_has_help(menu)) | ||||
| 			printf("/?"); | ||||
| 		printf("] "); | ||||
| 		printf("/?] "); | ||||
| 		if (!conf_askvalue(sym, sym_get_string_value(sym))) | ||||
| 			return 0; | ||||
| 		strip(line); | ||||
| @@ -241,7 +237,7 @@ static int conf_choice(struct menu *menu) | ||||
|  | ||||
| 	sym = menu->sym; | ||||
| 	is_new = !sym_has_value(sym); | ||||
| 	if (sym_is_changable(sym)) { | ||||
| 	if (sym_is_changeable(sym)) { | ||||
| 		conf_sym(menu); | ||||
| 		sym_calc_value(sym); | ||||
| 		switch (sym_get_tristate_value(sym)) { | ||||
| @@ -257,7 +253,7 @@ static int conf_choice(struct menu *menu) | ||||
| 		case no: | ||||
| 			return 1; | ||||
| 		case mod: | ||||
| 			printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); | ||||
| 			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); | ||||
| 			return 0; | ||||
| 		case yes: | ||||
| 			break; | ||||
| @@ -267,7 +263,7 @@ static int conf_choice(struct menu *menu) | ||||
| 	while (1) { | ||||
| 		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); | ||||
| 		cnt = def = 0; | ||||
| 		line[0] = 0; | ||||
| @@ -275,7 +271,7 @@ static int conf_choice(struct menu *menu) | ||||
| 			if (!menu_is_visible(child)) | ||||
| 				continue; | ||||
| 			if (!child->sym) { | ||||
| 				printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); | ||||
| 				printf("%*c %s\n", indent, '*', menu_get_prompt(child)); | ||||
| 				continue; | ||||
| 			} | ||||
| 			cnt++; | ||||
| @@ -284,31 +280,27 @@ static int conf_choice(struct menu *menu) | ||||
| 				printf("%*c", indent, '>'); | ||||
| 			} else | ||||
| 				printf("%*c", indent, ' '); | ||||
| 			printf(" %d. %s", cnt, _(menu_get_prompt(child))); | ||||
| 			printf(" %d. %s", cnt, menu_get_prompt(child)); | ||||
| 			if (child->sym->name) | ||||
| 				printf(" (%s)", child->sym->name); | ||||
| 			if (!sym_has_value(child->sym)) | ||||
| 			        printf("%s",_(" (NEW)")); | ||||
| 				printf(" (NEW)"); | ||||
| 			printf("\n"); | ||||
| 		} | ||||
| 		printf(_("%*schoice"), indent - 1, ""); | ||||
| 		printf("%*schoice", indent - 1, ""); | ||||
| 		if (cnt == 1) { | ||||
| 			printf("[1]: 1\n"); | ||||
| 			goto conf_childs; | ||||
| 		} | ||||
| 		printf("[1-%d", cnt); | ||||
| 		if (menu_has_help(menu)) | ||||
| 			printf("?"); | ||||
| 		printf("]: "); | ||||
| 		printf("[1-%d?]: ", cnt); | ||||
| 		switch (input_mode) { | ||||
| 		case oldconfig: | ||||
| 		case silentoldconfig: | ||||
| 		case syncconfig: | ||||
| 			if (!is_new) { | ||||
| 				cnt = def; | ||||
| 				printf("%d\n", cnt); | ||||
| 				break; | ||||
| 			} | ||||
| 			check_stdin(); | ||||
| 			/* fall through */ | ||||
| 		case oldaskconfig: | ||||
| 			fflush(stdout); | ||||
| @@ -368,10 +360,11 @@ static void conf(struct menu *menu) | ||||
|  | ||||
| 		switch (prop->type) { | ||||
| 		case P_MENU: | ||||
| 			if ((input_mode == silentoldconfig || | ||||
| 			     input_mode == listnewconfig || | ||||
| 			     input_mode == olddefconfig) && | ||||
| 			    rootEntry != menu) { | ||||
| 			/* | ||||
| 			 * Except in oldaskconfig mode, we show only menus that | ||||
| 			 * contain new symbols. | ||||
| 			 */ | ||||
| 			if (input_mode != oldaskconfig && rootEntry != menu) { | ||||
| 				check_conf(menu); | ||||
| 				return; | ||||
| 			} | ||||
| @@ -381,7 +374,7 @@ static void conf(struct menu *menu) | ||||
| 			if (prompt) | ||||
| 				printf("%*c\n%*c %s\n%*c\n", | ||||
| 					indent, '*', | ||||
| 					indent, '*', _(prompt), | ||||
| 					indent, '*', prompt, | ||||
| 					indent, '*'); | ||||
| 		default: | ||||
| 			; | ||||
| @@ -428,15 +421,30 @@ static void check_conf(struct menu *menu) | ||||
|  | ||||
| 	sym = menu->sym; | ||||
| 	if (sym && !sym_has_value(sym)) { | ||||
| 		if (sym_is_changable(sym) || | ||||
| 		if (sym_is_changeable(sym) || | ||||
| 		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { | ||||
| 			if (input_mode == listnewconfig) { | ||||
| 				if (sym->name && !sym_is_choice_value(sym)) { | ||||
| 					printf("%s%s\n", CONFIG_, sym->name); | ||||
| 				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) { | ||||
| 				} | ||||
| 			} else if (input_mode == helpnewconfig) { | ||||
| 				printf("-----\n"); | ||||
| 				print_help(menu); | ||||
| 				printf("-----\n"); | ||||
|  | ||||
| 			} else { | ||||
| 				if (!conf_cnt++) | ||||
| 				        printf("%s",_("*\n* Restart config...\n*\n")); | ||||
| 					printf("*\n* Restart config...\n*\n"); | ||||
| 				rootEntry = menu_get_parent_menu(menu); | ||||
| 				conf(rootEntry); | ||||
| 			} | ||||
| @@ -450,8 +458,8 @@ static void check_conf(struct menu *menu) | ||||
| static struct option long_opts[] = { | ||||
| 	{"oldaskconfig",    no_argument,       NULL, oldaskconfig}, | ||||
| 	{"oldconfig",       no_argument,       NULL, oldconfig}, | ||||
| 	{"silentoldconfig", no_argument,       NULL, silentoldconfig}, | ||||
| 	{"defconfig",       optional_argument, NULL, defconfig}, | ||||
| 	{"syncconfig",      no_argument,       NULL, syncconfig}, | ||||
| 	{"defconfig",       required_argument, NULL, defconfig}, | ||||
| 	{"savedefconfig",   required_argument, NULL, savedefconfig}, | ||||
| 	{"allnoconfig",     no_argument,       NULL, allnoconfig}, | ||||
| 	{"allyesconfig",    no_argument,       NULL, allyesconfig}, | ||||
| @@ -459,13 +467,10 @@ static struct option long_opts[] = { | ||||
| 	{"alldefconfig",    no_argument,       NULL, alldefconfig}, | ||||
| 	{"randconfig",      no_argument,       NULL, randconfig}, | ||||
| 	{"listnewconfig",   no_argument,       NULL, listnewconfig}, | ||||
| 	{"helpnewconfig",   no_argument,       NULL, helpnewconfig}, | ||||
| 	{"olddefconfig",    no_argument,       NULL, olddefconfig}, | ||||
| 	/* | ||||
| 	 * oldnoconfig is an alias of olddefconfig, because people already | ||||
| 	 * are dependent on its behavior(sets new symbols to their default | ||||
| 	 * value but not 'n') with the counter-intuitive name. | ||||
| 	 */ | ||||
| 	{"oldnoconfig",     no_argument,       NULL, olddefconfig}, | ||||
| 	{"yes2modconfig",   no_argument,       NULL, yes2modconfig}, | ||||
| 	{"mod2yesconfig",   no_argument,       NULL, mod2yesconfig}, | ||||
| 	{NULL, 0, NULL, 0} | ||||
| }; | ||||
|  | ||||
| @@ -475,11 +480,12 @@ static void conf_usage(const char *progname) | ||||
| 	printf("Usage: %s [-s] [option] <kconfig-file>\n", progname); | ||||
| 	printf("[option] is _one_ of the following:\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("  --oldconfig             Update a configuration using a provided .config as base\n"); | ||||
| 	printf("  --silentoldconfig       Same as oldconfig, but quietly, additionally update deps\n"); | ||||
| 	printf("  --olddefconfig          Same as silentoldconfig but sets new symbols to their default value\n"); | ||||
| 	printf("  --oldnoconfig           An alias of olddefconfig\n"); | ||||
| 	printf("  --syncconfig            Similar to oldconfig but generates configuration in\n" | ||||
| 	       "                          include/{generated/,config/}\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("  --savedefconfig <file>  Save the minimal current configuration to <file>\n"); | ||||
| 	printf("  --allnoconfig           New config where all options are answered with no\n"); | ||||
| @@ -487,6 +493,8 @@ static void conf_usage(const char *progname) | ||||
| 	printf("  --allmodconfig          New config where all options are answered with mod\n"); | ||||
| 	printf("  --alldefconfig          New config with all symbols set to default\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"); | ||||
| } | ||||
|  | ||||
| int main(int ac, char **av) | ||||
| @@ -494,14 +502,10 @@ int main(int ac, char **av) | ||||
| 	const char *progname = av[0]; | ||||
| 	int opt; | ||||
| 	const char *name, *defconfig_file = NULL /* gcc uninit */; | ||||
| 	struct stat tmpstat; | ||||
| 	const char *input_file = NULL, *output_file = NULL; | ||||
| 	int no_conf_write = 0; | ||||
|  | ||||
| 	setlocale(LC_ALL, ""); | ||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); | ||||
| 	textdomain(PACKAGE); | ||||
|  | ||||
| 	tty_stdio = isatty(0) && isatty(1) && isatty(2); | ||||
| 	tty_stdio = isatty(0) && isatty(1); | ||||
|  | ||||
| 	while ((opt = getopt_long(ac, av, "r:w:s", long_opts, NULL)) != -1) { | ||||
| 		if (opt == 's') { | ||||
| @@ -509,7 +513,12 @@ int main(int ac, char **av) | ||||
| 			continue; | ||||
| 		} | ||||
| 		switch (opt) { | ||||
| 		case silentoldconfig: | ||||
| 		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: | ||||
| @@ -548,7 +557,10 @@ int main(int ac, char **av) | ||||
| 		case allmodconfig: | ||||
| 		case alldefconfig: | ||||
| 		case listnewconfig: | ||||
| 		case helpnewconfig: | ||||
| 		case olddefconfig: | ||||
| 		case yes2modconfig: | ||||
| 		case mod2yesconfig: | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			input_file = optarg; | ||||
| @@ -564,43 +576,34 @@ int main(int ac, char **av) | ||||
| 		input_mode = (enum input_mode)opt; | ||||
| 	} | ||||
| 	if (ac == optind) { | ||||
| 		printf(_("%s: Kconfig file missing\n"), av[0]); | ||||
| 		fprintf(stderr, "%s: Kconfig file missing\n", av[0]); | ||||
| 		conf_usage(progname); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	name = av[optind]; | ||||
| 	conf_parse(name); | ||||
| 	//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) { | ||||
| 	case defconfig: | ||||
| 		if (!defconfig_file) | ||||
| 			defconfig_file = conf_get_default_confname(); | ||||
| 		if (conf_read(defconfig_file)) { | ||||
| 			printf(_("***\n" | ||||
| 			fprintf(stderr, | ||||
| 				"***\n" | ||||
| 				  "*** Can't find default configuration \"%s\"!\n" | ||||
| 				"***\n"), defconfig_file); | ||||
| 				  "***\n", | ||||
| 				defconfig_file); | ||||
| 			exit(1); | ||||
| 		} | ||||
| 		break; | ||||
| 	case savedefconfig: | ||||
| 	case silentoldconfig: | ||||
| 	case syncconfig: | ||||
| 	case oldaskconfig: | ||||
| 	case oldconfig: | ||||
| 	case listnewconfig: | ||||
| 	case helpnewconfig: | ||||
| 	case olddefconfig: | ||||
| 	case yes2modconfig: | ||||
| 	case mod2yesconfig: | ||||
| 	case allnoconfig: | ||||
| 	case allyesconfig: | ||||
| 	case allmodconfig: | ||||
| @@ -613,15 +616,15 @@ int main(int ac, char **av) | ||||
| 	} | ||||
|  | ||||
| 	if (sync_kconfig) { | ||||
| 		if (conf_get_changed()) { | ||||
| 		name = getenv("KCONFIG_NOSILENTUPDATE"); | ||||
| 		if (name && *name) { | ||||
| 			if (conf_get_changed()) { | ||||
| 				fprintf(stderr, | ||||
| 					_("\n*** The configuration requires explicit update.\n\n")); | ||||
| 					"\n*** The configuration requires explicit update.\n\n"); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			no_conf_write = 1; | ||||
| 		} | ||||
| 		valid_stdin = tty_stdio; | ||||
| 	} | ||||
|  | ||||
| 	switch (input_mode) { | ||||
| @@ -646,58 +649,59 @@ int main(int ac, char **av) | ||||
| 		break; | ||||
| 	case savedefconfig: | ||||
| 		break; | ||||
| 	case yes2modconfig: | ||||
| 		conf_rewrite_mod_or_yes(def_y2m); | ||||
| 		break; | ||||
| 	case mod2yesconfig: | ||||
| 		conf_rewrite_mod_or_yes(def_m2y); | ||||
| 		break; | ||||
| 	case oldaskconfig: | ||||
| 		rootEntry = &rootmenu; | ||||
| 		conf(&rootmenu); | ||||
| 		input_mode = silentoldconfig; | ||||
| 		input_mode = oldconfig; | ||||
| 		/* fall through */ | ||||
| 	case oldconfig: | ||||
| 	case listnewconfig: | ||||
| 	case olddefconfig: | ||||
| 	case silentoldconfig: | ||||
| 	case helpnewconfig: | ||||
| 	case syncconfig: | ||||
| 		/* Update until a loop caused no more changes */ | ||||
| 		do { | ||||
| 			conf_cnt = 0; | ||||
| 			check_conf(&rootmenu); | ||||
| 		} while (conf_cnt && | ||||
| 			 (input_mode != listnewconfig && | ||||
| 			  input_mode != olddefconfig)); | ||||
| 		} while (conf_cnt); | ||||
| 		break; | ||||
| 	case olddefconfig: | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	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 ((output_file || conf_get_changed()) && | ||||
| 		    conf_write(output_file)) { | ||||
| 			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 (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; | ||||
| 		} | ||||
| 	} else if (input_mode != listnewconfig) { | ||||
| 		if (conf_write(output_file)) { | ||||
| 			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); | ||||
| 	} else if (input_mode != listnewconfig && input_mode != helpnewconfig) { | ||||
| 		if ((output_file || !no_conf_write) && | ||||
| 		    conf_write(output_file)) { | ||||
| 			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); | ||||
| 			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; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * 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"); | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,14 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h> | ||||
| #include <ctype.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <limits.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| @@ -16,6 +18,151 @@ | ||||
|  | ||||
| #include "lkc.h" | ||||
|  | ||||
| /* return true if 'path' exists, false otherwise */ | ||||
| static bool is_present(const char *path) | ||||
| { | ||||
| 	struct stat st; | ||||
|  | ||||
| 	return !stat(path, &st); | ||||
| } | ||||
|  | ||||
| /* return true if 'path' exists and it is a directory, false otherwise */ | ||||
| static bool is_dir(const char *path) | ||||
| { | ||||
| 	struct stat st; | ||||
|  | ||||
| 	if (stat(path, &st)) | ||||
| 		return 0; | ||||
|  | ||||
| 	return S_ISDIR(st.st_mode); | ||||
| } | ||||
|  | ||||
| /* return true if the given two files are the same, false otherwise */ | ||||
| static bool is_same(const char *file1, const char *file2) | ||||
| { | ||||
| 	int fd1, fd2; | ||||
| 	struct stat st1, st2; | ||||
| 	void *map1, *map2; | ||||
| 	bool ret = false; | ||||
|  | ||||
| 	fd1 = open(file1, O_RDONLY); | ||||
| 	if (fd1 < 0) | ||||
| 		return ret; | ||||
|  | ||||
| 	fd2 = open(file2, O_RDONLY); | ||||
| 	if (fd2 < 0) | ||||
| 		goto close1; | ||||
|  | ||||
| 	ret = fstat(fd1, &st1); | ||||
| 	if (ret) | ||||
| 		goto close2; | ||||
| 	ret = fstat(fd2, &st2); | ||||
| 	if (ret) | ||||
| 		goto close2; | ||||
|  | ||||
| 	if (st1.st_size != st2.st_size) | ||||
| 		goto close2; | ||||
|  | ||||
| 	map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); | ||||
| 	if (map1 == MAP_FAILED) | ||||
| 		goto close2; | ||||
|  | ||||
| 	map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); | ||||
| 	if (map2 == MAP_FAILED) | ||||
| 		goto close2; | ||||
|  | ||||
| 	if (bcmp(map1, map2, st1.st_size)) | ||||
| 		goto close2; | ||||
|  | ||||
| 	ret = true; | ||||
| close2: | ||||
| 	close(fd2); | ||||
| close1: | ||||
| 	close(fd1); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Create the parent directory of the given path. | ||||
|  * | ||||
|  * For example, if 'include/config/auto.conf' is given, create 'include/config'. | ||||
|  */ | ||||
| static int make_parent_dir(const char *path) | ||||
| { | ||||
| 	char tmp[PATH_MAX + 1]; | ||||
| 	char *p; | ||||
|  | ||||
| 	strncpy(tmp, path, sizeof(tmp)); | ||||
| 	tmp[sizeof(tmp) - 1] = 0; | ||||
|  | ||||
| 	/* Remove the base name. Just return if nothing is left */ | ||||
| 	p = strrchr(tmp, '/'); | ||||
| 	if (!p) | ||||
| 		return 0; | ||||
| 	*(p + 1) = 0; | ||||
|  | ||||
| 	/* Just in case it is an absolute path */ | ||||
| 	p = tmp; | ||||
| 	while (*p == '/') | ||||
| 		p++; | ||||
|  | ||||
| 	while ((p = strchr(p, '/'))) { | ||||
| 		*p = 0; | ||||
|  | ||||
| 		/* skip if the directory exists */ | ||||
| 		if (!is_dir(tmp) && mkdir(tmp, 0755)) | ||||
| 			return -1; | ||||
|  | ||||
| 		*p = '/'; | ||||
| 		while (*p == '/') | ||||
| 			p++; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static char depfile_path[PATH_MAX]; | ||||
| static size_t depfile_prefix_len; | ||||
|  | ||||
| /* touch depfile for symbol 'name' */ | ||||
| static int conf_touch_dep(const char *name) | ||||
| { | ||||
| 	int fd, ret; | ||||
| 	const char *s; | ||||
| 	char *d, c; | ||||
|  | ||||
| 	/* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */ | ||||
| 	if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path)) | ||||
| 		return -1; | ||||
|  | ||||
| 	d = depfile_path + depfile_prefix_len; | ||||
| 	s = name; | ||||
|  | ||||
| 	while ((c = *s++)) | ||||
| 		*d++ = (c == '_') ? '/' : tolower(c); | ||||
| 	strcpy(d, ".h"); | ||||
|  | ||||
| 	/* Assume directory path already exists. */ | ||||
| 	fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); | ||||
| 	if (fd == -1) { | ||||
| 		if (errno != ENOENT) | ||||
| 			return -1; | ||||
|  | ||||
| 		ret = make_parent_dir(depfile_path); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
|  | ||||
| 		/* Try it again. */ | ||||
| 		fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); | ||||
| 		if (fd == -1) | ||||
| 			return -1; | ||||
| 	} | ||||
| 	close(fd); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| struct conf_printer { | ||||
| 	void (*print_symbol)(FILE *, struct symbol *, const char *, void *); | ||||
| 	void (*print_comment)(FILE *, const char *, void *); | ||||
| @@ -28,9 +175,7 @@ static void conf_message(const char *fmt, ...) | ||||
| 	__attribute__ ((format (printf, 1, 2))); | ||||
|  | ||||
| static const char *conf_filename; | ||||
| static int conf_lineno, conf_warnings, conf_unsaved; | ||||
|  | ||||
| const char conf_defname[] = "arch/$ARCH/defconfig"; | ||||
| static int conf_lineno, conf_warnings; | ||||
|  | ||||
| static void conf_warning(const char *fmt, ...) | ||||
| { | ||||
| @@ -43,16 +188,16 @@ static void conf_warning(const char *fmt, ...) | ||||
| 	conf_warnings++; | ||||
| } | ||||
|  | ||||
| static void conf_default_message_callback(const char *fmt, va_list ap) | ||||
| static void conf_default_message_callback(const char *s) | ||||
| { | ||||
| 	printf("#\n# "); | ||||
| 	vprintf(fmt, ap); | ||||
| 	printf("%s", s); | ||||
| 	printf("\n#\n"); | ||||
| } | ||||
|  | ||||
| static void (*conf_message_callback) (const char *fmt, va_list ap) = | ||||
| static void (*conf_message_callback)(const char *s) = | ||||
| 	conf_default_message_callback; | ||||
| void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) | ||||
| void conf_set_message_callback(void (*fn)(const char *s)) | ||||
| { | ||||
| 	conf_message_callback = fn; | ||||
| } | ||||
| @@ -60,10 +205,15 @@ void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) | ||||
| static void conf_message(const char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 	char buf[4096]; | ||||
|  | ||||
| 	if (!conf_message_callback) | ||||
| 		return; | ||||
|  | ||||
| 	va_start(ap, fmt); | ||||
| 	if (conf_message_callback) | ||||
| 		conf_message_callback(fmt, ap); | ||||
|  | ||||
| 	vsnprintf(buf, sizeof(buf), fmt, ap); | ||||
| 	conf_message_callback(buf); | ||||
| 	va_end(ap); | ||||
| } | ||||
|  | ||||
| @@ -74,55 +224,13 @@ const char *conf_get_configname(void) | ||||
| 	return name ? name : ".config"; | ||||
| } | ||||
|  | ||||
| const char *conf_get_autoconfig_name(void) | ||||
| static const char *conf_get_autoconfig_name(void) | ||||
| { | ||||
| 	char *name = getenv("KCONFIG_AUTOCONFIG"); | ||||
|  | ||||
| 	return name ? name : "include/config/auto.conf"; | ||||
| } | ||||
|  | ||||
| static char *conf_expand_value(const char *in) | ||||
| { | ||||
| 	struct symbol *sym; | ||||
| 	const char *src; | ||||
| 	static char res_value[SYMBOL_MAXLENGTH]; | ||||
| 	char *dst, name[SYMBOL_MAXLENGTH]; | ||||
|  | ||||
| 	res_value[0] = 0; | ||||
| 	dst = name; | ||||
| 	while ((src = strchr(in, '$'))) { | ||||
| 		strncat(res_value, in, src - in); | ||||
| 		src++; | ||||
| 		dst = name; | ||||
| 		while (isalnum(*src) || *src == '_') | ||||
| 			*dst++ = *src++; | ||||
| 		*dst = 0; | ||||
| 		sym = sym_lookup(name, 0); | ||||
| 		sym_calc_value(sym); | ||||
| 		strcat(res_value, sym_get_string_value(sym)); | ||||
| 		in = src; | ||||
| 	} | ||||
| 	strcat(res_value, in); | ||||
|  | ||||
| 	return res_value; | ||||
| } | ||||
|  | ||||
| char *conf_get_default_confname(void) | ||||
| { | ||||
| 	struct stat buf; | ||||
| 	static char fullname[PATH_MAX+1]; | ||||
| 	char *env, *name; | ||||
|  | ||||
| 	name = conf_expand_value(conf_defname); | ||||
| 	env = getenv(SRCTREE); | ||||
| 	if (env) { | ||||
| 		sprintf(fullname, "%s/%s", env, name); | ||||
| 		if (!stat(fullname, &buf)) | ||||
| 			return fullname; | ||||
| 	} | ||||
| 	return name; | ||||
| } | ||||
|  | ||||
| static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | ||||
| { | ||||
| 	char *p2; | ||||
| @@ -150,14 +258,6 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | ||||
| 			conf_warning("symbol value '%s' invalid for %s", | ||||
| 				     p, sym->name); | ||||
| 		return 1; | ||||
| 	case S_OTHER: | ||||
| 		if (*p != '"') { | ||||
| 			for (p2 = p; *p2 && !isspace(*p2); p2++) | ||||
| 				; | ||||
| 			sym->type = S_STRING; | ||||
| 			goto done; | ||||
| 		} | ||||
| 		/* fall through */ | ||||
| 	case S_STRING: | ||||
| 		if (*p++ != '"') | ||||
| 			break; | ||||
| @@ -176,9 +276,8 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | ||||
| 		/* fall through */ | ||||
| 	case S_INT: | ||||
| 	case S_HEX: | ||||
| 	done: | ||||
| 		if (sym_string_valid(sym, p)) { | ||||
| 			sym->def[def].val = strdup(p); | ||||
| 			sym->def[def].val = xstrdup(p); | ||||
| 			sym->flags |= def_flags; | ||||
| 		} else { | ||||
| 			if (def != S_DEF_AUTO) | ||||
| @@ -201,7 +300,7 @@ static int add_byte(int c, char **lineptr, size_t slen, size_t *n) | ||||
| 	if (new_size > *n) { | ||||
| 		new_size += LINE_GROWTH - 1; | ||||
| 		new_size *= 2; | ||||
| 		nline = realloc(*lineptr, new_size); | ||||
| 		nline = xrealloc(*lineptr, new_size); | ||||
| 		if (!nline) | ||||
| 			return -1; | ||||
|  | ||||
| @@ -299,10 +398,11 @@ int conf_read_simple(const char *name, int def) | ||||
| 			if (expr_calc_value(prop->visible.expr) == no || | ||||
| 			    prop->expr->type != E_SYMBOL) | ||||
| 				continue; | ||||
| 			name = conf_expand_value(prop->expr->left.sym->name); | ||||
| 			sym_calc_value(prop->expr->left.sym); | ||||
| 			name = sym_get_string_value(prop->expr->left.sym); | ||||
| 			in = zconf_fopen(name); | ||||
| 			if (in) { | ||||
| 				conf_message(_("using defaults found in %s"), | ||||
| 				conf_message("using defaults found in %s", | ||||
| 					 name); | ||||
| 				goto load; | ||||
| 			} | ||||
| @@ -315,7 +415,6 @@ load: | ||||
| 	conf_filename = name; | ||||
| 	conf_lineno = 0; | ||||
| 	conf_warnings = 0; | ||||
| 	conf_unsaved = 0; | ||||
|  | ||||
| 	def_flags = SYMBOL_DEF << def; | ||||
| 	conf_reset(def); | ||||
| @@ -336,7 +435,7 @@ load: | ||||
| 				sym = sym_find(line + 2 + strlen(CONFIG_)); | ||||
| 				if (!sym) { | ||||
| 					sym_add_change_count(1); | ||||
| 					goto setsym; | ||||
| 					continue; | ||||
| 				} | ||||
| 			} else { | ||||
| 				sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); | ||||
| @@ -363,17 +462,22 @@ load: | ||||
| 				if (*p2 == '\r') | ||||
| 					*p2 = 0; | ||||
| 			} | ||||
| 			if (def == S_DEF_USER) { | ||||
|  | ||||
| 			sym = sym_find(line + strlen(CONFIG_)); | ||||
| 			if (!sym) { | ||||
| 				if (def == S_DEF_AUTO) | ||||
| 					/* | ||||
| 					 * Reading from include/config/auto.conf | ||||
| 					 * If CONFIG_FOO previously existed in | ||||
| 					 * auto.conf but it is missing now, | ||||
| 					 * include/config/foo.h must be touched. | ||||
| 					 */ | ||||
| 					conf_touch_dep(line + strlen(CONFIG_)); | ||||
| 				else | ||||
| 					sym_add_change_count(1); | ||||
| 					goto setsym; | ||||
| 				} | ||||
| 			} else { | ||||
| 				sym = sym_lookup(line + strlen(CONFIG_), 0); | ||||
| 				if (sym->type == S_UNKNOWN) | ||||
| 					sym->type = S_OTHER; | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (conf_set_sym_val(sym, def, def_flags, p)) | ||||
| 				continue; | ||||
| 		} else { | ||||
| @@ -383,7 +487,7 @@ load: | ||||
|  | ||||
| 			continue; | ||||
| 		} | ||||
| setsym: | ||||
|  | ||||
| 		if (sym && sym_is_choice_value(sym)) { | ||||
| 			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); | ||||
| 			switch (sym->def[def].tri) { | ||||
| @@ -412,6 +516,7 @@ setsym: | ||||
| int conf_read(const char *name) | ||||
| { | ||||
| 	struct symbol *sym; | ||||
| 	int conf_unsaved = 0; | ||||
| 	int i; | ||||
|  | ||||
| 	sym_set_change_count(0); | ||||
| @@ -425,18 +530,16 @@ int conf_read(const char *name) | ||||
|  | ||||
| 	for_all_symbols(i, sym) { | ||||
| 		sym_calc_value(sym); | ||||
| 		if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) | ||||
| 		if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) | ||||
| 			continue; | ||||
| 		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { | ||||
| 			/* check that calculated value agrees with saved value */ | ||||
| 			switch (sym->type) { | ||||
| 			case S_BOOLEAN: | ||||
| 			case S_TRISTATE: | ||||
| 				if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) | ||||
| 					break; | ||||
| 				if (!sym_is_choice(sym)) | ||||
| 				if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) | ||||
| 					continue; | ||||
| 				/* fall through */ | ||||
| 				break; | ||||
| 			default: | ||||
| 				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) | ||||
| 					continue; | ||||
| @@ -610,32 +713,12 @@ static struct conf_printer header_printer_cb = | ||||
| 	.print_comment = header_print_comment, | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Tristate printer | ||||
|  * | ||||
|  * This printer is used when generating the `include/config/tristate.conf' file. | ||||
|  */ | ||||
| static void | ||||
| tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) | ||||
| { | ||||
|  | ||||
| 	if (sym->type == S_TRISTATE && *value != 'n') | ||||
| 		fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value)); | ||||
| } | ||||
|  | ||||
| static struct conf_printer tristate_printer_cb = | ||||
| { | ||||
| 	.print_symbol = tristate_print_symbol, | ||||
| 	.print_comment = kconfig_print_comment, | ||||
| }; | ||||
|  | ||||
| static void conf_write_symbol(FILE *fp, struct symbol *sym, | ||||
| 			      struct conf_printer *printer, void *printer_arg) | ||||
| { | ||||
| 	const char *str; | ||||
|  | ||||
| 	switch (sym->type) { | ||||
| 	case S_OTHER: | ||||
| 	case S_UNKNOWN: | ||||
| 		break; | ||||
| 	case S_STRING: | ||||
| @@ -695,7 +778,7 @@ int conf_write_defconfig(const char *filename) | ||||
| 				goto next_menu; | ||||
| 			sym->flags &= ~SYMBOL_WRITE; | ||||
| 			/* If we cannot change the symbol - skip */ | ||||
| 			if (!sym_is_changable(sym)) | ||||
| 			if (!sym_is_changeable(sym)) | ||||
| 				goto next_menu; | ||||
| 			/* If symbol equals to default value - skip */ | ||||
| 			if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) | ||||
| @@ -746,41 +829,36 @@ int conf_write(const char *name) | ||||
| 	FILE *out; | ||||
| 	struct symbol *sym; | ||||
| 	struct menu *menu; | ||||
| 	const char *basename; | ||||
| 	const char *str; | ||||
| 	char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; | ||||
| 	char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; | ||||
| 	char *env; | ||||
| 	int i; | ||||
| 	bool need_newline = false; | ||||
|  | ||||
| 	dirname[0] = 0; | ||||
| 	if (name && name[0]) { | ||||
| 		struct stat st; | ||||
| 		char *slash; | ||||
| 	if (!name) | ||||
| 		name = conf_get_configname(); | ||||
|  | ||||
| 		if (!stat(name, &st) && S_ISDIR(st.st_mode)) { | ||||
| 			strcpy(dirname, name); | ||||
| 			strcat(dirname, "/"); | ||||
| 			basename = conf_get_configname(); | ||||
| 		} else if ((slash = strrchr(name, '/'))) { | ||||
| 			int size = slash - name + 1; | ||||
| 			memcpy(dirname, name, size); | ||||
| 			dirname[size] = 0; | ||||
| 			if (slash[1]) | ||||
| 				basename = slash + 1; | ||||
| 			else | ||||
| 				basename = conf_get_configname(); | ||||
| 		} else | ||||
| 			basename = name; | ||||
| 	} else | ||||
| 		basename = conf_get_configname(); | ||||
| 	if (!*name) { | ||||
| 		fprintf(stderr, "config name is empty\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (is_dir(name)) { | ||||
| 		fprintf(stderr, "%s: Is a directory\n", name); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (make_parent_dir(name)) | ||||
| 		return -1; | ||||
|  | ||||
| 	sprintf(newname, "%s%s", dirname, basename); | ||||
| 	env = getenv("KCONFIG_OVERWRITECONFIG"); | ||||
| 	if (!env || !*env) { | ||||
| 		sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); | ||||
| 		out = fopen(tmpname, "w"); | ||||
| 	} else { | ||||
| 	if (env && *env) { | ||||
| 		*tmpname = 0; | ||||
| 		out = fopen(newname, "w"); | ||||
| 		out = fopen(name, "w"); | ||||
| 	} else { | ||||
| 		snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", | ||||
| 			 name, (int)getpid()); | ||||
| 		out = fopen(tmpname, "w"); | ||||
| 	} | ||||
| 	if (!out) | ||||
| 		return 1; | ||||
| @@ -801,12 +879,17 @@ int conf_write(const char *name) | ||||
| 				     "#\n" | ||||
| 				     "# %s\n" | ||||
| 				     "#\n", str); | ||||
| 		} else if (!(sym->flags & SYMBOL_CHOICE)) { | ||||
| 			need_newline = false; | ||||
| 		} else if (!(sym->flags & SYMBOL_CHOICE) && | ||||
| 			   !(sym->flags & SYMBOL_WRITTEN)) { | ||||
| 			sym_calc_value(sym); | ||||
| 			if (!(sym->flags & SYMBOL_WRITE)) | ||||
| 				goto next; | ||||
| 			sym->flags &= ~SYMBOL_WRITE; | ||||
|  | ||||
| 			if (need_newline) { | ||||
| 				fprintf(out, "\n"); | ||||
| 				need_newline = false; | ||||
| 			} | ||||
| 			sym->flags |= SYMBOL_WRITTEN; | ||||
| 			conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); | ||||
| 		} | ||||
|  | ||||
| @@ -818,6 +901,12 @@ next: | ||||
| 		if (menu->next) | ||||
| 			menu = menu->next; | ||||
| 		else while ((menu = menu->parent)) { | ||||
| 			if (!menu->sym && menu_is_visible(menu) && | ||||
| 			    menu != &rootmenu) { | ||||
| 				str = menu_get_prompt(menu); | ||||
| 				fprintf(out, "# end of %s\n", str); | ||||
| 				need_newline = true; | ||||
| 			} | ||||
| 			if (menu->next) { | ||||
| 				menu = menu->next; | ||||
| 				break; | ||||
| @@ -826,41 +915,76 @@ next: | ||||
| 	} | ||||
| 	fclose(out); | ||||
|  | ||||
| 	for_all_symbols(i, sym) | ||||
| 		sym->flags &= ~SYMBOL_WRITTEN; | ||||
|  | ||||
| 	if (*tmpname) { | ||||
| 		strcat(dirname, basename); | ||||
| 		strcat(dirname, ".old"); | ||||
| 		rename(newname, dirname); | ||||
| 		if (rename(tmpname, newname)) | ||||
| 		if (is_same(name, tmpname)) { | ||||
| 			conf_message("No change to %s", name); | ||||
| 			unlink(tmpname); | ||||
| 			sym_set_change_count(0); | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		snprintf(oldname, sizeof(oldname), "%s.old", name); | ||||
| 		rename(name, oldname); | ||||
| 		if (rename(tmpname, name)) | ||||
| 			return 1; | ||||
| 	} | ||||
|  | ||||
| 	conf_message(_("configuration written to %s"), newname); | ||||
| 	conf_message("configuration written to %s", name); | ||||
|  | ||||
| 	sym_set_change_count(0); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int conf_split_config(void) | ||||
| /* write a dependency file as used by kbuild to track dependencies */ | ||||
| static int conf_write_dep(const char *name) | ||||
| { | ||||
| 	struct file *file; | ||||
| 	FILE *out; | ||||
|  | ||||
| 	out = fopen("..config.tmp", "w"); | ||||
| 	if (!out) | ||||
| 		return 1; | ||||
| 	fprintf(out, "deps_config := \\\n"); | ||||
| 	for (file = file_list; file; file = file->next) { | ||||
| 		if (file->next) | ||||
| 			fprintf(out, "\t%s \\\n", file->name); | ||||
| 		else | ||||
| 			fprintf(out, "\t%s\n", file->name); | ||||
| 	} | ||||
| 	fprintf(out, "\n%s: \\\n" | ||||
| 		     "\t$(deps_config)\n\n", conf_get_autoconfig_name()); | ||||
|  | ||||
| 	env_write_dep(out, conf_get_autoconfig_name()); | ||||
|  | ||||
| 	fprintf(out, "\n$(deps_config): ;\n"); | ||||
| 	fclose(out); | ||||
|  | ||||
| 	if (make_parent_dir(name)) | ||||
| 		return 1; | ||||
| 	rename("..config.tmp", name); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int conf_touch_deps(void) | ||||
| { | ||||
| 	const char *name; | ||||
| 	char path[PATH_MAX+1]; | ||||
| 	char *s, *d, c; | ||||
| 	struct symbol *sym; | ||||
| 	struct stat sb; | ||||
| 	int res, i, fd; | ||||
| 	int res, i; | ||||
|  | ||||
| 	strcpy(depfile_path, "include/config/"); | ||||
| 	depfile_prefix_len = strlen(depfile_path); | ||||
|  | ||||
| 	name = conf_get_autoconfig_name(); | ||||
| 	conf_read_simple(name, S_DEF_AUTO); | ||||
| 	sym_calc_value(modules_sym); | ||||
|  | ||||
| 	if (chdir("include/config")) | ||||
| 		return 1; | ||||
|  | ||||
| 	res = 0; | ||||
| 	for_all_symbols(i, sym) { | ||||
| 		sym_calc_value(sym); | ||||
| 		if ((sym->flags & SYMBOL_AUTO) || !sym->name) | ||||
| 		if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) | ||||
| 			continue; | ||||
| 		if (sym->flags & SYMBOL_WRITE) { | ||||
| 			if (sym->flags & SYMBOL_DEF_AUTO) { | ||||
| @@ -909,86 +1033,44 @@ static int conf_split_config(void) | ||||
| 		 *	different from 'no'). | ||||
| 		 */ | ||||
|  | ||||
| 		/* Replace all '_' and append ".h" */ | ||||
| 		s = sym->name; | ||||
| 		d = path; | ||||
| 		while ((c = *s++)) { | ||||
| 			c = tolower(c); | ||||
| 			*d++ = (c == '_') ? '/' : c; | ||||
| 		} | ||||
| 		strcpy(d, ".h"); | ||||
|  | ||||
| 		/* Assume directory path already exists. */ | ||||
| 		fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); | ||||
| 		if (fd == -1) { | ||||
| 			if (errno != ENOENT) { | ||||
| 				res = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			/* | ||||
| 			 * Create directory components, | ||||
| 			 * unless they exist already. | ||||
| 			 */ | ||||
| 			d = path; | ||||
| 			while ((d = strchr(d, '/'))) { | ||||
| 				*d = 0; | ||||
| 				if (stat(path, &sb) && mkdir(path, 0755)) { | ||||
| 					res = 1; | ||||
| 					goto out; | ||||
| 				} | ||||
| 				*d++ = '/'; | ||||
| 			} | ||||
| 			/* Try it again. */ | ||||
| 			fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); | ||||
| 			if (fd == -1) { | ||||
| 				res = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		close(fd); | ||||
| 	} | ||||
| out: | ||||
| 	if (chdir("../..")) | ||||
| 		return 1; | ||||
|  | ||||
| 		res = conf_touch_dep(sym->name); | ||||
| 		if (res) | ||||
| 			return res; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int conf_write_autoconf(void) | ||||
| int conf_write_autoconf(int overwrite) | ||||
| { | ||||
| 	struct symbol *sym; | ||||
| 	const char *name; | ||||
| 	FILE *out, *tristate, *out_h; | ||||
| 	const char *autoconf_name = conf_get_autoconfig_name(); | ||||
| 	FILE *out, *out_h; | ||||
| 	int i; | ||||
|  | ||||
| 	sym_clear_all_valid(); | ||||
| #ifndef OPENWRT_DOES_NOT_WANT_THIS | ||||
| 	return 0; | ||||
| #endif | ||||
| 	if (!overwrite && is_present(autoconf_name)) | ||||
| 		return 0; | ||||
|  | ||||
| 	file_write_dep("include/config/auto.conf.cmd"); | ||||
| 	conf_write_dep("include/config/auto.conf.cmd"); | ||||
|  | ||||
| 	if (conf_split_config()) | ||||
| 	if (conf_touch_deps()) | ||||
| 		return 1; | ||||
|  | ||||
| 	out = fopen(".tmpconfig", "w"); | ||||
| 	if (!out) | ||||
| 		return 1; | ||||
|  | ||||
| 	tristate = fopen(".tmpconfig_tristate", "w"); | ||||
| 	if (!tristate) { | ||||
| 		fclose(out); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	out_h = fopen(".tmpconfig.h", "w"); | ||||
| 	if (!out_h) { | ||||
| 		fclose(out); | ||||
| 		fclose(tristate); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	conf_write_heading(out, &kconfig_printer_cb, NULL); | ||||
|  | ||||
| 	conf_write_heading(tristate, &tristate_printer_cb, NULL); | ||||
|  | ||||
| 	conf_write_heading(out_h, &header_printer_cb, NULL); | ||||
|  | ||||
| 	for_all_symbols(i, sym) { | ||||
| @@ -996,33 +1078,28 @@ int conf_write_autoconf(void) | ||||
| 		if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | ||||
| 			continue; | ||||
|  | ||||
| 		/* write symbol to auto.conf, tristate and header files */ | ||||
| 		/* write symbols to auto.conf and autoconf.h */ | ||||
| 		conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); | ||||
|  | ||||
| 		conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); | ||||
|  | ||||
| 		conf_write_symbol(out_h, sym, &header_printer_cb, NULL); | ||||
| 	} | ||||
| 	fclose(out); | ||||
| 	fclose(tristate); | ||||
| 	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)) | ||||
| 		return 1; | ||||
| 	name = getenv("KCONFIG_TRISTATE"); | ||||
| 	if (!name) | ||||
| 		name = "include/config/tristate.conf"; | ||||
| 	if (rename(".tmpconfig_tristate", name)) | ||||
|  | ||||
| 	if (make_parent_dir(autoconf_name)) | ||||
| 		return 1; | ||||
| 	name = conf_get_autoconfig_name(); | ||||
| 	/* | ||||
| 	 * This must be the last step, kbuild has a dependency on auto.conf | ||||
| 	 * and this marks the successful completion of the previous steps. | ||||
| 	 */ | ||||
| 	if (rename(".tmpconfig", name)) | ||||
| 	if (rename(".tmpconfig", autoconf_name)) | ||||
| 		return 1; | ||||
|  | ||||
| 	return 0; | ||||
| @@ -1126,7 +1203,7 @@ void set_all_choice_values(struct symbol *csym) | ||||
| bool conf_set_all_new_symbols(enum conf_def_mode mode) | ||||
| { | ||||
| 	struct symbol *sym, *csym; | ||||
| 	int i, cnt, pby, pty, ptm;	/* pby: probability of boolean  = y | ||||
| 	int i, cnt, pby, pty, ptm;	/* pby: probability of bool     = y | ||||
| 					 * pty: probability of tristate = y | ||||
| 					 * ptm: probability of tristate = m | ||||
| 					 */ | ||||
| @@ -1250,3 +1327,19 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode) | ||||
|  | ||||
| 	return has_changed; | ||||
| } | ||||
|  | ||||
| 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_add_change_count(1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * 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 <stdlib.h> | ||||
| #include <string.h> | ||||
| @@ -11,7 +13,6 @@ | ||||
|  | ||||
| #define DEBUG_EXPR	0 | ||||
|  | ||||
| static int expr_eq(struct expr *e1, struct expr *e2); | ||||
| static struct expr *expr_eliminate_yn(struct expr *e); | ||||
|  | ||||
| struct expr *expr_alloc_symbol(struct symbol *sym) | ||||
| @@ -94,7 +95,7 @@ struct expr *expr_copy(const struct expr *org) | ||||
| 		e->right.expr = expr_copy(org->right.expr); | ||||
| 		break; | ||||
| 	default: | ||||
| 		printf("can't copy type %d\n", e->type); | ||||
| 		fprintf(stderr, "can't copy type %d\n", e->type); | ||||
| 		free(e); | ||||
| 		e = NULL; | ||||
| 		break; | ||||
| @@ -113,7 +114,7 @@ void expr_free(struct expr *e) | ||||
| 		break; | ||||
| 	case E_NOT: | ||||
| 		expr_free(e->left.expr); | ||||
| 		return; | ||||
| 		break; | ||||
| 	case E_EQUAL: | ||||
| 	case E_GEQ: | ||||
| 	case E_GTH: | ||||
| @@ -127,7 +128,7 @@ void expr_free(struct expr *e) | ||||
| 		expr_free(e->right.expr); | ||||
| 		break; | ||||
| 	default: | ||||
| 		printf("how to free type %d?\n", e->type); | ||||
| 		fprintf(stderr, "how to free type %d?\n", e->type); | ||||
| 		break; | ||||
| 	} | ||||
| 	free(e); | ||||
| @@ -138,8 +139,18 @@ static int trans_count; | ||||
| #define e1 (*ep1) | ||||
| #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) | ||||
| { | ||||
| 	/* Recurse down to leaves */ | ||||
|  | ||||
| 	if (e1->type == type) { | ||||
| 		__expr_eliminate_eq(type, &e1->left.expr, &e2); | ||||
| 		__expr_eliminate_eq(type, &e1->right.expr, &e2); | ||||
| @@ -150,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); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* e1 and e2 are leaves. Compare them. */ | ||||
|  | ||||
| 	if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && | ||||
| 	    e1->left.sym == e2->left.sym && | ||||
| 	    (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) | ||||
| 		return; | ||||
| 	if (!expr_eq(e1, e2)) | ||||
| 		return; | ||||
|  | ||||
| 	/* e1 and e2 are equal leaves. Prepare them for elimination. */ | ||||
|  | ||||
| 	trans_count++; | ||||
| 	expr_free(e1); expr_free(e2); | ||||
| 	switch (type) { | ||||
| @@ -172,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) | ||||
| { | ||||
| 	if (!e1 || !e2) | ||||
| @@ -197,10 +243,23 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) | ||||
| #undef e1 | ||||
| #undef e2 | ||||
|  | ||||
| static int expr_eq(struct expr *e1, struct expr *e2) | ||||
| /* | ||||
|  * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two | ||||
|  * &&/|| expressions are considered equal if every operand in one expression | ||||
|  * equals some operand in the other (operands do not need to appear in the same | ||||
|  * order), recursively. | ||||
|  */ | ||||
| int expr_eq(struct expr *e1, struct expr *e2) | ||||
| { | ||||
| 	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) | ||||
| 		return 0; | ||||
| 	switch (e1->type) { | ||||
| @@ -243,6 +302,17 @@ static int expr_eq(struct expr *e1, struct expr *e2) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * 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; | ||||
| @@ -516,12 +586,21 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2) | ||||
| 	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) | ||||
| { | ||||
| #define e1 (*ep1) | ||||
| #define e2 (*ep2) | ||||
| 	struct expr *tmp; | ||||
|  | ||||
| 	/* Recurse down to leaves */ | ||||
|  | ||||
| 	if (e1->type == type) { | ||||
| 		expr_eliminate_dups1(type, &e1->left.expr, &e2); | ||||
| 		expr_eliminate_dups1(type, &e1->right.expr, &e2); | ||||
| @@ -532,6 +611,9 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct | ||||
| 		expr_eliminate_dups1(type, &e1, &e2->right.expr); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	/* e1 and e2 are leaves. Compare and process them. */ | ||||
|  | ||||
| 	if (e1 == e2) | ||||
| 		return; | ||||
|  | ||||
| @@ -568,6 +650,17 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct | ||||
| #undef e2 | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Rewrites 'e' in-place to remove ("join") duplicate and other redundant | ||||
|  * operands. | ||||
|  * | ||||
|  * Example simplifications: | ||||
|  * | ||||
|  *	A || B || A    ->  A || B | ||||
|  *	A && B && A=y  ->  A=y && B | ||||
|  * | ||||
|  * Returns the deduplicated expression. | ||||
|  */ | ||||
| struct expr *expr_eliminate_dups(struct expr *e) | ||||
| { | ||||
| 	int oldcount; | ||||
| @@ -584,6 +677,7 @@ struct expr *expr_eliminate_dups(struct expr *e) | ||||
| 			; | ||||
| 		} | ||||
| 		if (!trans_count) | ||||
| 			/* No simplifications done in this pass. We're done */ | ||||
| 			break; | ||||
| 		e = expr_eliminate_yn(e); | ||||
| 	} | ||||
| @@ -591,6 +685,12 @@ struct expr *expr_eliminate_dups(struct expr *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 *tmp; | ||||
| @@ -805,6 +905,20 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym) | ||||
|  	return false; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Inserts explicit comparisons of type 'type' to symbol 'sym' into the | ||||
|  * expression 'e'. | ||||
|  * | ||||
|  * Examples transformations for type == E_UNEQUAL, sym == &symbol_no: | ||||
|  * | ||||
|  *	A              ->  A!=n | ||||
|  *	!A             ->  A=n | ||||
|  *	A && B         ->  !(A=n || B=n) | ||||
|  *	A || B         ->  !(A=n && B=n) | ||||
|  *	A && (B || C)  ->  !(A=n || (B=n && C=n)) | ||||
|  * | ||||
|  * Allocates and returns a new expression. | ||||
|  */ | ||||
| struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) | ||||
| { | ||||
| 	struct expr *e1, *e2; | ||||
| @@ -874,7 +988,6 @@ enum string_value_kind { | ||||
| 	k_string, | ||||
| 	k_signed, | ||||
| 	k_unsigned, | ||||
| 	k_invalid | ||||
| }; | ||||
|  | ||||
| union string_value { | ||||
| @@ -905,13 +1018,10 @@ static enum string_value_kind expr_parse_string(const char *str, | ||||
| 		val->u = strtoull(str, &tail, 16); | ||||
| 		kind = k_unsigned; | ||||
| 		break; | ||||
| 	case S_STRING: | ||||
| 	case S_UNKNOWN: | ||||
| 	default: | ||||
| 		val->s = strtoll(str, &tail, 0); | ||||
| 		kind = k_signed; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return k_invalid; | ||||
| 	} | ||||
| 	return !errno && !*tail && tail > str && isxdigit(tail[-1]) | ||||
| 	       ? kind : k_string; | ||||
| @@ -967,13 +1077,7 @@ tristate expr_calc_value(struct expr *e) | ||||
|  | ||||
| 	if (k1 == k_string || k2 == k_string) | ||||
| 		res = strcmp(str1, str2); | ||||
| 	else if (k1 == k_invalid || k2 == k_invalid) { | ||||
| 		if (e->type != E_EQUAL && e->type != E_UNEQUAL) { | ||||
| 			printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2); | ||||
| 			return no; | ||||
| 		} | ||||
| 		res = strcmp(str1, str2); | ||||
| 	} else if (k1 == k_unsigned || k2 == k_unsigned) | ||||
| 	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); | ||||
| @@ -1031,49 +1135,9 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static inline struct expr * | ||||
| expr_get_leftmost_symbol(const struct expr *e) | ||||
| { | ||||
|  | ||||
| 	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) | ||||
| void expr_print(struct expr *e, | ||||
| 		void (*fn)(void *, struct symbol *, const char *), | ||||
| 		void *data, int prevtoken) | ||||
| { | ||||
| 	if (!e) { | ||||
| 		fn(data, NULL, "y"); | ||||
| @@ -1207,3 +1271,33 @@ void expr_gstr_print(struct expr *e, struct gstr *gs) | ||||
| { | ||||
| 	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> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #ifndef EXPR_H | ||||
| @@ -62,7 +62,7 @@ struct symbol_value { | ||||
| }; | ||||
|  | ||||
| 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[] */ | ||||
| @@ -74,20 +74,64 @@ enum { | ||||
| 	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 { | ||||
| 	/* The next symbol in the same bucket in the symbol hash table */ | ||||
| 	struct symbol *next; | ||||
|  | ||||
| 	/* The name of the symbol, e.g. "FOO" for 'config FOO' */ | ||||
| 	char *name; | ||||
|  | ||||
| 	/* S_BOOLEAN, S_TRISTATE, ... */ | ||||
| 	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; | ||||
|  | ||||
| 	/* | ||||
| 	 * Values for the symbol provided from outside. def[S_DEF_USER] holds | ||||
| 	 * the .config value. | ||||
| 	 */ | ||||
| 	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; | ||||
|  | ||||
| 	/* SYMBOL_* flags */ | ||||
| 	int flags; | ||||
|  | ||||
| 	/* List of properties. See prop_type. */ | ||||
| 	struct property *prop; | ||||
|  | ||||
| 	/* Dependencies from enclosing menus, choices, and ifs */ | ||||
| 	struct expr_value dir_dep; | ||||
|  | ||||
| 	/* Reverse dependencies through being selected by other symbols */ | ||||
| 	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_CHECK      0x0008  /* used during dependency checking */ | ||||
| @@ -97,7 +141,8 @@ struct symbol { | ||||
| #define SYMBOL_OPTIONAL   0x0100  /* choice is optional - values can be 'n' */ | ||||
| #define SYMBOL_WRITE      0x0200  /* write symbol to file (KCONFIG_CONFIG) */ | ||||
| #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_WARNED     0x8000  /* warning has been issued */ | ||||
|  | ||||
| @@ -127,24 +172,26 @@ struct symbol { | ||||
|  * config BAZ | ||||
|  *         int "BAZ Value" | ||||
|  *         range 1..255 | ||||
|  * | ||||
|  * Please, also check parser.y:print_symbol() when modifying the | ||||
|  * list of property types! | ||||
|  */ | ||||
| enum prop_type { | ||||
| 	P_UNKNOWN, | ||||
| 	P_PROMPT,   /* prompt "foo prompt" or "BAZ Value" */ | ||||
| 	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_CHOICE,   /* choice value */ | ||||
| 	P_SELECT,   /* select BAR */ | ||||
| 	P_IMPLY,    /* imply BAR */ | ||||
| 	P_RANGE,    /* range 7..100 (for a symbol) */ | ||||
| 	P_ENV,      /* value from environment variable */ | ||||
| 	P_SYMBOL,   /* where a symbol is defined */ | ||||
| 	P_RESET,	/* reset to defaults condition */ | ||||
| }; | ||||
|  | ||||
| struct property { | ||||
| 	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 */ | ||||
| 	const char *text;          /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ | ||||
| 	struct expr_value visible; | ||||
| @@ -165,22 +212,67 @@ struct property { | ||||
| 	for (st = sym->prop; st; st = st->next) \ | ||||
| 		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 { | ||||
| 	/* The next menu node at the same level */ | ||||
| 	struct menu *next; | ||||
|  | ||||
| 	/* The parent menu node, corresponding to e.g. a menu or choice */ | ||||
| 	struct menu *parent; | ||||
|  | ||||
| 	/* The first child menu node, for e.g. menus and choices */ | ||||
| 	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; | ||||
|  | ||||
| 	/* | ||||
| 	 * 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; | ||||
|  | ||||
| 	/* | ||||
| 	 * 'visible if' dependencies. If more than one is given, they will be | ||||
| 	 * ANDed together. | ||||
| 	 */ | ||||
| 	struct expr *visibility; | ||||
|  | ||||
| 	/* | ||||
| 	 * Ordinary dependencies from e.g. 'depends on' and 'if', ANDed | ||||
| 	 * together | ||||
| 	 */ | ||||
| 	struct expr *dep; | ||||
|  | ||||
| 	/* MENU_* flags */ | ||||
| 	unsigned int flags; | ||||
|  | ||||
| 	/* Any help text associated with the node */ | ||||
| 	char *help; | ||||
|  | ||||
| 	/* The location where the menu node appears in the Kconfig files */ | ||||
| 	struct file *file; | ||||
| 	int lineno; | ||||
|  | ||||
| 	/* For use by front ends that need to store auxiliary 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_ROOT		0x0002 | ||||
|  | ||||
| struct jump_key { | ||||
| @@ -209,6 +301,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); | ||||
| struct expr *expr_copy(const struct expr *org); | ||||
| void expr_free(struct expr *e); | ||||
| 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); | ||||
| struct expr *expr_trans_bool(struct expr *e); | ||||
| struct expr *expr_eliminate_dups(struct expr *e); | ||||
| @@ -216,11 +309,12 @@ struct expr *expr_transform(struct expr *e); | ||||
| int expr_contains_symbol(struct expr *dep, struct symbol *sym); | ||||
| bool expr_depends_symbol(struct expr *dep, struct symbol *sym); | ||||
| struct expr *expr_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); | ||||
| struct gstr; /* forward */ | ||||
| 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) | ||||
| { | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * 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 *xpm_load[] = { | ||||
| "22 22 5 1", | ||||
| ". c None", | ||||
| "# c #000000", | ||||
| @@ -33,7 +35,7 @@ static const char *xpm_load[] = { | ||||
| "###############.......", | ||||
| "......................"}; | ||||
|  | ||||
| static const char *xpm_save[] = { | ||||
| const char *xpm_save[] = { | ||||
| "22 22 5 1", | ||||
| ". c None", | ||||
| "# c #000000", | ||||
| @@ -63,7 +65,7 @@ static const char *xpm_save[] = { | ||||
| "..##################..", | ||||
| "......................"}; | ||||
|  | ||||
| static const char *xpm_back[] = { | ||||
| const char *xpm_back[] = { | ||||
| "22 22 3 1", | ||||
| ". c None", | ||||
| "# c #000083", | ||||
| @@ -91,7 +93,7 @@ static const char *xpm_back[] = { | ||||
| "......................", | ||||
| "......................"}; | ||||
|  | ||||
| static const char *xpm_tree_view[] = { | ||||
| const char *xpm_tree_view[] = { | ||||
| "22 22 2 1", | ||||
| ". c None", | ||||
| "# c #000000", | ||||
| @@ -118,7 +120,7 @@ static const char *xpm_tree_view[] = { | ||||
| "......................", | ||||
| "......................"}; | ||||
|  | ||||
| static const char *xpm_single_view[] = { | ||||
| const char *xpm_single_view[] = { | ||||
| "22 22 2 1", | ||||
| ". c None", | ||||
| "# c #000000", | ||||
| @@ -145,7 +147,7 @@ static const char *xpm_single_view[] = { | ||||
| "......................", | ||||
| "......................"}; | ||||
|  | ||||
| static const char *xpm_split_view[] = { | ||||
| const char *xpm_split_view[] = { | ||||
| "22 22 2 1", | ||||
| ". c None", | ||||
| "# c #000000", | ||||
| @@ -172,7 +174,7 @@ static const char *xpm_split_view[] = { | ||||
| "......................", | ||||
| "......................"}; | ||||
|  | ||||
| static const char *xpm_symbol_no[] = { | ||||
| const char *xpm_symbol_no[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -189,7 +191,7 @@ static const char *xpm_symbol_no[] = { | ||||
| " .......... ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_symbol_mod[] = { | ||||
| const char *xpm_symbol_mod[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -206,7 +208,7 @@ static const char *xpm_symbol_mod[] = { | ||||
| " .......... ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_symbol_yes[] = { | ||||
| const char *xpm_symbol_yes[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -223,7 +225,7 @@ static const char *xpm_symbol_yes[] = { | ||||
| " .......... ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_choice_no[] = { | ||||
| const char *xpm_choice_no[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -240,7 +242,7 @@ static const char *xpm_choice_no[] = { | ||||
| "    ....    ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_choice_yes[] = { | ||||
| const char *xpm_choice_yes[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -257,7 +259,7 @@ static const char *xpm_choice_yes[] = { | ||||
| "    ....    ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_menu[] = { | ||||
| const char *xpm_menu[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -274,7 +276,7 @@ static const char *xpm_menu[] = { | ||||
| " .......... ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_menu_inv[] = { | ||||
| const char *xpm_menu_inv[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -291,7 +293,7 @@ static const char *xpm_menu_inv[] = { | ||||
| " .......... ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_menuback[] = { | ||||
| const char *xpm_menuback[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
| @@ -308,7 +310,7 @@ static const char *xpm_menuback[] = { | ||||
| " .......... ", | ||||
| "            "}; | ||||
|  | ||||
| static const char *xpm_void[] = { | ||||
| const char *xpm_void[] = { | ||||
| "12 12 2 1", | ||||
| "  c white", | ||||
| ". c black", | ||||
|   | ||||
							
								
								
									
										33
									
								
								scripts/config/images.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								scripts/config/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 *xpm_load[]; | ||||
| extern const char *xpm_save[]; | ||||
| extern const char *xpm_back[]; | ||||
| extern const char *xpm_tree_view[]; | ||||
| extern const char *xpm_single_view[]; | ||||
| extern const char *xpm_split_view[]; | ||||
| extern const char *xpm_symbol_no[]; | ||||
| extern const char *xpm_symbol_mod[]; | ||||
| extern const char *xpm_symbol_yes[]; | ||||
| extern const char *xpm_choice_no[]; | ||||
| extern const char *xpm_choice_yes[]; | ||||
| extern const char *xpm_menu[]; | ||||
| extern const char *xpm_menu_inv[]; | ||||
| extern const char *xpm_menuback[]; | ||||
| extern const char *xpm_void[]; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif /* IMAGES_H */ | ||||
| @@ -1,13 +1,13 @@ | ||||
| %option nostdinit noyywrap never-interactive full ecs | ||||
| %option 8bit nodefault perf-report perf-report | ||||
| %option noinput | ||||
| %x COMMAND HELP STRING PARAM | ||||
| %{ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
| %option nostdinit noyywrap never-interactive full ecs | ||||
| %option 8bit nodefault yylineno | ||||
| %x ASSIGN_VAL HELP STRING | ||||
| %{ | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <limits.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| @@ -17,6 +17,9 @@ | ||||
| #include <libgen.h> | ||||
| 
 | ||||
| #include "lkc.h" | ||||
| #include "parser.tab.h" | ||||
| 
 | ||||
| #define YY_DECL		static int yylex1(void) | ||||
| 
 | ||||
| #define START_STRSIZE	16 | ||||
| 
 | ||||
| @@ -25,6 +28,8 @@ static struct { | ||||
| 	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; | ||||
| 
 | ||||
| @@ -37,6 +42,8 @@ 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); | ||||
| 
 | ||||
| @@ -54,7 +61,7 @@ static void append_string(const char *str, int size) | ||||
| 	if (new_size > text_asize) { | ||||
| 		new_size += START_STRSIZE - 1; | ||||
| 		new_size &= -START_STRSIZE; | ||||
| 		text = realloc(text, new_size); | ||||
| 		text = xrealloc(text, new_size); | ||||
| 		text_asize = new_size; | ||||
| 	} | ||||
| 	memcpy(text + text_size, str, size); | ||||
| @@ -73,7 +80,7 @@ static void warn_ignored_character(char chr) | ||||
| { | ||||
| 	fprintf(stderr, | ||||
| 	        "%s:%d:warning: ignoring unsupported character '%c'\n", | ||||
| 	        zconf_curname(), zconf_lineno(), chr); | ||||
| 	        current_file->name, yylineno, chr); | ||||
| } | ||||
| %} | ||||
| 
 | ||||
| @@ -83,116 +90,114 @@ 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; | ||||
| 	} | ||||
| 	.	warn_ignored_character(*yytext); | ||||
| 	\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; | ||||
| 	"<="	return T_LESS_EQUAL; | ||||
| 	">="	return T_GREATER_EQUAL; | ||||
| 	"<"	return T_LESS; | ||||
| 	">"	return T_GREATER; | ||||
| 	\"|\'	{ | ||||
| #.*			/* ignore comment */ | ||||
| [ \t]*			/* whitespaces */ | ||||
| \\\n			/* escaped new line */ | ||||
| \n			return T_EOL; | ||||
| "allnoconfig_y"		return T_ALLNOCONFIG_Y; | ||||
| "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; | ||||
| "defconfig_list"	return T_DEFCONFIG_LIST; | ||||
| "depends"		return T_DEPENDS; | ||||
| "endchoice"		return T_ENDCHOICE; | ||||
| "endif"			return T_ENDIF; | ||||
| "endmenu"		return T_ENDMENU; | ||||
| "help"|"---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; | ||||
| "option"		return T_OPTION; | ||||
| "optional"		return T_OPTIONAL; | ||||
| "prompt"		return T_PROMPT; | ||||
| "range"			return T_RANGE; | ||||
| "reset"			return T_RESET; | ||||
| "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	BEGIN(INITIAL); current_file->lineno++; return T_EOL; | ||||
| 	({n}|[/.])+	{ | ||||
| 		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); | ||||
| 		if (id && id->flags & TF_PARAM) { | ||||
| 			zconflval.id = id; | ||||
| 			return id->token; | ||||
| 		} | ||||
| ({n}|[/.])+		{ | ||||
| 				alloc_string(yytext, yyleng); | ||||
| 		zconflval.string = text; | ||||
| 				yylval.string = text; | ||||
| 				return T_WORD; | ||||
| 			} | ||||
| 	#.*	/* comment */ | ||||
| 	\\\n	current_file->lineno++; | ||||
| 	[[:blank:]]+ | ||||
| 	.	warn_ignored_character(*yytext); | ||||
| 	<<EOF>> { | ||||
| 		BEGIN(INITIAL); | ||||
| ({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>{ | ||||
| 	[^'"\\\n]+/\n	{ | ||||
| 	"$".*	append_expanded_string(yytext); | ||||
| 	[^$'"\\\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; | ||||
| 			BEGIN(INITIAL); | ||||
| 			yylval.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++; | ||||
| 		fprintf(stderr, | ||||
| 			"%s:%d:warning: multi-line strings not supported\n", | ||||
| 			zconf_curname(), zconf_lineno()); | ||||
| 		unput('\n'); | ||||
| 		BEGIN(INITIAL); | ||||
| 		return T_EOL; | ||||
| 		yylval.string = text; | ||||
| 		return T_WORD_QUOTE; | ||||
| 	} | ||||
| 	<<EOF>>	{ | ||||
| 		BEGIN(INITIAL); | ||||
| 		yylval.string = text; | ||||
| 		return T_WORD_QUOTE; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @@ -220,12 +225,10 @@ n	[A-Za-z0-9_-] | ||||
| 		} | ||||
| 	} | ||||
| 	[ \t]*\n/[^ \t\n] { | ||||
| 		current_file->lineno++; | ||||
| 		zconf_endhelp(); | ||||
| 		return T_HELPTEXT; | ||||
| 	} | ||||
| 	[ \t]*\n	{ | ||||
| 		current_file->lineno++; | ||||
| 		append_string("\n", 1); | ||||
| 	} | ||||
| 	[^ \t\n].* { | ||||
| @@ -245,6 +248,12 @@ n	[A-Za-z0-9_-] | ||||
| } | ||||
| 
 | ||||
| <<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; | ||||
| @@ -254,6 +263,93 @@ n	[A-Za-z0-9_-] | ||||
| } | ||||
| 
 | ||||
| %% | ||||
| 
 | ||||
| /* 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(); | ||||
| @@ -263,7 +359,7 @@ void zconf_starthelp(void) | ||||
| 
 | ||||
| static void zconf_endhelp(void) | ||||
| { | ||||
| 	zconflval.string = text; | ||||
| 	yylval.string = text; | ||||
| 	BEGIN(INITIAL); | ||||
| } | ||||
| 
 | ||||
| @@ -285,7 +381,8 @@ FILE *zconf_fopen(const char *name) | ||||
| 	if (!f && name != NULL && name[0] != '/') { | ||||
| 		env = getenv(SRCTREE); | ||||
| 		if (env) { | ||||
| 			sprintf(fullname, "%s/%s", env, name); | ||||
| 			snprintf(fullname, sizeof(fullname), | ||||
| 				 "%s/%s", env, name); | ||||
| 			f = fopen(fullname, "r"); | ||||
| 		} | ||||
| 	} | ||||
| @@ -296,7 +393,7 @@ void zconf_initscan(const char *name) | ||||
| { | ||||
| 	yyin = zconf_fopen(name); | ||||
| 	if (!yyin) { | ||||
| 		printf("can't find file %s\n", name); | ||||
| 		fprintf(stderr, "can't find file %s\n", name); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 
 | ||||
| @@ -304,7 +401,7 @@ void zconf_initscan(const char *name) | ||||
| 	memset(current_buf, 0, sizeof(*current_buf)); | ||||
| 
 | ||||
| 	current_file = file_lookup(name); | ||||
| 	current_file->lineno = 1; | ||||
| 	yylineno = 1; | ||||
| } | ||||
| 
 | ||||
| static void __zconf_nextfile(const char *name) | ||||
| @@ -317,7 +414,7 @@ static void __zconf_nextfile(const char *name) | ||||
| 	current_buf->state = YY_CURRENT_BUFFER; | ||||
| 	yyin = zconf_fopen(file->name); | ||||
| 	if (!yyin) { | ||||
| 		printf("%s:%d: can't open file \"%s\"\n", | ||||
| 		fprintf(stderr, "%s:%d: can't open file \"%s\"\n", | ||||
| 			zconf_curname(), zconf_lineno(), file->name); | ||||
| 		exit(1); | ||||
| 	} | ||||
| @@ -325,27 +422,26 @@ static void __zconf_nextfile(const char *name) | ||||
| 	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); | ||||
| 	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; | ||||
| 			} | ||||
| 			if (iter) | ||||
| 				printf("  included from: '%s:%d'\n", | ||||
| 				       iter->name, iter->lineno+1); | ||||
| 				fprintf(stderr, "  included from: %s:%d\n", | ||||
| 					iter->name, iter->lineno - 1); | ||||
| 			} while (strcmp(iter->name, file->name)); | ||||
| 			exit(1); | ||||
| 		} | ||||
| 	} | ||||
| 	file->lineno = 1; | ||||
| 	file->parent = current_file; | ||||
| 
 | ||||
| 	yylineno = 1; | ||||
| 	current_file = file; | ||||
| } | ||||
| 
 | ||||
| @@ -405,6 +501,8 @@ 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) { | ||||
							
								
								
									
										4499
									
								
								scripts/config/lexer.lex.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4499
									
								
								scripts/config/lexer.lex.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,3 +1,4 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| #ifndef LIST_H | ||||
| #define LIST_H | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #ifndef LKC_H | ||||
| @@ -8,15 +8,6 @@ | ||||
|  | ||||
| #include "expr.h" | ||||
|  | ||||
| #ifndef KBUILD_NO_NLS | ||||
| # 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 | ||||
| extern "C" { | ||||
| #endif | ||||
| @@ -29,11 +20,6 @@ extern "C" { | ||||
| #define PACKAGE "linux" | ||||
| #endif | ||||
|  | ||||
| #define LOCALEDIR "/usr/share/locale" | ||||
|  | ||||
| #define _(text) gettext(text) | ||||
| #define N_(text) (text) | ||||
|  | ||||
| #ifndef CONFIG_ | ||||
| #define CONFIG_ "CONFIG_" | ||||
| #endif | ||||
| @@ -44,30 +30,17 @@ static inline const char *CONFIG_prefix(void) | ||||
| #undef CONFIG_ | ||||
| #define CONFIG_ CONFIG_prefix() | ||||
|  | ||||
| #define TF_COMMAND	0x0001 | ||||
| #define TF_PARAM	0x0002 | ||||
| #define TF_OPTION	0x0004 | ||||
|  | ||||
| enum conf_def_mode { | ||||
| 	def_default, | ||||
| 	def_yes, | ||||
| 	def_mod, | ||||
| 	def_y2m, | ||||
| 	def_m2y, | ||||
| 	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 yylineno; | ||||
| void zconfdump(FILE *out); | ||||
| void zconf_starthelp(void); | ||||
| FILE *zconf_fopen(const char *name); | ||||
| @@ -78,11 +51,10 @@ const char *zconf_curname(void); | ||||
|  | ||||
| /* confdata.c */ | ||||
| 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 conf_rewrite_mod_or_yes(enum conf_def_mode mode); | ||||
| void set_all_choice_values(struct symbol *csym); | ||||
|  | ||||
| /* confdata.c and expr.c */ | ||||
| @@ -100,22 +72,28 @@ 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_prop(enum prop_type type, 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_add_option_modules(void); | ||||
| void menu_add_option_defconfig_list(void); | ||||
| void menu_add_option_allnoconfig_y(void); | ||||
| void menu_finalize(struct menu *parent); | ||||
| void menu_set_type(int type); | ||||
|  | ||||
| /* util.c */ | ||||
| struct file *file_lookup(const char *name); | ||||
| int file_write_dep(const char *name); | ||||
| void *xmalloc(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 { | ||||
| 	size_t len; | ||||
| @@ -133,16 +111,12 @@ void str_printf(struct gstr *gs, const char *fmt, ...); | ||||
| const char *str_get(struct gstr *gs); | ||||
|  | ||||
| /* symbol.c */ | ||||
| extern struct expr *sym_env_list; | ||||
|  | ||||
| void sym_init(void); | ||||
| void sym_clear_all_valid(void); | ||||
| 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); | ||||
| 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 property *sym_get_env_prop(struct symbol *sym); | ||||
|  | ||||
| static inline tristate sym_get_tristate_value(struct symbol *sym) | ||||
| { | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| #include <stdarg.h> | ||||
|  | ||||
| /* confdata.c */ | ||||
| @@ -7,10 +8,10 @@ int conf_read_simple(const char *name, int); | ||||
| void conf_reset(int def); | ||||
| int conf_write_defconfig(const char *name); | ||||
| int conf_write(const char *name); | ||||
| int conf_write_autoconf(void); | ||||
| int conf_write_autoconf(int overwrite); | ||||
| bool conf_get_changed(void); | ||||
| void conf_set_changed_callback(void (*fn)(void)); | ||||
| void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap)); | ||||
| void conf_set_message_callback(void (*fn)(const char *s)); | ||||
|  | ||||
| /* menu.c */ | ||||
| extern struct menu rootmenu; | ||||
| @@ -31,7 +32,6 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; | ||||
|  | ||||
| struct symbol * sym_lookup(const char *name, int flags); | ||||
| struct symbol * sym_find(const char *name); | ||||
| const char * sym_expand_string_value(const char *in); | ||||
| const char * sym_escape_string_value(const char *in); | ||||
| struct symbol ** sym_re_search(const char *pattern); | ||||
| const char * sym_type_name(enum symbol_type type); | ||||
| @@ -43,11 +43,24 @@ tristate sym_toggle_tristate_value(struct symbol *sym); | ||||
| bool sym_string_valid(struct symbol *sym, const char *newval); | ||||
| bool sym_string_within_range(struct symbol *sym, const char *str); | ||||
| bool sym_set_string_value(struct symbol *sym, const char *newval); | ||||
| bool sym_is_changable(struct symbol *sym); | ||||
| bool sym_is_changeable(struct symbol *sym); | ||||
| struct property * sym_get_choice_prop(struct symbol *sym); | ||||
| const char * sym_get_string_value(struct symbol *sym); | ||||
|  | ||||
| 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 */ | ||||
| void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); | ||||
|   | ||||
							
								
								
									
										2
									
								
								scripts/config/lxdialog/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								scripts/config/lxdialog/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | ||||
| lxdialog | ||||
| *.o | ||||
| @@ -1,91 +0,0 @@ | ||||
| #!/bin/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 ; 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 | ||||
|  * | ||||
| @@ -5,20 +6,6 @@ | ||||
|  *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension | ||||
|  *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two | ||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| #include "dialog.h" | ||||
| @@ -103,8 +90,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | ||||
| 	int x = width / 2 - 11; | ||||
| 	int y = height - 2; | ||||
|  | ||||
| 	print_button(dialog, gettext("Select"), y, x, selected == 0); | ||||
| 	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); | ||||
| 	print_button(dialog, "Select", y, x, selected == 0); | ||||
| 	print_button(dialog, " Help ", y, x + 14, selected == 1); | ||||
|  | ||||
| 	wmove(dialog, y, x + 1 + 14 * selected); | ||||
| 	wrefresh(dialog); | ||||
|   | ||||
| @@ -1,21 +1,8 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0+ */ | ||||
| /* | ||||
|  *  dialog.h -- common declarations for all dialog modules | ||||
|  * | ||||
|  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
| @@ -26,16 +13,10 @@ | ||||
| #include <string.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| #ifndef KBUILD_NO_NLS | ||||
| # include <libintl.h> | ||||
| #else | ||||
| # define gettext(Msgid) ((const char *) (Msgid)) | ||||
| #endif | ||||
|  | ||||
| #ifdef __sun__ | ||||
| #define CURS_MACROS | ||||
| #endif | ||||
| #include CURSES_LOC | ||||
| #include <ncurses.h> | ||||
|  | ||||
| /* | ||||
|  * 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 | ||||
|  * | ||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| #include "dialog.h" | ||||
| @@ -31,8 +18,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | ||||
| 	int x = width / 2 - 11; | ||||
| 	int y = height - 2; | ||||
|  | ||||
| 	print_button(dialog, gettext("  Ok  "), y, x, selected == 0); | ||||
| 	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); | ||||
| 	print_button(dialog, "  Ok  ", y, x, selected == 0); | ||||
| 	print_button(dialog, " Help ", y, x + 14, selected == 1); | ||||
|  | ||||
| 	wmove(dialog, y, x + 1 + 14 * selected); | ||||
| 	wrefresh(dialog); | ||||
| @@ -126,7 +113,8 @@ do_resize: | ||||
| 			case KEY_DOWN: | ||||
| 				break; | ||||
| 			case KEY_BACKSPACE: | ||||
| 			case 127: | ||||
| 			case 8:   /* ^H */ | ||||
| 			case 127: /* ^? */ | ||||
| 				if (pos) { | ||||
| 					wattrset(dialog, dlg.inputbox.atr); | ||||
| 					if (input_x == 0) { | ||||
|   | ||||
| @@ -1,22 +1,9 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0+ | ||||
| /* | ||||
|  *  menubox.c -- implements the menu box | ||||
|  * | ||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
| @@ -157,11 +144,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected) | ||||
| 	int x = width / 2 - 28; | ||||
| 	int y = height - 2; | ||||
|  | ||||
| 	print_button(win, gettext("Select"), y, x, selected == 0); | ||||
| 	print_button(win, gettext(" Exit "), y, x + 12, selected == 1); | ||||
| 	print_button(win, gettext(" Help "), y, x + 24, selected == 2); | ||||
| 	print_button(win, gettext(" Save "), y, x + 36, selected == 3); | ||||
| 	print_button(win, gettext(" Load "), y, x + 48, selected == 4); | ||||
| 	print_button(win, "Select", y, x, selected == 0); | ||||
| 	print_button(win, " Exit ", y, x + 12, selected == 1); | ||||
| 	print_button(win, " Help ", y, x + 24, selected == 2); | ||||
| 	print_button(win, " Save ", y, x + 36, selected == 3); | ||||
| 	print_button(win, " Load ", y, x + 48, selected == 4); | ||||
|  | ||||
| 	wmove(win, y, x + 1 + 12 * selected); | ||||
| 	wrefresh(win); | ||||
|   | ||||
| @@ -1,22 +1,9 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0+ | ||||
| /* | ||||
|  *  textbox.c -- implements the text box | ||||
|  * | ||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| #include "dialog.h" | ||||
| @@ -129,7 +116,7 @@ do_resize: | ||||
|  | ||||
| 	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); | ||||
| 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */ | ||||
|  | ||||
|   | ||||
| @@ -1,22 +1,9 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0+ | ||||
| /* | ||||
|  *  util.c | ||||
|  * | ||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| #include <stdarg.h> | ||||
|   | ||||
| @@ -1,22 +1,9 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0+ | ||||
| /* | ||||
|  *  yesno.c -- implements the yes/no box | ||||
|  * | ||||
|  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||||
|  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU General Public License | ||||
|  *  as published by the Free Software Foundation; either version 2 | ||||
|  *  of the License, or (at your option) any later version. | ||||
|  * | ||||
|  *  This program is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with this program; if not, write to the Free Software | ||||
|  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
|  | ||||
| #include "dialog.h" | ||||
| @@ -29,8 +16,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | ||||
| 	int x = width / 2 - 10; | ||||
| 	int y = height - 2; | ||||
|  | ||||
| 	print_button(dialog, gettext(" Yes "), y, x, selected == 0); | ||||
| 	print_button(dialog, gettext("  No  "), y, x + 13, selected == 1); | ||||
| 	print_button(dialog, " Yes ", y, x, selected == 0); | ||||
| 	print_button(dialog, "  No  ", y, x + 13, selected == 1); | ||||
|  | ||||
| 	wmove(dialog, y, x + 1 + 13 * selected); | ||||
| 	wrefresh(dialog); | ||||
|   | ||||
							
								
								
									
										50
									
								
								scripts/config/mconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								scripts/config/mconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| #!/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 | ||||
|  | ||||
| if [ -f /usr/include/ncurses.h ]; 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> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  * | ||||
|  * Introduced single menu mode (show all sub-menus in one large tree). | ||||
|  * 2002-11-06 Petr Baudis <pasky@ucw.cz> | ||||
| @@ -15,23 +15,27 @@ | ||||
| #include <stdarg.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <strings.h> | ||||
| #include <signal.h> | ||||
| #include <unistd.h> | ||||
| #include <locale.h> | ||||
|  | ||||
| #include "lkc.h" | ||||
| #include "lxdialog/dialog.h" | ||||
|  | ||||
| static const char mconf_readme[] = N_( | ||||
| static const char mconf_readme[] = | ||||
| "Overview\n" | ||||
| "--------\n" | ||||
| "Some OpenWrt features may be built directly into the image.\n" | ||||
| "Some may be made into installable ipkg packages. Some features\n" | ||||
| "may be completely removed altogether.\n" | ||||
| "Some may be made into installable ipkg packages (referred here as\n" | ||||
| "modules). Some features may be completely removed altogether.\n" | ||||
| "\n" | ||||
| "Menu items beginning with [*], <M> or [ ] represent features\n" | ||||
| "configured to be included, built as package or removed respectively.\n" | ||||
| "Pointed brackets <> represent packaging capable features.\n" | ||||
| "Menu items beginning with following braces represent features that\n" | ||||
| "  [ ] can be built in or removed\n" | ||||
| "  < > can be built in, modularized or removed\n" | ||||
| "  { } can be built in or modularized (selected by other feature)\n" | ||||
| "  - - are selected by other feature,\n" | ||||
| "while *, M or whitespace inside braces means to build in, build as\n" | ||||
| "a module or to exclude the feature respectively.\n" | ||||
| "\n" | ||||
| "To change any of these features, highlight it with the cursor\n" | ||||
| "keys and press <Y> to build it in, <M> to make it a module or\n" | ||||
| @@ -167,37 +171,37 @@ static const char mconf_readme[] = N_( | ||||
| " blackbg    => selects a color scheme with black background\n" | ||||
| " classic    => theme with blue background. The classic look\n" | ||||
| " bluetitle  => an LCD friendly version of classic. (default)\n" | ||||
| "\n"), | ||||
| menu_instructions[] = N_( | ||||
| "\n", | ||||
| menu_instructions[] = | ||||
| 	"Arrow keys navigate the menu.  " | ||||
| 	"<Enter> selects submenus ---> (or empty submenus ----).  " | ||||
| 	"Highlighted letters are hotkeys.  " | ||||
| 	"Pressing <Y> includes, <N> excludes, <M> modularizes features.  " | ||||
| 	"Press <Esc><Esc> to exit, <?> for Help, </> for Search.  " | ||||
| 	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"), | ||||
| radiolist_instructions[] = N_( | ||||
| 	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable", | ||||
| radiolist_instructions[] = | ||||
| 	"Use the arrow keys to navigate this window or " | ||||
| 	"press the hotkey of the item you wish to select " | ||||
| 	"followed by the <SPACE BAR>. " | ||||
| 	"Press <?> for additional information about this option."), | ||||
| inputbox_instructions_int[] = N_( | ||||
| 	"Press <?> for additional information about this option.", | ||||
| inputbox_instructions_int[] = | ||||
| 	"Please enter a decimal value. " | ||||
| 	"Fractions will not be accepted.  " | ||||
| 	"Use the <TAB> key to move from the input field to the buttons below it."), | ||||
| inputbox_instructions_hex[] = N_( | ||||
| 	"Use the <TAB> key to move from the input field to the buttons below it.", | ||||
| inputbox_instructions_hex[] = | ||||
| 	"Please enter a hexadecimal value. " | ||||
| 	"Use the <TAB> key to move from the input field to the buttons below it."), | ||||
| inputbox_instructions_string[] = N_( | ||||
| 	"Use the <TAB> key to move from the input field to the buttons below it.", | ||||
| inputbox_instructions_string[] = | ||||
| 	"Please enter a string value. " | ||||
| 	"Use the <TAB> key to move from the input field to the buttons below it."), | ||||
| setmod_text[] = N_( | ||||
| 	"Use the <TAB> key to move from the input field to the buttons below it.", | ||||
| setmod_text[] = | ||||
| 	"This feature depends on another which has been configured as a module.\n" | ||||
| 	"As a result, this feature will be built as a module."), | ||||
| load_config_text[] = N_( | ||||
| 	"As a result, this feature will be built as a module.", | ||||
| load_config_text[] = | ||||
| 	"Enter the name of the configuration file you wish to load.  " | ||||
| 	"Accept the name shown to restore the configuration you " | ||||
| 	"last retrieved.  Leave blank to abort."), | ||||
| load_config_help[] = N_( | ||||
| 	"last retrieved.  Leave blank to abort.", | ||||
| load_config_help[] = | ||||
| 	"\n" | ||||
| 	"For various reasons, one may wish to keep several different\n" | ||||
| 	"configurations available on a single machine.\n" | ||||
| @@ -207,11 +211,11 @@ load_config_help[] = N_( | ||||
| 	"configuration.\n" | ||||
| 	"\n" | ||||
| 	"If you are uncertain, then you have probably never used alternate\n" | ||||
| 	"configuration files. You should therefore leave this blank to abort.\n"), | ||||
| save_config_text[] = N_( | ||||
| 	"configuration files. You should therefore leave this blank to abort.\n", | ||||
| save_config_text[] = | ||||
| 	"Enter a filename to which this configuration should be saved " | ||||
| 	"as an alternate.  Leave blank to abort."), | ||||
| save_config_help[] = N_( | ||||
| 	"as an alternate.  Leave blank to abort.", | ||||
| save_config_help[] = | ||||
| 	"\n" | ||||
| 	"For various reasons, one may wish to keep different configurations\n" | ||||
| 	"available on a single machine.\n" | ||||
| @@ -221,8 +225,8 @@ save_config_help[] = N_( | ||||
| 	"configuration options you have selected at that time.\n" | ||||
| 	"\n" | ||||
| 	"If you are uncertain what all this means then you should probably\n" | ||||
| 	"leave this blank.\n"), | ||||
| search_help[] = N_( | ||||
| 	"leave this blank.\n", | ||||
| search_help[] = | ||||
| 	"\n" | ||||
| 	"Search for symbols and display their relations.\n" | ||||
| 	"Regular expressions are allowed.\n" | ||||
| @@ -242,7 +246,7 @@ search_help[] = N_( | ||||
| 	"  Selected by: BAR [=n]\n" | ||||
| 	"-----------------------------------------------------------------\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" | ||||
| 	"  this symbol\n" | ||||
| 	"o The 'Defined at' line tells at what file / line number the symbol\n" | ||||
| @@ -267,7 +271,7 @@ search_help[] = N_( | ||||
| 	"Examples: USB	=> find all symbols containing USB\n" | ||||
| 	"          ^USB => find all symbols starting with USB\n" | ||||
| 	"          USB$ => find all symbols ending with USB\n" | ||||
| 	"\n"); | ||||
| 	"\n"; | ||||
|  | ||||
| static int indent; | ||||
| static struct menu *current_menu; | ||||
| @@ -396,19 +400,19 @@ static void search_conf(void) | ||||
| 	struct subtitle_part stpart; | ||||
|  | ||||
| 	title = str_new(); | ||||
| 	str_printf( &title, _("Enter (sub)string or regexp to search for " | ||||
| 			      "(with or without \"%s\")"), CONFIG_); | ||||
| 	str_printf( &title, "Enter (sub)string or regexp to search for " | ||||
| 			      "(with or without \"%s\")", CONFIG_); | ||||
|  | ||||
| again: | ||||
| 	dialog_clear(); | ||||
| 	dres = dialog_inputbox(_("Search Configuration Parameter"), | ||||
| 	dres = dialog_inputbox("Search Configuration Parameter", | ||||
| 			      str_get(&title), | ||||
| 			      10, 75, ""); | ||||
| 	switch (dres) { | ||||
| 	case 0: | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		show_helptext(_("Search Configuration"), search_help); | ||||
| 		show_helptext("Search Configuration", search_help); | ||||
| 		goto again; | ||||
| 	default: | ||||
| 		str_free(&title); | ||||
| @@ -439,7 +443,7 @@ again: | ||||
|  | ||||
| 		res = get_relations_str(sym_arr, &head); | ||||
| 		set_subtitle(); | ||||
| 		dres = show_textbox_ext(_("Search Results"), (char *) | ||||
| 		dres = show_textbox_ext("Search Results", (char *) | ||||
| 					str_get(&res), 0, 0, keys, &vscroll, | ||||
| 					&hscroll, &update_text, (void *) | ||||
| 					&data); | ||||
| @@ -487,7 +491,6 @@ static void build_conf(struct menu *menu) | ||||
| 			switch (prop->type) { | ||||
| 			case P_MENU: | ||||
| 				child_count++; | ||||
| 				prompt = _(prompt); | ||||
| 				if (single_menu_mode) { | ||||
| 					item_make("%s%*c%s", | ||||
| 						  menu->data ? "-->" : "++>", | ||||
| @@ -504,7 +507,7 @@ static void build_conf(struct menu *menu) | ||||
| 			case P_COMMENT: | ||||
| 				if (prompt) { | ||||
| 					child_count++; | ||||
| 					item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt)); | ||||
| 					item_make("   %*c*** %s ***", indent + 1, ' ', prompt); | ||||
| 					item_set_tag(':'); | ||||
| 					item_set_data(menu); | ||||
| 				} | ||||
| @@ -512,7 +515,7 @@ static void build_conf(struct menu *menu) | ||||
| 			default: | ||||
| 				if (prompt) { | ||||
| 					child_count++; | ||||
| 					item_make("---%*c%s", indent + 1, ' ', _(prompt)); | ||||
| 					item_make("---%*c%s", indent + 1, ' ', prompt); | ||||
| 					item_set_tag(':'); | ||||
| 					item_set_data(menu); | ||||
| 				} | ||||
| @@ -534,7 +537,7 @@ static void build_conf(struct menu *menu) | ||||
| 		} | ||||
|  | ||||
| 		val = sym_get_tristate_value(sym); | ||||
| 		if (sym_is_changable(sym)) { | ||||
| 		if (sym_is_changeable(sym)) { | ||||
| 			switch (type) { | ||||
| 			case S_BOOLEAN: | ||||
| 				item_make("[%c]", val == no ? ' ' : '*'); | ||||
| @@ -556,10 +559,10 @@ static void build_conf(struct menu *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 (def_menu) { | ||||
| 				item_add_str(" (%s)", _(menu_get_prompt(def_menu))); | ||||
| 				item_add_str(" (%s)", menu_get_prompt(def_menu)); | ||||
| 				item_add_str("  --->"); | ||||
| 				if (def_menu->list) { | ||||
| 					indent += 2; | ||||
| @@ -571,7 +574,7 @@ static void build_conf(struct menu *menu) | ||||
| 		} | ||||
| 	} else { | ||||
| 		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_data(menu); | ||||
| 			goto conf_childs; | ||||
| @@ -585,7 +588,7 @@ static void build_conf(struct menu *menu) | ||||
| 		} else { | ||||
| 			switch (type) { | ||||
| 			case S_BOOLEAN: | ||||
| 				if (sym_is_changable(sym)) | ||||
| 				if (sym_is_changeable(sym)) | ||||
| 					item_make("[%c]", val == no ? ' ' : '*'); | ||||
| 				else | ||||
| 					item_make("-%c-", val == no ? ' ' : '*'); | ||||
| @@ -598,7 +601,7 @@ static void build_conf(struct menu *menu) | ||||
| 				case mod: ch = 'M'; break; | ||||
| 				default:  ch = ' '; break; | ||||
| 				} | ||||
| 				if (sym_is_changable(sym)) { | ||||
| 				if (sym_is_changeable(sym)) { | ||||
| 					if (sym->rev_dep.tri == mod) | ||||
| 						item_make("{%c}", ch); | ||||
| 					else | ||||
| @@ -614,17 +617,17 @@ static void build_conf(struct menu *menu) | ||||
| 				tmp = indent - tmp + 4; | ||||
| 				if (tmp < 0) | ||||
| 					tmp = 0; | ||||
| 				item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), | ||||
| 					     (sym_has_value(sym) || !sym_is_changable(sym)) ? | ||||
| 					     "" : _(" (NEW)")); | ||||
| 				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), | ||||
| 					     (sym_has_value(sym) || !sym_is_changeable(sym)) ? | ||||
| 					     "" : " (NEW)"); | ||||
| 				item_set_tag('s'); | ||||
| 				item_set_data(menu); | ||||
| 				goto conf_childs; | ||||
| 			} | ||||
| 		} | ||||
| 		item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), | ||||
| 			  (sym_has_value(sym) || !sym_is_changable(sym)) ? | ||||
| 			  "" : _(" (NEW)")); | ||||
| 		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), | ||||
| 			  (sym_has_value(sym) || !sym_is_changeable(sym)) ? | ||||
| 			  "" : " (NEW)"); | ||||
| 		if (menu->prompt->type == P_MENU) { | ||||
| 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->"); | ||||
| 			return; | ||||
| @@ -661,8 +664,8 @@ static void conf(struct menu *menu, struct menu *active_menu) | ||||
| 			break; | ||||
| 		set_subtitle(); | ||||
| 		dialog_clear(); | ||||
| 		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), | ||||
| 				  _(menu_instructions), | ||||
| 		res = dialog_menu(prompt ? prompt : "Main Menu", | ||||
| 				  menu_instructions, | ||||
| 				  active_menu, &s_scroll); | ||||
| 		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) | ||||
| 			break; | ||||
| @@ -704,7 +707,7 @@ static void conf(struct menu *menu, struct menu *active_menu) | ||||
| 				show_help(submenu); | ||||
| 			else { | ||||
| 				reset_subtitle(); | ||||
| 				show_helptext(_("README"), _(mconf_readme)); | ||||
| 				show_helptext("README", mconf_readme); | ||||
| 			} | ||||
| 			break; | ||||
| 		case 3: | ||||
| @@ -769,16 +772,13 @@ static void show_helptext(const char *title, const char *text) | ||||
| 	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]; | ||||
|  | ||||
| 	vsnprintf(buf, sizeof(buf), fmt, ap); | ||||
| 	if (save_and_exit) { | ||||
| 		if (!silent) | ||||
| 			printf("%s", buf); | ||||
| 			printf("%s", s); | ||||
| 	} else { | ||||
| 		show_textbox(NULL, buf, 6, 60); | ||||
| 		show_textbox(NULL, s, 6, 60); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -789,13 +789,13 @@ static void show_help(struct menu *menu) | ||||
| 	help.max_width = getmaxx(stdscr) - 10; | ||||
| 	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); | ||||
| } | ||||
|  | ||||
| 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 symbol *active; | ||||
| 	struct property *prop; | ||||
| @@ -811,9 +811,9 @@ static void conf_choice(struct menu *menu) | ||||
| 			if (!menu_is_visible(child)) | ||||
| 				continue; | ||||
| 			if (child->sym) | ||||
| 				item_make("%s", _(menu_get_prompt(child))); | ||||
| 				item_make("%s", menu_get_prompt(child)); | ||||
| 			else { | ||||
| 				item_make("*** %s ***", _(menu_get_prompt(child))); | ||||
| 				item_make("*** %s ***", menu_get_prompt(child)); | ||||
| 				item_set_tag(':'); | ||||
| 			} | ||||
| 			item_set_data(child); | ||||
| @@ -823,8 +823,8 @@ static void conf_choice(struct menu *menu) | ||||
| 				item_set_tag('X'); | ||||
| 		} | ||||
| 		dialog_clear(); | ||||
| 		res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), | ||||
| 					_(radiolist_instructions), | ||||
| 		res = dialog_checklist(prompt ? prompt : "Main Menu", | ||||
| 					radiolist_instructions, | ||||
| 					MENUBOX_HEIGTH_MIN, | ||||
| 					MENUBOX_WIDTH_MIN, | ||||
| 					CHECKLIST_HEIGTH_MIN); | ||||
| @@ -874,26 +874,26 @@ static void conf_string(struct menu *menu) | ||||
|  | ||||
| 		switch (sym_get_type(menu->sym)) { | ||||
| 		case S_INT: | ||||
| 			heading = _(inputbox_instructions_int); | ||||
| 			heading = inputbox_instructions_int; | ||||
| 			break; | ||||
| 		case S_HEX: | ||||
| 			heading = _(inputbox_instructions_hex); | ||||
| 			heading = inputbox_instructions_hex; | ||||
| 			break; | ||||
| 		case S_STRING: | ||||
| 			heading = _(inputbox_instructions_string); | ||||
| 			heading = inputbox_instructions_string; | ||||
| 			break; | ||||
| 		default: | ||||
| 			heading = _("Internal mconf error!"); | ||||
| 			heading = "Internal mconf error!"; | ||||
| 		} | ||||
| 		dialog_clear(); | ||||
| 		res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), | ||||
| 		res = dialog_inputbox(prompt ? prompt : "Main Menu", | ||||
| 				      heading, 10, 75, | ||||
| 				      sym_get_string_value(menu->sym)); | ||||
| 		switch (res) { | ||||
| 		case 0: | ||||
| 			if (sym_set_string_value(menu->sym, dialog_input_result)) | ||||
| 				return; | ||||
| 			show_textbox(NULL, _("You have made an invalid entry."), 5, 43); | ||||
| 			show_textbox(NULL, "You have made an invalid entry.", 5, 43); | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			show_help(menu); | ||||
| @@ -921,10 +921,10 @@ static void conf_load(void) | ||||
| 				sym_set_change_count(1); | ||||
| 				return; | ||||
| 			} | ||||
| 			show_textbox(NULL, _("File does not exist!"), 5, 38); | ||||
| 			show_textbox(NULL, "File does not exist!", 5, 38); | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			show_helptext(_("Load Alternate Configuration"), load_config_help); | ||||
| 			show_helptext("Load Alternate Configuration", load_config_help); | ||||
| 			break; | ||||
| 		case KEY_ESC: | ||||
| 			return; | ||||
| @@ -947,10 +947,10 @@ static void conf_save(void) | ||||
| 				set_config_filename(dialog_input_result); | ||||
| 				return; | ||||
| 			} | ||||
| 			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60); | ||||
| 			show_textbox(NULL, "Can't create file!", 5, 60); | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			show_helptext(_("Save Alternate Configuration"), save_config_help); | ||||
| 			show_helptext("Save Alternate Configuration", save_config_help); | ||||
| 			break; | ||||
| 		case KEY_ESC: | ||||
| 			return; | ||||
| @@ -967,8 +967,8 @@ static int handle_exit(void) | ||||
| 	dialog_clear(); | ||||
| 	if (conf_get_changed()) | ||||
| 		res = dialog_yesno(NULL, | ||||
| 				   _("Do you wish to save your new configuration?\n" | ||||
| 				     "(Press <ESC><ESC> to continue kernel configuration.)"), | ||||
| 				   "Do you wish to save your new configuration?\n" | ||||
| 				     "(Press <ESC><ESC> to continue kernel configuration.)", | ||||
| 				   6, 60); | ||||
| 	else | ||||
| 		res = -1; | ||||
| @@ -978,26 +978,27 @@ static int handle_exit(void) | ||||
| 	switch (res) { | ||||
| 	case 0: | ||||
| 		if (conf_write(filename)) { | ||||
| 			fprintf(stderr, _("\n\n" | ||||
| 			fprintf(stderr, "\n\n" | ||||
| 					  "Error while writing of the configuration.\n" | ||||
| 					  "Your configuration changes were NOT saved." | ||||
| 					  "\n\n")); | ||||
| 					  "\n\n"); | ||||
| 			return 1; | ||||
| 		} | ||||
| 		conf_write_autoconf(0); | ||||
| 		/* fall through */ | ||||
| 	case -1: | ||||
| 		if (!silent) | ||||
| 			printf(_("\n\n" | ||||
| 			printf("\n\n" | ||||
| 				 "*** End of the configuration.\n" | ||||
| 				 "*** Execute 'make' to start the build or try 'make help'." | ||||
| 				 "\n\n")); | ||||
| 				 "\n\n"); | ||||
| 		res = 0; | ||||
| 		break; | ||||
| 	default: | ||||
| 		if (!silent) | ||||
| 			fprintf(stderr, _("\n\n" | ||||
| 			fprintf(stderr, "\n\n" | ||||
| 					  "Your configuration changes were NOT saved." | ||||
| 					  "\n\n")); | ||||
| 					  "\n\n"); | ||||
| 		if (res != KEY_ESC) | ||||
| 			res = 0; | ||||
| 	} | ||||
| @@ -1015,10 +1016,6 @@ int main(int ac, char **av) | ||||
| 	char *mode; | ||||
| 	int res; | ||||
|  | ||||
| 	setlocale(LC_ALL, ""); | ||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); | ||||
| 	textdomain(PACKAGE); | ||||
|  | ||||
| 	signal(SIGINT, sig_handler); | ||||
|  | ||||
| 	if (ac > 1 && strcmp(av[1], "-s") == 0) { | ||||
| @@ -1037,8 +1034,8 @@ int main(int ac, char **av) | ||||
| 	} | ||||
|  | ||||
| 	if (init_dialog(NULL)) { | ||||
| 		fprintf(stderr, N_("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, "Your display is too small to run Menuconfig!\n"); | ||||
| 		fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #include <ctype.h> | ||||
| @@ -62,13 +62,8 @@ void menu_add_entry(struct symbol *sym) | ||||
| 		menu_add_symbol(P_SYMBOL, sym, NULL); | ||||
| } | ||||
|  | ||||
| void menu_end_entry(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| struct menu *menu_add_menu(void) | ||||
| { | ||||
| 	menu_end_entry(); | ||||
| 	last_entry_ptr = ¤t_entry->list; | ||||
| 	return current_menu = current_entry; | ||||
| } | ||||
| @@ -79,19 +74,23 @@ void menu_end_menu(void) | ||||
| 	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) | ||||
| 		return e; | ||||
|  | ||||
| 	switch (e->type) { | ||||
| 	case E_NOT: | ||||
| 		e->left.expr = menu_check_dep(e->left.expr); | ||||
| 		e->left.expr = rewrite_m(e->left.expr); | ||||
| 		break; | ||||
| 	case E_OR: | ||||
| 	case E_AND: | ||||
| 		e->left.expr = menu_check_dep(e->left.expr); | ||||
| 		e->right.expr = menu_check_dep(e->right.expr); | ||||
| 		e->left.expr = rewrite_m(e->left.expr); | ||||
| 		e->right.expr = rewrite_m(e->right.expr); | ||||
| 		break; | ||||
| 	case E_SYMBOL: | ||||
| 		/* change 'm' into 'm' && MODULES */ | ||||
| @@ -106,7 +105,7 @@ static struct expr *menu_check_dep(struct expr *e) | ||||
|  | ||||
| void menu_add_dep(struct expr *dep) | ||||
| { | ||||
| 	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) | ||||
| @@ -125,25 +124,49 @@ void menu_set_type(int 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) | ||||
| 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->expr = expr; | ||||
| 	prop->visible.expr = menu_check_dep(dep); | ||||
| 	prop->visible.expr = dep; | ||||
|  | ||||
| 	/* append property to the prop list of symbol */ | ||||
| 	if (current_entry->sym) { | ||||
| 		struct property **propp; | ||||
|  | ||||
| 		for (propp = ¤t_entry->sym->prop; | ||||
| 		     *propp; | ||||
| 		     propp = &(*propp)->next) | ||||
| 			; | ||||
| 		*propp = prop; | ||||
| 	} | ||||
|  | ||||
| 	return prop; | ||||
| } | ||||
|  | ||||
| struct property *menu_add_prompt(enum prop_type type, char *prompt, | ||||
| 				 struct expr *dep) | ||||
| { | ||||
| 	struct property *prop = menu_add_prop(type, NULL, dep); | ||||
|  | ||||
| 	if (prompt) { | ||||
| 	if (isspace(*prompt)) { | ||||
| 		prop_warn(prop, "leading whitespace ignored"); | ||||
| 		while (isspace(*prompt)) | ||||
| 			prompt++; | ||||
| 	} | ||||
| 		if (current_entry->prompt && current_entry != &rootmenu) | ||||
| 	if (current_entry->prompt) | ||||
| 		prop_warn(prop, "prompt redefined"); | ||||
|  | ||||
| 	/* Apply all upper menus' visibilities to actual prompts. */ | ||||
| 		if(type == P_PROMPT) { | ||||
| 	if (type == P_PROMPT) { | ||||
| 		struct menu *menu = current_entry; | ||||
|  | ||||
| 		while ((menu = menu->parent) != NULL) { | ||||
| @@ -152,34 +175,25 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e | ||||
| 			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. | ||||
| 			 * 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, | ||||
| 			prop->visible.expr = expr_alloc_and(prop->visible.expr, | ||||
| 							    dup_expr); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	current_entry->prompt = prop; | ||||
| 	} | ||||
| 	prop->text = prompt; | ||||
|  | ||||
| 	return prop; | ||||
| } | ||||
|  | ||||
| struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) | ||||
| { | ||||
| 	return menu_add_prop(type, prompt, NULL, dep); | ||||
| } | ||||
|  | ||||
| void menu_add_visibility(struct expr *expr) | ||||
| { | ||||
| 	current_entry->visibility = expr_alloc_and(current_entry->visibility, | ||||
| @@ -188,39 +202,34 @@ void menu_add_visibility(struct expr *expr) | ||||
|  | ||||
| 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) | ||||
| { | ||||
| 	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) | ||||
| void menu_add_option_modules(void) | ||||
| { | ||||
| 	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 | ||||
| 				    ); | ||||
| 		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: | ||||
| } | ||||
|  | ||||
| void menu_add_option_defconfig_list(void) | ||||
| { | ||||
| 	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: | ||||
| 	sym_defconfig_list->flags |= SYMBOL_NO_WRITE; | ||||
| } | ||||
|  | ||||
| void menu_add_option_allnoconfig_y(void) | ||||
| { | ||||
| 	current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int menu_validate_number(struct symbol *sym, struct symbol *sym2) | ||||
| @@ -233,6 +242,8 @@ static void sym_check_prop(struct symbol *sym) | ||||
| { | ||||
| 	struct property *prop; | ||||
| 	struct symbol *sym2; | ||||
| 	char *use; | ||||
|  | ||||
| 	for (prop = sym->prop; prop; prop = prop->next) { | ||||
| 		switch (prop->type) { | ||||
| 		case P_DEFAULT: | ||||
| @@ -250,20 +261,32 @@ static void sym_check_prop(struct symbol *sym) | ||||
| 					    "'%s': number is invalid", | ||||
| 					    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; | ||||
| 		case P_SELECT: | ||||
| 		case P_IMPLY: | ||||
| 			use = prop->type == P_SELECT ? "select" : "imply"; | ||||
| 			sym2 = prop_get_symbol(prop); | ||||
| 			if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) | ||||
| 				prop_warn(prop, | ||||
| 				    "config symbol '%s' uses select, but is " | ||||
| 				    "not boolean or tristate", sym->name); | ||||
| 				    "config symbol '%s' uses %s, but is " | ||||
| 				    "not bool or tristate", sym->name, use); | ||||
| 			else if (sym2->type != S_UNKNOWN && | ||||
| 				 sym2->type != S_BOOLEAN && | ||||
| 				 sym2->type != S_TRISTATE) | ||||
| 				prop_warn(prop, | ||||
| 				    "'%s' has wrong type. 'select' only " | ||||
| 				    "accept arguments of boolean and " | ||||
| 				    "tristate type", sym2->name); | ||||
| 				    "'%s' has wrong type. '%s' only " | ||||
| 				    "accept arguments of bool and " | ||||
| 				    "tristate type", sym2->name, use); | ||||
| 			break; | ||||
| 		case P_RANGE: | ||||
| 			if (sym->type != S_INT && sym->type != S_HEX) | ||||
| @@ -288,6 +311,11 @@ void menu_finalize(struct menu *parent) | ||||
|  | ||||
| 	sym = parent->sym; | ||||
| 	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->type == S_UNKNOWN) { | ||||
| 				/* find the first choice value to find out choice type */ | ||||
| @@ -305,65 +333,167 @@ void menu_finalize(struct menu *parent) | ||||
| 				if (menu->sym && menu->sym->type == S_UNKNOWN) | ||||
| 					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) { | ||||
| 			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_eliminate_dups(basedep); | ||||
| 			menu->dep = basedep; | ||||
|  | ||||
| 			if (menu->sym) | ||||
| 				/* | ||||
| 				 * Note: For symbols, all prompts are included | ||||
| 				 * too in the symbol's own property list | ||||
| 				 */ | ||||
| 				prop = menu->sym->prop; | ||||
| 			else | ||||
| 				/* | ||||
| 				 * For non-symbol menu nodes, we just need to | ||||
| 				 * handle the prompt | ||||
| 				 */ | ||||
| 				prop = menu->prompt; | ||||
|  | ||||
| 			/* For each property... */ | ||||
| 			for (; prop; prop = prop->next) { | ||||
| 				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; | ||||
| 				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_eliminate_dups(dep); | ||||
| 				if (menu->sym && menu->sym->type != S_TRISTATE) | ||||
| 					dep = expr_trans_bool(dep); | ||||
| 				prop->visible.expr = dep; | ||||
|  | ||||
| 				/* | ||||
| 				 * Handle selects and implies, which modify the | ||||
| 				 * dependencies of the selected/implied symbol | ||||
| 				 */ | ||||
| 				if (prop->type == P_SELECT) { | ||||
| 					struct symbol *es = prop_get_symbol(prop); | ||||
| 					es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, | ||||
| 							expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); | ||||
| 				} 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) | ||||
| 			menu_finalize(menu); | ||||
| 	} 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 = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); | ||||
| 		basedep = expr_eliminate_dups(expr_transform(basedep)); | ||||
|  | ||||
| 		/* Examine consecutive elements after sym */ | ||||
| 		last_menu = NULL; | ||||
| 		for (menu = parent->next; menu; menu = menu->next) { | ||||
| 			dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; | ||||
| 			if (!expr_contains_symbol(dep, sym)) | ||||
| 				/* No dependency, quit */ | ||||
| 				break; | ||||
| 			if (expr_depends_symbol(dep, sym)) | ||||
| 				/* Absolute dependency, put in submenu */ | ||||
| 				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_eliminate_dups(expr_transform(dep)); | ||||
| 			dep2 = expr_copy(basedep); | ||||
| 			expr_eliminate_eq(&dep, &dep2); | ||||
| 			expr_free(dep); | ||||
| 			if (!expr_is_yes(dep2)) { | ||||
| 				/* Not superset, quit */ | ||||
| 				expr_free(dep2); | ||||
| 				break; | ||||
| 			} | ||||
| 			/* Superset, put in submenu */ | ||||
| 			expr_free(dep2); | ||||
| 		next: | ||||
| 			menu_finalize(menu); | ||||
| 			menu->parent = parent; | ||||
| 			last_menu = menu; | ||||
| 		} | ||||
| 		expr_free(basedep); | ||||
| 		if (last_menu) { | ||||
| 			parent->list = parent->next; | ||||
| 			parent->next = last_menu->next; | ||||
| @@ -412,6 +542,35 @@ void menu_finalize(struct menu *parent) | ||||
| 			*ep = expr_alloc_one(E_LIST, NULL); | ||||
| 			(*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)) { | ||||
| 			for (last_menu = menu->list; ; last_menu = last_menu->next) { | ||||
| 				last_menu->parent = parent; | ||||
| @@ -436,6 +595,15 @@ void menu_finalize(struct menu *parent) | ||||
| 		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) { | ||||
| 		sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, | ||||
| 				expr_alloc_and(parent->prompt->visible.expr, | ||||
| @@ -543,6 +711,21 @@ const char *menu_get_help(struct menu *menu) | ||||
| 		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, | ||||
| 			   struct list_head *head) | ||||
| { | ||||
| @@ -550,7 +733,20 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | ||||
| 	struct menu *submenu[8], *menu, *location = 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; | ||||
| 	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { | ||||
| 		bool accessible = menu_is_visible(menu); | ||||
| @@ -583,16 +779,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | ||||
| 	} | ||||
|  | ||||
| 	if (i > 0) { | ||||
| 		str_printf(r, _("  Location:\n")); | ||||
| 		str_printf(r, "  Location:\n"); | ||||
| 		for (j = 4; --i >= 0; j += 2) { | ||||
| 			menu = submenu[i]; | ||||
| 			if (jump && menu == location) | ||||
| 				jump->offset = strlen(r->s); | ||||
| 			str_printf(r, "%*c-> %s", j, ' ', | ||||
| 				   _(menu_get_prompt(menu))); | ||||
| 				   menu_get_prompt(menu)); | ||||
| 			if (menu->sym) { | ||||
| 				str_printf(r, " (%s [=%s])", menu->sym->name ? | ||||
| 					menu->sym->name : _("<choice>"), | ||||
| 					menu->sym->name : "<choice>", | ||||
| 					sym_get_string_value(menu->sym)); | ||||
| 			} | ||||
| 			str_append(r, "\n"); | ||||
| @@ -600,16 +796,22 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * get property of type P_SYMBOL | ||||
|  */ | ||||
| static struct property *get_symbol_prop(struct symbol *sym) | ||||
| static void get_symbol_props_str(struct gstr *r, struct symbol *sym, | ||||
| 				 enum prop_type tok, const char *prefix) | ||||
| { | ||||
| 	struct property *prop = NULL; | ||||
| 	bool hit = false; | ||||
| 	struct property *prop; | ||||
|  | ||||
| 	for_all_properties(sym, prop, P_SYMBOL) | ||||
| 		break; | ||||
| 	return prop; | ||||
| 	for_all_properties(sym, prop, tok) { | ||||
| 		if (!hit) { | ||||
| 			str_append(r, prefix); | ||||
| 			hit = true; | ||||
| 		} else | ||||
| 			str_printf(r, " && "); | ||||
| 		expr_gstr_print(prop->expr, r); | ||||
| 	} | ||||
| 	if (hit) | ||||
| 		str_append(r, "\n"); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -618,7 +820,6 @@ static struct property *get_symbol_prop(struct symbol *sym) | ||||
| static void get_symbol_str(struct gstr *r, struct symbol *sym, | ||||
| 		    struct list_head *head) | ||||
| { | ||||
| 	bool hit; | ||||
| 	struct property *prop; | ||||
|  | ||||
| 	if (sym && sym->name) { | ||||
| @@ -634,36 +835,36 @@ static 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); | ||||
| 	if (prop) { | ||||
| 		str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name, | ||||
| 			prop->menu->lineno); | ||||
| 		if (!expr_is_yes(prop->visible.expr)) { | ||||
| 			str_append(r, _("  Depends on: ")); | ||||
| 			expr_gstr_print(prop->visible.expr, r); | ||||
| 			str_append(r, "\n"); | ||||
| 	/* Print the definitions with prompts before the ones without */ | ||||
| 	for_all_properties(sym, prop, P_SYMBOL) { | ||||
| 		if (prop->menu->prompt) { | ||||
| 			get_def_str(r, prop->menu); | ||||
| 			get_prompt_str(r, prop->menu->prompt, head); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	hit = false; | ||||
| 	for_all_properties(sym, prop, P_SELECT) { | ||||
| 		if (!hit) { | ||||
| 			str_append(r, "  Selects: "); | ||||
| 			hit = true; | ||||
| 		} else | ||||
| 			str_printf(r, " && "); | ||||
| 		expr_gstr_print(prop->expr, r); | ||||
| 	for_all_properties(sym, prop, P_SYMBOL) { | ||||
| 		if (!prop->menu->prompt) { | ||||
| 			get_def_str(r, prop->menu); | ||||
| 			get_dep_str(r, prop->menu->dep, "  Depends on: "); | ||||
| 		} | ||||
| 	if (hit) | ||||
| 		str_append(r, "\n"); | ||||
| 	} | ||||
|  | ||||
| 	get_symbol_props_str(r, sym, P_SELECT, "Selects: "); | ||||
| 	if (sym->rev_dep.expr) { | ||||
| 		str_append(r, _("  Selected by: ")); | ||||
| 		expr_gstr_print(sym->rev_dep.expr, r); | ||||
| 		str_append(r, "\n"); | ||||
| 		expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n"); | ||||
| 		expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\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"); | ||||
| } | ||||
|  | ||||
| @@ -676,7 +877,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) | ||||
| 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++) | ||||
| 		get_symbol_str(&res, sym, head); | ||||
| 	if (!i) | ||||
| 		str_append(&res, _("No matches found.\n")); | ||||
| 		str_append(&res, "No matches found.\n"); | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| @@ -691,7 +892,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help) | ||||
| 			str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); | ||||
| 		help_text = menu_get_help(menu); | ||||
| 	} | ||||
| 	str_printf(help, "%s\n", _(help_text)); | ||||
| 	str_printf(help, "%s\n", help_text); | ||||
| 	if (sym) | ||||
| 		get_symbol_str(help, sym, NULL); | ||||
| } | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										129
									
								
								scripts/config/parser.tab.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								scripts/config/parser.tab.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| /* A Bison parser, made by GNU Bison 3.1.  */ | ||||
|  | ||||
| /* Bison interface for Yacc-like parsers in C | ||||
|  | ||||
|    Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. | ||||
|  | ||||
|    This program is free software: you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation, either version 3 of the License, or | ||||
|    (at your option) any later version. | ||||
|  | ||||
|    This program is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|    GNU General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | ||||
|  | ||||
| /* As a special exception, you may create a larger work that contains | ||||
|    part or all of the Bison parser skeleton and distribute that work | ||||
|    under terms of your choice, so long as that work isn't itself a | ||||
|    parser generator using the skeleton or a modified version thereof | ||||
|    as a parser skeleton.  Alternatively, if you modify or redistribute | ||||
|    the parser skeleton itself, you may (at your option) remove this | ||||
|    special exception, which will cause the skeleton and the resulting | ||||
|    Bison output files to be licensed under the GNU General Public | ||||
|    License without this special exception. | ||||
|  | ||||
|    This special exception was added by the Free Software Foundation in | ||||
|    version 2.2 of Bison.  */ | ||||
|  | ||||
| #ifndef YY_YY_PARSER_TAB_H_INCLUDED | ||||
| # define YY_YY_PARSER_TAB_H_INCLUDED | ||||
| /* Debug traces.  */ | ||||
| #ifndef YYDEBUG | ||||
| # define YYDEBUG 0 | ||||
| #endif | ||||
| #if YYDEBUG | ||||
| extern int yydebug; | ||||
| #endif | ||||
|  | ||||
| /* Token type.  */ | ||||
| #ifndef YYTOKENTYPE | ||||
| # define YYTOKENTYPE | ||||
|   enum yytokentype | ||||
|   { | ||||
|     T_HELPTEXT = 258, | ||||
|     T_WORD = 259, | ||||
|     T_WORD_QUOTE = 260, | ||||
|     T_ALLNOCONFIG_Y = 261, | ||||
|     T_BOOL = 262, | ||||
|     T_CHOICE = 263, | ||||
|     T_CLOSE_PAREN = 264, | ||||
|     T_COLON_EQUAL = 265, | ||||
|     T_COMMENT = 266, | ||||
|     T_CONFIG = 267, | ||||
|     T_DEFAULT = 268, | ||||
|     T_DEFCONFIG_LIST = 269, | ||||
|     T_DEF_BOOL = 270, | ||||
|     T_DEF_TRISTATE = 271, | ||||
|     T_DEPENDS = 272, | ||||
|     T_ENDCHOICE = 273, | ||||
|     T_ENDIF = 274, | ||||
|     T_ENDMENU = 275, | ||||
|     T_HELP = 276, | ||||
|     T_HEX = 277, | ||||
|     T_IF = 278, | ||||
|     T_IMPLY = 279, | ||||
|     T_INT = 280, | ||||
|     T_MAINMENU = 281, | ||||
|     T_MENU = 282, | ||||
|     T_MENUCONFIG = 283, | ||||
|     T_MODULES = 284, | ||||
|     T_ON = 285, | ||||
|     T_OPEN_PAREN = 286, | ||||
|     T_OPTION = 287, | ||||
|     T_OPTIONAL = 288, | ||||
|     T_PLUS_EQUAL = 289, | ||||
|     T_PROMPT = 290, | ||||
|     T_RANGE = 291, | ||||
|     T_RESET = 292, | ||||
|     T_SELECT = 293, | ||||
|     T_SOURCE = 294, | ||||
|     T_STRING = 295, | ||||
|     T_TRISTATE = 296, | ||||
|     T_VISIBLE = 297, | ||||
|     T_EOL = 298, | ||||
|     T_ASSIGN_VAL = 299, | ||||
|     T_OR = 300, | ||||
|     T_AND = 301, | ||||
|     T_EQUAL = 302, | ||||
|     T_UNEQUAL = 303, | ||||
|     T_LESS = 304, | ||||
|     T_LESS_EQUAL = 305, | ||||
|     T_GREATER = 306, | ||||
|     T_GREATER_EQUAL = 307, | ||||
|     T_NOT = 308 | ||||
|   }; | ||||
| #endif | ||||
|  | ||||
| /* Value type.  */ | ||||
| #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED | ||||
|  | ||||
| union YYSTYPE | ||||
| { | ||||
|  | ||||
|  | ||||
| 	char *string; | ||||
| 	struct symbol *symbol; | ||||
| 	struct expr *expr; | ||||
| 	struct menu *menu; | ||||
| 	enum symbol_type type; | ||||
| 	enum variable_flavor flavor; | ||||
|  | ||||
|  | ||||
| }; | ||||
|  | ||||
| typedef union YYSTYPE YYSTYPE; | ||||
| # define YYSTYPE_IS_TRIVIAL 1 | ||||
| # define YYSTYPE_IS_DECLARED 1 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| extern YYSTYPE yylval; | ||||
|  | ||||
| int yyparse (void); | ||||
|  | ||||
| #endif /* !YY_YY_PARSER_TAB_H_INCLUDED  */ | ||||
| @@ -1,8 +1,8 @@ | ||||
| %{ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
| %{ | ||||
| 
 | ||||
| #include <ctype.h> | ||||
| #include <stdarg.h> | ||||
| @@ -20,63 +20,70 @@ | ||||
| 
 | ||||
| int cdebug = PRINTD; | ||||
| 
 | ||||
| extern int zconflex(void); | ||||
| static void yyerror(const char *err); | ||||
| static void zconfprint(const char *err, ...); | ||||
| static void zconf_error(const char *err, ...); | ||||
| static void zconferror(const char *err); | ||||
| static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); | ||||
| static bool zconf_endtoken(const char *tokenname, | ||||
| 			   const char *expected_tokenname); | ||||
| 
 | ||||
| struct symbol *symbol_hash[SYMBOL_HASHSIZE]; | ||||
| 
 | ||||
| static struct menu *current_menu, *current_entry; | ||||
| 
 | ||||
| %} | ||||
| %expect 30 | ||||
| 
 | ||||
| %union | ||||
| { | ||||
| 	char *string; | ||||
| 	struct file *file; | ||||
| 	struct symbol *symbol; | ||||
| 	struct expr *expr; | ||||
| 	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 <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 <id>T_RESET | ||||
| %token <string> T_WORD | ||||
| %token <string> T_WORD_QUOTE | ||||
| %token T_UNEQUAL | ||||
| %token T_LESS | ||||
| %token T_LESS_EQUAL | ||||
| %token T_GREATER | ||||
| %token T_GREATER_EQUAL | ||||
| %token T_ALLNOCONFIG_Y | ||||
| %token T_BOOL | ||||
| %token T_CHOICE | ||||
| %token T_CLOSE_PAREN | ||||
| %token T_COLON_EQUAL | ||||
| %token T_COMMENT | ||||
| %token T_CONFIG | ||||
| %token T_DEFAULT | ||||
| %token T_DEFCONFIG_LIST | ||||
| %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_OPTION | ||||
| %token T_OPTIONAL | ||||
| %token T_PLUS_EQUAL | ||||
| %token T_PROMPT | ||||
| %token T_RANGE | ||||
| %token T_RESET | ||||
| %token T_SELECT | ||||
| %token T_SOURCE | ||||
| %token T_STRING | ||||
| %token T_TRISTATE | ||||
| %token T_VISIBLE | ||||
| %token T_EOL | ||||
| %token <string> T_ASSIGN_VAL | ||||
| 
 | ||||
| %left T_OR | ||||
| %left T_AND | ||||
| @@ -84,14 +91,15 @@ static struct menu *current_menu, *current_entry; | ||||
| %left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL | ||||
| %nonassoc T_NOT | ||||
| 
 | ||||
| %type <string> prompt | ||||
| %type <symbol> nonconst_symbol | ||||
| %type <symbol> symbol | ||||
| %type <type> type logic_type default | ||||
| %type <expr> expr | ||||
| %type <expr> if_expr | ||||
| %type <id> end | ||||
| %type <id> option_name | ||||
| %type <string> end | ||||
| %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 { | ||||
| 	fprintf(stderr, "%s:%d: missing end statement for this entry\n", | ||||
| @@ -100,71 +108,53 @@ static struct menu *current_menu, *current_entry; | ||||
| 		menu_end_menu(); | ||||
| } if_entry menu_entry choice_entry | ||||
| 
 | ||||
| %{ | ||||
| /* Include zconf.hash.c here so it can see the token constants. */ | ||||
| #include "zconf.hash.c" | ||||
| %} | ||||
| 
 | ||||
| %% | ||||
| input: 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: | ||||
| 	  /* empty */ | ||||
| 	| stmt_list common_stmt | ||||
| 	| stmt_list choice_stmt | ||||
| 	| stmt_list menu_stmt | ||||
| 	| stmt_list end			{ zconf_error("unexpected end statement"); } | ||||
| 	| 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"); } | ||||
| ; | ||||
| 
 | ||||
| option_name: | ||||
| 	T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE | T_RESET | ||||
| ; | ||||
| 
 | ||||
| common_stmt: | ||||
| 	  T_EOL | ||||
| 	| if_stmt | ||||
| 	  if_stmt | ||||
| 	| comment_stmt | ||||
| 	| config_stmt | ||||
| 	| menuconfig_stmt | ||||
| 	| source_stmt | ||||
| 	| assignment_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_entry_start: T_CONFIG T_WORD T_EOL | ||||
| config_entry_start: T_CONFIG nonconst_symbol T_EOL | ||||
| { | ||||
| 	struct symbol *sym = sym_lookup($2, 0); | ||||
| 	sym->flags |= SYMBOL_OPTIONAL; | ||||
| 	menu_add_entry(sym); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); | ||||
| 	$2->flags |= SYMBOL_OPTIONAL; | ||||
| 	menu_add_entry($2); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name); | ||||
| }; | ||||
| 
 | ||||
| config_stmt: config_entry_start config_option_list | ||||
| { | ||||
| 	menu_end_entry(); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); | ||||
| }; | ||||
| 
 | ||||
| menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL | ||||
| menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL | ||||
| { | ||||
| 	struct symbol *sym = sym_lookup($2, 0); | ||||
| 	sym->flags |= SYMBOL_OPTIONAL; | ||||
| 	menu_add_entry(sym); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); | ||||
| 	$2->flags |= SYMBOL_OPTIONAL; | ||||
| 	menu_add_entry($2); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name); | ||||
| }; | ||||
| 
 | ||||
| menuconfig_stmt: menuconfig_entry_start config_option_list | ||||
| @@ -173,84 +163,82 @@ menuconfig_stmt: menuconfig_entry_start config_option_list | ||||
| 		current_entry->prompt->type = P_MENU; | ||||
| 	else | ||||
| 		zconfprint("warning: menuconfig statement without prompt"); | ||||
| 	menu_end_entry(); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); | ||||
| }; | ||||
| 
 | ||||
| config_option_list: | ||||
| 	  /* empty */ | ||||
| 	| config_option_list config_option | ||||
| 	| config_option_list symbol_option | ||||
| 	| config_option_list depends | ||||
| 	| 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", | ||||
| 		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); | ||||
| 	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); | ||||
| 	if ($1->stype != S_UNKNOWN) | ||||
| 		menu_set_type($1->stype); | ||||
| 	if ($1 != S_UNKNOWN) | ||||
| 		menu_set_type($1); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:default(%u)\n", | ||||
| 		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()); | ||||
| }; | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
| 	menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); | ||||
| }; | ||||
| 
 | ||||
| symbol_option: T_OPTION symbol_option_list T_EOL | ||||
| ; | ||||
| 
 | ||||
| symbol_option_list: | ||||
| 	  /* empty */ | ||||
| 	| symbol_option_list T_WORD symbol_option_arg | ||||
| config_option: T_OPTION T_MODULES T_EOL | ||||
| { | ||||
| 	const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); | ||||
| 	if (id && id->flags & TF_OPTION) | ||||
| 		menu_add_option(id->token, $3); | ||||
| 	else | ||||
| 		zconfprint("warning: ignoring unknown option %s", $2); | ||||
| 	free($2); | ||||
| 	menu_add_option_modules(); | ||||
| }; | ||||
| 
 | ||||
| symbol_option_arg: | ||||
| 	  /* empty */		{ $$ = NULL; } | ||||
| 	| T_EQUAL prompt	{ $$ = $2; } | ||||
| ; | ||||
| config_option: T_OPTION T_DEFCONFIG_LIST T_EOL | ||||
| { | ||||
| 	menu_add_option_defconfig_list(); | ||||
| }; | ||||
| 
 | ||||
| config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL | ||||
| { | ||||
| 	menu_add_option_allnoconfig_y(); | ||||
| }; | ||||
| 
 | ||||
| /* choice entry */ | ||||
| 
 | ||||
| choice: T_CHOICE word_opt T_EOL | ||||
| { | ||||
| 	struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); | ||||
| 	sym->flags |= SYMBOL_AUTO; | ||||
| 	sym->flags |= SYMBOL_NO_WRITE; | ||||
| 	menu_add_entry(sym); | ||||
| 	menu_add_expr(P_CHOICE, NULL, NULL); | ||||
| 	free($2); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); | ||||
| }; | ||||
| 
 | ||||
| @@ -261,7 +249,7 @@ choice_entry: choice choice_option_list | ||||
| 
 | ||||
| choice_end: end | ||||
| { | ||||
| 	if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { | ||||
| 	if (zconf_endtoken($1, "choice")) { | ||||
| 		menu_end_menu(); | ||||
| 		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); | ||||
| 	} | ||||
| @@ -275,25 +263,19 @@ choice_option_list: | ||||
| 	| choice_option_list choice_option | ||||
| 	| choice_option_list depends | ||||
| 	| 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); | ||||
| 	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->stype); | ||||
| 	menu_set_type($1); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:type(%u)\n", | ||||
| 			zconf_curname(), zconf_lineno(), | ||||
| 			$1->stype); | ||||
| 	} else | ||||
| 		YYERROR; | ||||
| 	       zconf_curname(), zconf_lineno(), $1); | ||||
| }; | ||||
| 
 | ||||
| choice_option: T_OPTIONAL T_EOL | ||||
| @@ -304,19 +286,31 @@ choice_option: T_OPTIONAL T_EOL | ||||
| 
 | ||||
| choice_option: T_RESET if_expr T_EOL | ||||
| { | ||||
| 	menu_add_prop(P_RESET, NULL, NULL, $2); | ||||
| 	menu_add_prop(P_RESET, NULL, $2); | ||||
| }; | ||||
| 
 | ||||
| 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, sym_lookup($2, 0), $3); | ||||
| 	menu_add_symbol(P_DEFAULT, $2, $3); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:default\n", | ||||
| 	       zconf_curname(), zconf_lineno()); | ||||
| 	} else | ||||
| 		YYERROR; | ||||
| }; | ||||
| 
 | ||||
| type: | ||||
| 	  logic_type | ||||
| 	| 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; } | ||||
| 
 | ||||
| choice_block: | ||||
| 	  /* empty */ | ||||
| 	| choice_block common_stmt | ||||
| @@ -324,7 +318,7 @@ choice_block: | ||||
| 
 | ||||
| /* 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()); | ||||
| 	menu_add_entry(NULL); | ||||
| @@ -334,80 +328,69 @@ if_entry: T_IF expr nl | ||||
| 
 | ||||
| if_end: end | ||||
| { | ||||
| 	if (zconf_endtoken($1, T_IF, T_ENDIF)) { | ||||
| 	if (zconf_endtoken($1, "if")) { | ||||
| 		menu_end_menu(); | ||||
| 		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: | ||||
| 	  /* 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: T_MENU prompt T_EOL | ||||
| menu: T_MENU T_WORD_QUOTE T_EOL | ||||
| { | ||||
| 	menu_add_entry(NULL); | ||||
| 	menu_add_prompt(P_MENU, $2, NULL); | ||||
| 	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_end: end | ||||
| { | ||||
| 	if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { | ||||
| 	if (zconf_endtoken($1, "menu")) { | ||||
| 		menu_end_menu(); | ||||
| 		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 */ | ||||
| 	| menu_block common_stmt | ||||
| 	| menu_block menu_stmt | ||||
| 	| menu_block choice_stmt | ||||
| 	| menu_option_list visible | ||||
| 	| menu_option_list depends | ||||
| ; | ||||
| 
 | ||||
| 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); | ||||
| 	zconf_nextfile($2); | ||||
| 	free($2); | ||||
| }; | ||||
| 
 | ||||
| /* comment entry */ | ||||
| 
 | ||||
| comment: T_COMMENT prompt T_EOL | ||||
| comment: T_COMMENT T_WORD_QUOTE T_EOL | ||||
| { | ||||
| 	menu_add_entry(NULL); | ||||
| 	menu_add_prompt(P_COMMENT, $2, NULL); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); | ||||
| }; | ||||
| 
 | ||||
| comment_stmt: comment depends_list | ||||
| { | ||||
| 	menu_end_entry(); | ||||
| }; | ||||
| comment_stmt: comment comment_option_list | ||||
| ; | ||||
| 
 | ||||
| comment_option_list: | ||||
| 	  /* empty */ | ||||
| 	| comment_option_list depends | ||||
| ; | ||||
| 
 | ||||
| /* help option */ | ||||
| 
 | ||||
| @@ -419,37 +402,24 @@ help_start: T_HELP T_EOL | ||||
| 
 | ||||
| help: help_start T_HELPTEXT | ||||
| { | ||||
| 	/* 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; | ||||
| }; | ||||
| 
 | ||||
| /* depends option */ | ||||
| 
 | ||||
| depends_list: | ||||
| 	  /* empty */ | ||||
| 	| depends_list depends | ||||
| 	| depends_list T_EOL | ||||
| 	| depends_list option_error | ||||
| ; | ||||
| 
 | ||||
| depends: T_DEPENDS T_ON expr T_EOL | ||||
| { | ||||
| 	menu_add_dep($3); | ||||
| 	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); | ||||
| } | T_DEPENDS expr T_EOL | ||||
| { | ||||
| 	menu_add_dep($2); | ||||
| 	zconfprint("warning: deprecated 'depends' syntax, use 'depends on' instead."); | ||||
| }; | ||||
| 
 | ||||
| /* visibility option */ | ||||
| 
 | ||||
| visibility_list: | ||||
| 	  /* empty */ | ||||
| 	| visibility_list visible | ||||
| 	| visibility_list T_EOL | ||||
| ; | ||||
| 
 | ||||
| visible: T_VISIBLE if_expr | ||||
| visible: T_VISIBLE if_expr T_EOL | ||||
| { | ||||
| 	menu_add_visibility($2); | ||||
| }; | ||||
| @@ -458,23 +428,14 @@ visible: T_VISIBLE if_expr | ||||
| 
 | ||||
| prompt_stmt_opt: | ||||
| 	  /* empty */ | ||||
| 	| prompt if_expr | ||||
| 	| T_WORD_QUOTE if_expr | ||||
| { | ||||
| 	menu_add_prompt(P_PROMPT, $1, $2); | ||||
| }; | ||||
| 
 | ||||
| prompt:	  T_WORD | ||||
| 	| T_WORD_QUOTE | ||||
| ; | ||||
| 
 | ||||
| end:	  T_ENDMENU T_EOL	{ $$ = $1; } | ||||
| 	| T_ENDCHOICE T_EOL	{ $$ = $1; } | ||||
| 	| T_ENDIF T_EOL		{ $$ = $1; } | ||||
| ; | ||||
| 
 | ||||
| nl: | ||||
| 	  T_EOL | ||||
| 	| nl T_EOL | ||||
| end:	  T_ENDMENU T_EOL	{ $$ = "menu"; } | ||||
| 	| T_ENDCHOICE T_EOL	{ $$ = "choice"; } | ||||
| 	| T_ENDIF T_EOL		{ $$ = "if"; } | ||||
| ; | ||||
| 
 | ||||
| if_expr:  /* empty */			{ $$ = NULL; } | ||||
| @@ -494,13 +455,31 @@ expr:	  symbol				{ $$ = expr_alloc_symbol($1); } | ||||
| 	| 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); } | ||||
| ; | ||||
| 
 | ||||
| word_opt: /* empty */			{ $$ = NULL; } | ||||
| 	| 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) | ||||
| @@ -510,63 +489,53 @@ void conf_parse(const char *name) | ||||
| 
 | ||||
| 	zconf_initscan(name); | ||||
| 
 | ||||
| 	sym_init(); | ||||
| 	_menu_init(); | ||||
| 	rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); | ||||
| 
 | ||||
| #if YYDEBUG | ||||
| 	if (getenv("ZCONF_DEBUG")) | ||||
| 		zconfdebug = 1; | ||||
| 		yydebug = 1; | ||||
| #endif | ||||
| 	zconfparse(); | ||||
| 	if (zconfnerrs) | ||||
| 	yyparse(); | ||||
| 
 | ||||
| 	/* Variables are expanded in the parse phase. We can free them here. */ | ||||
| 	variable_all_del(); | ||||
| 
 | ||||
| 	if (yynerrs) | ||||
| 		exit(1); | ||||
| 	if (!modules_sym) | ||||
| 		modules_sym = sym_find( "n" ); | ||||
| 
 | ||||
| 	rootmenu.prompt->text = _(rootmenu.prompt->text); | ||||
| 	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); | ||||
| 	if (!menu_has_prompt(&rootmenu)) { | ||||
| 		current_entry = &rootmenu; | ||||
| 		menu_add_prompt(P_MENU, "Main menu", NULL); | ||||
| 	} | ||||
| 
 | ||||
| 	menu_finalize(&rootmenu); | ||||
| 	for_all_symbols(i, sym) { | ||||
| 		if (sym_check_deps(sym)) | ||||
| 			zconfnerrs++; | ||||
| 			yynerrs++; | ||||
| 	} | ||||
| 	if (zconfnerrs) | ||||
| 	if (yynerrs) | ||||
| 		exit(1); | ||||
| 	sym_set_change_count(1); | ||||
| } | ||||
| 
 | ||||
| static const char *zconf_tokenname(int token) | ||||
| static bool zconf_endtoken(const char *tokenname, | ||||
| 			   const char *expected_tokenname) | ||||
| { | ||||
| 	switch (token) { | ||||
| 	case T_MENU:		return "menu"; | ||||
| 	case T_ENDMENU:		return "endmenu"; | ||||
| 	case T_CHOICE:		return "choice"; | ||||
| 	case T_ENDCHOICE:	return "endchoice"; | ||||
| 	case T_IF:		return "if"; | ||||
| 	case T_ENDIF:		return "endif"; | ||||
| 	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) { | ||||
| 	if (strcmp(tokenname, expected_tokenname)) { | ||||
| 		zconf_error("unexpected '%s' within %s block", | ||||
| 			kconf_id_strings + id->name, zconf_tokenname(starttoken)); | ||||
| 		zconfnerrs++; | ||||
| 			    tokenname, expected_tokenname); | ||||
| 		yynerrs++; | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (current_menu->file != current_file) { | ||||
| 		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", | ||||
| 			current_menu->file->name, current_menu->lineno, | ||||
| 			zconf_tokenname(starttoken)); | ||||
| 		zconfnerrs++; | ||||
| 			expected_tokenname); | ||||
| 		yynerrs++; | ||||
| 		return false; | ||||
| 	} | ||||
| 	return true; | ||||
| @@ -587,7 +556,7 @@ static void zconf_error(const char *err, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
| 	zconfnerrs++; | ||||
| 	yynerrs++; | ||||
| 	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); | ||||
| 	va_start(ap, err); | ||||
| 	vfprintf(stderr, err, ap); | ||||
| @@ -595,7 +564,7 @@ static void zconf_error(const char *err, ...) | ||||
| 	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); | ||||
| } | ||||
| @@ -628,7 +597,7 @@ static void print_symbol(FILE *out, struct menu *menu) | ||||
| 		fprintf(out, "\nconfig %s\n", sym->name); | ||||
| 	switch (sym->type) { | ||||
| 	case S_BOOLEAN: | ||||
| 		fputs("  boolean\n", out); | ||||
| 		fputs("  bool\n", out); | ||||
| 		break; | ||||
| 	case S_TRISTATE: | ||||
| 		fputs("  tristate\n", out); | ||||
| @@ -676,6 +645,11 @@ static void print_symbol(FILE *out, struct menu *menu) | ||||
| 			expr_fprint(prop->expr, out); | ||||
| 			fputc('\n', out); | ||||
| 			break; | ||||
| 		case P_IMPLY: | ||||
| 			fputs( "  imply ", out); | ||||
| 			expr_fprint(prop->expr, out); | ||||
| 			fputc('\n', out); | ||||
| 			break; | ||||
| 		case P_RANGE: | ||||
| 			fputs( "  range ", out); | ||||
| 			expr_fprint(prop->expr, out); | ||||
| @@ -686,6 +660,10 @@ static void print_symbol(FILE *out, struct menu *menu) | ||||
| 			print_quoted_string(out, prop->text); | ||||
| 			fputc('\n', out); | ||||
| 			break; | ||||
| 		case P_SYMBOL: | ||||
| 			fputs( "  symbol ", out); | ||||
| 			fprintf(out, "%s\n", prop->menu->sym->name); | ||||
| 			break; | ||||
| 		default: | ||||
| 			fprintf(out, "  unknown prop %d!\n", prop->type); | ||||
| 			break; | ||||
| @@ -746,9 +724,4 @@ void zconfdump(FILE *out) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #include "zconf.lex.c" | ||||
| #include "util.c" | ||||
| #include "confdata.c" | ||||
| #include "expr.c" | ||||
| #include "symbol.c" | ||||
| #include "menu.c" | ||||
							
								
								
									
										575
									
								
								scripts/config/preprocess.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										575
									
								
								scripts/config/preprocess.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,575 @@ | ||||
| // 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 NULL; | ||||
| } | ||||
|  | ||||
| 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) | ||||
| { | ||||
| 	/* Why are '.' and '/' valid characters for symbols? */ | ||||
| 	return !(isalnum(c) || c == '_' || 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); | ||||
| } | ||||
							
								
								
									
										32
									
								
								scripts/config/qconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										32
									
								
								scripts/config/qconf-cfg.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #!/bin/sh | ||||
| # SPDX-License-Identifier: GPL-2.0 | ||||
|  | ||||
| PKG="Qt5Core Qt5Gui Qt5Widgets" | ||||
| PKG2="QtCore QtGui" | ||||
|  | ||||
| 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 Qt5Core Qt5Gui Qt5Widgets)\" | ||||
| 	echo libs=\"$(pkg-config --libs $PKG)\" | ||||
| 	echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" | ||||
| 	exit 0 | ||||
| fi | ||||
|  | ||||
| if pkg-config --exists $PKG2; then | ||||
| 	echo cflags=\"$(pkg-config --cflags $PKG2)\" | ||||
| 	echo libs=\"$(pkg-config --libs $PKG2)\" | ||||
| 	echo moc=\"$(pkg-config --variable=moc_location QtCore)\" | ||||
| 	exit 0 | ||||
| fi | ||||
|  | ||||
| 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 | ||||
| @@ -1,7 +1,7 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #include <qglobal.h> | ||||
| @@ -32,12 +32,8 @@ | ||||
| #include "qconf.h" | ||||
|  | ||||
| #include "qconf.moc" | ||||
| #include "images.c" | ||||
| #include "images.h" | ||||
|  | ||||
| #ifdef _ | ||||
| # undef _ | ||||
| # define _ qgettext | ||||
| #endif | ||||
|  | ||||
| static QApplication *configApp; | ||||
| static ConfigSettings *configSettings; | ||||
| @@ -46,12 +42,7 @@ QAction *ConfigMainWindow::saveAction; | ||||
|  | ||||
| static inline QString qgettext(const char* str) | ||||
| { | ||||
| 	return QString::fromLocal8Bit(gettext(str)); | ||||
| } | ||||
|  | ||||
| static inline QString qgettext(const QString& str) | ||||
| { | ||||
| 	return QString::fromLocal8Bit(gettext(str.toLatin1())); | ||||
| 	return QString::fromLocal8Bit(str); | ||||
| } | ||||
|  | ||||
| ConfigSettings::ConfigSettings() | ||||
| @@ -65,12 +56,20 @@ ConfigSettings::ConfigSettings() | ||||
| QList<int> ConfigSettings::readSizes(const QString& key, bool *ok) | ||||
| { | ||||
| 	QList<int> result; | ||||
|  | ||||
| 	if (contains(key)) | ||||
| 	{ | ||||
| 		QStringList entryList = value(key).toStringList(); | ||||
| 		QStringList::Iterator it; | ||||
|  | ||||
| 		for (it = entryList.begin(); it != entryList.end(); ++it) | ||||
| 			result.push_back((*it).toInt()); | ||||
|  | ||||
| 		*ok = true; | ||||
| 	} | ||||
| 	else | ||||
| 		*ok = false; | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -119,7 +118,7 @@ void ConfigItem::updateMenu(void) | ||||
|  | ||||
| 	sym = menu->sym; | ||||
| 	prop = menu->prompt; | ||||
| 	prompt = _(menu_get_prompt(menu)); | ||||
| 	prompt = qgettext(menu_get_prompt(menu)); | ||||
|  | ||||
| 	if (prop) switch (prop->type) { | ||||
| 	case P_MENU: | ||||
| @@ -153,7 +152,7 @@ void ConfigItem::updateMenu(void) | ||||
| 	case S_TRISTATE: | ||||
| 		char ch; | ||||
|  | ||||
| 		if (!sym_is_changable(sym) && list->optMode == normalOpt) { | ||||
| 		if (!sym_is_changeable(sym) && list->optMode == normalOpt) { | ||||
| 			setPixmap(promptColIdx, QIcon()); | ||||
| 			setText(noColIdx, QString::null); | ||||
| 			setText(modColIdx, QString::null); | ||||
| @@ -208,7 +207,7 @@ void ConfigItem::updateMenu(void) | ||||
| 		break; | ||||
| 	} | ||||
| 	if (!sym_has_value(sym) && visible) | ||||
| 		prompt += _(" (NEW)"); | ||||
| 		prompt += " (NEW)"; | ||||
| set_prompt: | ||||
| 	setText(promptColIdx, prompt); | ||||
| } | ||||
| @@ -319,7 +318,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name) | ||||
| 	setVerticalScrollMode(ScrollPerPixel); | ||||
| 	setHorizontalScrollMode(ScrollPerPixel); | ||||
|  | ||||
| 	setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value")); | ||||
| 	setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); | ||||
|  | ||||
| 	connect(this, SIGNAL(itemSelectionChanged(void)), | ||||
| 		SLOT(updateSelection(void))); | ||||
| @@ -875,7 +874,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) | ||||
| 			QAction *action; | ||||
|  | ||||
| 			headerPopup = new QMenu(this); | ||||
| 			action = new QAction(_("Show Name"), this); | ||||
| 			action = new QAction("Show Name", this); | ||||
| 			  action->setCheckable(true); | ||||
| 			  connect(action, SIGNAL(toggled(bool)), | ||||
| 				  parent(), SLOT(setShowName(bool))); | ||||
| @@ -883,7 +882,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) | ||||
| 				  action, SLOT(setOn(bool))); | ||||
| 			  action->setChecked(showName); | ||||
| 			  headerPopup->addAction(action); | ||||
| 			action = new QAction(_("Show Range"), this); | ||||
| 			action = new QAction("Show Range", this); | ||||
| 			  action->setCheckable(true); | ||||
| 			  connect(action, SIGNAL(toggled(bool)), | ||||
| 				  parent(), SLOT(setShowRange(bool))); | ||||
| @@ -891,7 +890,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) | ||||
| 				  action, SLOT(setOn(bool))); | ||||
| 			  action->setChecked(showRange); | ||||
| 			  headerPopup->addAction(action); | ||||
| 			action = new QAction(_("Show Data"), this); | ||||
| 			action = new QAction("Show Data", this); | ||||
| 			  action->setCheckable(true); | ||||
| 			  connect(action, SIGNAL(toggled(bool)), | ||||
| 				  parent(), SLOT(setShowData(bool))); | ||||
| @@ -1014,7 +1013,7 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) | ||||
|  | ||||
| 	if (!objectName().isEmpty()) { | ||||
| 		configSettings->beginGroup(objectName()); | ||||
| 		_showDebug = configSettings->value("/showDebug", false).toBool(); | ||||
| 		setShowDebug(configSettings->value("/showDebug", false).toBool()); | ||||
| 		configSettings->endGroup(); | ||||
| 		connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); | ||||
| 	} | ||||
| @@ -1078,7 +1077,7 @@ void ConfigInfoView::menuInfo(void) | ||||
| 	if (sym) { | ||||
| 		if (_menu->prompt) { | ||||
| 			head += "<big><b>"; | ||||
| 			head += print_filter(_(_menu->prompt->text)); | ||||
| 			head += print_filter(_menu->prompt->text); | ||||
| 			head += "</b></big>"; | ||||
| 			if (sym->name) { | ||||
| 				head += " ("; | ||||
| @@ -1109,7 +1108,7 @@ void ConfigInfoView::menuInfo(void) | ||||
| 		str_free(&help_gstr); | ||||
| 	} else if (_menu->prompt) { | ||||
| 		head += "<big><b>"; | ||||
| 		head += print_filter(_(_menu->prompt->text)); | ||||
| 		head += print_filter(_menu->prompt->text); | ||||
| 		head += "</b></big><br><br>"; | ||||
| 		if (showDebug()) { | ||||
| 			if (_menu->prompt->visible.expr) { | ||||
| @@ -1144,13 +1143,12 @@ QString ConfigInfoView::debug_info(struct symbol *sym) | ||||
| 		case P_PROMPT: | ||||
| 		case P_MENU: | ||||
| 			debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu); | ||||
| 			debug += print_filter(_(prop->text)); | ||||
| 			debug += print_filter(prop->text); | ||||
| 			debug += "</a><br>"; | ||||
| 			break; | ||||
| 		case P_DEFAULT: | ||||
| 		case P_SELECT: | ||||
| 		case P_RANGE: | ||||
| 		case P_ENV: | ||||
| 			debug += prop_get_type_name(prop->type); | ||||
| 			debug += ": "; | ||||
| 			expr_print(prop->expr, expr_print_help, &debug, E_NONE); | ||||
| @@ -1226,7 +1224,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char | ||||
| QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) | ||||
| { | ||||
| 	QMenu* popup = Parent::createStandardContextMenu(pos); | ||||
| 	QAction* action = new QAction(_("Show Debug Info"), popup); | ||||
| 	QAction* action = new QAction("Show Debug Info", popup); | ||||
| 	  action->setCheckable(true); | ||||
| 	  connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); | ||||
| 	  connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); | ||||
| @@ -1253,11 +1251,11 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam | ||||
| 	QHBoxLayout* layout2 = new QHBoxLayout(0); | ||||
| 	layout2->setContentsMargins(0, 0, 0, 0); | ||||
| 	layout2->setSpacing(6); | ||||
| 	layout2->addWidget(new QLabel(_("Find:"), this)); | ||||
| 	layout2->addWidget(new QLabel("Find:", this)); | ||||
| 	editField = new QLineEdit(this); | ||||
| 	connect(editField, SIGNAL(returnPressed()), SLOT(search())); | ||||
| 	layout2->addWidget(editField); | ||||
| 	searchButton = new QPushButton(_("Search"), this); | ||||
| 	searchButton = new QPushButton("Search", this); | ||||
| 	searchButton->setAutoDefault(false); | ||||
| 	connect(searchButton, SIGNAL(clicked()), SLOT(search())); | ||||
| 	layout2->addWidget(searchButton); | ||||
| @@ -1379,44 +1377,46 @@ ConfigMainWindow::ConfigMainWindow(void) | ||||
| 	toolBar = new QToolBar("Tools", this); | ||||
| 	addToolBar(toolBar); | ||||
|  | ||||
| 	backAction = new QAction(QPixmap(xpm_back), _("Back"), this); | ||||
| 	backAction = new QAction(QPixmap(xpm_back), "Back", this); | ||||
| 	  connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); | ||||
| 	  backAction->setEnabled(false); | ||||
| 	QAction *quitAction = new QAction(_("&Quit"), this); | ||||
| 	QAction *quitAction = new QAction("&Quit", this); | ||||
| 	quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); | ||||
| 	  connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); | ||||
| 	QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this); | ||||
| 	QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); | ||||
| 	loadAction->setShortcut(Qt::CTRL + Qt::Key_L); | ||||
| 	  connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); | ||||
| 	saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this); | ||||
| 	saveAction = new QAction(QPixmap(xpm_save), "&Save", this); | ||||
| 	saveAction->setShortcut(Qt::CTRL + Qt::Key_S); | ||||
| 	  connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); | ||||
| 	conf_set_changed_callback(conf_changed); | ||||
| 	// Set saveAction's initial state | ||||
| 	conf_changed(); | ||||
| 	QAction *saveAsAction = new QAction(_("Save &As..."), this); | ||||
| 	configname = xstrdup(conf_get_configname()); | ||||
|  | ||||
| 	QAction *saveAsAction = new QAction("Save &As...", this); | ||||
| 	  connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs())); | ||||
| 	QAction *searchAction = new QAction(_("&Find"), this); | ||||
| 	QAction *searchAction = new QAction("&Find", this); | ||||
| 	searchAction->setShortcut(Qt::CTRL + Qt::Key_F); | ||||
| 	  connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig())); | ||||
| 	singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this); | ||||
| 	singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); | ||||
| 	singleViewAction->setCheckable(true); | ||||
| 	  connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView())); | ||||
| 	splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this); | ||||
| 	splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); | ||||
| 	splitViewAction->setCheckable(true); | ||||
| 	  connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView())); | ||||
| 	fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this); | ||||
| 	fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); | ||||
| 	fullViewAction->setCheckable(true); | ||||
| 	  connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView())); | ||||
|  | ||||
| 	QAction *showNameAction = new QAction(_("Show Name"), this); | ||||
| 	QAction *showNameAction = new QAction("Show Name", this); | ||||
| 	  showNameAction->setCheckable(true); | ||||
| 	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); | ||||
| 	  showNameAction->setChecked(configView->showName()); | ||||
| 	QAction *showRangeAction = new QAction(_("Show Range"), this); | ||||
| 	QAction *showRangeAction = new QAction("Show Range", this); | ||||
| 	  showRangeAction->setCheckable(true); | ||||
| 	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); | ||||
| 	QAction *showDataAction = new QAction(_("Show Data"), this); | ||||
| 	QAction *showDataAction = new QAction("Show Data", this); | ||||
| 	  showDataAction->setCheckable(true); | ||||
| 	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); | ||||
|  | ||||
| @@ -1427,21 +1427,21 @@ ConfigMainWindow::ConfigMainWindow(void) | ||||
| 	connect(optGroup, SIGNAL(triggered(QAction *)), menuView, | ||||
| 		SLOT(setOptionMode(QAction *))); | ||||
|  | ||||
| 	configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup); | ||||
| 	configView->showAllAction = new QAction(_("Show All Options"), optGroup); | ||||
| 	configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup); | ||||
| 	configView->showNormalAction = new QAction("Show Normal Options", optGroup); | ||||
| 	configView->showAllAction = new QAction("Show All Options", optGroup); | ||||
| 	configView->showPromptAction = new QAction("Show Prompt Options", optGroup); | ||||
| 	configView->showNormalAction->setCheckable(true); | ||||
| 	configView->showAllAction->setCheckable(true); | ||||
| 	configView->showPromptAction->setCheckable(true); | ||||
|  | ||||
| 	QAction *showDebugAction = new QAction( _("Show Debug Info"), this); | ||||
| 	QAction *showDebugAction = new QAction("Show Debug Info", this); | ||||
| 	  showDebugAction->setCheckable(true); | ||||
| 	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); | ||||
| 	  showDebugAction->setChecked(helpText->showDebug()); | ||||
|  | ||||
| 	QAction *showIntroAction = new QAction( _("Introduction"), this); | ||||
| 	QAction *showIntroAction = new QAction("Introduction", this); | ||||
| 	  connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro())); | ||||
| 	QAction *showAboutAction = new QAction( _("About"), this); | ||||
| 	QAction *showAboutAction = new QAction("About", this); | ||||
| 	  connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout())); | ||||
|  | ||||
| 	// init tool bar | ||||
| @@ -1455,7 +1455,7 @@ ConfigMainWindow::ConfigMainWindow(void) | ||||
| 	toolBar->addAction(fullViewAction); | ||||
|  | ||||
| 	// create config menu | ||||
| 	QMenu* config = menu->addMenu(_("&File")); | ||||
| 	QMenu* config = menu->addMenu("&File"); | ||||
| 	config->addAction(loadAction); | ||||
| 	config->addAction(saveAction); | ||||
| 	config->addAction(saveAsAction); | ||||
| @@ -1463,21 +1463,22 @@ ConfigMainWindow::ConfigMainWindow(void) | ||||
| 	config->addAction(quitAction); | ||||
|  | ||||
| 	// create edit menu | ||||
| 	QMenu* editMenu = menu->addMenu(_("&Edit")); | ||||
| 	QMenu* editMenu = menu->addMenu("&Edit"); | ||||
| 	editMenu->addAction(searchAction); | ||||
|  | ||||
| 	// create options menu | ||||
| 	QMenu* optionMenu = menu->addMenu(_("&Option")); | ||||
| 	QMenu* optionMenu = menu->addMenu("&Option"); | ||||
| 	optionMenu->addAction(showNameAction); | ||||
| 	optionMenu->addAction(showRangeAction); | ||||
| 	optionMenu->addAction(showDataAction); | ||||
| 	optionMenu->addSeparator(); | ||||
| 	optionMenu->addActions(optGroup->actions()); | ||||
| 	optionMenu->addSeparator(); | ||||
| 	optionMenu->addAction(showDebugAction); | ||||
|  | ||||
| 	// create help menu | ||||
| 	menu->addSeparator(); | ||||
| 	QMenu* helpMenu = menu->addMenu(_("&Help")); | ||||
| 	QMenu* helpMenu = menu->addMenu("&Help"); | ||||
| 	helpMenu->addAction(showIntroAction); | ||||
| 	helpMenu->addAction(showAboutAction); | ||||
|  | ||||
| @@ -1521,29 +1522,57 @@ ConfigMainWindow::ConfigMainWindow(void) | ||||
|  | ||||
| void ConfigMainWindow::loadConfig(void) | ||||
| { | ||||
| 	QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname()); | ||||
| 	if (s.isNull()) | ||||
| 	QString str; | ||||
| 	QByteArray ba; | ||||
| 	const char *name; | ||||
|  | ||||
| 	str = QFileDialog::getOpenFileName(this, "", configname); | ||||
| 	if (str.isNull()) | ||||
| 		return; | ||||
| 	if (conf_read(QFile::encodeName(s))) | ||||
| 		QMessageBox::information(this, "qconf", _("Unable to load configuration!")); | ||||
|  | ||||
| 	ba = str.toLocal8Bit(); | ||||
| 	name = ba.data(); | ||||
|  | ||||
| 	if (conf_read(name)) | ||||
| 		QMessageBox::information(this, "qconf", "Unable to load configuration!"); | ||||
|  | ||||
| 	free(configname); | ||||
| 	configname = xstrdup(name); | ||||
|  | ||||
| 	ConfigView::updateListAll(); | ||||
| } | ||||
|  | ||||
| bool ConfigMainWindow::saveConfig(void) | ||||
| { | ||||
| 	if (conf_write(NULL)) { | ||||
| 		QMessageBox::information(this, "qconf", _("Unable to save configuration!")); | ||||
| 	if (conf_write(configname)) { | ||||
| 		QMessageBox::information(this, "qconf", "Unable to save configuration!"); | ||||
| 		return false; | ||||
| 	} | ||||
| 	conf_write_autoconf(0); | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void ConfigMainWindow::saveConfigAs(void) | ||||
| { | ||||
| 	QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname()); | ||||
| 	if (s.isNull()) | ||||
| 	QString str; | ||||
| 	QByteArray ba; | ||||
| 	const char *name; | ||||
|  | ||||
| 	str = QFileDialog::getSaveFileName(this, "", configname); | ||||
| 	if (str.isNull()) | ||||
| 		return; | ||||
| 	saveConfig(); | ||||
|  | ||||
| 	ba = str.toLocal8Bit(); | ||||
| 	name = ba.data(); | ||||
|  | ||||
| 	if (conf_write(name)) { | ||||
| 		QMessageBox::information(this, "qconf", "Unable to save configuration!"); | ||||
| 	} | ||||
| 	conf_write_autoconf(0); | ||||
|  | ||||
| 	free(configname); | ||||
| 	configname = xstrdup(name); | ||||
| } | ||||
|  | ||||
| void ConfigMainWindow::searchConfig(void) | ||||
| @@ -1714,11 +1743,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) | ||||
| 		e->accept(); | ||||
| 		return; | ||||
| 	} | ||||
| 	QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning, | ||||
| 	QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, | ||||
| 			QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); | ||||
| 	mb.setButtonText(QMessageBox::Yes, _("&Save Changes")); | ||||
| 	mb.setButtonText(QMessageBox::No, _("&Discard Changes")); | ||||
| 	mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit")); | ||||
| 	mb.setButtonText(QMessageBox::Yes, "&Save Changes"); | ||||
| 	mb.setButtonText(QMessageBox::No, "&Discard Changes"); | ||||
| 	mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); | ||||
| 	switch (mb.exec()) { | ||||
| 	case QMessageBox::Yes: | ||||
| 		if (saveConfig()) | ||||
| @@ -1737,7 +1766,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) | ||||
|  | ||||
| void ConfigMainWindow::showIntro(void) | ||||
| { | ||||
| 	static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n" | ||||
| 	static const QString str = "Welcome to the qconf graphical configuration tool.\n\n" | ||||
| 		"For each option, a blank box indicates the feature is disabled, a check\n" | ||||
| 		"indicates it is enabled, and a dot indicates that it is to be compiled\n" | ||||
| 		"as a module.  Clicking on the box will cycle through the three states.\n\n" | ||||
| @@ -1747,16 +1776,16 @@ void ConfigMainWindow::showIntro(void) | ||||
| 		"options must be enabled to support the option you are interested in, you can\n" | ||||
| 		"still view the help of a grayed-out option.\n\n" | ||||
| 		"Toggling Show Debug Info under the Options menu will show the dependencies,\n" | ||||
| 		"which you can then match by examining other options.\n\n"); | ||||
| 		"which you can then match by examining other options.\n\n"; | ||||
|  | ||||
| 	QMessageBox::information(this, "qconf", str); | ||||
| } | ||||
|  | ||||
| void ConfigMainWindow::showAbout(void) | ||||
| { | ||||
| 	static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n" | ||||
| 	static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n" | ||||
| 		"Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n" | ||||
| 		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"); | ||||
| 		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"; | ||||
|  | ||||
| 	QMessageBox::information(this, "qconf", str); | ||||
| } | ||||
| @@ -1817,7 +1846,7 @@ static const char *progname; | ||||
|  | ||||
| static void usage(void) | ||||
| { | ||||
| 	printf(_("%s [-s] <config>\n").toLatin1().constData(), progname); | ||||
| 	printf("%s [-s] <config>\n", progname); | ||||
| 	exit(0); | ||||
| } | ||||
|  | ||||
| @@ -1826,9 +1855,6 @@ int main(int ac, char** av) | ||||
| 	ConfigMainWindow* v; | ||||
| 	const char *name; | ||||
|  | ||||
| 	bindtextdomain(PACKAGE, LOCALEDIR); | ||||
| 	textdomain(PACKAGE); | ||||
|  | ||||
| 	progname = av[0]; | ||||
| 	configApp = new QApplication(ac, av); | ||||
| 	if (ac > 1 && av[1][0] == '-') { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #include <QTextBrowser> | ||||
| @@ -291,6 +291,7 @@ protected: | ||||
| class ConfigMainWindow : public QMainWindow { | ||||
| 	Q_OBJECT | ||||
|  | ||||
| 	char *configname; | ||||
| 	static QAction *saveAction; | ||||
| 	static void conf_changed(void); | ||||
| public: | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0 | ||||
| /* | ||||
|  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #include <ctype.h> | ||||
| @@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list; | ||||
| struct symbol *modules_sym; | ||||
| 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; | ||||
| 	struct utsname uts; | ||||
| 	static bool inited = false; | ||||
|  | ||||
| 	if (inited) | ||||
| 		return; | ||||
| 	inited = true; | ||||
|  | ||||
| 	uname(&uts); | ||||
|  | ||||
| 	sym = sym_lookup("UNAME_RELEASE", 0); | ||||
| 	sym->type = S_STRING; | ||||
| 	sym->flags |= SYMBOL_AUTO; | ||||
| 	sym_add_default(sym, uts.release); | ||||
| } | ||||
|  | ||||
| enum symbol_type sym_get_type(struct symbol *sym) | ||||
| { | ||||
| 	enum symbol_type type = sym->type; | ||||
| @@ -77,7 +50,7 @@ const char *sym_type_name(enum symbol_type type) | ||||
| { | ||||
| 	switch (type) { | ||||
| 	case S_BOOLEAN: | ||||
| 		return "boolean"; | ||||
| 		return "bool"; | ||||
| 	case S_TRISTATE: | ||||
| 		return "tristate"; | ||||
| 	case S_INT: | ||||
| @@ -88,8 +61,6 @@ const char *sym_type_name(enum symbol_type type) | ||||
| 		return "string"; | ||||
| 	case S_UNKNOWN: | ||||
| 		return "unknown"; | ||||
| 	case S_OTHER: | ||||
| 		break; | ||||
| 	} | ||||
| 	return "???"; | ||||
| } | ||||
| @@ -103,15 +74,6 @@ struct property *sym_get_choice_prop(struct symbol *sym) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| struct property *sym_get_env_prop(struct symbol *sym) | ||||
| { | ||||
| 	struct property *prop; | ||||
|  | ||||
| 	for_all_properties(sym, prop, P_ENV) | ||||
| 		return prop; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| static struct property *sym_get_default_prop(struct symbol *sym) | ||||
| { | ||||
| 	struct property *prop; | ||||
| @@ -124,7 +86,7 @@ static struct property *sym_get_default_prop(struct symbol *sym) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| static struct property *sym_get_range_prop(struct symbol *sym) | ||||
| struct property *sym_get_range_prop(struct symbol *sym) | ||||
| { | ||||
| 	struct property *prop; | ||||
|  | ||||
| @@ -183,7 +145,7 @@ static void sym_validate_range(struct symbol *sym) | ||||
| 		sprintf(str, "%lld", val2); | ||||
| 	else | ||||
| 		sprintf(str, "0x%llx", val2); | ||||
| 	sym->curr.val = strdup(str); | ||||
| 	sym->curr.val = xstrdup(str); | ||||
| } | ||||
|  | ||||
| static void sym_set_changed(struct symbol *sym) | ||||
| @@ -243,7 +205,7 @@ static void sym_calc_visibility(struct symbol *sym) | ||||
| 	tri = yes; | ||||
| 	if (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; | ||||
| 	if (sym->dir_dep.tri != tri) { | ||||
| 		sym->dir_dep.tri = tri; | ||||
| @@ -258,6 +220,15 @@ static void sym_calc_visibility(struct symbol *sym) | ||||
| 		sym->rev_dep.tri = tri; | ||||
| 		sym_set_changed(sym); | ||||
| 	} | ||||
| 	tri = no; | ||||
| 	if (sym->implied.expr && sym->dir_dep.tri != no) | ||||
| 		tri = expr_calc_value(sym->implied.expr); | ||||
| 	if (tri == mod && sym_get_type(sym) == S_BOOLEAN) | ||||
| 		tri = yes; | ||||
| 	if (sym->implied.tri != tri) { | ||||
| 		sym->implied.tri = tri; | ||||
| 		sym_set_changed(sym); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -362,11 +333,13 @@ void sym_calc_value(struct symbol *sym) | ||||
| 		sym->curr.tri = no; | ||||
| 		return; | ||||
| 	} | ||||
| 	if (!sym_is_choice_value(sym)) | ||||
| 	sym->flags &= ~SYMBOL_WRITE; | ||||
|  | ||||
| 	sym_calc_visibility(sym); | ||||
|  | ||||
| 	if (sym->visible != no) | ||||
| 		sym->flags |= SYMBOL_WRITE; | ||||
|  | ||||
| 	/* set default if recursively called */ | ||||
| 	sym->curr = newval; | ||||
|  | ||||
| @@ -381,7 +354,6 @@ void sym_calc_value(struct symbol *sym) | ||||
| 				/* if the symbol is visible use the user value | ||||
| 				 * if available, otherwise try the default value | ||||
| 				 */ | ||||
| 				sym->flags |= SYMBOL_WRITE; | ||||
| 				if (sym_has_value(sym)) { | ||||
| 					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, | ||||
| 							      sym->visible); | ||||
| @@ -397,27 +369,29 @@ void sym_calc_value(struct symbol *sym) | ||||
| 					newval.tri = EXPR_AND(expr_calc_value(prop->expr), | ||||
| 							      prop->visible.tri); | ||||
| 				} | ||||
| 				if (sym->implied.tri != no) { | ||||
| 					sym->flags |= SYMBOL_WRITE; | ||||
| 					newval.tri = EXPR_OR(newval.tri, sym->implied.tri); | ||||
| 				} | ||||
| 			} | ||||
| 		calc_newval: | ||||
| 			if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { | ||||
| 			if (sym->dir_dep.tri < sym->rev_dep.tri) { | ||||
| 				newval.tri = no; | ||||
| 			} else { | ||||
| 				newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); | ||||
| 			} | ||||
| 		} | ||||
| 		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) | ||||
| 		if (newval.tri == mod && | ||||
| 		    (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes)) | ||||
| 			newval.tri = yes; | ||||
| 		break; | ||||
| 	case S_STRING: | ||||
| 	case S_HEX: | ||||
| 	case S_INT: | ||||
| 		if (sym->visible != no) { | ||||
| 			sym->flags |= SYMBOL_WRITE; | ||||
| 			if (sym_has_value(sym)) { | ||||
| 		if (sym->visible != no && sym_has_value(sym)) { | ||||
| 			newval.val = sym->def[S_DEF_USER].val; | ||||
| 			break; | ||||
| 		} | ||||
| 		} | ||||
| 		prop = sym_get_default_prop(sym); | ||||
| 		if (prop) { | ||||
| 			struct symbol *ds = prop_get_symbol(prop); | ||||
| @@ -458,7 +432,7 @@ void sym_calc_value(struct symbol *sym) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (sym->flags & SYMBOL_AUTO) | ||||
| 	if (sym->flags & SYMBOL_NO_WRITE) | ||||
| 		sym->flags &= ~SYMBOL_WRITE; | ||||
|  | ||||
| 	if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) | ||||
| @@ -490,6 +464,8 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) | ||||
| 		return false; | ||||
| 	if (sym->visible <= sym->rev_dep.tri) | ||||
| 		return false; | ||||
| 	if (sym->implied.tri == yes && val == mod) | ||||
| 		return false; | ||||
| 	if (sym_is_choice_value(sym) && sym->visible == yes) | ||||
| 		return val == yes; | ||||
| 	return val >= sym->rev_dep.tri && val <= sym->visible; | ||||
| @@ -742,6 +718,10 @@ const char *sym_get_string_default(struct symbol *sym) | ||||
| 	if (sym->type == S_BOOLEAN && val == mod) | ||||
| 		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) { | ||||
| 	case S_BOOLEAN: | ||||
| 	case S_TRISTATE: | ||||
| @@ -755,7 +735,6 @@ const char *sym_get_string_default(struct symbol *sym) | ||||
| 		return str; | ||||
| 	case S_STRING: | ||||
| 		return str; | ||||
| 	case S_OTHER: | ||||
| 	case S_UNKNOWN: | ||||
| 		break; | ||||
| 	} | ||||
| @@ -786,7 +765,7 @@ const char *sym_get_string_value(struct symbol *sym) | ||||
| 	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; | ||||
| } | ||||
| @@ -823,7 +802,7 @@ struct symbol *sym_lookup(const char *name, int flags) | ||||
| 				   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) | ||||
| 				return symbol; | ||||
| 		} | ||||
| 		new_name = strdup(name); | ||||
| 		new_name = xstrdup(name); | ||||
| 	} else { | ||||
| 		new_name = NULL; | ||||
| 		hash = 0; | ||||
| @@ -868,55 +847,6 @@ struct symbol *sym_find(const char *name) | ||||
| 	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 *p; | ||||
| @@ -1033,7 +963,7 @@ struct symbol **sym_re_search(const char *pattern) | ||||
| 	} | ||||
| 	if (sym_match_arr) { | ||||
| 		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) | ||||
| 			goto sym_re_search_free; | ||||
| 		for (i = 0; i < cnt; i++) | ||||
| @@ -1058,7 +988,7 @@ static struct dep_stack { | ||||
| 	struct dep_stack *prev, *next; | ||||
| 	struct symbol *sym; | ||||
| 	struct property *prop; | ||||
| 	struct expr *expr; | ||||
| 	struct expr **expr; | ||||
| } *check_top; | ||||
|  | ||||
| static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) | ||||
| @@ -1122,20 +1052,8 @@ static void sym_check_print_recursive(struct symbol *last_sym) | ||||
| 		if (stack->sym == last_sym) | ||||
| 			fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", | ||||
| 				prop->file->name, prop->lineno); | ||||
| 			fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n"); | ||||
| 			fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n"); | ||||
| 		if (stack->expr) { | ||||
| 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", | ||||
| 				prop->file->name, prop->lineno, | ||||
| 				sym->name ? sym->name : "<choice>", | ||||
| 				prop_get_type_name(prop->type), | ||||
| 				next_sym->name ? next_sym->name : "<choice>"); | ||||
| 		} else if (stack->prop) { | ||||
| 			fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", | ||||
| 				prop->file->name, prop->lineno, | ||||
| 				sym->name ? sym->name : "<choice>", | ||||
| 				next_sym->name ? next_sym->name : "<choice>"); | ||||
| 		} else if (sym_is_choice(sym)) { | ||||
|  | ||||
| 		if (sym_is_choice(sym)) { | ||||
| 			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", | ||||
| 				menu->file->name, menu->lineno, | ||||
| 				sym->name ? sym->name : "<choice>", | ||||
| @@ -1145,14 +1063,41 @@ static void sym_check_print_recursive(struct symbol *last_sym) | ||||
| 				menu->file->name, menu->lineno, | ||||
| 				sym->name ? 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", | ||||
| 				prop->file->name, prop->lineno, | ||||
| 				sym->name ? 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) | ||||
| 		dep_stack_remove(); | ||||
| } | ||||
| @@ -1187,7 +1132,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e) | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	printf("Oops! How to check %d?\n", e->type); | ||||
| 	fprintf(stderr, "Oops! How to check %d?\n", e->type); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| @@ -1200,12 +1145,26 @@ static struct symbol *sym_check_sym_deps(struct symbol *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); | ||||
| 	if (sym2) | ||||
| 		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) { | ||||
| 		if (prop->type == P_CHOICE || prop->type == P_SELECT) | ||||
| 		if (prop->type == P_CHOICE || prop->type == P_SELECT || | ||||
| 		    prop->type == P_IMPLY) | ||||
| 			continue; | ||||
| 		stack.prop = prop; | ||||
| 		sym2 = sym_check_expr_deps(prop->visible.expr); | ||||
| @@ -1213,7 +1172,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) | ||||
| 			break; | ||||
| 		if (prop->type != P_DEFAULT || sym_is_choice(sym)) | ||||
| 			continue; | ||||
| 		stack.expr = prop->expr; | ||||
| 		stack.expr = &prop->expr; | ||||
| 		sym2 = sym_check_expr_deps(prop->expr); | ||||
| 		if (sym2) | ||||
| 			break; | ||||
| @@ -1291,34 +1250,9 @@ struct symbol *sym_check_deps(struct symbol *sym) | ||||
| 		sym->flags &= ~SYMBOL_CHECK; | ||||
| 	} | ||||
|  | ||||
| 	if (sym2 && sym2 == sym) | ||||
| 		sym2 = NULL; | ||||
|  | ||||
| 	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) | ||||
| { | ||||
| 	if (prop->expr && (prop->expr->type == E_SYMBOL || | ||||
| @@ -1332,8 +1266,6 @@ const char *prop_get_type_name(enum prop_type type) | ||||
| 	switch (type) { | ||||
| 	case P_PROMPT: | ||||
| 		return "prompt"; | ||||
| 	case P_ENV: | ||||
| 		return "env"; | ||||
| 	case P_COMMENT: | ||||
| 		return "comment"; | ||||
| 	case P_MENU: | ||||
| @@ -1344,6 +1276,8 @@ const char *prop_get_type_name(enum prop_type type) | ||||
| 		return "choice"; | ||||
| 	case P_SELECT: | ||||
| 		return "select"; | ||||
| 	case P_IMPLY: | ||||
| 		return "imply"; | ||||
| 	case P_RANGE: | ||||
| 		return "range"; | ||||
| 	case P_SYMBOL: | ||||
| @@ -1355,32 +1289,3 @@ const char *prop_get_type_name(enum prop_type type) | ||||
| 	} | ||||
| 	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 Sam Ravnborg <sam@ravnborg.org> | ||||
|  * | ||||
|  * Released under the terms of the GNU GPL v2.0. | ||||
|  */ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| @@ -14,69 +13,21 @@ | ||||
| struct file *file_lookup(const char *name) | ||||
| { | ||||
| 	struct file *file; | ||||
| 	const char *file_name = sym_expand_string_value(name); | ||||
|  | ||||
| 	for (file = file_list; file; file = file->next) { | ||||
| 		if (!strcmp(name, file->name)) { | ||||
| 			free((void *)file_name); | ||||
| 			return file; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	file = xmalloc(sizeof(*file)); | ||||
| 	memset(file, 0, sizeof(*file)); | ||||
| 	file->name = file_name; | ||||
| 	file->name = xstrdup(name); | ||||
| 	file->next = file_list; | ||||
| 	file_list = 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; | ||||
|  | ||||
| 	if (!name) | ||||
| 		name = ".kconfig.d"; | ||||
| 	out = fopen("..config.tmp", "w"); | ||||
| 	if (!out) | ||||
| 		return 1; | ||||
| 	fprintf(out, "deps_config := \\\n"); | ||||
| 	for (file = file_list; file; file = file->next) { | ||||
| 		if (file->next) | ||||
| 			fprintf(out, "\t%s \\\n", file->name); | ||||
| 		else | ||||
| 			fprintf(out, "\t%s\n", file->name); | ||||
| 	} | ||||
| 	fprintf(out, "\n%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); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Allocate initial growable string */ | ||||
| struct gstr str_new(void) | ||||
| { | ||||
| @@ -104,7 +55,7 @@ void str_append(struct gstr *gs, const char *s) | ||||
| 	if (s) { | ||||
| 		l = strlen(gs->s) + strlen(s) + 1; | ||||
| 		if (l > gs->len) { | ||||
| 			gs->s   = realloc(gs->s, l); | ||||
| 			gs->s = xrealloc(gs->s, l); | ||||
| 			gs->len = l; | ||||
| 		} | ||||
| 		strcat(gs->s, s); | ||||
| @@ -145,3 +96,34 @@ void *xcalloc(size_t nmemb, size_t size) | ||||
| 	fprintf(stderr, "Out of memory.\n"); | ||||
| 	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,49 +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; | ||||
|  | ||||
|  | ||||
| %% | ||||
| mainmenu,	T_MAINMENU,	TF_COMMAND | ||||
| menu,		T_MENU,		TF_COMMAND | ||||
| endmenu,	T_ENDMENU,	TF_COMMAND | ||||
| source,		T_SOURCE,	TF_COMMAND | ||||
| choice,		T_CHOICE,	TF_COMMAND | ||||
| endchoice,	T_ENDCHOICE,	TF_COMMAND | ||||
| comment,	T_COMMENT,	TF_COMMAND | ||||
| config,		T_CONFIG,	TF_COMMAND | ||||
| menuconfig,	T_MENUCONFIG,	TF_COMMAND | ||||
| help,		T_HELP,		TF_COMMAND | ||||
| ---help---,	T_HELP,		TF_COMMAND | ||||
| if,		T_IF,		TF_COMMAND|TF_PARAM | ||||
| endif,		T_ENDIF,	TF_COMMAND | ||||
| depends,	T_DEPENDS,	TF_COMMAND | ||||
| optional,	T_OPTIONAL,	TF_COMMAND | ||||
| default,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN | ||||
| prompt,		T_PROMPT,	TF_COMMAND | ||||
| tristate,	T_TYPE,		TF_COMMAND, S_TRISTATE | ||||
| def_tristate,	T_DEFAULT,	TF_COMMAND, S_TRISTATE | ||||
| bool,		T_TYPE,		TF_COMMAND, S_BOOLEAN | ||||
| 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 | ||||
| reset,		T_RESET,	TF_COMMAND | ||||
| %% | ||||
| @@ -1,250 +0,0 @@ | ||||
| /* ANSI-C code produced by gperf version 3.0.4 */ | ||||
| /* Command-line: gperf  */ | ||||
| /* Computed positions: -k'1,3' */ | ||||
|  | ||||
| #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 | ||||
|  | ||||
| struct kconf_id; | ||||
| /* maximum key range = 47, 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 unsigned char asso_values[] = | ||||
|     { | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 10, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 20, 40,  5, | ||||
|        0,  0,  5, 49,  5, 20, 49, 49,  5, 20, | ||||
|        5,  0, 35, 49,  0, 15,  0, 10, 15, 49, | ||||
|       25, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49, 49, 49, 49, 49, | ||||
|       49, 49, 49, 49, 49, 49 | ||||
|     }; | ||||
|   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; | ||||
| } | ||||
|  | ||||
| struct kconf_id_strings_t | ||||
|   { | ||||
|     char kconf_id_strings_str2[sizeof("on")]; | ||||
|     char kconf_id_strings_str5[sizeof("endif")]; | ||||
|     char kconf_id_strings_str6[sizeof("option")]; | ||||
|     char kconf_id_strings_str7[sizeof("endmenu")]; | ||||
|     char kconf_id_strings_str8[sizeof("optional")]; | ||||
|     char kconf_id_strings_str9[sizeof("endchoice")]; | ||||
|     char kconf_id_strings_str10[sizeof("range")]; | ||||
|     char kconf_id_strings_str11[sizeof("choice")]; | ||||
|     char kconf_id_strings_str12[sizeof("default")]; | ||||
|     char kconf_id_strings_str13[sizeof("def_bool")]; | ||||
|     char kconf_id_strings_str14[sizeof("help")]; | ||||
|     char kconf_id_strings_str16[sizeof("config")]; | ||||
|     char kconf_id_strings_str17[sizeof("def_tristate")]; | ||||
|     char kconf_id_strings_str18[sizeof("env")]; | ||||
|     char kconf_id_strings_str19[sizeof("defconfig_list")]; | ||||
|     char kconf_id_strings_str20[sizeof("reset")]; | ||||
|     char kconf_id_strings_str21[sizeof("string")]; | ||||
|     char kconf_id_strings_str22[sizeof("if")]; | ||||
|     char kconf_id_strings_str23[sizeof("int")]; | ||||
|     char kconf_id_strings_str26[sizeof("select")]; | ||||
|     char kconf_id_strings_str27[sizeof("modules")]; | ||||
|     char kconf_id_strings_str28[sizeof("tristate")]; | ||||
|     char kconf_id_strings_str29[sizeof("menu")]; | ||||
|     char kconf_id_strings_str30[sizeof("---help---")]; | ||||
|     char kconf_id_strings_str31[sizeof("source")]; | ||||
|     char kconf_id_strings_str32[sizeof("comment")]; | ||||
|     char kconf_id_strings_str33[sizeof("hex")]; | ||||
|     char kconf_id_strings_str35[sizeof("menuconfig")]; | ||||
|     char kconf_id_strings_str37[sizeof("visible")]; | ||||
|     char kconf_id_strings_str38[sizeof("allnoconfig_y")]; | ||||
|     char kconf_id_strings_str41[sizeof("prompt")]; | ||||
|     char kconf_id_strings_str42[sizeof("depends")]; | ||||
|     char kconf_id_strings_str44[sizeof("bool")]; | ||||
|     char kconf_id_strings_str47[sizeof("boolean")]; | ||||
|     char kconf_id_strings_str48[sizeof("mainmenu")]; | ||||
|   }; | ||||
| static struct kconf_id_strings_t kconf_id_strings_contents = | ||||
|   { | ||||
|     "on", | ||||
|     "endif", | ||||
|     "option", | ||||
|     "endmenu", | ||||
|     "optional", | ||||
|     "endchoice", | ||||
|     "range", | ||||
|     "choice", | ||||
|     "default", | ||||
|     "def_bool", | ||||
|     "help", | ||||
|     "config", | ||||
|     "def_tristate", | ||||
|     "env", | ||||
|     "defconfig_list", | ||||
|     "reset", | ||||
|     "string", | ||||
|     "if", | ||||
|     "int", | ||||
|     "select", | ||||
|     "modules", | ||||
|     "tristate", | ||||
|     "menu", | ||||
|     "---help---", | ||||
|     "source", | ||||
|     "comment", | ||||
|     "hex", | ||||
|     "menuconfig", | ||||
|     "visible", | ||||
|     "allnoconfig_y", | ||||
|     "prompt", | ||||
|     "depends", | ||||
|     "bool", | ||||
|     "boolean", | ||||
|     "mainmenu" | ||||
|   }; | ||||
| #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 | ||||
| struct kconf_id * | ||||
| kconf_id_lookup (register const char *str, register unsigned int len) | ||||
| { | ||||
|   enum | ||||
|     { | ||||
|       TOTAL_KEYWORDS = 35, | ||||
|       MIN_WORD_LENGTH = 2, | ||||
|       MAX_WORD_LENGTH = 14, | ||||
|       MIN_HASH_VALUE = 2, | ||||
|       MAX_HASH_VALUE = 48 | ||||
|     }; | ||||
|  | ||||
|   static struct kconf_id wordlist[] = | ||||
|     { | ||||
|       {-1}, {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,		T_ON,		TF_PARAM}, | ||||
|       {-1}, {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5,		T_ENDIF,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6,		T_OPTION,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,	T_ENDMENU,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8,	T_OPTIONAL,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9,	T_ENDCHOICE,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10,		T_RANGE,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11,		T_CHOICE,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,		T_HELP,		TF_COMMAND}, | ||||
|       {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,		T_CONFIG,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,	T_DEFAULT,	TF_COMMAND, S_TRISTATE}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,		T_OPT_ENV,	TF_OPTION}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19,	T_OPT_DEFCONFIG_LIST,TF_OPTION}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20,		T_RESET,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,		T_TYPE,		TF_COMMAND, S_STRING}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,		T_IF,		TF_COMMAND|TF_PARAM}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,		T_TYPE,		TF_COMMAND, S_INT}, | ||||
|       {-1}, {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,		T_SELECT,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,	T_OPT_MODULES,	TF_OPTION}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,	T_TYPE,		TF_COMMAND, S_TRISTATE}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29,		T_MENU,		TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str30,	T_HELP,		TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,		T_SOURCE,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,	T_COMMENT,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,		T_TYPE,		TF_COMMAND, S_HEX}, | ||||
|       {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,	T_MENUCONFIG,	TF_COMMAND}, | ||||
|       {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,	T_VISIBLE,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str38,	T_OPT_ALLNOCONFIG_Y,TF_OPTION}, | ||||
|       {-1}, {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,		T_PROMPT,	TF_COMMAND}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,	T_DEPENDS,	TF_COMMAND}, | ||||
|       {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44,		T_TYPE,		TF_COMMAND, S_BOOLEAN}, | ||||
|       {-1}, {-1}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47,	T_TYPE,		TF_COMMAND, S_BOOLEAN}, | ||||
|       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,	T_MAINMENU,	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; | ||||
| } | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user