Browse Source

- pull kconfig from 2.6.25.4
It has nicer "-*-" etc hints

Bernhard Reutner-Fischer 17 years ago
parent
commit
b7a51199bd

+ 19 - 0
extra/config/.gitignore

@@ -0,0 +1,19 @@
+#
+# Generated files
+#
+config*
+lex.*.c
+*.tab.c
+*.tab.h
+zconf.hash.c
+*.moc
+lkc_defs.h
+
+#
+# configuration programs
+#
+conf
+mconf
+qconf
+gconf
+kxgettext

+ 5 - 1
extra/config/Makefile

@@ -7,6 +7,10 @@ include $(top_builddir)Rules.mak
 
 
 include Makefile.kconfig
 include Makefile.kconfig
 
 
+ifeq ($(findstring mconf,$(MAKECMDGOALS)),mconf)
+hostprogs-y += mconf
+endif
+
 -include .depend
 -include .depend
 .depend: $(wildcard *.h *.c)
 .depend: $(wildcard *.h *.c)
 	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) -MM *.c > .depend 2>/dev/null || :
 	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) -MM *.c > .depend 2>/dev/null || :
@@ -30,7 +34,7 @@ $(obj)/%:: $(src)/%_shipped
 	$(Q)cat $< > $@
 	$(Q)cat $< > $@
 
 
 clean:
 clean:
-	$(Q)rm -f $(clean-files)
+	$(Q)rm -f $(clean-files) conf
 distclean: clean
 distclean: clean
 	$(Q)rm -f $(lxdialog) $(conf-objs) $(mconf-objs) $(kxgettext-objs) \
 	$(Q)rm -f $(lxdialog) $(conf-objs) $(mconf-objs) $(kxgettext-objs) \
 		$(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs)
 		$(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs)

+ 61 - 54
extra/config/Makefile.kconfig

@@ -4,67 +4,73 @@
 
 
 PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
 PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
 
 
+Kconfig := arch/$(SRCARCH)/Kconfig
+
 xconfig: $(obj)/qconf
 xconfig: $(obj)/qconf
-	$< arch/$(ARCH)/Kconfig
+	$< $(Kconfig)
 
 
 gconfig: $(obj)/gconf
 gconfig: $(obj)/gconf
-	$< arch/$(ARCH)/Kconfig
+	$< $(Kconfig)
 
 
 menuconfig: $(obj)/mconf
 menuconfig: $(obj)/mconf
-	$< arch/$(ARCH)/Kconfig
+	$< $(Kconfig)
 
 
 config: $(obj)/conf
 config: $(obj)/conf
-	$< arch/$(ARCH)/Kconfig
+	$< $(Kconfig)
 
 
 oldconfig: $(obj)/conf
 oldconfig: $(obj)/conf
-	$< -o arch/$(ARCH)/Kconfig
+	$< -o $(Kconfig)
 
 
 silentoldconfig: $(obj)/conf
 silentoldconfig: $(obj)/conf
-	$< -s arch/$(ARCH)/Kconfig
+	$< -s $(Kconfig)
-
+
-update-po-config: $(obj)/kxgettext
+# Create new linux.pot file
-	xgettext --default-domain=linux \
+# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
-	  --add-comments --keyword=_ --keyword=N_ \
+# The symlink is used to repair a deficiency in arch/um
-	  --files-from=scripts/kconfig/POTFILES.in \
+update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
-	  --output scripts/kconfig/config.pot
+	$(Q)echo "  GEN config"
-	$(Q)ln -fs Kconfig_i386 arch/um/Kconfig_arch
+	$(Q)xgettext --default-domain=linux              \
-	$(Q)for i in `ls arch/`; \
+	    --add-comments --keyword=_ --keyword=N_      \
-	do \
+	    --from-code=UTF-8                            \
-	  scripts/kconfig/kxgettext arch/$$i/Kconfig \
+	    --files-from=scripts/kconfig/POTFILES.in     \
-	    | msguniq -o scripts/kconfig/linux_$${i}.pot; \
+	    --output $(obj)/config.pot
-	done
+	$(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
-	$(Q)msgcat scripts/kconfig/config.pot \
+	$(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch
-	  `find scripts/kconfig/ -type f -name linux_*.pot` \
+	$(Q)(for i in `ls arch/`;                        \
-	  --output scripts/kconfig/linux_raw.pot
+	    do                                           \
-	$(Q)msguniq --sort-by-file scripts/kconfig/linux_raw.pot \
+		echo "  GEN $$i";                        \
-	    --output scripts/kconfig/linux.pot
+		$(obj)/kxgettext arch/$$i/Kconfig        \
-	$(Q)rm -f arch/um/Kconfig_arch
+		     >> $(obj)/config.pot;               \
-	$(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot
+	    done )
+	$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
+	    --output $(obj)/linux.pot
+	$(Q)rm -f arch/um/Kconfig.arch
+	$(Q)rm -f $(obj)/config.pot
 
 
 PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
 PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
 
 
 randconfig: $(obj)/conf
 randconfig: $(obj)/conf
-	$< -r arch/$(ARCH)/Kconfig
+	$< -r $(Kconfig)
 
 
 allyesconfig: $(obj)/conf
 allyesconfig: $(obj)/conf
-	$< -y arch/$(ARCH)/Kconfig
+	$< -y $(Kconfig)
 
 
 allnoconfig: $(obj)/conf
 allnoconfig: $(obj)/conf
-	$< -n arch/$(ARCH)/Kconfig
+	$< -n $(Kconfig)
 
 
 allmodconfig: $(obj)/conf
 allmodconfig: $(obj)/conf
-	$< -m arch/$(ARCH)/Kconfig
+	$< -m $(Kconfig)
 
 
 defconfig: $(obj)/conf
 defconfig: $(obj)/conf
 ifeq ($(KBUILD_DEFCONFIG),)
 ifeq ($(KBUILD_DEFCONFIG),)
-	$< -d arch/$(ARCH)/Kconfig
+	$< -d $(Kconfig)
 else
 else
-	@echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)'
+	@echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
-	$(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig
+	$(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
 endif
 endif
 
 
 %_defconfig: $(obj)/conf
 %_defconfig: $(obj)/conf
-	$(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig
+	$(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig)
 
 
 # Help text used by make help
 # Help text used by make help
 help:
 help:
@@ -83,19 +89,13 @@ help:
 # lxdialog stuff
 # lxdialog stuff
 check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
 check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
 
 
-# Use reursively expanded variables so we do not call gcc unless
+# Use recursively expanded variables so we do not call gcc unless
 # we really need to do so. (Do not call gcc as part of make mrproper)
 # we really need to do so. (Do not call gcc as part of make mrproper)
 HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
 HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
 HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
 HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
 
 
 HOST_EXTRACFLAGS += -DLOCALE
 HOST_EXTRACFLAGS += -DLOCALE
 
 
-PHONY += $(obj)/dochecklxdialog
-$(obj)/dochecklxdialog:
-	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
-
-always := dochecklxdialog
-
 
 
 # ===========================================================================
 # ===========================================================================
 # Shared Makefile for the various kconfig executables:
 # Shared Makefile for the various kconfig executables:
@@ -117,9 +117,9 @@ kxgettext-objs	:= kxgettext.o zconf.tab.o
 
 
 hostprogs-y := conf qconf gconf kxgettext
 hostprogs-y := conf qconf gconf kxgettext
 
 
-#ifeq ($(MAKECMDGOALS),menuconfig)
+ifeq ($(MAKECMDGOALS),menuconfig)
 	hostprogs-y += mconf
 	hostprogs-y += mconf
-#endif
+endif
 
 
 ifeq ($(MAKECMDGOALS),xconfig)
 ifeq ($(MAKECMDGOALS),xconfig)
 	qconf-target := 1
 	qconf-target := 1
@@ -139,16 +139,20 @@ gconf-objs	:= gconf.o kconfig_load.o zconf.tab.o
 endif
 endif
 
 
 clean-files	:= lkc_defs.h qconf.moc .tmp_qtcheck \
 clean-files	:= lkc_defs.h qconf.moc .tmp_qtcheck \
-		   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
+		   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
-
+clean-files     += mconf qconf gconf
-# Needed for systems without gettext
+clean-files     += config.pot linux.pot
-KBUILD_HAVE_NLS := $(shell \
+
-     if echo "\#include <libintl.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
+# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
-     then echo yes ; \
+PHONY += $(obj)/dochecklxdialog
-     else echo no ; fi)
+$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
-ifeq ($(KBUILD_HAVE_NLS),no)
+$(obj)/dochecklxdialog:
-HOSTCFLAGS	+= -DKBUILD_NO_NLS
+	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES)
-endif
+
+always := dochecklxdialog
+
+# Add environment specific flags
+HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
 
 
 # generated files seem to need this to find local include files
 # generated files seem to need this to find local include files
 HOSTCFLAGS_lex.zconf.o	:= -I$(src)
 HOSTCFLAGS_lex.zconf.o	:= -I$(src)
@@ -183,8 +187,8 @@ $(obj)/.tmp_qtcheck:
 	  done; \
 	  done; \
 	  if [ -z "$$dir" ]; then \
 	  if [ -z "$$dir" ]; then \
 	    echo "*"; \
 	    echo "*"; \
-	    echo "* Unable to find the QT installation. Please make sure that"; \
+	    echo "* Unable to find the QT3 installation. Please make sure that"; \
-	    echo "* the QT development package is correctly installed and"; \
+	    echo "* the QT3 development package is correctly installed and"; \
 	    echo "* either install pkg-config or set the QTDIR environment"; \
 	    echo "* either install pkg-config or set the QTDIR environment"; \
 	    echo "* variable to the correct location."; \
 	    echo "* variable to the correct location."; \
 	    echo "*"; \
 	    echo "*"; \
@@ -250,6 +254,9 @@ $(obj)/%.moc: $(src)/%.h
 $(obj)/lkc_defs.h: $(src)/lkc_proto.h
 $(obj)/lkc_defs.h: $(src)/lkc_proto.h
 	sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
 	sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
 
 
+# Extract gconf menu items for I18N support
+$(obj)/gconf.glade.h: $(obj)/gconf.glade
+	intltool-extract --type=gettext/glade $(obj)/gconf.glade
 
 
 ###
 ###
 # The following requires flex/bison/gperf
 # The following requires flex/bison/gperf

+ 7 - 0
extra/config/POTFILES.in

@@ -1,5 +1,12 @@
+scripts/kconfig/lxdialog/checklist.c
+scripts/kconfig/lxdialog/inputbox.c
+scripts/kconfig/lxdialog/menubox.c
+scripts/kconfig/lxdialog/textbox.c
+scripts/kconfig/lxdialog/util.c
+scripts/kconfig/lxdialog/yesno.c
 scripts/kconfig/mconf.c
 scripts/kconfig/mconf.c
 scripts/kconfig/conf.c
 scripts/kconfig/conf.c
 scripts/kconfig/confdata.c
 scripts/kconfig/confdata.c
 scripts/kconfig/gconf.c
 scripts/kconfig/gconf.c
+scripts/kconfig/gconf.glade.h
 scripts/kconfig/qconf.cc
 scripts/kconfig/qconf.cc

+ 14 - 0
extra/config/check.sh

@@ -0,0 +1,14 @@
+#!/bin/sh
+# Needed for systems without gettext
+$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+#include <libintl.h>
+int main()
+{
+	gettext("");
+	return 0;
+}
+EOF
+if [ ! "$?" -eq "0"  ]; then
+	echo -DKBUILD_NO_NLS;
+fi
+

+ 69 - 62
extra/config/conf.c

@@ -3,12 +3,13 @@
  * Released under the terms of the GNU GPL v2.0.
  * Released under the terms of the GNU GPL v2.0.
  */
  */
 
 
+#include <locale.h>
 #include <ctype.h>
 #include <ctype.h>
-#include <stdlib.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <string.h>
-#include <unistd.h>
 #include <time.h>
 #include <time.h>
+#include <unistd.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
 #define LKC_DIRECT_LINK
 #define LKC_DIRECT_LINK
@@ -37,6 +38,14 @@ static struct menu *rootEntry;
 
 
 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
 
 
+static const char *get_help(struct menu *menu)
+{
+	if (menu_has_help(menu))
+		return _(menu_get_help(menu));
+	else
+		return nohelp_text;
+}
+
 static void strip(char *str)
 static void strip(char *str)
 {
 {
 	char *p = str;
 	char *p = str;
@@ -64,13 +73,13 @@ static void check_stdin(void)
 	}
 	}
 }
 }
 
 
-static void conf_askvalue(struct symbol *sym, const char *def)
+static int conf_askvalue(struct symbol *sym, const char *def)
 {
 {
 	enum symbol_type type = sym_get_type(sym);
 	enum symbol_type type = sym_get_type(sym);
 	tristate val;
 	tristate val;
 
 
 	if (!sym_has_value(sym))
 	if (!sym_has_value(sym))
-		printf("(NEW) ");
+		printf(_("(NEW) "));
 
 
 	line[0] = '\n';
 	line[0] = '\n';
 	line[1] = 0;
 	line[1] = 0;
@@ -79,7 +88,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 		printf("%s\n", def);
 		printf("%s\n", def);
 		line[0] = '\n';
 		line[0] = '\n';
 		line[1] = 0;
 		line[1] = 0;
-		return;
+		return 0;
 	}
 	}
 
 
 	switch (input_mode) {
 	switch (input_mode) {
@@ -89,23 +98,23 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 	case set_random:
 	case set_random:
 		if (sym_has_value(sym)) {
 		if (sym_has_value(sym)) {
 			printf("%s\n", def);
 			printf("%s\n", def);
-			return;
+			return 0;
 		}
 		}
 		break;
 		break;
 	case ask_new:
 	case ask_new:
 	case ask_silent:
 	case ask_silent:
 		if (sym_has_value(sym)) {
 		if (sym_has_value(sym)) {
 			printf("%s\n", def);
 			printf("%s\n", def);
-			return;
+			return 0;
 		}
 		}
 		check_stdin();
 		check_stdin();
 	case ask_all:
 	case ask_all:
 		fflush(stdout);
 		fflush(stdout);
 		fgets(line, 128, stdin);
 		fgets(line, 128, stdin);
-		return;
+		return 1;
 	case set_default:
 	case set_default:
 		printf("%s\n", def);
 		printf("%s\n", def);
-		return;
+		return 1;
 	default:
 	default:
 		break;
 		break;
 	}
 	}
@@ -115,7 +124,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 	case S_HEX:
 	case S_HEX:
 	case S_STRING:
 	case S_STRING:
 		printf("%s\n", def);
 		printf("%s\n", def);
-		return;
+		return 1;
 	default:
 	default:
 		;
 		;
 	}
 	}
@@ -152,7 +161,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 		}
 		}
 	case set_random:
 	case set_random:
 		do {
 		do {
-			val = (tristate)(random() % 3);
+			val = (tristate)(rand() % 3);
 		} while (!sym_tristate_within_range(sym, val));
 		} while (!sym_tristate_within_range(sym, val));
 		switch (val) {
 		switch (val) {
 		case no: line[0] = 'n'; break;
 		case no: line[0] = 'n'; break;
@@ -166,30 +175,29 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 		break;
 		break;
 	}
 	}
 	printf("%s", line);
 	printf("%s", line);
