- pull kconfig from linux-2.6.21.5

This commit is contained in:
Bernhard Reutner-Fischer 2007-06-28 10:46:19 +00:00
parent e89cffadee
commit a665ed3496
36 changed files with 10292 additions and 4822 deletions

View File

@ -1,134 +1,38 @@
# Makefile for buildroot2 obj := .
# src := .
# Copyright (C) 2002-2005 Erik Andersen <andersen@codepoet.org> top_srcdir=../../
# top_builddir=../../
# This program is free software; you can redistribute it and/or modify it under srctree := .
# the terms of the GNU Library General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
# details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Select the compiler needed to build binaries for your development system include Makefile.kconfig
HOSTCC = gcc
HOSTCFLAGS= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc.
LC_ALL:= C
all: ncurses conf mconf -include .depend
.depend: $(wildcard *.h *.c)
$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) -MM *.c > .depend 2>/dev/null || :
ifeq ($(shell uname),SunOS) __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
LIBS = -lcurses host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
else host-cmulti := $(foreach m,$(__hostprogs),\
LIBS = -lncurses $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
endif host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
else
ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
else
ifeq (/usr/local/include/ncurses/ncurses.h, $(wildcard /usr/local/include/ncurses/ncurses.h))
HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="<ncurses.h>"
else
ifeq (/usr/local/include/ncurses/curses.h, $(wildcard /usr/local/include/ncurses/curses.h))
HOSTCFLAGS += -I/usr/local/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
else
ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
HOSTNCURSES += -DCURSES_LOC="<ncurses.h>"
else
HOSTNCURSES += -DCURSES_LOC="<curses.h>"
endif
endif
endif
endif
endif
CONF_SRC = conf.c $(host-csingle): %: %.c
MCONF_SRC = mconf.c $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(HOST_LOADLIBES) $< -o $@
LXD_SRC = lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \
lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \
lxdialog/msgbox.c
SHARED_SRC = zconf.tab.c
SHARED_DEPS := lkc.h lkc_proto.h lkc_defs.h expr.h zconf.tab.h
CONF_OBJS = $(patsubst %.c,%.o, $(CONF_SRC))
MCONF_OBJS = $(patsubst %.c,%.o, $(MCONF_SRC) $(LXD_SRC))
SHARED_OBJS = $(patsubst %.c,%.o, $(SHARED_SRC))
conf: $(CONF_OBJS) $(SHARED_OBJS) $(host-cmulti): %: $(host-cobjs) $(host-cshlib)
$(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(HOST_LOADLIBES) $($@-objs) -o $@
mconf: $(MCONF_OBJS) $(SHARED_OBJS) $(host-cobjs): %.o: %.c
$(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ $(LIBS) $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) -c $< -o $@
$(CONF_OBJS): %.o : %.c $(SHARED_DEPS) $(obj)/%:: $(src)/%_shipped
$(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@ $(Q)cat $< > $@
$(MCONF_OBJS): %.o : %.c $(SHARED_DEPS)
$(HOSTCC) $(HOSTCFLAGS) $(HOSTNCURSES) -I. -c $< -o $@
lkc_defs.h: 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
lex.zconf.o: lex.zconf.c $(SHARED_DEPS)
$(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
lex.zconf.c: lex.zconf.c_shipped
cp lex.zconf.c_shipped lex.zconf.c
zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS)
$(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
zconf.tab.c: zconf.tab.c_shipped
cp zconf.tab.c_shipped zconf.tab.c
zconf.tab.h: zconf.tab.h_shipped
cp zconf.tab.h_shipped zconf.tab.h
endif
.PHONY: ncurses
ncurses:
@echo "main() {}" > lxtemp.c
@if $(HOSTCC) lxtemp.c $(LIBS) ; then \
$(RM) lxtemp.c a.out; \
else \
$(RM) lxtemp.c; \
/bin/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
clean: clean:
$(RM) *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) \ $(Q)rm -f $(clean-files)
conf mconf zconf.tab.c zconf.tab.h lex.zconf.c lkc_defs.h 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

View File

@ -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 <libintl.h>" | $(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

View File

@ -0,0 +1,5 @@
scripts/kconfig/mconf.c
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kconfig/gconf.c
scripts/kconfig/qconf.cc

View File

@ -0,0 +1,18 @@
This is a copy of the kconfig code in the kernel tweaked to suit Buildroot.
To update:
cp -r /usr/src/linux/scripts/kconfig package/config.new
cd package/config.new
cp /usr/src/linux/Documentation/kbuild/kconfig-language.txt .
mv Makefile Makefile.kconfig
patch -p1 < ../config/kconfig-to-buildroot.patch
cp ../config/README.buildroot2 .
cd ..
rm -rf config
mv config.new config
Then verify the toplevel targets work:
config
defconfig
menuconfig
oldconfig

View File

@ -5,6 +5,7 @@
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
@ -31,14 +32,14 @@ char *defconfig_file;
static int indent = 1; static int indent = 1;
static int valid_stdin = 1; static int valid_stdin = 1;
static int conf_cnt; static int conf_cnt;
static signed char line[128]; static char line[128];
static struct menu *rootEntry; static struct menu *rootEntry;
static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
static void strip(signed char *str) static void strip(char *str)
{ {
signed char *p = str; char *p = str;
int l; int l;
while ((isspace(*p))) while ((isspace(*p)))
@ -56,9 +57,9 @@ static void strip(signed char *str)
static void check_stdin(void) static void check_stdin(void)
{ {
if (!valid_stdin && input_mode == ask_silent) { if (!valid_stdin && input_mode == ask_silent) {
printf("aborted!\n\n"); printf(_("aborted!\n\n"));
printf("Console input/output is redirected. "); printf(_("Console input/output is redirected. "));
printf("Run 'make oldconfig' to update configuration.\n\n"); printf(_("Run 'make oldconfig' to update configuration.\n\n"));
exit(1); exit(1);
} }
} }
@ -82,6 +83,15 @@ static void conf_askvalue(struct symbol *sym, const char *def)
} }
switch (input_mode) { 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_new:
case ask_silent: case ask_silent:
if (sym_has_value(sym)) { 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)); 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;
line[1] = 0;
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;
@ -467,15 +476,14 @@ static void check_conf(struct menu *menu)
return; return;
sym = menu->sym; sym = menu->sym;
if (sym) { if (sym && !sym_has_value(sym)) {
if (sym_is_changable(sym) && !sym_has_value(sym)) { if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (!conf_cnt++) if (!conf_cnt++)
printf("*\n* Restart config...\n*\n"); printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu); rootEntry = menu_get_parent_menu(menu);
conf(rootEntry); conf(rootEntry);
} }
if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
return;
} }
for (child = menu->list; child; child = child->next) for (child = menu->list; child; child = child->next)
@ -504,7 +512,7 @@ int main(int ac, char **av)
input_mode = set_default; input_mode = set_default;
defconfig_file = av[i++]; defconfig_file = av[i++];
if (!defconfig_file) { if (!defconfig_file) {
printf("%s: No default config file specified\n", printf(_("%s: No default config file specified\n"),
av[0]); av[0]);
exit(1); exit(1);
} }
@ -524,13 +532,14 @@ int main(int ac, char **av)
break; break;
case 'h': case 'h':
case '?': case '?':
printf("%s [-o|-s] config\n", av[0]); fprintf(stderr, "See README for usage info\n");
exit(0); exit(0);
} }
} }
name = av[i]; name = av[i];
if (!name) { if (!name) {
printf("%s: configuration file missing\n", av[0]); printf(_("%s: Kconfig file missing\n"), av[0]);
exit(1);
} }
conf_parse(name); conf_parse(name);
//zconfdump(stdout); //zconfdump(stdout);
@ -547,18 +556,39 @@ int main(int ac, char **av)
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 Buildroot!\n" "*** You have not yet configured Buildroot!\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 config\").\n"
"***\n"); "***\n"));
exit(1); exit(1);
} }
case ask_all: case ask_all:
case ask_new: case ask_new:
conf_read(NULL); conf_read(NULL);
break; 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: default:
break; break;
} }
@ -570,14 +600,28 @@ int main(int ac, char **av)
input_mode = ask_silent; input_mode = ask_silent;
valid_stdin = 1; valid_stdin = 1;
} }
} } else if (conf_get_changed()) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
fprintf(stderr, _("\n*** Buildroot configuration requires explicit update.\n\n"));
return 1;
}
} else
goto skip_check;
do { do {
conf_cnt = 0; conf_cnt = 0;
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 Buildroot configuration.\n\n"); fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n"));
return 1; return 1;
} }
skip_check:
if (/*input_mode == ask_silent &&*/ conf_write_autoconf()) {
fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n"));
return 1;
}
return 0; return 0;
} }

View File

@ -5,28 +5,46 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#define LKC_DIRECT_LINK #define LKC_DIRECT_LINK
#include "lkc.h" #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[] = ".defconfig"; static const char *conf_filename;
static int conf_lineno, conf_warnings, conf_unsaved;
const char *conf_confnames[] = { const char conf_defname[] = "extra/Configs/defconfigs/$ARCH";
".config",
conf_defname,
NULL,
};
static char *conf_expand_value(const signed char *in) 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)
{ {
struct symbol *sym; struct symbol *sym;
const signed char *src; const char *src;
static char res_value[SYMBOL_MAXLENGTH]; static char res_value[SYMBOL_MAXLENGTH];
char *dst, name[SYMBOL_MAXLENGTH]; char *dst, name[SYMBOL_MAXLENGTH];
@ -65,53 +83,70 @@ char *conf_get_default_confname(void)
return name; return name;
} }
int conf_read(const char *name) int conf_read_simple(const char *name, int def)
{ {
FILE *in = NULL; FILE *in = NULL;
char line[1024]; char line[1024];
char *p, *p2; char *p, *p2;
int lineno = 0;
struct symbol *sym; struct symbol *sym;
struct property *prop; int i, def_flags;
struct expr *e;
int i;
if (name) { if (name) {
in = zconf_fopen(name); in = zconf_fopen(name);
} else { } else {
const char **names = conf_confnames; struct property *prop;
while ((name = *names++)) {
name = conf_expand_value(name); 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); in = zconf_fopen(name);
if (in) { if (in) {
printf("#\n" printf(_("#\n"
"# using defaults found in %s\n" "# using defaults found in %s\n"
"#\n", name); "#\n"), name);
break; goto load;
} }
} }
} }
if (!in) if (!in)
return 1; 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) { for_all_symbols(i, sym) {
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~SYMBOL_VALID; sym->flags &= ~(def_flags|SYMBOL_VALID);
if (sym_is_choice(sym))
sym->flags |= def_flags;
switch (sym->type) { switch (sym->type) {
case S_INT: case S_INT:
case S_HEX: case S_HEX:
case S_STRING: case S_STRING:
if (sym->user.val) if (sym->def[def].val)
free(sym->user.val); free(sym->def[def].val);
default: default:
sym->user.val = NULL; sym->def[def].val = NULL;
sym->user.tri = no; sym->def[def].tri = no;
} }
} }
while (fgets(line, sizeof(line), in)) { while (fgets(line, sizeof(line), in)) {
lineno++; conf_lineno++;
sym = NULL; sym = NULL;
switch (line[0]) { switch (line[0]) {
case '#': case '#':
@ -123,54 +158,84 @@ int conf_read(const char *name)
*p++ = 0; *p++ = 0;
if (strncmp(p, "is not set", 10)) if (strncmp(p, "is not set", 10))
continue; continue;
sym = sym_find(line + 2); if (def == S_DEF_USER) {
if (!sym) { sym = sym_find(line + 2);
fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, 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; break;
} }
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
sym->user.tri = no; sym->def[def].tri = no;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
default: default:
; ;
} }
break; break;
case 'A' ... 'Z': case 'A' ... 'Z':
p = strchr(line, '='); p = strchr(line, '=');
if (!p) if (!p)
continue; continue;
*p++ = 0; *p++ = 0;
p2 = strchr(p, '\n'); p2 = strchr(p, '\n');
if (p2) if (p2) {
*p2 = 0; *p2-- = 0;
sym = sym_find(line); if (*p2 == '\r')
if (!sym) { *p2 = 0;
fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line); }
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; break;
} }
switch (sym->type) { switch (sym->type) {
case S_TRISTATE: case S_TRISTATE:
if (p[0] == 'm') { if (p[0] == 'm') {
sym->user.tri = mod; sym->def[def].tri = mod;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
case S_BOOLEAN: case S_BOOLEAN:
if (p[0] == 'y') { if (p[0] == 'y') {
sym->user.tri = yes; sym->def[def].tri = yes;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
if (p[0] == 'n') { if (p[0] == 'n') {
sym->user.tri = no; sym->def[def].tri = no;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
break; break;
case S_OTHER:
if (*p != '"') {
for (p2 = p; *p2 && !isspace(*p2); p2++)
;
sym->type = S_STRING;
goto done;
}
case S_STRING: case S_STRING:
if (*p++ != '"') if (*p++ != '"')
break; break;
@ -182,62 +247,105 @@ int conf_read(const char *name)
memmove(p2, p2 + 1, strlen(p2)); memmove(p2, p2 + 1, strlen(p2));
} }
if (!p2) { if (!p2) {
fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); conf_warning("invalid string found");
exit(1); continue;
} }
case S_INT: case S_INT:
case S_HEX: case S_HEX:
done:
if (sym_string_valid(sym, p)) { if (sym_string_valid(sym, p)) {
sym->user.val = strdup(p); sym->def[def].val = strdup(p);
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
} else { } else {
fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); conf_warning("symbol value '%s' invalid for %s", p, sym->name);
exit(1); continue;
} }
break; break;
default: default:
; ;
} }
break; break;
case '\r':
case '\n': case '\n':
break; break;
default: default:
conf_warning("unexpected data");
continue; continue;
} }
if (sym && sym_is_choice_value(sym)) { if (sym && sym_is_choice_value(sym)) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
switch (sym->user.tri) { switch (sym->def[def].tri) {
case no: case no:
break; break;
case mod: case mod:
if (cs->user.tri == yes) if (cs->def[def].tri == yes) {
/* warn? */; conf_warning("%s creates inconsistent choice state", sym->name);
cs->flags &= ~def_flags;
}
break; break;
case yes: case yes:
if (cs->user.tri != no) if (cs->def[def].tri != no) {
/* warn? */; conf_warning("%s creates inconsistent choice state", sym->name);
cs->user.val = sym; cs->flags &= ~def_flags;
} else
cs->def[def].val = sym;
break; break;
} }
cs->user.tri = E_OR(cs->user.tri, sym->user.tri); cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
cs->flags &= ~SYMBOL_NEW;
} }
} }
fclose(in); fclose(in);
if (modules_sym) if (modules_sym)
sym_calc_value(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) { for_all_symbols(i, sym) {
sym_calc_value(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_has_value(sym) && !sym_is_choice_value(sym)) {
if (sym->visible == no) if (sym->visible == no)
sym->flags |= SYMBOL_NEW; 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->user.val)) if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
sym->flags |= SYMBOL_NEW; sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
default: default:
break; break;
} }
@ -245,12 +353,14 @@ int conf_read(const char *name)
if (!sym_is_choice(sym)) if (!sym_is_choice(sym))
continue; continue;
prop = sym_get_choice_prop(sym); prop = sym_get_choice_prop(sym);
flags = sym->flags;
for (e = prop->expr; e; e = e->left.expr) for (e = prop->expr; e; e = e->left.expr)
if (e->right.sym->visible != no) 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; return 0;
} }
@ -264,6 +374,9 @@ int conf_write(const char *name)
char dirname[128], tmpname[128], newname[128]; char dirname[128], tmpname[128], newname[128];
int type, l; int type, l;
const char *str; const char *str;
time_t now;
int use_timestamp = 1;
char *env;
dirname[0] = 0; dirname[0] = 0;
if (name && name[0]) { if (name && name[0]) {
@ -273,7 +386,7 @@ int conf_write(const char *name)
if (!stat(name, &st) && S_ISDIR(st.st_mode)) { if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
strcpy(dirname, name); strcpy(dirname, name);
strcat(dirname, "/"); strcat(dirname, "/");
basename = conf_def_filename; basename = conf_get_configname();
} else if ((slash = strrchr(name, '/'))) { } else if ((slash = strrchr(name, '/'))) {
int size = slash - name + 1; int size = slash - name + 1;
memcpy(dirname, name, size); memcpy(dirname, name, size);
@ -281,21 +394,39 @@ int conf_write(const char *name)
if (slash[1]) if (slash[1])
basename = slash + 1; basename = slash + 1;
else else
basename = conf_def_filename; basename = conf_get_configname();
} else } else
basename = name; basename = name;
} else } else
basename = conf_def_filename; basename = conf_get_configname();
sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); sprintf(newname, "%s%s", dirname, basename);
out = fopen(newname, "w"); 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) if (!out)
return 1; return 1;
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
"#\n");
if (!sym_change_count) sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
time(&now);
env = getenv("KCONFIG_NOTIMESTAMP");
if (env && *env)
use_timestamp = 0;
fprintf(out, _("#\n"
"# Automatically generated make config: don't edit\n"
"%s%s"
"#\n"),
use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : "");
if (!conf_get_changed())
sym_clear_all_valid(); sym_clear_all_valid();
menu = rootmenu.list; menu = rootmenu.list;
@ -336,20 +467,18 @@ int conf_write(const char *name)
} }
break; break;
case S_STRING: case S_STRING:
// fix me
str = sym_get_string_value(sym); str = sym_get_string_value(sym);
fprintf(out, "%s=\"", sym->name); fprintf(out, "%s=\"", sym->name);
do { while (1) {
l = strcspn(str, "\"\\"); l = strcspn(str, "\"\\");
if (l) { if (l) {
fwrite(str, l, 1, out); fwrite(str, l, 1, out);
str += l;
} }
str += l; if (!*str)
while (*str == '\\' || *str == '"') { break;
fprintf(out, "\\%c", *str); fprintf(out, "\\%c", *str++);
str++; }
}
} while (*str);
fputs("\"\n", out); fputs("\"\n", out);
break; break;
case S_HEX: case S_HEX:
@ -380,18 +509,279 @@ int conf_write(const char *name)
} }
} }
fclose(out); fclose(out);
file_write_dep(NULL);
if (!name || basename != conf_def_filename) {
if (!name)
name = conf_def_filename;
sprintf(tmpname, "%s.old", name);
rename(name, tmpname);
}
sprintf(tmpname, "%s%s", dirname, basename);
if (rename(newname, tmpname))
return 1;
sym_change_count = 0; if (*tmpname) {
strcat(dirname, basename);
strcat(dirname, ".old");
rename(newname, dirname);
if (rename(tmpname, newname))
return 1;
}
printf(_("#\n"
"# configuration written to %s\n"
"#\n"), newname);
sym_set_change_count(0);
return 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);
}
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 0;
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;
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;
}

View File

@ -145,7 +145,8 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
return; return;
} }
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) e1->left.sym == e2->left.sym &&
(e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
return; return;
if (!expr_eq(e1, e2)) if (!expr_eq(e1, e2))
return; return;
@ -1012,73 +1013,73 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
#endif #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) { if (!e) {
fn(data, "y"); fn(data, NULL, "y");
return; return;
} }
if (expr_compare_type(prevtoken, e->type) > 0) if (expr_compare_type(prevtoken, e->type) > 0)
fn(data, "("); fn(data, NULL, "(");
switch (e->type) { switch (e->type) {
case E_SYMBOL: case E_SYMBOL:
if (e->left.sym->name) if (e->left.sym->name)
fn(data, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
else else
fn(data, "<choice>"); fn(data, NULL, "<choice>");
break; break;
case E_NOT: case E_NOT:
fn(data, "!"); fn(data, NULL, "!");
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->name); fn(data, e->left.sym, e->left.sym->name);
fn(data, "="); fn(data, NULL, "=");
fn(data, 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->name); fn(data, e->left.sym, e->left.sym->name);
fn(data, "!="); fn(data, NULL, "!=");
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
break; break;
case E_OR: case E_OR:
expr_print(e->left.expr, fn, data, 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); expr_print(e->right.expr, fn, data, E_OR);
break; break;
case E_AND: case E_AND:
expr_print(e->left.expr, fn, data, 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); expr_print(e->right.expr, fn, data, E_AND);
break; break;
case E_CHOICE: case E_CHOICE:
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
if (e->left.expr) { if (e->left.expr) {
fn(data, " ^ "); fn(data, NULL, " ^ ");
expr_print(e->left.expr, fn, data, E_CHOICE); expr_print(e->left.expr, fn, data, E_CHOICE);
} }
break; break;
case E_RANGE: case E_RANGE:
fn(data, "["); fn(data, NULL, "[");
fn(data, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
fn(data, " "); fn(data, NULL, " ");
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
fn(data, "]"); fn(data, NULL, "]");
break; break;
default: default:
{ {
char buf[32]; char buf[32];
sprintf(buf, "<unknown type %d>", e->type); sprintf(buf, "<unknown type %d>", e->type);
fn(data, buf); fn(data, NULL, buf);
break; break;
} }
} }
if (expr_compare_type(prevtoken, e->type) > 0) 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); 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); 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); str_append((struct gstr*)data, str);
} }

View File

@ -63,12 +63,18 @@ enum symbol_type {
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
}; };
enum {
S_DEF_USER, /* main user value */
S_DEF_AUTO,
};
struct symbol { struct symbol {
struct symbol *next; struct symbol *next;
char *name; char *name;
char *help; char *help;
enum symbol_type type; enum symbol_type type;
struct symbol_value curr, user; struct symbol_value curr;
struct symbol_value def[4];
tristate visible; tristate visible;
int flags; int flags;
struct property *prop; 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 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_CONST 0x0001
#define SYMBOL_MOD 0x0002
#define SYMBOL_NO 0x0004
#define SYMBOL_CONST 0x0007
#define SYMBOL_CHECK 0x0008 #define SYMBOL_CHECK 0x0008
#define SYMBOL_CHOICE 0x0010 #define SYMBOL_CHOICE 0x0010
#define SYMBOL_CHOICEVAL 0x0020 #define SYMBOL_CHOICEVAL 0x0020
@ -90,11 +93,14 @@ struct symbol {
#define SYMBOL_OPTIONAL 0x0100 #define SYMBOL_OPTIONAL 0x0100
#define SYMBOL_WRITE 0x0200 #define SYMBOL_WRITE 0x0200
#define SYMBOL_CHANGED 0x0400 #define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000 #define SYMBOL_AUTO 0x1000
#define SYMBOL_CHECKED 0x2000 #define SYMBOL_CHECKED 0x2000
#define SYMBOL_CHECK_DONE 0x4000
#define SYMBOL_WARNED 0x8000 #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_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257 #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 symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym; extern struct symbol *modules_sym;
extern struct symbol *sym_defconfig_list;
extern int cdebug; extern int cdebug;
struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_symbol(struct symbol *sym);
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);

1636
package/config/gconf.c Normal file

File diff suppressed because it is too large Load Diff

648
package/config/gconf.glade Normal file
View File

@ -0,0 +1,648 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
<property name="title" translatable="yes">Gtk Buildroot Configurator</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">640</property>
<property name="default_height">480</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<signal name="destroy" handler="on_window1_destroy" object="window1"/>
<signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/>
<signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="file1">
<property name="visible">True</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="file1_menu">
<child>
<widget class="GtkImageMenuItem" id="load1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Load a config file</property>
<property name="label" translatable="yes">_Load</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_load1_activate"/>
<accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image39">
<property name="visible">True</property>
<property name="stock">gtk-open</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Save the config in .config</property>
<property name="label" translatable="yes">_Save</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_save_activate"/>
<accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image40">
<property name="visible">True</property>
<property name="stock">gtk-save</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save_as1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Save the config in a file</property>
<property name="label" translatable="yes">Save _as</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_save_as1_activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image41">
<property name="visible">True</property>
<property name="stock">gtk-save-as</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="quit1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Quit</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_quit1_activate"/>
<accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image42">
<property name="visible">True</property>
<property name="stock">gtk-quit</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="options1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Options</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="options1_menu">
<child>
<widget class="GtkCheckMenuItem" id="show_name1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Show name</property>
<property name="label" translatable="yes">Show _name</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="on_show_name1_activate"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="show_range1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Show range (Y/M/N)</property>
<property name="label" translatable="yes">Show _range</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="on_show_range1_activate"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="show_data1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Show value of the option</property>
<property name="label" translatable="yes">Show _data</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="on_show_data1_activate"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator2">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="show_all_options1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Show all options</property>
<property name="label" translatable="yes">Show all _options</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="on_show_all_options1_activate"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="show_debug_info1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Show masked options</property>
<property name="label" translatable="yes">Show _debug info</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="on_show_debug_info1_activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="help1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="help1_menu">
<child>
<widget class="GtkImageMenuItem" id="introduction1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Introduction</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_introduction1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
<accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image43">
<property name="visible">True</property>
<property name="stock">gtk-dialog-question</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="about1">
<property name="visible">True</property>
<property name="label" translatable="yes">_About</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_about1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
<accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image44">
<property name="visible">True</property>
<property name="stock">gtk-properties</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="license1">
<property name="visible">True</property>
<property name="label" translatable="yes">_License</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image45">
<property name="visible">True</property>
<property name="stock">gtk-justify-fill</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHandleBox" id="handlebox1">
<property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_OUT</property>
<property name="handle_position">GTK_POS_LEFT</property>
<property name="snap_edge">GTK_POS_TOP</property>
<child>
<widget class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
<property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
<property name="tooltips">True</property>
<property name="show_arrow">True</property>
<child>
<widget class="GtkToolButton" id="button1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Goes up of one level (single view)</property>
<property name="label" translatable="yes">Back</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-undo</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_back_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolItem" id="toolitem1">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<child>
<widget class="GtkVSeparator" id="vseparator1">
<property name="visible">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button2">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Load a config file</property>
<property name="label" translatable="yes">Load</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-open</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_load_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button3">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Save a config file</property>
<property name="label" translatable="yes">Save</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-save</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_save_activate"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolItem" id="toolitem2">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<child>
<widget class="GtkVSeparator" id="vseparator2">
<property name="visible">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button4">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Single view</property>
<property name="label" translatable="yes">Single</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-missing-image</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button5">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Split view</property>
<property name="label" translatable="yes">Split</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-missing-image</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button6">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Full view</property>
<property name="label" translatable="yes">Full</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-missing-image</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolItem" id="toolitem3">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<child>
<widget class="GtkVSeparator" id="vseparator3">
<property name="visible">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button7">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property>
<property name="label" translatable="yes">Collapse</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-remove</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_collapse_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="button8">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property>
<property name="label" translatable="yes">Expand</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-add</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_expand_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHPaned" id="hpaned1">
<property name="width_request">1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
<signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
<signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="shrink">True</property>
<property name="resize">False</property>
</packing>
</child>
<child>
<widget class="GtkVPaned" id="vpaned1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="treeview2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
<signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
<signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="shrink">True</property>
<property name="resize">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow3">
<property name="visible">True</property>
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="textview3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_WORD</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes">Sorry, no help available for this option yet.</property>
</widget>
</child>
</widget>
<packing>
<property name="shrink">True</property>
<property name="resize">True</property>
</packing>
</child>
</widget>
<packing>
<property name="shrink">True</property>
<property name="resize">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

326
package/config/images.c Normal file
View File

@ -0,0 +1,326 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
static const char *xpm_load[] = {
"22 22 5 1",
". c None",
"# c #000000",
"c c #838100",
"a c #ffff00",
"b c #ffffff",
"......................",
"......................",
"......................",
"............####....#.",
"...........#....##.##.",
"..................###.",
".................####.",
".####...........#####.",
"#abab##########.......",
"#babababababab#.......",
"#ababababababa#.......",
"#babababababab#.......",
"#ababab###############",
"#babab##cccccccccccc##",
"#abab##cccccccccccc##.",
"#bab##cccccccccccc##..",
"#ab##cccccccccccc##...",
"#b##cccccccccccc##....",
"###cccccccccccc##.....",
"##cccccccccccc##......",
"###############.......",
"......................"};
static const char *xpm_save[] = {
"22 22 5 1",
". c None",
"# c #000000",
"a c #838100",
"b c #c5c2c5",
"c c #cdb6d5",
"......................",
".####################.",
".#aa#bbbbbbbbbbbb#bb#.",
".#aa#bbbbbbbbbbbb#bb#.",
".#aa#bbbbbbbbbcbb####.",
".#aa#bbbccbbbbbbb#aa#.",
".#aa#bbbccbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aa#bbbbbbbbbbbb#aa#.",
".#aaa############aaa#.",
".#aaaaaaaaaaaaaaaaaa#.",
".#aaaaaaaaaaaaaaaaaa#.",
".#aaa#############aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
".#aaa#########bbb#aa#.",
"..##################..",
"......................"};
static const char *xpm_back[] = {
"22 22 3 1",
". c None",
"# c #000083",
"a c #838183",
"......................",
"......................",
"......................",
"......................",
"......................",
"...........######a....",
"..#......##########...",
"..##...####......##a..",
"..###.###.........##..",
"..######..........##..",
"..#####...........##..",
"..######..........##..",
"..#######.........##..",
"..########.......##a..",
"...............a###...",
"...............###....",
"......................",
"......................",
"......................",
"......................",
"......................",
"......................"};
static const char *xpm_tree_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
"......................",
"......................",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......########........",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......########........",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......#...............",
"......########........",
"......................",
"......................"};
static const char *xpm_single_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
"......................",
"......................",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"..........#...........",
"......................",
"......................"};
static const char *xpm_split_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
"......................",
"......................",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......#......#........",
"......................",
"......................"};
static const char *xpm_symbol_no[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" .......... ",
" "};
static const char *xpm_symbol_mod[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . . ",
" . .. . ",
" . .... . ",
" . .... . ",
" . .. . ",
" . . ",
" . . ",
" .......... ",
" "};
static const char *xpm_symbol_yes[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . . ",
" . . . ",
" . .. . ",
" . . .. . ",
" . .... . ",
" . .. . ",
" . . ",
" .......... ",
" "};
static const char *xpm_choice_no[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .... ",
" .. .. ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" .. .. ",
" .... ",
" "};
static const char *xpm_choice_yes[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .... ",
" .. .. ",
" . . ",
" . .. . ",
" . .... . ",
" . .... . ",
" . .. . ",
" . . ",
" .. .. ",
" .... ",
" "};
static const char *xpm_menu[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . .. . ",
" . .... . ",
" . ...... . ",
" . ...... . ",
" . .... . ",
" . .. . ",
" . . ",
" .......... ",
" "};
static const char *xpm_menu_inv[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" .......... ",
" .. ...... ",
" .. .... ",
" .. .. ",
" .. .. ",
" .. .... ",
" .. ...... ",
" .......... ",
" .......... ",
" "};
static const char *xpm_menuback[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" .......... ",
" . . ",
" . .. . ",
" . .... . ",
" . ...... . ",
" . ...... . ",
" . .... . ",
" . .. . ",
" . . ",
" .......... ",
" "};
static const char *xpm_void[] = {
"12 12 2 1",
" c white",
". c black",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};

