From 43a95b8896b0d271de3bbb28cc18810f39b2e15b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 14 Feb 2007 08:21:06 +0000 Subject: pull latest kconfig from kernel --- extra/config/Kconfig-language.txt | 282 ----- extra/config/Makefile | 42 +- extra/config/Makefile.in | 128 -- extra/config/Makefile.kconfig | 278 +++++ extra/config/POTFILES.in | 5 + extra/config/README.uClibc | 18 + extra/config/conf-header.sh | 27 + extra/config/conf.c | 62 +- extra/config/confdata.c | 602 +++++++--- extra/config/expr.c | 53 +- extra/config/expr.h | 21 +- extra/config/gconf.c | 1636 +++++++++++++++++++++++++ extra/config/gconf.glade | 648 ++++++++++ extra/config/images.c | 326 +++++ extra/config/kconfig-language.txt | 282 +++++ extra/config/kconfig-to-uclibc.patch | 462 ++++++++ extra/config/kconfig_load.c | 35 + extra/config/kxgettext.c | 227 ++++ extra/config/lex.zconf.c_shipped | 1974 +++++-------------------------- extra/config/lkc.h | 42 +- extra/config/lkc_proto.h | 7 +- extra/config/lxdialog/check-lxdialog.sh | 84 ++ extra/config/lxdialog/checklist.c | 587 +++++---- extra/config/lxdialog/colors.h | 161 --- extra/config/lxdialog/dialog.h | 205 ++-- extra/config/lxdialog/inputbox.c | 392 +++--- extra/config/lxdialog/menubox.c | 672 ++++++----- extra/config/lxdialog/msgbox.c | 85 -- extra/config/lxdialog/textbox.c | 797 +++++-------- extra/config/lxdialog/util.c | 795 ++++++++----- extra/config/lxdialog/yesno.c | 156 ++- extra/config/mconf.c | 426 +++---- extra/config/menu.c | 49 +- extra/config/qconf.cc | 1743 +++++++++++++++++++++++++++ extra/config/qconf.h | 334 ++++++ extra/config/symbol.c | 148 ++- extra/config/util.c | 8 +- extra/config/zconf.gperf | 46 + extra/config/zconf.hash.c_shipped | 242 ++++ extra/config/zconf.l | 96 +- extra/config/zconf.tab.c_shipped | 1501 +++++++++++++---------- extra/config/zconf.tab.h_shipped | 125 -- extra/config/zconf.y | 354 +++--- 43 files changed, 10589 insertions(+), 5574 deletions(-) delete mode 100644 extra/config/Kconfig-language.txt delete mode 100644 extra/config/Makefile.in create mode 100644 extra/config/Makefile.kconfig create mode 100644 extra/config/POTFILES.in create mode 100644 extra/config/README.uClibc create mode 100755 extra/config/conf-header.sh create mode 100644 extra/config/gconf.c create mode 100644 extra/config/gconf.glade create mode 100644 extra/config/images.c create mode 100644 extra/config/kconfig-language.txt create mode 100644 extra/config/kconfig-to-uclibc.patch create mode 100644 extra/config/kconfig_load.c create mode 100644 extra/config/kxgettext.c create mode 100755 extra/config/lxdialog/check-lxdialog.sh delete mode 100644 extra/config/lxdialog/colors.h delete mode 100644 extra/config/lxdialog/msgbox.c create mode 100644 extra/config/qconf.cc create mode 100644 extra/config/qconf.h create mode 100644 extra/config/zconf.gperf create mode 100644 extra/config/zconf.hash.c_shipped delete mode 100644 extra/config/zconf.tab.h_shipped (limited to 'extra') diff --git a/extra/config/Kconfig-language.txt b/extra/config/Kconfig-language.txt deleted file mode 100644 index da51c0e7c..000000000 --- a/extra/config/Kconfig-language.txt +++ /dev/null @@ -1,282 +0,0 @@ -Introduction ------------- - -The configuration database is collection of configuration options -organized in a tree structure: - - +- Code maturity level options - | +- Prompt for development and/or incomplete code/drivers - +- General setup - | +- Networking support - | +- System V IPC - | +- BSD Process Accounting - | +- Sysctl support - +- Loadable module support - | +- Enable loadable module support - | +- Set version information on all module symbols - | +- Kernel module loader - +- ... - -Every entry has its own dependencies. These dependencies are used -to determine the visibility of an entry. Any child entry is only -visible if its parent entry is also visible. - -Menu entries ------------- - -Most entries define a config option, all other entries help to organize -them. A single configuration option is defined like this: - -config MODVERSIONS - bool "Set version information on all module symbols" - depends MODULES - help - Usually, modules have to be recompiled whenever you switch to a new - kernel. ... - -Every line starts with a key word and can be followed by multiple -arguments. "config" starts a new config entry. The following lines -define attributes for this config option. Attributes can be the type of -the config option, input prompt, dependencies, help text and default -values. A config option can be defined multiple times with the same -name, but every definition can have only a single input prompt and the -type must not conflict. - -Menu attributes ---------------- - -A menu entry can have a number of attributes. Not all of them are -applicable everywhere (see syntax). - -- type definition: "bool"/"tristate"/"string"/"hex"/"integer" - Every config option must have a type. There are only two basic types: - tristate and string, the other types are based on these two. The type - definition optionally accepts an input prompt, so these two examples - are equivalent: - - bool "Networking support" - and - bool - prompt "Networking support" - -- input prompt: "prompt" ["if" ] - Every menu entry can have at most one prompt, which is used to display - to the user. Optionally dependencies only for this prompt can be added - with "if". - -- default value: "default" ["if" ] - A config option can have any number of default values. If multiple - default values are visible, only the first defined one is active. - Default values are not limited to the menu entry, where they are - defined, this means the default can be defined somewhere else or be - overridden by an earlier definition. - The default value is only assigned to the config symbol if no other - value was set by the user (via the input prompt above). If an input - prompt is visible the default value is presented to the user and can - be overridden by him. - Optionally dependencies only for this default value can be added with - "if". - -- dependencies: "depends on"/"requires" - This defines a dependency for this menu entry. If multiple - dependencies are defined they are connected with '&&'. Dependencies - are applied to all other options within this menu entry (which also - accept an "if" expression), so these two examples are equivalent: - - bool "foo" if BAR - default y if BAR - and - depends on BAR - bool "foo" - default y - -- reverse dependencies: "select" ["if" ] - While normal dependencies reduce the upper limit of a symbol (see - below), reverse dependencies can be used to force a lower limit of - another symbol. The value of the current menu symbol is used as the - minimal value can be set to. If is selected multiple - times, the limit is set to the largest selection. - Reverse dependencies can only be used with boolean or tristate - symbols. - -- numerical ranges: "range" ["if" ] - This allows to limit the range of possible input values for integer - and hex symbols. The user can only input a value which is larger than - or equal to the first symbol and smaller than or equal to the second - symbol. - -- help text: "help" or "---help---" - This defines a help text. The end of the help text is determined by - the indentation level, this means it ends at the first line which has - a smaller indentation than the first line of the help text. - "---help---" and "help" do not differ in behaviour, "---help---" is - used to help visually seperate configuration logic from help within - the file as an aid to developers. - - -Menu dependencies ------------------ - -Dependencies define the visibility of a menu entry and can also reduce -the input range of tristate symbols. The tristate logic used in the -expressions uses one more state than normal boolean logic to express the -module state. Dependency expressions have the following syntax: - - ::= (1) - '=' (2) - '!=' (3) - '(' ')' (4) - '!' (5) - '&&' (6) - '||' (7) - -Expressions are listed in decreasing order of precedence. - -(1) Convert the symbol into an expression. Boolean and tristate symbols - are simply converted into the respective expression values. All - other symbol types result in 'n'. -(2) If the values of both symbols are equal, it returns 'y', - otherwise 'n'. -(3) If the values of both symbols are equal, it returns 'n', - otherwise 'y'. -(4) Returns the value of the expression. Used to override precedence. -(5) Returns the result of (2-/expr/). -(6) Returns the result of min(/expr/, /expr/). -(7) Returns the result of max(/expr/, /expr/). - -An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 -respectively for calculations). A menu entry becomes visible when it's -expression evaluates to 'm' or 'y'. - -There are two types of symbols: constant and nonconstant symbols. -Nonconstant symbols are the most common ones and are defined with the -'config' statement. Nonconstant symbols consist entirely of alphanumeric -characters or underscores. -Constant symbols are only part of expressions. Constant symbols are -always surrounded by single or double quotes. Within the quote any -other character is allowed and the quotes can be escaped using '\'. - -Menu structure --------------- - -The position of a menu entry in the tree is determined in two ways. First -it can be specified explicitly: - -menu "Network device support" - depends NET - -config NETDEVICES - ... - -endmenu - -All entries within the "menu" ... "endmenu" block become a submenu of -"Network device support". All subentries inherit the dependencies from -the menu entry, e.g. this means the dependency "NET" is added to the -dependency list of the config option NETDEVICES. - -The other way to generate the menu structure is done by analyzing the -dependencies. If a menu entry somehow depends on the previous entry, it -can be made a submenu of it. First, the previous (parent) symbol must -be part of the dependency list and then one of these two conditions -must be true: -- the child entry must become invisible, if the parent is set to 'n' -- the child entry must only be visible, if the parent is visible - -config MODULES - bool "Enable loadable module support" - -config MODVERSIONS - bool "Set version information on all module symbols" - depends MODULES - -comment "module support disabled" - depends !MODULES - -MODVERSIONS directly depends on MODULES, this means it's only visible if -MODULES is different from 'n'. The comment on the other hand is always -visible when MODULES is visible (the (empty) dependency of MODULES is -also part of the comment dependencies). - - -Kconfig syntax --------------- - -The configuration file describes a series of menu entries, where every -line starts with a keyword (except help texts). The following keywords -end a menu entry: -- config -- menuconfig -- choice/endchoice -- comment -- menu/endmenu -- if/endif -- source -The first five also start the definition of a menu entry. - -config: - - "config" - - -This defines a config symbol and accepts any of above -attributes as options. - -menuconfig: - "menuconfig" - - -This is similiar to the simple config entry above, but it also gives a -hint to front ends, that all suboptions should be displayed as a -separate list of options. - -choices: - - "choice" - - - "endchoice" - -This defines a choice group and accepts any of above attributes as -options. A choice can only be of type bool or tristate, while a boolean -choice only allows a single config entry to be selected, a tristate -choice also allows any number of config entries to be set to 'm'. This -can be used if multiple drivers for a single hardware exists and only a -single driver can be compiled/loaded into the kernel, but all drivers -can be compiled as modules. -A choice accepts another option "optional", which allows to set the -choice to 'n' and no entry needs to be selected. - -comment: - - "comment" - - -This defines a comment which is displayed to the user during the -configuration process and is also echoed to the output files. The only -possible options are dependencies. - -menu: - - "menu" - - - "endmenu" - -This defines a menu block, see "Menu structure" above for more -information. The only possible options are dependencies. - -if: - - "if" - - "endif" - -This defines an if block. The dependency expression is appended -to all enclosed menu entries. - -source: - - "source" - -This reads the specified configuration file. This file is always parsed. diff --git a/extra/config/Makefile b/extra/config/Makefile index 519d55844..84a0ed34f 100644 --- a/extra/config/Makefile +++ b/extra/config/Makefile @@ -1,13 +1,35 @@ -# Makefile for uClibc -# -# Copyright (C) 2000-2005 Erik Andersen -# -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -# - +obj := . +src := . top_srcdir=../../ top_builddir=../../ +srctree := . include $(top_builddir)Rules.mak -all: objs -include Makefile.in -include $(top_srcdir)Makerules + +include Makefile.kconfig + +__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) +host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) +host-cmulti := $(foreach m,$(__hostprogs),\ + $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) +host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs))) + +$(host-csingle): %: %.c FORCE + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(HOST_LOADLIBES) $< -o $@ + +$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(HOST_LOADLIBES) $($@-objs) -o $@ + +$(host-cobjs): %.o: %.c FORCE + $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) -c $< -o $@ + +$(obj)/%:: $(src)/%_shipped + $(Q)cat $< > $@ + +clean: + $(Q)rm -f $(clean-files) +distclean: clean + $(Q)rm -f $(lxdialog) $(conf-objs) $(mconf-objs) $(kxgettext-objs) \ + $(hostprogs-y) $(qconf-cxxobjs) $(qconf-objs) $(gconf-objs) + +FORCE: +.PHONY: FORCE clean distclean diff --git a/extra/config/Makefile.in b/extra/config/Makefile.in deleted file mode 100644 index 9d9b70e3b..000000000 --- a/extra/config/Makefile.in +++ /dev/null @@ -1,128 +0,0 @@ -# Makefile for uClibc -# -# Copyright (C) 2000-2005 Erik Andersen -# -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -# - -ifeq ($(shell uname),SunOS) -HOSTLIBNCURSES = -lcurses -else -HOSTLIBNCURSES = -lncurses -endif -ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) - HOSTNCURSES = -I/usr/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) - HOSTNCURSES = -I/usr/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h)) - HOSTNCURSES = -I/usr/local/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h)) - HOSTNCURSES = -I/usr/local/include/ncurses -DCURSES_LOC="" -else -ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) - HOSTNCURSES = -DCURSES_LOC="" -else - HOSTNCURSES = -DCURSES_LOC="" -endif -endif -endif -endif -endif - -BUILD_CFLAGS-config := -I. - -BUILD_CFLAGS-mconf.o := $(HOSTNCURSES) -BUILD_CFLAGS-lxdialog := $(HOSTNCURSES) - -BUILD_LDFLAGS-mconf := $(HOSTLIBNCURSES) - -config_DIR := $(top_srcdir)extra/config -config_OUT := $(top_builddir)extra/config - -config_SHIPPED_SRC := $(patsubst %,$(config_OUT)/%,lex.zconf.c zconf.tab.c zconf.tab.h) - -config_CONF_SRC := conf.c -config_MCONF_SRC := mconf.c -config_LXD_SRC := \ - lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \ - lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \ - lxdialog/msgbox.c -config_SHARED_SRC := $(config_OUT)/zconf.tab.c -config_SHARED_DEP1 := $(patsubst %,$(config_DIR)/%,lkc.h lkc_proto.h expr.h) -config_SHARED_DEP2 := $(patsubst %,$(config_OUT)/%,lkc_defs.h zconf.tab.h) -config_SHARED_DEPS := $(config_SHARED_DEP1) $(config_SHARED_DEP2) -config_CONF_OBJS := $(patsubst %.c,$(config_OUT)/%.o,$(config_CONF_SRC)) -config_MCONF_OBJS := $(patsubst %.c,$(config_OUT)/%.o,$(config_MCONF_SRC) $(config_LXD_SRC)) -config_SHARED_OBJS := $(patsubst %.c,%.o,$(config_SHARED_SRC)) - -objs: ncurses $(config_OUT)/conf $(config_OUT)/mconf - -conf $(config_OUT)/conf: $(config_CONF_OBJS) $(config_SHARED_OBJS) - $(hcompile.u) - -mconf $(config_OUT)/mconf: $(config_MCONF_OBJS) $(config_SHARED_OBJS) | ncurses - $(hcompile.u) - -$(config_CONF_OBJS) $(config_MCONF_OBJS): $(config_OUT)/%.o : $(config_DIR)/%.c | $(config_SHARED_DEPS) - $(hcompile.o) - -$(config_OUT)/lkc_defs.h: $(config_DIR)/lkc_proto.h - @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' - -### -# The following requires flex/bison -# By default we use the _shipped versions, uncomment the -# following line if you are modifying the flex/bison src. -#LKC_GENPARSER := 1 - -ifdef LKC_GENPARSER - -%.tab.c %.tab.h: %.y - bison -t -d -v -b $* -p $(notdir $*) $< - -lex.%.c: %.l - flex -P$(notdir $*) -o$@ $< -else - -$(config_OUT)/lex.zconf.o: $(config_OUT)/lex.zconf.c | $(config_SHARED_DEPS) - $(hcompile.o) - -$(config_SHIPPED_SRC): $(config_OUT)/% : $(config_DIR)/%_shipped - cp $< $@ - -$(config_OUT)/zconf.tab.o: $(config_SHARED_SRC) | $(config_OUT)/lex.zconf.c $(patsubst %,$(config_DIR)/%,confdata.c expr.c symbol.c menu.c) $(config_SHARED_DEPS) - $(hcompile.o) - -endif - -.PHONY: ncurses - -ncurses: - @echo "main() {}" > $(config_OUT)/lxtemp.c - @if $(HOSTCC) $(config_OUT)/lxtemp.c -o $(config_OUT)/a.out $(HOSTLIBNCURSES) ; then \ - $(RM) $(config_OUT)/{lxtemp.c,a.out}; \ - else \ - $(RM) $(config_OUT)/lxtemp.c; \ - echo -e "\007" ;\ - echo ">> Unable to find the Ncurses libraries." ;\ - echo ">>" ;\ - echo ">> You must have Ncurses installed in order" ;\ - echo ">> to use 'make menuconfig'" ;\ - echo ">>" ;\ - echo ">> Maybe you want to try 'make config', which" ;\ - echo ">> doesn't depend on the Ncurses libraries." ;\ - echo ;\ - exit 1 ;\ - fi - -objclean-y += config_clean - -# to be removed after including into top Makefile.in -clean: config_clean - -config_clean: - $(RM) $(config_OUT)/*.o $(config_OUT)/lxdialog/*.o $(config_SHIPPED_SRC) $(MCONF_OBJS) $(CONF_OBJS) \ - conf mconf lkc_defs.h diff --git a/extra/config/Makefile.kconfig b/extra/config/Makefile.kconfig new file mode 100644 index 000000000..e67947d53 --- /dev/null +++ b/extra/config/Makefile.kconfig @@ -0,0 +1,278 @@ +# =========================================================================== +# Kernel configuration targets +# These targets are used from top-level makefile + +PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config + +xconfig: $(obj)/qconf + $< arch/$(ARCH)/Kconfig + +gconfig: $(obj)/gconf + $< arch/$(ARCH)/Kconfig + +menuconfig: $(obj)/mconf + $< arch/$(ARCH)/Kconfig + +config: $(obj)/conf + $< arch/$(ARCH)/Kconfig + +oldconfig: $(obj)/conf + $< -o arch/$(ARCH)/Kconfig + +silentoldconfig: $(obj)/conf + $< -s arch/$(ARCH)/Kconfig + +update-po-config: $(obj)/kxgettext + xgettext --default-domain=linux \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=scripts/kconfig/POTFILES.in \ + --output scripts/kconfig/config.pot + $(Q)ln -fs Kconfig_i386 arch/um/Kconfig_arch + $(Q)for i in `ls arch/`; \ + do \ + scripts/kconfig/kxgettext arch/$$i/Kconfig \ + | msguniq -o scripts/kconfig/linux_$${i}.pot; \ + done + $(Q)msgcat scripts/kconfig/config.pot \ + `find scripts/kconfig/ -type f -name linux_*.pot` \ + --output scripts/kconfig/linux_raw.pot + $(Q)msguniq --sort-by-file scripts/kconfig/linux_raw.pot \ + --output scripts/kconfig/linux.pot + $(Q)rm -f arch/um/Kconfig_arch + $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot + +PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig + +randconfig: $(obj)/conf + $< -r arch/$(ARCH)/Kconfig + +allyesconfig: $(obj)/conf + $< -y arch/$(ARCH)/Kconfig + +allnoconfig: $(obj)/conf + $< -n arch/$(ARCH)/Kconfig + +allmodconfig: $(obj)/conf + $< -m arch/$(ARCH)/Kconfig + +defconfig: $(obj)/conf +ifeq ($(KBUILD_DEFCONFIG),) + $< -d arch/$(ARCH)/Kconfig +else + @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)' + $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig +endif + +%_defconfig: $(obj)/conf + $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig + +# Help text used by make help +help: + @echo ' config - Update current config utilising a line-oriented program' + @echo ' menuconfig - Update current config utilising a menu based program' + @echo ' xconfig - Update current config utilising a QT based front-end' + @echo ' gconfig - Update current config utilising a GTK based front-end' + @echo ' oldconfig - Update current config utilising a provided .config as base' + @echo ' silentoldconfig - Same as oldconfig, but quietly' + @echo ' randconfig - New config with random answer to all options' + @echo ' defconfig - New config with default answer to all options' + @echo ' allmodconfig - New config selecting modules when possible' + @echo ' allyesconfig - New config where all options are accepted with yes' + @echo ' allnoconfig - New config where all options are answered with no' + +# lxdialog stuff +check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh + +# Use reursively expanded variables so we do not call gcc unless +# we really need to do so. (Do not call gcc as part of make mrproper) +HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) +HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) + +HOST_EXTRACFLAGS += -DLOCALE + +PHONY += $(obj)/dochecklxdialog +$(obj)/dochecklxdialog: + $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) + +always := dochecklxdialog + + +# =========================================================================== +# Shared Makefile for the various kconfig executables: +# conf: Used for defconfig, oldconfig and related targets +# mconf: Used for the mconfig target. +# Utilizes the lxdialog package +# qconf: Used for the xconfig target +# Based on QT which needs to be installed to compile it +# gconf: Used for the gconfig target +# Based on GTK which needs to be installed to compile it +# object files used by all kconfig flavours + +lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o +lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o + +conf-objs := conf.o zconf.tab.o +mconf-objs := mconf.o zconf.tab.o $(lxdialog) +kxgettext-objs := kxgettext.o zconf.tab.o + +hostprogs-y := conf qconf gconf kxgettext + +#ifeq ($(MAKECMDGOALS),menuconfig) + hostprogs-y += mconf +#endif + +ifeq ($(MAKECMDGOALS),xconfig) + qconf-target := 1 +endif +ifeq ($(MAKECMDGOALS),gconfig) + gconf-target := 1 +endif + + +ifeq ($(qconf-target),1) +qconf-cxxobjs := qconf.o +qconf-objs := kconfig_load.o zconf.tab.o +endif + +ifeq ($(gconf-target),1) +gconf-objs := gconf.o kconfig_load.o zconf.tab.o +endif + +clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ + .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c + +# Needed for systems without gettext +KBUILD_HAVE_NLS := $(shell \ + if echo "\#include " | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \ + then echo yes ; \ + else echo no ; fi) +ifeq ($(KBUILD_HAVE_NLS),no) +HOSTCFLAGS += -DKBUILD_NO_NLS +endif + +# generated files seem to need this to find local include files +HOSTCFLAGS_lex.zconf.o := -I$(src) +HOSTCFLAGS_zconf.tab.o := -I$(src) + +HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl +HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK + +HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` +HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ + -D LKC_DIRECT_LINK + +$(obj)/qconf.o: $(obj)/.tmp_qtcheck + +ifeq ($(qconf-target),1) +$(obj)/.tmp_qtcheck: $(src)/Makefile +-include $(obj)/.tmp_qtcheck + +# QT needs some extra effort... +$(obj)/.tmp_qtcheck: + @set -e; echo " CHECK qt"; dir=""; pkg=""; \ + pkg-config --exists qt 2> /dev/null && pkg=qt; \ + pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ + if [ -n "$$pkg" ]; then \ + cflags="\$$(shell pkg-config $$pkg --cflags)"; \ + libs="\$$(shell pkg-config $$pkg --libs)"; \ + moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ + dir="$$(pkg-config $$pkg --variable=prefix)"; \ + else \ + for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ + if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ + done; \ + if [ -z "$$dir" ]; then \ + echo "*"; \ + echo "* Unable to find the QT installation. Please make sure that"; \ + echo "* the QT development package is correctly installed and"; \ + echo "* either install pkg-config or set the QTDIR environment"; \ + echo "* variable to the correct location."; \ + echo "*"; \ + false; \ + fi; \ + libpath=$$dir/lib; lib=qt; osdir=""; \ + $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ + osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ + test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ + test -f $$libpath/libqt-mt.so && lib=qt-mt; \ + cflags="-I$$dir/include"; \ + libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ + moc="$$dir/bin/moc"; \ + fi; \ + if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ + echo "*"; \ + echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ + echo "*"; \ + moc="/usr/bin/moc"; \ + fi; \ + echo "KC_QT_CFLAGS=$$cflags" > $@; \ + echo "KC_QT_LIBS=$$libs" >> $@; \ + echo "KC_QT_MOC=$$moc" >> $@ +endif + +$(obj)/gconf.o: $(obj)/.tmp_gtkcheck + +ifeq ($(gconf-target),1) +-include $(obj)/.tmp_gtkcheck + +# GTK needs some extra effort, too... +$(obj)/.tmp_gtkcheck: + @if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ + if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \ + touch $@; \ + else \ + echo "*"; \ + echo "* GTK+ is present but version >= 2.0.0 is required."; \ + echo "*"; \ + false; \ + fi \ + else \ + echo "*"; \ + echo "* Unable to find the GTK+ installation. Please make sure that"; \ + echo "* the GTK+ 2.0 development package is correctly installed..."; \ + echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ + echo "*"; \ + false; \ + fi +endif + +$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c + +$(obj)/kconfig_load.o: $(obj)/lkc_defs.h + +$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h + +$(obj)/gconf.o: $(obj)/lkc_defs.h + +$(obj)/%.moc: $(src)/%.h + $(KC_QT_MOC) -i $< -o $@ + +$(obj)/lkc_defs.h: $(src)/lkc_proto.h + sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + + +### +# The following requires flex/bison/gperf +# By default we use the _shipped versions, uncomment the following line if +# you are modifying the flex/bison src. +# LKC_GENPARSER := 1 + +ifdef LKC_GENPARSER + +$(obj)/zconf.tab.c: $(src)/zconf.y +$(obj)/lex.zconf.c: $(src)/zconf.l +$(obj)/zconf.hash.c: $(src)/zconf.gperf + +%.tab.c: %.y + bison -l -b $* -p $(notdir $*) $< + cp $@ $@_shipped + +lex.%.c: %.l + flex -L -P$(notdir $*) -o$@ $< + cp $@ $@_shipped + +%.hash.c: %.gperf + gperf < $< > $@ + cp $@ $@_shipped + +endif diff --git a/extra/config/POTFILES.in b/extra/config/POTFILES.in new file mode 100644 index 000000000..cc94e46a7 --- /dev/null +++ b/extra/config/POTFILES.in @@ -0,0 +1,5 @@ +scripts/kconfig/mconf.c +scripts/kconfig/conf.c +scripts/kconfig/confdata.c +scripts/kconfig/gconf.c +scripts/kconfig/qconf.cc diff --git a/extra/config/README.uClibc b/extra/config/README.uClibc new file mode 100644 index 000000000..a20d89963 --- /dev/null +++ b/extra/config/README.uClibc @@ -0,0 +1,18 @@ +This is a copy of the kconfig code in the kernel tweaked to suite uClibc. + +To update: + cp -r /usr/src/linux/scripts/kconfig extra/config.new + cd extra/config.new + cp /usr/src/linux/Documentation/kbuild/kconfig-language.txt . + mv Makefile Makefile.kconfig + patch -p1 < ../config/kconfig-to-uclibc.patch + cp ../config/conf-header.sh ../config/README.uClibc . + cd .. + rm -rf config + mv config.new config + +Then verify the toplevel targets work: + config + defconfig + menuconfig + oldconfig diff --git a/extra/config/conf-header.sh b/extra/config/conf-header.sh new file mode 100755 index 000000000..90dfa999a --- /dev/null +++ b/extra/config/conf-header.sh @@ -0,0 +1,27 @@ +#!/bin/sh -e + +# Turn .config into a header file + +if [ -z "$1" ] ; then + echo "Usage: conf-header.sh <.config>" + exit 1 +fi + +cat < directly; use instead +#endif + +#define __UCLIBC_MAJOR__ ${MAJOR_VERSION} +#define __UCLIBC_MINOR__ ${MINOR_VERSION} +#define __UCLIBC_SUBLEVEL__ ${SUBLEVEL} +EOF + +exec \ +sed \ + -e '/^#$/d' \ + -e '/^[^#]/s:^\([^=]*\)=\(.*\):#define __\1__ \2:' \ + -e '/^#define /s: y$: 1:' \ + -e '/^# .* is not set$/s:^# \(.*\) is not set$:#undef __\1__:' \ + -e 's:^# \(.*\)$:/* \1 */:' \ + $1 diff --git a/extra/config/conf.c b/extra/config/conf.c index 0907369dd..8ad8d9d4f 100644 --- a/extra/config/conf.c +++ b/extra/config/conf.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,15 @@ static void conf_askvalue(struct symbol *sym, const char *def) } switch (input_mode) { + case set_no: + case set_mod: + case set_yes: + case set_random: + if (sym_has_value(sym)) { + printf("%s\n", def); + return; + } + break; case ask_new: case ask_silent: if (sym_has_value(sym)) { @@ -305,8 +315,7 @@ static int conf_choice(struct menu *menu) printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); def_sym = sym_get_choice_value(sym); cnt = def = 0; - line[0] = '0'; - line[1] = 0; + line[0] = 0; for (child = menu->list; child; child = child->next) { if (!menu_is_visible(child)) continue; @@ -467,15 +476,14 @@ static void check_conf(struct menu *menu) return; sym = menu->sym; - if (sym) { - if (sym_is_changable(sym) && !sym_has_value(sym)) { + if (sym && !sym_has_value(sym)) { + if (sym_is_changable(sym) || + (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); conf(rootEntry); } - if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod) - return; } for (child = menu->list; child; child = child->next) @@ -524,13 +532,14 @@ int main(int ac, char **av) break; case 'h': case '?': - printf("%s [-o|-s] config\n", av[0]); + fprintf(stderr, "See README for usage info\n"); exit(0); } } name = av[i]; if (!name) { printf(_("%s: Kconfig file missing\n"), av[0]); + exit(1); } conf_parse(name); //zconfdump(stdout); @@ -559,6 +568,27 @@ int main(int ac, char **av) case ask_new: conf_read(NULL); break; + case set_no: + case set_mod: + case set_yes: + case set_random: + name = getenv("KCONFIG_ALLCONFIG"); + if (name && !stat(name, &tmpstat)) { + conf_read_simple(name, S_DEF_USER); + break; + } + switch (input_mode) { + case set_no: name = "allno.config"; break; + case set_mod: name = "allmod.config"; break; + case set_yes: name = "allyes.config"; break; + case set_random: name = "allrandom.config"; break; + default: break; + } + if (!stat(name, &tmpstat)) + conf_read_simple(name, S_DEF_USER); + else if (!stat("all.config", &tmpstat)) + conf_read_simple("all.config", S_DEF_USER); + break; default: break; } @@ -570,14 +600,28 @@ int main(int ac, char **av) input_mode = ask_silent; valid_stdin = 1; } - } + } else if (conf_get_changed()) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, _("\n*** uClibc configuration requires explicit update.\n\n")); + return 1; + } + } else + goto skip_check; + do { conf_cnt = 0; check_conf(&rootmenu); } while (conf_cnt); if (conf_write(NULL)) { - fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + fprintf(stderr, _("\n*** Error during writing of the uClibc configuration.\n\n")); return 1; } +skip_check: + if (/*input_mode == ask_silent &&*/ conf_write_autoconf()) { + fprintf(stderr, _("\n*** Error during writing of the uClibc configuration.\n\n")); + return 1; + } + return 0; } diff --git a/extra/config/confdata.c b/extra/config/confdata.c index 60bfe77c4..0dbd14152 100644 --- a/extra/config/confdata.c +++ b/extra/config/confdata.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -14,15 +15,31 @@ #define LKC_DIRECT_LINK #include "lkc.h" -const char conf_def_filename[] = ".config"; +static void conf_warning(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); -const char conf_defname[] = "extra/Configs/Config.default"; +static const char *conf_filename; +static int conf_lineno, conf_warnings, conf_unsaved; -const char *conf_confnames[] = { - ".config", - conf_defname, - NULL, -}; +const char conf_defname[] = "extra/Configs/defconfigs/$ARCH"; + +static void conf_warning(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + conf_warnings++; +} + +const char *conf_get_configname(void) +{ + char *name = getenv("KCONFIG_CONFIG"); + + return name ? name : ".config"; +} static char *conf_expand_value(const char *in) { @@ -66,53 +83,70 @@ char *conf_get_default_confname(void) return name; } -int conf_read(const char *name) +int conf_read_simple(const char *name, int def) { FILE *in = NULL; char line[1024]; char *p, *p2; - int lineno = 0; struct symbol *sym; - struct property *prop; - struct expr *e; - int i; + int i, def_flags; if (name) { in = zconf_fopen(name); } else { - const char **names = conf_confnames; - while ((name = *names++)) { - name = conf_expand_value(name); + struct property *prop; + + name = conf_get_configname(); + in = zconf_fopen(name); + if (in) + goto load; + sym_add_change_count(1); + if (!sym_defconfig_list) + return 1; + + for_all_defaults(sym_defconfig_list, prop) { + if (expr_calc_value(prop->visible.expr) == no || + prop->expr->type != E_SYMBOL) + continue; + name = conf_expand_value(prop->expr->left.sym->name); in = zconf_fopen(name); if (in) { printf(_("#\n" - "# using defaults found in %s\n" - "#\n"), name); - break; + "# using defaults found in %s\n" + "#\n"), name); + goto load; } } } - if (!in) return 1; +load: + conf_filename = name; + conf_lineno = 0; + conf_warnings = 0; + conf_unsaved = 0; + + def_flags = SYMBOL_DEF << def; for_all_symbols(i, sym) { - sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; - sym->flags &= ~SYMBOL_VALID; + sym->flags |= SYMBOL_CHANGED; + sym->flags &= ~(def_flags|SYMBOL_VALID); + if (sym_is_choice(sym)) + sym->flags |= def_flags; switch (sym->type) { case S_INT: case S_HEX: case S_STRING: - if (sym->user.val) - free(sym->user.val); + if (sym->def[def].val) + free(sym->def[def].val); default: - sym->user.val = NULL; - sym->user.tri = no; + sym->def[def].val = NULL; + sym->def[def].tri = no; } } while (fgets(line, sizeof(line), in)) { - lineno++; + conf_lineno++; sym = NULL; switch (line[0]) { case '#': @@ -124,54 +158,84 @@ int conf_read(const char *name) *p++ = 0; if (strncmp(p, "is not set", 10)) continue; - sym = sym_find(line + 2); - if (!sym) { - fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 2); + if (def == S_DEF_USER) { + sym = sym_find(line + 2); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 2); + break; + } + } else { + sym = sym_lookup(line + 2, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_BOOLEAN; + } + if (sym->flags & def_flags) { + conf_warning("trying to reassign symbol %s", sym->name); break; } switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - sym->user.tri = no; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = no; + sym->flags |= def_flags; break; default: ; } break; - case 'A' ... 'Z': p = strchr(line, '='); if (!p) continue; *p++ = 0; p2 = strchr(p, '\n'); - if (p2) - *p2 = 0; - sym = sym_find(line); - if (!sym) { - fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line); + if (p2) { + *p2-- = 0; + if (*p2 == '\r') + *p2 = 0; + } + if (def == S_DEF_USER) { + sym = sym_find(line); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line); + break; + } + } else { + sym = sym_lookup(line, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_OTHER; + } + if (sym->flags & def_flags) { + conf_warning("trying to reassign symbol %s", sym->name); break; } switch (sym->type) { case S_TRISTATE: if (p[0] == 'm') { - sym->user.tri = mod; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = mod; + sym->flags |= def_flags; break; } case S_BOOLEAN: if (p[0] == 'y') { - sym->user.tri = yes; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = yes; + sym->flags |= def_flags; break; } if (p[0] == 'n') { - sym->user.tri = no; - sym->flags &= ~SYMBOL_NEW; + 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; @@ -183,62 +247,105 @@ int conf_read(const char *name) memmove(p2, p2 + 1, strlen(p2)); } if (!p2) { - fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); - exit(1); + conf_warning("invalid string found"); + continue; } case S_INT: case S_HEX: + done: if (sym_string_valid(sym, p)) { - sym->user.val = strdup(p); - sym->flags &= ~SYMBOL_NEW; + sym->def[def].val = strdup(p); + sym->flags |= def_flags; } else { - fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); - exit(1); + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + continue; } break; default: ; } break; + case '\r': case '\n': break; default: + conf_warning("unexpected data"); continue; } if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - switch (sym->user.tri) { + switch (sym->def[def].tri) { case no: break; case mod: - if (cs->user.tri == yes) - /* warn? */; + if (cs->def[def].tri == yes) { + conf_warning("%s creates inconsistent choice state", sym->name); + cs->flags &= ~def_flags; + } break; case yes: - if (cs->user.tri != no) - /* warn? */; - cs->user.val = sym; + if (cs->def[def].tri != no) { + conf_warning("%s creates inconsistent choice state", sym->name); + cs->flags &= ~def_flags; + } else + cs->def[def].val = sym; break; } - cs->user.tri = E_OR(cs->user.tri, sym->user.tri); - cs->flags &= ~SYMBOL_NEW; + cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri); } } fclose(in); if (modules_sym) sym_calc_value(modules_sym); + return 0; +} + +int conf_read(const char *name) +{ + struct symbol *sym; + struct property *prop; + struct expr *e; + int i, flags; + + sym_set_change_count(0); + + if (conf_read_simple(name, S_DEF_USER)) + return 1; + for_all_symbols(i, sym) { sym_calc_value(sym); + if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) + goto sym_ok; + if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { + /* check that calculated value agrees with saved value */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) + break; + if (!sym_is_choice(sym)) + goto sym_ok; + default: + if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) + goto sym_ok; + break; + } + } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) + /* no previous value and not saved */ + goto sym_ok; + conf_unsaved++; + /* maybe print value in verbose mode... */ + sym_ok: if (sym_has_value(sym) && !sym_is_choice_value(sym)) { if (sym->visible == no) - sym->flags |= SYMBOL_NEW; + sym->flags &= ~SYMBOL_DEF_USER; switch (sym->type) { case S_STRING: case S_INT: case S_HEX: - if (!sym_string_within_range(sym, sym->user.val)) - sym->flags |= SYMBOL_NEW; + if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val)) + sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); default: break; } @@ -246,19 +353,21 @@ int conf_read(const char *name) 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) - sym->flags |= e->right.sym->flags & SYMBOL_NEW; + flags &= e->right.sym->flags; + sym->flags &= flags | ~SYMBOL_DEF_USER; } - sym_change_count = 1; + sym_add_change_count(conf_warnings || conf_unsaved); return 0; } int conf_write(const char *name) { - FILE *out, *out_h; + FILE *out; struct symbol *sym; struct menu *menu; const char *basename; @@ -277,7 +386,7 @@ int conf_write(const char *name) if (!stat(name, &st) && S_ISDIR(st.st_mode)) { strcpy(dirname, name); strcat(dirname, "/"); - basename = conf_def_filename; + basename = conf_get_configname(); } else if ((slash = strrchr(name, '/'))) { int size = slash - name + 1; memcpy(dirname, name, size); @@ -285,22 +394,26 @@ int conf_write(const char *name) if (slash[1]) basename = slash + 1; else - basename = conf_def_filename; + basename = conf_get_configname(); } else basename = name; } else - basename = conf_def_filename; + basename = conf_get_configname(); - sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(newname, "w"); + sprintf(newname, "%s%s", dirname, basename); + env = getenv("KCONFIG_OVERWRITECONFIG"); + if (!env || !*env) { + sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); + out = fopen(tmpname, "w"); + } else { + *tmpname = 0; + out = fopen(newname, "w"); + } if (!out) return 1; - out_h = NULL; - if (!name) { - out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) - return 1; - } + + sym = sym_lookup("VERSION", 0); + sym_calc_value(sym); time(&now); env = getenv("KCONFIG_NOTIMESTAMP"); if (env && *env) @@ -312,27 +425,8 @@ int conf_write(const char *name) "#\n"), use_timestamp ? "# " : "", use_timestamp ? ctime(&now) : ""); - if (out_h) - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - "%s%s" - " */\n" - "#if !defined __FEATURES_H && !defined __need_uClibc_config_h\n" - "#error Never include directly; use instead\n" - "#endif\n\n" - "/*\n" - " * Version Number\n" - " */\n" - "#define __UCLIBC_MAJOR__ %s\n" - "#define __UCLIBC_MINOR__ %s\n" - "#define __UCLIBC_SUBLEVEL__ %s\n", - use_timestamp ? " * " : "", - use_timestamp ? ctime(&now) : "", - getenv("MAJOR_VERSION"), - getenv("MINOR_VERSION"), - getenv("SUBLEVEL")); - - if (!sym_change_count) + + if (!conf_get_changed()) sym_clear_all_valid(); menu = rootmenu.list; @@ -346,11 +440,6 @@ int conf_write(const char *name) "#\n" "# %s\n" "#\n", str); - if (out_h) - fprintf(out_h, "\n" - "/*\n" - " * %s\n" - " */\n", str); } else if (!(sym->flags & SYMBOL_CHOICE)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) @@ -368,59 +457,39 @@ int conf_write(const char *name) switch (sym_get_tristate_value(sym)) { case no: fprintf(out, "# %s is not set\n", sym->name); - if (out_h) - fprintf(out_h, "#undef __%s__\n", sym->name); break; case mod: fprintf(out, "%s=m\n", sym->name); - if (out_h) - fprintf(out_h, "#define %s_MODULE 1\n", sym->name); break; case yes: fprintf(out, "%s=y\n", sym->name); - if (out_h) - fprintf(out_h, "#define __%s__ 1\n", sym->name); break; } break; case S_STRING: - // fix me str = sym_get_string_value(sym); fprintf(out, "%s=\"", sym->name); - if (out_h) - fprintf(out_h, "#define __%s__ \"", sym->name); - do { + while (1) { l = strcspn(str, "\"\\"); if (l) { fwrite(str, l, 1, out); - if (out_h) - fwrite(str, l, 1, out_h); - } - str += l; - while (*str == '\\' || *str == '"') { - fprintf(out, "\\%c", *str); - if (out_h) - fprintf(out_h, "\\%c", *str); - str++; + str += l; } - } while (*str); + if (!*str) + break; + fprintf(out, "\\%c", *str++); + } fputs("\"\n", out); - if (out_h) - fputs("\"\n", out_h); break; case S_HEX: str = sym_get_string_value(sym); if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { fprintf(out, "%s=%s\n", sym->name, str); - if (out_h) - fprintf(out_h, "#define __%s__ 0x%s\n", sym->name, str); break; } case S_INT: str = sym_get_string_value(sym); fprintf(out, "%s=%s\n", sym->name, str); - if (out_h) - fprintf(out_h, "#define __%s__ %s\n", sym->name, str); break; } } @@ -440,22 +509,279 @@ int conf_write(const char *name) } } fclose(out); - if (out_h) { - fclose(out_h); - rename(".tmpconfig.h", "include/bits/uClibc_config.h"); - file_write_dep(NULL); + + if (*tmpname) { + strcat(dirname, basename); + strcat(dirname, ".old"); + rename(newname, dirname); + if (rename(tmpname, newname)) + return 1; } - if (!name || basename != conf_def_filename) { - if (!name) - name = conf_def_filename; - sprintf(tmpname, "%s.old", name); - rename(name, tmpname); + + printf(_("#\n" + "# configuration written to %s\n" + "#\n"), newname); + + sym_set_change_count(0); + + return 0; +} + +int conf_split_config(void) +{ + char *name, path[128]; + char *s, *d, c; + struct symbol *sym; + struct stat sb; + int res, i, fd; + + name = getenv("KCONFIG_AUTOCONFIG"); + if (!name) + name = "include/config/auto.conf"; + conf_read_simple(name, S_DEF_AUTO); + + if (chdir("include/config")) + return 1; + + res = 0; + for_all_symbols(i, sym) { + sym_calc_value(sym); + if ((sym->flags & SYMBOL_AUTO) || !sym->name) + continue; + if (sym->flags & SYMBOL_WRITE) { + if (sym->flags & SYMBOL_DEF_AUTO) { + /* + * symbol has old and new value, + * so compare them... + */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_get_tristate_value(sym) == + sym->def[S_DEF_AUTO].tri) + continue; + break; + case S_STRING: + case S_HEX: + case S_INT: + if (!strcmp(sym_get_string_value(sym), + sym->def[S_DEF_AUTO].val)) + continue; + break; + default: + break; + } + } else { + /* + * If there is no old value, only 'no' (unset) + * is allowed as new value. + */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_get_tristate_value(sym) == no) + continue; + break; + default: + break; + } + } + } else if (!(sym->flags & SYMBOL_DEF_AUTO)) + /* There is neither an old nor a new value. */ + continue; + /* else + * There is an old value, but no new value ('no' (unset) + * isn't saved in auto.conf, so the old value is always + * different from 'no'). + */ + + /* Replace all '_' and append ".h" */ + s = sym->name; + d = path; + while ((c = *s++)) { + c = tolower(c); + *d++ = (c == '_') ? '/' : c; + } + strcpy(d, ".h"); + + /* Assume directory path already exists. */ + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + if (errno != ENOENT) { + res = 1; + break; + } + /* + * Create directory components, + * unless they exist already. + */ + d = path; + while ((d = strchr(d, '/'))) { + *d = 0; + if (stat(path, &sb) && mkdir(path, 0755)) { + res = 1; + goto out; + } + *d++ = '/'; + } + /* Try it again. */ + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + res = 1; + break; + } + } + close(fd); } - sprintf(tmpname, "%s%s", dirname, basename); - if (rename(newname, tmpname)) +out: + if (chdir("../..")) + return 1; + + return res; +} + +int conf_write_autoconf(void) +{ + struct symbol *sym; + const char *str; + char *name; + FILE *out, *out_h; + time_t now; + int i, l; + + return system("./extra/config/conf-header.sh .config > include/bits/uClibc_config.h"); + + sym_clear_all_valid(); + + file_write_dep("include/config/auto.conf.cmd"); + + if (conf_split_config()) + return 1; + + out = fopen(".tmpconfig", "w"); + if (!out) return 1; - sym_change_count = 0; + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) { + fclose(out); + return 1; + } + + sym = sym_lookup("VERSION", 0); + sym_calc_value(sym); + time(&now); + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" + "# %s" + "#\n", + ctime(&now)); + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " * %s" + " */\n", + ctime(&now)); + + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE) || !sym->name) + continue; + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + break; + case mod: + fprintf(out, "%s=m\n", sym->name); + fprintf(out_h, "#define %s_MODULE 1\n", sym->name); + break; + case yes: + fprintf(out, "%s=y\n", sym->name); + fprintf(out_h, "#define %s 1\n", sym->name); + break; + } + break; + case S_STRING: + str = sym_get_string_value(sym); + fprintf(out, "%s=\"", sym->name); + fprintf(out_h, "#define %s \"", sym->name); + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + fwrite(str, l, 1, out_h); + str += l; + } + if (!*str) + break; + fprintf(out, "\\%c", *str); + fprintf(out_h, "\\%c", *str); + str++; + } + fputs("\"\n", out); + fputs("\"\n", out_h); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "%s=%s\n", sym->name, str); + fprintf(out_h, "#define %s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "%s=%s\n", sym->name, str); + fprintf(out_h, "#define %s %s\n", sym->name, str); + break; + default: + break; + } + } + fclose(out); + fclose(out_h); + + name = getenv("KCONFIG_AUTOHEADER"); + if (!name) + name = "include/linux/autoconf.h"; + if (rename(".tmpconfig.h", name)) + return 1; + name = getenv("KCONFIG_AUTOCONFIG"); + if (!name) + name = "include/config/auto.conf"; + /* + * This must be the last step, kbuild has a dependency on auto.conf + * and this marks the successful completion of the previous steps. + */ + if (rename(".tmpconfig", name)) + return 1; return 0; } + +static int sym_change_count; +static void (*conf_changed_callback)(void); + +void sym_set_change_count(int count) +{ + int _sym_change_count = sym_change_count; + sym_change_count = count; + if (conf_changed_callback && + (bool)_sym_change_count != (bool)count) + conf_changed_callback(); +} + +void sym_add_change_count(int count) +{ + sym_set_change_count(count + sym_change_count); +} + +bool conf_get_changed(void) +{ + return sym_change_count; +} + +void conf_set_changed_callback(void (*fn)(void)) +{ + conf_changed_callback = fn; +} diff --git a/extra/config/expr.c b/extra/config/expr.c index 30e4f9d69..6f98dbfe7 100644 --- a/extra/config/expr.c +++ b/extra/config/expr.c @@ -145,7 +145,8 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e return; } if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && - e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) + e1->left.sym == e2->left.sym && + (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) return; if (!expr_eq(e1, e2)) return; @@ -1012,73 +1013,73 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) #endif } -void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) +void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) { if (!e) { - fn(data, "y"); + fn(data, NULL, "y"); return; } if (expr_compare_type(prevtoken, e->type) > 0) - fn(data, "("); + fn(data, NULL, "("); switch (e->type) { case E_SYMBOL: if (e->left.sym->name) - fn(data, e->left.sym->name); + fn(data, e->left.sym, e->left.sym->name); else - fn(data, ""); + fn(data, NULL, ""); break; case E_NOT: - fn(data, "!"); + fn(data, NULL, "!"); expr_print(e->left.expr, fn, data, E_NOT); break; case E_EQUAL: - fn(data, e->left.sym->name); - fn(data, "="); - fn(data, e->right.sym->name); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, "="); + fn(data, e->right.sym, e->right.sym->name); break; case E_UNEQUAL: - fn(data, e->left.sym->name); - fn(data, "!="); - fn(data, e->right.sym->name); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, "!="); + fn(data, e->right.sym, e->right.sym->name); break; case E_OR: expr_print(e->left.expr, fn, data, E_OR); - fn(data, " || "); + fn(data, NULL, " || "); expr_print(e->right.expr, fn, data, E_OR); break; case E_AND: expr_print(e->left.expr, fn, data, E_AND); - fn(data, " && "); + fn(data, NULL, " && "); expr_print(e->right.expr, fn, data, E_AND); break; case E_CHOICE: - fn(data, e->right.sym->name); + fn(data, e->right.sym, e->right.sym->name); if (e->left.expr) { - fn(data, " ^ "); + fn(data, NULL, " ^ "); expr_print(e->left.expr, fn, data, E_CHOICE); } break; case E_RANGE: - fn(data, "["); - fn(data, e->left.sym->name); - fn(data, " "); - fn(data, e->right.sym->name); - fn(data, "]"); + fn(data, NULL, "["); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, " "); + fn(data, e->right.sym, e->right.sym->name); + fn(data, NULL, "]"); break; default: { char buf[32]; sprintf(buf, "", e->type); - fn(data, buf); + fn(data, NULL, buf); break; } } if (expr_compare_type(prevtoken, e->type) > 0) - fn(data, ")"); + fn(data, NULL, ")"); } -static void expr_print_file_helper(void *data, const char *str) +static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) { fwrite(str, strlen(str), 1, data); } @@ -1088,7 +1089,7 @@ void expr_fprint(struct expr *e, FILE *out) expr_print(e, expr_print_file_helper, out, E_NONE); } -static void expr_print_gstr_helper(void *data, const char *str) +static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) { str_append((struct gstr*)data, str); } diff --git a/extra/config/expr.h b/extra/config/expr.h index 7d39ff43e..6084525f6 100644 --- a/extra/config/expr.h +++ b/extra/config/expr.h @@ -63,12 +63,18 @@ enum symbol_type { S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER }; +enum { + S_DEF_USER, /* main user value */ + S_DEF_AUTO, +}; + struct symbol { struct symbol *next; char *name; char *help; enum symbol_type type; - struct symbol_value curr, user; + struct symbol_value curr; + struct symbol_value def[4]; tristate visible; int flags; struct property *prop; @@ -78,10 +84,7 @@ struct symbol { #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) -#define SYMBOL_YES 0x0001 -#define SYMBOL_MOD 0x0002 -#define SYMBOL_NO 0x0004 -#define SYMBOL_CONST 0x0007 +#define SYMBOL_CONST 0x0001 #define SYMBOL_CHECK 0x0008 #define SYMBOL_CHOICE 0x0010 #define SYMBOL_CHOICEVAL 0x0020 @@ -90,11 +93,14 @@ struct symbol { #define SYMBOL_OPTIONAL 0x0100 #define SYMBOL_WRITE 0x0200 #define SYMBOL_CHANGED 0x0400 -#define SYMBOL_NEW 0x0800 #define SYMBOL_AUTO 0x1000 #define SYMBOL_CHECKED 0x2000 -#define SYMBOL_CHECK_DONE 0x4000 #define SYMBOL_WARNED 0x8000 +#define SYMBOL_DEF 0x10000 +#define SYMBOL_DEF_USER 0x10000 +#define SYMBOL_DEF_AUTO 0x20000 +#define SYMBOL_DEF3 0x40000 +#define SYMBOL_DEF4 0x80000 #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 257 @@ -150,6 +156,7 @@ struct file *lookup_file(const char *name); extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol *modules_sym; +extern struct symbol *sym_defconfig_list; extern int cdebug; struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); diff --git a/extra/config/gconf.c b/extra/config/gconf.c new file mode 100644 index 000000000..abefae26b --- /dev/null +++ b/extra/config/gconf.c @@ -0,0 +1,1636 @@ +/* Hey EMACS -*- linux-c -*- */ +/* + * + * Copyright (C) 2002-2003 Romain Lievin + * Released under the terms of the GNU GPL v2.0. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "lkc.h" +#include "images.c" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//#define DEBUG + +enum { + SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW +}; + +static gint view_mode = FULL_VIEW; +static gboolean show_name = TRUE; +static gboolean show_range = TRUE; +static gboolean show_value = TRUE; +static gboolean show_all = FALSE; +static gboolean show_debug = FALSE; +static gboolean resizeable = FALSE; + +static char nohelp_text[] = + N_("Sorry, no help available for this option yet.\n"); + +GtkWidget *main_wnd = NULL; +GtkWidget *tree1_w = NULL; // left frame +GtkWidget *tree2_w = NULL; // right frame +GtkWidget *text_w = NULL; +GtkWidget *hpaned = NULL; +GtkWidget *vpaned = NULL; +GtkWidget *back_btn = NULL; +GtkWidget *save_btn = NULL; +GtkWidget *save_menu_item = NULL; + +GtkTextTag *tag1, *tag2; +GdkColor color; + +GtkTreeStore *tree1, *tree2, *tree; +GtkTreeModel *model1, *model2; +static GtkTreeIter *parents[256]; +static gint indent; + +static struct menu *current; // current node for SINGLE view +static struct menu *browsed; // browsed node for SPLIT view + +enum { + COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE, + COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF, + COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD, + COL_NUMBER +}; + +static void display_list(void); +static void display_tree(struct menu *menu); +static void display_tree_part(void); +static void update_tree(struct menu *src, GtkTreeIter * dst); +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); +static gchar **fill_row(struct menu *menu); +static void conf_changed(void); + +/* Helping/Debugging Functions */ + + +const char *dbg_print_stype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == S_UNKNOWN) + strcpy(buf, "unknown"); + if (val == S_BOOLEAN) + strcpy(buf, "boolean"); + if (val == S_TRISTATE) + strcpy(buf, "tristate"); + if (val == S_INT) + strcpy(buf, "int"); + if (val == S_HEX) + strcpy(buf, "hex"); + if (val == S_STRING) + strcpy(buf, "string"); + if (val == S_OTHER) + strcpy(buf, "other"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_flags(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val & SYMBOL_CONST) + strcat(buf, "const/"); + if (val & SYMBOL_CHECK) + strcat(buf, "check/"); + if (val & SYMBOL_CHOICE) + strcat(buf, "choice/"); + if (val & SYMBOL_CHOICEVAL) + strcat(buf, "choiceval/"); + if (val & SYMBOL_PRINTED) + strcat(buf, "printed/"); + if (val & SYMBOL_VALID) + strcat(buf, "valid/"); + if (val & SYMBOL_OPTIONAL) + strcat(buf, "optional/"); + if (val & SYMBOL_WRITE) + strcat(buf, "write/"); + if (val & SYMBOL_CHANGED) + strcat(buf, "changed/"); + if (val & SYMBOL_AUTO) + strcat(buf, "auto/"); + + buf[strlen(buf) - 1] = '\0'; +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_ptype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == P_UNKNOWN) + strcpy(buf, "unknown"); + if (val == P_PROMPT) + strcpy(buf, "prompt"); + if (val == P_COMMENT) + strcpy(buf, "comment"); + if (val == P_MENU) + strcpy(buf, "menu"); + if (val == P_DEFAULT) + strcpy(buf, "default"); + if (val == P_CHOICE) + strcpy(buf, "choice"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + + +void replace_button_icon(GladeXML * xml, GdkDrawable * window, + GtkStyle * style, gchar * btn_name, gchar ** xpm) +{ + GdkPixmap *pixmap; + GdkBitmap *mask; + GtkToolButton *button; + GtkWidget *image; + + pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, + &style->bg[GTK_STATE_NORMAL], + xpm); + + button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name)); + image = gtk_image_new_from_pixmap(pixmap, mask); + gtk_widget_show(image); + gtk_tool_button_set_icon_widget(button, image); +} + +/* Main Window Initialization */ +void init_main_window(const gchar * glade_file) +{ + GladeXML *xml; + GtkWidget *widget; + GtkTextBuffer *txtbuf; + char title[256]; + GtkStyle *style; + + xml = glade_xml_new(glade_file, "window1", NULL); + if (!xml) + g_error(_("GUI loading failed !\n")); + glade_xml_signal_autoconnect(xml); + + main_wnd = glade_xml_get_widget(xml, "window1"); + hpaned = glade_xml_get_widget(xml, "hpaned1"); + vpaned = glade_xml_get_widget(xml, "vpaned1"); + tree1_w = glade_xml_get_widget(xml, "treeview1"); + tree2_w = glade_xml_get_widget(xml, "treeview2"); + text_w = glade_xml_get_widget(xml, "textview3"); + + back_btn = glade_xml_get_widget(xml, "button1"); + gtk_widget_set_sensitive(back_btn, FALSE); + + widget = glade_xml_get_widget(xml, "show_name1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_name); + + widget = glade_xml_get_widget(xml, "show_range1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_range); + + widget = glade_xml_get_widget(xml, "show_data1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_value); + + save_btn = glade_xml_get_widget(xml, "button3"); + save_menu_item = glade_xml_get_widget(xml, "save1"); + conf_set_changed_callback(conf_changed); + + s