+	return 1;
 }
 }
 
 
 int conf_string(struct menu *menu)
 int conf_string(struct menu *menu)
 {
 {
 	struct symbol *sym = menu->sym;
 	struct symbol *sym = menu->sym;
-	const char *def, *help;
+	const char *def;
 
 
 	while (1) {
 	while (1) {
-		printf("%*s%s ", indent - 1, "", menu->prompt->text);
+		printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
 		printf("(%s) ", sym->name);
 		printf("(%s) ", sym->name);
 		def = sym_get_string_value(sym);
 		def = sym_get_string_value(sym);
 		if (sym_get_string_value(sym))
 		if (sym_get_string_value(sym))
 			printf("[%s] ", def);
 			printf("[%s] ", def);
-		conf_askvalue(sym, def);
+		if (!conf_askvalue(sym, def))
+			return 0;
 		switch (line[0]) {
 		switch (line[0]) {
 		case '\n':
 		case '\n':
 			break;
 			break;
 		case '?':
 		case '?':
 			/* print help */
 			/* print help */
 			if (line[1] == '\n') {
 			if (line[1] == '\n') {
-				help = nohelp_text;
+				printf("\n%s\n", get_help(menu));
-				if (menu->sym->help)
-					help = menu->sym->help;
-				printf("\n%s\n", menu->sym->help);
 				def = NULL;
 				def = NULL;
 				break;
 				break;
 			}
 			}
@@ -207,10 +215,9 @@ static int conf_sym(struct menu *menu)
 	struct symbol *sym = menu->sym;
 	struct symbol *sym = menu->sym;
 	int type;
 	int type;
 	tristate oldval, newval;
 	tristate oldval, newval;
-	const char *help;
 
 
 	while (1) {
 	while (1) {
-		printf("%*s%s ", indent - 1, "", menu->prompt->text);
+		printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
 		if (sym->name)
 		if (sym->name)
 			printf("(%s) ", sym->name);
 			printf("(%s) ", sym->name);
 		type = sym_get_type(sym);
 		type = sym_get_type(sym);
@@ -233,10 +240,11 @@ static int conf_sym(struct menu *menu)
 			printf("/m");
 			printf("/m");
 		if (oldval != yes && sym_tristate_within_range(sym, yes))
 		if (oldval != yes && sym_tristate_within_range(sym, yes))
 			printf("/y");
 			printf("/y");
-		if (sym->help)
+		if (menu_has_help(menu))
 			printf("/?");
 			printf("/?");
 		printf("] ");
 		printf("] ");
-		conf_askvalue(sym, sym_get_string_value(sym));
+		if (!conf_askvalue(sym, sym_get_string_value(sym)))
+			return 0;
 		strip(line);
 		strip(line);
 
 
 		switch (line[0]) {
 		switch (line[0]) {
@@ -269,10 +277,7 @@ static int conf_sym(struct menu *menu)
 		if (sym_set_tristate_value(sym, newval))
 		if (sym_set_tristate_value(sym, newval))
 			return 0;
 			return 0;
 help:
 help:
-		help = nohelp_text;
+		printf("\n%s\n", get_help(menu));
-		if (sym->help)
-			help = sym->help;
-		printf("\n%s\n", help);
 	}
 	}
 }
 }
 
 
@@ -302,7 +307,7 @@ static int conf_choice(struct menu *menu)
 		case no:
 		case no:
 			return 1;
 			return 1;
 		case mod:
 		case mod:
-			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+			printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
 			return 0;
 			return 0;
 		case yes:
 		case yes:
 			break;
 			break;
@@ -312,7 +317,7 @@ static int conf_choice(struct menu *menu)
 	while (1) {
 	while (1) {
 		int cnt, def;
 		int cnt, def;
 
 
-		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+		printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
 		def_sym = sym_get_choice_value(sym);
 		def_sym = sym_get_choice_value(sym);
 		cnt = def = 0;
 		cnt = def = 0;
 		line[0] = 0;
 		line[0] = 0;
@@ -320,7 +325,7 @@ static int conf_choice(struct menu *menu)
 			if (!menu_is_visible(child))
 			if (!menu_is_visible(child))
 				continue;
 				continue;
 			if (!child->sym) {
 			if (!child->sym) {
-				printf("%*c %s\n", indent, '*', menu_get_prompt(child));
+				printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
 				continue;
 				continue;
 			}
 			}
 			cnt++;
 			cnt++;
@@ -329,20 +334,20 @@ static int conf_choice(struct menu *menu)
 				printf("%*c", indent, '>');
 				printf("%*c", indent, '>');
 			} else
 			} else
 				printf("%*c", indent, ' ');
 				printf("%*c", indent, ' ');
-			printf(" %d. %s", cnt, menu_get_prompt(child));
+			printf(" %d. %s", cnt, _(menu_get_prompt(child)));
 			if (child->sym->name)
 			if (child->sym->name)
 				printf(" (%s)", child->sym->name);
 				printf(" (%s)", child->sym->name);
 			if (!sym_has_value(child->sym))
 			if (!sym_has_value(child->sym))
-				printf(" (NEW)");
+				printf(_(" (NEW)"));
 			printf("\n");
 			printf("\n");
 		}
 		}
-		printf("%*schoice", indent - 1, "");
+		printf(_("%*schoice"), indent - 1, "");
 		if (cnt == 1) {
 		if (cnt == 1) {
 			printf("[1]: 1\n");
 			printf("[1]: 1\n");
 			goto conf_childs;
 			goto conf_childs;
 		}
 		}
 		printf("[1-%d", cnt);
 		printf("[1-%d", cnt);
-		if (sym->help)
+		if (menu_has_help(menu))
 			printf("?");
 			printf("?");
 		printf("]: ");
 		printf("]: ");
 		switch (input_mode) {
 		switch (input_mode) {
@@ -359,8 +364,7 @@ static int conf_choice(struct menu *menu)
 			fgets(line, 128, stdin);
 			fgets(line, 128, stdin);
 			strip(line);
 			strip(line);
 			if (line[0] == '?') {
 			if (line[0] == '?') {
-				printf("\n%s\n", menu->sym->help ?
+				printf("\n%s\n", get_help(menu));
-					menu->sym->help : nohelp_text);
 				continue;
 				continue;
 			}
 			}
 			if (!line[0])
 			if (!line[0])
@@ -371,7 +375,8 @@ static int conf_choice(struct menu *menu)
 				continue;
 				continue;
 			break;
 			break;
 		case set_random:
 		case set_random:
-			def = (random() % cnt) + 1;
+			if (is_new)
+				def = (rand() % cnt) + 1;
 		case set_default:
 		case set_default:
 		case set_yes:
 		case set_yes:
 		case set_mod:
 		case set_mod:
@@ -391,14 +396,13 @@ static int conf_choice(struct menu *menu)
 		if (!child)
 		if (!child)
 			continue;
 			continue;
 		if (line[strlen(line) - 1] == '?') {
 		if (line[strlen(line) - 1] == '?') {
-			printf("\n%s\n", child->sym->help ?
+			printf("\n%s\n", get_help(child));
-				child->sym->help : nohelp_text);
 			continue;
 			continue;
 		}
 		}
 		sym_set_choice_value(sym, child->sym);
 		sym_set_choice_value(sym, child->sym);
-		if (child->list) {
+		for (child = child->list; child; child = child->next) {
 			indent += 2;
 			indent += 2;
-			conf(child->list);
+			conf(child);
 			indent -= 2;
 			indent -= 2;
 		}
 		}
 		return 1;
 		return 1;
@@ -430,7 +434,7 @@ static void conf(struct menu *menu)
 			if (prompt)
 			if (prompt)
 				printf("%*c\n%*c %s\n%*c\n",
 				printf("%*c\n%*c %s\n%*c\n",
 					indent, '*',
 					indent, '*',
-					indent, '*', prompt,
+					indent, '*', _(prompt),
 					indent, '*');
 					indent, '*');
 		default:
 		default:
 			;
 			;
@@ -492,12 +496,16 @@ static void check_conf(struct menu *menu)
 
 
 int main(int ac, char **av)
 int main(int ac, char **av)
 {
 {
-	int i = 1;
+	int opt;
 	const char *name;
 	const char *name;
 	struct stat tmpstat;
 	struct stat tmpstat;
 
 
-	if (ac > i && av[i][0] == '-') {
+	setlocale(LC_ALL, "");
-		switch (av[i++][1]) {
+	bindtextdomain(PACKAGE, LOCALEDIR);
+	textdomain(PACKAGE);
+
+	while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+		switch (opt) {
 		case 'o':
 		case 'o':
 			input_mode = ask_new;
 			input_mode = ask_new;
 			break;
 			break;
@@ -510,12 +518,7 @@ int main(int ac, char **av)
 			break;
 			break;
 		case 'D':
 		case 'D':
 			input_mode = set_default;
 			input_mode = set_default;
-			defconfig_file = av[i++];
+			defconfig_file = optarg;
-			if (!defconfig_file) {
-				printf(_("%s: No default config file specified\n"),
-					av[0]);
-				exit(1);
-			}
 			break;
 			break;
 		case 'n':
 		case 'n':
 			input_mode = set_no;
 			input_mode = set_no;
@@ -528,19 +531,22 @@ int main(int ac, char **av)
 			break;
 			break;
 		case 'r':
 		case 'r':
 			input_mode = set_random;
 			input_mode = set_random;
-			srandom(time(NULL));
+			srand(time(NULL));
 			break;
 			break;
 		case 'h':
 		case 'h':
-		case '?':
+			printf(_("See README for usage info\n"));
-			fprintf(stderr, "See README for usage info\n");
 			exit(0);
 			exit(0);
+			break;
+		default:
+			fprintf(stderr, _("See README for usage info\n"));
+			exit(1);
 		}
 		}
 	}
 	}
-  	name = av[i];
+	if (ac == optind) {
-	if (!name) {
 		printf(_("%s: Kconfig file missing\n"), av[0]);
 		printf(_("%s: Kconfig file missing\n"), av[0]);
 		exit(1);
 		exit(1);
 	}
 	}
+	name = av[optind];
 	conf_parse(name);
 	conf_parse(name);
 	//zconfdump(stdout);
 	//zconfdump(stdout);
 	switch (input_mode) {
 	switch (input_mode) {
@@ -548,19 +554,20 @@ int main(int ac, char **av)
 		if (!defconfig_file)
 		if (!defconfig_file)
 			defconfig_file = conf_get_default_confname();
 			defconfig_file = conf_get_default_confname();
 		if (conf_read(defconfig_file)) {
 		if (conf_read(defconfig_file)) {
-			printf("***\n"
+			printf(_("***\n"
 				"*** Can't find default configuration \"%s\"!\n"
 				"*** Can't find default configuration \"%s\"!\n"
-				"***\n", defconfig_file);
+				"***\n"), defconfig_file);
 			exit(1);
 			exit(1);
 		}
 		}
 		break;
 		break;
 	case ask_silent:
 	case ask_silent:
 		if (stat(".config", &tmpstat)) {
 		if (stat(".config", &tmpstat)) {
 			printf(_("***\n"
 			printf(_("***\n"
-				"*** You have not yet configured uClibc!\n"
+				"*** You have not yet configured!\n"
+				"*** (missing .config file)\n"
 				"***\n"
 				"***\n"
 				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
 				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
-				"*** \"make menuconfig\" or \"make config\").\n"
+				"*** \"make menuconfig\" or \"make xconfig\").\n"
 				"***\n"));
 				"***\n"));
 			exit(1);
 			exit(1);
 		}
 		}
@@ -603,7 +610,7 @@ int main(int ac, char **av)
 	} else if (conf_get_changed()) {
 	} else if (conf_get_changed()) {
 		name = getenv("KCONFIG_NOSILENTUPDATE");
 		name = getenv("KCONFIG_NOSILENTUPDATE");
 		if (name && *name) {
 		if (name && *name) {
-			fprintf(stderr, _("\n*** uClibc configuration requires explicit update.\n\n"));
+			fprintf(stderr, _("\n*** configuration requires explicit update.\n\n"));
 			return 1;
 			return 1;
 		}
 		}
 	} else
 	} else
@@ -614,12 +621,12 @@ int main(int ac, char **av)
 		check_conf(&rootmenu);
 		check_conf(&rootmenu);
 	} while (conf_cnt);
 	} while (conf_cnt);
 	if (conf_write(NULL)) {
 	if (conf_write(NULL)) {
-		fprintf(stderr, _("\n*** Error during writing of the uClibc configuration.\n\n"));
+		fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
 		return 1;
 		return 1;
 	}
 	}
 skip_check:
 skip_check:
 	if (/*input_mode == ask_silent &&*/ conf_write_autoconf()) {
 	if (/*input_mode == ask_silent &&*/ conf_write_autoconf()) {
-		fprintf(stderr, _("\n*** Error during writing of the uClibc configuration.\n\n"));
+		fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
 		return 1;
 		return 1;
 	}
 	}
 
 

+ 97 - 77
extra/config/confdata.c

@@ -83,6 +83,68 @@ char *conf_get_default_confname(void)
 	return name;
 	return name;
 }
 }
 
 
+static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
+{
+	char *p2;
+
+	switch (sym->type) {
+	case S_TRISTATE:
+		if (p[0] == 'm') {
+			sym->def[def].tri = mod;
+			sym->flags |= def_flags;
+			break;
+		}
+	case S_BOOLEAN:
+		if (p[0] == 'y') {
+			sym->def[def].tri = yes;
+			sym->flags |= def_flags;
+			break;
+		}
+		if (p[0] == 'n') {
+			sym->def[def].tri = no;
+			sym->flags |= def_flags;
+			break;
+		}
+		conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+		break;
+	case S_OTHER:
+		if (*p != '"') {
+			for (p2 = p; *p2 && !isspace(*p2); p2++)
+				;
+			sym->type = S_STRING;
+			goto done;
+		}
+	case S_STRING:
+		if (*p++ != '"')
+			break;
+		for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+			if (*p2 == '"') {
+				*p2 = 0;
+				break;
+			}
+			memmove(p2, p2 + 1, strlen(p2));
+		}
+		if (!p2) {
+			conf_warning("invalid string found");
+			return 1;
+		}
+	case S_INT:
+	case S_HEX:
+	done:
+		if (sym_string_valid(sym, p)) {
+			sym->def[def].val = strdup(p);
+			sym->flags |= def_flags;
+		} else {
+			conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+			return 1;
+		}
+		break;
+	default:
+		;
+	}
+	return 0;
+}
+
 int conf_read_simple(const char *name, int def)
 int conf_read_simple(const char *name, int def)
 {
 {
 	FILE *in = NULL;
 	FILE *in = NULL;
@@ -170,8 +232,7 @@ load:
 					sym->type = S_BOOLEAN;
 					sym->type = S_BOOLEAN;
 			}
 			}
 			if (sym->flags & def_flags) {
 			if (sym->flags & def_flags) {
-				conf_warning("trying to reassign symbol %s", sym->name);
+				conf_warning("override: reassigning to symbol %s", sym->name);
-				break;
 			}
 			}
 			switch (sym->type) {
 			switch (sym->type) {
 			case S_BOOLEAN:
 			case S_BOOLEAN:
@@ -206,64 +267,10 @@ load:
 					sym->type = S_OTHER;
 					sym->type = S_OTHER;
 			}
 			}
 			if (sym->flags & def_flags) {
 			if (sym->flags & def_flags) {
-				conf_warning("trying to reassign symbol %s", sym->name);
+				conf_warning("override: reassigning to symbol %s", sym->name);
-				break;
-			}
-			switch (sym->type) {
-			case S_TRISTATE:
-				if (p[0] == 'm') {
-					sym->def[def].tri = mod;
-					sym->flags |= def_flags;
-					break;
-				}
-			case S_BOOLEAN:
-				if (p[0] == 'y') {
-					sym->def[def].tri = yes;
-					sym->flags |= def_flags;
-					break;
-				}
-				if (p[0] == 'n') {
-					sym->def[def].tri = no;
-					sym->flags |= def_flags;
-					break;
-				}
-				conf_warning("symbol value '%s' invalid for %s", p, sym->name);
-				break;
-			case S_OTHER:
-				if (*p != '"') {
-					for (p2 = p; *p2 && !isspace(*p2); p2++)
-						;
-					sym->type = S_STRING;
-					goto done;
-				}
-			case S_STRING:
-				if (*p++ != '"')
-					break;
-				for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
-					if (*p2 == '"') {
-						*p2 = 0;
-						break;
-					}
-					memmove(p2, p2 + 1, strlen(p2));
-				}
-				if (!p2) {
-					conf_warning("invalid string found");
-					continue;
-				}
-			case S_INT:
-			case S_HEX:
-			done:
-				if (sym_string_valid(sym, p)) {
-					sym->def[def].val = strdup(p);
-					sym->flags |= def_flags;
-				} else {
-					conf_warning("symbol value '%s' invalid for %s", p, sym->name);
-					continue;
-				}
-				break;
-			default:
-				;
 			}
 			}
+			if (conf_set_sym_val(sym, def, def_flags, p))
+				continue;
 			break;
 			break;
 		case '\r':
 		case '\r':
 		case '\n':
 		case '\n':
@@ -284,14 +291,12 @@ load:
 				}
 				}
 				break;
 				break;
 			case yes:
 			case yes:
-				if (cs->def[def].tri != no) {
+				if (cs->def[def].tri != no)
-					conf_warning("%s creates inconsistent choice state", sym->name);
+					conf_warning("override: %s changes choice state", sym->name);
-					cs->flags &= ~def_flags;
+				cs->def[def].val = sym;
-				} else
-					cs->def[def].val = sym;
 				break;
 				break;
 			}
 			}
-			cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
+			cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
 		}
 		}
 	}
 	}
 	fclose(in);
 	fclose(in);
@@ -303,7 +308,7 @@ load:
 
 
 int conf_read(const char *name)
 int conf_read(const char *name)
 {
 {
-	struct symbol *sym;
+	struct symbol *sym, *choice_sym;
 	struct property *prop;
 	struct property *prop;
 	struct expr *e;
 	struct expr *e;
 	int i, flags;
 	int i, flags;
@@ -337,27 +342,42 @@ int conf_read(const char *name)
 		conf_unsaved++;
 		conf_unsaved++;
 		/* maybe print value in verbose mode... */
 		/* maybe print value in verbose mode... */
 	sym_ok:
 	sym_ok:
+		if (!sym_is_choice(sym))
+			continue;
+		/* The choice symbol only has a set value (and thus is not new)
+		 * if all its visible childs have values.
+		 */
+		prop = sym_get_choice_prop(sym);
+		flags = sym->flags;
+		expr_list_for_each_sym(prop->expr, e, choice_sym)
+			if (choice_sym->visible != no)
+				flags &= choice_sym->flags;
+		sym->flags &= flags | ~SYMBOL_DEF_USER;
+	}
+
+	for_all_symbols(i, sym) {
 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
-			if (sym->visible == no)
+			/* Reset values of generates values, so they'll appear
+			 * as new, if they should become visible, but that
+			 * doesn't quite work if the Kconfig and the saved
+			 * configuration disagree.
+			 */
+			if (sym->visible == no && !conf_unsaved)
 				sym->flags &= ~SYMBOL_DEF_USER;
 				sym->flags &= ~SYMBOL_DEF_USER;
 			switch (sym->type) {
 			switch (sym->type) {
 			case S_STRING:
 			case S_STRING:
 			case S_INT:
 			case S_INT:
 			case S_HEX:
 			case S_HEX:
-				if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+				/* Reset a string value if it's out of range */
-					sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+					break;
+				sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				conf_unsaved++;
+				break;
 			default:
 			default:
 				break;
 				break;
 			}
 			}
 		}
 		}
-		if (!sym_is_choice(sym))
-			continue;
-		prop = sym_get_choice_prop(sym);
-		flags = sym->flags;
-		for (e = prop->expr; e; e = e->left.expr)
-			if (e->right.sym->visible != no)
-				flags &= e->right.sym->flags;
-		sym->flags &= flags | ~SYMBOL_DEF_USER;
 	}
 	}
 
 
 	sym_add_change_count(conf_warnings || conf_unsaved);
 	sym_add_change_count(conf_warnings || conf_unsaved);

+ 19 - 13
extra/config/expr.c

@@ -87,7 +87,7 @@ struct expr *expr_copy(struct expr *org)
 		break;
 		break;
 	case E_AND:
 	case E_AND:
 	case E_OR:
 	case E_OR:
-	case E_CHOICE:
+	case E_LIST:
 		e->left.expr = expr_copy(org->left.expr);
 		e->left.expr = expr_copy(org->left.expr);
 		e->right.expr = expr_copy(org->right.expr);
 		e->right.expr = expr_copy(org->right.expr);
 		break;
 		break;
@@ -217,7 +217,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
 		expr_free(e2);
 		expr_free(e2);
 		trans_count = old_count;
 		trans_count = old_count;
 		return res;
 		return res;
-	case E_CHOICE:
+	case E_LIST:
 	case E_RANGE:
 	case E_RANGE:
 	case E_NONE:
 	case E_NONE:
 		/* panic */;
 		/* panic */;
@@ -648,7 +648,7 @@ struct expr *expr_transform(struct expr *e)
 	case E_EQUAL:
 	case E_EQUAL:
 	case E_UNEQUAL:
 	case E_UNEQUAL:
 	case E_SYMBOL:
 	case E_SYMBOL:
-	case E_CHOICE:
+	case E_LIST:
 		break;
 		break;
 	default:
 	default:
 		e->left.expr = expr_transform(e->left.expr);
 		e->left.expr = expr_transform(e->left.expr);
@@ -932,7 +932,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
 		break;
 		break;
 	case E_SYMBOL:
 	case E_SYMBOL:
 		return expr_alloc_comp(type, e->left.sym, sym);
 		return expr_alloc_comp(type, e->left.sym, sym);