View File

@ -0,0 +1,453 @@
--- kconfig/conf.c
+++ Buildroot/conf.c
@@ -557,10 +557,10 @@
case ask_silent:
if (stat(".config", &tmpstat)) {
printf(_("***\n"
- "*** You have not yet configured your kernel!\n"
+ "*** You have not yet configured Buildroot!\n"
"***\n"
"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
- "*** \"make menuconfig\" or \"make xconfig\").\n"
+ "*** \"make menuconfig\" or \"make config\").\n"
"***\n"));
exit(1);
}
@@ -603,7 +603,7 @@
} else if (conf_get_changed()) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
- fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n"));
+ fprintf(stderr, _("\n*** Buildroot configuration requires explicit update.\n\n"));
return 1;
}
} else
@@ -614,12 +614,12 @@
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 Buildroot configuration.\n\n"));
return 1;
}
skip_check:
- if (input_mode == ask_silent && conf_write_autoconf()) {
- fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
+ if (/*input_mode == ask_silent &&*/ conf_write_autoconf()) {
+ fprintf(stderr, _("\n*** Error during writing of the Buildroot configuration.\n\n"));
return 1;
}
--- kconfig/confdata.c
+++ Buildroot/confdata.c
@@ -21,7 +21,7 @@
static const char *conf_filename;
static int conf_lineno, conf_warnings, conf_unsaved;
-const char conf_defname[] = "arch/$ARCH/defconfig";
+const char conf_defname[] = "extra/Configs/defconfigs/$ARCH";
static void conf_warning(const char *fmt, ...)
{
@@ -150,22 +150,22 @@
sym = NULL;
switch (line[0]) {
case '#':
- if (memcmp(line + 2, "CONFIG_", 7))
+ if (line[1]!=' ')
continue;
- p = strchr(line + 9, ' ');
+ p = strchr(line + 2, ' ');
if (!p)
continue;
*p++ = 0;
if (strncmp(p, "is not set", 10))
continue;
if (def == S_DEF_USER) {
- sym = sym_find(line + 9);
+ sym = sym_find(line + 2);
if (!sym) {
- conf_warning("trying to assign nonexistent symbol %s", line + 9);
+ conf_warning("trying to assign nonexistent symbol %s", line + 2);
break;
}
} else {
- sym = sym_lookup(line + 9, 0);
+ sym = sym_lookup(line + 2, 0);
if (sym->type == S_UNKNOWN)
sym->type = S_BOOLEAN;
}
@@ -183,12 +183,8 @@
;
}
break;
- case 'C':
- if (memcmp(line, "CONFIG_", 7)) {
- conf_warning("unexpected data");
- continue;
- }
- p = strchr(line + 7, '=');
+ case 'A' ... 'Z':
+ p = strchr(line, '=');
if (!p)
continue;
*p++ = 0;
@@ -199,13 +195,13 @@
*p2 = 0;
}
if (def == S_DEF_USER) {
- sym = sym_find(line + 7);
+ sym = sym_find(line);
if (!sym) {
- conf_warning("trying to assign nonexistent symbol %s", line + 7);
+ conf_warning("trying to assign nonexistent symbol %s", line);
break;
}
} else {
- sym = sym_lookup(line + 7, 0);
+ sym = sym_lookup(line, 0);
if (sym->type == S_UNKNOWN)
sym->type = S_OTHER;
}
@@ -416,7 +412,7 @@
if (!out)
return 1;
- sym = sym_lookup("KERNELVERSION", 0);
+ sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
time(&now);
env = getenv("KCONFIG_NOTIMESTAMP");
@@ -425,10 +421,8 @@
fprintf(out, _("#\n"
"# Automatically generated make config: don't edit\n"
- "# Linux kernel version: %s\n"
"%s%s"
"#\n"),
- sym_get_string_value(sym),
use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : "");
@@ -462,19 +456,19 @@
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
- fprintf(out, "# CONFIG_%s is not set\n", sym->name);
+ fprintf(out, "# %s is not set\n", sym->name);
break;
case mod:
- fprintf(out, "CONFIG_%s=m\n", sym->name);
+ fprintf(out, "%s=m\n", sym->name);
break;
case yes:
- fprintf(out, "CONFIG_%s=y\n", sym->name);
+ fprintf(out, "%s=y\n", sym->name);
break;
}
break;
case S_STRING:
str = sym_get_string_value(sym);
- fprintf(out, "CONFIG_%s=\"", sym->name);
+ fprintf(out, "%s=\"", sym->name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
@@ -490,12 +484,12 @@
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
- fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+ fprintf(out, "%s=%s\n", sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
- fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+ fprintf(out, "%s=%s\n", sym->name, str);
break;
}
}
@@ -655,6 +649,8 @@
time_t now;
int i, l;
+ return 0;
+
sym_clear_all_valid();
file_write_dep("include/config/auto.conf.cmd");
@@ -672,22 +668,19 @@
return 1;
}
- sym = sym_lookup("KERNELVERSION", 0);
+ sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
time(&now);
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
- "# Linux kernel version: %s\n"
"# %s"
"#\n",
- sym_get_string_value(sym), ctime(&now));
+ ctime(&now));
fprintf(out_h, "/*\n"
" * Automatically generated C config: don't edit\n"
- " * Linux kernel version: %s\n"
" * %s"
- " */\n"
- "#define AUTOCONF_INCLUDED\n",
- sym_get_string_value(sym), ctime(&now));
+ " */\n",
+ ctime(&now));
for_all_symbols(i, sym) {
sym_calc_value(sym);
@@ -700,19 +693,19 @@
case no:
break;
case mod:
- fprintf(out, "CONFIG_%s=m\n", sym->name);
- fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
+ fprintf(out, "%s=m\n", sym->name);
+ fprintf(out_h, "#define %s_MODULE 1\n", sym->name);
break;
case yes:
- fprintf(out, "CONFIG_%s=y\n", sym->name);
- fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
+ 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, "CONFIG_%s=\"", sym->name);
- fprintf(out_h, "#define CONFIG_%s \"", sym->name);
+ fprintf(out, "%s=\"", sym->name);
+ fprintf(out_h, "#define %s \"", sym->name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
@@ -732,14 +725,14 @@
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
- fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
- fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
+ 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, "CONFIG_%s=%s\n", sym->name, str);
- fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
+ fprintf(out, "%s=%s\n", sym->name, str);
+ fprintf(out_h, "#define %s %s\n", sym->name, str);
break;
default:
break;
--- kconfig/gconf.c
+++ Buildroot/gconf.c
@@ -271,8 +271,8 @@
/*"style", PANGO_STYLE_OBLIQUE, */
NULL);
- sprintf(title, _("Linux Kernel v%s Configuration"),
- getenv("KERNELVERSION"));
+ sprintf(title, _("Buildroot v%s Configuration"),
+ getenv("VERSION"));
gtk_window_set_title(GTK_WINDOW(main_wnd), title);
gtk_widget_show(main_wnd);
--- kconfig/mconf.c
+++ Buildroot/mconf.c
@@ -30,20 +30,18 @@
static const char mconf_readme[] = N_(
"Overview\n"
"--------\n"
-"Some kernel features may be built directly into the kernel.\n"
-"Some may be made into loadable runtime modules. Some features\n"
+"Some features may be built directly into Buildroot. Some features\n"
"may be completely removed altogether. There are also certain\n"
-"kernel 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"
"\n"
-"Menu items beginning with [*], <M> or [ ] represent features\n"
-"configured to be built in, modularized or removed respectively.\n"
-"Pointed brackets <> represent module capable features.\n"
+"Menu items beginning with [*] or [ ] represent features\n"
+"configured to be built in or removed respectively.\n"
"\n"
"To change any of these features, highlight it with the cursor\n"
-"keys and press <Y> to build it in, <M> to make it a module or\n"
-"<N> to removed it. You may also press the <Space Bar> to cycle\n"
-"through the available options (ie. Y->N->M->Y).\n"
+"keys and press <Y> to build it in or <N> to removed it.\n"
+"You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->Y).\n"
"\n"
"Some additional keyboard hints:\n"
"\n"
@@ -116,7 +114,7 @@
"-----------------------------\n"
"Menuconfig supports the use of alternate configuration files for\n"
"those who, for various reasons, find it necessary to switch\n"
-"between different kernel configurations.\n"
+"between different configurations.\n"
"\n"
"At the end of the main menu you will find two options. One is\n"
"for saving the current configuration to a file of your choosing.\n"
@@ -149,7 +147,7 @@
"\n"
"Optional personality available\n"
"------------------------------\n"
-"If you prefer to have all of the kernel options listed in a single\n"
+"If you prefer to have all of the options listed in a single\n"
"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
"\n"
@@ -179,9 +177,9 @@
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
"Highlighted letters are hotkeys. "
- "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
+ "Pressing <Y> selectes a feature, while <N> will exclude a feature. "
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
- "Legend: [*] built-in [ ] excluded <M> module < > module capable"),
+ "Legend: [*] feature is selected [ ] feature is excluded"),
radiolist_instructions[] = N_(
"Use the arrow keys to navigate this window or "
"press the hotkey of the item you wish to select "
@@ -201,18 +199,18 @@
"This feature depends on another which has been configured as a module.\n"
"As a result, this feature will be built as a module."),
nohelp_text[] = N_(
- "There is no help available for this kernel option.\n"),
+ "There is no help available for this option.\n"),
load_config_text[] = N_(
"Enter the name of the configuration file you wish to load. "
"Accept the name shown to restore the configuration you "
"last retrieved. Leave blank to abort."),
load_config_help[] = N_(
"\n"
- "For various reasons, one may wish to keep several different kernel\n"
+ "For various reasons, one may wish to keep several different Buildroot\n"
"configurations available on a single machine.\n"
"\n"
"If you have saved a previous configuration in a file other than the\n"
- "kernel's default, entering the name of the file here will allow you\n"
+ "Buildroot's default, entering the name of the file here will allow you\n"
"to modify that configuration.\n"
"\n"
"If you are uncertain, then you have probably never used alternate\n"
@@ -222,7 +220,7 @@
"as an alternate. Leave blank to abort."),
save_config_help[] = N_(
"\n"
- "For various reasons, one may wish to keep different kernel\n"
+ "For various reasons, one may wish to keep different Buildroot\n"
"configurations available on a single machine.\n"
"\n"
"Entering a file name here will allow you to later retrieve, modify\n"
@@ -871,9 +869,9 @@
conf_parse(av[1]);
conf_read(NULL);
- sym = sym_lookup("KERNELVERSION", 0);
+ sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
- sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"),
+ sprintf(menu_backtitle, _("Buildroot v%s Configuration"),
sym_get_string_value(sym));
mode = getenv("MENUCONFIG_MODE");
@@ -893,7 +891,7 @@
if (conf_get_changed())
res = dialog_yesno(NULL,
_("Do you wish to save your "
- "new kernel configuration?\n"
+ "new Buildroot configuration?\n"
"<ESC><ESC> to continue."),
6, 60);
else
@@ -905,22 +903,22 @@
case 0:
if (conf_write(NULL)) {
fprintf(stderr, _("\n\n"
- "Error during writing of the kernel configuration.\n"
- "Your kernel configuration changes were NOT saved."
+ "Error during writing of the Buildroot configuration.\n"
+ "Your Buildroot configuration changes were NOT saved."
"\n\n"));
return 1;
}
case -1:
printf(_("\n\n"
- "*** End of Linux kernel configuration.\n"
- "*** Execute 'make' to build the kernel or try 'make help'."
+ "*** End of Buildroot configuration.\n"
+ "*** Execute 'make' to build Buildroot or try 'make help'."
"\n\n"));
break;
default:
fprintf(stderr, _("\n\n"
- "Your kernel configuration changes were NOT saved."
+ "Your Buildroot configuration changes were NOT saved."
"\n\n"));
}
- return 0;
+ return conf_write_autoconf();
}
--- kconfig/symbol.c
+++ Buildroot/symbol.c
@@ -61,10 +61,10 @@
if (p)
sym_add_default(sym, p);
- sym = sym_lookup("KERNELVERSION", 0);
+ sym = sym_lookup("VERSION", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
- p = getenv("KERNELVERSION");
+ p = getenv("VERSION");
if (p)
sym_add_default(sym, p);
--- kconfig/zconf.tab.c_shipped
+++ Buildroot/zconf.tab.c_shipped
@@ -2115,7 +2115,7 @@
modules_sym = sym_lookup(NULL, 0);
modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO;
- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
+ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL);
#if YYDEBUG
if (getenv("ZCONF_DEBUG"))
--- kconfig/zconf.y
+++ Buildroot/zconf.y
@@ -484,7 +484,7 @@
modules_sym = sym_lookup(NULL, 0);
modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO;
- rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
+ rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL);
#if YYDEBUG
if (getenv("ZCONF_DEBUG"))
--- kconfig/gconf.glade 2007-06-11 20:37:06.000000000 +0200
+++ Buildroot/gconf.glade 2007-06-28 12:17:40.000000000 +0200
@@ -5,7 +5,7 @@
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
- <property name="title" translatable="yes">Gtk Kernel Configurator</property>
+ <property name="title" translatable="yes">Gtk Buildroot Configurator</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>

View File

@ -0,0 +1,35 @@
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include "lkc.h"
#define P(name,type,arg) type (*name ## _p) arg
#include "lkc_proto.h"
#undef P
void kconfig_load(void)
{
void *handle;
char *error;
handle = dlopen("./libkconfig.so", RTLD_LAZY);
if (!handle) {
handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
}
#define P(name,type,arg) \
{ \
name ## _p = dlsym(handle, #name); \
if ((error = dlerror())) { \
fprintf(stderr, "%s\n", error); \
exit(1); \
} \
}
#include "lkc_proto.h"
#undef P
}

227
package/config/kxgettext.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
*
* Released under the terms of the GNU GPL v2.0
*/
#include <stdlib.h>
#include <string.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
static char *escape(const char* text, char *bf, int len)
{
char *bfp = bf;
int multiline = strchr(text, '\n') != NULL;
int eol = 0;
int textlen = strlen(text);
if ((textlen > 0) && (text[textlen-1] == '\n'))
eol = 1;
*bfp++ = '"';
--len;
if (multiline) {
*bfp++ = '"';
*bfp++ = '\n';
*bfp++ = '"';
len -= 3;
}
while (*text != '\0' && len > 1) {
if (*text == '"')
*bfp++ = '\\';
else if (*text == '\n') {
*bfp++ = '\\';
*bfp++ = 'n';
*bfp++ = '"';
*bfp++ = '\n';
*bfp++ = '"';
len -= 5;
++text;
goto next;
}
*bfp++ = *text++;
next:
--len;
}
if (multiline && eol)
bfp -= 3;
*bfp++ = '"';
*bfp = '\0';
return bf;
}
struct file_line {
struct file_line *next;
char* file;
int lineno;
};
static struct file_line *file_line__new(char *file, int lineno)
{
struct file_line *self = malloc(sizeof(*self));
if (self == NULL)
goto out;
self->file = file;
self->lineno = lineno;
self->next = NULL;
out:
return self;
}
struct message {
const char *msg;
const char *option;
struct message *next;
struct file_line *files;
};
static struct message *message__list;
static struct message *message__new(const char *msg, char *option, char *file, int lineno)
{
struct message *self = malloc(sizeof(*self));
if (self == NULL)
goto out;
self->files = file_line__new(file, lineno);
if (self->files == NULL)
goto out_fail;
self->msg = strdup(msg);
if (self->msg == NULL)
goto out_fail_msg;
self->option = option;
self->next = NULL;
out:
return self;
out_fail_msg:
free(self->files);
out_fail:
free(self);
self = NULL;
goto out;
}
static struct message *mesage__find(const char *msg)
{
struct message *m = message__list;
while (m != NULL) {
if (strcmp(m->msg, msg) == 0)
break;
m = m->next;
}
return m;
}
static int message__add_file_line(struct message *self, char *file, int lineno)
{
int rc = -1;
struct file_line *fl = file_line__new(file, lineno);
if (fl == NULL)
goto out;
fl->next = self->files;
self->files = fl;
rc = 0;
out:
return rc;
}
static int message__add(const char *msg, char *option, char *file, int lineno)
{
int rc = 0;
char bf[16384];
char *escaped = escape(msg, bf, sizeof(bf));
struct message *m = mesage__find(escaped);
if (m != NULL)
rc = message__add_file_line(m, file, lineno);
else {
m = message__new(escaped, option, file, lineno);
if (m != NULL) {
m->next = message__list;
message__list = m;
} else
rc = -1;
}
return rc;
}
void menu_build_message_list(struct menu *menu)
{
struct menu *child;
message__add(menu_get_prompt(menu), NULL,
menu->file == NULL ? "Root Menu" : menu->file->name,
menu->lineno);
if (menu->sym != NULL && menu->sym->help != NULL)
message__add(menu->sym->help, menu->sym->name,
menu->file == NULL ? "Root Menu" : menu->file->name,
menu->lineno);
for (child = menu->list; child != NULL; child = child->next)
if (child->prompt != NULL)
menu_build_message_list(child);
}
static void message__print_file_lineno(struct message *self)
{
struct file_line *fl = self->files;
putchar('\n');
if (self->option != NULL)
printf("# %s:00000\n", self->option);
printf("#: %s:%d", fl->file, fl->lineno);
fl = fl->next;
while (fl != NULL) {
printf(", %s:%d", fl->file, fl->lineno);
fl = fl->next;
}
putchar('\n');
}
static void message__print_gettext_msgid_msgstr(struct message *self)
{
message__print_file_lineno(self);
printf("msgid %s\n"
"msgstr \"\"\n", self->msg);
}
void menu__xgettext(void)
{
struct message *m = message__list;
while (m != NULL) {
message__print_gettext_msgid_msgstr(m);
m = m->next;
}
}
int main(int ac, char **av)
{
conf_parse(av[1]);
menu_build_message_list(menu_get_root_menu(NULL));
menu__xgettext();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,14 @@
#include "expr.h" #include "expr.h"
#ifndef KBUILD_NO_NLS
# include <libintl.h>
#else
# define gettext(Msgid) ((const char *) (Msgid))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -23,6 +31,27 @@ extern "C" {
#define SRCTREE "srctree" #define SRCTREE "srctree"
#define PACKAGE "linux"
#define LOCALEDIR "/usr/share/locale"
#define _(text) gettext(text)
#define N_(text) (text)
#define TF_COMMAND 0x0001
#define TF_PARAM 0x0002
#define TF_OPTION 0x0004
#define T_OPT_MODULES 1
#define T_OPT_DEFCONFIG_LIST 2
struct kconf_id {
int name;
int token;
unsigned int flags;
enum symbol_type stype;
};
int zconfparse(void); int zconfparse(void);
void zconfdump(FILE *out); void zconfdump(FILE *out);
@ -35,25 +64,25 @@ int zconf_lineno(void);
char *zconf_curname(void); char *zconf_curname(void);
/* confdata.c */ /* confdata.c */
extern const char conf_def_filename[];
extern char conf_filename[];
char *conf_get_default_confname(void); char *conf_get_default_confname(void);
void sym_set_change_count(int count);
void sym_add_change_count(int count);
/* kconfig_load.c */ /* kconfig_load.c */
void kconfig_load(void); void kconfig_load(void);
/* menu.c */ /* menu.c */
void menu_init(void); void menu_init(void);
void menu_add_menu(void); struct menu *menu_add_menu(void);
void menu_end_menu(void); void menu_end_menu(void);
void menu_add_entry(struct symbol *sym); void menu_add_entry(struct symbol *sym);
void menu_end_entry(void); void menu_end_entry(void);
void menu_add_dep(struct expr *dep); void menu_add_dep(struct expr *dep);
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
void menu_add_option(int token, char *arg);
void menu_finalize(struct menu *parent); void menu_finalize(struct menu *parent);
void menu_set_type(int type); void menu_set_type(int type);
@ -75,6 +104,7 @@ const char *str_get(struct gstr *gs);
/* symbol.c */ /* symbol.c */
void sym_init(void); void sym_init(void);
void sym_clear_all_valid(void); void sym_clear_all_valid(void);
void sym_set_all_changed(void);
void sym_set_changed(struct symbol *sym); 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);
@ -113,7 +143,7 @@ static inline bool sym_is_optional(struct symbol *sym)
static inline bool sym_has_value(struct symbol *sym) static inline bool sym_has_value(struct symbol *sym)
{ {
return sym->flags & SYMBOL_NEW ? false : true; return sym->flags & SYMBOL_DEF_USER ? true : false;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -2,7 +2,11 @@
/* confdata.c */ /* confdata.c */
P(conf_parse,void,(const char *name)); P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name)); P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name, int));
P(conf_write,int,(const char *name)); P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void));
P(conf_get_changed,bool,(void));
P(conf_set_changed_callback, void,(void (*fn)(void)));
/* menu.c */ /* menu.c */
P(rootmenu,struct menu,); P(rootmenu,struct menu,);
@ -14,7 +18,6 @@ P(menu_get_parent_menu,struct menu *,(struct menu *menu));
/* symbol.c */ /* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
P(sym_change_count,int,);
P(sym_lookup,struct symbol *,(const char *name, int isconst)); P(sym_lookup,struct symbol *,(const char *name, int isconst));
P(sym_find,struct symbol *,(const char *name)); P(sym_find,struct symbol *,(const char *name));
@ -37,4 +40,4 @@ P(prop_get_type_name,const char *,(enum prop_type type));
/* expr.c */ /* expr.c */
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken));

View File

@ -0,0 +1,84 @@
#!/bin/sh
# Check ncurses compatibility
# What library to link
ldflags()
{
$cc -print-file-name=libncursesw.so | grep -q /
if [ $? -eq 0 ]; then
echo '-lncursesw'
exit
fi
$cc -print-file-name=libncurses.so | grep -q /
if [ $? -eq 0 ]; then
echo '-lncurses'
exit
fi
$cc -print-file-name=libcurses.so | grep -q /
if [ $? -eq 0 ]; then
echo '-lcurses'
exit
fi
exit 1
}
# Where is ncurses.h?
ccflags()
{
if [ -f /usr/include/ncurses/ncurses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncurses/curses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
elif [ -f /usr/include/ncurses.h ]; then
echo '-DCURSES_LOC="<ncurses.h>"'
else
echo '-DCURSES_LOC="<curses.h>"'
fi
}
# Temp file, try to clean up after us
tmp=.lxdialog.tmp
trap "rm -f $tmp" 0 1 2 3 15
# Check if we can link to ncurses
check() {
echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null
if [ $? != 0 ]; then
echo " *** Unable to find the ncurses libraries." 1>&2
echo " *** make menuconfig require the ncurses libraries" 1>&2
echo " *** " 1>&2
echo " *** Install ncurses (ncurses-devel) and try again" 1>&2
echo " *** " 1>&2
exit 1
fi
}
usage() {
printf "Usage: $0 [-check compiler options|-header|-library]\n"
}
if [ $# == 0 ]; then
usage
exit 1
fi
cc=""
case "$1" in
"-check")
shift
cc="$@"
check
;;
"-ccflags")
ccflags
;;
"-ldflags")
shift
cc="$@"
ldflags
;;
"*")
usage
exit 1
;;
esac

View File

@ -23,350 +23,303 @@
#include "dialog.h" #include "dialog.h"
static int list_width, check_x, item_x, checkflag; static int list_width, check_x, item_x;
/* /*
* Print list item * Print list item
*/ */
static void static void print_item(WINDOW * win, int choice, int selected)
print_item (WINDOW * win, const char *item, int status,
int choice, int selected)
{ {
int i; int i;
/* Clear 'residue' of last item */ /* Clear 'residue' of last item */
wattrset (win, menubox_attr); wattrset(win, dlg.menubox.atr);
wmove (win, choice, 0); wmove(win, choice, 0);
for (i = 0; i < list_width; i++) for (i = 0; i < list_width; i++)
waddch (win, ' '); waddch(win, ' ');
wmove (win, choice, check_x); wmove(win, choice, check_x);
wattrset (win, selected ? check_selected_attr : check_attr); wattrset(win, selected ? dlg.check_selected.atr
if (checkflag == FLAG_CHECK) : dlg.check.atr);
wprintw (win, "[%c]", status ? 'X' : ' '); wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
else
wprintw (win, "(%c)", status ? 'X' : ' ');
wattrset (win, selected ? tag_selected_attr : tag_attr); wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
mvwaddch(win, choice, item_x, item[0]); mvwaddch(win, choice, item_x, item_str()[0]);
wattrset (win, selected ? item_selected_attr : item_attr); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
waddstr (win, (char *)item+1); waddstr(win, (char *)item_str() + 1);
if (selected) { if (selected) {
wmove (win, choice, check_x+1); wmove(win, choice, check_x + 1);
wrefresh (win); wrefresh(win);
} }
} }
/* /*
* Print the scroll indicators. * Print the scroll indicators.
*/ */
static void static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
print_arrows (WINDOW * win, int choice, int item_no, int scroll, int y, int x, int height)
int y, int x, int height)
{ {
wmove(win, y, x); wmove(win, y, x);
if (scroll > 0) { if (scroll > 0) {
wattrset (win, uarrow_attr); wattrset(win, dlg.uarrow.atr);
waddch (win, ACS_UARROW); waddch(win, ACS_UARROW);
waddstr (win, "(-)"); waddstr(win, "(-)");
} } else {
else { wattrset(win, dlg.menubox.atr);
wattrset (win, menubox_attr); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); }
}
y = y + height + 1; y = y + height + 1;
wmove(win, y, x); wmove(win, y, x);
if ((height < item_no) && (scroll + choice < item_no - 1)) { if ((height < item_no) && (scroll + choice < item_no - 1)) {
wattrset (win, darrow_attr); wattrset(win, dlg.darrow.atr);
waddch (win, ACS_DARROW); waddch(win, ACS_DARROW);
waddstr (win, "(+)"); waddstr(win, "(+)");
} } else {
else { wattrset(win, dlg.menubox_border.atr);
wattrset (win, menubox_border_attr); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); }
}
} }
/* /*
* Display the termination buttons * Display the termination buttons
*/ */
static void static void print_buttons(WINDOW * dialog, int height, int width, int selected)
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, "Select", y, x, selected == 0);
print_button (dialog, " Help ", y, x + 14, selected == 1); print_button(dialog, " Help ", y, x + 14, selected == 1);
wmove(dialog, y, x+1 + 14*selected); wmove(dialog, y, x + 1 + 14 * selected);
wrefresh (dialog); wrefresh(dialog);
} }
/* /*
* Display a dialog box with a list of options that can be turned on or off * Display a dialog box with a list of options that can be turned on or off
* The `flag' parameter is used to select between radiolist and checklist. * in the style of radiolist (only one option turned on at a time).
*/ */
int int dialog_checklist(const char *title, const char *prompt, int height,
dialog_checklist (const char *title, const char *prompt, int height, int width, int width, int list_height)
int list_height, int item_no, struct dialog_list_item ** items,
int flag)
{ {
int i, x, y, box_x, box_y; int i, x, y, box_x, box_y;
int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
WINDOW *dialog, *list; WINDOW *dialog, *list;
checkflag = flag; /* which item to highlight */
item_foreach() {
/* Allocate space for storing item on/off status */ if (item_is_tag('X'))
if ((status = malloc (sizeof (int) * item_no)) == NULL) { choice = item_n();
endwin (); if (item_is_selected()) {
fprintf (stderr, choice = item_n();
"\nCan't allocate memory in dialog_checklist().\n"); break;
exit (-1);
}
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = (items[i]->selected == 1); /* ON */
if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */
choice = i + 1;
}
if (choice)
choice--;
max_choice = MIN (list_height, item_no);
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
draw_shadow (stdscr, y, x, height, width);
dialog = newwin (height, width, y, x);
keypad (dialog, TRUE);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset (dialog, border_attr);
mvwaddch (dialog, height-3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) {
/* truncate long title -- mec */
char * title2 = malloc(width-2+1);
memcpy( title2, title, width-2 );
title2[width-2] = '\0';
title = title2;
}
if (title != NULL) {
wattrset (dialog, title_attr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
wattrset (dialog, dialog_attr);
print_autowrap (dialog, prompt, width - 2, 1, 3);
list_width = width - 6;
box_y = height - list_height - 5;
box_x = (width - list_width) / 2 - 1;
/* create new window for the list */
list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
keypad (list, TRUE);
/* draw a box around the list items */
draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
menubox_border_attr, menubox_attr);
/* Find length of longest item in order to center checklist */
check_x = 0;
for (i = 0; i < item_no; i++)
check_x = MAX (check_x, + strlen (items[i]->name) + 4);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
if (choice >= list_height) {
scroll = choice - list_height + 1;
choice -= scroll;
}
/* Print the list */
for (i = 0; i < max_choice; i++) {
print_item (list, items[scroll + i]->name,
status[i+scroll], i, i == choice);
}
print_arrows(dialog, choice, item_no, scroll,
box_y, box_x + check_x + 5, list_height);
print_buttons(dialog, height, width, 0);
wnoutrefresh (list);
wnoutrefresh (dialog);
doupdate ();
while (key != ESC) {
key = wgetch (dialog);
for (i = 0; i < max_choice; i++)
if (toupper(key) == toupper(items[scroll + i]->name[0]))
break;
if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
key == '+' || key == '-' ) {
if (key == KEY_UP || key == '-') {
if (!choice) {
if (!scroll)
continue;
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
print_item (list, items[scroll]->name,
status[scroll], 0, FALSE);
scrollok (list, TRUE);
wscrl (list, -1);
scrollok (list, FALSE);
}
scroll--;
print_item (list, items[scroll]->name,
status[scroll], 0, TRUE);
wnoutrefresh (list);
print_arrows(dialog, choice, item_no, scroll,
box_y, box_x + check_x + 5, list_height);
wrefresh (dialog);
continue; /* wait for another key press */
} else
i = choice - 1;
} else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll + choice >= item_no - 1)
continue;
/* Scroll list up */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item (list, items[scroll + max_choice - 1]->name,
status[scroll + max_choice - 1],
max_choice - 1, FALSE);
scrollok (list, TRUE);
scroll (list);
scrollok (list, FALSE);
}
scroll++;
print_item (list, items[scroll + max_choice - 1]->name,
status[scroll + max_choice - 1],
max_choice - 1, TRUE);
wnoutrefresh (list);
print_arrows(dialog, choice, item_no, scroll,
box_y, box_x + check_x + 5, list_height);
wrefresh (dialog);
continue; /* wait for another key press */
} else
i = choice + 1;
}
if (i != choice) {
/* De-highlight current item */
print_item (list, items[scroll + choice]->name,
status[scroll + choice], choice, FALSE);
/* Highlight new item */
choice = i;
print_item (list, items[scroll + choice]->name,
status[scroll + choice], choice, TRUE);
wnoutrefresh (list);
wrefresh (dialog);
}
continue; /* wait for another key press */
}
switch (key) {
case 'H':
case 'h':
case '?':
for (i = 0; i < item_no; i++)
items[i]->selected = 0;
items[scroll + choice]->selected = 1;
delwin (dialog);
free (status);
return 1;
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 1 : (button > 1 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh (dialog);
break;
case 'S':
case 's':
case ' ':
case '\n':
if (!button) {
if (flag == FLAG_CHECK) {
status[scroll + choice] = !status[scroll + choice];
wmove (list, choice, check_x);
wattrset (list, check_selected_attr);
wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
} else {
if (!status[scroll + choice]) {
for (i = 0; i < item_no; i++)
status[i] = 0;
status[scroll + choice] = 1;
for (i = 0; i < max_choice; i++)
print_item (list, items[scroll + i]->name,
status[scroll + i], i, i == choice);
}
} }
wnoutrefresh (list);
wrefresh (dialog);
for (i = 0; i < item_no; i++) {
items[i]->selected = status[i];
}
} else {
for (i = 0; i < item_no; i++)
items[i]->selected = 0;
items[scroll + choice]->selected = 1;
}
delwin (dialog);
free (status);
return button;
case 'X':
case 'x':
key = ESC;
case ESC:
break;
} }
/* Now, update everything... */ do_resize:
doupdate (); if (getmaxy(stdscr) < (height + 6))
} return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) < (width + 6))
return -ERRDISPLAYTOOSMALL;
delwin (dialog); max_choice = MIN(list_height, item_count());
free (status);
return -1; /* ESC pressed */ /* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
draw_shadow(stdscr, y, x, height, width);
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
draw_box(dialog, 0, 0, height, width,
dlg.dialog.atr, dlg.border.atr);
wattrset(dialog, dlg.border.atr);
mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
list_width = width - 6;
box_y = height - list_height - 5;
box_x = (width - list_width) / 2 - 1;
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1,
x + box_x + 1);
keypad(list, TRUE);
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
dlg.menubox_border.atr, dlg.menubox.atr);
/* Find length of longest item in order to center checklist */
check_x = 0;
item_foreach()
check_x = MAX(check_x, strlen(item_str()) + 4);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
if (choice >= list_height) {
scroll = choice - list_height + 1;
choice -= scroll;
}
/* Print the list */
for (i = 0; i < max_choice; i++) {
item_set(scroll + i);
print_item(list, i, i == choice);
}
print_arrows(dialog, choice, item_count(), scroll,
box_y, box_x + check_x + 5, list_height);
print_buttons(dialog, height, width, 0);
wnoutrefresh(dialog);
wnoutrefresh(list);
doupdate();
while (key != KEY_ESC) {
key = wgetch(dialog);
for (i = 0; i < max_choice; i++) {
item_set(i + scroll);
if (toupper(key) == toupper(item_str()[0]))
break;
}
if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
key == '+' || key == '-') {
if (key == KEY_UP || key == '-') {
if (!choice) {
if (!scroll)
continue;
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
item_set(scroll);
print_item(list, 0, FALSE);
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
item_set(scroll);
print_item(list, 0, TRUE);
print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog);
wrefresh(list);
continue; /* wait for another key press */
} else
i = choice - 1;
} else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll + choice >= item_count() - 1)
continue;
/* Scroll list up */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
item_set(scroll + max_choice - 1);
print_item(list,
max_choice - 1,
FALSE);
scrollok(list, TRUE);
wscrl(list, 1);
scrollok(list, FALSE);
}
scroll++;
item_set(scroll + max_choice - 1);
print_item(list, max_choice - 1, TRUE);
print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog);
wrefresh(list);
continue; /* wait for another key press */
} else
i = choice + 1;
}
if (i != choice) {
/* De-highlight current item */
item_set(scroll + choice);
print_item(list, choice, FALSE);
/* Highlight new item */
choice = i;
item_set(scroll + choice);
print_item(list, choice, TRUE);
wnoutrefresh(dialog);
wrefresh(list);
}
continue; /* wait for another key press */
}
switch (key) {
case 'H':
case 'h':
case '?':
button = 1;
/* fall-through */
case 'S':
case 's':
case ' ':
case '\n':
item_foreach()
item_set_selected(0);
item_set(scroll + choice);
item_set_selected(1);
delwin(list);
delwin(dialog);
return button;
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 1 : (button > 1 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh(dialog);
break;
case 'X':
case 'x':
key = KEY_ESC;
break;
case KEY_ESC:
key = on_key_esc(dialog);
break;
case KEY_RESIZE:
delwin(list);
delwin(dialog);
on_key_resize();
goto do_resize;
}
/* Now, update everything... */
doupdate();
}
delwin(list);
delwin(dialog);
return key; /* ESC pressed */
} }

View File

@ -1,4 +1,3 @@
/* /*
* dialog.h -- common declarations for all dialog modules * dialog.h -- common declarations for all dialog modules
* *
@ -25,8 +24,8 @@
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#ifdef CURSES_LOC
#ifdef __sun__ #ifdef __sun__
#define CURS_MACROS #define CURS_MACROS
#endif #endif
@ -43,21 +42,20 @@
#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) #if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
#define OLD_NCURSES 1 #define OLD_NCURSES 1
#undef wbkgdset #undef wbkgdset
#define wbkgdset(w,p) /*nothing*/ #define wbkgdset(w,p) /*nothing */
#else #else
#define OLD_NCURSES 0 #define OLD_NCURSES 0
#endif #endif
#define TR(params) _tracef params #define TR(params) _tracef params
#define ESC 27 #define KEY_ESC 27
#define TAB 9 #define TAB 9
#define MAX_LEN 2048 #define MAX_LEN 2048
#define BUF_SIZE (10*1024) #define BUF_SIZE (10*1024)
#define MIN(x,y) (x < y ? x : y) #define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y) #define MAX(x,y) (x > y ? x : y)
#ifndef ACS_ULCORNER #ifndef ACS_ULCORNER
#define ACS_ULCORNER '+' #define ACS_ULCORNER '+'
#endif #endif
@ -89,93 +87,130 @@
#define ACS_DARROW 'v' #define ACS_DARROW 'v'
#endif #endif
/* /* error return codes */
* Attribute names #define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
*/
#define screen_attr attributes[0]
#define shadow_attr attributes[1]
#define dialog_attr attributes[2]
#define title_attr attributes[3]
#define border_attr attributes[4]
#define button_active_attr attributes[5]
#define button_inactive_attr attributes[6]
#define button_key_active_attr attributes[7]
#define button_key_inactive_attr attributes[8]
#define button_label_active_attr attributes[9]
#define button_label_inactive_attr attributes[10]
#define inputbox_attr attributes[11]
#define inputbox_border_attr attributes[12]
#define searchbox_attr attributes[13]
#define searchbox_title_attr attributes[14]
#define searchbox_border_attr attributes[15]
#define position_indicator_attr attributes[16]
#define menubox_attr attributes[17]
#define menubox_border_attr attributes[18]
#define item_attr attributes[19]
#define item_selected_attr attributes[20]
#define tag_attr attributes[21]
#define tag_selected_attr attributes[22]
#define tag_key_attr attributes[23]
#define tag_key_selected_attr attributes[24]
#define check_attr attributes[25]
#define check_selected_attr attributes[26]
#define uarrow_attr attributes[27]
#define darrow_attr attributes[28]
/* number of attributes */ /*
#define ATTRIBUTE_COUNT 29 * Color definitions
*/
struct dialog_color {
chtype atr; /* Color attribute */
int fg; /* foreground */
int bg; /* background */
int hl; /* highlight this item */
};
struct dialog_info {
const char *backtitle;
struct dialog_color screen;
struct dialog_color shadow;
struct dialog_color dialog;
struct dialog_color title;
struct dialog_color border;
struct dialog_color button_active;
struct dialog_color button_inactive;
struct dialog_color button_key_active;
struct dialog_color button_key_inactive;
struct dialog_color button_label_active;
struct dialog_color button_label_inactive;
struct dialog_color inputbox;
struct dialog_color inputbox_border;
struct dialog_color searchbox;
struct dialog_color searchbox_title;
struct dialog_color searchbox_border;
struct dialog_color position_indicator;
struct dialog_color menubox;
struct dialog_color menubox_border;
struct dialog_color item;
struct dialog_color item_selected;
struct dialog_color tag;
struct dialog_color tag_selected;
struct dialog_color tag_key;
struct dialog_color tag_key_selected;
struct dialog_color check;
struct dialog_color check_selected;
struct dialog_color uarrow;
struct dialog_color darrow;
};
/* /*
* Global variables * Global variables
*/ */
extern bool use_colors; extern struct dialog_info dlg;
extern char dialog_input_result[];
extern chtype attributes[];
#endif
extern const char *backtitle;
struct dialog_list_item {
char *name;
int namelen;
char *tag;
int selected; /* Set to 1 by dialog_*() function. */
};
/* /*
* Function prototypes * Function prototypes
*/ */
void init_dialog (void); /* item list as used by checklist and menubox */
void end_dialog (void); void item_reset(void);
void dialog_clear (void); void item_make(const char *fmt, ...);
#ifdef CURSES_LOC void item_add_str(const char *fmt, ...);
void attr_clear (WINDOW * win, int height, int width, chtype attr); void item_set_tag(char tag);
void color_setup (void); void item_set_data(void *p);
void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x); void item_set_selected(int val);
void print_button (WINDOW * win, const char *label, int y, int x, int selected); int item_activate_selected(void);
void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box, void *item_data(void);
chtype border); char item_tag(void);
void draw_shadow (WINDOW * win, int y, int x, int height, int width);
#endif
int first_alpha (const char *string, const char *exempt); /* item list manipulation for lxdialog use */
int dialog_yesno (const char *title, const char *prompt, int height, int width); #define MAXITEMSTR 200
int dialog_msgbox (const char *title, const char *prompt, int height, struct dialog_item {
int width, int pause); char str[MAXITEMSTR]; /* promtp displayed */
int dialog_textbox (const char *title, const char *file, int height, int width); char tag;
int dialog_menu (const char *title, const char *prompt, int height, int width, void *data; /* pointer to menu item - used by menubox+checklist */
int menu_height, const char *choice, int item_no, int selected; /* Set to 1 by dialog_*() function if selected. */
struct dialog_list_item ** items); };
int dialog_checklist (const char *title, const char *prompt, int height,
int width, int list_height, int item_no,
struct dialog_list_item ** items, int flag);
extern unsigned char dialog_input_result[];
int dialog_inputbox (const char *title, const char *prompt, int height,
int width, const char *init);
struct dialog_list_item *first_sel_item(int item_no, /* list of lialog_items */
struct dialog_list_item ** items); struct dialog_list {
struct dialog_item node;
struct dialog_list *next;
};
extern struct dialog_list *item_cur;
extern struct dialog_list item_nil;
extern struct dialog_list *item_head;
int item_count(void);
void item_set(int n);
int item_n(void);
const char *item_str(void);
int item_is_selected(void);
int item_is_tag(char tag);
#define item_foreach() \
for (item_cur = item_head ? item_head: item_cur; \
item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
/* generic key handlers */
int on_key_esc(WINDOW *win);
int on_key_resize(void);
void init_dialog(const char *backtitle);
void reset_dialog(void);
void end_dialog(void);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void);
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
void print_button(WINDOW * win, const char *label, int y, int x, int selected);
void print_title(WINDOW *dialog, const char *title, int width);
void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box,
chtype border);
void draw_shadow(WINDOW * win, int y, int x, int height, int width);
int first_alpha(const char *string, const char *exempt);
int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
int dialog_textbox(const char *title, const char *file, int height, int width);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height);
extern char dialog_input_result[];
int dialog_inputbox(const char *title, const char *prompt, int height,
int width, const char *init);
/* /*
* This is the base for fictitious keys, which activate * This is the base for fictitious keys, which activate
@ -186,14 +221,4 @@ struct dialog_list_item *first_sel_item(int item_no,
* -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
* -- uppercase chars are used to invoke the button (M_EVENT + 'O') * -- uppercase chars are used to invoke the button (M_EVENT + 'O')
*/ */
#ifdef CURSES_LOC
#define M_EVENT (KEY_MAX+1) #define M_EVENT (KEY_MAX+1)
#endif
/*
* The `flag' parameter in checklist is used to select between
* radiolist and checklist
*/
#define FLAG_CHECK 1
#define FLAG_RADIO 0

View File

@ -21,220 +21,218 @@
#include "dialog.h" #include "dialog.h"
unsigned char dialog_input_result[MAX_LEN + 1]; char dialog_input_result[MAX_LEN + 1];
/* /*
* Print the termination buttons * Print the termination buttons
*/ */
static void static void print_buttons(WINDOW * dialog, int height, int width, int selected)
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, " Ok ", y, x, selected == 0);
print_button (dialog, " Help ", y, x + 14, selected==1); print_button(dialog, " Help ", y, x + 14, selected == 1);
wmove(dialog, y, x+1+14*selected); wmove(dialog, y, x + 1 + 14 * selected);
wrefresh(dialog); wrefresh(dialog);
} }
/* /*
* Display a dialog box for inputing a string * Display a dialog box for inputing a string
*/ */
int int dialog_inputbox(const char *title, const char *prompt, int height, int width,
dialog_inputbox (const char *title, const char *prompt, int height, int width, const char *init)
const char *init)
{ {
int i, x, y, box_y, box_x, box_width; int i, x, y, box_y, box_x, box_width;
int input_x = 0, scroll = 0, key = 0, button = -1; int input_x = 0, scroll = 0, key = 0, button = -1;
unsigned char *instr = dialog_input_result; char *instr = dialog_input_result;
WINDOW *dialog; WINDOW *dialog;
/* center dialog box on screen */ if (!init)
x = (COLS - width) / 2; instr[0] = '\0';
y = (LINES - height) / 2; else
strcpy(instr, init);
do_resize:
if (getmaxy(stdscr) <= (height - 2))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) <= (width - 2))
return -ERRDISPLAYTOOSMALL;
draw_shadow (stdscr, y, x, height, width); /* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
dialog = newwin (height, width, y, x); draw_shadow(stdscr, y, x, height, width);
keypad (dialog, TRUE);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); dialog = newwin(height, width, y, x);
wattrset (dialog, border_attr); keypad(dialog, TRUE);
mvwaddch (dialog, height-3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) { draw_box(dialog, 0, 0, height, width,
/* truncate long title -- mec */ dlg.dialog.atr, dlg.border.atr);
char * title2 = malloc(width-2+1); wattrset(dialog, dlg.border.atr);
memcpy( title2, title, width-2 ); mvwaddch(dialog, height - 3, 0, ACS_LTEE);
title2[width-2] = '\0'; for (i = 0; i < width - 2; i++)
title = title2; waddch(dialog, ACS_HLINE);
} wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
if (title != NULL) { print_title(dialog, title, width);
wattrset (dialog, title_attr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
wattrset (dialog, dialog_attr); wattrset(dialog, dlg.dialog.atr);
print_autowrap (dialog, prompt, width - 2, 1, 3); print_autowrap(dialog, prompt, width - 2, 1, 3);
/* Draw the input field box */ /* Draw the input field box */
box_width = width - 6; box_width = width - 6;
getyx (dialog, y, x); getyx(dialog, y, x);
box_y = y + 2; box_y = y + 2;
box_x = (width - box_width) / 2; box_x = (width - box_width) / 2;
draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
border_attr, dialog_attr); dlg.border.atr, dlg.dialog.atr);
print_buttons(dialog, height, width, 0); print_buttons(dialog, height, width, 0);
/* Set up the initial value */ /* Set up the initial value */
wmove (dialog, box_y, box_x); wmove(dialog, box_y, box_x);
wattrset (dialog, inputbox_attr); wattrset(dialog, dlg.inputbox.atr);
if (!init) input_x = strlen(instr);
instr[0] = '\0';
else
strcpy (instr, init);
input_x = strlen (instr); if (input_x >= box_width) {
scroll = input_x - box_width + 1;
input_x = box_width - 1;
for (i = 0; i < box_width - 1; i++)
waddch(dialog, instr[scroll + i]);
} else {
waddstr(dialog, instr);
}
if (input_x >= box_width) { wmove(dialog, box_y, box_x + input_x);
scroll = input_x - box_width + 1;
input_x = box_width - 1;
for (i = 0; i < box_width - 1; i++)
waddch (dialog, instr[scroll + i]);
} else
waddstr (dialog, instr);
wmove (dialog, box_y, box_x + input_x); wrefresh(dialog);
wrefresh (dialog); while (key != KEY_ESC) {
key = wgetch(dialog);
while (key != ESC) { if (button == -1) { /* Input box selected */
key = wgetch (dialog); switch (key) {
case TAB:
if (button == -1) { /* Input box selected */ case KEY_UP:
switch (key) { case KEY_DOWN:
case TAB: break;
case KEY_UP: case KEY_LEFT:
case KEY_DOWN: continue;
break; case KEY_RIGHT:
case KEY_LEFT: continue;
continue; case KEY_BACKSPACE:
case KEY_RIGHT: case 127:
continue; if (input_x || scroll) {
case KEY_BACKSPACE: wattrset(dialog, dlg.inputbox.atr);
case 127: if (!input_x) {
if (input_x || scroll) { scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
wattrset (dialog, inputbox_attr); wmove(dialog, box_y, box_x);
if (!input_x) { for (i = 0; i < box_width; i++)
scroll = scroll < box_width - 1 ? waddch(dialog,
0 : scroll - (box_width - 1); instr[scroll + input_x + i] ?
wmove (dialog, box_y, box_x); instr[scroll + input_x + i] : ' ');
for (i = 0; i < box_width; i++) input_x = strlen(instr) - scroll;
waddch (dialog, instr[scroll + input_x + i] ? } else
instr[scroll + input_x + i] : ' '); input_x--;
input_x = strlen (instr) - scroll; instr[scroll + input_x] = '\0';
} else mvwaddch(dialog, box_y, input_x + box_x, ' ');
input_x--; wmove(dialog, box_y, input_x + box_x);
instr[scroll + input_x] = '\0'; wrefresh(dialog);
mvwaddch (dialog, box_y, input_x + box_x, ' '); }
wmove (dialog, box_y, input_x + box_x); continue;
wrefresh (dialog); default:
} if (key < 0x100 && isprint(key)) {
continue; if (scroll + input_x < MAX_LEN) {
default: wattrset(dialog, dlg.inputbox.atr);
if (key < 0x100 && isprint (key)) { instr[scroll + input_x] = key;
if (scroll + input_x < MAX_LEN) { instr[scroll + input_x + 1] = '\0';
wattrset (dialog, inputbox_attr); if (input_x == box_width - 1) {
instr[scroll + input_x] = key; scroll++;
instr[scroll + input_x + 1] = '\0'; wmove(dialog, box_y, box_x);
if (input_x == box_width - 1) { for (i = 0; i < box_width - 1; i++)
scroll++; waddch(dialog, instr [scroll + i]);
wmove (dialog, box_y, box_x); } else {
for (i = 0; i < box_width - 1; i++) wmove(dialog, box_y, input_x++ + box_x);
waddch (dialog, instr[scroll + i]); waddch(dialog, key);
} else { }
wmove (dialog, box_y, input_x++ + box_x); wrefresh(dialog);
waddch (dialog, key); } else
flash(); /* Alarm user about overflow */
continue;
}
} }
wrefresh (dialog);
} else
flash (); /* Alarm user about overflow */
continue;
} }
} switch (key) {
case 'O':
case 'o':
delwin(dialog);
return 0;
case 'H':
case 'h':
delwin(dialog);
return 1;
case KEY_UP:
case KEY_LEFT:
switch (button) {
case -1:
button = 1; /* Indicates "Cancel" button is selected */
print_buttons(dialog, height, width, 1);
break;
case 0:
button = -1; /* Indicates input box is selected */
print_buttons(dialog, height, width, 0);
wmove(dialog, box_y, box_x + input_x);
wrefresh(dialog);
break;
case 1:
button = 0; /* Indicates "OK" button is selected */
print_buttons(dialog, height, width, 0);
break;
}
break;
case TAB:
case KEY_DOWN:
case KEY_RIGHT:
switch (button) {
case -1:
button = 0; /* Indicates "OK" button is selected */
print_buttons(dialog, height, width, 0);
break;
case 0:
button = 1; /* Indicates "Cancel" button is selected */
print_buttons(dialog, height, width, 1);
break;
case 1:
button = -1; /* Indicates input box is selected */
print_buttons(dialog, height, width, 0);
wmove(dialog, box_y, box_x + input_x);
wrefresh(dialog);
break;
}
break;
case ' ':
case '\n':
delwin(dialog);
return (button == -1 ? 0 : button);
case 'X':
case 'x':
key = KEY_ESC;
break;
case KEY_ESC:
key = on_key_esc(dialog);
break;
case KEY_RESIZE:
delwin(dialog);
on_key_resize();
goto do_resize;
}
} }
switch (key) {
case 'O':
case 'o':
delwin (dialog);
return 0;
case 'H':
case 'h':
delwin (dialog);
return 1;
case KEY_UP:
case KEY_LEFT:
switch (button) {
case -1:
button = 1; /* Indicates "Cancel" button is selected */
print_buttons(dialog, height, width, 1);
break;
case 0:
button = -1; /* Indicates input box is selected */
print_buttons(dialog, height, width, 0);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
break;
case 1:
button = 0; /* Indicates "OK" button is selected */
print_buttons(dialog, height, width, 0);
break;
}
break;
case TAB:
case KEY_DOWN:
case KEY_RIGHT:
switch (button) {
case -1:
button = 0; /* Indicates "OK" button is selected */
print_buttons(dialog, height, width, 0);
break;
case 0:
button = 1; /* Indicates "Cancel" button is selected */
print_buttons(dialog, height, width, 1);
break;
case 1:
button = -1; /* Indicates input box is selected */
print_buttons(dialog, height, width, 0);
wmove (dialog, box_y, box_x + input_x);
wrefresh (dialog);
break;
}
break;
case ' ':
case '\n':
delwin (dialog);
return (button == -1 ? 0 : button);
case 'X':
case 'x':
key = ESC;
case ESC:
break;
}
}
delwin (dialog); delwin(dialog);
return -1; /* ESC pressed */ return KEY_ESC; /* ESC pressed */
} }