-	case E_CHOICE:
+	case E_LIST:
 	case E_RANGE:
 	case E_RANGE:
 	case E_NONE:
 	case E_NONE:
 		/* panic */;
 		/* panic */;
@@ -955,14 +955,14 @@ tristate expr_calc_value(struct expr *e)
 	case E_AND:
 	case E_AND:
 		val1 = expr_calc_value(e->left.expr);
 		val1 = expr_calc_value(e->left.expr);
 		val2 = expr_calc_value(e->right.expr);
 		val2 = expr_calc_value(e->right.expr);
-		return E_AND(val1, val2);
+		return EXPR_AND(val1, val2);
 	case E_OR:
 	case E_OR:
 		val1 = expr_calc_value(e->left.expr);
 		val1 = expr_calc_value(e->left.expr);
 		val2 = expr_calc_value(e->right.expr);
 		val2 = expr_calc_value(e->right.expr);
-		return E_OR(val1, val2);
+		return EXPR_OR(val1, val2);
 	case E_NOT:
 	case E_NOT:
 		val1 = expr_calc_value(e->left.expr);
 		val1 = expr_calc_value(e->left.expr);
-		return E_NOT(val1);
+		return EXPR_NOT(val1);
 	case E_EQUAL:
 	case E_EQUAL:
 		sym_calc_value(e->left.sym);
 		sym_calc_value(e->left.sym);
 		sym_calc_value(e->right.sym);
 		sym_calc_value(e->right.sym);
@@ -1000,9 +1000,9 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
 		if (t2 == E_OR)
 		if (t2 == E_OR)
 			return 1;
 			return 1;
 	case E_OR:
 	case E_OR:
-		if (t2 == E_CHOICE)
+		if (t2 == E_LIST)
 			return 1;
 			return 1;
-	case E_CHOICE:
+	case E_LIST:
 		if (t2 == 0)
 		if (t2 == 0)
 			return 1;
 			return 1;
 	default:
 	default:
@@ -1034,12 +1034,18 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
 		expr_print(e->left.expr, fn, data, E_NOT);
 		expr_print(e->left.expr, fn, data, E_NOT);
 		break;
 		break;
 	case E_EQUAL:
 	case E_EQUAL:
-		fn(data, e->left.sym, e->left.sym->name);
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
 		fn(data, NULL, "=");
 		fn(data, NULL, "=");
 		fn(data, e->right.sym, e->right.sym->name);
 		fn(data, e->right.sym, e->right.sym->name);
 		break;
 		break;
 	case E_UNEQUAL:
 	case E_UNEQUAL:
-		fn(data, e->left.sym, e->left.sym->name);
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
 		fn(data, NULL, "!=");
 		fn(data, NULL, "!=");
 		fn(data, e->right.sym, e->right.sym->name);
 		fn(data, e->right.sym, e->right.sym->name);
 		break;
 		break;
@@ -1053,11 +1059,11 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
 		fn(data, NULL, " && ");
 		fn(data, NULL, " && ");
 		expr_print(e->right.expr, fn, data, E_AND);
 		expr_print(e->right.expr, fn, data, E_AND);
 		break;
 		break;
-	case E_CHOICE:
+	case E_LIST:
 		fn(data, e->right.sym, e->right.sym->name);
 		fn(data, e->right.sym, e->right.sym->name);
 		if (e->left.expr) {
 		if (e->left.expr) {
 			fn(data, NULL, " ^ ");
 			fn(data, NULL, " ^ ");
-			expr_print(e->left.expr, fn, data, E_CHOICE);
+			expr_print(e->left.expr, fn, data, E_LIST);
 		}
 		}
 		break;
 		break;
 	case E_RANGE:
 	case E_RANGE:

+ 10 - 10
extra/config/expr.h