View File

@ -63,376 +63,372 @@ static int menu_width, item_x;
/* /*
* Print menu item * Print menu item
*/ */
static void static void do_print_item(WINDOW * win, const char *item, int line_y,
print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey) int selected, int hotkey)
{ {
int j; int j;
char menu_item[menu_width+1]; char *menu_item = malloc(menu_width + 1);
strncpy(menu_item, item, menu_width); strncpy(menu_item, item, menu_width - item_x);
menu_item[menu_width] = 0; menu_item[menu_width - item_x] = '\0';
j = first_alpha(menu_item, "YyNnMmHh"); j = first_alpha(menu_item, "YyNnMmHh");
/* Clear 'residue' of last item */ /* Clear 'residue' of last item */
wattrset (win, menubox_attr); wattrset(win, dlg.menubox.atr);
wmove (win, choice, 0); wmove(win, line_y, 0);
#if OLD_NCURSES #if OLD_NCURSES
{ {
int i; int i;
for (i = 0; i < menu_width; i++) for (i = 0; i < menu_width; i++)
waddch (win, ' '); waddch(win, ' ');
} }
#else #else
wclrtoeol(win); wclrtoeol(win);
#endif #endif
wattrset (win, selected ? item_selected_attr : item_attr); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
mvwaddstr (win, choice, item_x, menu_item); mvwaddstr(win, line_y, item_x, menu_item);
if (hotkey) { if (hotkey) {
wattrset (win, selected ? tag_key_selected_attr : tag_key_attr); wattrset(win, selected ? dlg.tag_key_selected.atr
mvwaddch(win, choice, item_x+j, menu_item[j]); : dlg.tag_key.atr);
} mvwaddch(win, line_y, item_x + j, menu_item[j]);
if (selected) { }
wmove (win, choice, item_x+1); if (selected) {
wrefresh (win); wmove(win, line_y, item_x + 1);
} }
free(menu_item);
wrefresh(win);
} }
#define print_item(index, choice, selected) \
do { \
item_set(index); \
do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
} while (0)
/* /*
* Print the scroll indicators. * Print the scroll indicators.
*/ */
static void static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
print_arrows (WINDOW * win, int item_no, int scroll, int height)
int y, int x, int height)
{ {
int cur_y, cur_x; int cur_y, cur_x;
getyx(win, cur_y, cur_x); getyx(win, cur_y, cur_x);
wmove(win, y, x); wmove(win, y, x);
if (scroll > 0) { if (scroll > 0) {
wattrset (win, uarrow_attr); wattrset(win, dlg.uarrow.atr);
waddch (win, ACS_UARROW); waddch(win, ACS_UARROW);
waddstr (win, "(-)"); waddstr(win, "(-)");
} } else {
else { wattrset(win, dlg.menubox.atr);
wattrset (win, menubox_attr); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); }
}
y = y + height + 1; y = y + height + 1;
wmove(win, y, x); wmove(win, y, x);
wrefresh(win);
if ((height < item_no) && (scroll + height < item_no)) { if ((height < item_no) && (scroll + height < item_no)) {
wattrset (win, darrow_attr); wattrset(win, dlg.darrow.atr);
waddch (win, ACS_DARROW); waddch(win, ACS_DARROW);
waddstr (win, "(+)"); waddstr(win, "(+)");
} } else {
else { wattrset(win, dlg.menubox_border.atr);
wattrset (win, menubox_border_attr); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); waddch(win, ACS_HLINE);
waddch (win, ACS_HLINE); }
}
wmove(win, cur_y, cur_x); wmove(win, cur_y, cur_x);
wrefresh(win);
} }
/* /*
* Display the termination buttons. * Display the termination buttons.
*/ */
static void static void print_buttons(WINDOW * win, int height, int width, int selected)
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, "Select", y, x, selected == 0);
print_button (win, " Exit ", y, x + 12, selected == 1); print_button(win, " Exit ", y, x + 12, selected == 1);
print_button (win, " Help ", y, x + 24, selected == 2); print_button(win, " Help ", y, x + 24, selected == 2);
wmove(win, y, x+1+12*selected); wmove(win, y, x + 1 + 12 * selected);
wrefresh (win); wrefresh(win);
}
/* scroll up n lines (n may be negative) */
static void do_scroll(WINDOW *win, int *scroll, int n)
{
/* Scroll menu up */
scrollok(win, TRUE);
wscrl(win, n);
scrollok(win, FALSE);
*scroll = *scroll + n;
wrefresh(win);
} }
/* /*
* Display a menu for choosing among a number of options * Display a menu for choosing among a number of options
*/ */
int int dialog_menu(const char *title, const char *prompt,
dialog_menu (const char *title, const char *prompt, int height, int width, const void *selected, int *s_scroll)
int menu_height, const char *current, int item_no,
struct dialog_list_item ** items)
{ {
int i, j, x, y, box_x, box_y; int i, j, x, y, box_x, box_y;
int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice; int height, width, menu_height;
WINDOW *dialog, *menu; int key = 0, button = 0, scroll = 0, choice = 0;
FILE *f; int first_item = 0, max_choice;
WINDOW *dialog, *menu;
max_choice = MIN (menu_height, item_no); do_resize:
height = getmaxy(stdscr);
width = getmaxx(stdscr);
if (height < 15 || width < 65)
return -ERRDISPLAYTOOSMALL;
/* center dialog box on screen */ height -= 4;
x = (COLS - width) / 2; width -= 5;
y = (LINES - height) / 2; menu_height = height - 10;
draw_shadow (stdscr, y, x, height, width); max_choice = MIN(menu_height, item_count());
dialog = newwin (height, width, y, x); /* center dialog box on screen */
keypad (dialog, TRUE); x = (COLS - width) / 2;
y = (LINES - height) / 2;
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); draw_shadow(stdscr, y, x, height, width);
wattrset (dialog, border_attr);
mvwaddch (dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
wbkgdset (dialog, dialog_attr & A_COLOR);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) { dialog = newwin(height, width, y, x);
/* truncate long title -- mec */ keypad(dialog, TRUE);
char * title2 = malloc(width-2+1);
memcpy( title2, title, width-2 );
title2[width-2] = '\0';
title = title2;
}
if (title != NULL) { draw_box(dialog, 0, 0, height, width,
wattrset (dialog, title_attr); dlg.dialog.atr, dlg.border.atr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); wattrset(dialog, dlg.border.atr);
waddstr (dialog, (char *)title); mvwaddch(dialog, height - 3, 0, ACS_LTEE);
waddch (dialog, ' '); for (i = 0; i < width - 2; i++)
} waddch(dialog, ACS_HLINE);
wattrset(dialog, dlg.dialog.atr);
wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
waddch(dialog, ACS_RTEE);
wattrset (dialog, dialog_attr); print_title(dialog, title, width);
print_autowrap (dialog, prompt, width - 2, 1, 3);
menu_width = width - 6; wattrset(dialog, dlg.dialog.atr);
box_y = height - menu_height - 5; print_autowrap(dialog, prompt, width - 2, 1, 3);
box_x = (width - menu_width) / 2 - 1;
/* create new window for the menu */ menu_width = width - 6;
menu = subwin (dialog, menu_height, menu_width, box_y = height - menu_height - 5;
y + box_y + 1, x + box_x + 1); box_x = (width - menu_width) / 2 - 1;
keypad (menu, TRUE);
/* draw a box around the menu items */ /* create new window for the menu */
draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2, menu = subwin(dialog, menu_height, menu_width,
menubox_border_attr, menubox_attr); y + box_y + 1, x + box_x + 1);
keypad(menu, TRUE);
/* /* draw a box around the menu items */
* Find length of longest item in order to center menu. draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
* Set 'choice' to default item. dlg.menubox_border.atr, dlg.menubox.atr);
*/
item_x = 0;
for (i = 0; i < item_no; i++) {
item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2));
if (strcmp(current, items[i]->tag) == 0) choice = i;
}
item_x = (menu_width - item_x) / 2; if (menu_width >= 80)
item_x = (menu_width - 70) / 2;
/* get the scroll info from the temp file */
if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
(scroll+max_choice > choice) && (scroll >= 0) &&
(scroll+max_choice <= item_no) ) {
first_item = scroll;
choice = choice - scroll;
fclose(f);
} else {
scroll=0;
remove("lxdialog.scrltmp");
fclose(f);
f=NULL;
}
}
if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
if (choice >= item_no-max_choice/2)
scroll = first_item = item_no-max_choice;
else else
scroll = first_item = choice - max_choice/2; item_x = 4;
choice = choice - scroll;
}
/* Print the menu */ /* Set choice to default item */
for (i=0; i < max_choice; i++) { item_foreach()
print_item (menu, items[first_item + i]->name, i, i == choice, if (selected && (selected == item_data()))
(items[first_item + i]->tag[0] != ':')); choice = item_n();
} /* get the saved scroll info */
scroll = *s_scroll;
wnoutrefresh (menu); if ((scroll <= choice) && (scroll + max_choice > choice) &&
(scroll >= 0) && (scroll + max_choice <= item_count())) {
print_arrows(dialog, item_no, scroll, first_item = scroll;
box_y, box_x+item_x+1, menu_height); choice = choice - scroll;
} else {
print_buttons (dialog, height, width, 0); scroll = 0;
wmove (menu, choice, item_x+1);
wrefresh (menu);
while (key != ESC) {
key = wgetch(menu);
if (key < 256 && isalpha(key)) key = tolower(key);
if (strchr("ynmh", key))
i = max_choice;
else {
for (i = choice+1; i < max_choice; i++) {
j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
if (key == tolower(items[scroll + i]->name[j]))
break;
} }
if (i == max_choice) if ((choice >= max_choice)) {
for (i = 0; i < max_choice; i++) { if (choice >= item_count() - max_choice / 2)
j = first_alpha(items[scroll + i]->name, "YyNnMmHh"); scroll = first_item = item_count() - max_choice;
if (key == tolower(items[scroll + i]->name[j])) else
break; scroll = first_item = choice - max_choice / 2;
choice = choice - scroll;
}
/* Print the menu */
for (i = 0; i < max_choice; i++) {
print_item(first_item + i, i, i == choice);
}
wnoutrefresh(menu);
print_arrows(dialog, item_count(), scroll,
box_y, box_x + item_x + 1, menu_height);
print_buttons(dialog, height, width, 0);
wmove(menu, choice, item_x + 1);
wrefresh(menu);
while (key != KEY_ESC) {
key = wgetch(menu);
if (key < 256 && isalpha(key))
key = tolower(key);
if (strchr("ynmh", key))
i = max_choice;
else {
for (i = choice + 1; i < max_choice; i++) {
item_set(scroll + i);
j = first_alpha(item_str(), "YyNnMmHh");
if (key == tolower(item_str()[j]))
break;
}
if (i == max_choice)
for (i = 0; i < max_choice; i++) {
item_set(scroll + i);
j = first_alpha(item_str(), "YyNnMmHh");
if (key == tolower(item_str()[j]))
break;
}
}
if (i < max_choice ||
key == KEY_UP || key == KEY_DOWN ||
key == '-' || key == '+' ||
key == KEY_PPAGE || key == KEY_NPAGE) {
/* Remove highligt of current item */
print_item(scroll + choice, choice, FALSE);
if (key == KEY_UP || key == '-') {
if (choice < 2 && scroll) {
/* Scroll menu down */
do_scroll(menu, &scroll, -1);
print_item(scroll, 0, FALSE);
} else
choice = MAX(choice - 1, 0);
} else if (key == KEY_DOWN || key == '+') {
print_item(scroll+choice, choice, FALSE);
if ((choice > max_choice - 3) &&
(scroll + max_choice < item_count())) {
/* Scroll menu up */
do_scroll(menu, &scroll, 1);
print_item(scroll+max_choice - 1,
max_choice - 1, FALSE);
} else
choice = MIN(choice + 1, max_choice - 1);
} else if (key == KEY_PPAGE) {
scrollok(menu, TRUE);
for (i = 0; (i < max_choice); i++) {
if (scroll > 0) {
do_scroll(menu, &scroll, -1);
print_item(scroll, 0, FALSE);
} else {
if (choice > 0)
choice--;
}
}
} else if (key == KEY_NPAGE) {
for (i = 0; (i < max_choice); i++) {
if (scroll + max_choice < item_count()) {
do_scroll(menu, &scroll, 1);
print_item(scroll+max_choice-1,
max_choice - 1, FALSE);
} else {
if (choice + 1 < max_choice)
choice++;
}
}
} else
choice = i;
print_item(scroll + choice, choice, TRUE);
print_arrows(dialog, item_count(), scroll,
box_y, box_x + item_x + 1, menu_height);
wnoutrefresh(dialog);
wrefresh(menu);
continue; /* wait for another key press */
}
switch (key) {
case KEY_LEFT:
case TAB:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 2 : (button > 2 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh(menu);
break;
case ' ':
case 's':
case 'y':
case 'n':
case 'm':
case '/':
/* save scroll info */
*s_scroll = scroll;
delwin(menu);
delwin(dialog);
item_set(scroll + choice);
item_set_selected(1);
switch (key) {
case 's':
return 3;
case 'y':
return 3;
case 'n':
return 4;
case 'm':
return 5;
case ' ':
return 6;
case '/':
return 7;
}
return 0;
case 'h':
case '?':
button = 2;
case '\n':
*s_scroll = scroll;
delwin(menu);
delwin(dialog);
item_set(scroll + choice);
item_set_selected(1);
return button;
case 'e':
case 'x':
key = KEY_ESC;
break;
case KEY_ESC:
key = on_key_esc(menu);
break;
case KEY_RESIZE:
on_key_resize();
delwin(menu);
delwin(dialog);
goto do_resize;
} }
} }
delwin(menu);
if (i < max_choice || delwin(dialog);
key == KEY_UP || key == KEY_DOWN || return key; /* ESC pressed */
key == '-' || key == '+' ||
key == KEY_PPAGE || key == KEY_NPAGE) {
print_item (menu, items[scroll + choice]->name, choice, FALSE,
(items[scroll + choice]->tag[0] != ':'));
if (key == KEY_UP || key == '-') {
if (choice < 2 && scroll) {
/* Scroll menu down */
scrollok (menu, TRUE);
wscrl (menu, -1);
scrollok (menu, FALSE);
scroll--;
print_item (menu, items[scroll]->name, 0, FALSE,
(items[scroll]->tag[0] != ':'));
} else
choice = MAX(choice - 1, 0);
} else if (key == KEY_DOWN || key == '+') {
print_item (menu, items[scroll + choice]->name, choice, FALSE,
(items[scroll + choice]->tag[0] != ':'));
if ((choice > max_choice-3) &&
(scroll + max_choice < item_no)
) {
/* Scroll menu up */
scrollok (menu, TRUE);
scroll (menu);
scrollok (menu, FALSE);
scroll++;
print_item (menu, items[scroll + max_choice - 1]->name,
max_choice-1, FALSE,
(items[scroll + max_choice - 1]->tag[0] != ':'));
} else
choice = MIN(choice+1, max_choice-1);
} else if (key == KEY_PPAGE) {
scrollok (menu, TRUE);
for (i=0; (i < max_choice); i++) {
if (scroll > 0) {
wscrl (menu, -1);
scroll--;
print_item (menu, items[scroll]->name, 0, FALSE,
(items[scroll]->tag[0] != ':'));
} else {
if (choice > 0)
choice--;
}
}
scrollok (menu, FALSE);
} else if (key == KEY_NPAGE) {
for (i=0; (i < max_choice); i++) {
if (scroll+max_choice < item_no) {
scrollok (menu, TRUE);
scroll(menu);
scrollok (menu, FALSE);
scroll++;
print_item (menu, items[scroll + max_choice - 1]->name,
max_choice-1, FALSE,
(items[scroll + max_choice - 1]->tag[0] != ':'));
} else {
if (choice+1 < max_choice)
choice++;
}
}
} else
choice = i;
print_item (menu, items[scroll + choice]->name, choice, TRUE,
(items[scroll + choice]->tag[0] != ':'));
print_arrows(dialog, item_no, scroll,
box_y, box_x+item_x+1, menu_height);
wnoutrefresh (dialog);
wrefresh (menu);
continue; /* wait for another key press */
}
switch (key) {
case KEY_LEFT:
case TAB:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 2 : (button > 2 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh (menu);
break;
case ' ':
case 's':
case 'y':
case 'n':
case 'm':
case '/':
/* save scroll info */
if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
fprintf(f,"%d\n",scroll);
fclose(f);
}
delwin (dialog);
items[scroll + choice]->selected = 1;
switch (key) {
case 's': return 3;
case 'y': return 3;
case 'n': return 4;
case 'm': return 5;
case ' ': return 6;
case '/': return 7;
}
return 0;
case 'h':
case '?':
button = 2;
case '\n':
delwin (dialog);
items[scroll + choice]->selected = 1;
remove("lxdialog.scrltmp");
return button;
case 'e':
case 'x':
key = ESC;
case ESC:
break;
}
}
delwin (dialog);
remove("lxdialog.scrltmp");
return -1; /* ESC pressed */
} }

View File