@@ -25,14 +25,13 @@ struct file {
 
 
 #define FILE_BUSY		0x0001
 #define FILE_BUSY		0x0001
 #define FILE_SCANNED		0x0002
 #define FILE_SCANNED		0x0002
-#define FILE_PRINTED		0x0004
 
 
 typedef enum tristate {
 typedef enum tristate {
 	no, mod, yes
 	no, mod, yes
 } tristate;
 } tristate;
 
 
 enum expr_type {
 enum expr_type {
-	E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+	E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
 };
 };
 
 
 union expr_data {
 union expr_data {
@@ -45,9 +44,12 @@ struct expr {
 	union expr_data left, right;
 	union expr_data left, right;
 };
 };
 
 
-#define E_OR(dep1, dep2)	(((dep1)>(dep2))?(dep1):(dep2))
+#define EXPR_OR(dep1, dep2)	(((dep1)>(dep2))?(dep1):(dep2))
-#define E_AND(dep1, dep2)	(((dep1)<(dep2))?(dep1):(dep2))
+#define EXPR_AND(dep1, dep2)	(((dep1)<(dep2))?(dep1):(dep2))
-#define E_NOT(dep)		(2-(dep))
+#define EXPR_NOT(dep)		(2-(dep))
+
+#define expr_list_for_each_sym(l, e, s) \
+	for (e = (l); e && (s = e->right.sym); e = e->left.expr)
 
 
 struct expr_value {
 struct expr_value {
 	struct expr *expr;
 	struct expr *expr;
@@ -71,14 +73,12 @@ enum {
 struct symbol {
 struct symbol {
 	struct symbol *next;
 	struct symbol *next;
 	char *name;
 	char *name;
-	char *help;
 	enum symbol_type type;
 	enum symbol_type type;
 	struct symbol_value curr;
 	struct symbol_value curr;
 	struct symbol_value def[4];
 	struct symbol_value def[4];
 	tristate visible;
 	tristate visible;
 	int flags;
 	int flags;
 	struct property *prop;
 	struct property *prop;
-	struct expr *dep, *dep2;
 	struct expr_value rev_dep;
 	struct expr_value rev_dep;
 };
 };
 
 
@@ -88,7 +88,6 @@ struct symbol {
 #define SYMBOL_CHECK		0x0008
 #define SYMBOL_CHECK		0x0008
 #define SYMBOL_CHOICE		0x0010
 #define SYMBOL_CHOICE		0x0010
 #define SYMBOL_CHOICEVAL	0x0020
 #define SYMBOL_CHOICEVAL	0x0020
-#define SYMBOL_PRINTED		0x0040
 #define SYMBOL_VALID		0x0080
 #define SYMBOL_VALID		0x0080
 #define SYMBOL_OPTIONAL		0x0100
 #define SYMBOL_OPTIONAL		0x0100
 #define SYMBOL_WRITE		0x0200
 #define SYMBOL_WRITE		0x0200
@@ -107,7 +106,8 @@ struct symbol {
 #define SYMBOL_HASHMASK		0xff
 #define SYMBOL_HASHMASK		0xff
 
 
 enum prop_type {
 enum prop_type {
-	P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+	P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE,
+	P_SELECT, P_RANGE, P_ENV
 };
 };
 
 
 struct property {
 struct property {
@@ -139,7 +139,7 @@ struct menu {
 	struct property *prompt;
 	struct property *prompt;
 	struct expr *dep;
 	struct expr *dep;
 	unsigned int flags;
 	unsigned int flags;
-	//char *help;
+	char *help;
 	struct file *file;
 	struct file *file;
 	int lineno;
 	int lineno;
 	void *data;
 	void *data;

+ 12 - 16
extra/config/gconf.c

@@ -38,9 +38,6 @@ static gboolean show_all = FALSE;
 static gboolean show_debug = FALSE;
 static gboolean show_debug = FALSE;
 static gboolean resizeable = FALSE;
 static gboolean resizeable = FALSE;
 
 
-static char nohelp_text[] =
-    N_("Sorry, no help available for this option yet.\n");
-
 GtkWidget *main_wnd = NULL;
 GtkWidget *main_wnd = NULL;
 GtkWidget *tree1_w = NULL;	// left  frame
 GtkWidget *tree1_w = NULL;	// left  frame
 GtkWidget *tree2_w = NULL;	// right frame
 GtkWidget *tree2_w = NULL;	// right frame
@@ -122,8 +119,6 @@ const char *dbg_print_flags(int val)
 		strcat(buf, "choice/");
 		strcat(buf, "choice/");
 	if (val & SYMBOL_CHOICEVAL)
 	if (val & SYMBOL_CHOICEVAL)
 		strcat(buf, "choiceval/");
 		strcat(buf, "choiceval/");
-	if (val & SYMBOL_PRINTED)
-		strcat(buf, "printed/");
 	if (val & SYMBOL_VALID)
 	if (val & SYMBOL_VALID)
 		strcat(buf, "valid/");
 		strcat(buf, "valid/");
 	if (val & SYMBOL_OPTIONAL)
 	if (val & SYMBOL_OPTIONAL)
@@ -460,17 +455,18 @@ static void text_insert_help(struct menu *menu)
 {
 {
 	GtkTextBuffer *buffer;
 	GtkTextBuffer *buffer;
 	GtkTextIter start, end;
 	GtkTextIter start, end;
-	const char *prompt = menu_get_prompt(menu);
+	const char *prompt = _(menu_get_prompt(menu));
 	gchar *name;
 	gchar *name;
-	const char *help = _(nohelp_text);
+	const char *help;
 
 
-	if (!menu->sym)
+	help = menu_get_help(menu);
-		help = "";
+
-	else if (menu->sym->help)
+	/* Gettextize if the help text not empty */
-		help = _(menu->sym->help);
+	if ((help != 0) && (help[0] != 0))
+		help = _(help);
 
 
 	if (menu->sym && menu->sym->name)
 	if (menu->sym && menu->sym->name)
-		name = g_strdup_printf(_(menu->sym->name));
+		name = g_strdup_printf(menu->sym->name);
 	else
 	else
 		name = g_strdup("");
 		name = g_strdup("");
 
 
@@ -735,8 +731,8 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
 {
 	GtkWidget *dialog;
 	GtkWidget *dialog;
 	const gchar *intro_text = _(
 	const gchar *intro_text = _(
-	    "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
+	    "Welcome to gkc, the GTK+ graphical configuration tool\n"
-	    "for Linux.\n"
+	    "for uClibc.\n"
 	    "For each option, a blank box indicates the feature is disabled, a\n"
 	    "For each option, a blank box indicates the feature is disabled, a\n"
 	    "check indicates it is enabled, and a dot indicates that it is to\n"
 	    "check indicates it is enabled, and a dot indicates that it is to\n"
 	    "be compiled as a module.  Clicking on the box will cycle through the three states.\n"
 	    "be compiled as a module.  Clicking on the box will cycle through the three states.\n"
@@ -1177,7 +1173,7 @@ static gchar **fill_row(struct menu *menu)
 	bzero(row, sizeof(row));
 	bzero(row, sizeof(row));
 
 
 	row[COL_OPTION] =
 	row[COL_OPTION] =
-	    g_strdup_printf("%s %s", menu_get_prompt(menu),
+	    g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
 			    sym && sym_has_value(sym) ? "(NEW)" : "");
 			    sym && sym_has_value(sym) ? "(NEW)" : "");
 
 
 	if (show_all && !menu_is_visible(menu))
 	if (show_all && !menu_is_visible(menu))
@@ -1227,7 +1223,7 @@ static gchar **fill_row(struct menu *menu)
 
 
 		if (def_menu)
 		if (def_menu)
 			row[COL_VALUE] =
 			row[COL_VALUE] =
-			    g_strdup(menu_get_prompt(def_menu));
+			    g_strdup(_(menu_get_prompt(def_menu)));
 	}
 	}
 	if (sym->flags & SYMBOL_CHOICEVAL)
 	if (sym->flags & SYMBOL_CHOICEVAL)
 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);

+ 1 - 1
extra/config/gconf.glade

@@ -5,7 +5,7 @@
 
 
 <widget class="GtkWindow" id="window1">
 <widget class="GtkWindow" id="window1">
   <property name="visible">True</property>
   <property name="visible">True</property>
-  <property name="title" translatable="yes">Gtk Kernel Configurator</property>
+  <property name="title" translatable="yes">Gtk uClibc Configurator</property>
   <property name="type">GTK_WINDOW_TOPLEVEL</property>
   <property name="type">GTK_WINDOW_TOPLEVEL</property>
   <property name="window_position">GTK_WIN_POS_NONE</property>
   <property name="window_position">GTK_WIN_POS_NONE</property>
   <property name="modal">False</property>
   <property name="modal">False</property>

+ 126 - 6
extra/config/kconfig-language.txt

@@ -24,7 +24,7 @@ visible if its parent entry is also visible.
 Menu entries
 Menu entries
 ------------
 ------------
 
 
-Most entries define a config option, all other entries help to organize
+Most entries define a config option; all other entries help to organize
 them. A single configuration option is defined like this:
 them. A single configuration option is defined like this:
 
 
 config MODVERSIONS
 config MODVERSIONS
@@ -50,7 +50,7 @@ applicable everywhere (see syntax).
 
 
 - type definition: "bool"/"tristate"/"string"/"hex"/"int"
 - type definition: "bool"/"tristate"/"string"/"hex"/"int"
   Every config option must have a type. There are only two basic types:
   Every config option must have a type. There are only two basic types:
-  tristate and string, the other types are based on these two. The type
+  tristate and string; the other types are based on these two. The type
   definition optionally accepts an input prompt, so these two examples
   definition optionally accepts an input prompt, so these two examples
   are equivalent:
   are equivalent:
 
 
@@ -77,7 +77,12 @@ applicable everywhere (see syntax).
   Optionally, dependencies only for this default value can be added with
   Optionally, dependencies only for this default value can be added with
   "if".
   "if".
 
 
-- dependencies: "depends on"/"requires" <expr>
+- type definition + default value:
+	"def_bool"/"def_tristate" <expr> ["if" <expr>]
+  This is a shorthand notation for a type definition plus a value.
+  Optionally dependencies for this default value can be added with "if".
+
+- dependencies: "depends on" <expr>
   This defines a dependency for this menu entry. If multiple
   This defines a dependency for this menu entry. If multiple
   dependencies are defined, they are connected with '&&'. Dependencies
   dependencies are defined, they are connected with '&&'. Dependencies
   are applied to all other options within this menu entry (which also
   are applied to all other options within this menu entry (which also
@@ -98,6 +103,15 @@ applicable everywhere (see syntax).
   times, the limit is set to the largest selection.
   times, the limit is set to the largest selection.
   Reverse dependencies can only be used with boolean or tristate
   Reverse dependencies can only be used with boolean or tristate
   symbols.
   symbols.
+  Note:
+	select is evil.... select will by brute force set a symbol
+	equal to 'y' without visiting the dependencies. So abusing
+	select you are able to select a symbol FOO even if FOO depends
+	on BAR that is not set. In general use select only for
+	non-visible symbols (no prompts anywhere) and for symbols with
+	no dependencies. That will limit the usefulness but on the
+	other hand avoid the illegal configurations all over. kconfig
+	should one day warn about such things.
 
 
 - numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
 - numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
   This allows to limit the range of possible input values for int
   This allows to limit the range of possible input values for int
@@ -113,6 +127,27 @@ applicable everywhere (see syntax).
   used to help visually separate configuration logic from help within
   used to help visually separate configuration logic from help within
   the file as an aid to developers.
   the file as an aid to developers.
 
 
+- misc options: "option" <symbol>[=<value>]
+  Various less common options can be defined via this option syntax,
+  which can modify the behaviour of the menu entry and its config
+  symbol. These options are currently possible:
+
+  - "defconfig_list"
+    This declares a list of default entries which can be used when
+    looking for the default configuration (which is used when the main
+    .config doesn't exists yet.)
+
+  - "modules"
+    This declares the symbol to be used as the MODULES symbol, which
+    enables the third modular state for all config symbols.
+
+  - "env"=<value>
+    This imports the environment variable into Kconfig. It behaves like
+    a default, except that the value comes from the environment, this
+    also means that the behaviour when mixing it with normal defaults is
+    undefined at this point. The symbol is currently not exported back
+    to the build environment (if this is desired, it can be done via
+    another symbol).
 
 
 Menu dependencies
 Menu dependencies
 -----------------
 -----------------
@@ -148,9 +183,9 @@ An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
 respectively for calculations). A menu entry becomes visible when it's
 respectively for calculations). A menu entry becomes visible when it's
 expression evaluates to 'm' or 'y'.
 expression evaluates to 'm' or 'y'.
 
 
-There are two types of symbols: constant and nonconstant symbols.
+There are two types of symbols: constant and non-constant symbols.
-Nonconstant symbols are the most common ones and are defined with the
+Non-constant symbols are the most common ones and are defined with the
-'config' statement. Nonconstant symbols consist entirely of alphanumeric
+'config' statement. Non-constant symbols consist entirely of alphanumeric
 characters or underscores.
 characters or underscores.
 Constant symbols are only part of expressions. Constant symbols are
 Constant symbols are only part of expressions. Constant symbols are
 always surrounded by single or double quotes. Within the quote, any
 always surrounded by single or double quotes. Within the quote, any
@@ -280,3 +315,88 @@ source:
 	"source" <prompt>
 	"source" <prompt>
 
 
 This reads the specified configuration file. This file is always parsed.
 This reads the specified configuration file. This file is always parsed.
+
+mainmenu:
+
+	"mainmenu" <prompt>
+
+This sets the config program's title bar if the config program chooses
+to use it.
+
+
+Kconfig hints
+-------------
+This is a collection of Kconfig tips, most of which aren't obvious at
+first glance and most of which have become idioms in several Kconfig
+files.
+
+Adding common features and make the usage configurable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It is a common idiom to implement a feature/functionality that are
+relevant for some architectures but not all.
+The recommended way to do so is to use a config variable named HAVE_*
+that is defined in a common Kconfig file and selected by the relevant
+architectures.
+An example is the generic IOMAP functionality.
+
+We would in lib/Kconfig see:
+
+# Generic IOMAP is used to ...
+config HAVE_GENERIC_IOMAP
+
+config GENERIC_IOMAP
+	depends on HAVE_GENERIC_IOMAP && FOO
+
+And in lib/Makefile we would see:
+obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
+
+For each architecture using the generic IOMAP functionality we would see:
+
+config X86
+	select ...
+	select HAVE_GENERIC_IOMAP
+	select ...
+
+Note: we use the existing config option and avoid creating a new
+config variable to select HAVE_GENERIC_IOMAP.
+
+Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is
+introduced to overcome the limitation of select which will force a
+config option to 'y' no matter the dependencies.
+The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the
+situation where select forces a symbol equals to 'y'.
+
+Build as module only
+~~~~~~~~~~~~~~~~~~~~
+To restrict a component build to module-only, qualify its config symbol
+with "depends on m".  E.g.:
+
+config FOO
+	depends on BAR && m
+
+limits FOO to module (=m) or disabled (=n).
+
+
+Build limited by a third config symbol which may be =y or =m
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A common idiom that we see (and sometimes have problems with) is this:
+
+When option C in B (module or subsystem) uses interfaces from A (module
+or subsystem), and both A and B are tristate (could be =y or =m if they
+were independent of each other, but they aren't), then we need to limit
+C such that it cannot be built statically if A is built as a loadable
+module.  (C already depends on B, so there is no dependency issue to
+take care of here.)
+
+If A is linked statically into the kernel image, C can be built
+statically or as loadable module(s).  However, if A is built as loadable
+module(s), then C must be restricted to loadable module(s) also.  This
+can be expressed in kconfig language as:
+
+config C
+	depends on A = y || A = B
+
+or for real examples, use this command in a kernel tree:
+
+$ find . -name Kconfig\* | xargs grep -ns "depends on.*=.*||.*=" | grep -v orig
+

+ 5 - 3
extra/config/kxgettext.c

@@ -170,8 +170,8 @@ void menu_build_message_list(struct menu *menu)
 		     menu->file == NULL ? "Root Menu" : menu->file->name,
 		     menu->file == NULL ? "Root Menu" : menu->file->name,
 		     menu->lineno);
 		     menu->lineno);
 
 
-	if (menu->sym != NULL && menu->sym->help != NULL)
+	if (menu->sym != NULL && menu_has_help(menu))
-		message__add(menu->sym->help, menu->sym->name,
+		message__add(menu_get_help(menu), menu->sym->name,
 			     menu->file == NULL ? "Root Menu" : menu->file->name,
 			     menu->file == NULL ? "Root Menu" : menu->file->name,
 			     menu->lineno);
 			     menu->lineno);
 
 
@@ -212,7 +212,9 @@ void menu__xgettext(void)
 	struct message *m = message__list;
 	struct message *m = message__list;
 
 
 	while (m != NULL) {
 	while (m != NULL) {
-		message__print_gettext_msgid_msgstr(m);
+		/* skip empty lines ("") */
+		if (strlen(m->msg) > sizeof("\"\""))
+			message__print_gettext_msgid_msgstr(m);
 		m = m->next;
 		m = m->next;
 	}
 	}
 }
 }

+ 27 - 3
extra/config/lex.zconf.c_shipped

@@ -5,6 +5,25 @@
 
 
 /* A lexical scanner generated by flex */
 /* A lexical scanner generated by flex */
 
 
+#define yy_create_buffer zconf_create_buffer
+#define yy_delete_buffer zconf_delete_buffer
+#define yy_flex_debug zconf_flex_debug
+#define yy_init_buffer zconf_init_buffer
+#define yy_flush_buffer zconf_flush_buffer
+#define yy_load_buffer_state zconf_load_buffer_state
+#define yy_switch_to_buffer zconf_switch_to_buffer
+#define yyin zconfin
+#define yyleng zconfleng
+#define yylex zconflex
+#define yylineno zconflineno
+#define yyout zconfout
+#define yyrestart zconfrestart
+#define yytext zconftext
+#define yywrap zconfwrap
+#define yyalloc zconfalloc
+#define yyrealloc zconfrealloc
+#define yyfree zconffree
+
 #define FLEX_SCANNER
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
 #define YY_FLEX_MINOR_VERSION 5
@@ -335,7 +354,7 @@ void zconffree (void *  );
 
 
 /* Begin user sect3 */
 /* Begin user sect3 */
 
 
-#define zconfwrap() 1
+#define zconfwrap(n) 1
 #define YY_SKIP_YYWRAP
 #define YY_SKIP_YYWRAP
 
 
 typedef unsigned char YY_CHAR;
 typedef unsigned char YY_CHAR;
@@ -1256,6 +1275,11 @@ YY_RULE_SETUP
 case 32:
 case 32:
 YY_RULE_SETUP
 YY_RULE_SETUP
 {
 {
+		while (zconfleng) {
+			if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t'))
+				break;
+			zconfleng--;
+		}
 		append_string(zconftext, zconfleng);
 		append_string(zconftext, zconfleng);
 		if (!first_ts)
 		if (!first_ts)
 			first_ts = last_ts;
 			first_ts = last_ts;
@@ -1983,7 +2007,7 @@ YY_BUFFER_STATE zconf_scan_buffer  (char * base, yy_size_t  size )
 
 
 /** Setup the input buffer state to scan a string. The next call to zconflex() will
 /** Setup the input buffer state to scan a string. The next call to zconflex() will
  * scan from a @e copy of @a str.
  * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
+ * @param str a NUL-terminated string to scan
  * 
  * 
  * @return the newly allocated buffer state object.
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
  * @note If you want to scan bytes that may contain NUL values, then use
@@ -2264,7 +2288,7 @@ FILE *zconf_fopen(const char *name)
 	FILE *f;
 	FILE *f;
 
 
 	f = fopen(name, "r");
 	f = fopen(name, "r");
-	if (!f && name[0] != '/') {
+	if (!f && name != NULL && name[0] != '/') {
 		env = getenv(SRCTREE);
 		env = getenv(SRCTREE);
 		if (env) {
 		if (env) {
 			sprintf(fullname, "%s/%s", env, name);
 			sprintf(fullname, "%s/%s", env, name);

+ 6 - 0
extra/config/lkc.h

@@ -44,6 +44,7 @@ extern "C" {
 
 
 #define T_OPT_MODULES		1
 #define T_OPT_MODULES		1
 #define T_OPT_DEFCONFIG_LIST	2
 #define T_OPT_DEFCONFIG_LIST	2
+#define T_OPT_ENV		3
 
 
 struct kconf_id {
 struct kconf_id {
 	int name;
 	int name;
@@ -64,6 +65,7 @@ int zconf_lineno(void);
 char *zconf_curname(void);
 char *zconf_curname(void);
 
 
 /* confdata.c */
 /* confdata.c */
+const char *conf_get_configname(void);
 char *conf_get_default_confname(void);
 char *conf_get_default_confname(void);
 void sym_set_change_count(int count);
 void sym_set_change_count(int count);
 void sym_add_change_count(int count);
 void sym_add_change_count(int count);
@@ -73,6 +75,7 @@ void kconfig_load(void);
 
 
 /* menu.c */
 /* menu.c */
 void menu_init(void);
 void menu_init(void);
+void menu_warn(struct menu *menu, const char *fmt, ...);
 struct menu *menu_add_menu(void);
 struct menu *menu_add_menu(void);
 void menu_end_menu(void);
 void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
 void menu_add_entry(struct symbol *sym);
@@ -102,6 +105,8 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
 const char *str_get(struct gstr *gs);
 const char *str_get(struct gstr *gs);
 
 
 /* symbol.c */
 /* symbol.c */
+extern struct expr *sym_env_list;
+
 void sym_init(void);
 void sym_init(void);
 void sym_clear_all_valid(void);
 void sym_clear_all_valid(void);
 void sym_set_all_changed(void);
 void sym_set_all_changed(void);
@@ -109,6 +114,7 @@ void sym_set_changed(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
 struct property *prop_alloc(enum prop_type type, struct symbol *sym);
 struct property *prop_alloc(enum prop_type type, struct symbol *sym);
 struct symbol *prop_get_symbol(struct property *prop);
 struct symbol *prop_get_symbol(struct property *prop);
+struct property *sym_get_env_prop(struct symbol *sym);
 
 
 static inline tristate sym_get_tristate_value(struct symbol *sym)
 static inline tristate sym_get_tristate_value(struct symbol *sym)
 {
 {

+ 2 - 0
extra/config/lkc_proto.h

@@ -15,6 +15,8 @@ P(menu_is_visible,bool,(struct menu *menu));
 P(menu_get_prompt,const char *,(struct menu *menu));
 P(menu_get_prompt,const char *,(struct menu *menu));
 P(menu_get_root_menu,struct menu *,(struct menu *menu));
 P(menu_get_root_menu,struct menu *,(struct menu *menu));
 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+P(menu_has_help,bool,(struct menu *menu));
+P(menu_get_help,const char *,(struct menu *menu));
 
 
 /* symbol.c */
 /* symbol.c */
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);

+ 4 - 0
extra/config/lxdialog/.gitignore

@@ -0,0 +1,4 @@
+#
+# Generated files
+#
+lxdialog

+ 18 - 22
extra/config/lxdialog/check-lxdialog.sh

@@ -4,21 +4,15 @@
 # What library to link
 # What library to link
 ldflags()
 ldflags()
 {
 {
-	$cc -print-file-name=libncursesw.so | grep -q /
+	for ext in so a dylib ; do
-	if [ $? -eq 0 ]; then
+		for lib in ncursesw ncurses curses ; do
-		echo '-lncursesw'
+			$cc -print-file-name=lib${lib}.${ext} | grep -q /
-		exit
+			if [ $? -eq 0 ]; then
-	fi
+				echo "-l${lib}"
-	$cc -print-file-name=libncurses.so | grep -q /
+				exit
-	if [ $? -eq 0 ]; then
+			fi
-		echo '-lncurses'
+		done
-		exit
+	done
-	fi
-	$cc -print-file-name=libcurses.so | grep -q /
-	if [ $? -eq 0 ]; then
-		echo '-lcurses'
-		exit
-	fi
 	exit 1
 	exit 1
 }
 }
 
 
@@ -42,14 +36,16 @@ trap "rm -f $tmp" 0 1 2 3 15
 
 
 # Check if we can link to ncurses
 # Check if we can link to ncurses
 check() {
 check() {
-	echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null
+	echo -e " #include CURSES_LOC \n main() {}" |
+	    $cc -xc - -o $tmp 2> /dev/null
 	if [ $? != 0 ]; then
 	if [ $? != 0 ]; then
-		echo " *** Unable to find the ncurses libraries."          1>&2
+	    echo " *** Unable to find the ncurses libraries or the"       1>&2
-		echo " *** make menuconfig require the ncurses libraries"  1>&2
+	    echo " *** required header files."                            1>&2
-		echo " *** "                                               1>&2
+	    echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
-		echo " *** Install ncurses (ncurses-devel) and try again"  1>&2
+	    echo " *** "                                                  1>&2
-		echo " *** "                                               1>&2
+	    echo " *** Install ncurses (ncurses-devel) and try again."    1>&2
-		exit 1
+	    echo " *** "                                                  1>&2
+	    exit 1
 	fi
 	fi
 }
 }
 
 

+ 2 - 2
extra/config/lxdialog/checklist.c

@@ -97,8 +97,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
 	int x = width / 2 - 11;
 	int x = width / 2 - 11;
 	int y = height - 2;
 	int y = height - 2;
 
 
-	print_button(dialog, "Select", y, x, selected == 0);
+	print_button(dialog, gettext("Select"), y, x, selected == 0);
-	print_button(dialog, " Help ", y, x + 14, selected == 1);
+	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
 
 
 	wmove(dialog, y, x + 1 + 14 * selected);
 	wmove(dialog, y, x + 1 + 14 * selected);
 	wrefresh(dialog);
 	wrefresh(dialog);

+ 9 - 3
extra/config/lxdialog/dialog.h

@@ -26,6 +26,12 @@
 #include <string.h>
 #include <string.h>
 #include <stdbool.h>
 #include <stdbool.h>
 
 
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+#endif
+
 #ifdef __sun__
 #ifdef __sun__
 #define CURS_MACROS
 #define CURS_MACROS
 #endif
 #endif
@@ -187,9 +193,9 @@ int item_is_tag(char tag);
 int on_key_esc(WINDOW *win);
 int on_key_esc(WINDOW *win);
 int on_key_resize(void);
 int on_key_resize(void);
 
 
-void init_dialog(const char *backtitle);
+int init_dialog(const char *backtitle);
-void reset_dialog(void);
+void set_dialog_backtitle(const char *backtitle);
-void end_dialog(void);
+void end_dialog(int x, int y);
 void attr_clear(WINDOW * win, int height, int width, chtype attr);
 void attr_clear(WINDOW * win, int height, int width, chtype attr);
 void dialog_clear(void);
 void dialog_clear(void);
 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);

+ 2 - 2
extra/config/lxdialog/inputbox.c

@@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
 	int x = width / 2 - 11;
 	int x = width / 2 - 11;
 	int y = height - 2;
 	int y = height - 2;
 
 
-	print_button(dialog, "  Ok  ", y, x, selected == 0);
+	print_button(dialog, gettext("  Ok  "), y, x, selected == 0);
-	print_button(dialog, " Help ", y, x + 14, selected == 1);
+	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
 
 
 	wmove(dialog, y, x + 1 + 14 * selected);
 	wmove(dialog, y, x + 1 + 14 * selected);
 	wrefresh(dialog);
 	wrefresh(dialog);

+ 3 - 3
extra/config/lxdialog/menubox.c

@@ -157,9 +157,9 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
 	int x = width / 2 - 16;
 	int x = width / 2 - 16;
 	int y = height - 2;
 	int y = height - 2;
 
 
-	print_button(win, "Select", y, x, selected == 0);
+	print_button(win, gettext("Select"), y, x, selected == 0);
-	print_button(win, " Exit ", y, x + 12, selected == 1);
+	print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
-	print_button(win, " Help ", y, x + 24, selected == 2);
+	print_button(win, gettext(" Help "), y, x + 24, selected == 2);
 
 
 	wmove(win, y, x + 1 + 12 * selected);
 	wmove(win, y, x + 1 + 12 * selected);
 	wrefresh(win);
 	wrefresh(win);

+ 1 - 1
extra/config/lxdialog/textbox.c

@@ -114,7 +114,7 @@ do_resize:
 
 
 	print_title(dialog, title, width);
 	print_title(dialog, title, width);
 
 
-	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+	print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
 	wnoutrefresh(dialog);
 	wnoutrefresh(dialog);
 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
 
 

+ 21 - 6
extra/config/lxdialog/util.c

@@ -266,26 +266,41 @@ void dialog_clear(void)
 /*
 /*
  * Do some initialization for dialog
  * Do some initialization for dialog
  */
  */
-void init_dialog(const char *backtitle)
+int init_dialog(const char *backtitle)
 {
 {
+	int height, width;
+
+	initscr();		/* Init curses */
+	getmaxyx(stdscr, height, width);
+	if (height < 19 || width < 80) {
+		endwin();
+		return -ERRDISPLAYTOOSMALL;
+	}
+
 	dlg.backtitle = backtitle;
 	dlg.backtitle = backtitle;
 	color_setup(getenv("MENUCONFIG_COLOR"));
 	color_setup(getenv("MENUCONFIG_COLOR"));
-}
 
 
-void reset_dialog(void)
-{
-	initscr();		/* Init curses */
 	keypad(stdscr, TRUE);
 	keypad(stdscr, TRUE);
 	cbreak();
 	cbreak();
 	noecho();
 	noecho();
 	dialog_clear();
 	dialog_clear();
+
+	return 0;
+}
+
+void set_dialog_backtitle(const char *backtitle)
+{
+	dlg.backtitle = backtitle;
 }
 }
 
 
 /*
 /*
  * End using dialog functions.
  * End using dialog functions.
  */
  */
-void end_dialog(void)
+void end_dialog(int x, int y)
 {
 {
+	/* move cursor back to original position */
+	move(y, x);
+	refresh();
 	endwin();
 	endwin();
 }
 }
 
 

+ 2 - 2
extra/config/lxdialog/yesno.c

@@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
 	int x = width / 2 - 10;
 	int x = width / 2 - 10;
 	int y = height - 2;
 	int y = height - 2;
 
 
-	print_button(dialog, " Yes ", y, x, selected == 0);
+	print_button(dialog, gettext(" Yes "), y, x, selected == 0);
-	print_button(dialog, "  No  ", y, x + 13, selected == 1);
+	print_button(dialog, gettext("  No  "), y, x + 13, selected == 1);
 
 
 	wmove(dialog, y, x + 1 + 13 * selected);
 	wmove(dialog, y, x + 1 + 13 * selected);
 	wrefresh(dialog);
 	wrefresh(dialog);

+ 115 - 113
extra/config/mconf.c

@@ -8,17 +8,13 @@
  * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  */
  */
 
 
-#include <sys/ioctl.h>
-#include <sys/wait.h>
 #include <ctype.h>
 #include <ctype.h>
 #include <errno.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <limits.h>
-#include <signal.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
-#include <termios.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <locale.h>
 #include <locale.h>
 
 
@@ -26,7 +22,6 @@
 #include "lkc.h"
 #include "lkc.h"
 #include "lxdialog/dialog.h"
 #include "lxdialog/dialog.h"
 
 
-static char menu_backtitle[128];
 static const char mconf_readme[] = N_(
 static const char mconf_readme[] = N_(
 "Overview\n"
 "Overview\n"
 "--------\n"
 "--------\n"
@@ -35,13 +30,18 @@ static const char mconf_readme[] = N_(
 "parameters which are not really features, but must be\n"
 "parameters which are not really features, but must be\n"
 "entered in as decimal or hexadecimal numbers or possibly text.\n"
 "entered in as decimal or hexadecimal numbers or possibly text.\n"
 "\n"
 "\n"
-"Menu items beginning with [*] or [ ] represent features\n"
+"Menu items beginning with following braces represent features that\n"
-"configured to be built in or removed respectively.\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"
 "\n"
 "To change any of these features, highlight it with the cursor\n"
 "To change any of these features, highlight it with the cursor\n"
-"keys and press <Y> to build it in or <N> to removed it.\n"
+"keys and press <Y> to build it in, <M> to make it a module or\n"
-"You may also press the <Space Bar> to cycle\n"
+"<N> to removed it.  You may also press the <Space Bar> to cycle\n"
-"through the available options (ie. Y->N->Y).\n"
+"through the available options (ie. Y->N->M->Y).\n"
 "\n"
 "\n"
 "Some additional keyboard hints:\n"
 "Some additional keyboard hints:\n"
 "\n"
 "\n"
@@ -206,11 +206,11 @@ load_config_text[] = N_(
 	"last retrieved.  Leave blank to abort."),
 	"last retrieved.  Leave blank to abort."),
 load_config_help[] = N_(
 load_config_help[] = N_(
 	"\n"
 	"\n"
-	"For various reasons, one may wish to keep several different uClibc\n"
+	"For various reasons, one may wish to keep several different\n"
 	"configurations available on a single machine.\n"
 	"configurations available on a single machine.\n"
 	"\n"
 	"\n"
 	"If you have saved a previous configuration in a file other than the\n"
 	"If you have saved a previous configuration in a file other than the\n"
-	"uClibc's default, entering the name of the file here will allow you\n"
+	"default, entering the name of the file here will allow you\n"
 	"to modify that configuration.\n"
 	"to modify that configuration.\n"
 	"\n"
 	"\n"
 	"If you are uncertain, then you have probably never used alternate\n"
 	"If you are uncertain, then you have probably never used alternate\n"
@@ -220,7 +220,7 @@ save_config_text[] = N_(
 	"as an alternate.  Leave blank to abort."),
 	"as an alternate.  Leave blank to abort."),
 save_config_help[] = N_(
 save_config_help[] = N_(
 	"\n"
 	"\n"
-	"For various reasons, one may wish to keep different uClibc\n"
+	"For various reasons, one may wish to keep different\n"
 	"configurations available on a single machine.\n"
 	"configurations available on a single machine.\n"
 	"\n"
 	"\n"
 	"Entering a file name here will allow you to later retrieve, modify\n"
 	"Entering a file name here will allow you to later retrieve, modify\n"
@@ -269,10 +269,7 @@ search_help[] = N_(
 	"          USB$ => find all CONFIG_ symbols ending with USB\n"
 	"          USB$ => find all CONFIG_ symbols ending with USB\n"
 	"\n");
 	"\n");
 
 
-static char filename[PATH_MAX+1] = ".config";
 static int indent;
 static int indent;
-static struct termios ios_org;
-static int rows = 0, cols = 0;
 static struct menu *current_menu;
 static struct menu *current_menu;
 static int child_count;
 static int child_count;
 static int single_menu_mode;
 static int single_menu_mode;
@@ -286,51 +283,16 @@ static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
 static void show_help(struct menu *menu);
 
 
-static void init_wsize(void)
-{
-	struct winsize ws;
-	char *env;
-
-	if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
-		rows = ws.ws_row;
-		cols = ws.ws_col;
-	}
-
-	if (!rows) {
-		env = getenv("LINES");
-		if (env)
-			rows = atoi(env);
-		if (!rows)
-			rows = 24;
-	}
-	if (!cols) {
-		env = getenv("COLUMNS");
-		if (env)
-			cols = atoi(env);
-		if (!cols)
-			cols = 80;
-	}
-
-	if (rows < 19 || cols < 80) {
-		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
-		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
-		exit(1);
-	}
-
-	rows -= 4;
-	cols -= 5;
-}
-
 static void get_prompt_str(struct gstr *r, struct property *prop)
 static void get_prompt_str(struct gstr *r, struct property *prop)
 {
 {
 	int i, j;
 	int i, j;
 	struct menu *submenu[8], *menu;
 	struct menu *submenu[8], *menu;
 
 
-	str_printf(r, "Prompt: %s\n", prop->text);
+	str_printf(r, _("Prompt: %s\n"), _(prop->text));
-	str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
+	str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name,
 		prop->menu->lineno);
 		prop->menu->lineno);
 	if (!expr_is_yes(prop->visible.expr)) {
 	if (!expr_is_yes(prop->visible.expr)) {
-		str_append(r, "  Depends on: ");
+		str_append(r, _("  Depends on: "));
 		expr_gstr_print(prop->visible.expr, r);
 		expr_gstr_print(prop->visible.expr, r);
 		str_append(r, "\n");
 		str_append(r, "\n");
 	}
 	}
@@ -338,13 +300,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
 	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
 	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
 		submenu[i++] = menu;
 		submenu[i++] = menu;
 	if (i > 0) {
 	if (i > 0) {
-		str_printf(r, "  Location:\n");
+		str_printf(r, _("  Location:\n"));
 		for (j = 4; --i >= 0; j += 2) {
 		for (j = 4; --i >= 0; j += 2) {
 			menu = submenu[i];
 			menu = submenu[i];
-			str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+			str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
 			if (menu->sym) {
 			if (menu->sym) {
 				str_printf(r, " (%s [=%s])", menu->sym->name ?
 				str_printf(r, " (%s [=%s])", menu->sym->name ?
-					menu->sym->name : "<choice>",
+					menu->sym->name : _("<choice>"),
 					sym_get_string_value(menu->sym));
 					sym_get_string_value(menu->sym));
 			}
 			}
 			str_append(r, "\n");
 			str_append(r, "\n");
@@ -357,8 +319,9 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
 	bool hit;
 	bool hit;
 	struct property *prop;
 	struct property *prop;
 
 
-	str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+	if (sym && sym->name)
-	                               sym_get_string_value(sym));
+		str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+		                                    sym_get_string_value(sym));
 	for_all_prompts(sym, prop)
 	for_all_prompts(sym, prop)
 		get_prompt_str(r, prop);
 		get_prompt_str(r, prop);
 	hit = false;
 	hit = false;
@@ -373,7 +336,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
 	if (hit)
 	if (hit)
 		str_append(r, "\n");
 		str_append(r, "\n");
 	if (sym->rev_dep.expr) {
 	if (sym->rev_dep.expr) {
-		str_append(r, "  Selected by: ");
+		str_append(r, _("  Selected by: "));
 		expr_gstr_print(sym->rev_dep.expr, r);
 		expr_gstr_print(sym->rev_dep.expr, r);
 		str_append(r, "\n");
 		str_append(r, "\n");
 	}
 	}
@@ -389,19 +352,43 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
 		get_symbol_str(&res, sym);
 		get_symbol_str(&res, sym);
 	if (!i)
 	if (!i)
-		str_append(&res, "No matches found.\n");
+		str_append(&res, _("No matches found.\n"));
 	return res;
 	return res;
 }
 }
 
 
+static char filename[PATH_MAX+1];
+static void set_config_filename(const char *config_filename)
+{
+	static char menu_backtitle[PATH_MAX+128];
+	int size;
+	struct symbol *sym;
+
+	sym = sym_lookup("VERSION", 0);
+	sym_calc_value(sym);
+	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
+	                _("%s - uClibc v%s Configuration"),
+		        config_filename, sym_get_string_value(sym));
+	if (size >= sizeof(menu_backtitle))
+		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
+	set_dialog_backtitle(menu_backtitle);
+
+	size = snprintf(filename, sizeof(filename), "%s", config_filename);
+	if (size >= sizeof(filename))
+		filename[sizeof(filename)-1] = '\0';
+}
+
+
 static void search_conf(void)
 static void search_conf(void)
 {
 {
 	struct symbol **sym_arr;
 	struct symbol **sym_arr;
 	struct gstr res;
 	struct gstr res;
+	char *dialog_input;
 	int dres;
 	int dres;
 again:
 again:
 	dialog_clear();
 	dialog_clear();
 	dres = dialog_inputbox(_("Search Configuration Parameter"),
 	dres = dialog_inputbox(_("Search Configuration Parameter"),
-			      _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
+			      _("Enter CONFIG_ (sub)string to search for "
+				"(with or without \"CONFIG\")"),
 			      10, 75, "");
 			      10, 75, "");
 	switch (dres) {
 	switch (dres) {
 	case 0:
 	case 0:
@@ -413,7 +400,12 @@ again:
 		return;
 		return;
 	}
 	}
 
 
-	sym_arr = sym_re_search(dialog_input_result);
+	/* strip CONFIG_ if necessary */
+	dialog_input = dialog_input_result;
+	if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
+		dialog_input += 7;
+
+	sym_arr = sym_re_search(dialog_input);
 	res = get_relations_str(sym_arr);
 	res = get_relations_str(sym_arr);
 	free(sym_arr);
 	free(sym_arr);
 	show_textbox(_("Search Results"), str_get(&res), 0, 0);
 	show_textbox(_("Search Results"), str_get(&res), 0, 0);
@@ -440,6 +432,7 @@ static void build_conf(struct menu *menu)
 			switch (prop->type) {
 			switch (prop->type) {
 			case P_MENU:
 			case P_MENU:
 				child_count++;
 				child_count++;
+				prompt = _(prompt);
 				if (single_menu_mode) {
 				if (single_menu_mode) {
 					item_make("%s%*c%s",
 					item_make("%s%*c%s",
 						  menu->data ? "-->" : "++>",
 						  menu->data ? "-->" : "++>",
@@ -452,10 +445,18 @@ static void build_conf(struct menu *menu)
 				if (single_menu_mode && menu->data)
 				if (single_menu_mode && menu->data)
 					goto conf_childs;
 					goto conf_childs;
 				return;
 				return;
+			case P_COMMENT:
+				if (prompt) {
+					child_count++;
+					item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt));
+					item_set_tag(':');
+					item_set_data(menu);
+				}
+				break;
 			default:
 			default:
 				if (prompt) {
 				if (prompt) {
 					child_count++;
 					child_count++;
-					item_make("---%*c%s", indent + 1, ' ', prompt);
+					item_make("---%*c%s", indent + 1, ' ', _(prompt));
 					item_set_tag(':');
 					item_set_tag(':');
 					item_set_data(menu);
 					item_set_data(menu);
 				}
 				}
@@ -499,10 +500,10 @@ static void build_conf(struct menu *menu)
 			item_set_data(menu);
 			item_set_data(menu);
 		}
 		}
 
 
-		item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+		item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
 		if (val == yes) {
 		if (val == yes) {
 			if (def_menu) {
 			if (def_menu) {
-				item_add_str(" (%s)", menu_get_prompt(def_menu));
+				item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
 				item_add_str("  --->");
 				item_add_str("  --->");
 				if (def_menu->list) {
 				if (def_menu->list) {
 					indent += 2;
 					indent += 2;
@@ -514,7 +515,7 @@ static void build_conf(struct menu *menu)
 		}
 		}
 	} else {
 	} else {
 		if (menu == current_menu) {
 		if (menu == current_menu) {
-			item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+			item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
 			item_set_tag(':');
 			item_set_tag(':');
 			item_set_data(menu);
 			item_set_data(menu);
 			goto conf_childs;
 			goto conf_childs;
@@ -531,7 +532,7 @@ static void build_conf(struct menu *menu)
 				if (sym_is_changable(sym))
 				if (sym_is_changable(sym))
 					item_make("[%c]", val == no ? ' ' : '*');
 					item_make("[%c]", val == no ? ' ' : '*');
 				else
 				else
-					item_make("---");
+					item_make("-%c-", val == no ? ' ' : '*');
 				item_set_tag('t');
 				item_set_tag('t');
 				item_set_data(menu);
 				item_set_data(menu);
 				break;
 				break;
@@ -541,10 +542,13 @@ static void build_conf(struct menu *menu)
 				case mod: ch = 'M'; break;
 				case mod: ch = 'M'; break;
 				default:  ch = ' '; break;
 				default:  ch = ' '; break;
 				}
 				}
-				if (sym_is_changable(sym))
+				if (sym_is_changable(sym)) {
-					item_make("<%c>", ch);
+					if (sym->rev_dep.tri == mod)
-				else
+						item_make("{%c}", ch);
-					item_make("---");
+					else
+						item_make("<%c>", ch);
+				} else
+					item_make("-%c-", ch);
 				item_set_tag('t');
 				item_set_tag('t');
 				item_set_data(menu);
 				item_set_data(menu);
 				break;
 				break;
@@ -554,17 +558,17 @@ static void build_conf(struct menu *menu)
 				tmp = indent - tmp + 4;
 				tmp = indent - tmp + 4;
 				if (tmp < 0)
 				if (tmp < 0)
 					tmp = 0;
 					tmp = 0;
-				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+				item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
 					     (sym_has_value(sym) || !sym_is_changable(sym)) ?
 					     (sym_has_value(sym) || !sym_is_changable(sym)) ?
-					     "" : " (NEW)");
+					     "" : _(" (NEW)"));
 				item_set_tag('s');
 				item_set_tag('s');
 				item_set_data(menu);
 				item_set_data(menu);
 				goto conf_childs;
 				goto conf_childs;
 			}
 			}
 		}
 		}
-		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+		item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
 			  (sym_has_value(sym) || !sym_is_changable(sym)) ?
 			  (sym_has_value(sym) || !sym_is_changable(sym)) ?
-			  "" : " (NEW)");
+			  "" : _(" (NEW)"));
 		if (menu->prompt->type == P_MENU) {
 		if (menu->prompt->type == P_MENU) {
 			item_add_str("  --->");
 			item_add_str("  --->");
 			return;
 			return;
@@ -602,7 +606,7 @@ static void conf(struct menu *menu)
 			item_set_tag('S');
 			item_set_tag('S');
 		}
 		}
 		dialog_clear();
 		dialog_clear();
-		res = dialog_menu(prompt ? prompt : _("Main Menu"),
+		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
 				  _(menu_instructions),
 				  _(menu_instructions),
 				  active_menu, &s_scroll);
 				  active_menu, &s_scroll);
 		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
 		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
@@ -649,7 +653,7 @@ static void conf(struct menu *menu)
 			if (sym)
 			if (sym)
 				show_help(submenu);
 				show_help(submenu);
 			else
 			else
-				show_helptext("README", _(mconf_readme));
+				show_helptext(_("README"), _(mconf_readme));
 			break;
 			break;
 		case 3:
 		case 3:
 			if (item_is_tag('t')) {
 			if (item_is_tag('t')) {
@@ -696,24 +700,24 @@ static void show_help(struct menu *menu)
 	struct gstr help = str_new();
 	struct gstr help = str_new();
 	struct symbol *sym = menu->sym;
 	struct symbol *sym = menu->sym;
 
 
-	if (sym->help)
+	if (menu_has_help(menu))
 	{
 	{
 		if (sym->name) {
 		if (sym->name) {
-			str_printf(&help, "CONFIG_%s:\n\n", sym->name);
+			str_printf(&help, "%s:\n\n", sym->name);
-			str_append(&help, _(sym->help));
+			str_append(&help, _(menu_get_help(menu)));
 			str_append(&help, "\n");
 			str_append(&help, "\n");
 		}
 		}
 	} else {
 	} else {
 		str_append(&help, nohelp_text);
 		str_append(&help, nohelp_text);
 	}
 	}
 	get_symbol_str(&help, sym);
 	get_symbol_str(&help, sym);
-	show_helptext(menu_get_prompt(menu), str_get(&help));
+	show_helptext(_(menu_get_prompt(menu)), str_get(&help));
 	str_free(&help);
 	str_free(&help);
 }
 }
 
 
 static void conf_choice(struct menu *menu)
 static void conf_choice(struct menu *menu)
 {
 {
-	const char *prompt = menu_get_prompt(menu);
+	const char *prompt = _(menu_get_prompt(menu));
 	struct menu *child;
 	struct menu *child;
 	struct symbol *active;
 	struct symbol *active;
 
 
@@ -727,7 +731,7 @@ static void conf_choice(struct menu *menu)
 		for (child = menu->list; child; child = child->next) {
 		for (child = menu->list; child; child = child->next) {
 			if (!menu_is_visible(child))
 			if (!menu_is_visible(child))
 				continue;
 				continue;
-			item_make("%s", menu_get_prompt(child));
+			item_make("%s", _(menu_get_prompt(child)));
 			item_set_data(child);
 			item_set_data(child);
 			if (child->sym == active)
 			if (child->sym == active)
 				item_set_selected(1);
 				item_set_selected(1);
@@ -735,7 +739,7 @@ static void conf_choice(struct menu *menu)
 				item_set_tag('X');
 				item_set_tag('X');
 		}
 		}
 		dialog_clear();
 		dialog_clear();
-		res = dialog_checklist(prompt ? prompt : _("Main Menu"),
+		res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
 					_(radiolist_instructions),
 					_(radiolist_instructions),
 					 15, 70, 6);
 					 15, 70, 6);
 		selected = item_activate_selected();
 		selected = item_activate_selected();
@@ -781,10 +785,10 @@ static void conf_string(struct menu *menu)
 			heading = _(inputbox_instructions_string);
 			heading = _(inputbox_instructions_string);
 			break;
 			break;
 		default:
 		default:
-			heading = "Internal mconf error!";
+			heading = _("Internal mconf error!");
 		}
 		}
 		dialog_clear();
 		dialog_clear();
-		res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
+		res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
 				      heading, 10, 75,
 				      heading, 10, 75,
 				      sym_get_string_value(menu->sym));
 				      sym_get_string_value(menu->sym));
 		switch (res) {
 		switch (res) {
@@ -814,8 +818,11 @@ static void conf_load(void)
 		case 0:
 		case 0:
 			if (!dialog_input_result[0])
 			if (!dialog_input_result[0])
 				return;
 				return;
-			if (!conf_read(dialog_input_result))
+			if (!conf_read(dialog_input_result)) {
+				set_config_filename(dialog_input_result);
+				sym_set_change_count(1);
 				return;
 				return;
+			}
 			show_textbox(NULL, _("File does not exist!"), 5, 38);
 			show_textbox(NULL, _("File does not exist!"), 5, 38);
 			break;
 			break;
 		case 1:
 		case 1:
@@ -838,8 +845,10 @@ static void conf_save(void)
 		case 0:
 		case 0:
 			if (!dialog_input_result[0])
 			if (!dialog_input_result[0])
 				return;
 				return;
-			if (!conf_write(dialog_input_result))
+			if (!conf_write(dialog_input_result)) {
+				set_config_filename(dialog_input_result);
 				return;
 				return;
+			}
 			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
 			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
 			break;
 			break;
 		case 1:
 		case 1:
@@ -851,14 +860,9 @@ static void conf_save(void)
 	}
 	}
 }
 }
 
 
-static void conf_cleanup(void)
-{
-	tcsetattr(1, TCSAFLUSH, &ios_org);
-}
-
 int main(int ac, char **av)
 int main(int ac, char **av)
 {
 {
-	struct symbol *sym;
+	int saved_x, saved_y;
 	char *mode;
 	char *mode;
 	int res;
 	int res;
 
 
@@ -869,54 +873,52 @@ int main(int ac, char **av)
 	conf_parse(av[1]);
 	conf_parse(av[1]);
 	conf_read(NULL);
 	conf_read(NULL);
 
 
-	sym = sym_lookup("VERSION", 0);
-	sym_calc_value(sym);
-	sprintf(menu_backtitle, _("uClibc v%s Configuration"),
-		sym_get_string_value(sym));
-
 	mode = getenv("MENUCONFIG_MODE");
 	mode = getenv("MENUCONFIG_MODE");
 	if (mode) {
 	if (mode) {
 		if (!strcasecmp(mode, "single_menu"))
 		if (!strcasecmp(mode, "single_menu"))
 			single_menu_mode = 1;
 			single_menu_mode = 1;
 	}
 	}
 
 
-	tcgetattr(1, &ios_org);
+	getyx(stdscr, saved_y, saved_x);
-	atexit(conf_cleanup);
+	if (init_dialog(NULL)) {
-	init_wsize();
+		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
-	reset_dialog();
+		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
-	init_dialog(menu_backtitle);
+		return 1;
+	}
+
+	set_config_filename(conf_get_configname());
 	do {
 	do {
 		conf(&rootmenu);
 		conf(&rootmenu);
 		dialog_clear();
 		dialog_clear();
 		if (conf_get_changed())
 		if (conf_get_changed())
 			res = dialog_yesno(NULL,
 			res = dialog_yesno(NULL,
 					   _("Do you wish to save your "
 					   _("Do you wish to save your "
-					     "new uClibc configuration?\n"
+					     "new configuration?\n"
 					     "<ESC><ESC> to continue."),
 					     "<ESC><ESC> to continue."),
 					   6, 60);
 					   6, 60);
 		else
 		else
 			res = -1;
 			res = -1;
 	} while (res == KEY_ESC);
 	} while (res == KEY_ESC);
-	end_dialog();
+	end_dialog(saved_x, saved_y);
 
 
 	switch (res) {
 	switch (res) {
 	case 0:
 	case 0:
-		if (conf_write(NULL)) {
+		if (conf_write(filename)) {
 			fprintf(stderr, _("\n\n"
 			fprintf(stderr, _("\n\n"
-				"Error during writing of the uClibc configuration.\n"
+				"Error during writing of the configuration.\n"
-				"Your uClibc configuration changes were NOT saved."
+				"Your configuration changes were NOT saved."
 				"\n\n"));
 				"\n\n"));
 			return 1;
 			return 1;
 		}
 		}
 	case -1:
 	case -1:
 		printf(_("\n\n"
 		printf(_("\n\n"
-			"*** End of uClibc configuration.\n"
+			"*** End of configuration.\n"
-			"*** Execute 'make' to build uClibc or try 'make help'."
+			"*** Execute 'make' to build or try 'make help'."
 			"\n\n"));
 			"\n\n"));
 		break;
 		break;
 	default:
 	default:
 		fprintf(stderr, _("\n\n"
 		fprintf(stderr, _("\n\n"
-			"Your uClibc configuration changes were NOT saved."
+			"Your configuration changes were NOT saved."
 			"\n\n"));
 			"\n\n"));
 	}
 	}
 
 

+ 57 - 13
extra/config/menu.c

@@ -15,7 +15,7 @@ static struct menu **last_entry_ptr;
 struct file *file_list;
 struct file *file_list;
 struct file *current_file;
 struct file *current_file;
 
 
-static void menu_warn(struct menu *menu, const char *fmt, ...)
+void menu_warn(struct menu *menu, const char *fmt, ...)
 {
 {
 	va_list ap;
 	va_list ap;
 	va_start(ap, fmt);
 	va_start(ap, fmt);
@@ -172,6 +172,9 @@ void menu_add_option(int token, char *arg)
 		else if (sym_defconfig_list != current_entry->sym)
 		else if (sym_defconfig_list != current_entry->sym)
 			zconf_error("trying to redefine defconfig symbol");
 			zconf_error("trying to redefine defconfig symbol");
 		break;
 		break;
+	case T_OPT_ENV:
+		prop_add_env(arg);
+		break;
 	}
 	}
 }
 }
 
 
@@ -200,12 +203,9 @@ void sym_check_prop(struct symbol *sym)
 				prop_warn(prop,
 				prop_warn(prop,
 				    "config symbol '%s' uses select, but is "
 				    "config symbol '%s' uses select, but is "
 				    "not boolean or tristate", sym->name);
 				    "not boolean or tristate", sym->name);
-			else if (sym2->type == S_UNKNOWN)
+			else if (sym2->type != S_UNKNOWN &&
-				prop_warn(prop,
+			         sym2->type != S_BOOLEAN &&
-				    "'select' used by config symbol '%s' "
+			         sym2->type != S_TRISTATE)
-				    "refer to undefined symbol '%s'",
-				    sym->name, sym2->name);
-			else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
 				prop_warn(prop,
 				prop_warn(prop,
 				    "'%s' has wrong type. 'select' only "
 				    "'%s' has wrong type. 'select' only "
 				    "accept arguments of boolean and "
 				    "accept arguments of boolean and "
@@ -239,9 +239,11 @@ void menu_finalize(struct menu *parent)
 			for (menu = parent->list; menu; menu = menu->next) {
 			for (menu = parent->list; menu; menu = menu->next) {
 				if (menu->sym) {
 				if (menu->sym) {
 					current_entry = parent;
 					current_entry = parent;
-					menu_set_type(menu->sym->type);
+					if (sym->type == S_UNKNOWN)
+						menu_set_type(menu->sym->type);
 					current_entry = menu;
 					current_entry = menu;
-					menu_set_type(sym->type);
+					if (menu->sym->type == S_UNKNOWN)
+						menu_set_type(sym->type);
 					break;
 					break;
 				}
 				}
 			}
 			}
@@ -326,12 +328,42 @@ void menu_finalize(struct menu *parent)
 					    "values not supported");
 					    "values not supported");
 			}
 			}
 			current_entry = menu;
 			current_entry = menu;
-			menu_set_type(sym->type);
+			if (menu->sym->type == S_UNKNOWN)
+				menu_set_type(sym->type);
+			/* Non-tristate choice values of tristate choices must
+			 * depend on the choice being set to Y. The choice
+			 * values' dependencies were propagated to their
+			 * properties above, so the change here must be re-
+			 * propagated. */
+			if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
+				basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
+				basedep = expr_alloc_and(basedep, menu->dep);
+				basedep = expr_eliminate_dups(basedep);
+				menu->dep = basedep;
+				for (prop = menu->sym->prop; prop; prop = prop->next) {
+					if (prop->menu != menu)
+						continue;
+					dep = expr_alloc_and(expr_copy(basedep),
+							     prop->visible.expr);
+					dep = expr_eliminate_dups(dep);
+					dep = expr_trans_bool(dep);
+					prop->visible.expr = dep;
+					if (prop->type == P_SELECT) {
+						struct symbol *es = prop_get_symbol(prop);
+						dep2 = expr_alloc_symbol(menu->sym);
+						dep = expr_alloc_and(dep2,
+								     expr_copy(dep));
+						dep = expr_alloc_or(es->rev_dep.expr, dep);
+						dep = expr_eliminate_dups(dep);
+						es->rev_dep.expr = dep;
+					}
+				}
+			}
 			menu_add_symbol(P_CHOICE, sym, NULL);
 			menu_add_symbol(P_CHOICE, sym, NULL);
 			prop = sym_get_choice_prop(sym);
 			prop = sym_get_choice_prop(sym);
 			for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
 			for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
 				;
 				;
-			*ep = expr_alloc_one(E_CHOICE, NULL);
+			*ep = expr_alloc_one(E_LIST, NULL);
 			(*ep)->right.sym = menu->sym;
 			(*ep)->right.sym = menu->sym;
 		}
 		}
 		if (menu->list && (!menu->prompt || !menu->prompt->text)) {
 		if (menu->list && (!menu->prompt || !menu->prompt->text)) {
@@ -394,9 +426,9 @@ bool menu_is_visible(struct menu *menu)
 const char *menu_get_prompt(struct menu *menu)
 const char *menu_get_prompt(struct menu *menu)
 {
 {
 	if (menu->prompt)
 	if (menu->prompt)
-		return _(menu->prompt->text);
+		return menu->prompt->text;
 	else if (menu->sym)
 	else if (menu->sym)
-		return _(menu->sym->name);
+		return menu->sym->name;
 	return NULL;
 	return NULL;
 }
 }
 
 
@@ -417,3 +449,15 @@ struct menu *menu_get_parent_menu(struct menu *menu)
 	return menu;
 	return menu;
 }
 }
 
 
+bool menu_has_help(struct menu *menu)
+{
+	return menu->help != NULL;
+}
+
+const char *menu_get_help(struct menu *menu)
+{
+	if (menu->help)
+		return menu->help;
+	else
+		return "";
+}

+ 74 - 58
extra/config/qconf.cc

@@ -89,6 +89,7 @@ void ConfigItem::okRename(int col)
 {
 {
 	Parent::okRename(col);
 	Parent::okRename(col);
 	sym_set_string_value(menu->sym, text(dataColIdx).latin1());
 	sym_set_string_value(menu->sym, text(dataColIdx).latin1());
+	listView()->updateList(this);
 }
 }
 #endif
 #endif
 
 
@@ -113,7 +114,7 @@ void ConfigItem::updateMenu(void)
 
 
 	sym = menu->sym;
 	sym = menu->sym;
 	prop = menu->prompt;
 	prop = menu->prompt;
-	prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
+	prompt = _(menu_get_prompt(menu));
 
 
 	if (prop) switch (prop->type) {
 	if (prop) switch (prop->type) {
 	case P_MENU:
 	case P_MENU:
@@ -207,7 +208,7 @@ void ConfigItem::updateMenu(void)
 		break;
 		break;
 	}
 	}
 	if (!sym_has_value(sym) && visible)
 	if (!sym_has_value(sym) && visible)
-		prompt += " (NEW)";
+		prompt += _(" (NEW)");
 set_prompt:
 set_prompt:
 	setText(promptColIdx, prompt);
 	setText(promptColIdx, prompt);
 }
 }
@@ -345,7 +346,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
 
 
 	for (i = 0; i < colNr; i++)
 	for (i = 0; i < colNr; i++)
 		colMap[i] = colRevMap[i] = -1;
 		colMap[i] = colRevMap[i] = -1;
-	addColumn(promptColIdx, "Option");
+	addColumn(promptColIdx, _("Option"));
 
 
 	reinit();
 	reinit();
 }
 }
@@ -359,14 +360,14 @@ void ConfigList::reinit(void)
 	removeColumn(nameColIdx);
 	removeColumn(nameColIdx);
 
 
 	if (showName)
 	if (showName)
-		addColumn(nameColIdx, "Name");
+		addColumn(nameColIdx, _("Name"));
 	if (showRange) {
 	if (showRange) {
 		addColumn(noColIdx, "N");
 		addColumn(noColIdx, "N");
 		addColumn(modColIdx, "M");
 		addColumn(modColIdx, "M");
 		addColumn(yesColIdx, "Y");
 		addColumn(yesColIdx, "Y");
 	}
 	}
 	if (showData)
 	if (showData)
-		addColumn(dataColIdx, "Value");
+		addColumn(dataColIdx, _("Value"));
 
 
 	updateListAll();
 	updateListAll();
 }
 }
@@ -605,6 +606,8 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
 
 
 		visible = menu_is_visible(child);
 		visible = menu_is_visible(child);
 		if (showAll || visible) {
 		if (showAll || visible) {
+			if (!child->sym && !child->list && !child->prompt)
+				continue;
 			if (!item || item->menu != child)
 			if (!item || item->menu != child)
 				item = new ConfigItem(parent, last, child, visible);
 				item = new ConfigItem(parent, last, child, visible);
 			else
 			else
@@ -800,7 +803,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
 			QAction *action;
 			QAction *action;
 
 
 			headerPopup = new QPopupMenu(this);
 			headerPopup = new QPopupMenu(this);
-			action = new QAction(NULL, "Show Name", 0, this);
+			action = new QAction(NULL, _("Show Name"), 0, this);
 			  action->setToggleAction(TRUE);
 			  action->setToggleAction(TRUE);
 			  connect(action, SIGNAL(toggled(bool)),
 			  connect(action, SIGNAL(toggled(bool)),
 				  parent(), SLOT(setShowName(bool)));
 				  parent(), SLOT(setShowName(bool)));
@@ -808,7 +811,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
 				  action, SLOT(setOn(bool)));
 				  action, SLOT(setOn(bool)));
 			  action->setOn(showName);
 			  action->setOn(showName);
 			  action->addTo(headerPopup);
 			  action->addTo(headerPopup);