@ -21,463 +21,324 @@
#include "dialog.h" #include "dialog.h"
static void back_lines (int n); static void back_lines(int n);
static void print_page (WINDOW * win, int height, int width); static void print_page(WINDOW * win, int height, int width);
static void print_line (WINDOW * win, int row, int width); static void print_line(WINDOW * win, int row, int width);
static char *get_line (void); static char *get_line(void);
static void print_position (WINDOW * win, int height, int width); static void print_position(WINDOW * win);
static int hscroll;
static int begin_reached, end_reached, page_length;
static const char *buf;
static const char *page;
/*
* refresh window content
*/
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
int cur_y, int cur_x)
{
print_page(box, boxh, boxw);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
static int hscroll, fd, file_size, bytes_read;
static int begin_reached = 1, end_reached, page_length;
static char *buf, *page;
/* /*
* Display text from a file in a dialog box. * Display text from a file in a dialog box.
*/ */
int int dialog_textbox(const char *title, const char *tbuf,
dialog_textbox (const char *title, const char *file, int height, int width) int initial_height, int initial_width)
{ {
int i, x, y, cur_x, cur_y, fpos, key = 0; int i, x, y, cur_x, cur_y, key = 0;
int passed_end; int height, width, boxh, boxw;
char search_term[MAX_LEN + 1]; int passed_end;
WINDOW *dialog, *text; WINDOW *dialog, *box;
search_term[0] = '\0'; /* no search term entered yet */ begin_reached = 1;
end_reached = 0;
page_length = 0;
hscroll = 0;
buf = tbuf;
page = buf; /* page is pointer to start of page to be displayed */
/* Open input file for reading */ do_resize:
if ((fd = open (file, O_RDONLY)) == -1) { getmaxyx(stdscr, height, width);
endwin (); if (height < 8 || width < 8)
fprintf (stderr, return -ERRDISPLAYTOOSMALL;
"\nCan't open input file in dialog_textbox().\n"); if (initial_height != 0)
exit (-1); height = initial_height;
} else
/* Get file size. Actually, 'file_size' is the real file size - 1, if (height > 4)
since it's only the last byte offset from the beginning */ height -= 4;
if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { else
endwin (); height = 0;
fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); if (initial_width != 0)
exit (-1); width = initial_width;
} else
/* Restore file pointer to beginning of file after getting file size */ if (width > 5)
if (lseek (fd, 0, SEEK_SET) == -1) { width -= 5;
endwin (); else
fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); width = 0;
exit (-1);
}
/* Allocate space for read buffer */
if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
endwin ();
fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
exit (-1);
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr, "\nError reading file in dialog_textbox().\n");
exit (-1);
}
buf[bytes_read] = '\0'; /* mark end of valid data */
page = buf; /* page is pointer to start of page to be displayed */
/* center dialog box on screen */ /* center dialog box on screen */
x = (COLS - width) / 2; x = (COLS - width) / 2;
y = (LINES - height) / 2; y = (LINES - height) / 2;
draw_shadow(stdscr, y, x, height, width);
draw_shadow (stdscr, y, x, height, width); dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
dialog = newwin (height, width, y, x); /* Create window for box region, used for scrolling text */
keypad (dialog, TRUE); boxh = height - 4;
boxw = width - 2;
box = subwin(dialog, boxh, boxw, y + 1, x + 1);
wattrset(box, dlg.dialog.atr);
wbkgdset(box, dlg.dialog.atr & A_COLOR);
/* Create window for text region, used for scrolling text */ keypad(box, TRUE);
text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
wattrset (text, dialog_attr);
wbkgdset (text, dialog_attr & A_COLOR);
keypad (text, TRUE); /* register the new window, along with its borders */
draw_box(dialog, 0, 0, height, width,
dlg.dialog.atr, dlg.border.atr);
/* register the new window, along with its borders */ wattrset(dialog, dlg.border.atr);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); mvwaddch(dialog, height - 3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dlg.dialog.atr);
wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
waddch(dialog, ACS_RTEE);
wattrset (dialog, border_attr); print_title(dialog, title, width);
mvwaddch (dialog, height-3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
wbkgdset (dialog, dialog_attr & A_COLOR);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) { print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
/* truncate long title -- mec */ wnoutrefresh(dialog);
char * title2 = malloc(width-2+1); getyx(dialog, cur_y, cur_x); /* Save cursor position */
memcpy( title2, title, width-2 );
title2[width-2] = '\0';
title = title2;
}
if (title != NULL) { /* Print first page of text */
wattrset (dialog, title_attr); attr_clear(box, boxh, boxw, dlg.dialog.atr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
wnoutrefresh (dialog);
getyx (dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */ while ((key != KEY_ESC) && (key != '\n')) {
attr_clear (text, height - 4, width - 2, dialog_attr); key = wgetch(dialog);
print_page (text, height - 4, width - 2); switch (key) {
print_position (dialog, height, width); case 'E': /* Exit */
wmove (dialog, cur_y, cur_x); /* Restore cursor position */ case 'e':
wrefresh (dialog); case 'X':
case 'x':
delwin(box);
delwin(dialog);
return 0;
case 'g': /* First page */
case KEY_HOME:
if (!begin_reached) {
begin_reached = 1;
page = buf;
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
}
break;
case 'G': /* Last page */
case KEY_END:
while ((key != ESC) && (key != '\n')) { end_reached = 1;
key = wgetch (dialog); /* point to last char in buf */
switch (key) { page = buf + strlen(buf);
case 'E': /* Exit */ back_lines(boxh);
case 'e': refresh_text_box(dialog, box, boxh, boxw,
case 'X': cur_y, cur_x);
case 'x': break;
delwin (dialog); case 'K': /* Previous line */
free (buf); case 'k':
close (fd); case KEY_UP:
return 0; if (!begin_reached) {
case 'g': /* First page */ back_lines(page_length + 1);
case KEY_HOME:
if (!begin_reached) { /* We don't call print_page() here but use
begin_reached = 1; * scrolling to ensure faster screen update.
/* First page not in buffer? */ * However, 'end_reached' and 'page_length'
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { * should still be updated, and 'page' should
endwin (); * point to start of next page. This is done
fprintf (stderr, * by calling get_line() in the following
"\nError moving file pointer in dialog_textbox().\n"); * 'for' loop. */
exit (-1); scrollok(box, TRUE);
wscrl(box, -1); /* Scroll box region down one line */
scrollok(box, FALSE);
page_length = 0;
passed_end = 0;
for (i = 0; i < boxh; i++) {
if (!i) {
/* print first line of page */
print_line(box, 0, boxw);
wnoutrefresh(box);
} else
/* Called to update 'end_reached' and 'page' */
get_line();
if (!passed_end)
page_length++;
if (end_reached && !passed_end)
passed_end = 1;
}
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
break;
case 'B': /* Previous page */
case 'b':
case KEY_PPAGE:
if (begin_reached)
break;
back_lines(page_length + boxh);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
break;
case 'J': /* Next line */
case 'j':
case KEY_DOWN:
if (!end_reached) {
begin_reached = 0;
scrollok(box, TRUE);
scroll(box); /* Scroll box region up one line */
scrollok(box, FALSE);
print_line(box, boxh - 1, boxw);
wnoutrefresh(box);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
break;
case KEY_NPAGE: /* Next page */
case ' ':
if (end_reached)
break;
begin_reached = 0;
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
case 'h':
case KEY_LEFT:
if (hscroll <= 0)
break;
if (key == '0')
hscroll = 0;
else
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
break;
case 'L': /* Scroll right */
case 'l':
case KEY_RIGHT:
if (hscroll >= MAX_LEN)
break;
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
break;
case KEY_ESC:
key = on_key_esc(dialog);
break;
case KEY_RESIZE:
back_lines(height);
delwin(box);
delwin(dialog);
on_key_resize();
goto do_resize;
} }
if (fpos > bytes_read) { /* Yes, we have to read it in */
if (lseek (fd, 0, SEEK_SET) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in "
"dialog_textbox().\n");
exit (-1);
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr,
"\nError reading file in dialog_textbox().\n");
exit (-1);
}
buf[bytes_read] = '\0';
}
page = buf;
print_page (text, height - 4, width - 2);
print_position (dialog, height, width);
wmove (dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh (dialog);
}
break;
case 'G': /* Last page */
case KEY_END:
end_reached = 1;
/* Last page not in buffer? */
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr,
"\nError moving file pointer in dialog_textbox().\n");
exit (-1);
}
if (fpos < file_size) { /* Yes, we have to read it in */
if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
endwin ();
fprintf (stderr,
"\nError moving file pointer in dialog_textbox().\n");
exit (-1);
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr,
"\nError reading file in dialog_textbox().\n");
exit (-1);
}
buf[bytes_read] = '\0';
}
page = buf + bytes_read;
back_lines (height - 4);
print_page (text, height - 4, width - 2);
print_position (dialog, height, width);
wmove (dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh (dialog);
break;
case 'K': /* Previous line */
case 'k':
case KEY_UP:
if (!begin_reached) {
back_lines (page_length + 1);
/* We don't call print_page() here but use scrolling to ensure
faster screen update. However, 'end_reached' and
'page_length' should still be updated, and 'page' should
point to start of next page. This is done by calling
get_line() in the following 'for' loop. */
scrollok (text, TRUE);
wscrl (text, -1); /* Scroll text region down one line */
scrollok (text, FALSE);
page_length = 0;
passed_end = 0;
for (i = 0; i < height - 4; i++) {
if (!i) {
/* print first line of page */
print_line (text, 0, width - 2);
wnoutrefresh (text);
} else
/* Called to update 'end_reached' and 'page' */
get_line ();
if (!passed_end)
page_length++;
if (end_reached && !passed_end)
passed_end = 1;
}
print_position (dialog, height, width);
wmove (dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh (dialog);
}
break;
case 'B': /* Previous page */
case 'b':
case KEY_PPAGE:
if (begin_reached)
break;
back_lines (page_length + height - 4);
print_page (text, height - 4, width - 2);
print_position (dialog, height, width);
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case 'J': /* Next line */
case 'j':
case KEY_DOWN:
if (!end_reached) {
begin_reached = 0;
scrollok (text, TRUE);
scroll (text); /* Scroll text region up one line */
scrollok (text, FALSE);
print_line (text, height - 5, width - 2);
wnoutrefresh (text);
print_position (dialog, height, width);
wmove (dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh (dialog);
}
break;
case KEY_NPAGE: /* Next page */
case ' ':
if (end_reached)
break;
begin_reached = 0;
print_page (text, height - 4, width - 2);
print_position (dialog, height, width);
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
case 'h':
case KEY_LEFT:
if (hscroll <= 0)
break;
if (key == '0')
hscroll = 0;
else
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines (page_length);
print_page (text, height - 4, width - 2);
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case 'L': /* Scroll right */
case 'l':
case KEY_RIGHT:
if (hscroll >= MAX_LEN)
break;
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines (page_length);
print_page (text, height - 4, width - 2);
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case ESC:
break;
} }
} delwin(box);
delwin(dialog);
delwin (dialog); return key; /* ESC pressed */
free (buf);
close (fd);
return 1; /* ESC pressed */
} }
/* /*
* Go back 'n' lines in text file. Called by dialog_textbox(). * Go back 'n' lines in text. Called by dialog_textbox().
* 'page' will be updated to point to the desired line in 'buf'. * 'page' will be updated to point to the desired line in 'buf'.
*/ */
static void static void back_lines(int n)
back_lines (int n)
{ {
int i, fpos; int i;
begin_reached = 0; begin_reached = 0;
/* We have to distinguish between end_reached and !end_reached /* Go back 'n' lines */
since at end of file, the line is not ended by a '\n'. for (i = 0; i < n; i++) {
The code inside 'if' basically does a '--page' to move one if (*page == '\0') {
character backward so as to skip '\n' of the previous line */ if (end_reached) {
if (!end_reached) { end_reached = 0;
/* Either beginning of buffer or beginning of file reached? */ continue;
if (page == buf) {
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in "
"back_lines().\n");
exit (-1);
}
if (fpos > bytes_read) { /* Not beginning of file yet */
/* We've reached beginning of buffer, but not beginning of
file yet, so read previous part of file into buffer.
Note that we only move backward for BUF_SIZE/2 bytes,
but not BUF_SIZE bytes to avoid re-reading again in
print_page() later */
/* Really possible to move backward BUF_SIZE/2 bytes? */
if (fpos < BUF_SIZE / 2 + bytes_read) {
/* No, move less then */
if (lseek (fd, 0, SEEK_SET) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in "
"back_lines().\n");
exit (-1);
}
page = buf + fpos - bytes_read;
} else { /* Move backward BUF_SIZE/2 bytes */
if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
== -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer "
"in back_lines().\n");
exit (-1);
}
page = buf + BUF_SIZE / 2;
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr, "\nError reading file in back_lines().\n");
exit (-1);
}
buf[bytes_read] = '\0';
} else { /* Beginning of file reached */
begin_reached = 1;
return;
}
}
if (*(--page) != '\n') { /* '--page' here */
/* Something's wrong... */
endwin ();
fprintf (stderr, "\nInternal error in back_lines().\n");
exit (-1);
}
}
/* Go back 'n' lines */
for (i = 0; i < n; i++)
do {
if (page == buf) {
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr,
"\nError moving file pointer in back_lines().\n");
exit (-1);
}
if (fpos > bytes_read) {
/* Really possible to move backward BUF_SIZE/2 bytes? */
if (fpos < BUF_SIZE / 2 + bytes_read) {
/* No, move less then */
if (lseek (fd, 0, SEEK_SET) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer "
"in back_lines().\n");
exit (-1);
} }
page = buf + fpos - bytes_read;
} else { /* Move backward BUF_SIZE/2 bytes */
if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
SEEK_CUR) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer"
" in back_lines().\n");
exit (-1);
}
page = buf + BUF_SIZE / 2;
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr, "\nError reading file in "
"back_lines().\n");
exit (-1);
}
buf[bytes_read] = '\0';
} else { /* Beginning of file reached */
begin_reached = 1;
return;
} }
} if (page == buf) {
} while (*(--page) != '\n'); begin_reached = 1;
page++; return;
}
page--;
do {
if (page == buf) {
begin_reached = 1;
return;
}
page--;
} while (*page != '\n');
page++;
}
} }
/* /*
* Print a new page of text. Called by dialog_textbox(). * Print a new page of text. Called by dialog_textbox().
*/ */
static void static void print_page(WINDOW * win, int height, int width)
print_page (WINDOW * win, int height, int width)
{ {
int i, passed_end = 0; int i, passed_end = 0;
page_length = 0; page_length = 0;
for (i = 0; i < height; i++) { for (i = 0; i < height; i++) {
print_line (win, i, width); print_line(win, i, width);
if (!passed_end) if (!passed_end)
page_length++; page_length++;
if (end_reached && !passed_end) if (end_reached && !passed_end)
passed_end = 1; passed_end = 1;
} }
wnoutrefresh (win); wnoutrefresh(win);
} }
/* /*
* Print a new line of text. Called by dialog_textbox() and print_page(). * Print a new line of text. Called by dialog_textbox() and print_page().
*/ */
static void static void print_line(WINDOW * win, int row, int width)
print_line (WINDOW * win, int row, int width)
{ {
int y, x; int y, x;
char *line; char *line;
line = get_line (); line = get_line();
line += MIN (strlen (line), hscroll); /* Scroll horizontally */ line += MIN(strlen(line), hscroll); /* Scroll horizontally */
wmove (win, row, 0); /* move cursor to correct line */ wmove(win, row, 0); /* move cursor to correct line */
waddch (win, ' '); waddch(win, ' ');
waddnstr (win, line, MIN (strlen (line), width - 2)); waddnstr(win, line, MIN(strlen(line), width - 2));
getyx (win, y, x); getyx(win, y, x);
/* Clear 'residue' of previous line */ /* Clear 'residue' of previous line */
#if OLD_NCURSES #if OLD_NCURSES
{ {
int i; int i;
for (i = 0; i < width - x; i++) for (i = 0; i < width - x; i++)
waddch (win, ' '); waddch(win, ' ');
} }
#else #else
wclrtoeol(win); wclrtoeol(win);
#endif #endif
} }
@ -486,71 +347,45 @@ print_line (WINDOW * win, int row, int width)
* 'page' should point to start of current line before calling, and will be * 'page' should point to start of current line before calling, and will be
* updated to point to start of next line. * updated to point to start of next line.
*/ */
static char * static char *get_line(void)
get_line (void)
{ {
int i = 0, fpos; int i = 0;
static char line[MAX_LEN + 1]; static char line[MAX_LEN + 1];
end_reached = 0; end_reached = 0;
while (*page != '\n') { while (*page != '\n') {
if (*page == '\0') { if (*page == '\0') {
/* Either end of file or end of buffer reached */ if (!end_reached) {
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { end_reached = 1;
endwin (); break;
fprintf (stderr, "\nError moving file pointer in " }
"get_line().\n"); } else if (i < MAX_LEN)
exit (-1); line[i++] = *(page++);
} else {
if (fpos < file_size) { /* Not end of file yet */ /* Truncate lines longer than MAX_LEN characters */
/* We've reached end of buffer, but not end of file yet, if (i == MAX_LEN)
so read next part of file into buffer */ line[i++] = '\0';
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { page++;
endwin ();
fprintf (stderr, "\nError reading file in get_line().\n");
exit (-1);
} }
buf[bytes_read] = '\0';
page = buf;
} else {
if (!end_reached)
end_reached = 1;
break;
}
} else if (i < MAX_LEN)
line[i++] = *(page++);
else {
/* Truncate lines longer than MAX_LEN characters */
if (i == MAX_LEN)
line[i++] = '\0';
page++;
} }
} if (i <= MAX_LEN)
if (i <= MAX_LEN) line[i] = '\0';
line[i] = '\0'; if (!end_reached)
if (!end_reached) page++; /* move pass '\n' */
page++; /* move pass '\n' */
return line; return line;
} }
/* /*
* Print current position * Print current position
*/ */
static void static void print_position(WINDOW * win)
print_position (WINDOW * win, int height, int width)
{ {
int fpos, percent; int percent;
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { wattrset(win, dlg.position_indicator.atr);
endwin (); wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
fprintf (stderr, "\nError moving file pointer in print_position().\n"); percent = (page - buf) * 100 / strlen(buf);
exit (-1); wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
} wprintw(win, "(%3d%%)", percent);
wattrset (win, position_indicator_attr);
wbkgdset (win, position_indicator_attr & A_COLOR);
percent = !file_size ?
100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
wmove (win, height - 3, width - 9);
wprintw (win, "(%3d%%)", percent);
} }

View File

@ -21,172 +21,287 @@
#include "dialog.h" #include "dialog.h"
struct dialog_info dlg;
/* use colors by default? */ static void set_mono_theme(void)
bool use_colors = 1;
const char *backtitle = NULL;
const char *dialog_result;
/*
* Attribute values, default is for mono display
*/
chtype attributes[] =
{ {
A_NORMAL, /* screen_attr */ dlg.screen.atr = A_NORMAL;
A_NORMAL, /* shadow_attr */ dlg.shadow.atr = A_NORMAL;
A_NORMAL, /* dialog_attr */ dlg.dialog.atr = A_NORMAL;
A_BOLD, /* title_attr */ dlg.title.atr = A_BOLD;
A_NORMAL, /* border_attr */ dlg.border.atr = A_NORMAL;
A_REVERSE, /* button_active_attr */ dlg.button_active.atr = A_REVERSE;
A_DIM, /* button_inactive_attr */ dlg.button_inactive.atr = A_DIM;
A_REVERSE, /* button_key_active_attr */ dlg.button_key_active.atr = A_REVERSE;
A_BOLD, /* button_key_inactive_attr */ dlg.button_key_inactive.atr = A_BOLD;
A_REVERSE, /* button_label_active_attr */ dlg.button_label_active.atr = A_REVERSE;
A_NORMAL, /* button_label_inactive_attr */ dlg.button_label_inactive.atr = A_NORMAL;
A_NORMAL, /* inputbox_attr */ dlg.inputbox.atr = A_NORMAL;
A_NORMAL, /* inputbox_border_attr */ dlg.inputbox_border.atr = A_NORMAL;
A_NORMAL, /* searchbox_attr */ dlg.searchbox.atr = A_NORMAL;
A_BOLD, /* searchbox_title_attr */ dlg.searchbox_title.atr = A_BOLD;
A_NORMAL, /* searchbox_border_attr */ dlg.searchbox_border.atr = A_NORMAL;
A_BOLD, /* position_indicator_attr */ dlg.position_indicator.atr = A_BOLD;
A_NORMAL, /* menubox_attr */ dlg.menubox.atr = A_NORMAL;
A_NORMAL, /* menubox_border_attr */ dlg.menubox_border.atr = A_NORMAL;
A_NORMAL, /* item_attr */ dlg.item.atr = A_NORMAL;
A_REVERSE, /* item_selected_attr */ dlg.item_selected.atr = A_REVERSE;
A_BOLD, /* tag_attr */ dlg.tag.atr = A_BOLD;
A_REVERSE, /* tag_selected_attr */ dlg.tag_selected.atr = A_REVERSE;
A_BOLD, /* tag_key_attr */ dlg.tag_key.atr = A_BOLD;
A_REVERSE, /* tag_key_selected_attr */ dlg.tag_key_selected.atr = A_REVERSE;
A_BOLD, /* check_attr */ dlg.check.atr = A_BOLD;
A_REVERSE, /* check_selected_attr */ dlg.check_selected.atr = A_REVERSE;
A_BOLD, /* uarrow_attr */ dlg.uarrow.atr = A_BOLD;
A_BOLD /* darrow_attr */ dlg.darrow.atr = A_BOLD;
};
#include "colors.h"
/*
* Table of color values
*/
int color_table[][3] =
{
{SCREEN_FG, SCREEN_BG, SCREEN_HL},
{SHADOW_FG, SHADOW_BG, SHADOW_HL},
{DIALOG_FG, DIALOG_BG, DIALOG_HL},
{TITLE_FG, TITLE_BG, TITLE_HL},
{BORDER_FG, BORDER_BG, BORDER_HL},
{BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
{BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
{BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
{BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
{BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
{BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
BUTTON_LABEL_INACTIVE_HL},
{INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
{INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
{SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
{SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
{SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
{POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
{MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
{MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
{ITEM_FG, ITEM_BG, ITEM_HL},
{ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
{TAG_FG, TAG_BG, TAG_HL},
{TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
{TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
{TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
{CHECK_FG, CHECK_BG, CHECK_HL},
{CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
{UARROW_FG, UARROW_BG, UARROW_HL},
{DARROW_FG, DARROW_BG, DARROW_HL},
}; /* color_table */
/*
* Set window to attribute 'attr'
*/
void
attr_clear (WINDOW * win, int height, int width, chtype attr)
{
int i, j;
wattrset (win, attr);
for (i = 0; i < height; i++) {
wmove (win, i, 0);
for (j = 0; j < width; j++)
waddch (win, ' ');
}
touchwin (win);
} }
void dialog_clear (void) #define DLG_COLOR(dialog, f, b, h) \
{ do { \
attr_clear (stdscr, LINES, COLS, screen_attr); dlg.dialog.fg = (f); \
/* Display background title if it exists ... - SLH */ dlg.dialog.bg = (b); \
if (backtitle != NULL) { dlg.dialog.hl = (h); \
int i; } while (0)
static void set_classic_theme(void)
{
DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true);
DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true);
DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true);
DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true);
DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true);
DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false);
DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true);
DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true);
DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true);
DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true);
DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true);
DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true);
DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true);
}
static void set_blackbg_theme(void)
{
DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true);
DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false);
DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true);
DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false);
DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true);
DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true);
DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true);
DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true);
DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false);
DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false);
DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true);
DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true);
DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true);
DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
}
static void set_bluetitle_theme(void)
{
set_classic_theme();
DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true);
DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true);
wattrset (stdscr, screen_attr);
mvwaddstr (stdscr, 0, 1, (char *)backtitle);
wmove (stdscr, 1, 1);
for (i = 1; i < COLS - 1; i++)
waddch (stdscr, ACS_HLINE);
}
wnoutrefresh (stdscr);
} }
/* /*
* Do some initialization for dialog * Select color theme
*/ */
void static int set_theme(const char *theme)
init_dialog (void)
{ {
initscr (); /* Init curses */ int use_color = 1;
keypad (stdscr, TRUE); if (!theme)
cbreak (); set_bluetitle_theme();
noecho (); else if (strcmp(theme, "classic") == 0)
set_classic_theme();
else if (strcmp(theme, "bluetitle") == 0)
set_bluetitle_theme();
else if (strcmp(theme, "blackbg") == 0)
set_blackbg_theme();
else if (strcmp(theme, "mono") == 0)
use_color = 0;
return use_color;
}
if (use_colors) /* Set up colors */ static void init_one_color(struct dialog_color *color)
color_setup (); {
static int pair = 0;
pair++;
init_pair(pair, color->fg, color->bg);
if (color->hl)
color->atr = A_BOLD | COLOR_PAIR(pair);
else
color->atr = COLOR_PAIR(pair);
}
dialog_clear (); static void init_dialog_colors(void)
{
init_one_color(&dlg.screen);
init_one_color(&dlg.shadow);
init_one_color(&dlg.dialog);
init_one_color(&dlg.title);
init_one_color(&dlg.border);
init_one_color(&dlg.button_active);
init_one_color(&dlg.button_inactive);
init_one_color(&dlg.button_key_active);
init_one_color(&dlg.button_key_inactive);
init_one_color(&dlg.button_label_active);
init_one_color(&dlg.button_label_inactive);
init_one_color(&dlg.inputbox);
init_one_color(&dlg.inputbox_border);
init_one_color(&dlg.searchbox);
init_one_color(&dlg.searchbox_title);
init_one_color(&dlg.searchbox_border);
init_one_color(&dlg.position_indicator);
init_one_color(&dlg.menubox);
init_one_color(&dlg.menubox_border);
init_one_color(&dlg.item);
init_one_color(&dlg.item_selected);
init_one_color(&dlg.tag);
init_one_color(&dlg.tag_selected);
init_one_color(&dlg.tag_key);
init_one_color(&dlg.tag_key_selected);
init_one_color(&dlg.check);
init_one_color(&dlg.check_selected);
init_one_color(&dlg.uarrow);
init_one_color(&dlg.darrow);
} }
/* /*
* Setup for color display * Setup for color display
*/ */
void static void color_setup(const char *theme)
color_setup (void)
{ {
int i; int use_color;
if (has_colors ()) { /* Terminal supports color? */ use_color = set_theme(theme);
start_color (); if (use_color && has_colors()) {
start_color();
init_dialog_colors();
} else
set_mono_theme();
}
/* Initialize color pairs */ /*
for (i = 0; i < ATTRIBUTE_COUNT; i++) * Set window to attribute 'attr'
init_pair (i + 1, color_table[i][0], color_table[i][1]); */
void attr_clear(WINDOW * win, int height, int width, chtype attr)
{
int i, j;
/* Setup color attributes */ wattrset(win, attr);
for (i = 0; i < ATTRIBUTE_COUNT; i++) for (i = 0; i < height; i++) {
attributes[i] = C_ATTR (color_table[i][2], i + 1); wmove(win, i, 0);
} for (j = 0; j < width; j++)
waddch(win, ' ');
}
touchwin(win);
}
void dialog_clear(void)
{
attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
/* Display background title if it exists ... - SLH */
if (dlg.backtitle != NULL) {
int i;
wattrset(stdscr, dlg.screen.atr);
mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
wmove(stdscr, 1, 1);
for (i = 1; i < COLS - 1; i++)
waddch(stdscr, ACS_HLINE);
}
wnoutrefresh(stdscr);
}
/*
* Do some initialization for dialog
*/
void init_dialog(const char *backtitle)
{
dlg.backtitle = backtitle;
color_setup(getenv("MENUCONFIG_COLOR"));
}
void reset_dialog(void)
{
initscr(); /* Init curses */
keypad(stdscr, TRUE);
cbreak();
noecho();
dialog_clear();
} }
/* /*
* End using dialog functions. * End using dialog functions.
*/ */
void void end_dialog(void)
end_dialog (void)
{ {
endwin (); endwin();
} }
/* Print the title of the dialog. Center the title and truncate
* tile if wider than dialog (- 2 chars).
**/
void print_title(WINDOW *dialog, const char *title, int width)
{
if (title) {
int tlen = MIN(width - 2, strlen(title));
wattrset(dialog, dlg.title.atr);
mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
waddch(dialog, ' ');
}
}
/* /*
* Print a string of text in a window, automatically wrap around to the * Print a string of text in a window, automatically wrap around to the
@ -194,164 +309,166 @@ end_dialog (void)
* characters '\n' are replaced by spaces. We start on a new line * characters '\n' are replaced by spaces. We start on a new line
* if there is no room for at least 4 nonblanks following a double-space. * if there is no room for at least 4 nonblanks following a double-space.
*/ */
void void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
{ {
int newl, cur_x, cur_y; int newl, cur_x, cur_y;
int i, prompt_len, room, wlen; int i, prompt_len, room, wlen;
char tempstr[MAX_LEN + 1], *word, *sp, *sp2; char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
strcpy (tempstr, prompt); strcpy(tempstr, prompt);
prompt_len = strlen(tempstr); prompt_len = strlen(tempstr);
/*
* Remove newlines
*/
for(i=0; i<prompt_len; i++) {
if(tempstr[i] == '\n') tempstr[i] = ' ';
}
if (prompt_len <= width - x * 2) { /* If prompt is short */ /*
wmove (win, y, (width - prompt_len) / 2); * Remove newlines
waddstr (win, tempstr); */
} else { for (i = 0; i < prompt_len; i++) {
cur_x = x; if (tempstr[i] == '\n')
cur_y = y; tempstr[i] = ' ';
newl = 1; }
word = tempstr;
while (word && *word) { if (prompt_len <= width - x * 2) { /* If prompt is short */
sp = index(word, ' '); wmove(win, y, (width - prompt_len) / 2);
if (sp) waddstr(win, tempstr);
*sp++ = 0; } else {
cur_x = x;
/* Wrap to next line if either the word does not fit, cur_y = y;
or it is the first word of a new sentence, and it is newl = 1;
short, and the next word does not fit. */ word = tempstr;
room = width - cur_x; while (word && *word) {
wlen = strlen(word); sp = index(word, ' ');
if (wlen > room || if (sp)
(newl && wlen < 4 && sp && wlen+1+strlen(sp) > room *sp++ = 0;
&& (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
cur_y++; /* Wrap to next line if either the word does not fit,
cur_x = x; or it is the first word of a new sentence, and it is
} short, and the next word does not fit. */
wmove (win, cur_y, cur_x); room = width - cur_x;
waddstr (win, word); wlen = strlen(word);
getyx (win, cur_y, cur_x); if (wlen > room ||
cur_x++; (newl && wlen < 4 && sp
if (sp && *sp == ' ') { && wlen + 1 + strlen(sp) > room
cur_x++; /* double space */ && (!(sp2 = index(sp, ' '))
while (*++sp == ' '); || wlen + 1 + (sp2 - sp) > room))) {
newl = 1; cur_y++;
} else cur_x = x;
newl = 0; }
word = sp; wmove(win, cur_y, cur_x);
waddstr(win, word);
getyx(win, cur_y, cur_x);
cur_x++;
if (sp && *sp == ' ') {
cur_x++; /* double space */
while (*++sp == ' ') ;
newl = 1;
} else
newl = 0;
word = sp;
}
} }
}
} }
/* /*
* Print a button * Print a button
*/ */
void void print_button(WINDOW * win, const char *label, int y, int x, int selected)
print_button (WINDOW * win, const char *label, int y, int x, int selected)
{ {
int i, temp; int i, temp;
wmove (win, y, x); wmove(win, y, x);
wattrset (win, selected ? button_active_attr : button_inactive_attr); wattrset(win, selected ? dlg.button_active.atr
waddstr (win, "<"); : dlg.button_inactive.atr);
temp = strspn (label, " "); waddstr(win, "<");
label += temp; temp = strspn(label, " ");
wattrset (win, selected ? button_label_active_attr label += temp;
: button_label_inactive_attr); wattrset(win, selected ? dlg.button_label_active.atr
for (i = 0; i < temp; i++) : dlg.button_label_inactive.atr);
waddch (win, ' '); for (i = 0; i < temp; i++)
wattrset (win, selected ? button_key_active_attr waddch(win, ' ');
: button_key_inactive_attr); wattrset(win, selected ? dlg.button_key_active.atr
waddch (win, label[0]); : dlg.button_key_inactive.atr);
wattrset (win, selected ? button_label_active_attr waddch(win, label[0]);
: button_label_inactive_attr); wattrset(win, selected ? dlg.button_label_active.atr
waddstr (win, (char *)label + 1); : dlg.button_label_inactive.atr);
wattrset (win, selected ? button_active_attr : button_inactive_attr); waddstr(win, (char *)label + 1);
waddstr (win, ">"); wattrset(win, selected ? dlg.button_active.atr
wmove (win, y, x + temp + 1); : dlg.button_inactive.atr);
waddstr(win, ">");
wmove(win, y, x + temp + 1);
} }
/* /*
* Draw a rectangular box with line drawing characters * Draw a rectangular box with line drawing characters
*/ */
void void
draw_box (WINDOW * win, int y, int x, int height, int width, draw_box(WINDOW * win, int y, int x, int height, int width,
chtype box, chtype border) chtype box, chtype border)
{ {
int i, j; int i, j;
wattrset (win, 0); wattrset(win, 0);
for (i = 0; i < height; i++) { for (i = 0; i < height; i++) {
wmove (win, y + i, x); wmove(win, y + i, x);
for (j = 0; j < width; j++) for (j = 0; j < width; j++)
if (!i && !j) if (!i && !j)
waddch (win, border | ACS_ULCORNER); waddch(win, border | ACS_ULCORNER);
else if (i == height - 1 && !j) else if (i == height - 1 && !j)
waddch (win, border | ACS_LLCORNER); waddch(win, border | ACS_LLCORNER);
else if (!i && j == width - 1) else if (!i && j == width - 1)
waddch (win, box | ACS_URCORNER); waddch(win, box | ACS_URCORNER);
else if (i == height - 1 && j == width - 1) else if (i == height - 1 && j == width - 1)
waddch (win, box | ACS_LRCORNER); waddch(win, box | ACS_LRCORNER);
else if (!i) else if (!i)
waddch (win, border | ACS_HLINE); waddch(win, border | ACS_HLINE);
else if (i == height - 1) else if (i == height - 1)
waddch (win, box | ACS_HLINE); waddch(win, box | ACS_HLINE);
else if (!j) else if (!j)
waddch (win, border | ACS_VLINE); waddch(win, border | ACS_VLINE);
else if (j == width - 1) else if (j == width - 1)
waddch (win, box | ACS_VLINE); waddch(win, box | ACS_VLINE);
else else
waddch (win, box | ' '); waddch(win, box | ' ');
} }
} }
/* /*
* Draw shadows along the right and bottom edge to give a more 3D look * Draw shadows along the right and bottom edge to give a more 3D look
* to the boxes * to the boxes
*/ */
void void draw_shadow(WINDOW * win, int y, int x, int height, int width)
draw_shadow (WINDOW * win, int y, int x, int height, int width)
{ {
int i; int i;
if (has_colors ()) { /* Whether terminal supports color? */ if (has_colors()) { /* Whether terminal supports color? */
wattrset (win, shadow_attr); wattrset(win, dlg.shadow.atr);
wmove (win, y + height, x + 2); wmove(win, y + height, x + 2);
for (i = 0; i < width; i++) for (i = 0; i < width; i++)
waddch (win, winch (win) & A_CHARTEXT); waddch(win, winch(win) & A_CHARTEXT);
for (i = y + 1; i < y + height + 1; i++) { for (i = y + 1; i < y + height + 1; i++) {
wmove (win, i, x + width); wmove(win, i, x + width);
waddch (win, winch (win) & A_CHARTEXT); waddch(win, winch(win) & A_CHARTEXT);
waddch (win, winch (win) & A_CHARTEXT); waddch(win, winch(win) & A_CHARTEXT);
}
wnoutrefresh(win);
} }
wnoutrefresh (win);
}
} }
/* /*
* Return the position of the first alphabetic character in a string. * Return the position of the first alphabetic character in a string.
*/ */
int int first_alpha(const char *string, const char *exempt)
first_alpha(const char *string, const char *exempt)
{ {
int i, in_paren=0, c; int i, in_paren = 0, c;
for (i = 0; i < strlen(string); i++) { for (i = 0; i < strlen(string); i++) {
c = tolower(string[i]); c = tolower(string[i]);
if (strchr("<[(", c)) ++in_paren; if (strchr("<[(", c))
if (strchr(">])", c) && in_paren > 0) --in_paren; ++in_paren;
if (strchr(">])", c) && in_paren > 0)
--in_paren;
if ((! in_paren) && isalpha(c) && if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
strchr(exempt, c) == 0)
return i; return i;
} }
@ -359,17 +476,165 @@ first_alpha(const char *string, const char *exempt)
} }
/* /*
* Get the first selected item in the dialog_list_item list. * ncurses uses ESC to detect escaped char sequences. This resutl in
* a small timeout before ESC is actually delivered to the application.
* lxdialog suggest <ESC> <ESC> which is correctly translated to two
* times esc. But then we need to ignore the second esc to avoid stepping
* out one menu too much. Filter away all escaped key sequences since
* keypad(FALSE) turn off ncurses support for escape sequences - and thats
* needed to make notimeout() do as expected.
*/ */
struct dialog_list_item * int on_key_esc(WINDOW *win)
first_sel_item(int item_no, struct dialog_list_item ** items)
{ {
int i; int key;
int key2;
int key3;
for (i = 0; i < item_no; i++) { nodelay(win, TRUE);
if (items[i]->selected) keypad(win, FALSE);
return items[i]; key = wgetch(win);
} key2 = wgetch(win);
do {
key3 = wgetch(win);
} while (key3 != ERR);
nodelay(win, FALSE);
keypad(win, TRUE);
if (key == KEY_ESC && key2 == ERR)
return KEY_ESC;
else if (key != ERR && key != KEY_ESC && key2 == ERR)
ungetch(key);
return NULL; return -1;
}
/* redraw screen in new size */
int on_key_resize(void)
{
dialog_clear();
return KEY_RESIZE;
}
struct dialog_list *item_cur;
struct dialog_list item_nil;
struct dialog_list *item_head;
void item_reset(void)
{
struct dialog_list *p, *next;
for (p = item_head; p; p = next) {
next = p->next;
free(p);
}
item_head = NULL;
item_cur = &item_nil;
}
void item_make(const char *fmt, ...)
{
va_list ap;
struct dialog_list *p = malloc(sizeof(*p));
if (item_head)
item_cur->next = p;
else
item_head = p;
item_cur = p;
memset(p, 0, sizeof(*p));
va_start(ap, fmt);
vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
va_end(ap);
}
void item_add_str(const char *fmt, ...)
{
va_list ap;
size_t avail;
avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
va_start(ap, fmt);
vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
avail, fmt, ap);
item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
va_end(ap);
}
void item_set_tag(char tag)
{
item_cur->node.tag = tag;
}
void item_set_data(void *ptr)
{
item_cur->node.data = ptr;
}
void item_set_selected(int val)
{
item_cur->node.selected = val;
}
int item_activate_selected(void)
{
item_foreach()
if (item_is_selected())
return 1;
return 0;
}
void *item_data(void)
{
return item_cur->node.data;
}
char item_tag(void)
{
return item_cur->node.tag;
}
int item_count(void)
{
int n = 0;
struct dialog_list *p;
for (p = item_head; p; p = p->next)
n++;
return n;
}
void item_set(int n)
{
int i = 0;
item_foreach()
if (i++ == n)
return;
}
int item_n(void)
{
int n = 0;
struct dialog_list *p;
for (p = item_head; p; p = p->next) {
if (p == item_cur)
return n;
n++;
}
return 0;
}
const char *item_str(void)
{
return item_cur->node.str;
}
int item_is_selected(void)
{
return (item_cur->node.selected != 0);
}
int item_is_tag(char tag)
{
return (item_cur->node.tag == tag);
} }

View File

@ -24,95 +24,91 @@
/* /*
* Display termination buttons * Display termination buttons
*/ */
static void static void print_buttons(WINDOW * dialog, int height, int width, int selected)
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, " Yes ", y, x, selected == 0);
print_button (dialog, " No ", y, x + 13, selected == 1); print_button(dialog, " No ", y, x + 13, selected == 1);
wmove(dialog, y, x+1 + 13*selected ); wmove(dialog, y, x + 1 + 13 * selected);
wrefresh (dialog); wrefresh(dialog);
} }
/* /*
* Display a dialog box with two buttons - Yes and No * Display a dialog box with two buttons - Yes and No
*/ */
int int dialog_yesno(const char *title, const char *prompt, int height, int width)
dialog_yesno (const char *title, const char *prompt, int height, int width)
{ {
int i, x, y, key = 0, button = 0; int i, x, y, key = 0, button = 0;
WINDOW *dialog; WINDOW *dialog;
/* center dialog box on screen */ do_resize:
x = (COLS - width) / 2; if (getmaxy(stdscr) < (height + 4))
y = (LINES - height) / 2; return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) < (width + 4))
return -ERRDISPLAYTOOSMALL;
draw_shadow (stdscr, y, x, height, width); /* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
dialog = newwin (height, width, y, x); draw_shadow(stdscr, y, x, height, width);
keypad (dialog, TRUE);
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); dialog = newwin(height, width, y, x);
wattrset (dialog, border_attr); keypad(dialog, TRUE);
mvwaddch (dialog, height-3, 0, ACS_LTEE);
for (i = 0; i < width - 2; i++)
waddch (dialog, ACS_HLINE);
wattrset (dialog, dialog_attr);
waddch (dialog, ACS_RTEE);
if (title != NULL && strlen(title) >= width-2 ) { draw_box(dialog, 0, 0, height, width,
/* truncate long title -- mec */ dlg.dialog.atr, dlg.border.atr);
char * title2 = malloc(width-2+1); wattrset(dialog, dlg.border.atr);
memcpy( title2, title, width-2 ); mvwaddch(dialog, height - 3, 0, ACS_LTEE);
title2[width-2] = '\0'; for (i = 0; i < width - 2; i++)
title = title2; waddch(dialog, ACS_HLINE);
} wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
if (title != NULL) { print_title(dialog, title, width);
wattrset (dialog, title_attr);
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
waddstr (dialog, (char *)title);
waddch (dialog, ' ');
}
wattrset (dialog, dialog_attr); wattrset(dialog, dlg.dialog.atr);
print_autowrap (dialog, prompt, width - 2, 1, 3); print_autowrap(dialog, prompt, width - 2, 1, 3);
print_buttons(dialog, height, width, 0); print_buttons(dialog, height, width, 0);
while (key != ESC) { while (key != KEY_ESC) {
key = wgetch (dialog); key = wgetch(dialog);
switch (key) { switch (key) {
case 'Y': case 'Y':
case 'y': case 'y':
delwin (dialog); delwin(dialog);
return 0; return 0;
case 'N': case 'N':
case 'n': case 'n':
delwin (dialog); delwin(dialog);
return 1; return 1;
case TAB: case TAB:
case KEY_LEFT: case KEY_LEFT:
case KEY_RIGHT: case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0) button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);
? 1 : (button > 1 ? 0 : button);
print_buttons(dialog, height, width, button); print_buttons(dialog, height, width, button);
wrefresh (dialog); wrefresh(dialog);
break; break;
case ' ': case ' ':
case '\n': case '\n':
delwin (dialog); delwin(dialog);
return button; return button;
case ESC: case KEY_ESC:
break; key = on_key_esc(dialog);
break;
case KEY_RESIZE:
delwin(dialog);
on_key_resize();
goto do_resize;
}
} }
}
delwin (dialog); delwin(dialog);
return -1; /* ESC pressed */ return key; /* ESC pressed */
} }

View File

@ -5,13 +5,11 @@
* Introduced single menu mode (show all sub-menus in one large tree). * Introduced single menu mode (show all sub-menus in one large tree).
* 2002-11-06 Petr Baudis <pasky@ucw.cz> * 2002-11-06 Petr Baudis <pasky@ucw.cz>
* *
* Directly use liblxdialog library routines. * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* 2002-11-14 Petr Baudis <pasky@ucw.cz>
*/ */
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/termios.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -22,14 +20,14 @@
#include <string.h> #include <string.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
#include <locale.h>
#include "lxdialog/dialog.h"
#define LKC_DIRECT_LINK #define LKC_DIRECT_LINK
#include "lkc.h" #include "lkc.h"
#include "lxdialog/dialog.h"
static char menu_backtitle[128]; static char menu_backtitle[128];
static const char mconf_readme[] = static const char mconf_readme[] = N_(
"Overview\n" "Overview\n"
"--------\n" "--------\n"
"Some features may be built directly into Buildroot. Some features\n" "Some features may be built directly into Buildroot. Some features\n"
@ -160,39 +158,53 @@ static const char mconf_readme[] =
"\n" "\n"
"Note that this mode can eventually be a little more CPU expensive\n" "Note that this mode can eventually be a little more CPU expensive\n"
"(especially with a larger number of unrolled categories) than the\n" "(especially with a larger number of unrolled categories) than the\n"
"default mode.\n", "default mode.\n"
menu_instructions[] = "\n"
"Different color themes available\n"
"--------------------------------\n"
"It is possible to select different color themes using the variable\n"
"MENUCONFIG_COLOR. To select a theme use:\n"
"\n"
"make MENUCONFIG_COLOR=<theme> menuconfig\n"
"\n"
"Available themes are\n"
" mono => selects colors suitable for monochrome displays\n"
" blackbg => selects a color scheme with black background\n"
" classic => theme with blue background. The classic look\n"
" bluetitle => a LCD friendly version of classic. (default)\n"
"\n"),
menu_instructions[] = N_(
"Arrow keys navigate the menu. " "Arrow keys navigate the menu. "
"<Enter> selects submenus --->. " "<Enter> selects submenus --->. "
"Highlighted letters are hotkeys. " "Highlighted letters are hotkeys. "
"Pressing <Y> selectes a feature, while <N> will exclude a feature. " "Pressing <Y> selectes a feature, while <N> will exclude a feature. "
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. " "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
"Legend: [*] feature is selected [ ] feature is excluded", "Legend: [*] feature is selected [ ] feature is excluded"),
radiolist_instructions[] = radiolist_instructions[] = N_(
"Use the arrow keys to navigate this window or " "Use the arrow keys to navigate this window or "
"press the hotkey of the item you wish to select " "press the hotkey of the item you wish to select "
"followed by the <SPACE BAR>. " "followed by the <SPACE BAR>. "
"Press <?> for additional information about this option.", "Press <?> for additional information about this option."),
inputbox_instructions_int[] = inputbox_instructions_int[] = N_(
"Please enter a decimal value. " "Please enter a decimal value. "
"Fractions will not be accepted. " "Fractions will not be accepted. "
"Use the <TAB> key to move from the input field to the buttons below it.", "Use the <TAB> key to move from the input field to the buttons below it."),
inputbox_instructions_hex[] = inputbox_instructions_hex[] = N_(
"Please enter a hexadecimal value. " "Please enter a hexadecimal value. "
"Use the <TAB> key to move from the input field to the buttons below it.", "Use the <TAB> key to move from the input field to the buttons below it."),
inputbox_instructions_string[] = inputbox_instructions_string[] = N_(
"Please enter a string value. " "Please enter a string value. "
"Use the <TAB> key to move from the input field to the buttons below it.", "Use the <TAB> key to move from the input field to the buttons below it."),
setmod_text[] = setmod_text[] = N_(
"This feature depends on another which has been configured as a module.\n" "This feature depends on another which has been configured as a module.\n"
"As a result, this feature will be built as a module.", "As a result, this feature will be built as a module."),
nohelp_text[] = nohelp_text[] = N_(
"There is no help available for this option.\n", "There is no help available for this option.\n"),
load_config_text[] = load_config_text[] = N_(
"Enter the name of the configuration file you wish to load. " "Enter the name of the configuration file you wish to load. "
"Accept the name shown to restore the configuration you " "Accept the name shown to restore the configuration you "
"last retrieved. Leave blank to abort.", "last retrieved. Leave blank to abort."),
load_config_help[] = load_config_help[] = N_(
"\n" "\n"
"For various reasons, one may wish to keep several different Buildroot\n" "For various reasons, one may wish to keep several different Buildroot\n"
"configurations available on a single machine.\n" "configurations available on a single machine.\n"
@ -202,11 +214,11 @@ load_config_help[] =
"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"
"configuration files. You should therefor leave this blank to abort.\n", "configuration files. You should therefor leave this blank to abort.\n"),
save_config_text[] = save_config_text[] = N_(
"Enter a filename to which this configuration should be saved " "Enter a filename to which this configuration should be saved "
"as an alternate. Leave blank to abort.", "as an alternate. Leave blank to abort."),
save_config_help[] = save_config_help[] = N_(
"\n" "\n"
"For various reasons, one may wish to keep different Buildroot\n" "For various reasons, one may wish to keep different Buildroot\n"
"configurations available on a single machine.\n" "configurations available on a single machine.\n"
@ -216,10 +228,11 @@ save_config_help[] =
"configuration options you have selected at that time.\n" "configuration options you have selected at that time.\n"
"\n" "\n"
"If you are uncertain what all this means then you should probably\n" "If you are uncertain what all this means then you should probably\n"
"leave this blank.\n", "leave this blank.\n"),
search_help[] = search_help[] = N_(
"\n" "\n"
"Search for CONFIG_ symbols and display their relations.\n" "Search for CONFIG_ symbols and display their relations.\n"
"Regular expressions are allowed.\n"
"Example: search for \"^FOO\"\n" "Example: search for \"^FOO\"\n"
"Result:\n" "Result:\n"
"-----------------------------------------------------------------\n" "-----------------------------------------------------------------\n"
@ -254,7 +267,7 @@ search_help[] =
"Examples: USB => find all CONFIG_ symbols containing USB\n" "Examples: USB => find all CONFIG_ symbols containing USB\n"
" ^USB => find all CONFIG_ symbols starting with USB\n" " ^USB => find all CONFIG_ symbols starting with USB\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 char filename[PATH_MAX+1] = ".config";
static int indent; static int indent;
@ -264,9 +277,6 @@ static struct menu *current_menu;
static int child_count; static int child_count;
static int single_menu_mode; static int single_menu_mode;
static struct dialog_list_item *items[16384]; /* FIXME: This ought to be dynamic. */
static int item_no;
static void conf(struct menu *menu); static void conf(struct menu *menu);
static void conf_choice(struct menu *menu); static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu); static void conf_string(struct menu *menu);
@ -275,7 +285,6 @@ static void conf_save(void);
static void show_textbox(const char *title, const char *text, int r, int c); 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 show_file(const char *filename, const char *title, int r, int c);
static void init_wsize(void) static void init_wsize(void)
{ {
@ -303,8 +312,8 @@ static void init_wsize(void)
} }
if (rows < 19 || cols < 80) { if (rows < 19 || cols < 80) {
fprintf(stderr, "Your display is too small to run Menuconfig!\n"); fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
exit(1); exit(1);
} }
@ -312,65 +321,6 @@ static void init_wsize(void)
cols -= 5; cols -= 5;
} }
static void cinit(void)
{
item_no = 0;
}
static void cmake(void)
{
items[item_no] = malloc(sizeof(struct dialog_list_item));
memset(items[item_no], 0, sizeof(struct dialog_list_item));
items[item_no]->tag = malloc(32); items[item_no]->tag[0] = 0;
items[item_no]->name = malloc(512); items[item_no]->name[0] = 0;
items[item_no]->namelen = 0;
item_no++;
}
static int cprint_name(const char *fmt, ...)
{
va_list ap;
int res;
if (!item_no)
cmake();
va_start(ap, fmt);
res = vsnprintf(items[item_no - 1]->name + items[item_no - 1]->namelen,
512 - items[item_no - 1]->namelen, fmt, ap);
if (res > 0)
items[item_no - 1]->namelen += res;
va_end(ap);
return res;
}
static int cprint_tag(const char *fmt, ...)
{
va_list ap;
int res;
if (!item_no)
cmake();
va_start(ap, fmt);
res = vsnprintf(items[item_no - 1]->tag, 32, fmt, ap);
va_end(ap);
return res;
}
static void cdone(void)
{
int i;
for (i = 0; i < item_no; i++) {
free(items[i]->tag);
free(items[i]->name);
free(items[i]);
}
item_no = 0;
}
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;
@ -447,15 +397,17 @@ static void search_conf(void)
{ {
struct symbol **sym_arr; struct symbol **sym_arr;
struct gstr res; struct gstr res;
int dres;
again: again:
switch (dialog_inputbox("Search Configuration Parameter", dialog_clear();
"Enter Keyword", 10, 75, dres = dialog_inputbox(_("Search Configuration Parameter"),
NULL)) { _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
10, 75, "");
switch (dres) {
case 0: case 0:
break; break;
case 1: case 1:
show_helptext("Search Configuration", search_help); show_helptext(_("Search Configuration"), search_help);
goto again; goto again;
default: default:
return; return;
@ -464,7 +416,7 @@ again:
sym_arr = sym_re_search(dialog_input_result); sym_arr = sym_re_search(dialog_input_result);
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);
str_free(&res); str_free(&res);
} }
@ -488,26 +440,24 @@ static void build_conf(struct menu *menu)
switch (prop->type) { switch (prop->type) {
case P_MENU: case P_MENU:
child_count++; child_count++;
cmake();
cprint_tag("m%p", menu);
if (single_menu_mode) { if (single_menu_mode) {
cprint_name("%s%*c%s", item_make("%s%*c%s",
menu->data ? "-->" : "++>", menu->data ? "-->" : "++>",
indent + 1, ' ', prompt); indent + 1, ' ', prompt);
} else { } else
cprint_name(" %*c%s --->", indent + 1, ' ', prompt); item_make(" %*c%s --->", indent + 1, ' ', prompt);
}
item_set_tag('m');
item_set_data(menu);
if (single_menu_mode && menu->data) if (single_menu_mode && menu->data)
goto conf_childs; goto conf_childs;
return; return;
default: default:
if (prompt) { if (prompt) {
child_count++; child_count++;
cmake(); item_make("---%*c%s", indent + 1, ' ', prompt);
cprint_tag(":%p", menu); item_set_tag(':');
cprint_name("---%*c%s", indent + 1, ' ', prompt); item_set_data(menu);
} }
} }
} else } else
@ -515,7 +465,6 @@ static void build_conf(struct menu *menu)
goto conf_childs; goto conf_childs;
} }
cmake();
type = sym_get_type(sym); type = sym_get_type(sym);
if (sym_is_choice(sym)) { if (sym_is_choice(sym)) {
struct symbol *def_sym = sym_get_choice_value(sym); struct symbol *def_sym = sym_get_choice_value(sym);
@ -529,10 +478,9 @@ static void build_conf(struct menu *menu)
val = sym_get_tristate_value(sym); val = sym_get_tristate_value(sym);
if (sym_is_changable(sym)) { if (sym_is_changable(sym)) {
cprint_tag("t%p", menu);
switch (type) { switch (type) {
case S_BOOLEAN: case S_BOOLEAN:
cprint_name("[%c]", val == no ? ' ' : '*'); item_make("[%c]", val == no ? ' ' : '*');
break; break;
case S_TRISTATE: case S_TRISTATE:
switch (val) { switch (val) {
@ -540,19 +488,22 @@ static void build_conf(struct menu *menu)
case mod: ch = 'M'; break; case mod: ch = 'M'; break;
default: ch = ' '; break; default: ch = ' '; break;
} }
cprint_name("<%c>", ch); item_make("<%c>", ch);
break; break;
} }
item_set_tag('t');
item_set_data(menu);
} else { } else {
cprint_tag("%c%p", def_menu ? 't' : ':', menu); item_make(" ");
cprint_name(" "); item_set_tag(def_menu ? 't' : ':');
item_set_data(menu);
} }
cprint_name("%*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) {
cprint_name(" (%s)", menu_get_prompt(def_menu)); item_add_str(" (%s)", menu_get_prompt(def_menu));
cprint_name(" --->"); item_add_str(" --->");
if (def_menu->list) { if (def_menu->list) {
indent += 2; indent += 2;
build_conf(def_menu); build_conf(def_menu);
@ -563,53 +514,59 @@ static void build_conf(struct menu *menu)
} }
} else { } else {
if (menu == current_menu) { if (menu == current_menu) {
cprint_tag(":%p", menu); item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
cprint_name("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); item_set_tag(':');
item_set_data(menu);
goto conf_childs; goto conf_childs;
} }
child_count++; child_count++;
val = sym_get_tristate_value(sym); val = sym_get_tristate_value(sym);
if (sym_is_choice_value(sym) && val == yes) { if (sym_is_choice_value(sym) && val == yes) {
cprint_tag(":%p", menu); item_make(" ");
cprint_name(" "); item_set_tag(':');
item_set_data(menu);
} else { } else {
switch (type) { switch (type) {
case S_BOOLEAN: case S_BOOLEAN:
cprint_tag("t%p", menu);
if (sym_is_changable(sym)) if (sym_is_changable(sym))
cprint_name("[%c]", val == no ? ' ' : '*'); item_make("[%c]", val == no ? ' ' : '*');
else else
cprint_name("---"); item_make("---");
item_set_tag('t');
item_set_data(menu);
break; break;
case S_TRISTATE: case S_TRISTATE:
cprint_tag("t%p", menu);
switch (val) { switch (val) {
case yes: ch = '*'; break; case yes: ch = '*'; break;
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))
cprint_name("<%c>", ch); item_make("<%c>", ch);
else else
cprint_name("---"); item_make("---");
item_set_tag('t');
item_set_data(menu);
break; break;
default: default:
cprint_tag("s%p", menu); tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
tmp = cprint_name("(%s)", sym_get_string_value(sym)); item_make("(%s)", sym_get_string_value(sym));
tmp = indent - tmp + 4; tmp = indent - tmp + 4;
if (tmp < 0) if (tmp < 0)
tmp = 0; tmp = 0;
cprint_name("%*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_data(menu);
goto conf_childs; goto conf_childs;
} }
} }
cprint_name("%*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) {
cprint_name(" --->"); item_add_str(" --->");
return; return;
} }
} }
@ -623,56 +580,48 @@ conf_childs:
static void conf(struct menu *menu) static void conf(struct menu *menu)
{ {
struct dialog_list_item *active_item = NULL;
struct menu *submenu; struct menu *submenu;
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
struct symbol *sym; struct symbol *sym;
char active_entry[40]; struct menu *active_menu = NULL;
int stat, type; int res;
int s_scroll = 0;
unlink("lxdialog.scrltmp");
active_entry[0] = 0;
while (1) { while (1) {
indent = 0; item_reset();
child_count = 0;
current_menu = menu; current_menu = menu;
cdone(); cinit();
build_conf(menu); build_conf(menu);
if (!child_count) if (!child_count)
break; break;
if (menu == &rootmenu) { if (menu == &rootmenu) {
cmake(); cprint_tag(":"); cprint_name("--- "); item_make("--- ");
cmake(); cprint_tag("L"); cprint_name("Load an Alternate Configuration File"); item_set_tag(':');
cmake(); cprint_tag("S"); cprint_name("Save Configuration to an Alternate File"); item_make(_(" Load an Alternate Configuration File"));
item_set_tag('L');
item_make(_(" Save an Alternate Configuration File"));
item_set_tag('S');
} }
dialog_clear(); dialog_clear();
stat = dialog_menu(prompt ? prompt : "Main Menu", res = dialog_menu(prompt ? prompt : _("Main Menu"),
menu_instructions, rows, cols, rows - 10, _(menu_instructions),
active_entry, item_no, items); active_menu, &s_scroll);
if (stat < 0) if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
return;
if (stat == 1 || stat == 255)
break; break;
if (!item_activate_selected())
active_item = first_sel_item(item_no, items);
if (!active_item)
continue; continue;
active_item->selected = 0; if (!item_tag())
strncpy(active_entry, active_item->tag, sizeof(active_entry));
active_entry[sizeof(active_entry)-1] = 0;
type = active_entry[0];
if (!type)
continue; continue;
sym = NULL; submenu = item_data();
submenu = NULL; active_menu = item_data();
if (sscanf(active_entry + 1, "%p", &submenu) == 1) if (submenu)
sym = submenu->sym; sym = submenu->sym;
else
sym = NULL;
switch (stat) { switch (res) {
case 0: case 0:
switch (type) { switch (item_tag()) {
case 'm': case 'm':
if (single_menu_mode) if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data; submenu->data = (void *) (long) !submenu->data;
@ -700,10 +649,10 @@ 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 (type == 't') { if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes)) if (sym_set_tristate_value(sym, yes))
break; break;
if (sym_set_tristate_value(sym, mod)) if (sym_set_tristate_value(sym, mod))
@ -711,17 +660,17 @@ static void conf(struct menu *menu)
} }
break; break;
case 4: case 4:
if (type == 't') if (item_is_tag('t'))
sym_set_tristate_value(sym, no); sym_set_tristate_value(sym, no);
break; break;
case 5: case 5:
if (type == 't') if (item_is_tag('t'))
sym_set_tristate_value(sym, mod); sym_set_tristate_value(sym, mod);
break; break;
case 6: case 6:
if (type == 't') if (item_is_tag('t'))
sym_toggle_tristate_value(sym); sym_toggle_tristate_value(sym);
else if (type == 'm') else if (item_is_tag('m'))
conf(submenu); conf(submenu);
break; break;
case 7: case 7:
@ -733,13 +682,8 @@ static void conf(struct menu *menu)
static void show_textbox(const char *title, const char *text, int r, int c) static void show_textbox(const char *title, const char *text, int r, int c)
{ {
int fd; dialog_clear();
dialog_textbox(title, text, r, c);
fd = creat(".help.tmp", 0777);
write(fd, text, strlen(text));
close(fd);
show_file(".help.tmp", title, r, c);
unlink(".help.tmp");
} }
static void show_helptext(const char *title, const char *text) static void show_helptext(const char *title, const char *text)
@ -755,8 +699,8 @@ static void show_help(struct menu *menu)
if (sym->help) if (sym->help)
{ {
if (sym->name) { if (sym->name) {
str_printf(&help, "%s:\n\n", sym->name); str_printf(&help, "CONFIG_%s:\n\n", sym->name);
str_append(&help, sym->help); str_append(&help, _(sym->help));
str_append(&help, "\n"); str_append(&help, "\n");
} }
} else { } else {
@ -767,12 +711,6 @@ static void show_help(struct menu *menu)
str_free(&help); str_free(&help);
} }
static void show_file(const char *filename, const char *title, int r, int c)
{
while (dialog_textbox(title, filename, r ? r : rows, c ? c : cols) < 0)
;
}
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);
@ -781,38 +719,44 @@ static void conf_choice(struct menu *menu)
active = sym_get_choice_value(menu->sym); active = sym_get_choice_value(menu->sym);
while (1) { while (1) {
int res;
int selected;
item_reset();
current_menu = menu; current_menu = menu;
cdone(); cinit();
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;
cmake(); item_make("%s", menu_get_prompt(child));
cprint_tag("%p", child); item_set_data(child);
cprint_name("%s", menu_get_prompt(child)); if (child->sym == active)
item_set_selected(1);
if (child->sym == sym_get_choice_value(menu->sym)) if (child->sym == sym_get_choice_value(menu->sym))
items[item_no - 1]->selected = 1; /* ON */ item_set_tag('X');
else if (child->sym == active)
items[item_no - 1]->selected = 2; /* SELECTED */
else
items[item_no - 1]->selected = 0; /* OFF */
} }
dialog_clear();
switch (dialog_checklist(prompt ? prompt : "Main Menu", res = dialog_checklist(prompt ? prompt : _("Main Menu"),
radiolist_instructions, 15, 70, 6, _(radiolist_instructions),
item_no, items, FLAG_RADIO)) { 15, 70, 6);
selected = item_activate_selected();
switch (res) {
case 0: case 0:
if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) != 1) if (selected) {
break; child = item_data();
sym_set_tristate_value(child->sym, yes); sym_set_tristate_value(child->sym, yes);
}
return; return;
case 1: case 1:
if (sscanf(first_sel_item(item_no, items)->tag, "%p", &child) == 1) { if (selected) {
child = item_data();
show_help(child); show_help(child);
active = child->sym; active = child->sym;
} else } else
show_help(menu); show_help(menu);
break; break;
case 255: case KEY_ESC:
return;
case -ERRDISPLAYTOOSMALL:
return; return;
} }
} }
@ -823,35 +767,36 @@ static void conf_string(struct menu *menu)
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
while (1) { while (1) {
int res;
char *heading; char *heading;
switch (sym_get_type(menu->sym)) { switch (sym_get_type(menu->sym)) {
case S_INT: case S_INT:
heading = (char *) inputbox_instructions_int; heading = _(inputbox_instructions_int);
break; break;
case S_HEX: case S_HEX:
heading = (char *) inputbox_instructions_hex; heading = _(inputbox_instructions_hex);
break; break;
case S_STRING: case S_STRING:
heading = (char *) inputbox_instructions_string; heading = _(inputbox_instructions_string);
break; break;
default: default:
heading = "Internal mconf error!"; heading = "Internal mconf error!";
/* panic? */;
} }
dialog_clear();
switch (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) {
case 0: case 0:
if (sym_set_string_value(menu->sym, dialog_input_result)) if (sym_set_string_value(menu->sym, dialog_input_result))
return; return;
show_textbox(NULL, "You have made an invalid entry.", 5, 43); show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
break; break;
case 1: case 1:
show_help(menu); show_help(menu);
break; break;
case 255: case KEY_ESC:
return; return;
} }
} }
@ -859,20 +804,24 @@ static void conf_string(struct menu *menu)
static void conf_load(void) static void conf_load(void)
{ {
while (1) { while (1) {
switch (dialog_inputbox(NULL, load_config_text, 11, 55, int res;
filename)) { dialog_clear();
res = dialog_inputbox(NULL, load_config_text,
11, 55, filename);
switch(res) {
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))
return; return;
show_textbox(NULL, "File does not exist!", 5, 38); show_textbox(NULL, _("File does not exist!"), 5, 38);
break; break;
case 1: case 1:
show_helptext("Load Alternate Configuration", load_config_help); show_helptext(_("Load Alternate Configuration"), load_config_help);
break; break;
case 255: case KEY_ESC:
return; return;
} }
} }
@ -881,19 +830,22 @@ static void conf_load(void)
static void conf_save(void) static void conf_save(void)
{ {
while (1) { while (1) {
switch (dialog_inputbox(NULL, save_config_text, 11, 55, int res;
filename)) { dialog_clear();
res = dialog_inputbox(NULL, save_config_text,
11, 55, filename);
switch(res) {
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))
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:
show_helptext("Save Alternate Configuration", save_config_help); show_helptext(_("Save Alternate Configuration"), save_config_help);
break; break;
case 255: case KEY_ESC:
return; return;
} }
} }
@ -902,42 +854,25 @@ static void conf_save(void)
static void conf_cleanup(void) static void conf_cleanup(void)
{ {
tcsetattr(1, TCSAFLUSH, &ios_org); tcsetattr(1, TCSAFLUSH, &ios_org);
unlink(".help.tmp");
}
static void winch_handler(int sig)
{
struct winsize ws;
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
rows = 24;
cols = 80;
} else {
rows = ws.ws_row;
cols = ws.ws_col;
}
if (rows < 19 || cols < 80) {
end_dialog();
fprintf(stderr, "Your display is too small to run Menuconfig!\n");
fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
exit(1);
}
rows -= 4;
cols -= 5;
} }
int main(int ac, char **av) int main(int ac, char **av)
{ {
struct symbol *sym;
char *mode; char *mode;
int stat; int res;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
conf_parse(av[1]); conf_parse(av[1]);
conf_read(NULL); conf_read(NULL);
snprintf(menu_backtitle, 128, "Buildroot Configuration"); sym = sym_lookup("VERSION", 0);
sym_calc_value(sym);
sprintf(menu_backtitle, _("Buildroot v%s Configuration"),
sym_get_string_value(sym));
mode = getenv("MENUCONFIG_MODE"); mode = getenv("MENUCONFIG_MODE");
if (mode) { if (mode) {
@ -948,26 +883,42 @@ int main(int ac, char **av)
tcgetattr(1, &ios_org); tcgetattr(1, &ios_org);
atexit(conf_cleanup); atexit(conf_cleanup);
init_wsize(); init_wsize();
init_dialog(); reset_dialog();
signal(SIGWINCH, winch_handler); init_dialog(menu_backtitle);
conf(&rootmenu);
end_dialog();
/* Restart dialog to act more like when lxdialog was still separate */
init_dialog();
do { do {
stat = dialog_yesno(NULL, conf(&rootmenu);
"Do you wish to save your new Buildroot configuration?", 5, 60); dialog_clear();
} while (stat < 0); if (conf_get_changed())
res = dialog_yesno(NULL,
_("Do you wish to save your "
"new Buildroot configuration?\n"
"<ESC><ESC> to continue."),
6, 60);
else
res = -1;
} while (res == KEY_ESC);
end_dialog(); end_dialog();
if (stat == 0) { switch (res) {
conf_write(NULL); case 0:
printf("\n\n" if (conf_write(NULL)) {
fprintf(stderr, _("\n\n"
"Error during writing of the Buildroot configuration.\n"
"Your Buildroot configuration changes were NOT saved."
"\n\n"));
return 1;
}
case -1:
printf(_("\n\n"
"*** End of Buildroot configuration.\n" "*** End of Buildroot configuration.\n"
"*** Check the top-level Makefile for additional configuration options.\n\n"); "*** Execute 'make' to build Buildroot or try 'make help'."
} else "\n\n"));
printf("\n\nYour Buildroot configuration changes were NOT saved.\n\n"); break;
default:
fprintf(stderr, _("\n\n"
"Your Buildroot configuration changes were NOT saved."
"\n\n"));
}
return 0; return conf_write_autoconf();
} }

View File

@ -61,10 +61,11 @@ void menu_end_entry(void)
{ {
} }
void menu_add_menu(void) struct menu *menu_add_menu(void)
{ {
current_menu = current_entry; menu_end_entry();
last_entry_ptr = &current_entry->list; last_entry_ptr = &current_entry->list;
return current_menu = current_entry;
} }
void menu_end_menu(void) void menu_end_menu(void)
@ -113,7 +114,7 @@ void menu_set_type(int type)
sym->type = type; sym->type = type;
return; return;
} }
menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n", menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'",
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
sym_type_name(sym->type), sym_type_name(type)); sym_type_name(sym->type), sym_type_name(type));
} }
@ -123,22 +124,27 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
struct property *prop = prop_alloc(type, current_entry->sym); struct property *prop = prop_alloc(type, current_entry->sym);
prop->menu = current_entry; prop->menu = current_entry;
prop->text = prompt;
prop->expr = expr; prop->expr = expr;
prop->visible.expr = menu_check_dep(dep); prop->visible.expr = menu_check_dep(dep);
if (prompt) { if (prompt) {
if (isspace(*prompt)) {
prop_warn(prop, "leading whitespace ignored");
while (isspace(*prompt))
prompt++;
}
if (current_entry->prompt) if (current_entry->prompt)
menu_warn(current_entry, "prompt redefined\n"); prop_warn(prop, "prompt redefined");
current_entry->prompt = prop; current_entry->prompt = prop;
} }
prop->text = prompt;
return prop; return prop;
} }
void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
{ {
menu_add_prop(type, prompt, NULL, dep); return menu_add_prop(type, prompt, NULL, dep);
} }
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
@ -151,6 +157,30 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
} }
void menu_add_option(int token, char *arg)
{
struct property *prop;
switch (token) {
case T_OPT_MODULES:
prop = prop_alloc(P_DEFAULT, modules_sym);
prop->expr = expr_alloc_symbol(current_entry->sym);
break;
case T_OPT_DEFCONFIG_LIST:
if (!sym_defconfig_list)
sym_defconfig_list = current_entry->sym;
else if (sym_defconfig_list != current_entry->sym)
zconf_error("trying to redefine defconfig symbol");
break;
}
}
static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
{
return sym2->type == S_INT || sym2->type == S_HEX ||
(sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
}
void sym_check_prop(struct symbol *sym) void sym_check_prop(struct symbol *sym)
{ {
struct property *prop; struct property *prop;
@ -185,8 +215,8 @@ void sym_check_prop(struct symbol *sym)
if (sym->type != S_INT && sym->type != S_HEX) if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed " prop_warn(prop, "range is only allowed "
"for int or hex symbols"); "for int or hex symbols");
if (!sym_string_valid(sym, prop->expr->left.sym->name) || if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
!sym_string_valid(sym, prop->expr->right.sym->name)) !menu_range_valid_sym(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid"); prop_warn(prop, "range is invalid");
break; break;
default: default:
@ -318,11 +348,10 @@ void menu_finalize(struct menu *parent)
if (sym && !(sym->flags & SYMBOL_WARNED)) { if (sym && !(sym->flags & SYMBOL_WARNED)) {
if (sym->type == S_UNKNOWN) if (sym->type == S_UNKNOWN)
menu_warn(parent, "config symbol defined " menu_warn(parent, "config symbol defined without type");
"without type\n");
if (sym_is_choice(sym) && !parent->prompt) if (sym_is_choice(sym) && !parent->prompt)
menu_warn(parent, "choice must have a prompt\n"); menu_warn(parent, "choice must have a prompt");
/* Check properties connected to this symbol */ /* Check properties connected to this symbol */
sym_check_prop(sym); sym_check_prop(sym);
@ -365,9 +394,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;
} }

1753
package/config/qconf.cc Normal file

File diff suppressed because it is too large Load Diff

334
package/config/qconf.h Normal file
View File

@ -0,0 +1,334 @@
/*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0.
*/
#include <qlistview.h>
#if QT_VERSION >= 300
#include <qsettings.h>
#else
class QSettings {
public:
void beginGroup(const QString& group) { }
void endGroup(void) { }
bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const
{ if (ok) *ok = FALSE; return def; }
int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const
{ if (ok) *ok = FALSE; return def; }
QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const
{ if (ok) *ok = FALSE; return def; }
QStringList readListEntry(const QString& key, bool* ok = 0) const
{ if (ok) *ok = FALSE; return QStringList(); }
template <class t>
bool writeEntry(const QString& key, t value)
{ return TRUE; }
};
#endif
class ConfigView;
class ConfigList;
class ConfigItem;
class ConfigLineEdit;
class ConfigMainWindow;
class ConfigSettings : public QSettings {
public:
QValueList<int> readSizes(const QString& key, bool *ok);
bool writeSizes(const QString& key, const QValueList<int>& value);
};
enum colIdx {
promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
};
enum listMode {
singleMode, menuMode, symbolMode, fullMode, listMode
};
class ConfigList : public QListView {
Q_OBJECT
typedef class QListView Parent;
public:
ConfigList(ConfigView* p, const char *name = 0);
void reinit(void);
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
ConfigItem* findConfigItem(struct menu *);
protected:
void keyPressEvent(QKeyEvent *e);
void contentsMousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e);
void contentsMouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e);
void contextMenuEvent(QContextMenuEvent *e);
public slots:
void setRootMenu(struct menu *menu);
void updateList(ConfigItem *item);
void setValue(ConfigItem* item, tristate val);
void changeValue(ConfigItem* item);
void updateSelection(void);
void saveSettings(void);
signals:
void menuChanged(struct menu *menu);
void menuSelected(struct menu *menu);
void parentSelected(void);
void gotFocus(struct menu *);
public:
void updateListAll(void)
{
updateAll = true;
updateList(NULL);
updateAll = false;
}
ConfigList* listView()
{
return this;
}
ConfigItem* firstChild() const
{
return (ConfigItem *)Parent::firstChild();
}
int mapIdx(colIdx idx)
{
return colMap[idx];
}
void addColumn(colIdx idx, const QString& label)
{
colMap[idx] = Parent::addColumn(label);
colRevMap[colMap[idx]] = idx;
}
void removeColumn(colIdx idx)
{
int col = colMap[idx];
if (col >= 0) {
Parent::removeColumn(col);
colRevMap[col] = colMap[idx] = -1;
}
}
void setAllOpen(bool open);
void setParentMenu(void);
template <class P>
void updateMenuList(P*, struct menu*);
bool updateAll;
QPixmap symbolYesPix, symbolModPix, symbolNoPix;
QPixmap choiceYesPix, choiceNoPix;
QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
bool showAll, showName, showRange, showData;
enum listMode mode;
struct menu *rootEntry;
QColorGroup disabledColorGroup;
QColorGroup inactivedColorGroup;
QPopupMenu* headerPopup;
private:
int colMap[colNr];
int colRevMap[colNr];
};
class ConfigItem : public QListViewItem {
typedef class QListViewItem Parent;
public:
ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), menu(m), visible(v), goParent(false)
{
init();
}
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), menu(m), visible(v), goParent(false)
{
init();
}
ConfigItem(QListView *parent, ConfigItem *after, bool v)
: Parent(parent, after), menu(0), visible(v), goParent(true)
{
init();
}
~ConfigItem(void);
void init(void);
#if QT_VERSION >= 300
void okRename(int col);
#endif
void updateMenu(void);
void testUpdateMenu(bool v);
ConfigList* listView() const
{
return (ConfigList*)Parent::listView();
}
ConfigItem* firstChild() const
{
return (ConfigItem *)Parent::firstChild();
}
ConfigItem* nextSibling() const
{
return (ConfigItem *)Parent::nextSibling();
}
void setText(colIdx idx, const QString& text)
{
Parent::setText(listView()->mapIdx(idx), text);
}
QString text(colIdx idx) const
{
return Parent::text(listView()->mapIdx(idx));
}
void setPixmap(colIdx idx, const QPixmap& pm)
{
Parent::setPixmap(listView()->mapIdx(idx), pm);
}
const QPixmap* pixmap(colIdx idx) const
{
return Parent::pixmap(listView()->mapIdx(idx));
}
void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
ConfigItem* nextItem;
struct menu *menu;
bool visible;
bool goParent;
};
class ConfigLineEdit : public QLineEdit {
Q_OBJECT
typedef class QLineEdit Parent;
public:
ConfigLineEdit(ConfigView* parent);
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
void show(ConfigItem *i);
void keyPressEvent(QKeyEvent *e);
public:
ConfigItem *item;
};
class ConfigView : public QVBox {
Q_OBJECT
typedef class QVBox Parent;
public:
ConfigView(QWidget* parent, const char *name = 0);
~ConfigView(void);
static void updateList(ConfigItem* item);
static void updateListAll(void);
bool showAll(void) const { return list->showAll; }
bool showName(void) const { return list->showName; }
bool showRange(void) const { return list->showRange; }
bool showData(void) const { return list->showData; }
public slots:
void setShowAll(bool);
void setShowName(bool);
void setShowRange(bool);
void setShowData(bool);
signals:
void showAllChanged(bool);
void showNameChanged(bool);
void showRangeChanged(bool);
void showDataChanged(bool);
public:
ConfigList* list;
ConfigLineEdit* lineEdit;
static ConfigView* viewList;
ConfigView* nextView;
};
class ConfigInfoView : public QTextBrowser {
Q_OBJECT
typedef class QTextBrowser Parent;
public:
ConfigInfoView(QWidget* parent, const char *name = 0);
bool showDebug(void) const { return _showDebug; }
public slots:
void setInfo(struct menu *menu);
void saveSettings(void);
void setSource(const QString& name);
void setShowDebug(bool);
signals:
void showDebugChanged(bool);
void menuSelected(struct menu *);
protected:
void symbolInfo(void);
void menuInfo(void);
QString debug_info(struct symbol *sym);
static QString print_filter(const QString &str);
static void expr_print_help(void *data, struct symbol *sym, const char *str);
QPopupMenu* createPopupMenu(const QPoint& pos);
void contentsContextMenuEvent(QContextMenuEvent *e);
struct symbol *sym;
struct menu *menu;
bool _showDebug;
};
class ConfigSearchWindow : public QDialog {
Q_OBJECT
typedef class QDialog Parent;
public:
ConfigSearchWindow(QWidget* parent, const char *name = 0);
public slots:
void saveSettings(void);
void search(void);
protected:
QLineEdit* editField;
QPushButton* searchButton;
QSplitter* split;
ConfigView* list;
ConfigInfoView* info;
struct symbol **result;
};
class ConfigMainWindow : public QMainWindow {
Q_OBJECT
static QAction *saveAction;
static void conf_changed(void);
public:
ConfigMainWindow(void);
public slots:
void changeMenu(struct menu *);
void setMenuLink(struct menu *);
void listFocusChanged(void);
void goBack(void);
void loadConfig(void);
void saveConfig(void);
void saveConfigAs(void);
void searchConfig(void);
void showSingleView(void);
void showSplitView(void);
void showFullView(void);
void showIntro(void);
void showAbout(void);
void saveSettings(void);
protected:
void closeEvent(QCloseEvent *e);
ConfigSearchWindow *searchWindow;
ConfigView *menuView;
ConfigList *menuList;
ConfigView *configView;
ConfigList *configList;
ConfigInfoView *helpText;
QToolBar *toolBar;
QAction *backAction;
QSplitter* split1;
QSplitter* split2;
};