-			action = new QAction(NULL, "Show Range", 0, this);
+			action = new QAction(NULL, _("Show Range"), 0, this);
 			  action->setToggleAction(TRUE);
 			  action->setToggleAction(TRUE);
 			  connect(action, SIGNAL(toggled(bool)),
 			  connect(action, SIGNAL(toggled(bool)),
 				  parent(), SLOT(setShowRange(bool)));
 				  parent(), SLOT(setShowRange(bool)));
@@ -816,7 +819,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
 				  action, SLOT(setOn(bool)));
 				  action, SLOT(setOn(bool)));
 			  action->setOn(showRange);
 			  action->setOn(showRange);
 			  action->addTo(headerPopup);
 			  action->addTo(headerPopup);
-			action = new QAction(NULL, "Show Data", 0, this);
+			action = new QAction(NULL, _("Show Data"), 0, this);
 			  action->setToggleAction(TRUE);
 			  action->setToggleAction(TRUE);
 			  connect(action, SIGNAL(toggled(bool)),
 			  connect(action, SIGNAL(toggled(bool)),
 				  parent(), SLOT(setShowData(bool)));
 				  parent(), SLOT(setShowData(bool)));
@@ -1038,7 +1041,12 @@ void ConfigInfoView::menuInfo(void)
 		if (showDebug())
 		if (showDebug())
 			debug = debug_info(sym);
 			debug = debug_info(sym);
 
 
-		help = print_filter(_(sym->help));
+		help = menu_get_help(menu);
+		/* Gettextize if the help text not empty */
+		if (help.isEmpty())
+			help = print_filter(menu_get_help(menu));
+		else
+			help = print_filter(_(menu_get_help(menu)));
 	} else if (menu->prompt) {
 	} else if (menu->prompt) {
 		head += "<big><b>";
 		head += "<big><b>";
 		head += print_filter(_(menu->prompt->text));
 		head += print_filter(_(menu->prompt->text));
@@ -1080,7 +1088,11 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
 			debug += "</a><br>";
 			debug += "</a><br>";
 			break;
 			break;
 		case P_DEFAULT:
 		case P_DEFAULT:
-			debug += "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);
 			expr_print(prop->expr, expr_print_help, &debug, E_NONE);
 			debug += "<br>";
 			debug += "<br>";
 			break;
 			break;
@@ -1091,16 +1103,6 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
 				debug += "<br>";
 				debug += "<br>";
 			}
 			}
 			break;
 			break;
-		case P_SELECT:
-			debug += "select: ";
-			expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-			debug += "<br>";
-			break;
-		case P_RANGE:
-			debug += "range: ";
-			expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-			debug += "<br>";
-			break;
 		default:
 		default:
 			debug += "unknown property: ";
 			debug += "unknown property: ";
 			debug += prop_get_type_name(prop->type);
 			debug += prop_get_type_name(prop->type);
@@ -1164,7 +1166,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
 {
 {
 	QPopupMenu* popup = Parent::createPopupMenu(pos);
 	QPopupMenu* popup = Parent::createPopupMenu(pos);
-	QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
+	QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
 	  action->setToggleAction(TRUE);
 	  action->setToggleAction(TRUE);
 	  connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
 	  connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
 	  connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
 	  connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1179,18 +1181,18 @@ void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
 	Parent::contentsContextMenuEvent(e);
 	Parent::contentsContextMenuEvent(e);
 }
 }
 
 
-ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
+ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
 	: Parent(parent, name), result(NULL)
 	: Parent(parent, name), result(NULL)
 {
 {
 	setCaption("Search Config");
 	setCaption("Search Config");
 
 
 	QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
 	QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
 	QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
 	QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
-	layout2->addWidget(new QLabel("Find:", this));
+	layout2->addWidget(new QLabel(_("Find:"), this));
 	editField = new QLineEdit(this);
 	editField = new QLineEdit(this);
 	connect(editField, SIGNAL(returnPressed()), SLOT(search()));
 	connect(editField, SIGNAL(returnPressed()), SLOT(search()));
 	layout2->addWidget(editField);
 	layout2->addWidget(editField);
-	searchButton = new QPushButton("Search", this);
+	searchButton = new QPushButton(_("Search"), this);
 	searchButton->setAutoDefault(FALSE);
 	searchButton->setAutoDefault(FALSE);
 	connect(searchButton, SIGNAL(clicked()), SLOT(search()));
 	connect(searchButton, SIGNAL(clicked()), SLOT(search()));
 	layout2->addWidget(searchButton);
 	layout2->addWidget(searchButton);
@@ -1203,6 +1205,9 @@ ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
 	info = new ConfigInfoView(split, name);
 	info = new ConfigInfoView(split, name);
 	connect(list->list, SIGNAL(menuChanged(struct menu *)),
 	connect(list->list, SIGNAL(menuChanged(struct menu *)),
 		info, SLOT(setInfo(struct menu *)));
 		info, SLOT(setInfo(struct menu *)));
+	connect(list->list, SIGNAL(menuChanged(struct menu *)),
+		parent, SLOT(setMenuLink(struct menu *)));
+
 	layout1->addWidget(split);
 	layout1->addWidget(split);
 
 
 	if (name) {
 	if (name) {
@@ -1247,6 +1252,7 @@ void ConfigSearchWindow::search(void)
 
 
 	free(result);
 	free(result);
 	list->list->clear();
 	list->list->clear();
+	info->clear();
 
 
 	result = sym_re_search(editField->text().latin1());
 	result = sym_re_search(editField->text().latin1());
 	if (!result)
 	if (!result)
@@ -1267,8 +1273,12 @@ ConfigMainWindow::ConfigMainWindow(void)
 	QMenuBar* menu;
 	QMenuBar* menu;
 	bool ok;
 	bool ok;
 	int x, y, width, height;
 	int x, y, width, height;
+	char title[256];
 
 
 	QWidget *d = configApp->desktop();
 	QWidget *d = configApp->desktop();
+	snprintf(title, sizeof(title), _("uClibc v%s Configuration"),
+		getenv("VERSION"));
+	setCaption(title);
 
 
 	width = configSettings->readNumEntry("/window width", d->width() - 64);
 	width = configSettings->readNumEntry("/window width", d->width() - 64);
 	height = configSettings->readNumEntry("/window height", d->height() - 64);
 	height = configSettings->readNumEntry("/window height", d->height() - 64);
@@ -1302,58 +1312,58 @@ ConfigMainWindow::ConfigMainWindow(void)
 	menu = menuBar();
 	menu = menuBar();
 	toolBar = new QToolBar("Tools", this);
 	toolBar = new QToolBar("Tools", this);
 
 
-	backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
+	backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
 	  connect(backAction, SIGNAL(activated()), SLOT(goBack()));
 	  connect(backAction, SIGNAL(activated()), SLOT(goBack()));
 	  backAction->setEnabled(FALSE);
 	  backAction->setEnabled(FALSE);
-	QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
+	QAction *quitAction = new QAction("Quit", _("&Quit"), CTRL+Key_Q, this);
 	  connect(quitAction, SIGNAL(activated()), SLOT(close()));
 	  connect(quitAction, SIGNAL(activated()), SLOT(close()));
-	QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
+	QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), CTRL+Key_L, this);
 	  connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
 	  connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
-	saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
+	saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), CTRL+Key_S, this);
 	  connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
 	  connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
 	conf_set_changed_callback(conf_changed);
 	conf_set_changed_callback(conf_changed);
 	// Set saveAction's initial state
 	// Set saveAction's initial state
 	conf_changed();
 	conf_changed();