View File

@ -15,22 +15,22 @@
struct symbol symbol_yes = { struct symbol symbol_yes = {
.name = "y", .name = "y",
.curr = { "y", yes }, .curr = { "y", yes },
.flags = SYMBOL_YES|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_mod = { }, symbol_mod = {
.name = "m", .name = "m",
.curr = { "m", mod }, .curr = { "m", mod },
.flags = SYMBOL_MOD|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_no = { }, symbol_no = {
.name = "n", .name = "n",
.curr = { "n", no }, .curr = { "n", no },
.flags = SYMBOL_NO|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_empty = { }, symbol_empty = {
.name = "", .name = "",
.curr = { "", no }, .curr = { "", no },
.flags = SYMBOL_VALID, .flags = SYMBOL_VALID,
}; };
int sym_change_count; struct symbol *sym_defconfig_list;
struct symbol *modules_sym; struct symbol *modules_sym;
tristate modules_val; tristate modules_val;
@ -44,6 +44,7 @@ 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;
@ -51,6 +52,15 @@ 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 = sym_lookup("VERSION", 0);
sym->type = S_STRING; sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO; sym->flags |= SYMBOL_AUTO;
@ -58,13 +68,10 @@ void sym_init(void)
if (p) if (p)
sym_add_default(sym, p); sym_add_default(sym, p);
sym = sym_lookup("TARGET_ARCH", 0); sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING; sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO; sym->flags |= SYMBOL_AUTO;
p = getenv("TARGET_ARCH"); sym_add_default(sym, uts.release);
if (p)
sym_add_default(sym, p);
} }
enum symbol_type sym_get_type(struct symbol *sym) enum symbol_type sym_get_type(struct symbol *sym)
@ -134,6 +141,55 @@ struct property *sym_get_range_prop(struct symbol *sym)
return NULL; return NULL;
} }
static int sym_get_range_val(struct symbol *sym, int base)
{
sym_calc_value(sym);
switch (sym->type) {
case S_INT:
base = 10;
break;
case S_HEX:
base = 16;
break;
default:
break;
}
return strtol(sym->curr.val, NULL, base);
}
static void sym_validate_range(struct symbol *sym)
{
struct property *prop;
int base, val, val2;
char str[64];
switch (sym->type) {
case S_INT:
base = 10;
break;
case S_HEX:
base = 16;
break;
default:
return;
}
prop = sym_get_range_prop(sym);
if (!prop)
return;
val = strtol(sym->curr.val, NULL, base);
val2 = sym_get_range_val(prop->expr->left.sym, base);
if (val >= val2) {
val2 = sym_get_range_val(prop->expr->right.sym, base);
if (val <= val2)
return;
}
if (sym->type == S_INT)
sprintf(str, "%d", val2);
else
sprintf(str, "0x%x", val2);
sym->curr.val = strdup(str);
}
static void sym_calc_visibility(struct symbol *sym) static void sym_calc_visibility(struct symbol *sym)
{ {
struct property *prop; struct property *prop;
@ -171,7 +227,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
struct expr *e; struct expr *e;
/* is the user choice visible? */ /* is the user choice visible? */
def_sym = sym->user.val; def_sym = sym->def[S_DEF_USER].val;
if (def_sym) { if (def_sym) {
sym_calc_visibility(def_sym); sym_calc_visibility(def_sym);
if (def_sym->visible != no) if (def_sym->visible != no)
@ -250,7 +306,7 @@ void sym_calc_value(struct symbol *sym)
} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
sym->flags |= SYMBOL_WRITE; sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) if (sym_has_value(sym))
newval.tri = sym->user.tri; newval.tri = sym->def[S_DEF_USER].tri;
else if (!sym_is_choice(sym)) { else if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym); prop = sym_get_default_prop(sym);
if (prop) if (prop)
@ -273,7 +329,7 @@ void sym_calc_value(struct symbol *sym)
if (sym->visible != no) { if (sym->visible != no) {
sym->flags |= SYMBOL_WRITE; sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) { if (sym_has_value(sym)) {
newval.val = sym->user.val; newval.val = sym->def[S_DEF_USER].val;
break; break;
} }
} }
@ -294,11 +350,15 @@ void sym_calc_value(struct symbol *sym)
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);
sym_validate_range(sym);
if (memcmp(&oldval, &sym->curr, sizeof(oldval))) if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
sym_set_changed(sym); sym_set_changed(sym);
if (modules_sym == sym) if (modules_sym == sym) {
modules_val = modules_sym->curr.tri; sym_set_all_changed();
modules_val = modules_sym->curr.tri;
}
}
if (sym_is_choice(sym)) { if (sym_is_choice(sym)) {
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
@ -318,7 +378,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym) for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID; sym->flags &= ~SYMBOL_VALID;
sym_change_count++; sym_add_change_count(1);
if (modules_sym) if (modules_sym)
sym_calc_value(modules_sym); sym_calc_value(modules_sym);
} }
@ -369,23 +429,31 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
if (oldval != val && !sym_tristate_within_range(sym, val)) if (oldval != val && !sym_tristate_within_range(sym, val))
return false; return false;
if (sym->flags & SYMBOL_NEW) { if (!(sym->flags & SYMBOL_DEF_USER)) {
sym->flags &= ~SYMBOL_NEW; sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym); sym_set_changed(sym);
} }
/*
* setting a choice value also resets the new flag of the choice
* symbol and all other choice values.
*/
if (sym_is_choice_value(sym) && val == yes) { if (sym_is_choice_value(sym) && val == yes) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
struct property *prop;
struct expr *e;
cs->user.val = sym; cs->def[S_DEF_USER].val = sym;
cs->flags &= ~SYMBOL_NEW; cs->flags |= SYMBOL_DEF_USER;
prop = sym_get_choice_prop(cs);
for (e = prop->expr; e; e = e->left.expr) {
if (e->right.sym->visible != no)
e->right.sym->flags |= SYMBOL_DEF_USER;
}
} }
sym->user.tri = val; sym->def[S_DEF_USER].tri = val;
if (oldval != val) { if (oldval != val)
sym_clear_all_valid(); sym_clear_all_valid();
if (sym == modules_sym)
sym_set_all_changed();
}
return true; return true;
} }
@ -471,8 +539,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
if (!prop) if (!prop)
return true; return true;
val = strtol(str, NULL, 10); val = strtol(str, NULL, 10);
return val >= strtol(prop->expr->left.sym->name, NULL, 10) && return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
val <= strtol(prop->expr->right.sym->name, NULL, 10); val <= sym_get_range_val(prop->expr->right.sym, 10);
case S_HEX: case S_HEX:
if (!sym_string_valid(sym, str)) if (!sym_string_valid(sym, str))
return false; return false;
@ -480,8 +548,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
if (!prop) if (!prop)
return true; return true;
val = strtol(str, NULL, 16); val = strtol(str, NULL, 16);
return val >= strtol(prop->expr->left.sym->name, NULL, 16) && return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
val <= strtol(prop->expr->right.sym->name, NULL, 16); val <= sym_get_range_val(prop->expr->right.sym, 16);
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
switch (str[0]) { switch (str[0]) {
@ -523,20 +591,20 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
if (!sym_string_within_range(sym, newval)) if (!sym_string_within_range(sym, newval))
return false; return false;
if (sym->flags & SYMBOL_NEW) { if (!(sym->flags & SYMBOL_DEF_USER)) {
sym->flags &= ~SYMBOL_NEW; sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym); sym_set_changed(sym);
} }
oldval = sym->user.val; oldval = sym->def[S_DEF_USER].val;
size = strlen(newval) + 1; size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2; size += 2;
sym->user.val = val = malloc(size); sym->def[S_DEF_USER].val = val = malloc(size);
*val++ = '0'; *val++ = '0';
*val++ = 'x'; *val++ = 'x';
} else if (!oldval || strcmp(oldval, newval)) } else if (!oldval || strcmp(oldval, newval))
sym->user.val = val = malloc(size); sym->def[S_DEF_USER].val = val = malloc(size);
else else
return true; return true;
@ -611,7 +679,6 @@ struct symbol *sym_lookup(const char *name, int isconst)
memset(symbol, 0, sizeof(*symbol)); memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name; symbol->name = new_name;
symbol->type = S_UNKNOWN; symbol->type = S_UNKNOWN;
symbol->flags = SYMBOL_NEW;
if (isconst) if (isconst)
symbol->flags |= SYMBOL_CONST; symbol->flags |= SYMBOL_CONST;
@ -724,12 +791,12 @@ 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_DONE)
return NULL;
if (sym->flags & SYMBOL_CHECK) { if (sym->flags & SYMBOL_CHECK) {
printf("Warning! Found recursive dependency: %s", sym->name); printf("Warning! Found recursive dependency: %s", sym->name);
return sym; return sym;
} }
if (sym->flags & SYMBOL_CHECKED)
return NULL;
sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
sym2 = sym_check_expr_deps(sym->rev_dep.expr); sym2 = sym_check_expr_deps(sym->rev_dep.expr);
@ -749,8 +816,13 @@ struct symbol *sym_check_deps(struct symbol *sym)
goto out; goto out;
} }
out: out:
if (sym2) if (sym2) {
printf(" %s", sym->name); printf(" %s", sym->name);
if (sym2 == sym) {
printf("\n");
sym2 = NULL;
}
}
sym->flags &= ~SYMBOL_CHECK; sym->flags &= ~SYMBOL_CHECK;
return sym2; return sym2;
} }

View File

@ -33,8 +33,8 @@ int file_write_dep(const char *name)
FILE *out; FILE *out;
if (!name) if (!name)
name = ".config.cmd"; name = ".kconfig.d";
out = fopen(".config.tmp", "w"); out = fopen("..config.tmp", "w");
if (!out) if (!out)
return 1; return 1;
fprintf(out, "deps_config := \\\n"); fprintf(out, "deps_config := \\\n");
@ -44,12 +44,15 @@ int file_write_dep(const char *name)
else else
fprintf(out, "\t%s\n", file->name); fprintf(out, "\t%s\n", file->name);
} }
fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n"); fprintf(out, "\ninclude/config/auto.conf: \\\n"
"\t$(deps_config)\n\n"
"$(deps_config): ;\n");
fclose(out); fclose(out);
rename(".config.tmp", name); rename("..config.tmp", name);
return 0; return 0;
} }
/* Allocate initial growable sting */ /* Allocate initial growable sting */
struct gstr str_new(void) struct gstr str_new(void)
{ {
@ -100,7 +103,7 @@ void str_printf(struct gstr *gs, const char *fmt, ...)
va_end(ap); va_end(ap);
} }
/* Retreive value of growable string */ /* Retrieve value of growable string */
const char *str_get(struct gstr *gs) const char *str_get(struct gstr *gs)
{ {
return gs->s; return gs->s;

View File

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

View File

@ -0,0 +1,242 @@
/* ANSI-C code produced by gperf version 3.0.1 */
/* Command-line: gperf */
/* Computed positions: -k'1,3' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
struct kconf_id;
/* maximum key range = 45, duplicates = 0 */
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
kconf_id_hash (register const char *str, register unsigned int len)
{
static unsigned char asso_values[] =
{
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 25, 30, 15,
0, 15, 0, 47, 5, 15, 47, 47, 30, 20,
5, 0, 25, 15, 0, 0, 10, 35, 47, 47,
5, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47
};
register int hval = len;
switch (hval)
{
default:
hval += asso_values[(unsigned char)str[2]];
/*FALLTHROUGH*/
case 2:
case 1:
hval += asso_values[(unsigned char)str[0]];
break;
}
return hval;
}
struct kconf_id_strings_t
{
char kconf_id_strings_str2[sizeof("on")];
char kconf_id_strings_str6[sizeof("string")];
char kconf_id_strings_str7[sizeof("default")];
char kconf_id_strings_str8[sizeof("def_bool")];
char kconf_id_strings_str10[sizeof("range")];
char kconf_id_strings_str11[sizeof("def_boolean")];
char kconf_id_strings_str12[sizeof("def_tristate")];
char kconf_id_strings_str13[sizeof("hex")];
char kconf_id_strings_str14[sizeof("defconfig_list")];
char kconf_id_strings_str16[sizeof("option")];
char kconf_id_strings_str17[sizeof("if")];
char kconf_id_strings_str18[sizeof("optional")];
char kconf_id_strings_str20[sizeof("endif")];
char kconf_id_strings_str21[sizeof("choice")];
char kconf_id_strings_str22[sizeof("endmenu")];
char kconf_id_strings_str23[sizeof("requires")];
char kconf_id_strings_str24[sizeof("endchoice")];
char kconf_id_strings_str26[sizeof("config")];
char kconf_id_strings_str27[sizeof("modules")];
char kconf_id_strings_str28[sizeof("int")];
char kconf_id_strings_str29[sizeof("menu")];
char kconf_id_strings_str31[sizeof("prompt")];
char kconf_id_strings_str32[sizeof("depends")];
char kconf_id_strings_str33[sizeof("tristate")];
char kconf_id_strings_str34[sizeof("bool")];
char kconf_id_strings_str35[sizeof("menuconfig")];
char kconf_id_strings_str36[sizeof("select")];
char kconf_id_strings_str37[sizeof("boolean")];
char kconf_id_strings_str39[sizeof("help")];
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 =
{
"on",
"string",
"default",
"def_bool",
"range",
"def_boolean",
"def_tristate",
"hex",
"defconfig_list",
"option",
"if",
"optional",
"endif",
"choice",
"endmenu",
"requires",
"endchoice",
"config",
"modules",
"int",
"menu",
"prompt",
"depends",
"tristate",
"bool",
"menuconfig",
"select",
"boolean",
"help",
"source",
"comment",
"mainmenu",
"enable"
};
#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
#ifdef __GNUC__
__inline
#endif
struct kconf_id *
kconf_id_lookup (register const char *str, register unsigned int len)
{
enum
{
TOTAL_KEYWORDS = 33,
MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 14,
MIN_HASH_VALUE = 2,
MAX_HASH_VALUE = 46
};
static struct kconf_id wordlist[] =
{
{-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
{-1}, {-1}, {-1},
{(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},
{(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_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE},
{(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_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION},
{-1},
{(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_str17, T_IF, TF_COMMAND|TF_PARAM},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND},
{-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_CHOICE, TF_COMMAND},
{(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_REQUIRES, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24, T_ENDCHOICE, 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_str28, T_TYPE, TF_COMMAND, S_INT},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
{-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_str32, T_DEPENDS, 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_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},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_HELP, TF_COMMAND},
{-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_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)
{
register int key = kconf_id_hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
register int o = wordlist[key].name;
if (o >= 0)
{
register const char *s = o + kconf_id_strings;
if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
return &wordlist[key];
}
}
}
return 0;
}

View File

@ -18,8 +18,12 @@
#define START_STRSIZE 16 #define START_STRSIZE 16
char *text; static struct {
static char *text_ptr; struct file *file;
int lineno;
} current_pos;
static char *text;
static int text_size, text_asize; static int text_size, text_asize;
struct buffer { struct buffer {
@ -32,29 +36,28 @@ struct buffer *current_buf;
static int last_ts, first_ts; static int last_ts, first_ts;
static void zconf_endhelp(void); static void zconf_endhelp(void);
static struct buffer *zconf_endfile(void); static void zconf_endfile(void);
void new_string(void) void new_string(void)
{ {
text = malloc(START_STRSIZE); text = malloc(START_STRSIZE);
text_asize = START_STRSIZE; text_asize = START_STRSIZE;
text_ptr = text;
text_size = 0; text_size = 0;
*text_ptr = 0; *text = 0;
} }
void append_string(const char *str, int size) void append_string(const char *str, int size)
{ {
int new_size = text_size + size + 1; int new_size = text_size + size + 1;
if (new_size > text_asize) { if (new_size > text_asize) {
new_size += START_STRSIZE - 1;
new_size &= -START_STRSIZE;
text = realloc(text, new_size); text = realloc(text, new_size);
text_asize = new_size; text_asize = new_size;
text_ptr = text + text_size;
} }
memcpy(text_ptr, str, size); memcpy(text + text_size, str, size);
text_ptr += size;
text_size += size; text_size += size;
*text_ptr = 0; text[text_size] = 0;
} }
void alloc_string(const char *str, int size) void alloc_string(const char *str, int size)
@ -72,10 +75,13 @@ n [A-Za-z0-9_]
int str = 0; int str = 0;
int ts, i; int ts, i;
[ \t]*#.*\n current_file->lineno++; [ \t]*#.*\n |
[ \t]*\n {
current_file->lineno++;
return T_EOL;
}
[ \t]*#.* [ \t]*#.*
[ \t]*\n current_file->lineno++; return T_EOL;
[ \t]+ { [ \t]+ {
BEGIN(COMMAND); BEGIN(COMMAND);
@ -88,42 +94,25 @@ n [A-Za-z0-9_]
<COMMAND>{ <COMMAND>{
"mainmenu" BEGIN(PARAM); return T_MAINMENU;
"menu" BEGIN(PARAM); return T_MENU;
"endmenu" BEGIN(PARAM); return T_ENDMENU;
"source" BEGIN(PARAM); return T_SOURCE;
"choice" BEGIN(PARAM); return T_CHOICE;
"endchoice" BEGIN(PARAM); return T_ENDCHOICE;
"comment" BEGIN(PARAM); return T_COMMENT;
"config" BEGIN(PARAM); return T_CONFIG;
"menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
"help" BEGIN(PARAM); return T_HELP;
"if" BEGIN(PARAM); return T_IF;
"endif" BEGIN(PARAM); return T_ENDIF;
"depends" BEGIN(PARAM); return T_DEPENDS;
"requires" BEGIN(PARAM); return T_REQUIRES;
"optional" BEGIN(PARAM); return T_OPTIONAL;
"default" BEGIN(PARAM); return T_DEFAULT;
"prompt" BEGIN(PARAM); return T_PROMPT;
"tristate" BEGIN(PARAM); return T_TRISTATE;
"def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
"bool" BEGIN(PARAM); return T_BOOLEAN;
"boolean" BEGIN(PARAM); return T_BOOLEAN;
"def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
"def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
"int" BEGIN(PARAM); return T_INT;
"hex" BEGIN(PARAM); return T_HEX;
"string" BEGIN(PARAM); return T_STRING;
"select" BEGIN(PARAM); return T_SELECT;
"enable" BEGIN(PARAM); return T_SELECT;
"range" BEGIN(PARAM); return T_RANGE;
{n}+ { {n}+ {
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
BEGIN(PARAM);
current_pos.file = current_file;
current_pos.lineno = current_file->lineno;
if (id && id->flags & TF_COMMAND) {
zconflval.id = id;
return id->token;
}
alloc_string(yytext, yyleng); alloc_string(yytext, yyleng);
zconflval.string = text; zconflval.string = text;
return T_WORD; return T_WORD;
} }
. .
\n current_file->lineno++; BEGIN(INITIAL); \n {
BEGIN(INITIAL);
current_file->lineno++;
return T_EOL;
}
} }
<PARAM>{ <PARAM>{
@ -134,8 +123,6 @@ n [A-Za-z0-9_]
"!" return T_NOT; "!" return T_NOT;
"=" return T_EQUAL; "=" return T_EQUAL;
"!=" return T_UNEQUAL; "!=" return T_UNEQUAL;
"if" return T_IF;
"on" return T_ON;
\"|\' { \"|\' {
str = yytext[0]; str = yytext[0];
new_string(); new_string();
@ -144,6 +131,11 @@ n [A-Za-z0-9_]
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL; \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
--- /* ignore */ --- /* ignore */
({n}|[-/.])+ { ({n}|[-/.])+ {
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
if (id && id->flags & TF_PARAM) {
zconflval.id = id;
return id->token;
}
alloc_string(yytext, yyleng); alloc_string(yytext, yyleng);
zconflval.string = text; zconflval.string = text;
return T_WORD; return T_WORD;
@ -236,9 +228,9 @@ n [A-Za-z0-9_]
} }
<<EOF>> { <<EOF>> {
if (current_buf) { if (current_file) {
zconf_endfile(); zconf_endfile();
return T_EOF; return T_EOL;
} }
fclose(yyin); fclose(yyin);
yyterminate(); yyterminate();
@ -329,7 +321,7 @@ void zconf_nextfile(const char *name)
current_file = file; current_file = file;
} }
static struct buffer *zconf_endfile(void) static void zconf_endfile(void)
{ {
struct buffer *parent; struct buffer *parent;
@ -345,22 +337,14 @@ static struct buffer *zconf_endfile(void)
} }
free(current_buf); free(current_buf);
current_buf = parent; current_buf = parent;
return parent;
} }
int zconf_lineno(void) int zconf_lineno(void)
{ {
if (current_buf) return current_pos.lineno;
return current_file->lineno - 1;
else
return 0;
} }
char *zconf_curname(void) char *zconf_curname(void)
{ {
if (current_buf) return current_pos.file ? current_pos.file->name : "<none>";
return current_file->name;
else
return "<none>";
} }

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,11 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#include "zconf.hash.c"
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001 #define PRINTD 0x0001
@ -20,61 +25,60 @@ int cdebug = PRINTD;
extern int zconflex(void); extern int zconflex(void);
static void zconfprint(const char *err, ...); static void zconfprint(const char *err, ...);
static void zconf_error(const char *err, ...);
static void zconferror(const char *err); static void zconferror(const char *err);
static bool zconf_endtoken(int token, int starttoken, int endtoken); static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[257]; struct symbol *symbol_hash[257];
static struct menu *current_menu, *current_entry; static struct menu *current_menu, *current_entry;
#define YYDEBUG 0
#if YYDEBUG
#define YYERROR_VERBOSE #define YYERROR_VERBOSE
#endif
%} %}
%expect 40 %expect 26
%union %union
{ {
int token;
char *string; char *string;
struct file *file;
struct symbol *symbol; struct symbol *symbol;
struct expr *expr; struct expr *expr;
struct menu *menu; struct menu *menu;
struct kconf_id *id;
} }
%token T_MAINMENU %token <id>T_MAINMENU
%token T_MENU %token <id>T_MENU
%token T_ENDMENU %token <id>T_ENDMENU
%token T_SOURCE %token <id>T_SOURCE
%token T_CHOICE %token <id>T_CHOICE
%token T_ENDCHOICE %token <id>T_ENDCHOICE
%token T_COMMENT %token <id>T_COMMENT
%token T_CONFIG %token <id>T_CONFIG
%token T_MENUCONFIG %token <id>T_MENUCONFIG
%token T_HELP %token <id>T_HELP
%token <string> T_HELPTEXT %token <string> T_HELPTEXT
%token T_IF %token <id>T_IF
%token T_ENDIF %token <id>T_ENDIF
%token T_DEPENDS %token <id>T_DEPENDS
%token T_REQUIRES %token <id>T_REQUIRES
%token T_OPTIONAL %token <id>T_OPTIONAL
%token T_PROMPT %token <id>T_PROMPT
%token T_DEFAULT %token <id>T_TYPE
%token T_TRISTATE %token <id>T_DEFAULT
%token T_DEF_TRISTATE %token <id>T_SELECT
%token T_BOOLEAN %token <id>T_RANGE
%token T_DEF_BOOLEAN %token <id>T_OPTION
%token T_STRING %token <id>T_ON
%token T_INT
%token T_HEX
%token <string> T_WORD %token <string> T_WORD
%token <string> T_WORD_QUOTE %token <string> T_WORD_QUOTE
%token T_UNEQUAL %token T_UNEQUAL
%token T_EOF
%token T_EOL
%token T_CLOSE_PAREN %token T_CLOSE_PAREN
%token T_OPEN_PAREN %token T_OPEN_PAREN
%token T_ON %token T_EOL
%token T_SELECT
%token T_RANGE
%left T_OR %left T_OR
%left T_AND %left T_AND
@ -82,38 +86,55 @@ static struct menu *current_menu, *current_entry;
%nonassoc T_NOT %nonassoc T_NOT
%type <string> prompt %type <string> prompt
%type <string> source
%type <symbol> symbol %type <symbol> symbol
%type <expr> expr %type <expr> expr
%type <expr> if_expr %type <expr> if_expr
%type <token> end %type <id> end
%type <id> option_name
%type <menu> if_entry menu_entry choice_entry
%type <string> symbol_option_arg
%destructor {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
$$->file->name, $$->lineno);
if (current_menu == $$)
menu_end_menu();
} if_entry menu_entry choice_entry
%{
#define LKC_DIRECT_LINK
#include "lkc.h"
%}
%% %%
input: /* empty */ input: stmt_list;
| input block
stmt_list:
/* empty */
| stmt_list common_stmt
| stmt_list choice_stmt
| stmt_list menu_stmt
| stmt_list T_MAINMENU prompt nl
| stmt_list end { zconf_error("unexpected end statement"); }
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
| stmt_list option_name error T_EOL
{
zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
}
| stmt_list error T_EOL { zconf_error("invalid statement"); }
; ;
block: common_block option_name:
| choice_stmt T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
| menu_stmt
| T_MAINMENU prompt nl_or_eof
| T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
| T_ENDIF { zconfprint("unexpected 'endif' statement"); }
| T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
| error nl_or_eof { zconfprint("syntax error"); yyerrok; }
; ;
common_block: common_stmt:
if_stmt T_EOL
| if_stmt
| comment_stmt | comment_stmt
| config_stmt | config_stmt
| menuconfig_stmt | menuconfig_stmt
| source_stmt | source_stmt
| nl_or_eof ;
option_error:
T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
| error T_EOL { zconf_error("invalid option"); }
; ;
@ -154,53 +175,19 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
config_option_list: config_option_list:
/* empty */ /* empty */
| config_option_list config_option | config_option_list config_option
| config_option_list symbol_option
| config_option_list depends | config_option_list depends
| config_option_list help | config_option_list help
| config_option_list option_error
| config_option_list T_EOL | config_option_list T_EOL
; ;
config_option: T_TRISTATE prompt_stmt_opt T_EOL config_option: T_TYPE prompt_stmt_opt T_EOL
{ {
menu_set_type(S_TRISTATE); menu_set_type($1->stype);
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
}; zconf_curname(), zconf_lineno(),
$1->stype);
config_option: T_DEF_TRISTATE expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
menu_set_type(S_TRISTATE);
printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_BOOLEAN prompt_stmt_opt T_EOL
{
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_DEF_BOOLEAN expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
menu_set_type(S_BOOLEAN);
printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
};
config_option: T_INT prompt_stmt_opt T_EOL
{
menu_set_type(S_INT);
printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
};
config_option: T_HEX prompt_stmt_opt T_EOL
{
menu_set_type(S_HEX);
printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
};
config_option: T_STRING prompt_stmt_opt T_EOL
{
menu_set_type(S_STRING);
printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
}; };
config_option: T_PROMPT prompt if_expr T_EOL config_option: T_PROMPT prompt if_expr T_EOL
@ -212,7 +199,11 @@ config_option: T_PROMPT prompt if_expr T_EOL
config_option: T_DEFAULT expr if_expr T_EOL config_option: T_DEFAULT expr if_expr T_EOL
{ {
menu_add_expr(P_DEFAULT, $2, $3); menu_add_expr(P_DEFAULT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); if ($1->stype != S_UNKNOWN)
menu_set_type($1->stype);
printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
zconf_curname(), zconf_lineno(),
$1->stype);
}; };
config_option: T_SELECT T_WORD if_expr T_EOL config_option: T_SELECT T_WORD if_expr T_EOL
@ -227,6 +218,26 @@ config_option: T_RANGE symbol symbol if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
}; };
symbol_option: T_OPTION symbol_option_list T_EOL
;
symbol_option_list:
/* empty */
| symbol_option_list T_WORD symbol_option_arg
{
struct kconf_id *id = kconf_id_lookup($2, strlen($2));
if (id && id->flags & TF_OPTION)
menu_add_option(id->token, $3);
else
zconfprint("warning: ignoring unknown option %s", $2);
free($2);
};
symbol_option_arg:
/* empty */ { $$ = NULL; }
| T_EQUAL prompt { $$ = $2; }
;
/* choice entry */ /* choice entry */
choice: T_CHOICE T_EOL choice: T_CHOICE T_EOL
@ -240,8 +251,7 @@ choice: T_CHOICE T_EOL
choice_entry: choice choice_option_list choice_entry: choice choice_option_list
{ {
menu_end_entry(); $$ = menu_add_menu();
menu_add_menu();
}; };
choice_end: end choice_end: end
@ -252,13 +262,8 @@ choice_end: end
} }
}; };
choice_stmt: choice_stmt: choice_entry choice_block choice_end
choice_entry choice_block choice_end ;
| choice_entry choice_block
{
printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
choice_option_list: choice_option_list:
/* empty */ /* empty */
@ -266,6 +271,7 @@ choice_option_list:
| choice_option_list depends | choice_option_list depends
| choice_option_list help | choice_option_list help
| choice_option_list T_EOL | choice_option_list T_EOL
| choice_option_list option_error
; ;
choice_option: T_PROMPT prompt if_expr T_EOL choice_option: T_PROMPT prompt if_expr T_EOL
@ -274,16 +280,15 @@ choice_option: T_PROMPT prompt if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
}; };
choice_option: T_TRISTATE prompt_stmt_opt T_EOL choice_option: T_TYPE prompt_stmt_opt T_EOL
{ {
menu_set_type(S_TRISTATE); if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); menu_set_type($1->stype);
}; printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
zconf_curname(), zconf_lineno(),
choice_option: T_BOOLEAN prompt_stmt_opt T_EOL $1->stype);
{ } else
menu_set_type(S_BOOLEAN); YYERROR;
printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
}; };
choice_option: T_OPTIONAL T_EOL choice_option: T_OPTIONAL T_EOL
@ -294,24 +299,27 @@ choice_option: T_OPTIONAL T_EOL
choice_option: T_DEFAULT T_WORD if_expr T_EOL choice_option: T_DEFAULT T_WORD if_expr T_EOL
{ {
menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); if ($1->stype == S_UNKNOWN) {
printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
printd(DEBUG_PARSE, "%s:%d:default\n",
zconf_curname(), zconf_lineno());
} else
YYERROR;
}; };
choice_block: choice_block:
/* empty */ /* empty */
| choice_block common_block | choice_block common_stmt
; ;
/* if entry */ /* if entry */
if: T_IF expr T_EOL if_entry: T_IF expr nl
{ {
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL); menu_add_entry(NULL);
menu_add_dep($2); menu_add_dep($2);
menu_end_entry(); $$ = menu_add_menu();
menu_add_menu();
}; };
if_end: end if_end: end
@ -322,17 +330,12 @@ if_end: end
} }
}; };
if_stmt: if_stmt: if_entry if_block if_end
if if_block if_end ;
| if if_block
{
printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
if_block: if_block:
/* empty */ /* empty */
| if_block common_block | if_block common_stmt
| if_block menu_stmt | if_block menu_stmt
| if_block choice_stmt | if_block choice_stmt
; ;
@ -342,14 +345,13 @@ if_block:
menu: T_MENU prompt T_EOL menu: T_MENU prompt T_EOL
{ {
menu_add_entry(NULL); menu_add_entry(NULL);
menu_add_prop(P_MENU, $2, NULL, NULL); menu_add_prompt(P_MENU, $2, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
}; };
menu_entry: menu depends_list menu_entry: menu depends_list
{ {
menu_end_entry(); $$ = menu_add_menu();
menu_add_menu();
}; };
menu_end: end menu_end: end
@ -360,31 +362,20 @@ menu_end: end
} }
}; };
menu_stmt: menu_stmt: menu_entry menu_block menu_end
menu_entry menu_block menu_end ;
| menu_entry menu_block
{
printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
zconfnerrs++;
};
menu_block: menu_block:
/* empty */ /* empty */
| menu_block common_block | menu_block common_stmt
| menu_block menu_stmt | menu_block menu_stmt
| menu_block choice_stmt | menu_block choice_stmt
| menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
; ;
source: T_SOURCE prompt T_EOL source_stmt: T_SOURCE prompt T_EOL
{ {
$$ = $2;
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
}; zconf_nextfile($2);
source_stmt: source
{
zconf_nextfile($1);
}; };
/* comment entry */ /* comment entry */
@ -392,7 +383,7 @@ source_stmt: source
comment: T_COMMENT prompt T_EOL comment: T_COMMENT prompt T_EOL
{ {
menu_add_entry(NULL); menu_add_entry(NULL);
menu_add_prop(P_COMMENT, $2, NULL, NULL); menu_add_prompt(P_COMMENT, $2, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
}; };
@ -416,9 +407,11 @@ help: help_start T_HELPTEXT
/* depends option */ /* depends option */
depends_list: /* empty */ depends_list:
| depends_list depends /* empty */
| depends_list T_EOL | depends_list depends
| depends_list T_EOL
| depends_list option_error
; ;
depends: T_DEPENDS T_ON expr T_EOL depends: T_DEPENDS T_ON expr T_EOL
@ -443,20 +436,22 @@ prompt_stmt_opt:
/* empty */ /* empty */
| prompt if_expr | prompt if_expr
{ {
menu_add_prop(P_PROMPT, $1, NULL, $2); menu_add_prompt(P_PROMPT, $1, $2);
}; };
prompt: T_WORD prompt: T_WORD
| T_WORD_QUOTE | T_WORD_QUOTE
; ;
end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } end: T_ENDMENU T_EOL { $$ = $1; }
| T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } | T_ENDCHOICE T_EOL { $$ = $1; }
| T_ENDIF nl_or_eof { $$ = T_ENDIF; } | T_ENDIF T_EOL { $$ = $1; }
; ;
nl_or_eof: nl:
T_EOL | T_EOF; T_EOL
| nl T_EOL
;
if_expr: /* empty */ { $$ = NULL; } if_expr: /* empty */ { $$ = NULL; }
| T_IF expr { $$ = $2; } | T_IF expr { $$ = $2; }
@ -486,22 +481,30 @@ void conf_parse(const char *name)
sym_init(); sym_init();
menu_init(); menu_init();
modules_sym = sym_lookup("MODULES", 0); modules_sym = sym_lookup(NULL, 0);
rootmenu.prompt = menu_add_prop(P_MENU, "Buildroot Configuration", NULL, NULL); modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO;
rootmenu.prompt = menu_add_prompt(P_MENU, "Buildroot Configuration", NULL);
//zconfdebug = 1; #if YYDEBUG
if (getenv("ZCONF_DEBUG"))
zconfdebug = 1;
#endif
zconfparse(); zconfparse();
if (zconfnerrs) if (zconfnerrs)
exit(1); exit(1);
if (!modules_sym->prop) {
struct property *prop;
prop = prop_alloc(P_DEFAULT, modules_sym);
prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
}
menu_finalize(&rootmenu); menu_finalize(&rootmenu);
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) sym_check_deps(sym);
printf("\n");
else
sym->flags |= SYMBOL_CHECK_DONE;
} }
sym_change_count = 1; sym_set_change_count(1);
} }
const char *zconf_tokenname(int token) const char *zconf_tokenname(int token)
@ -513,20 +516,25 @@ const char *zconf_tokenname(int token)
case T_ENDCHOICE: return "endchoice"; case T_ENDCHOICE: return "endchoice";
case T_IF: return "if"; case T_IF: return "if";
case T_ENDIF: return "endif"; case T_ENDIF: return "endif";
case T_DEPENDS: return "depends";
} }
return "<token>"; return "<token>";
} }
static bool zconf_endtoken(int token, int starttoken, int endtoken) static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
{ {
if (token != endtoken) { if (id->token != endtoken) {
zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); zconf_error("unexpected '%s' within %s block",
kconf_id_strings + id->name, zconf_tokenname(starttoken));
zconfnerrs++; zconfnerrs++;
return false; return false;
} }
if (current_menu->file != current_file) { if (current_menu->file != current_file) {
zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); zconf_error("'%s' in different file than '%s'",
zconfprint("location of the '%s'", zconf_tokenname(starttoken)); kconf_id_strings + id->name, zconf_tokenname(starttoken));
fprintf(stderr, "%s:%d: location of the '%s'\n",
current_menu->file->name, current_menu->lineno,
zconf_tokenname(starttoken));
zconfnerrs++; zconfnerrs++;
return false; return false;
} }
@ -537,7 +545,19 @@ static void zconfprint(const char *err, ...)
{ {
va_list ap; va_list ap;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
fprintf(stderr, "\n");
}
static void zconf_error(const char *err, ...)
{
va_list ap;
zconfnerrs++;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
va_start(ap, err); va_start(ap, err);
vfprintf(stderr, err, ap); vfprintf(stderr, err, ap);
va_end(ap); va_end(ap);
@ -546,7 +566,9 @@ static void zconfprint(const char *err, ...)
static void zconferror(const char *err) static void zconferror(const char *err)
{ {
#if YYDEBUG
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
#endif
} }
void print_quoted_string(FILE *out, const char *str) void print_quoted_string(FILE *out, const char *str)