-	QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
+	QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
 	  connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
 	  connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
-	QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
+	QAction *searchAction = new QAction("Find", _("&Find"), CTRL+Key_F, this);
 	  connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
 	  connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
-	QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
+	QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
 	  connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
 	  connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
-	QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
+	QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
 	  connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
 	  connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
-	QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
+	QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
 	  connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
 	  connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
 
 
-	QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
+	QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
 	  showNameAction->setToggleAction(TRUE);
 	  showNameAction->setToggleAction(TRUE);
 	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
 	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
 	  connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
 	  connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
 	  showNameAction->setOn(configView->showName());
 	  showNameAction->setOn(configView->showName());
-	QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
+	QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
 	  showRangeAction->setToggleAction(TRUE);
 	  showRangeAction->setToggleAction(TRUE);
 	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
 	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
 	  connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
 	  connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
 	  showRangeAction->setOn(configList->showRange);
 	  showRangeAction->setOn(configList->showRange);
-	QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
+	QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
 	  showDataAction->setToggleAction(TRUE);
 	  showDataAction->setToggleAction(TRUE);
 	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
 	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
 	  connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
 	  connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
 	  showDataAction->setOn(configList->showData);
 	  showDataAction->setOn(configList->showData);
-	QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
+	QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
 	  showAllAction->setToggleAction(TRUE);
 	  showAllAction->setToggleAction(TRUE);
 	  connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
 	  connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
 	  connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
 	  connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
 	  showAllAction->setOn(configList->showAll);
 	  showAllAction->setOn(configList->showAll);
-	QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
+	QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
 	  showDebugAction->setToggleAction(TRUE);
 	  showDebugAction->setToggleAction(TRUE);
 	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
 	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
 	  connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
 	  connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
 	  showDebugAction->setOn(helpText->showDebug());
 	  showDebugAction->setOn(helpText->showDebug());
 
 
-	QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
+	QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
 	  connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
 	  connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
-	QAction *showAboutAction = new QAction(NULL, "About", 0, this);
+	QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
 	  connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
 	  connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
 
 
 	// init tool bar
 	// init tool bar
@@ -1368,18 +1378,21 @@ ConfigMainWindow::ConfigMainWindow(void)
 
 
 	// create config menu
 	// create config menu
 	QPopupMenu* config = new QPopupMenu(this);
 	QPopupMenu* config = new QPopupMenu(this);
-	menu->insertItem("&File", config);
+	menu->insertItem(_("&File"), config);
 	loadAction->addTo(config);
 	loadAction->addTo(config);
 	saveAction->addTo(config);
 	saveAction->addTo(config);
 	saveAsAction->addTo(config);
 	saveAsAction->addTo(config);
 	config->insertSeparator();
 	config->insertSeparator();
-	searchAction->addTo(config);
-	config->insertSeparator();
 	quitAction->addTo(config);
 	quitAction->addTo(config);
 
 
+	// create edit menu
+	QPopupMenu* editMenu = new QPopupMenu(this);
+	menu->insertItem(_("&Edit"), editMenu);
+	searchAction->addTo(editMenu);
+
 	// create options menu
 	// create options menu
 	QPopupMenu* optionMenu = new QPopupMenu(this);
 	QPopupMenu* optionMenu = new QPopupMenu(this);
-	menu->insertItem("&Option", optionMenu);
+	menu->insertItem(_("&Option"), optionMenu);
 	showNameAction->addTo(optionMenu);
 	showNameAction->addTo(optionMenu);
 	showRangeAction->addTo(optionMenu);
 	showRangeAction->addTo(optionMenu);
 	showDataAction->addTo(optionMenu);
 	showDataAction->addTo(optionMenu);
@@ -1390,7 +1403,7 @@ ConfigMainWindow::ConfigMainWindow(void)
 	// create help menu
 	// create help menu
 	QPopupMenu* helpMenu = new QPopupMenu(this);
 	QPopupMenu* helpMenu = new QPopupMenu(this);
 	menu->insertSeparator();
 	menu->insertSeparator();
-	menu->insertItem("&Help", helpMenu);
+	menu->insertItem(_("&Help"), helpMenu);
 	showIntroAction->addTo(helpMenu);
 	showIntroAction->addTo(helpMenu);
 	showAboutAction->addTo(helpMenu);
 	showAboutAction->addTo(helpMenu);
 
 
@@ -1438,14 +1451,14 @@ void ConfigMainWindow::loadConfig(void)
 	if (s.isNull())
 	if (s.isNull())
 		return;
 		return;
 	if (conf_read(QFile::encodeName(s)))
 	if (conf_read(QFile::encodeName(s)))
-		QMessageBox::information(this, "qconf", "Unable to load configuration!");
+		QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
 	ConfigView::updateListAll();
 	ConfigView::updateListAll();
 }
 }
 
 
 void ConfigMainWindow::saveConfig(void)
 void ConfigMainWindow::saveConfig(void)
 {
 {
 	if (conf_write(NULL))
 	if (conf_write(NULL))
-		QMessageBox::information(this, "qconf", "Unable to save configuration!");
+		QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
 }
 }
 
 
 void ConfigMainWindow::saveConfigAs(void)
 void ConfigMainWindow::saveConfigAs(void)
@@ -1454,7 +1467,7 @@ void ConfigMainWindow::saveConfigAs(void)
 	if (s.isNull())
 	if (s.isNull())
 		return;
 		return;
 	if (conf_write(QFile::encodeName(s)))
 	if (conf_write(QFile::encodeName(s)))
-		QMessageBox::information(this, "qconf", "Unable to save configuration!");
+		QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
 }
 }
 
 
 void ConfigMainWindow::searchConfig(void)
 void ConfigMainWindow::searchConfig(void)
@@ -1467,7 +1480,10 @@ void ConfigMainWindow::searchConfig(void)
 void ConfigMainWindow::changeMenu(struct menu *menu)
 void ConfigMainWindow::changeMenu(struct menu *menu)
 {
 {
 	configList->setRootMenu(menu);
 	configList->setRootMenu(menu);
-	backAction->setEnabled(TRUE);
+	if (configList->rootEntry->parent == &rootmenu)
+		backAction->setEnabled(FALSE);
+	else
+		backAction->setEnabled(TRUE);
 }
 }
 
 
 void ConfigMainWindow::setMenuLink(struct menu *menu)
 void ConfigMainWindow::setMenuLink(struct menu *menu)
@@ -1595,11 +1611,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
 		e->accept();
 		e->accept();
 		return;
 		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);
 			QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
-	mb.setButtonText(QMessageBox::Yes, "&Save Changes");
+	mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
-	mb.setButtonText(QMessageBox::No, "&Discard Changes");
+	mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
-	mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
+	mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
 	switch (mb.exec()) {
 	switch (mb.exec()) {
 	case QMessageBox::Yes:
 	case QMessageBox::Yes:
 		conf_write(NULL);
 		conf_write(NULL);
@@ -1614,7 +1630,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
 
 
 void ConfigMainWindow::showIntro(void)
 void ConfigMainWindow::showIntro(void)
 {
 {
-	static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
+	static const QString str = _("Welcome to the qconf graphical configuration tool for uClibc.\n\n"
 		"For each option, a blank box indicates the feature is disabled, a check\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"
 		"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"
 		"as a module.  Clicking on the box will cycle through the three states.\n\n"
@@ -1624,15 +1640,15 @@ void ConfigMainWindow::showIntro(void)
 		"options must be enabled to support the option you are interested in, you can\n"
 		"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"
 		"still view the help of a grayed-out option.\n\n"
 		"Toggling Show Debug Info under the Options menu will show the dependencies,\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);
 	QMessageBox::information(this, "qconf", str);
 }
 }
 
 
 void ConfigMainWindow::showAbout(void)
 void ConfigMainWindow::showAbout(void)
 {
 {
-	static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
+	static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\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://bugs.uClibc.org/\n");
 
 
 	QMessageBox::information(this, "qconf", str);
 	QMessageBox::information(this, "qconf", str);
 }
 }
@@ -1690,7 +1706,7 @@ static const char *progname;
 
 
 static void usage(void)
 static void usage(void)
 {
 {
-	printf("%s <config>\n", progname);
+	printf(_("%s <config>\n"), progname);
 	exit(0);
 	exit(0);
 }
 }
 
 

+ 1 - 1
extra/config/qconf.h

@@ -279,7 +279,7 @@ class ConfigSearchWindow : public QDialog {
 	Q_OBJECT
 	Q_OBJECT
 	typedef class QDialog Parent;
 	typedef class QDialog Parent;
 public:
 public:
-	ConfigSearchWindow(QWidget* parent, const char *name = 0);
+	ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0);
 
 
 public slots:
 public slots:
 	void saveSettings(void);
 	void saveSettings(void);

+ 84 - 48
extra/config/symbol.c

@@ -7,7 +7,6 @@
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
 #include <regex.h>
 #include <regex.h>
-#include <sys/utsname.h>
 
 
 #define LKC_DIRECT_LINK
 #define LKC_DIRECT_LINK
 #include "lkc.h"
 #include "lkc.h"
@@ -34,6 +33,8 @@ struct symbol *sym_defconfig_list;
 struct symbol *modules_sym;
 struct symbol *modules_sym;
 tristate modules_val;
 tristate modules_val;
 
 
+struct expr *sym_env_list;
+
 void sym_add_default(struct symbol *sym, const char *def)
 void sym_add_default(struct symbol *sym, const char *def)
 {
 {
 	struct property *prop = prop_alloc(P_DEFAULT, sym);
 	struct property *prop = prop_alloc(P_DEFAULT, sym);
@@ -44,7 +45,6 @@ void sym_add_default(struct symbol *sym, const char *def)
 void sym_init(void)
 void sym_init(void)
 {
 {
 	struct symbol *sym;
 	struct symbol *sym;
-	struct utsname uts;
 	char *p;
 	char *p;
 	static bool inited = false;
 	static bool inited = false;
 
 
@@ -52,26 +52,13 @@ void sym_init(void)
 		return;
 		return;
 	inited = true;
 	inited = true;
 
 
-	uname(&uts);
-
-	sym = sym_lookup("ARCH", 0);
-	sym->type = S_STRING;
-	sym->flags |= SYMBOL_AUTO;
-	p = getenv("ARCH");
-	if (p)
-		sym_add_default(sym, p);
-
-	sym = sym_lookup("VERSION", 0);
-	sym->type = S_STRING;
-	sym->flags |= SYMBOL_AUTO;
 	p = getenv("VERSION");
 	p = getenv("VERSION");
-	if (p)
+	if (p) {
+		sym = sym_lookup("VERSION", 0);
+		sym->type = S_STRING;
+		sym->flags |= SYMBOL_AUTO;
 		sym_add_default(sym, p);
 		sym_add_default(sym, p);
-
+	}
-	sym = sym_lookup("UNAME_RELEASE", 0);
-	sym->type = S_STRING;
-	sym->flags |= SYMBOL_AUTO;
-	sym_add_default(sym, uts.release);
 }
 }
 
 
 enum symbol_type sym_get_type(struct symbol *sym)
 enum symbol_type sym_get_type(struct symbol *sym)
@@ -117,6 +104,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
 	return NULL;
 	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;
+}
+
 struct property *sym_get_default_prop(struct symbol *sym)
 struct property *sym_get_default_prop(struct symbol *sym)
 {
 {
 	struct property *prop;
 	struct property *prop;
@@ -199,7 +195,7 @@ static void sym_calc_visibility(struct symbol *sym)
 	tri = no;
 	tri = no;
 	for_all_prompts(sym, prop) {
 	for_all_prompts(sym, prop) {
 		prop->visible.tri = expr_calc_value(prop->visible.expr);
 		prop->visible.tri = expr_calc_value(prop->visible.expr);
-		tri = E_OR(tri, prop->visible.tri);
+		tri = EXPR_OR(tri, prop->visible.tri);
 	}
 	}
 	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
 	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
 		tri = yes;
 		tri = yes;
@@ -247,8 +243,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
 
 
 	/* just get the first visible value */
 	/* just get the first visible value */
 	prop = sym_get_choice_prop(sym);
 	prop = sym_get_choice_prop(sym);
-	for (e = prop->expr; e; e = e->left.expr) {
+	expr_list_for_each_sym(prop->expr, e, def_sym) {
-		def_sym = e->right.sym;
 		sym_calc_visibility(def_sym);
 		sym_calc_visibility(def_sym);
 		if (def_sym->visible != no)
 		if (def_sym->visible != no)
 			return def_sym;
 			return def_sym;
@@ -303,22 +298,30 @@ void sym_calc_value(struct symbol *sym)
 		if (sym_is_choice_value(sym) && sym->visible == yes) {
 		if (sym_is_choice_value(sym) && sym->visible == yes) {
 			prop = sym_get_choice_prop(sym);
 			prop = sym_get_choice_prop(sym);
 			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
 			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
-		} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
+		} else {
-			sym->flags |= SYMBOL_WRITE;
+			if (sym->visible != no) {
-			if (sym_has_value(sym))
+				/* if the symbol is visible use the user value
-				newval.tri = sym->def[S_DEF_USER].tri;
+				 * if available, otherwise try the default value
-			else if (!sym_is_choice(sym)) {
+				 */
-				prop = sym_get_default_prop(sym);
+				sym->flags |= SYMBOL_WRITE;
-				if (prop)
+				if (sym_has_value(sym)) {
-					newval.tri = expr_calc_value(prop->expr);
+					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
+							      sym->visible);
+					goto calc_newval;
+				}
 			}
 			}
-			newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+			if (sym->rev_dep.tri != no)
-		} else if (!sym_is_choice(sym)) {
-			prop = sym_get_default_prop(sym);
-			if (prop) {
 				sym->flags |= SYMBOL_WRITE;
 				sym->flags |= SYMBOL_WRITE;
-				newval.tri = expr_calc_value(prop->expr);
+			if (!sym_is_choice(sym)) {
+				prop = sym_get_default_prop(sym);
+				if (prop) {
+					sym->flags |= SYMBOL_WRITE;
+					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
+							      prop->visible.tri);
+				}
 			}
 			}
+		calc_newval:
+			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)
 			newval.tri = yes;
 			newval.tri = yes;
@@ -347,6 +350,9 @@ void sym_calc_value(struct symbol *sym)
 		;
 		;
 	}
 	}
 
 
+	if (sym->flags & SYMBOL_AUTO)
+		sym->flags &= ~SYMBOL_WRITE;
+
 	sym->curr = newval;
 	sym->curr = newval;
 	if (sym_is_choice(sym) && newval.tri == yes)
 	if (sym_is_choice(sym) && newval.tri == yes)
 		sym->curr.val = sym_calc_choice(sym);
 		sym->curr.val = sym_calc_choice(sym);
@@ -361,12 +367,14 @@ void sym_calc_value(struct symbol *sym)
 	}
 	}
 
 
 	if (sym_is_choice(sym)) {
 	if (sym_is_choice(sym)) {
+		struct symbol *choice_sym;
 		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
 		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
+
 		prop = sym_get_choice_prop(sym);
 		prop = sym_get_choice_prop(sym);
-		for (e = prop->expr; e; e = e->left.expr) {
+		expr_list_for_each_sym(prop->expr, e, choice_sym) {
-			e->right.sym->flags |= flags;
+			choice_sym->flags |= flags;
 			if (flags & SYMBOL_CHANGED)
 			if (flags & SYMBOL_CHANGED)
-				sym_set_changed(e->right.sym);
+				sym_set_changed(choice_sym);
 		}
 		}
 	}
 	}
 }
 }
@@ -786,13 +794,15 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
 	return NULL;
 	return NULL;
 }
 }
 
 
+/* return NULL when dependencies are OK */
 struct symbol *sym_check_deps(struct symbol *sym)
 struct symbol *sym_check_deps(struct symbol *sym)
 {
 {
 	struct symbol *sym2;
 	struct symbol *sym2;
 	struct property *prop;
 	struct property *prop;
 
 
 	if (sym->flags & SYMBOL_CHECK) {
 	if (sym->flags & SYMBOL_CHECK) {
-		printf("Warning! Found recursive dependency: %s", sym->name);
+		fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
+		        sym->prop->file->name, sym->prop->lineno, sym->name);
 		return sym;
 		return sym;
 	}
 	}
 	if (sym->flags & SYMBOL_CHECKED)
 	if (sym->flags & SYMBOL_CHECKED)
@@ -816,13 +826,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
 			goto out;
 			goto out;
 	}
 	}
 out:
 out:
-	if (sym2) {
+	if (sym2)
-		printf(" %s", sym->name);
+		fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": "");
-		if (sym2 == sym) {
-			printf("\n");
-			sym2 = NULL;
-		}
-	}
 	sym->flags &= ~SYMBOL_CHECK;
 	sym->flags &= ~SYMBOL_CHECK;
 	return sym2;
 	return sym2;
 }
 }
@@ -852,7 +857,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym)
 struct symbol *prop_get_symbol(struct property *prop)
 struct symbol *prop_get_symbol(struct property *prop)
 {
 {
 	if (prop->expr && (prop->expr->type == E_SYMBOL ||
 	if (prop->expr && (prop->expr->type == E_SYMBOL ||
-			   prop->expr->type == E_CHOICE))
+			   prop->expr->type == E_LIST))
 		return prop->expr->left.sym;
 		return prop->expr->left.sym;
 	return NULL;
 	return NULL;
 }
 }
@@ -862,6 +867,8 @@ const char *prop_get_type_name(enum prop_type type)
 	switch (type) {
 	switch (type) {
 	case P_PROMPT:
 	case P_PROMPT:
 		return "prompt";
 		return "prompt";
+	case P_ENV:
+		return "env";
 	case P_COMMENT:
 	case P_COMMENT:
 		return "comment";
 		return "comment";
 	case P_MENU:
 	case P_MENU:
@@ -879,3 +886,32 @@ const char *prop_get_type_name(enum prop_type type)
 	}
 	}
 	return "unknown";
 	return "unknown";
 }
 }
+
+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, 1));
+
+	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);
+}

+ 29 - 7
extra/config/util.c

@@ -29,6 +29,8 @@ struct file *file_lookup(const char *name)
 /* write a dependency file as used by kbuild to track dependencies */
 /* write a dependency file as used by kbuild to track dependencies */
 int file_write_dep(const char *name)
 int file_write_dep(const char *name)
 {
 {
+	struct symbol *sym, *env_sym;
+	struct expr *e;
 	struct file *file;
 	struct file *file;
 	FILE *out;
 	FILE *out;
 
 
@@ -45,8 +47,25 @@ int file_write_dep(const char *name)
 			fprintf(out, "\t%s\n", file->name);
 			fprintf(out, "\t%s\n", file->name);
 	}
 	}
 	fprintf(out, "\ninclude/config/auto.conf: \\\n"
 	fprintf(out, "\ninclude/config/auto.conf: \\\n"
-		     "\t$(deps_config)\n\n"
+		     "\t$(deps_config)\n\n");
-		     "$(deps_config): ;\n");
+
+	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, "include/config/auto.conf: FORCE\n");
+		fprintf(out, "endif\n");
+	}
+
+	fprintf(out, "\n$(deps_config): ;\n");
 	fclose(out);
 	fclose(out);
 	rename("..config.tmp", name);
 	rename("..config.tmp", name);
 	return 0;
 	return 0;
@@ -84,12 +103,15 @@ void str_free(struct gstr *gs)
 /* Append to growable string */
 /* Append to growable string */
 void str_append(struct gstr *gs, const char *s)
 void str_append(struct gstr *gs, const char *s)
 {
 {
-	size_t l = strlen(gs->s) + strlen(s) + 1;
+	size_t l;
-	if (l > gs->len) {
+	if (s) {
-		gs->s   = realloc(gs->s, l);
+		l = strlen(gs->s) + strlen(s) + 1;
-		gs->len = l;
+		if (l > gs->len) {
+			gs->s   = realloc(gs->s, l);
+			gs->len = l;
+		}
+		strcat(gs->s, s);
 	}
 	}
-	strcat(gs->s, s);
 }
 }
 
 
 /* Append printf formatted string to growable string */
 /* Append printf formatted string to growable string */

+ 1 - 3
extra/config/zconf.gperf

@@ -23,7 +23,6 @@ help,		T_HELP,		TF_COMMAND
 if,		T_IF,		TF_COMMAND|TF_PARAM
 if,		T_IF,		TF_COMMAND|TF_PARAM
 endif,		T_ENDIF,	TF_COMMAND
 endif,		T_ENDIF,	TF_COMMAND
 depends,	T_DEPENDS,	TF_COMMAND
 depends,	T_DEPENDS,	TF_COMMAND
-requires,	T_REQUIRES,	TF_COMMAND
 optional,	T_OPTIONAL,	TF_COMMAND
 optional,	T_OPTIONAL,	TF_COMMAND
 default,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN
 default,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN
 prompt,		T_PROMPT,	TF_COMMAND
 prompt,		T_PROMPT,	TF_COMMAND
@@ -32,15 +31,14 @@ def_tristate,	T_DEFAULT,	TF_COMMAND, S_TRISTATE
 bool,		T_TYPE,		TF_COMMAND, S_BOOLEAN
 bool,		T_TYPE,		TF_COMMAND, S_BOOLEAN
 boolean,	T_TYPE,		TF_COMMAND, S_BOOLEAN
 boolean,	T_TYPE,		TF_COMMAND, S_BOOLEAN
 def_bool,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN
 def_bool,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN
-def_boolean,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN
 int,		T_TYPE,		TF_COMMAND, S_INT
 int,		T_TYPE,		TF_COMMAND, S_INT
 hex,		T_TYPE,		TF_COMMAND, S_HEX
 hex,		T_TYPE,		TF_COMMAND, S_HEX
 string,		T_TYPE,		TF_COMMAND, S_STRING
 string,		T_TYPE,		TF_COMMAND, S_STRING
 select,		T_SELECT,	TF_COMMAND
 select,		T_SELECT,	TF_COMMAND
-enable,		T_SELECT,	TF_COMMAND
 range,		T_RANGE,	TF_COMMAND
 range,		T_RANGE,	TF_COMMAND
 option,		T_OPTION,	TF_COMMAND
 option,		T_OPTION,	TF_COMMAND
 on,		T_ON,		TF_PARAM
 on,		T_ON,		TF_PARAM
 modules,	T_OPT_MODULES,	TF_OPTION
 modules,	T_OPT_MODULES,	TF_OPTION
 defconfig_list,	T_OPT_DEFCONFIG_LIST,TF_OPTION
 defconfig_list,	T_OPT_DEFCONFIG_LIST,TF_OPTION
+env,		T_OPT_ENV,	TF_OPTION
 %%
 %%

+ 109 - 114
extra/config/zconf.hash.c_shipped

@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.1 */
+/* ANSI-C code produced by gperf version 3.0.3 */
 /* Command-line: gperf  */
 /* Command-line: gperf  */
 /* Computed positions: -k'1,3' */
 /* Computed positions: -k'1,3' */
 
 
@@ -30,7 +30,7 @@
 #endif
 #endif
 
 
 struct kconf_id;
 struct kconf_id;
-/* maximum key range = 45, duplicates = 0 */
+/* maximum key range = 47, duplicates = 0 */
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
 __inline
 __inline
@@ -44,32 +44,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
 {
 {
   static unsigned char asso_values[] =
   static unsigned char asso_values[] =
     {
     {
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 25, 30, 15,
+      49, 49, 49, 49, 49, 49, 49, 49, 11,  5,
-       0, 15,  0, 47,  5, 15, 47, 47, 30, 20,
+       0,  0,  5, 49,  5, 20, 49, 49,  5, 20,
-       5,  0, 25, 15,  0,  0, 10, 35, 47, 47,
+       5,  0, 30, 49,  0, 15,  0, 10,  0, 49,
-       5, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      47, 47, 47, 47, 47, 47
+      49, 49, 49, 49, 49, 49
     };
     };
   register int hval = len;
   register int hval = len;
 
 
@@ -89,136 +89,131 @@ kconf_id_hash (register const char *str, register unsigned int len)
 struct kconf_id_strings_t
 struct kconf_id_strings_t
   {
   {
     char kconf_id_strings_str2[sizeof("on")];
     char kconf_id_strings_str2[sizeof("on")];
-    char kconf_id_strings_str6[sizeof("string")];
+    char kconf_id_strings_str3[sizeof("env")];
-    char kconf_id_strings_str7[sizeof("default")];
+    char kconf_id_strings_str5[sizeof("endif")];
-    char kconf_id_strings_str8[sizeof("def_bool")];
+    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_str10[sizeof("range")];
-    char kconf_id_strings_str11[sizeof("def_boolean")];
+    char kconf_id_strings_str11[sizeof("choice")];
-    char kconf_id_strings_str12[sizeof("def_tristate")];
+    char kconf_id_strings_str12[sizeof("default")];
-    char kconf_id_strings_str13[sizeof("hex")];
+    char kconf_id_strings_str13[sizeof("def_bool")];
-    char kconf_id_strings_str14[sizeof("defconfig_list")];
+    char kconf_id_strings_str14[sizeof("help")];
-    char kconf_id_strings_str16[sizeof("option")];
+    char kconf_id_strings_str15[sizeof("bool")];
-    char kconf_id_strings_str17[sizeof("if")];
+    char kconf_id_strings_str16[sizeof("config")];
-    char kconf_id_strings_str18[sizeof("optional")];
+    char kconf_id_strings_str17[sizeof("def_tristate")];
-    char kconf_id_strings_str20[sizeof("endif")];
+    char kconf_id_strings_str18[sizeof("boolean")];
-    char kconf_id_strings_str21[sizeof("choice")];
+    char kconf_id_strings_str19[sizeof("defconfig_list")];
-    char kconf_id_strings_str22[sizeof("endmenu")];
+    char kconf_id_strings_str21[sizeof("string")];
-    char kconf_id_strings_str23[sizeof("requires")];
+    char kconf_id_strings_str22[sizeof("if")];
-    char kconf_id_strings_str24[sizeof("endchoice")];
+    char kconf_id_strings_str23[sizeof("int")];
-    char kconf_id_strings_str26[sizeof("config")];
+    char kconf_id_strings_str26[sizeof("select")];
     char kconf_id_strings_str27[sizeof("modules")];
     char kconf_id_strings_str27[sizeof("modules")];
-    char kconf_id_strings_str28[sizeof("int")];
+    char kconf_id_strings_str28[sizeof("tristate")];
     char kconf_id_strings_str29[sizeof("menu")];
     char kconf_id_strings_str29[sizeof("menu")];
-    char kconf_id_strings_str31[sizeof("prompt")];
+    char kconf_id_strings_str31[sizeof("source")];
-    char kconf_id_strings_str32[sizeof("depends")];
+    char kconf_id_strings_str32[sizeof("comment")];
-    char kconf_id_strings_str33[sizeof("tristate")];
+    char kconf_id_strings_str33[sizeof("hex")];
-    char kconf_id_strings_str34[sizeof("bool")];
     char kconf_id_strings_str35[sizeof("menuconfig")];
     char kconf_id_strings_str35[sizeof("menuconfig")];
-    char kconf_id_strings_str36[sizeof("select")];
+    char kconf_id_strings_str36[sizeof("prompt")];
-    char kconf_id_strings_str37[sizeof("boolean")];
+    char kconf_id_strings_str37[sizeof("depends")];
-    char kconf_id_strings_str39[sizeof("help")];
+    char kconf_id_strings_str48[sizeof("mainmenu")];
-    char kconf_id_strings_str41[sizeof("source")];
-    char kconf_id_strings_str42[sizeof("comment")];
-    char kconf_id_strings_str43[sizeof("mainmenu")];
-    char kconf_id_strings_str46[sizeof("enable")];
   };
   };
 static struct kconf_id_strings_t kconf_id_strings_contents =
 static struct kconf_id_strings_t kconf_id_strings_contents =
   {
   {
     "on",
     "on",
-    "string",
+    "env",
+    "endif",
+    "option",
+    "endmenu",
+    "optional",
+    "endchoice",
+    "range",
+    "choice",
     "default",
     "default",
     "def_bool",
     "def_bool",
-    "range",
+    "help",
-    "def_boolean",
+    "bool",
+    "config",
     "def_tristate",
     "def_tristate",
-    "hex",
+    "boolean",
     "defconfig_list",
     "defconfig_list",
-    "option",
+    "string",
     "if",
     "if",
-    "optional",
-    "endif",
-    "choice",
-    "endmenu",
-    "requires",
-    "endchoice",
-    "config",
-    "modules",
     "int",
     "int",
-    "menu",
-    "prompt",
-    "depends",
-    "tristate",
-    "bool",
-    "menuconfig",
     "select",
     "select",
-    "boolean",
+    "modules",
-    "help",
+    "tristate",
+    "menu",
     "source",
     "source",
     "comment",
     "comment",
-    "mainmenu",
+    "hex",
-    "enable"
+    "menuconfig",
+    "prompt",
+    "depends",
+    "mainmenu"
   };
   };
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
 #ifdef __GNUC__
 #ifdef __GNUC__
 __inline
 __inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
 #endif
 #endif
 struct kconf_id *
 struct kconf_id *
 kconf_id_lookup (register const char *str, register unsigned int len)
 kconf_id_lookup (register const char *str, register unsigned int len)
 {
 {
   enum
   enum
     {
     {
-      TOTAL_KEYWORDS = 33,
+      TOTAL_KEYWORDS = 31,
       MIN_WORD_LENGTH = 2,
       MIN_WORD_LENGTH = 2,
       MAX_WORD_LENGTH = 14,
       MAX_WORD_LENGTH = 14,
       MIN_HASH_VALUE = 2,
       MIN_HASH_VALUE = 2,
-      MAX_HASH_VALUE = 46
+      MAX_HASH_VALUE = 48
     };
     };
 
 
   static struct kconf_id wordlist[] =
   static struct kconf_id wordlist[] =
     {
     {
       {-1}, {-1},
       {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,		T_ON,		TF_PARAM},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,		T_ON,		TF_PARAM},
-      {-1}, {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3,		T_OPT_ENV,	TF_OPTION},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6,		T_TYPE,		TF_COMMAND, S_STRING},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
       {-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_str10,		T_RANGE,	TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
+      {(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_TRISTATE},
+      {(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_TYPE,		TF_COMMAND, S_HEX},
+      {(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_OPT_DEFCONFIG_LIST,TF_OPTION},
+      {(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_str15,		T_TYPE,		TF_COMMAND, S_BOOLEAN},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,		T_OPTION,	TF_COMMAND},
+      {(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_IF,		TF_COMMAND|TF_PARAM},
+      {(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_OPTIONAL,	TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,	T_TYPE,		TF_COMMAND, S_BOOLEAN},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19,	T_OPT_DEFCONFIG_LIST,TF_OPTION},
       {-1},
       {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20,		T_ENDIF,	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_str21,		T_CHOICE,	TF_COMMAND},
+      {(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_str22,	T_ENDMENU,	TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,		T_TYPE,		TF_COMMAND, S_INT},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,	T_REQUIRES,	TF_COMMAND},
+      {-1}, {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24,	T_ENDCHOICE,	TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,		T_SELECT,	TF_COMMAND},
-      {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,		T_CONFIG,	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_str27,	T_OPT_MODULES,	TF_OPTION},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,		T_TYPE,		TF_COMMAND, S_INT},
+      {(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_str29,		T_MENU,		TF_COMMAND},
       {-1},
       {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,		T_PROMPT,	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_DEPENDS,	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_TRISTATE},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,		T_TYPE,		TF_COMMAND, S_HEX},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34,		T_TYPE,		TF_COMMAND, S_BOOLEAN},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,	T_MENUCONFIG,	TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,		T_SELECT,	TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,	T_TYPE,		TF_COMMAND, S_BOOLEAN},
       {-1},
       {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39,		T_HELP,		TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,	T_MENUCONFIG,	TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,		T_PROMPT,	TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,	T_DEPENDS,	TF_COMMAND},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
       {-1},
       {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,		T_SOURCE,	TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,	T_MAINMENU,	TF_COMMAND}
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,	T_COMMENT,	TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43,	T_MAINMENU,	TF_COMMAND},
-      {-1}, {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46,		T_SELECT,	TF_COMMAND}
     };
     };
 
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)

+ 6 - 1
extra/config/zconf.l

@@ -217,6 +217,11 @@ n	[A-Za-z0-9_]
 		append_string("\n", 1);
 		append_string("\n", 1);
 	}
 	}
 	[^ \t\n].* {
 	[^ \t\n].* {
+		while (yyleng) {
+			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
+				break;
+			yyleng--;
+		}
 		append_string(yytext, yyleng);
 		append_string(yytext, yyleng);
 		if (!first_ts)
 		if (!first_ts)
 			first_ts = last_ts;
 			first_ts = last_ts;
@@ -265,7 +270,7 @@ FILE *zconf_fopen(const char *name)
 	FILE *f;
 	FILE *f;
 
 
 	f = fopen(name, "r");
 	f = fopen(name, "r");
-	if (!f && name[0] != '/') {
+	if (!f && name != NULL && name[0] != '/') {
 		env = getenv(SRCTREE);
 		env = getenv(SRCTREE);
 		if (env) {
 		if (env) {
 			sprintf(fullname, "%s/%s", env, name);
 			sprintf(fullname, "%s/%s", env, name);

File diff suppressed because it is too large
+ 455 - 334
extra/config/zconf.tab.c_shipped


+ 10 - 19
extra/config/zconf.y

@@ -64,7 +64,6 @@ static struct menu *current_menu, *current_entry;
 %token <id>T_IF
 %token <id>T_IF
 %token <id>T_ENDIF
 %token <id>T_ENDIF
 %token <id>T_DEPENDS
 %token <id>T_DEPENDS
-%token <id>T_REQUIRES
 %token <id>T_OPTIONAL
 %token <id>T_OPTIONAL
 %token <id>T_PROMPT
 %token <id>T_PROMPT
 %token <id>T_TYPE
 %token <id>T_TYPE
@@ -402,7 +401,7 @@ help_start: T_HELP T_EOL
 
 
 help: help_start T_HELPTEXT
 help: help_start T_HELPTEXT
 {
 {
-	current_entry->sym->help = $2;
+	current_entry->help = $2;
 };
 };
 
 
 /* depends option */
 /* depends option */
@@ -418,16 +417,6 @@ depends: T_DEPENDS T_ON expr T_EOL
 {
 {
 	menu_add_dep($3);
 	menu_add_dep($3);
 	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
 	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
-}
-	| T_DEPENDS expr T_EOL
-{
-	menu_add_dep($2);
-	printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
-}
-	| T_REQUIRES expr T_EOL
-{
-	menu_add_dep($2);
-	printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
 };
 };
 
 
 /* prompt statement */
 /* prompt statement */
@@ -501,9 +490,11 @@ void conf_parse(const char *name)
 	}
 	}
 	menu_finalize(&rootmenu);
 	menu_finalize(&rootmenu);
 	for_all_symbols(i, sym) {
 	for_all_symbols(i, sym) {
-		sym_check_deps(sym);
+		if (sym_check_deps(sym))
+			zconfnerrs++;
         }
         }
-
+	if (zconfnerrs)
+		exit(1);
 	sym_set_change_count(1);
 	sym_set_change_count(1);
 }
 }
 
 
@@ -647,11 +638,11 @@ void print_symbol(FILE *out, struct menu *menu)
 			break;
 			break;
 		}
 		}
 	}
 	}
-	if (sym->help) {
+	if (menu->help) {
-		int len = strlen(sym->help);
+		int len = strlen(menu->help);
-		while (sym->help[--len] == '\n')
+		while (menu->help[--len] == '\n')
-			sym->help[len] = 0;
+			menu->help[len] = 0;
-		fprintf(out, "  help\n%s\n", sym->help);
+		fprintf(out, "  help\n%s\n", menu->help);
 	}
 	}
 	fputc('\n', out);
 	fputc('\n', out);
 }
 }

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