summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/Config.in4
-rw-r--r--payloads/libpayload/Makefile140
-rw-r--r--payloads/libpayload/i386/Makefile.inc6
-rw-r--r--payloads/libpayload/include/libpayload.h1
-rw-r--r--payloads/libpayload/util/kconfig/.gitignore19
-rw-r--r--payloads/libpayload/util/kconfig/Makefile384
-rw-r--r--payloads/libpayload/util/kconfig/POTFILES.in17
-rwxr-xr-xpayloads/libpayload/util/kconfig/check.sh14
-rw-r--r--payloads/libpayload/util/kconfig/conf.c154
-rw-r--r--payloads/libpayload/util/kconfig/confdata.c693
-rw-r--r--payloads/libpayload/util/kconfig/expr.c81
-rw-r--r--payloads/libpayload/util/kconfig/expr.h40
-rw-r--r--payloads/libpayload/util/kconfig/gconf.c1636
-rw-r--r--payloads/libpayload/util/kconfig/gconf.glade648
-rw-r--r--payloads/libpayload/util/kconfig/images.c326
-rw-r--r--payloads/libpayload/util/kconfig/kxgettext.c8
-rw-r--r--payloads/libpayload/util/kconfig/lex.zconf.c_shipped205
-rw-r--r--payloads/libpayload/util/kconfig/lkc.h20
-rw-r--r--payloads/libpayload/util/kconfig/lkc_proto.h10
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/.gitignore4
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/BIG.FAT.WARNING2
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/Makefile32
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/check-lxdialog.sh42
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/checklist.c184
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/colors.h154
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/dialog.h153
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/inputbox.c52
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/lxdialog.c204
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/menubox.c174
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/msgbox.c71
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/textbox.c418
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/util.c515
-rw-r--r--payloads/libpayload/util/kconfig/lxdialog/yesno.c30
-rw-r--r--payloads/libpayload/util/kconfig/mconf.c704
-rw-r--r--payloads/libpayload/util/kconfig/menu.c104
-rw-r--r--payloads/libpayload/util/kconfig/qconf.cc1764
-rw-r--r--payloads/libpayload/util/kconfig/qconf.h334
-rw-r--r--payloads/libpayload/util/kconfig/symbol.c173
-rw-r--r--payloads/libpayload/util/kconfig/util.c36
-rw-r--r--payloads/libpayload/util/kconfig/zconf.gperf7
-rw-r--r--payloads/libpayload/util/kconfig/zconf.hash.c231
-rw-r--r--payloads/libpayload/util/kconfig/zconf.hash.c_shipped208
-rw-r--r--payloads/libpayload/util/kconfig/zconf.l7
-rw-r--r--payloads/libpayload/util/kconfig/zconf.tab.c_shipped1588
-rw-r--r--payloads/libpayload/util/kconfig/zconf.y66
45 files changed, 8424 insertions, 3239 deletions
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index ea869a5bdc..6c02c6ec42 100644
--- a/payloads/libpayload/Config.in
+++ b/payloads/libpayload/Config.in
@@ -29,10 +29,6 @@
mainmenu "Libpayload Configuration"
-config HAVE_DOT_CONFIG
- bool
- default y
-
# When (if) we support multiple architectures, this will become an option.
config TARGET_I386
bool
diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile
index 04ebbb0195..b862f8da0f 100644
--- a/payloads/libpayload/Makefile
+++ b/payloads/libpayload/Makefile
@@ -2,6 +2,7 @@
## This file is part of the libpayload project.
##
## Copyright (C) 2008 Advanced Micro Devices, Inc.
+## Copyright (C) 2008 Uwe Hermann <uwe@hermann-uwe.de>
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
@@ -27,29 +28,41 @@
## SUCH DAMAGE.
##
-BASE_DIR=$(shell pwd)
-KCONFIG_DIR=util/kconfig
-DESTDIR=/opt
-
-ifeq (.config, $(wildcard .config))
-dot-config := 1
-else
-dot-config := 0
-config-targets := 1
+export src := $(shell pwd)
+export srctree := $(src)
+export srck := $(src)/util/kconfig
+export obj := $(src)/build
+export objk := $(src)/build/util/kconfig
+
+export KERNELVERSION := 0.1.0
+export KCONFIG_AUTOHEADER := $(obj)/config.h
+export KCONFIG_AUTOCONFIG := $(obj)/auto.conf
+
+CONFIG_SHELL := sh
+KBUILD_DEFCONFIG := configs/defconfig
+UNAME_RELEASE := $(shell uname -r)
+HAVE_DOTCONFIG := $(wildcard .config)
+MAKEFLAGS += -rR --no-print-directory
+
+# Make is silent per default, but 'make V=1' will show all compiler calls.
+ifneq ($(V),1)
+Q := @
endif
-ifneq ($(filter textconfig oldconfig defconfig menuconfig,$(MAKECMDGOALS)),)
-config-targets := 1
-dot-config := 0
-endif
+HOSTCC = gcc
+HOSTCXX = g++
+HOSTCFLAGS := -I$(srck) -I$(objk)
+HOSTCXXFLAGS := -I$(srck) -I$(objk)
+
+DESTDIR = /opt
+
+ifeq ($(strip $(HAVE_DOTCONFIG)),)
-ifeq ($(dot-config),0)
-all: .config
+all: config
-.config: oldconfig
- @echo "Configuration completed - type make to build libpayload"
else
--include .config
+
+include $(src)/.config
ARCHDIR-$(CONFIG_TARGET_I386) := i386
@@ -61,7 +74,8 @@ BUILD-$(CONFIG_TINYCURSES) += curses/Makefile.inc
include $(PLATFORM-y) $(BUILD-y)
-INCLUDES := -I./include
+OBJS := $(patsubst %,$(obj)/%,$(TARGETS-y))
+INCLUDES := -Iinclude -Ibuild
INCLUDES += -I$(shell $(CC) -print-search-dirs | head -n 1 | cut -d' ' -f2)include
try-run= $(shell set -e; \
@@ -79,64 +93,60 @@ STACKPROTECT += $(call cc-option, -fno-stack-protector,)
# TODO: Re-add -Os as soon as we find out why it caused problems.
CFLAGS := -Wall -Werror $(STACKPROTECT) -nostdinc $(INCLUDES)
-lib: lib/libpayload.a lib/$(ARCHDIR-y)/head.o
+all: lib
+
+lib: prepare $(obj)/lib/libpayload.a copystuff
-lib/libpayload.a: $(TARGETS-y)
- @ $(AR) rc $@ $(TARGETS-y)
+# Copy libpayload.a and head.o into $(src)/lib where lpgcc et al expect them.
+copystuff:
+ $(Q)cp $(obj)/$(ARCHDIR-y)/head.S.o $(src)/lib/$(ARCHDIR-y)/head.o
+ $(Q)cp $(obj)/lib/libpayload.a $(src)/lib
-lib/$(ARCHDIR-y)/head.o: $(ARCHDIR-y)/head.o
- @ mkdir -p lib/$(ARCHDIR-y)
- @ cp $< $@
+$(obj)/lib/libpayload.a: $(OBJS)
+ $(Q)printf " AR $(subst $(shell pwd)/,,$(@))\n"
+ $(Q)$(AR) rc $@ $(OBJS)
-%.o: %.c
- $(CC) -m32 $(CFLAGS) -c -o $@ $<
+$(obj)/%.o: $(src)/%.c
+ $(Q)printf " CC $(subst $(shell pwd)/,,$(@))\n"
+ $(Q)$(CC) -m32 $(CFLAGS) -c -o $@ $<
-%.o: %.S
- $(AS) --32 -o $@ $<
+$(obj)/%.S.o: $(src)/%.S
+ $(Q)printf " AS $(subst $(shell pwd)/,,$(@))\n"
+ $(Q)$(AS) --32 -o $@ $<
+
+endif
install: lib
- install -m 755 -d $(DESTDIR)/libpayload/lib
- cp -r lib/* $(DESTDIR)/libpayload/lib/
- install -m 755 -d $(DESTDIR)/libpayload/include
- for file in `find include -name *.h -type f`; do \
+ $(Q)printf " INSTALL $(DESTDIR)/libpayload/lib\n"
+ $(Q)install -m 755 -d $(DESTDIR)/libpayload/lib
+ $(Q)cp -r lib/* $(DESTDIR)/libpayload/lib/
+ $(Q)printf " INSTALL $(DESTDIR)/libpayload/include\n"
+ $(Q)install -m 755 -d $(DESTDIR)/libpayload/include
+ $(Q)for file in `find include -name *.h -type f`; do \
install -m 644 -D $$file $(DESTDIR)/libpayload/$$file; \
done
- install -m 755 -d $(DESTDIR)/libpayload/bin
- install -m 755 bin/lpgcc $(DESTDIR)/libpayload/bin
- install -m 755 bin/lpas $(DESTDIR)/libpayload/bin
- install -m 644 bin/lp.functions $(DESTDIR)/libpayload/bin
+ $(Q)printf " INSTALL $(DESTDIR)/libpayload/bin\n"
+ $(Q)install -m 755 -d $(DESTDIR)/libpayload/bin
+ $(Q)install -m 755 bin/lpgcc $(DESTDIR)/libpayload/bin
+ $(Q)install -m 755 bin/lpas $(DESTDIR)/libpayload/bin
+ $(Q)install -m 644 bin/lp.functions $(DESTDIR)/libpayload/bin
+
+prepare:
+ $(Q)mkdir -p $(obj)/util/kconfig/lxdialog
+ $(Q)mkdir -p $(obj)/crypto $(obj)/curses $(obj)/drivers/video
+ $(Q)mkdir -p $(obj)/i386 $(obj)/lib/$(ARCHDIR-y) $(obj)/libc
+ $(Q)mkdir -p $(src)/lib/$(ARCHDIR-y)
clean:
- @ rm -f $(TARGETS-y)
- @ rm -f lib/libpayload.a lib/$(ARCHDIR-y)/head.o
+ $(Q)rm -rf $(obj)/crypto $(obj)/curses $(obj)/drivers
+ $(Q)rm -rf $(obj)/i386 $(obj)/lib $(obj)/libc
+ $(Q)rm -rf $(src)/lib/i386 $(src)/lib/libpayload.a
distclean: clean
- @ make -C $(KCONFIG_DIR) clean
- @ rm -f $(KCONFIG_DIR)/lxdialog/lxdialog
- @ rm -f .config .kconfig.d include/autoconf.h
-endif
-
-ifeq ($(config-targets),1)
-
-$(KCONFIG_DIR)/conf:
- make -C $(KCONFIG_DIR) conf
-
-$(KCONFIG_DIR)/mconf:
- make -C $(KCONFIG_DIR) mconf
+ $(Q)rm -rf build
+ $(Q)rm -f .config .config.old ..config.tmp .kconfig.d .tmpconfig*
-$(KCONFIG_DIR)/lxdialog/lxdialog:
- make -C $(KCONFIG_DIR)/lxdialog lxdialog
+include util/kconfig/Makefile
-textconfig: $(KCONFIG_DIR)/conf
- @$(KCONFIG_DIR)/conf $(BASE_DIR)/Config.in
+.PHONY: $(PHONY) prepare clean distclean
-oldconfig: $(KCONFIG_DIR)/conf
- @$(KCONFIG_DIR)/conf -o $(BASE_DIR)/Config.in
-
-defconfig: $(KCONFIG_DIR)/conf
- @$(KCONFIG_DIR)/conf -d $(BASE_DIR)/Config.in
-
-menuconfig: $(KCONFIG_DIR)/lxdialog/lxdialog $(KCONFIG_DIR)/mconf
- @$(KCONFIG_DIR)/mconf $(BASE_DIR)/Config.in
-
-endif
diff --git a/payloads/libpayload/i386/Makefile.inc b/payloads/libpayload/i386/Makefile.inc
index e8d9339880..f12511f3e1 100644
--- a/payloads/libpayload/i386/Makefile.inc
+++ b/payloads/libpayload/i386/Makefile.inc
@@ -27,6 +27,6 @@
## SUCH DAMAGE.
##
-TARGETS-y += i386/head.o i386/main.o i386/sysinfo.o
-TARGETS-y += i386/timer.o i386/coreboot.o i386/util.o
-TARGETS-y += i386/exec.o
+TARGETS-y += i386/head.S.o i386/main.o i386/sysinfo.o
+TARGETS-y += i386/timer.o i386/coreboot.o i386/util.S.o
+TARGETS-y += i386/exec.S.o
diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h
index 6ad8940c08..188039e0f4 100644
--- a/payloads/libpayload/include/libpayload.h
+++ b/payloads/libpayload/include/libpayload.h
@@ -30,7 +30,6 @@
#ifndef _LIBPAYLOAD_H
#define _LIBPAYLOAD_H
-#include <autoconf.h>
#include <stddef.h>
#include <arch/types.h>
#include <arch/io.h>
diff --git a/payloads/libpayload/util/kconfig/.gitignore b/payloads/libpayload/util/kconfig/.gitignore
new file mode 100644
index 0000000000..b49584c932
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/.gitignore
@@ -0,0 +1,19 @@
+#
+# Generated files
+#
+config*
+lex.*.c
+*.tab.c
+*.tab.h
+zconf.hash.c
+*.moc
+lkc_defs.h
+
+#
+# configuration programs
+#
+conf
+mconf
+qconf
+gconf
+kxgettext
diff --git a/payloads/libpayload/util/kconfig/Makefile b/payloads/libpayload/util/kconfig/Makefile
index 9b62d756dc..5021d1e09c 100644
--- a/payloads/libpayload/util/kconfig/Makefile
+++ b/payloads/libpayload/util/kconfig/Makefile
@@ -1,107 +1,337 @@
-# Makefile for Pixil config
-# Originally from Busybox
+# ===========================================================================
+# Kernel configuration targets
+# These targets are used from top-level makefile
-HOSTCC ?= gcc
-HOSTCFLAGS=-O0 -g
+PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
-all: ncurses conf mconf
+Kconfig := Config.in
-LIBS = -lncurses
-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>"
+xconfig: prepare $(objk)/qconf
+ $(Q)$(objk)/qconf $(Kconfig)
+
+gconfig: prepare $(objk)/gconf
+ $(Q)$(objk)/gconf $(Kconfig)
+
+menuconfig: prepare $(objk)/mconf
+ $(Q)$(objk)/mconf $(Kconfig)
+
+config: prepare $(objk)/conf
+ $(Q)$(objk)/conf $(Kconfig)
+
+oldconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -o $(Kconfig)
+
+silentoldconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -s $(Kconfig)
+
+# --- UNUSED, ignore ----------------------------------------------------------
+# Create new linux.pot file
+# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
+# The symlink is used to repair a deficiency in arch/um
+update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
+ $(Q)echo " GEN config"
+ $(Q)xgettext --default-domain=linux \
+ --add-comments --keyword=_ --keyword=N_ \
+ --from-code=UTF-8 \
+ --files-from=scripts/kconfig/POTFILES.in \
+ --output $(obj)/config.pot
+ $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
+ $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch
+ $(Q)(for i in `ls arch/`; \
+ do \
+ echo " GEN $$i"; \
+ $(obj)/kxgettext arch/$$i/Kconfig \
+ >> $(obj)/config.pot; \
+ done )
+ $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
+ --output $(obj)/linux.pot
+ $(Q)rm -f arch/um/Kconfig.arch
+ $(Q)rm -f $(obj)/config.pot
+# --- UNUSED, ignore ----------------------------------------------------------
+
+PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
+
+randconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -r $(Kconfig)
+
+allyesconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -y $(Kconfig)
+
+allnoconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -n $(Kconfig)
+
+allmodconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -m $(Kconfig)
+
+defconfig: prepare $(objk)/conf
+ifeq ($(KBUILD_DEFCONFIG),)
+ $(Q)$(objk)/conf -d $(Kconfig)
else
- HOSTNCURSES += -DCURSES_LOC="<curses.h>"
+ @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
+ $(Q)$(objk)/conf -D $(KBUILD_DEFCONFIG) $(Kconfig)
endif
+
+%_defconfig: prepare $(objk)/conf
+ $(Q)$(objk)/conf -D configs/$@ $(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 := $(srck)/lxdialog/check-lxdialog.sh
+
+# Use recursively expanded variables so we do not call gcc unless
+# we really need to do so. (Do not call gcc as part of make mrproper)
+HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+
+HOST_EXTRACFLAGS += -DLOCALE
+
+
+# ===========================================================================
+# 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
-CONF_SRC =conf.c
-MCONF_SRC =mconf.c 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.hash.c
-CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC))
-MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC))
-SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC))
+ifeq ($(gconf-target),1)
+gconf-objs := gconf.o kconfig_load.o zconf.tab.o
+endif
-conf: $(CONF_OBJS) $(SHARED_OBJS)
- $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@
+clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
+ .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
+clean-files += mconf qconf gconf
+clean-files += config.pot coreinfo.pot
-mconf: $(MCONF_OBJS) $(SHARED_OBJS)
- $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ $(LIBS)
+# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
+PHONY += $(objk)/dochecklxdialog
+$(addprefix $(obj)/,$(lxdialog)): $(objk)/dochecklxdialog
+$(objk)/dochecklxdialog:
+ $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES)
-$(CONF_OBJS): %.o : %.c $(SHARED_DEPS)
- $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
+always := dochecklxdialog
-$(MCONF_OBJS): %.o : %.c $(SHARED_DEPS)
- $(HOSTCC) $(HOSTCFLAGS) $(HOSTNCURSES) -I. -c $< -o $@
+# Add environment specific flags
+HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srck)/check.sh $(HOSTCC) $(HOSTCFLAGS))
-lkc_defs.h: lkc_proto.h
- @sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
+# generated files seem to need this to find local include files
+HOSTCFLAGS_lex.zconf.o := -I$(src)
+HOSTCFLAGS_zconf.tab.o := -I$(src)
-###
-# 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
+HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl
+HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
-ifdef LKC_GENPARSER
+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
-%.tab.c %.tab.h: %.y
- bison -t -d -v -b $* -p $(notdir $*) $<
+$(objk)/qconf.o: $(objk)/.tmp_qtcheck
-lex.%.c: %.l
- flex -P$(notdir $*) -o$@ $<
-else
+ifeq ($(qconf-target),1)
+$(objk)/.tmp_qtcheck: $(srck)/Makefile
+-include $(objk)/.tmp_qtcheck
-lex.zconf.o: lex.zconf.c $(SHARED_DEPS)
- $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
+# QT needs some extra effort...
+$(objk)/.tmp_qtcheck: prepare
+ @set -e; 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 QT3 installation. Please make sure that"; \
+ echo "* the QT3 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
-lex.zconf.c: lex.zconf.c_shipped
- cp lex.zconf.c_shipped lex.zconf.c
+$(objk)/gconf.o: $(objk)/.tmp_gtkcheck
-zconf.hash.c: zconf.hash.c_shipped
- cp $< $@
+ifeq ($(gconf-target),1)
+-include $(objk)/.tmp_gtkcheck
-zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(SHARED_DEPS)
- $(HOSTCC) $(HOSTCFLAGS) -I. -c $< -o $@
+# GTK needs some extra effort, too...
+$(objk)/.tmp_gtkcheck: prepare
+ @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
+
+# --- UNUSED, ignore ----------------------------------------------------------
+ifdef UNUSED
+$(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
-zconf.tab.c: zconf.tab.c_shipped
- cp zconf.tab.c_shipped zconf.tab.c
+$(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)/'
+
+# Extract gconf menu items for I18N support
+$(obj)/gconf.glade.h: $(obj)/gconf.glade
+ intltool-extract --type=gettext/glade $(obj)/gconf.glade
endif
+# --- UNUSED, ignore ----------------------------------------------------------
-.PHONY: ncurses
+###
+# 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
-ncurses:
- @echo "main() {}" > lxtemp.c
- @if $(HOSTCC) lxtemp.c $(LIBS) ; then \
- rm -f lxtemp.c a.out; \
- else \
- rm -f lxtemp.c; \
- echo -e "\007" ;\
- echo ">> Unable to find the Ncurses libraries." ;\
- echo ">>" ;\
- echo ">> You must have Ncurses installed in order" ;\
- echo ">> to use 'make menuconfig'" ;\
- echo ;\
- exit 1 ;\
- fi
+ifdef LKC_GENPARSER
+
+# --- UNUSED, ignore ----------------------------------------------------------
+$(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
+# --- UNUSED, ignore ----------------------------------------------------------
+
+endif
+
+$(objk)/qconf: $(patsubst %,$(objk)/%,$(qconf-cxxobjs)) \
+ $(patsubst %,$(objk)/%,$(qconf-objs))
+ $(Q)$(HOSTCXX) $(HOSTCXXFLAGS) $(HOSTLOADLIBES_qconf) -o $@ $^
+$(objk)/gconf: $(patsubst %,$(objk)/%,$(gconf-objs))
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTLOADLIBES_gconf) -o $@ $^
+$(objk)/mconf: $(patsubst %,$(objk)/%,$(mconf-objs))
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) -o $@ $^
+$(objk)/conf: $(patsubst %,$(objk)/%,$(conf-objs))
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
+
+$(objk)/mconf.o: $(srck)/mconf.c
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $<
+$(objk)/conf.o: $(srck)/conf.c
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<
+
+$(objk)/zconf.tab.o: $(objk)/zconf.tab.c $(objk)/lex.zconf.c \
+ $(objk)/zconf.hash.c
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $(objk)/zconf.tab.c
+$(objk)/kconfig_load.o: $(srck)/kconfig_load.c $(objk)/lkc_defs.h
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<
+$(objk)/qconf.o: $(srck)/qconf.cc $(objk)/qconf.moc $(objk)/lkc_defs.h
+ $(Q)$(HOSTCXX) $(HOSTCXXFLAGS) $(HOSTCXXFLAGS_qconf.o) -c -o $@ $<
+$(objk)/gconf.o: $(srck)/gconf.c $(objk)/lkc_defs.h
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOSTCFLAGS_gconf.o) -c -o $@ $<
+$(objk)/%.moc: $(srck)/%.h
+ $(Q)$(KC_QT_MOC) -i $< -o $@
+$(objk)/lkc_defs.h: $(srck)/lkc_proto.h
+ $(Q)sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
+
+$(objk)/lex.zconf.c: $(srck)/lex.zconf.c_shipped
+ $(Q)cp $< $@
+$(objk)/zconf.hash.c: $(srck)/zconf.hash.c_shipped
+ $(Q)cp $< $@
+$(objk)/zconf.tab.c: $(srck)/zconf.tab.c_shipped
+ $(Q)cp $< $@
-clean:
- @ rm -f *.o *~ core $(TARGETS) $(MCONF_OBJS) $(CONF_OBJS) \
- conf mconf zconf.tab.c lex.zconf.c lkc_defs.h
+$(objk)/lxdialog/lxdialog: $(objk)/dochecklxdialog \
+ $(patsubst %,$(objk)/lxdialog/%,$(lxdialog))
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) \
+ $(patsubst %,$(objk)/lxdialog/%,$(lxdialog)) -o $@
+$(objk)/lxdialog/%.o: $(srck)/lxdialog/%.c
+ $(Q)$(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $^ -c -o $@
diff --git a/payloads/libpayload/util/kconfig/POTFILES.in b/payloads/libpayload/util/kconfig/POTFILES.in
index cc94e46a79..b6c78a9b70 100644
--- a/payloads/libpayload/util/kconfig/POTFILES.in
+++ b/payloads/libpayload/util/kconfig/POTFILES.in
@@ -1,5 +1,12 @@
-scripts/kconfig/mconf.c
-scripts/kconfig/conf.c
-scripts/kconfig/confdata.c
-scripts/kconfig/gconf.c
-scripts/kconfig/qconf.cc
+util/kconfig/lxdialog/checklist.c
+util/kconfig/lxdialog/inputbox.c
+util/kconfig/lxdialog/menubox.c
+util/kconfig/lxdialog/textbox.c
+util/kconfig/lxdialog/util.c
+util/kconfig/lxdialog/yesno.c
+util/kconfig/mconf.c
+util/kconfig/conf.c
+util/kconfig/confdata.c
+util/kconfig/gconf.c
+util/kconfig/gconf.glade.h
+util/kconfig/qconf.cc
diff --git a/payloads/libpayload/util/kconfig/check.sh b/payloads/libpayload/util/kconfig/check.sh
new file mode 100755
index 0000000000..fa59cbf9d6
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/check.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Needed for systems without gettext
+$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+#include <libintl.h>
+int main()
+{
+ gettext("");
+ return 0;
+}
+EOF
+if [ ! "$?" -eq "0" ]; then
+ echo -DKBUILD_NO_NLS;
+fi
+
diff --git a/payloads/libpayload/util/kconfig/conf.c b/payloads/libpayload/util/kconfig/conf.c
index 08eb1a01a0..e2873b683b 100644
--- a/payloads/libpayload/util/kconfig/conf.c
+++ b/payloads/libpayload/util/kconfig/conf.c
@@ -3,12 +3,13 @@
* Released under the terms of the GNU GPL v2.0.
*/
+#include <locale.h>
#include <ctype.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <time.h>
+#include <unistd.h>
#include <sys/stat.h>
#define LKC_DIRECT_LINK
@@ -37,6 +38,14 @@ static struct menu *rootEntry;
static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
+static const char *get_help(struct menu *menu)
+{
+ if (menu_has_help(menu))
+ return _(menu_get_help(menu));
+ else
+ return nohelp_text;
+}
+
static void strip(char *str)
{
char *p = str;
@@ -64,13 +73,13 @@ static void check_stdin(void)
}
}
-static void conf_askvalue(struct symbol *sym, const char *def)
+static int conf_askvalue(struct symbol *sym, const char *def)
{
enum symbol_type type = sym_get_type(sym);
tristate val;
if (!sym_has_value(sym))
- printf("(NEW) ");
+ printf(_("(NEW) "));
line[0] = '\n';
line[1] = 0;
@@ -79,7 +88,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
printf("%s\n", def);
line[0] = '\n';
line[1] = 0;
- return;
+ return 0;
}
switch (input_mode) {
@@ -89,23 +98,23 @@ static void conf_askvalue(struct symbol *sym, const char *def)
case set_random:
if (sym_has_value(sym)) {
printf("%s\n", def);
- return;
+ return 0;
}
break;
case ask_new:
case ask_silent:
if (sym_has_value(sym)) {
printf("%s\n", def);
- return;
+ return 0;
}
check_stdin();
case ask_all:
fflush(stdout);
fgets(line, 128, stdin);
- return;
+ return 1;
case set_default:
printf("%s\n", def);
- return;
+ return 1;
default:
break;
}
@@ -115,7 +124,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
case S_HEX:
case S_STRING:
printf("%s\n", def);
- return;
+ return 1;
default:
;
}
@@ -152,7 +161,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
}
case set_random:
do {
- val = (tristate)(random() % 3);
+ val = (tristate)(rand() % 3);
} while (!sym_tristate_within_range(sym, val));
switch (val) {
case no: line[0] = 'n'; break;
@@ -166,30 +175,29 @@ static void conf_askvalue(struct symbol *sym, const char *def)
break;
}
printf("%s", line);
+ return 1;
}
int conf_string(struct menu *menu)
{
struct symbol *sym = menu->sym;
- const char *def, *help;
+ const char *def;
while (1) {
- printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
printf("(%s) ", sym->name);
def = sym_get_string_value(sym);
if (sym_get_string_value(sym))
printf("[%s] ", def);
- conf_askvalue(sym, def);
+ if (!conf_askvalue(sym, def))
+ return 0;
switch (line[0]) {
case '\n':
break;
case '?':
/* print help */
if (line[1] == '\n') {
- help = nohelp_text;
- if (menu->sym->help)
- help = menu->sym->help;
- printf("\n%s\n", menu->sym->help);
+ printf("\n%s\n", get_help(menu));
def = NULL;
break;
}
@@ -207,10 +215,9 @@ static int conf_sym(struct menu *menu)
struct symbol *sym = menu->sym;
int type;
tristate oldval, newval;
- const char *help;
while (1) {
- printf("%*s%s ", indent - 1, "", menu->prompt->text);
+ printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
if (sym->name)
printf("(%s) ", sym->name);
type = sym_get_type(sym);
@@ -233,10 +240,11 @@ static int conf_sym(struct menu *menu)
printf("/m");
if (oldval != yes && sym_tristate_within_range(sym, yes))
printf("/y");
- if (sym->help)
+ if (menu_has_help(menu))
printf("/?");
printf("] ");
- conf_askvalue(sym, sym_get_string_value(sym));
+ if (!conf_askvalue(sym, sym_get_string_value(sym)))
+ return 0;
strip(line);
switch (line[0]) {
@@ -269,10 +277,7 @@ static int conf_sym(struct menu *menu)
if (sym_set_tristate_value(sym, newval))
return 0;
help:
- help = nohelp_text;
- if (sym->help)
- help = sym->help;
- printf("\n%s\n", help);
+ printf("\n%s\n", get_help(menu));
}
}
@@ -302,7 +307,7 @@ static int conf_choice(struct menu *menu)
case no:
return 1;
case mod:
- printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
return 0;
case yes:
break;
@@ -312,7 +317,7 @@ static int conf_choice(struct menu *menu)
while (1) {
int cnt, def;
- printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+ printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
def_sym = sym_get_choice_value(sym);
cnt = def = 0;
line[0] = 0;
@@ -320,7 +325,7 @@ static int conf_choice(struct menu *menu)
if (!menu_is_visible(child))
continue;
if (!child->sym) {
- printf("%*c %s\n", indent, '*', menu_get_prompt(child));
+ printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
continue;
}
cnt++;
@@ -329,20 +334,20 @@ static int conf_choice(struct menu *menu)
printf("%*c", indent, '>');
} else
printf("%*c", indent, ' ');
- printf(" %d. %s", cnt, menu_get_prompt(child));
+ printf(" %d. %s", cnt, _(menu_get_prompt(child)));
if (child->sym->name)
printf(" (%s)", child->sym->name);
if (!sym_has_value(child->sym))
- printf(" (NEW)");
+ printf(_(" (NEW)"));
printf("\n");
}
- printf("%*schoice", indent - 1, "");
+ printf(_("%*schoice"), indent - 1, "");
if (cnt == 1) {
printf("[1]: 1\n");
goto conf_childs;
}
printf("[1-%d", cnt);
- if (sym->help)
+ if (menu_has_help(menu))
printf("?");
printf("]: ");
switch (input_mode) {
@@ -359,8 +364,7 @@ static int conf_choice(struct menu *menu)
fgets(line, 128, stdin);
strip(line);
if (line[0] == '?') {
- printf("\n%s\n", menu->sym->help ?
- menu->sym->help : nohelp_text);
+ printf("\n%s\n", get_help(menu));
continue;
}
if (!line[0])
@@ -371,7 +375,8 @@ static int conf_choice(struct menu *menu)
continue;
break;
case set_random:
- def = (random() % cnt) + 1;
+ if (is_new)
+ def = (rand() % cnt) + 1;
case set_default:
case set_yes:
case set_mod:
@@ -390,15 +395,14 @@ static int conf_choice(struct menu *menu)
}
if (!child)
continue;
- if (strlen(line) > 0 && line[strlen(line) - 1] == '?') {
- printf("\n%s\n", child->sym->help ?
- child->sym->help : nohelp_text);
+ if (line[strlen(line) - 1] == '?') {
+ printf("\n%s\n", get_help(child));
continue;
}
sym_set_choice_value(sym, child->sym);
- if (child->list) {
+ for (child = child->list; child; child = child->next) {
indent += 2;
- conf(child->list);
+ conf(child);
indent -= 2;
}
return 1;
@@ -430,7 +434,7 @@ static void conf(struct menu *menu)
if (prompt)
printf("%*c\n%*c %s\n%*c\n",
indent, '*',
- indent, '*', prompt,
+ indent, '*', _(prompt),
indent, '*');
default:
;
@@ -492,12 +496,16 @@ static void check_conf(struct menu *menu)
int main(int ac, char **av)
{
- int i = 1;
+ int opt;
const char *name;
struct stat tmpstat;
- if (ac > i && av[i][0] == '-') {
- switch (av[i++][1]) {
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+ switch (opt) {
case 'o':
input_mode = ask_new;
break;
@@ -510,12 +518,7 @@ int main(int ac, char **av)
break;
case 'D':
input_mode = set_default;
- defconfig_file = av[i++];
- if (!defconfig_file) {
- printf(_("%s: No default config file specified\n"),
- av[0]);
- exit(1);
- }
+ defconfig_file = optarg;
break;
case 'n':
input_mode = set_no;
@@ -528,18 +531,22 @@ int main(int ac, char **av)
break;
case 'r':
input_mode = set_random;
- srandom(time(NULL));
+ srand(time(NULL));
break;
case 'h':
- case '?':
- fprintf(stderr, "See README for usage info\n");
+ printf(_("See README for usage info\n"));
exit(0);
+ break;
+ default:
+ fprintf(stderr, _("See README for usage info\n"));
+ exit(1);
}
}
- name = av[i];
- if (!name) {
+ if (ac == optind) {
printf(_("%s: Kconfig file missing\n"), av[0]);
+ exit(1);
}
+ name = av[optind];
conf_parse(name);
//zconfdump(stdout);
switch (input_mode) {
@@ -547,9 +554,9 @@ int main(int ac, char **av)
if (!defconfig_file)
defconfig_file = conf_get_default_confname();
if (conf_read(defconfig_file)) {
- printf("***\n"
+ printf(_("***\n"
"*** Can't find default configuration \"%s\"!\n"
- "***\n", defconfig_file);
+ "***\n"), defconfig_file);
exit(1);
}
break;
@@ -557,9 +564,10 @@ int main(int ac, char **av)
if (stat(".config", &tmpstat)) {
printf(_("***\n"
"*** You have not yet configured libpayload!\n"
+ "*** (missing .config file)\n"
"***\n"
"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
- "*** \"make menuconfig\" or \"make defconfig\").\n"
+ "*** \"make menuconfig\" or \"make xconfig\").\n"
"***\n"));
exit(1);
}
@@ -573,7 +581,7 @@ int main(int ac, char **av)
case set_random:
name = getenv("KCONFIG_ALLCONFIG");
if (name && !stat(name, &tmpstat)) {
- conf_read_simple(name);
+ conf_read_simple(name, S_DEF_USER);
break;
}
switch (input_mode) {
@@ -584,9 +592,9 @@ int main(int ac, char **av)
default: break;
}
if (!stat(name, &tmpstat))
- conf_read_simple(name);
+ conf_read_simple(name, S_DEF_USER);
else if (!stat("all.config", &tmpstat))
- conf_read_simple("all.config");
+ conf_read_simple("all.config", S_DEF_USER);
break;
default:
break;
@@ -599,14 +607,32 @@ int main(int ac, char **av)
input_mode = ask_silent;
valid_stdin = 1;
}
- }
+ } else if (conf_get_changed()) {
+ name = getenv("KCONFIG_NOSILENTUPDATE");
+ if (name && *name) {
+ fprintf(stderr, _("\n*** libpayload configuration requires explicit update.\n\n"));
+ return 1;
+ }
+ } else
+ goto skip_check;
+
do {
conf_cnt = 0;
check_conf(&rootmenu);
} while (conf_cnt);
if (conf_write(NULL)) {
- fprintf(stderr, _("\n*** Error during writing of the libpayload configuration.\n\n"));
+ fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
return 1;
}
+ if (conf_write_autoconf()) {
+ fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+ return 1;
+ }
+skip_check:
+ if (input_mode == ask_silent && conf_write_autoconf()) {
+ fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+ return 1;
+ }
+
return 0;
}
diff --git a/payloads/libpayload/util/kconfig/confdata.c b/payloads/libpayload/util/kconfig/confdata.c
index ce5fce530a..549dc0332e 100644
--- a/payloads/libpayload/util/kconfig/confdata.c
+++ b/payloads/libpayload/util/kconfig/confdata.c
@@ -5,6 +5,7 @@
#include <sys/stat.h>
#include <ctype.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -20,14 +21,7 @@ static void conf_warning(const char *fmt, ...)
static const char *conf_filename;
static int conf_lineno, conf_warnings, conf_unsaved;
-const char conf_def_filename[] = ".config";
-
-const char conf_defname[] = "util/defconfig";
-
-const char *conf_confnames[] = {
- ".config",
- NULL,
-};
+const char conf_defname[] = "arch/$ARCH/defconfig";
static void conf_warning(const char *fmt, ...)
{
@@ -40,6 +34,13 @@ static void conf_warning(const char *fmt, ...)
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;
@@ -82,51 +83,127 @@ char *conf_get_default_confname(void)
return name;
}
-int conf_read_simple(const char *name)
+static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
+{
+ char *p2;
+
+ switch (sym->type) {
+ case S_TRISTATE:
+ if (p[0] == 'm') {
+ sym->def[def].tri = mod;
+ sym->flags |= def_flags;
+ break;
+ }
+ case S_BOOLEAN:
+ if (p[0] == 'y') {
+ sym->def[def].tri = yes;
+ sym->flags |= def_flags;
+ break;
+ }
+ if (p[0] == 'n') {
+ sym->def[def].tri = no;
+ sym->flags |= def_flags;
+ break;
+ }
+ conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+ break;
+ case S_OTHER:
+ if (*p != '"') {
+ for (p2 = p; *p2 && !isspace(*p2); p2++)
+ ;
+ sym->type = S_STRING;
+ goto done;
+ }
+ case S_STRING:
+ if (*p++ != '"')
+ break;
+ for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+ if (*p2 == '"') {
+ *p2 = 0;
+ break;
+ }
+ memmove(p2, p2 + 1, strlen(p2));
+ }
+ if (!p2) {
+ conf_warning("invalid string found");
+ return 1;
+ }
+ case S_INT:
+ case S_HEX:
+ done:
+ if (sym_string_valid(sym, p)) {
+ sym->def[def].val = strdup(p);
+ sym->flags |= def_flags;
+ } else {
+ conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+ return 1;
+ }
+ break;
+ default:
+ ;
+ }
+ return 0;
+}
+
+int conf_read_simple(const char *name, int def)
{
FILE *in = NULL;
char line[1024];
char *p, *p2;
struct symbol *sym;
- int i;
+ int i, def_flags;
if (name) {
in = zconf_fopen(name);
} else {
- const char **names = conf_confnames;
- while ((name = *names++)) {
- name = conf_expand_value(name);
+ struct property *prop;
+
+ name = conf_get_configname();
+ in = zconf_fopen(name);
+ if (in)
+ goto load;
+ sym_add_change_count(1);
+ if (!sym_defconfig_list)
+ return 1;
+
+ for_all_defaults(sym_defconfig_list, prop) {
+ if (expr_calc_value(prop->visible.expr) == no ||
+ prop->expr->type != E_SYMBOL)
+ continue;
+ name = conf_expand_value(prop->expr->left.sym->name);
in = zconf_fopen(name);
if (in) {
printf(_("#\n"
- "# using defaults found in %s\n"
- "#\n"), name);
- break;
+ "# using defaults found in %s\n"
+ "#\n"), name);
+ goto load;
}
}
}
if (!in)
return 1;
+load:
conf_filename = name;
conf_lineno = 0;
conf_warnings = 0;
conf_unsaved = 0;
+ def_flags = SYMBOL_DEF << def;
for_all_symbols(i, sym) {
- sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
+ sym->flags |= SYMBOL_CHANGED;
+ sym->flags &= ~(def_flags|SYMBOL_VALID);
if (sym_is_choice(sym))
- sym->flags &= ~SYMBOL_NEW;
- sym->flags &= ~SYMBOL_VALID;
+ sym->flags |= def_flags;
switch (sym->type) {
case S_INT:
case S_HEX:
case S_STRING:
- if (sym->user.val)
- free(sym->user.val);
+ if (sym->def[def].val)
+ free(sym->def[def].val);
default:
- sym->user.val = NULL;
- sym->user.tri = no;
+ sym->def[def].val = NULL;
+ sym->def[def].tri = no;
}
}
@@ -143,19 +220,25 @@ int conf_read_simple(const char *name)
*p++ = 0;
if (strncmp(p, "is not set", 10))
continue;
- sym = sym_find(line + 9);
- if (!sym) {
- conf_warning("trying to assign nonexistent symbol %s", line + 9);
- break;
- } else if (!(sym->flags & SYMBOL_NEW)) {
- conf_warning("trying to reassign symbol %s", sym->name);
- break;
+ if (def == S_DEF_USER) {
+ sym = sym_find(line + 9);
+ if (!sym) {
+ conf_warning("trying to assign nonexistent symbol %s", line + 9);
+ break;
+ }
+ } else {
+ sym = sym_lookup(line + 9, 0);
+ if (sym->type == S_UNKNOWN)
+ sym->type = S_BOOLEAN;
+ }
+ if (sym->flags & def_flags) {
+ conf_warning("override: reassigning to symbol %s", sym->name);
}
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
- sym->user.tri = no;
- sym->flags &= ~SYMBOL_NEW;
+ sym->def[def].tri = no;
+ sym->flags |= def_flags;
break;
default:
;
@@ -171,64 +254,29 @@ int conf_read_simple(const char *name)
continue;
*p++ = 0;
p2 = strchr(p, '\n');
- if (p2)
- *p2 = 0;
- sym = sym_find(line + 7);
- if (!sym) {
- conf_warning("trying to assign nonexistent symbol %s", line + 7);
- break;
- } else if (!(sym->flags & SYMBOL_NEW)) {
- conf_warning("trying to reassign symbol %s", sym->name);
- break;
+ if (p2) {
+ *p2-- = 0;
+ if (*p2 == '\r')
+ *p2 = 0;
}
- switch (sym->type) {
- case S_TRISTATE:
- if (p[0] == 'm') {
- sym->user.tri = mod;
- sym->flags &= ~SYMBOL_NEW;
- break;
- }
- case S_BOOLEAN:
- if (p[0] == 'y') {
- sym->user.tri = yes;
- sym->flags &= ~SYMBOL_NEW;
- break;
- }
- if (p[0] == 'n') {
- sym->user.tri = no;
- sym->flags &= ~SYMBOL_NEW;
- break;
- }
- conf_warning("symbol value '%s' invalid for %s", p, sym->name);
- break;
- case S_STRING:
- if (*p++ != '"')
+ if (def == S_DEF_USER) {
+ sym = sym_find(line + 7);
+ if (!sym) {
+ conf_warning("trying to assign nonexistent symbol %s", line + 7);
break;
- for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
- if (*p2 == '"') {
- *p2 = 0;
- break;
- }
- memmove(p2, p2 + 1, strlen(p2));
- }
- if (!p2) {
- conf_warning("invalid string found");
- continue;
}
- case S_INT:
- case S_HEX:
- if (sym_string_valid(sym, p)) {
- sym->user.val = strdup(p);
- sym->flags &= ~SYMBOL_NEW;
- } else {
- conf_warning("symbol value '%s' invalid for %s", p, sym->name);
- continue;
- }
- break;
- default:
- ;
+ } else {
+ sym = sym_lookup(line + 7, 0);
+ if (sym->type == S_UNKNOWN)
+ sym->type = S_OTHER;
+ }
+ if (sym->flags & def_flags) {
+ conf_warning("override: reassigning to symbol %s", sym->name);
}
+ if (conf_set_sym_val(sym, def, def_flags, p))
+ continue;
break;
+ case '\r':
case '\n':
break;
default:
@@ -237,24 +285,22 @@ int conf_read_simple(const char *name)
}
if (sym && sym_is_choice_value(sym)) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
- switch (sym->user.tri) {
+ switch (sym->def[def].tri) {
case no:
break;
case mod:
- if (cs->user.tri == yes) {
+ if (cs->def[def].tri == yes) {
conf_warning("%s creates inconsistent choice state", sym->name);
- cs->flags |= SYMBOL_NEW;
+ cs->flags &= ~def_flags;
}
break;
case yes:
- if (cs->user.tri != no) {
- conf_warning("%s creates inconsistent choice state", sym->name);
- cs->flags |= SYMBOL_NEW;
- } else
- cs->user.val = sym;
+ if (cs->def[def].tri != no)
+ conf_warning("override: %s changes choice state", sym->name);
+ cs->def[def].val = sym;
break;
}
- cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
+ cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
}
}
fclose(in);
@@ -266,12 +312,14 @@ int conf_read_simple(const char *name)
int conf_read(const char *name)
{
- struct symbol *sym;
+ struct symbol *sym, *choice_sym;
struct property *prop;
struct expr *e;
- int i;
+ int i, flags;
+
+ sym_set_change_count(0);
- if (conf_read_simple(name))
+ if (conf_read_simple(name, S_DEF_USER))
return 1;
for_all_symbols(i, sym) {
@@ -283,12 +331,12 @@ int conf_read(const char *name)
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
- if (sym->user.tri != sym_get_tristate_value(sym))
+ 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->user.val))
+ if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
goto sym_ok;
break;
}
@@ -298,37 +346,52 @@ int conf_read(const char *name)
conf_unsaved++;
/* maybe print value in verbose mode... */
sym_ok:
+ if (!sym_is_choice(sym))
+ continue;
+ /* The choice symbol only has a set value (and thus is not new)
+ * if all its visible childs have values.
+ */
+ prop = sym_get_choice_prop(sym);
+ flags = sym->flags;
+ expr_list_for_each_sym(prop->expr, e, choice_sym)
+ if (choice_sym->visible != no)
+ flags &= choice_sym->flags;
+ sym->flags &= flags | ~SYMBOL_DEF_USER;
+ }
+
+ for_all_symbols(i, sym) {
if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
- if (sym->visible == no)
- sym->flags |= SYMBOL_NEW;
+ /* Reset values of generates values, so they'll appear
+ * as new, if they should become visible, but that
+ * doesn't quite work if the Kconfig and the saved
+ * configuration disagree.
+ */
+ if (sym->visible == no && !conf_unsaved)
+ sym->flags &= ~SYMBOL_DEF_USER;
switch (sym->type) {
case S_STRING:
case S_INT:
case S_HEX:
- if (!sym_string_within_range(sym, sym->user.val)) {
- sym->flags |= SYMBOL_NEW;
- sym->flags &= ~SYMBOL_VALID;
- }
+ /* Reset a string value if it's out of range */
+ if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+ break;
+ sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+ conf_unsaved++;
+ break;
default:
break;
}
}
- if (!sym_is_choice(sym))
- continue;
- prop = sym_get_choice_prop(sym);
- for (e = prop->expr; e; e = e->left.expr)
- if (e->right.sym->visible != no)
- sym->flags |= e->right.sym->flags & SYMBOL_NEW;
}
- sym_change_count = conf_warnings || conf_unsaved;
+ sym_add_change_count(conf_warnings || conf_unsaved);
return 0;
}
int conf_write(const char *name)
{
- FILE *out, *out_h;
+ FILE *out;
struct symbol *sym;
struct menu *menu;
const char *basename;
@@ -347,7 +410,7 @@ int conf_write(const char *name)
if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
strcpy(dirname, name);
strcat(dirname, "/");
- basename = conf_def_filename;
+ basename = conf_get_configname();
} else if ((slash = strrchr(name, '/'))) {
int size = slash - name + 1;
memcpy(dirname, name, size);
@@ -355,23 +418,24 @@ int conf_write(const char *name)
if (slash[1])
basename = slash + 1;
else
- basename = conf_def_filename;
+ basename = conf_get_configname();
} else
basename = name;
} else
- basename = conf_def_filename;
+ basename = conf_get_configname();
- sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
- out = fopen(newname, "w");
+ sprintf(newname, "%s%s", dirname, basename);
+ env = getenv("KCONFIG_OVERWRITECONFIG");
+ if (!env || !*env) {
+ sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
+ out = fopen(tmpname, "w");
+ } else {
+ *tmpname = 0;
+ out = fopen(newname, "w");
+ }
if (!out)
return 1;
- out_h = NULL;
- if (!name) {
- out_h = fopen(".tmpconfig.h", "w");
- if (!out_h)
- return 1;
- file_write_dep(NULL);
- }
+
sym = sym_lookup("KERNELVERSION", 0);
sym_calc_value(sym);
time(&now);
@@ -381,38 +445,14 @@ int conf_write(const char *name)
fprintf(out, _("#\n"
"# Automatically generated make config: don't edit\n"
- "# Libpayload version: %s\n"
+ "# libpayload version: %s\n"
"%s%s"
"#\n"),
- sym_get_string_value(sym),
+ getenv("KERNELVERSION"),
use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : "");
- if (out_h) {
- char buf[sizeof("#define AUTOCONF_TIMESTAMP "
- "\"YYYY-MM-DD HH:MM:SS some_timezone\"\n")];
- buf[0] = '\0';
- if (use_timestamp) {
- size_t ret = \
- strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP "
- "\"%Y-%m-%d %H:%M:%S %Z\"\n", localtime(&now));
- /* if user has Factory timezone or some other odd install, the
- * %Z above will overflow the string leaving us with undefined
- * results ... so let's try again without the timezone.
- */
- if (ret == 0)
- strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP "
- "\"%Y-%m-%d %H:%M:%S\"\n", localtime(&now));
- }
- fprintf(out_h, "/*\n"
- " * Automatically generated C config: don't edit\n"
- " * Libpayload version: %s\n"
- " */\n"
- "%s"
- "\n",
- sym_get_string_value(sym),
- buf);
- }
- if (!sym_change_count)
+
+ if (!conf_get_changed())
sym_clear_all_valid();
menu = rootmenu.list;
@@ -426,17 +466,10 @@ int conf_write(const char *name)
"#\n"
"# %s\n"
"#\n", str);
- if (out_h)
- fprintf(out_h, "\n"
- "/*\n"
- " * %s\n"
- " */\n", str);
} else if (!(sym->flags & SYMBOL_CHOICE)) {
sym_calc_value(sym);
-/* bbox: we want to all syms
if (!(sym->flags & SYMBOL_WRITE))
goto next;
-*/
sym->flags &= ~SYMBOL_WRITE;
type = sym->type;
if (type == S_TRISTATE) {
@@ -450,84 +483,39 @@ int conf_write(const char *name)
switch (sym_get_tristate_value(sym)) {
case no:
fprintf(out, "# CONFIG_%s is not set\n", sym->name);
- if (out_h) {
- fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
- /* bbox */
- fprintf(out_h, "#define ENABLE_%s 0\n", sym->name);
- fprintf(out_h, "#define USE_%s(...)\n", sym->name);
- fprintf(out_h, "#define SKIP_%s(...) __VA_ARGS__\n", sym->name);
- }
break;
case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name);
- if (out_h)
- fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
break;
case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name);
- if (out_h) {
- fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
- /* bbox */
- fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
- fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name);
- fprintf(out_h, "#define SKIP_%s(...)\n", sym->name);
- }
break;
}
break;
case S_STRING:
- // fix me
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=\"", sym->name);
- if (out_h)
- fprintf(out_h, "#define CONFIG_%s \"", sym->name);
- do {
+ while (1) {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
- if (out_h)
- fwrite(str, l, 1, out_h);
+ str += l;
}
- str += l;
- while (*str == '\\' || *str == '"') {
- fprintf(out, "\\%c", *str);
- if (out_h)
- fprintf(out_h, "\\%c", *str);
- str++;
- }
- } while (*str);
- fputs("\"\n", out);
- if (out_h) {
- fputs("\"\n", out_h);
- /* bbox */
- fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
- fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name);
- fprintf(out_h, "#define SKIP_%s(...)\n", sym->name);
+ if (!*str)
+ break;
+ fprintf(out, "\\%c", *str++);
}
+ fputs("\"\n", out);
break;
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);
- if (out_h) {
- fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
- /* bbox */
- fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
- fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name);
- fprintf(out_h, "#define SKIP_%s(...)\n", sym->name);
- }
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
- if (out_h) {
- fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
- /* bbox */
- fprintf(out_h, "#define ENABLE_%s 1\n", sym->name);
- fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name);
- fprintf(out_h, "#define SKIP_%s(...)\n", sym->name);
- }
break;
}
}
@@ -547,21 +535,282 @@ int conf_write(const char *name)
}
}
fclose(out);
- if (out_h) {
- fclose(out_h);
- rename(".tmpconfig.h", "include/autoconf.h");
+
+ if (*tmpname) {
+ strcat(dirname, basename);
+ strcat(dirname, ".old");
+ rename(newname, dirname);
+ if (rename(tmpname, newname))
+ return 1;
}
- if (!name || basename != conf_def_filename) {
- if (!name)
- name = conf_def_filename;
- sprintf(tmpname, "%s.old", name);
- rename(name, tmpname);
+
+ printf(_("#\n"
+ "# configuration written to %s\n"
+ "#\n"), newname);
+
+ sym_set_change_count(0);
+
+ return 0;
+}
+
+int conf_split_config(void)
+{
+ char *name, path[128];
+ char *s, *d, c;
+ struct symbol *sym;
+ struct stat sb;
+ int res, i, fd;
+
+ name = getenv("KCONFIG_AUTOCONFIG");
+ if (!name)
+ name = "include/config/auto.conf";
+ conf_read_simple(name, S_DEF_AUTO);
+
+ if (chdir("build"))
+ return 1;
+
+ res = 0;
+ for_all_symbols(i, sym) {
+ sym_calc_value(sym);
+ if ((sym->flags & SYMBOL_AUTO) || !sym->name)
+ continue;
+ if (sym->flags & SYMBOL_WRITE) {
+ if (sym->flags & SYMBOL_DEF_AUTO) {
+ /*
+ * symbol has old and new value,
+ * so compare them...
+ */
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ if (sym_get_tristate_value(sym) ==
+ sym->def[S_DEF_AUTO].tri)
+ continue;
+ break;
+ case S_STRING:
+ case S_HEX:
+ case S_INT:
+ if (!strcmp(sym_get_string_value(sym),
+ sym->def[S_DEF_AUTO].val))
+ continue;
+ break;
+ default:
+ break;
+ }
+ } else {
+ /*
+ * If there is no old value, only 'no' (unset)
+ * is allowed as new value.
+ */
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ if (sym_get_tristate_value(sym) == no)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
+ } else if (!(sym->flags & SYMBOL_DEF_AUTO))
+ /* There is neither an old nor a new value. */
+ continue;
+ /* else
+ * There is an old value, but no new value ('no' (unset)
+ * isn't saved in auto.conf, so the old value is always
+ * different from 'no').
+ */
+
+ /* Replace all '_' and append ".h" */
+ s = sym->name;
+ d = path;
+ while ((c = *s++)) {
+ c = tolower(c);
+ *d++ = (c == '_') ? '/' : c;
+ }
+ strcpy(d, ".h");
+
+ /* Assume directory path already exists. */
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd == -1) {
+ if (errno != ENOENT) {
+ res = 1;
+ break;
+ }
+ /*
+ * Create directory components,
+ * unless they exist already.
+ */
+ d = path;
+ while ((d = strchr(d, '/'))) {
+ *d = 0;
+ if (stat(path, &sb) && mkdir(path, 0755)) {
+ res = 1;
+ goto out;
+ }
+ *d++ = '/';
+ }
+ /* Try it again. */
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd == -1) {
+ res = 1;
+ break;
+ }
+ }
+ close(fd);
}
- sprintf(tmpname, "%s%s", dirname, basename);
- if (rename(newname, tmpname))
+out:
+ if (chdir("../.."))
return 1;
- sym_change_count = 0;
+ 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;
+
+ sym_clear_all_valid();
+
+ file_write_dep("build/auto.conf.cmd");
+
+#if 0
+ if (conf_split_config())
+ return 1;
+#endif
+
+ out = fopen(".tmpconfig", "w");
+ if (!out)
+ return 1;
+
+ out_h = fopen(".tmpconfig.h", "w");
+ if (!out_h) {
+ fclose(out);
+ return 1;
+ }
+
+ sym = sym_lookup("KERNELVERSION", 0);
+ sym_calc_value(sym);
+ time(&now);
+ fprintf(out, "#\n"
+ "# Automatically generated make config: don't edit\n"
+ "# libpayload version: %s\n"
+ "# %s"
+ "#\n",
+ getenv("KERNELVERSION"), ctime(&now));
+ fprintf(out_h, "/*\n"
+ " * Automatically generated C config: don't edit\n"
+ " * libpayload version: %s\n"
+ " * %s"
+ " */\n"
+ "#define AUTOCONF_INCLUDED\n",
+ getenv("KERNELVERSION"), 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, "CONFIG_%s=m\n", sym->name);
+ fprintf(out_h, "#define CONFIG_%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);
+ 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);
+ 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, "CONFIG_%s=%s\n", sym->name, str);
+ fprintf(out_h, "#define CONFIG_%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);
+ break;
+ default:
+ break;
+ }
+ }
+ fclose(out);
+ fclose(out_h);
+
+ name = getenv("KCONFIG_AUTOHEADER");
+ if (!name)
+ name = "include/linux/autoconf.h";
+ if (rename(".tmpconfig.h", name))
+ return 1;
+ name = getenv("KCONFIG_AUTOCONFIG");
+ if (!name)
+ name = "include/config/auto.conf";
+ /*
+ * This must be the last step, kbuild has a dependency on auto.conf
+ * and this marks the successful completion of the previous steps.
+ */
+ if (rename(".tmpconfig", name))
+ return 1;
return 0;
}
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+ int _sym_change_count = sym_change_count;
+ sym_change_count = count;
+ if (conf_changed_callback &&
+ (bool)_sym_change_count != (bool)count)
+ conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+ sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+ return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+ conf_changed_callback = fn;
+}
diff --git a/payloads/libpayload/util/kconfig/expr.c b/payloads/libpayload/util/kconfig/expr.c
index 30e4f9d69c..579ece4fa5 100644
--- a/payloads/libpayload/util/kconfig/expr.c
+++ b/payloads/libpayload/util/kconfig/expr.c
@@ -87,7 +87,7 @@ struct expr *expr_copy(struct expr *org)
break;
case E_AND:
case E_OR:
- case E_CHOICE:
+ case E_LIST:
e->left.expr = expr_copy(org->left.expr);
e->right.expr = expr_copy(org->right.expr);
break;
@@ -145,7 +145,8 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
return;
}
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
- e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
+ e1->left.sym == e2->left.sym &&
+ (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
return;
if (!expr_eq(e1, e2))
return;
@@ -216,7 +217,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
expr_free(e2);
trans_count = old_count;
return res;
- case E_CHOICE:
+ case E_LIST:
case E_RANGE:
case E_NONE:
/* panic */;
@@ -647,7 +648,7 @@ struct expr *expr_transform(struct expr *e)
case E_EQUAL:
case E_UNEQUAL:
case E_SYMBOL:
- case E_CHOICE:
+ case E_LIST:
break;
default:
e->left.expr = expr_transform(e->left.expr);
@@ -931,7 +932,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
break;
case E_SYMBOL:
return expr_alloc_comp(type, e->left.sym, sym);
- case E_CHOICE:
+ case E_LIST:
case E_RANGE:
case E_NONE:
/* panic */;
@@ -954,14 +955,14 @@ tristate expr_calc_value(struct expr *e)
case E_AND:
val1 = expr_calc_value(e->left.expr);
val2 = expr_calc_value(e->right.expr);
- return E_AND(val1, val2);
+ return EXPR_AND(val1, val2);
case E_OR:
val1 = expr_calc_value(e->left.expr);
val2 = expr_calc_value(e->right.expr);
- return E_OR(val1, val2);
+ return EXPR_OR(val1, val2);
case E_NOT:
val1 = expr_calc_value(e->left.expr);
- return E_NOT(val1);
+ return EXPR_NOT(val1);
case E_EQUAL:
sym_calc_value(e->left.sym);
sym_calc_value(e->right.sym);
@@ -999,9 +1000,9 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
if (t2 == E_OR)
return 1;
case E_OR:
- if (t2 == E_CHOICE)
+ if (t2 == E_LIST)
return 1;
- case E_CHOICE:
+ case E_LIST:
if (t2 == 0)
return 1;
default:
@@ -1012,73 +1013,79 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
#endif
}
-void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
+void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
{
if (!e) {
- fn(data, "y");
+ fn(data, NULL, "y");
return;
}
if (expr_compare_type(prevtoken, e->type) > 0)
- fn(data, "(");
+ fn(data, NULL, "(");
switch (e->type) {
case E_SYMBOL:
if (e->left.sym->name)
- fn(data, e->left.sym->name);
+ fn(data, e->left.sym, e->left.sym->name);
else
- fn(data, "<choice>");
+ fn(data, NULL, "<choice>");
break;
case E_NOT:
- fn(data, "!");
+ fn(data, NULL, "!");
expr_print(e->left.expr, fn, data, E_NOT);
break;
case E_EQUAL:
- fn(data, e->left.sym->name);
- fn(data, "=");
- fn(data, e->right.sym->name);
+ if (e->left.sym->name)
+ fn(data, e->left.sym, e->left.sym->name);
+ else
+ fn(data, NULL, "<choice>");
+ fn(data, NULL, "=");
+ fn(data, e->right.sym, e->right.sym->name);
break;
case E_UNEQUAL:
- fn(data, e->left.sym->name);
- fn(data, "!=");
- fn(data, e->right.sym->name);
+ if (e->left.sym->name)
+ fn(data, e->left.sym, e->left.sym->name);
+ else
+ fn(data, NULL, "<choice>");
+ fn(data, NULL, "!=");
+ fn(data, e->right.sym, e->right.sym->name);
break;
case E_OR:
expr_print(e->left.expr, fn, data, E_OR);
- fn(data, " || ");
+ fn(data, NULL, " || ");
expr_print(e->right.expr, fn, data, E_OR);
break;
case E_AND:
expr_print(e->left.expr, fn, data, E_AND);
- fn(data, " && ");
+ fn(data, NULL, " && ");
expr_print(e->right.expr, fn, data, E_AND);
break;
- case E_CHOICE:
- fn(data, e->right.sym->name);
+ case E_LIST:
+ fn(data, e->right.sym, e->right.sym->name);
if (e->left.expr) {
- fn(data, " ^ ");
- expr_print(e->left.expr, fn, data, E_CHOICE);
+ fn(data, NULL, " ^ ");
+ expr_print(e->left.expr, fn, data, E_LIST);
}
break;
case E_RANGE:
- fn(data, "[");
- fn(data, e->left.sym->name);
- fn(data, " ");
- fn(data, e->right.sym->name);
- fn(data, "]");
+ fn(data, NULL, "[");
+ fn(data, e->left.sym, e->left.sym->name);
+ fn(data, NULL, " ");
+ fn(data, e->right.sym, e->right.sym->name);
+ fn(data, NULL, "]");
break;
default:
{
char buf[32];
sprintf(buf, "<unknown type %d>", e->type);
- fn(data, buf);
+ fn(data, NULL, buf);
break;
}
}
if (expr_compare_type(prevtoken, e->type) > 0)
- fn(data, ")");
+ fn(data, NULL, ")");
}
-static void expr_print_file_helper(void *data, const char *str)
+static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
{
fwrite(str, strlen(str), 1, data);
}
@@ -1088,7 +1095,7 @@ void expr_fprint(struct expr *e, FILE *out)
expr_print(e, expr_print_file_helper, out, E_NONE);
}
-static void expr_print_gstr_helper(void *data, const char *str)
+static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
{
str_append((struct gstr*)data, str);
}
diff --git a/payloads/libpayload/util/kconfig/expr.h b/payloads/libpayload/util/kconfig/expr.h
index 1b36ef18c4..9d4cba1c00 100644
--- a/payloads/libpayload/util/kconfig/expr.h
+++ b/payloads/libpayload/util/kconfig/expr.h
@@ -25,14 +25,13 @@ struct file {
#define FILE_BUSY 0x0001
#define FILE_SCANNED 0x0002
-#define FILE_PRINTED 0x0004
typedef enum tristate {
no, mod, yes
} tristate;
enum expr_type {
- E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+ E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
};
union expr_data {
@@ -45,9 +44,12 @@ struct expr {
union expr_data left, right;
};
-#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
-#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
-#define E_NOT(dep) (2-(dep))
+#define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
+#define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
+#define EXPR_NOT(dep) (2-(dep))
+
+#define expr_list_for_each_sym(l, e, s) \
+ for (e = (l); e && (s = e->right.sym); e = e->left.expr)
struct expr_value {
struct expr *expr;
@@ -63,44 +65,49 @@ enum symbol_type {
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
};
+enum {
+ S_DEF_USER, /* main user value */
+ S_DEF_AUTO,
+};
+
struct symbol {
struct symbol *next;
char *name;
- char *help;
enum symbol_type type;
- struct symbol_value curr, user;
+ struct symbol_value curr;
+ struct symbol_value def[4];
tristate visible;
int flags;
struct property *prop;
- struct expr *dep, *dep2;
struct expr_value rev_dep;
};
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
-#define SYMBOL_YES 0x0001
-#define SYMBOL_MOD 0x0002
-#define SYMBOL_NO 0x0004
-#define SYMBOL_CONST 0x0007
+#define SYMBOL_CONST 0x0001
#define SYMBOL_CHECK 0x0008
#define SYMBOL_CHOICE 0x0010
#define SYMBOL_CHOICEVAL 0x0020
-#define SYMBOL_PRINTED 0x0040
#define SYMBOL_VALID 0x0080
#define SYMBOL_OPTIONAL 0x0100
#define SYMBOL_WRITE 0x0200
#define SYMBOL_CHANGED 0x0400
-#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000
#define SYMBOL_CHECKED 0x2000
#define SYMBOL_WARNED 0x8000
+#define SYMBOL_DEF 0x10000
+#define SYMBOL_DEF_USER 0x10000
+#define SYMBOL_DEF_AUTO 0x20000
+#define SYMBOL_DEF3 0x40000
+#define SYMBOL_DEF4 0x80000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257
#define SYMBOL_HASHMASK 0xff
enum prop_type {
- P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+ P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE,
+ P_SELECT, P_RANGE, P_ENV
};
struct property {
@@ -132,7 +139,7 @@ struct menu {
struct property *prompt;
struct expr *dep;
unsigned int flags;
- //char *help;
+ char *help;
struct file *file;
int lineno;
void *data;
@@ -149,6 +156,7 @@ struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym;
+extern struct symbol *sym_defconfig_list;
extern int cdebug;
struct expr *expr_alloc_symbol(struct symbol *sym);
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
diff --git a/payloads/libpayload/util/kconfig/gconf.c b/payloads/libpayload/util/kconfig/gconf.c
new file mode 100644
index 0000000000..bc9f5ba057
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/gconf.c
@@ -0,0 +1,1636 @@
+/* Hey EMACS -*- linux-c -*- */
+/*
+ *
+ * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info>
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "lkc.h"
+#include "images.c"
+
+#include <glade/glade.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+
+//#define DEBUG
+
+enum {
+ SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
+};
+
+static gint view_mode = FULL_VIEW;
+static gboolean show_name = TRUE;
+static gboolean show_range = TRUE;
+static gboolean show_value = TRUE;
+static gboolean show_all = FALSE;
+static gboolean show_debug = FALSE;
+static gboolean resizeable = FALSE;
+
+GtkWidget *main_wnd = NULL;
+GtkWidget *tree1_w = NULL; // left frame
+GtkWidget *tree2_w = NULL; // right frame
+GtkWidget *text_w = NULL;
+GtkWidget *hpaned = NULL;
+GtkWidget *vpaned = NULL;
+GtkWidget *back_btn = NULL;
+GtkWidget *save_btn = NULL;
+GtkWidget *save_menu_item = NULL;
+
+GtkTextTag *tag1, *tag2;
+GdkColor color;
+
+GtkTreeStore *tree1, *tree2, *tree;
+GtkTreeModel *model1, *model2;
+static GtkTreeIter *parents[256];
+static gint indent;
+
+static struct menu *current; // current node for SINGLE view
+static struct menu *browsed; // browsed node for SPLIT view
+
+enum {
+ COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
+ COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
+ COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
+ COL_NUMBER
+};
+
+static void display_list(void);
+static void display_tree(struct menu *menu);
+static void display_tree_part(void);
+static void update_tree(struct menu *src, GtkTreeIter * dst);
+static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
+static gchar **fill_row(struct menu *menu);
+static void conf_changed(void);
+
+/* Helping/Debugging Functions */
+
+
+const char *dbg_print_stype(int val)
+{
+ static char buf[256];
+
+ bzero(buf, 256);
+
+ if (val == S_UNKNOWN)
+ strcpy(buf, "unknown");
+ if (val == S_BOOLEAN)
+ strcpy(buf, "boolean");
+ if (val == S_TRISTATE)
+ strcpy(buf, "tristate");
+ if (val == S_INT)
+ strcpy(buf, "int");
+ if (val == S_HEX)
+ strcpy(buf, "hex");
+ if (val == S_STRING)
+ strcpy(buf, "string");
+ if (val == S_OTHER)
+ strcpy(buf, "other");
+
+#ifdef DEBUG
+ printf("%s", buf);
+#endif
+
+ return buf;
+}
+
+const char *dbg_print_flags(int val)
+{
+ static char buf[256];
+
+ bzero(buf, 256);
+
+ if (val & SYMBOL_CONST)
+ strcat(buf, "const/");
+ if (val & SYMBOL_CHECK)
+ strcat(buf, "check/");
+ if (val & SYMBOL_CHOICE)
+ strcat(buf, "choice/");
+ if (val & SYMBOL_CHOICEVAL)
+ strcat(buf, "choiceval/");
+ if (val & SYMBOL_VALID)
+ strcat(buf, "valid/");
+ if (val & SYMBOL_OPTIONAL)
+ strcat(buf, "optional/");
+ if (val & SYMBOL_WRITE)
+ strcat(buf, "write/");
+ if (val & SYMBOL_CHANGED)
+ strcat(buf, "changed/");
+ if (val & SYMBOL_AUTO)
+ strcat(buf, "auto/");
+
+ buf[strlen(buf) - 1] = '\0';
+#ifdef DEBUG
+ printf("%s", buf);
+#endif
+
+ return buf;
+}
+
+const char *dbg_print_ptype(int val)
+{
+ static char buf[256];
+
+ bzero(buf, 256);
+
+ if (val == P_UNKNOWN)
+ strcpy(buf, "unknown");
+ if (val == P_PROMPT)
+ strcpy(buf, "prompt");
+ if (val == P_COMMENT)
+ strcpy(buf, "comment");
+ if (val == P_MENU)
+ strcpy(buf, "menu");
+ if (val == P_DEFAULT)
+ strcpy(buf, "default");
+ if (val == P_CHOICE)
+ strcpy(buf, "choice");
+
+#ifdef DEBUG
+ printf("%s", buf);
+#endif
+
+ return buf;
+}
+
+
+void replace_button_icon(GladeXML * xml, GdkDrawable * window,
+ GtkStyle * style, gchar * btn_name, gchar ** xpm)
+{
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ GtkToolButton *button;
+ GtkWidget *image;
+
+ pixmap = gdk_pixmap_create_from_xpm_d(window, &mask,
+ &style->bg[GTK_STATE_NORMAL],
+ xpm);
+
+ button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name));
+ image = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_widget_show(image);
+ gtk_tool_button_set_icon_widget(button, image);
+}
+
+/* Main Window Initialization */
+void init_main_window(const gchar * glade_file)
+{
+ GladeXML *xml;
+ GtkWidget *widget;
+ GtkTextBuffer *txtbuf;
+ char title[256];
+ GtkStyle *style;
+
+ xml = glade_xml_new(glade_file, "window1", NULL);
+ if (!xml)
+ g_error(_("GUI loading failed !\n"));
+ glade_xml_signal_autoconnect(xml);
+
+ main_wnd = glade_xml_get_widget(xml, "window1");
+ hpaned = glade_xml_get_widget(xml, "hpaned1");
+ vpaned = glade_xml_get_widget(xml, "vpaned1");
+ tree1_w = glade_xml_get_widget(xml, "treeview1");
+ tree2_w = glade_xml_get_widget(xml, "treeview2");
+ text_w = glade_xml_get_widget(xml, "textview3");
+
+ back_btn = glade_xml_get_widget(xml, "button1");
+ gtk_widget_set_sensitive(back_btn, FALSE);
+
+ widget = glade_xml_get_widget(xml, "show_name1");
+ gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+ show_name);
+
+ widget = glade_xml_get_widget(xml, "show_range1");
+ gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+ show_range);
+
+ widget = glade_xml_get_widget(xml, "show_data1");
+ gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+ show_value);
+
+ save_btn = glade_xml_get_widget(xml, "button3");
+ save_menu_item = glade_xml_get_widget(xml, "save1");
+ conf_set_changed_callback(conf_changed);
+
+ style = gtk_widget_get_style(main_wnd);
+ widget = glade_xml_get_widget(xml, "toolbar1");
+
+#if 0 /* Use stock Gtk icons instead */
+ replace_button_icon(xml, main_wnd->window, style,
+ "button1", (gchar **) xpm_back);
+ replace_button_icon(xml, main_wnd->window, style,
+ "button2", (gchar **) xpm_load);
+ replace_button_icon(xml, main_wnd->window, style,
+ "button3", (gchar **) xpm_save);
+#endif
+ replace_button_icon(xml, main_wnd->window, style,
+ "button4", (gchar **) xpm_single_view);
+ replace_button_icon(xml, main_wnd->window, style,
+ "button5", (gchar **) xpm_split_view);
+ replace_button_icon(xml, main_wnd->window, style,
+ "button6", (gchar **) xpm_tree_view);
+
+#if 0
+ switch (view_mode) {
+ case SINGLE_VIEW:
+ widget = glade_xml_get_widget(xml, "button4");
+ g_signal_emit_by_name(widget, "clicked");
+ break;
+ case SPLIT_VIEW:
+ widget = glade_xml_get_widget(xml, "button5");
+ g_signal_emit_by_name(widget, "clicked");
+ break;
+ case FULL_VIEW:
+ widget = glade_xml_get_widget(xml, "button6");
+ g_signal_emit_by_name(widget, "clicked");
+ break;
+ }
+#endif
+ txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+ tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
+ "foreground", "red",
+ "weight", PANGO_WEIGHT_BOLD,
+ NULL);
+ tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
+ /*"style", PANGO_STYLE_OBLIQUE, */
+ NULL);
+
+ sprintf(title, _("libpayload v%s Configuration"),
+ getenv("KERNELVERSION"));
+ gtk_window_set_title(GTK_WINDOW(main_wnd), title);
+
+ gtk_widget_show(main_wnd);
+}
+
+void init_tree_model(void)
+{
+ gint i;
+
+ tree = tree2 = gtk_tree_store_new(COL_NUMBER,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_POINTER, GDK_TYPE_COLOR,
+ G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+ model2 = GTK_TREE_MODEL(tree2);
+
+ for (parents[0] = NULL, i = 1; i < 256; i++)
+ parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
+
+ tree1 = gtk_tree_store_new(COL_NUMBER,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_POINTER, GDK_TYPE_COLOR,
+ G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+ model1 = GTK_TREE_MODEL(tree1);
+}
+
+void init_left_tree(void)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *sel;
+ GtkTreeViewColumn *column;
+
+ gtk_tree_view_set_model(view, model1);
+ gtk_tree_view_set_headers_visible(view, TRUE);
+ gtk_tree_view_set_rules_hint(view, FALSE);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(view, column);
+ gtk_tree_view_column_set_title(column, _("Options"));
+
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "active", COL_BTNACT,
+ "inconsistent", COL_BTNINC,
+ "visible", COL_BTNVIS,
+ "radio", COL_BTNRAD, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "text", COL_OPTION,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+
+ sel = gtk_tree_view_get_selection(view);
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+ gtk_widget_realize(tree1_w);
+}
+
+static void renderer_edited(GtkCellRendererText * cell,
+ const gchar * path_string,
+ const gchar * new_text, gpointer user_data);
+static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
+ gchar * arg1, gpointer user_data);
+
+void init_right_tree(void)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *sel;
+ GtkTreeViewColumn *column;
+ gint i;
+
+ gtk_tree_view_set_model(view, model2);
+ gtk_tree_view_set_headers_visible(view, TRUE);
+ gtk_tree_view_set_rules_hint(view, FALSE);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(view, column);
+ gtk_tree_view_column_set_title(column, _("Options"));
+
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "pixbuf", COL_PIXBUF,
+ "visible", COL_PIXVIS, NULL);
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "active", COL_BTNACT,
+ "inconsistent", COL_BTNINC,
+ "visible", COL_BTNVIS,
+ "radio", COL_BTNRAD, NULL);
+ /*g_signal_connect(G_OBJECT(renderer), "toggled",
+ G_CALLBACK(renderer_toggled), NULL); */
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+ renderer, FALSE);
+ gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+ renderer,
+ "text", COL_OPTION,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ _("Name"), renderer,
+ "text", COL_NAME,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "N", renderer,
+ "text", COL_NO,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "M", renderer,
+ "text", COL_MOD,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ "Y", renderer,
+ "text", COL_YES,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(view, -1,
+ _("Value"), renderer,
+ "text", COL_VALUE,
+ "editable",
+ COL_EDIT,
+ "foreground-gdk",
+ COL_COLOR, NULL);
+ g_signal_connect(G_OBJECT(renderer), "edited",
+ G_CALLBACK(renderer_edited), NULL);
+
+ column = gtk_tree_view_get_column(view, COL_NAME);
+ gtk_tree_view_column_set_visible(column, show_name);
+ column = gtk_tree_view_get_column(view, COL_NO);
+ gtk_tree_view_column_set_visible(column, show_range);
+ column = gtk_tree_view_get_column(view, COL_MOD);
+ gtk_tree_view_column_set_visible(column, show_range);
+ column = gtk_tree_view_get_column(view, COL_YES);
+ gtk_tree_view_column_set_visible(column, show_range);
+ column = gtk_tree_view_get_column(view, COL_VALUE);
+ gtk_tree_view_column_set_visible(column, show_value);
+
+ if (resizeable) {
+ for (i = 0; i < COL_VALUE; i++) {
+ column = gtk_tree_view_get_column(view, i);
+ gtk_tree_view_column_set_resizable(column, TRUE);
+ }
+ }
+
+ sel = gtk_tree_view_get_selection(view);
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+}
+
+
+/* Utility Functions */
+
+
+static void text_insert_help(struct menu *menu)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ const char *prompt = _(menu_get_prompt(menu));
+ gchar *name;
+ const char *help;
+
+ help = menu_get_help(menu);
+
+ /* Gettextize if the help text not empty */
+ if ((help != 0) && (help[0] != 0))
+ help = _(help);
+
+ if (menu->sym && menu->sym->name)
+ name = g_strdup_printf(menu->sym->name);
+ else
+ name = g_strdup("");
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
+
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
+ NULL);
+ gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
+ NULL);
+ gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2,
+ NULL);
+}
+
+
+static void text_insert_msg(const char *title, const char *message)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ const char *msg = message;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
+
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
+ NULL);
+ gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
+ gtk_text_buffer_get_end_iter(buffer, &end);
+ gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
+ NULL);
+}
+
+
+/* Main Windows Callbacks */
+
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
+gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
+ gpointer user_data)
+{
+ GtkWidget *dialog, *label;
+ gint result;
+
+ if (!conf_get_changed())
+ return FALSE;
+
+ dialog = gtk_dialog_new_with_buttons(_("Warning !"),
+ GTK_WINDOW(main_wnd),
+ (GtkDialogFlags)
+ (GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT),
+ GTK_STOCK_OK,
+ GTK_RESPONSE_YES,
+ GTK_STOCK_NO,
+ GTK_RESPONSE_NO,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+ GTK_RESPONSE_CANCEL);
+
+ label = gtk_label_new(_("\nSave configuration ?\n"));
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
+ gtk_widget_show(label);
+
+ result = gtk_dialog_run(GTK_DIALOG(dialog));
+ switch (result) {
+ case GTK_RESPONSE_YES:
+ on_save_activate(NULL, NULL);
+ return FALSE;
+ case GTK_RESPONSE_NO:
+ return FALSE;
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_DELETE_EVENT:
+ default:
+ gtk_widget_destroy(dialog);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void on_window1_destroy(GtkObject * object, gpointer user_data)
+{
+ gtk_main_quit();
+}
+
+
+void
+on_window1_size_request(GtkWidget * widget,
+ GtkRequisition * requisition, gpointer user_data)
+{
+ static gint old_h;
+ gint w, h;
+
+ if (widget->window == NULL)
+ gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
+ else
+ gdk_window_get_size(widget->window, &w, &h);
+
+ if (h == old_h)
+ return;
+ old_h = h;
+
+ gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
+}
+
+
+/* Menu & Toolbar Callbacks */
+
+
+static void
+load_filename(GtkFileSelection * file_selector, gpointer user_data)
+{
+ const gchar *fn;
+
+ fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
+ (user_data));
+
+ if (conf_read(fn))
+ text_insert_msg(_("Error"), _("Unable to load configuration !"));
+ else
+ display_tree(&rootmenu);
+}
+
+void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *fs;
+
+ fs = gtk_file_selection_new(_("Load file..."));
+ g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked",
+ G_CALLBACK(load_filename), (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->cancel_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ gtk_widget_show(fs);
+}
+
+
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ if (conf_write(NULL))
+ text_insert_msg(_("Error"), _("Unable to save configuration !"));
+ if (conf_write_autoconf())
+ text_insert_msg(_("Error"), _("Unable to save configuration !"));
+}
+
+
+static void
+store_filename(GtkFileSelection * file_selector, gpointer user_data)
+{
+ const gchar *fn;
+
+ fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
+ (user_data));
+
+ if (conf_write(fn))
+ text_insert_msg(_("Error"), _("Unable to save configuration !"));
+ if (conf_write_autoconf())
+ text_insert_msg(_("Error"), _("Unable to save configuration !"));
+
+ gtk_widget_destroy(GTK_WIDGET(user_data));
+}
+
+void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *fs;
+
+ fs = gtk_file_selection_new(_("Save file as..."));
+ g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked",
+ G_CALLBACK(store_filename), (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ g_signal_connect_swapped(GTK_OBJECT
+ (GTK_FILE_SELECTION(fs)->cancel_button),
+ "clicked", G_CALLBACK(gtk_widget_destroy),
+ (gpointer) fs);
+ gtk_widget_show(fs);
+}
+
+
+void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ if (!on_window1_delete_event(NULL, NULL, NULL))
+ gtk_widget_destroy(GTK_WIDGET(main_wnd));
+}
+
+
+void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkTreeViewColumn *col;
+
+ show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_name);
+}
+
+
+void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkTreeViewColumn *col;
+
+ show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_range);
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_range);
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_range);
+
+}
+
+
+void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkTreeViewColumn *col;
+
+ show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
+ if (col)
+ gtk_tree_view_column_set_visible(col, show_value);
+}
+
+
+void
+on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
+
+ gtk_tree_store_clear(tree2);
+ display_tree(&rootmenu); // instead of update_tree to speed-up
+}
+
+
+void
+on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
+ update_tree(&rootmenu, NULL);
+}
+
+
+void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *dialog;
+ const gchar *intro_text = _(
+ "Welcome to gkc, the GTK+ graphical configuration tool\n"
+ "for libpayload.\n"
+ "For each option, a blank box indicates the feature is disabled, a\n"
+ "check indicates it is enabled, and a dot indicates that it is to\n"
+ "be compiled as a module. Clicking on the box will cycle through the three states.\n"
+ "\n"
+ "If you do not see an option (e.g., a device driver) that you\n"
+ "believe should be present, try turning on Show All Options\n"
+ "under the Options menu.\n"
+ "Although there is no cross reference yet to help you figure out\n"
+ "what other options must be enabled to support the option you\n"
+ "are interested in, you can still view the help of a grayed-out\n"
+ "option.\n"
+ "\n"
+ "Toggling Show Debug Info under the Options menu will show \n"
+ "the dependencies, which you can then match by examining other options.");
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE, intro_text);
+ g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
+ G_CALLBACK(gtk_widget_destroy),
+ GTK_OBJECT(dialog));
+ gtk_widget_show_all(dialog);
+}
+
+
+void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *dialog;
+ const gchar *about_text =
+ _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
+ "Based on the source code from Roman Zippel.\n");
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE, about_text);
+ g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
+ G_CALLBACK(gtk_widget_destroy),
+ GTK_OBJECT(dialog));
+ gtk_widget_show_all(dialog);
+}
+
+
+void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
+{
+ GtkWidget *dialog;
+ const gchar *license_text =
+ _("gkc is released under the terms of the GNU GPL v2.\n"
+ "For more information, please see the source code or\n"
+ "visit http://www.fsf.org/licenses/licenses.html\n");
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE, license_text);
+ g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
+ G_CALLBACK(gtk_widget_destroy),
+ GTK_OBJECT(dialog));
+ gtk_widget_show_all(dialog);
+}
+
+
+void on_back_clicked(GtkButton * button, gpointer user_data)
+{
+ enum prop_type ptype;
+
+ current = current->parent;
+ ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
+ if (ptype != P_MENU)
+ current = current->parent;
+ display_tree_part();
+
+ if (current == &rootmenu)
+ gtk_widget_set_sensitive(back_btn, FALSE);
+}
+
+
+void on_load_clicked(GtkButton * button, gpointer user_data)
+{
+ on_load1_activate(NULL, user_data);
+}
+
+
+void on_single_clicked(GtkButton * button, gpointer user_data)
+{
+ view_mode = SINGLE_VIEW;
+ gtk_paned_set_position(GTK_PANED(hpaned), 0);
+ gtk_widget_hide(tree1_w);
+ current = &rootmenu;
+ display_tree_part();
+}
+
+
+void on_split_clicked(GtkButton * button, gpointer user_data)
+{
+ gint w, h;
+ view_mode = SPLIT_VIEW;
+ gtk_widget_show(tree1_w);
+ gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
+ gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
+ if (tree2)
+ gtk_tree_store_clear(tree2);
+ display_list();
+
+ /* Disable back btn, like in full mode. */
+ gtk_widget_set_sensitive(back_btn, FALSE);
+}
+
+
+void on_full_clicked(GtkButton * button, gpointer user_data)
+{
+ view_mode = FULL_VIEW;
+ gtk_paned_set_position(GTK_PANED(hpaned), 0);
+ gtk_widget_hide(tree1_w);
+ if (tree2)
+ gtk_tree_store_clear(tree2);
+ display_tree(&rootmenu);
+ gtk_widget_set_sensitive(back_btn, FALSE);
+}
+
+
+void on_collapse_clicked(GtkButton * button, gpointer user_data)
+{
+ gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
+}
+
+
+void on_expand_clicked(GtkButton * button, gpointer user_data)
+{
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
+}
+
+
+/* CTree Callbacks */
+
+/* Change hex/int/string value in the cell */
+static void renderer_edited(GtkCellRendererText * cell,
+ const gchar * path_string,
+ const gchar * new_text, gpointer user_data)
+{
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
+ GtkTreeIter iter;
+ const char *old_def, *new_def;
+ struct menu *menu;
+ struct symbol *sym;
+
+ if (!gtk_tree_model_get_iter(model2, &iter, path))
+ return;
+
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+ sym = menu->sym;
+
+ gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
+ new_def = new_text;
+
+ sym_set_string_value(sym, new_def);
+
+ update_tree(&rootmenu, NULL);
+
+ gtk_tree_path_free(path);
+}
+
+/* Change the value of a symbol and update the tree */
+static void change_sym_value(struct menu *menu, gint col)
+{
+ struct symbol *sym = menu->sym;
+ tristate oldval, newval;
+
+ if (!sym)
+ return;
+
+ if (col == COL_NO)
+ newval = no;
+ else if (col == COL_MOD)
+ newval = mod;
+ else if (col == COL_YES)
+ newval = yes;
+ else
+ return;
+
+ switch (sym_get_type(sym)) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ oldval = sym_get_tristate_value(sym);
+ if (!sym_tristate_within_range(sym, newval))
+ newval = yes;
+ sym_set_tristate_value(sym, newval);
+ if (view_mode == FULL_VIEW)
+ update_tree(&rootmenu, NULL);
+ else if (view_mode == SPLIT_VIEW) {
+ update_tree(browsed, NULL);
+ display_list();
+ }
+ else if (view_mode == SINGLE_VIEW)
+ display_tree_part(); //fixme: keep exp/coll
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ default:
+ break;
+ }
+}
+
+static void toggle_sym_value(struct menu *menu)
+{
+ if (!menu->sym)
+ return;
+
+ sym_toggle_tristate_value(menu->sym);
+ if (view_mode == FULL_VIEW)
+ update_tree(&rootmenu, NULL);
+ else if (view_mode == SPLIT_VIEW) {
+ update_tree(browsed, NULL);
+ display_list();
+ }
+ else if (view_mode == SINGLE_VIEW)
+ display_tree_part(); //fixme: keep exp/coll
+}
+
+static void renderer_toggled(GtkCellRendererToggle * cell,
+ gchar * path_string, gpointer user_data)
+{
+ GtkTreePath *path, *sel_path = NULL;
+ GtkTreeIter iter, sel_iter;
+ GtkTreeSelection *sel;
+ struct menu *menu;
+
+ path = gtk_tree_path_new_from_string(path_string);
+ if (!gtk_tree_model_get_iter(model2, &iter, path))
+ return;
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
+ if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
+ sel_path = gtk_tree_model_get_path(model2, &sel_iter);
+ if (!sel_path)
+ goto out1;
+ if (gtk_tree_path_compare(path, sel_path))
+ goto out2;
+
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+ toggle_sym_value(menu);
+
+ out2:
+ gtk_tree_path_free(sel_path);
+ out1:
+ gtk_tree_path_free(path);
+}
+
+static gint column2index(GtkTreeViewColumn * column)
+{
+ gint i;
+
+ for (i = 0; i < COL_NUMBER; i++) {
+ GtkTreeViewColumn *col;
+
+ col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
+ if (col == column)
+ return i;
+ }
+
+ return -1;
+}
+
+
+/* User click: update choice (full) or goes down (single) */
+gboolean
+on_treeview2_button_press_event(GtkWidget * widget,
+ GdkEventButton * event, gpointer user_data)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(widget);
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ struct menu *menu;
+ gint col;
+
+#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
+ gint tx = (gint) event->x;
+ gint ty = (gint) event->y;
+ gint cx, cy;
+
+ gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
+ &cy);
+#else
+ gtk_tree_view_get_cursor(view, &path, &column);
+#endif
+ if (path == NULL)
+ return FALSE;
+
+ if (!gtk_tree_model_get_iter(model2, &iter, path))
+ return FALSE;
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+
+ col = column2index(column);
+ if (event->type == GDK_2BUTTON_PRESS) {
+ enum prop_type ptype;
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+
+ if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
+ // goes down into menu
+ current = menu;
+ display_tree_part();
+ gtk_widget_set_sensitive(back_btn, TRUE);
+ } else if ((col == COL_OPTION)) {
+ toggle_sym_value(menu);
+ gtk_tree_view_expand_row(view, path, TRUE);
+ }
+ } else {
+ if (col == COL_VALUE) {
+ toggle_sym_value(menu);
+ gtk_tree_view_expand_row(view, path, TRUE);
+ } else if (col == COL_NO || col == COL_MOD
+ || col == COL_YES) {
+ change_sym_value(menu, col);
+ gtk_tree_view_expand_row(view, path, TRUE);
+ }
+ }
+
+ return FALSE;
+}
+
+/* Key pressed: update choice */
+gboolean
+on_treeview2_key_press_event(GtkWidget * widget,
+ GdkEventKey * event, gpointer user_data)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(widget);
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ struct menu *menu;
+ gint col;
+
+ gtk_tree_view_get_cursor(view, &path, &column);
+ if (path == NULL)
+ return FALSE;
+
+ if (event->keyval == GDK_space) {
+ if (gtk_tree_view_row_expanded(view, path))
+ gtk_tree_view_collapse_row(view, path);
+ else
+ gtk_tree_view_expand_row(view, path, FALSE);
+ return TRUE;
+ }
+ if (event->keyval == GDK_KP_Enter) {
+ }
+ if (widget == tree1_w)
+ return FALSE;
+
+ gtk_tree_model_get_iter(model2, &iter, path);
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+
+ if (!strcasecmp(event->string, "n"))
+ col = COL_NO;
+ else if (!strcasecmp(event->string, "m"))
+ col = COL_MOD;
+ else if (!strcasecmp(event->string, "y"))
+ col = COL_YES;
+ else
+ col = -1;
+ change_sym_value(menu, col);
+
+ return FALSE;
+}
+
+
+/* Row selection changed: update help */
+void
+on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ struct menu *menu;
+
+ selection = gtk_tree_view_get_selection(treeview);
+ if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
+ gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+ text_insert_help(menu);
+ }
+}
+
+
+/* User click: display sub-tree in the right frame. */
+gboolean
+on_treeview1_button_press_event(GtkWidget * widget,
+ GdkEventButton * event, gpointer user_data)
+{
+ GtkTreeView *view = GTK_TREE_VIEW(widget);
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ struct menu *menu;
+
+ gint tx = (gint) event->x;
+ gint ty = (gint) event->y;
+ gint cx, cy;
+
+ gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
+ &cy);
+ if (path == NULL)
+ return FALSE;
+
+ gtk_tree_model_get_iter(model1, &iter, path);
+ gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
+
+ if (event->type == GDK_2BUTTON_PRESS) {
+ toggle_sym_value(menu);
+ current = menu;
+ display_tree_part();
+ } else {
+ browsed = menu;
+ display_tree_part();
+ }
+
+ gtk_widget_realize(tree2_w);
+ gtk_tree_view_set_cursor(view, path, NULL, FALSE);
+ gtk_widget_grab_focus(tree2_w);
+
+ return FALSE;
+}
+
+
+/* Fill a row of strings */
+static gchar **fill_row(struct menu *menu)
+{
+ static gchar *row[COL_NUMBER];
+ struct symbol *sym = menu->sym;
+ const char *def;
+ int stype;
+ tristate val;
+ enum prop_type ptype;
+ int i;
+
+ for (i = COL_OPTION; i <= COL_COLOR; i++)
+ g_free(row[i]);
+ bzero(row, sizeof(row));
+
+ row[COL_OPTION] =
+ g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
+ sym && sym_has_value(sym) ? "(NEW)" : "");
+
+ if (show_all && !menu_is_visible(menu))
+ row[COL_COLOR] = g_strdup("DarkGray");
+ else
+ row[COL_COLOR] = g_strdup("Black");
+
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ switch (ptype) {
+ case P_MENU:
+ row[COL_PIXBUF] = (gchar *) xpm_menu;
+ if (view_mode == SINGLE_VIEW)
+ row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+ break;
+ case P_COMMENT:
+ row[COL_PIXBUF] = (gchar *) xpm_void;
+ row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+ break;
+ default:
+ row[COL_PIXBUF] = (gchar *) xpm_void;
+ row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
+ break;
+ }
+
+ if (!sym)
+ return row;
+ row[COL_NAME] = g_strdup(sym->name);
+
+ sym_calc_value(sym);
+ sym->flags &= ~SYMBOL_CHANGED;
+
+ if (sym_is_choice(sym)) { // parse childs for getting final value
+ struct menu *child;
+ struct symbol *def_sym = sym_get_choice_value(sym);
+ struct menu *def_menu = NULL;
+
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child)
+ && child->sym == def_sym)
+ def_menu = child;
+ }
+
+ if (def_menu)
+ row[COL_VALUE] =
+ g_strdup(_(menu_get_prompt(def_menu)));
+ }
+ if (sym->flags & SYMBOL_CHOICEVAL)
+ row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
+
+ stype = sym_get_type(sym);
+ switch (stype) {
+ case S_BOOLEAN:
+ if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
+ row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
+ if (sym_is_choice(sym))
+ break;
+ case S_TRISTATE:
+ val = sym_get_tristate_value(sym);
+ switch (val) {
+ case no:
+ row[COL_NO] = g_strdup("N");
+ row[COL_VALUE] = g_strdup("N");
+ row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
+ row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
+ break;
+ case mod:
+ row[COL_MOD] = g_strdup("M");
+ row[COL_VALUE] = g_strdup("M");
+ row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
+ break;
+ case yes:
+ row[COL_YES] = g_strdup("Y");
+ row[COL_VALUE] = g_strdup("Y");
+ row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
+ row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
+ break;
+ }
+
+ if (val != no && sym_tristate_within_range(sym, no))
+ row[COL_NO] = g_strdup("_");
+ if (val != mod && sym_tristate_within_range(sym, mod))
+ row[COL_MOD] = g_strdup("_");
+ if (val != yes && sym_tristate_within_range(sym, yes))
+ row[COL_YES] = g_strdup("_");
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ def = sym_get_string_value(sym);
+ row[COL_VALUE] = g_strdup(def);
+ row[COL_EDIT] = GINT_TO_POINTER(TRUE);
+ row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
+ break;
+ }
+
+ return row;
+}
+
+
+/* Set the node content with a row of strings */
+static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
+{
+ GdkColor color;
+ gboolean success;
+ GdkPixbuf *pix;
+
+ pix = gdk_pixbuf_new_from_xpm_data((const char **)
+ row[COL_PIXBUF]);
+
+ gdk_color_parse(row[COL_COLOR], &color);
+ gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
+ FALSE, FALSE, &success);
+
+ gtk_tree_store_set(tree, node,
+ COL_OPTION, row[COL_OPTION],
+ COL_NAME, row[COL_NAME],
+ COL_NO, row[COL_NO],
+ COL_MOD, row[COL_MOD],
+ COL_YES, row[COL_YES],
+ COL_VALUE, row[COL_VALUE],
+ COL_MENU, (gpointer) menu,
+ COL_COLOR, &color,
+ COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
+ COL_PIXBUF, pix,
+ COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
+ COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
+ COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
+ COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
+ COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
+ -1);
+
+ g_object_unref(pix);
+}
+
+
+/* Add a node to the tree */
+static void place_node(struct menu *menu, char **row)
+{
+ GtkTreeIter *parent = parents[indent - 1];
+ GtkTreeIter *node = parents[indent];
+
+ gtk_tree_store_append(tree, node, parent);
+ set_node(node, menu, row);
+}
+
+
+/* Find a node in the GTK+ tree */
+static GtkTreeIter found;
+
+/*
+ * Find a menu in the GtkTree starting at parent.
+ */
+GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
+ struct menu *tofind)
+{
+ GtkTreeIter iter;
+ GtkTreeIter *child = &iter;
+ gboolean valid;
+ GtkTreeIter *ret;
+
+ valid = gtk_tree_model_iter_children(model2, child, parent);
+ while (valid) {
+ struct menu *menu;
+
+ gtk_tree_model_get(model2, child, 6, &menu, -1);
+
+ if (menu == tofind) {
+ memcpy(&found, child, sizeof(GtkTreeIter));
+ return &found;
+ }
+
+ ret = gtktree_iter_find_node(child, tofind);
+ if (ret)
+ return ret;
+
+ valid = gtk_tree_model_iter_next(model2, child);
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Update the tree by adding/removing entries
+ * Does not change other nodes
+ */
+static void update_tree(struct menu *src, GtkTreeIter * dst)
+{
+ struct menu *child1;
+ GtkTreeIter iter, tmp;
+ GtkTreeIter *child2 = &iter;
+ gboolean valid;
+ GtkTreeIter *sibling;
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *menu1, *menu2;
+
+ if (src == &rootmenu)
+ indent = 1;
+
+ valid = gtk_tree_model_iter_children(model2, child2, dst);
+ for (child1 = src->list; child1; child1 = child1->next) {
+
+ prop = child1->prompt;
+ sym = child1->sym;
+
+ reparse:
+ menu1 = child1;
+ if (valid)
+ gtk_tree_model_get(model2, child2, COL_MENU,
+ &menu2, -1);
+ else
+ menu2 = NULL; // force adding of a first child
+
+#ifdef DEBUG
+ printf("%*c%s | %s\n", indent, ' ',
+ menu1 ? menu_get_prompt(menu1) : "nil",
+ menu2 ? menu_get_prompt(menu2) : "nil");
+#endif
+
+ if (!menu_is_visible(child1) && !show_all) { // remove node
+ if (gtktree_iter_find_node(dst, menu1) != NULL) {
+ memcpy(&tmp, child2, sizeof(GtkTreeIter));
+ valid = gtk_tree_model_iter_next(model2,
+ child2);
+ gtk_tree_store_remove(tree2, &tmp);
+ if (!valid)
+ return; // next parent
+ else
+ goto reparse; // next child
+ } else
+ continue;
+ }
+
+ if (menu1 != menu2) {
+ if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node
+ if (!valid && !menu2)
+ sibling = NULL;
+ else
+ sibling = child2;
+ gtk_tree_store_insert_before(tree2,
+ child2,
+ dst, sibling);
+ set_node(child2, menu1, fill_row(menu1));
+ if (menu2 == NULL)
+ valid = TRUE;
+ } else { // remove node
+ memcpy(&tmp, child2, sizeof(GtkTreeIter));
+ valid = gtk_tree_model_iter_next(model2,
+ child2);
+ gtk_tree_store_remove(tree2, &tmp);
+ if (!valid)
+ return; // next parent
+ else
+ goto reparse; // next child
+ }
+ } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
+ set_node(child2, menu1, fill_row(menu1));
+ }
+
+ indent++;
+ update_tree(child1, child2);
+ indent--;
+
+ valid = gtk_tree_model_iter_next(model2, child2);
+ }
+}
+
+
+/* Display the whole tree (single/split/full view) */
+static void display_tree(struct menu *menu)
+{
+ struct symbol *sym;
+ struct property *prop;
+ struct menu *child;
+ enum prop_type ptype;
+
+ if (menu == &rootmenu) {
+ indent = 1;
+ current = &rootmenu;
+ }
+
+ for (child = menu->list; child; child = child->next) {
+ prop = child->prompt;
+ sym = child->sym;
+ ptype = prop ? prop->type : P_UNKNOWN;
+
+ if (sym)
+ sym->flags &= ~SYMBOL_CHANGED;
+
+ if ((view_mode == SPLIT_VIEW)
+ && !(child->flags & MENU_ROOT) && (tree == tree1))
+ continue;
+
+ if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT)
+ && (tree == tree2))
+ continue;
+
+ if (menu_is_visible(child) || show_all)
+ place_node(child, fill_row(child));
+#ifdef DEBUG
+ printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
+ printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
+ dbg_print_ptype(ptype);
+ printf(" | ");
+ if (sym) {
+ dbg_print_stype(sym->type);
+ printf(" | ");
+ dbg_print_flags(sym->flags);
+ printf("\n");
+ } else
+ printf("\n");
+#endif
+ if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
+ && (tree == tree2))
+ continue;
+/*
+ if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
+ || (view_mode == FULL_VIEW)
+ || (view_mode == SPLIT_VIEW))*/
+ if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
+ || (view_mode == FULL_VIEW)
+ || (view_mode == SPLIT_VIEW)) {
+ indent++;
+ display_tree(child);
+ indent--;
+ }
+ }
+}
+
+/* Display a part of the tree starting at current node (single/split view) */
+static void display_tree_part(void)
+{
+ if (tree2)
+ gtk_tree_store_clear(tree2);
+ if (view_mode == SINGLE_VIEW)
+ display_tree(current);
+ else if (view_mode == SPLIT_VIEW)
+ display_tree(browsed);
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
+}
+
+/* Display the list in the left frame (split view) */
+static void display_list(void)
+{
+ if (tree1)
+ gtk_tree_store_clear(tree1);
+
+ tree = tree1;
+ display_tree(&rootmenu);
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
+ tree = tree2;
+}
+
+void fixup_rootmenu(struct menu *menu)
+{
+ struct menu *child;
+ static int menu_cnt = 0;
+
+ menu->flags |= MENU_ROOT;
+ for (child = menu->list; child; child = child->next) {
+ if (child->prompt && child->prompt->type == P_MENU) {
+ menu_cnt++;
+ fixup_rootmenu(child);
+ menu_cnt--;
+ } else if (!menu_cnt)
+ fixup_rootmenu(child);
+ }
+}
+
+
+/* Main */
+int main(int ac, char *av[])
+{
+ const char *name;
+ char *env;
+ gchar *glade_file;
+
+#ifndef LKC_DIRECT_LINK
+ kconfig_load();
+#endif
+
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+ textdomain(PACKAGE);
+
+ /* GTK stuffs */
+ gtk_set_locale();
+ gtk_init(&ac, &av);
+ glade_init();
+
+ //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
+ //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
+
+ /* Determine GUI path */
+ env = getenv(SRCTREE);
+ if (env)
+ glade_file = g_strconcat(env, "/util/kconfig/gconf.glade", NULL);
+ else if (av[0][0] == '/')
+ glade_file = g_strconcat(av[0], ".glade", NULL);
+ else
+ glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
+
+ /* Load the interface and connect signals */
+ init_main_window(glade_file);
+ init_tree_model();
+ init_left_tree();
+ init_right_tree();
+
+ /* Conf stuffs */
+ if (ac > 1 && av[1][0] == '-') {
+ switch (av[1][1]) {
+ case 'a':
+ //showAll = 1;
+ break;
+ case 'h':
+ case '?':
+ printf("%s <config>\n", av[0]);
+ exit(0);
+ }
+ name = av[2];
+ } else
+ name = av[1];
+
+ conf_parse(name);
+ fixup_rootmenu(&rootmenu);
+ conf_read(NULL);
+
+ switch (view_mode) {
+ case SINGLE_VIEW:
+ display_tree_part();
+ break;
+ case SPLIT_VIEW:
+ display_list();
+ break;
+ case FULL_VIEW:
+ display_tree(&rootmenu);
+ break;
+ }
+
+ gtk_main();
+
+ return 0;
+}
+
+static void conf_changed(void)
+{
+ bool changed = conf_get_changed();
+ gtk_widget_set_sensitive(save_btn, changed);
+ gtk_widget_set_sensitive(save_menu_item, changed);
+}
diff --git a/payloads/libpayload/util/kconfig/gconf.glade b/payloads/libpayload/util/kconfig/gconf.glade
new file mode 100644
index 0000000000..6748865d93
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/gconf.glade
@@ -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 libpayload 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>
diff --git a/payloads/libpayload/util/kconfig/images.c b/payloads/libpayload/util/kconfig/images.c
new file mode 100644
index 0000000000..d4f84bd4a9
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/images.c
@@ -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",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/payloads/libpayload/util/kconfig/kxgettext.c b/payloads/libpayload/util/kconfig/kxgettext.c
index abee55ca61..6eb72a7f25 100644
--- a/payloads/libpayload/util/kconfig/kxgettext.c
+++ b/payloads/libpayload/util/kconfig/kxgettext.c
@@ -170,8 +170,8 @@ void menu_build_message_list(struct menu *menu)
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,
+ if (menu->sym != NULL && menu_has_help(menu))
+ message__add(menu_get_help(menu), menu->sym->name,
menu->file == NULL ? "Root Menu" : menu->file->name,
menu->lineno);
@@ -212,7 +212,9 @@ void menu__xgettext(void)
struct message *m = message__list;
while (m != NULL) {
- message__print_gettext_msgid_msgstr(m);
+ /* skip empty lines ("") */
+ if (strlen(m->msg) > sizeof("\"\""))
+ message__print_gettext_msgid_msgstr(m);
m = m->next;
}
}
diff --git a/payloads/libpayload/util/kconfig/lex.zconf.c_shipped b/payloads/libpayload/util/kconfig/lex.zconf.c_shipped
index 7a4ca2c162..1911092521 100644
--- a/payloads/libpayload/util/kconfig/lex.zconf.c_shipped
+++ b/payloads/libpayload/util/kconfig/lex.zconf.c_shipped
@@ -1,14 +1,33 @@
-#line 3 "scripts/kconfig/lex.zconf.c"
+#line 3 "util/kconfig/lex.zconf.c"
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
+#define yy_create_buffer zconf_create_buffer
+#define yy_delete_buffer zconf_delete_buffer
+#define yy_flex_debug zconf_flex_debug
+#define yy_init_buffer zconf_init_buffer
+#define yy_flush_buffer zconf_flush_buffer
+#define yy_load_buffer_state zconf_load_buffer_state
+#define yy_switch_to_buffer zconf_switch_to_buffer
+#define yyin zconfin
+#define yyleng zconfleng
+#define yylex zconflex
+#define yylineno zconflineno
+#define yyout zconfout
+#define yyrestart zconfrestart
+#define yytext zconftext
+#define yywrap zconfwrap
+#define yyalloc zconfalloc
+#define yyrealloc zconfrealloc
+#define yyfree zconffree
+
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
+#define YY_FLEX_SUBMINOR_VERSION 33
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -30,7 +49,15 @@
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
@@ -42,7 +69,7 @@ typedef uint32_t flex_uint32_t;
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
+typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
#endif /* ! C99 */
@@ -134,6 +161,10 @@ typedef unsigned int flex_uint32_t;
#define YY_BUF_SIZE 16384
#endif
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
@@ -148,7 +179,7 @@ extern FILE *zconfin, *zconfout;
#define EOB_ACT_LAST_MATCH 2
#define YY_LESS_LINENO(n)
-
+
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
do \
@@ -215,7 +246,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -267,7 +298,7 @@ int zconfleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
+static int yy_init = 0; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
/* Flag which is used to allow zconfwrap()'s to do buffer switches
@@ -323,7 +354,7 @@ void zconffree (void * );
/* Begin user sect3 */
-#define zconfwrap() 1
+#define zconfwrap(n) 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -820,6 +851,8 @@ void alloc_string(const char *str, int size)
#define YY_EXTRA_TYPE void *
#endif
+static int yy_init_globals (void );
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
@@ -833,7 +866,7 @@ extern int zconfwrap (void );
#endif
static void yyunput (int c,char *buf_ptr );
-
+
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int );
#endif
@@ -938,13 +971,13 @@ YY_DECL
register yy_state_type yy_current_state;
register char *yy_cp, *yy_bp;
register int yy_act;
-
+
int str = 0;
int ts, i;
- if ( (yy_init) )
+ if ( !(yy_init) )
{
- (yy_init) = 0;
+ (yy_init) = 1;
#ifdef YY_USER_INIT
YY_USER_INIT;
@@ -1242,6 +1275,11 @@ YY_RULE_SETUP
case 32:
YY_RULE_SETUP
{
+ while (zconfleng) {
+ if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t'))
+ break;
+ zconfleng--;
+ }
append_string(zconftext, zconfleng);
if (!first_ts)
first_ts = last_ts;
@@ -1452,7 +1490,7 @@ static int yy_get_next_buffer (void)
else
{
- size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1536,7 +1574,7 @@ static int yy_get_next_buffer (void)
{
register yy_state_type yy_current_state;
register char *yy_cp;
-
+
yy_current_state = (yy_start);
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
@@ -1555,7 +1593,7 @@ static int yy_get_next_buffer (void)
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
{
register int yy_is_jam;
-
+
yy_current_state = yy_nxt[yy_current_state][1];
yy_is_jam = (yy_current_state <= 0);
@@ -1565,7 +1603,7 @@ static int yy_get_next_buffer (void)
static void yyunput (int c, register char * yy_bp )
{
register char *yy_cp;
-
+
yy_cp = (yy_c_buf_p);
/* undo effects of setting up zconftext */
@@ -1608,7 +1646,7 @@ static int yy_get_next_buffer (void)
{
int c;
-
+
*(yy_c_buf_p) = (yy_hold_char);
if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
@@ -1675,12 +1713,12 @@ static int yy_get_next_buffer (void)
/** Immediately switch to a different input stream.
* @param input_file A readable stream.
- *
+ *
* @note This function does not reset the start condition to @c INITIAL .
*/
void zconfrestart (FILE * input_file )
{
-
+
if ( ! YY_CURRENT_BUFFER ){
zconfensure_buffer_stack ();
YY_CURRENT_BUFFER_LVALUE =
@@ -1693,11 +1731,11 @@ static int yy_get_next_buffer (void)
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
- *
+ *
*/
void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer )
{
-
+
/* TODO. We should be able to replace this entire function body
* with
* zconfpop_buffer_state();
@@ -1737,13 +1775,13 @@ static void zconf_load_buffer_state (void)
/** Allocate and initialize an input buffer state.
* @param file A readable stream.
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- *
+ *
* @return the allocated buffer state.
*/
YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size )
{
YY_BUFFER_STATE b;
-
+
b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
@@ -1766,11 +1804,11 @@ static void zconf_load_buffer_state (void)
/** Destroy the buffer.
* @param b a buffer created with zconf_create_buffer()
- *
+ *
*/
void zconf_delete_buffer (YY_BUFFER_STATE b )
{
-
+
if ( ! b )
return;
@@ -1791,7 +1829,7 @@ static void zconf_load_buffer_state (void)
{
int oerrno = errno;
-
+
zconf_flush_buffer(b );
b->yy_input_file = file;
@@ -1807,13 +1845,13 @@ static void zconf_load_buffer_state (void)
}
b->yy_is_interactive = 0;
-
+
errno = oerrno;
}
/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- *
+ *
*/
void zconf_flush_buffer (YY_BUFFER_STATE b )
{
@@ -1842,7 +1880,7 @@ static void zconf_load_buffer_state (void)
* the current state. This function will allocate the stack
* if necessary.
* @param new_buffer The new state.
- *
+ *
*/
void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
{
@@ -1872,7 +1910,7 @@ void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
/** Removes and deletes the top of the stack, if present.
* The next element becomes the new top.
- *
+ *
*/
void zconfpop_buffer_state (void)
{
@@ -1896,7 +1934,7 @@ void zconfpop_buffer_state (void)
static void zconfensure_buffer_stack (void)
{
int num_to_alloc;
-
+
if (!(yy_buffer_stack)) {
/* First allocation is just for 2 elements, since we don't know if this
@@ -1907,9 +1945,9 @@ static void zconfensure_buffer_stack (void)
(yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
);
-
+
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
(yy_buffer_stack_max) = num_to_alloc;
(yy_buffer_stack_top) = 0;
return;
@@ -1935,13 +1973,13 @@ static void zconfensure_buffer_stack (void)
/** Setup the input buffer state to scan directly from a user-specified character buffer.
* @param base the character buffer
* @param size the size in bytes of the character buffer
- *
- * @return the newly allocated buffer state object.
+ *
+ * @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
{
YY_BUFFER_STATE b;
-
+
if ( size < 2 ||
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
@@ -1969,42 +2007,42 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to zconflex() will
* scan from a @e copy of @a str.
- * @param yy_str a NUL-terminated string to scan
- *
+ * @param str a NUL-terminated string to scan
+ *
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
* zconf_scan_bytes() instead.
*/
-YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
+YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
{
-
- return zconf_scan_bytes(yy_str,strlen(yy_str) );
+
+ return zconf_scan_bytes(yystr,strlen(yystr) );
}
/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
* scan from a @e copy of @a bytes.
* @param bytes the byte buffer to scan
* @param len the number of bytes in the buffer pointed to by @a bytes.
- *
+ *
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len )
+YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len )
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
-
+
/* Get memory for full buffer, including space for trailing EOB's. */
- n = len + 2;
+ n = _yybytes_len + 2;
buf = (char *) zconfalloc(n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
- for ( i = 0; i < len; ++i )
- buf[i] = bytes[i];
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
b = zconf_scan_buffer(buf,n );
if ( ! b )
@@ -2048,16 +2086,16 @@ static void yy_fatal_error (yyconst char* msg )
/* Accessor methods (get/set functions) to struct members. */
/** Get the current line number.
- *
+ *
*/
int zconfget_lineno (void)
{
-
+
return zconflineno;
}
/** Get the input stream.
- *
+ *
*/
FILE *zconfget_in (void)
{
@@ -2065,7 +2103,7 @@ FILE *zconfget_in (void)
}
/** Get the output stream.
- *
+ *
*/
FILE *zconfget_out (void)
{
@@ -2073,7 +2111,7 @@ FILE *zconfget_out (void)
}
/** Get the length of the current token.
- *
+ *
*/
int zconfget_leng (void)
{
@@ -2081,7 +2119,7 @@ int zconfget_leng (void)
}
/** Get the current token.
- *
+ *
*/
char *zconfget_text (void)
@@ -2091,18 +2129,18 @@ char *zconfget_text (void)
/** Set the current line number.
* @param line_number
- *
+ *
*/
void zconfset_lineno (int line_number )
{
-
+
zconflineno = line_number;
}
/** Set the input stream. This does not discard the current
* input buffer.
* @param in_str A readable stream.
- *
+ *
* @see zconf_switch_to_buffer
*/
void zconfset_in (FILE * in_str )
@@ -2125,10 +2163,38 @@ void zconfset_debug (int bdebug )
zconf_flex_debug = bdebug ;
}
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from zconflex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ zconfin = stdin;
+ zconfout = stdout;
+#else
+ zconfin = (FILE *) 0;
+ zconfout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * zconflex_init()
+ */
+ return 0;
+}
+
/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
int zconflex_destroy (void)
{
-
+
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
zconf_delete_buffer(YY_CURRENT_BUFFER );
@@ -2140,6 +2206,10 @@ int zconflex_destroy (void)
zconffree((yy_buffer_stack) );
(yy_buffer_stack) = NULL;
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * zconflex() is called, initialization will occur. */
+ yy_init_globals( );
+
return 0;
}
@@ -2151,7 +2221,7 @@ int zconflex_destroy (void)
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
{
register int i;
- for ( i = 0; i < n; ++i )
+ for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
#endif
@@ -2160,7 +2230,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
static int yy_flex_strlen (yyconst char * s )
{
register int n;
- for ( n = 0; s[n]; ++n )
+ for ( n = 0; s[n]; ++n )
;
return n;
@@ -2191,19 +2261,6 @@ void zconffree (void * ptr )
#define YYTABLES_NAME "yytables"
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-
void zconf_starthelp(void)
{
new_string();
@@ -2231,7 +2288,7 @@ FILE *zconf_fopen(const char *name)
FILE *f;
f = fopen(name, "r");
- if (!f && name[0] != '/') {
+ if (!f && name != NULL && name[0] != '/') {
env = getenv(SRCTREE);
if (env) {
sprintf(fullname, "%s/%s", env, name);
diff --git a/payloads/libpayload/util/kconfig/lkc.h b/payloads/libpayload/util/kconfig/lkc.h
index 527f60c99c..459afaa03d 100644
--- a/payloads/libpayload/util/kconfig/lkc.h
+++ b/payloads/libpayload/util/kconfig/lkc.h
@@ -31,7 +31,7 @@ extern "C" {
#define SRCTREE "srctree"
-#define PACKAGE "linux"
+#define PACKAGE "libpayload"
#define LOCALEDIR "/usr/share/locale"
#define _(text) gettext(text)
@@ -40,6 +40,11 @@ extern "C" {
#define TF_COMMAND 0x0001
#define TF_PARAM 0x0002
+#define TF_OPTION 0x0004
+
+#define T_OPT_MODULES 1
+#define T_OPT_DEFCONFIG_LIST 2
+#define T_OPT_ENV 3
struct kconf_id {
int name;
@@ -60,15 +65,17 @@ int zconf_lineno(void);
char *zconf_curname(void);
/* confdata.c */
-extern const char conf_def_filename[];
-
+const char *conf_get_configname(void);
char *conf_get_default_confname(void);
+void sym_set_change_count(int count);
+void sym_add_change_count(int count);
/* kconfig_load.c */
void kconfig_load(void);
/* menu.c */
void menu_init(void);
+void menu_warn(struct menu *menu, const char *fmt, ...);
struct menu *menu_add_menu(void);
void menu_end_menu(void);
void menu_add_entry(struct symbol *sym);
@@ -78,6 +85,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
+void menu_add_option(int token, char *arg);
void menu_finalize(struct menu *parent);
void menu_set_type(int type);
@@ -97,12 +105,16 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
const char *str_get(struct gstr *gs);
/* symbol.c */
+extern struct expr *sym_env_list;
+
void sym_init(void);
void sym_clear_all_valid(void);
+void sym_set_all_changed(void);
void sym_set_changed(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym);
struct property *prop_alloc(enum prop_type type, struct symbol *sym);
struct symbol *prop_get_symbol(struct property *prop);
+struct property *sym_get_env_prop(struct symbol *sym);
static inline tristate sym_get_tristate_value(struct symbol *sym)
{
@@ -137,7 +149,7 @@ static inline bool sym_is_optional(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
diff --git a/payloads/libpayload/util/kconfig/lkc_proto.h b/payloads/libpayload/util/kconfig/lkc_proto.h
index b6a389c5fc..4d09f6ddef 100644
--- a/payloads/libpayload/util/kconfig/lkc_proto.h
+++ b/payloads/libpayload/util/kconfig/lkc_proto.h
@@ -2,8 +2,11 @@
/* confdata.c */
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
-P(conf_read_simple,int,(const char *name));
+P(conf_read_simple,int,(const char *name, int));
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 */
P(rootmenu,struct menu,);
@@ -12,10 +15,11 @@ P(menu_is_visible,bool,(struct menu *menu));
P(menu_get_prompt,const char *,(struct menu *menu));
P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+P(menu_has_help,bool,(struct menu *menu));
+P(menu_get_help,const char *,(struct menu *menu));
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
-P(sym_change_count,int,);
P(sym_lookup,struct symbol *,(const char *name, int isconst));
P(sym_find,struct symbol *,(const char *name));
@@ -38,4 +42,4 @@ P(prop_get_type_name,const char *,(enum prop_type type));
/* expr.c */
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));
diff --git a/payloads/libpayload/util/kconfig/lxdialog/.gitignore b/payloads/libpayload/util/kconfig/lxdialog/.gitignore
new file mode 100644
index 0000000000..90b08ff025
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/lxdialog/.gitignore
@@ -0,0 +1,4 @@
+#
+# Generated files
+#
+lxdialog
diff --git a/payloads/libpayload/util/kconfig/lxdialog/BIG.FAT.WARNING b/payloads/libpayload/util/kconfig/lxdialog/BIG.FAT.WARNING
index b5d3b10b2e..a8999d82bd 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/BIG.FAT.WARNING
+++ b/payloads/libpayload/util/kconfig/lxdialog/BIG.FAT.WARNING
@@ -1,4 +1,4 @@
This is NOT the official version of dialog. This version has been
significantly modified from the original. It is for use by the Linux
-busybox configuration script. Please do not bother Savio Lam with
+kernel configuration script. Please do not bother Savio Lam with
questions about this program.
diff --git a/payloads/libpayload/util/kconfig/lxdialog/Makefile b/payloads/libpayload/util/kconfig/lxdialog/Makefile
deleted file mode 100644
index ceddc8d663..0000000000
--- a/payloads/libpayload/util/kconfig/lxdialog/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# Makefile to build lxdialog package
-#
-
-CONFIG_SHELL := sh
-
-check-lxdialog := ./check-lxdialog.sh
-
-HOSTCC ?= gcc
-
-# Use recursively expanded variables so we do not call gcc unless
-# we really need to do so. (Do not call gcc as part of make mrproper)
-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
-
-HOST_EXTRACFLAGS += -DLOCALE
-
-PHONY += dochecklxdialog
-dochecklxdialog:
- $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
-
-hostprogs-y := lxdialog
-always := $(hostprogs-y) dochecklxdialog
-
-lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
- util.o lxdialog.o msgbox.o
-
-lxdialog: dochecklxdialog $(lxdialog-objs)
- $(CC) $(HOST_LOADLIBES) -o lxdialog $(lxdialog-objs)
-
-%.o: %.c
- $(Q)$(HOSTCC) $(HOST_EXTRACFLAGS) $^ -c -o $@
-
diff --git a/payloads/libpayload/util/kconfig/lxdialog/check-lxdialog.sh b/payloads/libpayload/util/kconfig/lxdialog/check-lxdialog.sh
index 120d624e67..62e1e02126 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/check-lxdialog.sh
+++ b/payloads/libpayload/util/kconfig/lxdialog/check-lxdialog.sh
@@ -4,21 +4,15 @@
# 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
+ for ext in so a dylib ; do
+ for lib in ncursesw ncurses curses ; do
+ $cc -print-file-name=lib${lib}.${ext} | grep -q /
+ if [ $? -eq 0 ]; then
+ echo "-l${lib}"
+ exit
+ fi
+ done
+ done
exit 1
}
@@ -42,14 +36,16 @@ 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
+ echo -e " #include CURSES_LOC \n 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
+ echo " *** Unable to find the ncurses libraries or the" 1>&2
+ echo " *** required header files." 1>&2
+ echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
+ echo " *** " 1>&2
+ echo " *** Install ncurses (ncurses-devel) and try again." 1>&2
+ echo " *** " 1>&2
+ exit 1
fi
}
@@ -57,7 +53,7 @@ usage() {
printf "Usage: $0 [-check compiler options|-header|-library]\n"
}
-if [ $# == 0 ]; then
+if [ $# -eq 0 ]; then
usage
exit 1
fi
diff --git a/payloads/libpayload/util/kconfig/lxdialog/checklist.c b/payloads/libpayload/util/kconfig/lxdialog/checklist.c
index be0200e9cd..b2a878c936 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/checklist.c
+++ b/payloads/libpayload/util/kconfig/lxdialog/checklist.c
@@ -28,25 +28,25 @@ static int list_width, check_x, item_x;
/*
* Print list item
*/
-static void print_item(WINDOW * win, const char *item, int status, int choice,
- int selected)
+static void print_item(WINDOW * win, int choice, int selected)
{
int i;
/* Clear 'residue' of last item */
- wattrset(win, menubox_attr);
+ wattrset(win, dlg.menubox.atr);
wmove(win, choice, 0);
for (i = 0; i < list_width; i++)
waddch(win, ' ');
wmove(win, choice, check_x);
- wattrset(win, selected ? check_selected_attr : check_attr);
- wprintw(win, "(%c)", status ? 'X' : ' ');
-
- wattrset(win, selected ? tag_selected_attr : tag_attr);
- mvwaddch(win, choice, item_x, item[0]);
- wattrset(win, selected ? item_selected_attr : item_attr);
- waddstr(win, (char *)item + 1);
+ wattrset(win, selected ? dlg.check_selected.atr
+ : dlg.check.atr);
+ wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
+
+ wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
+ mvwaddch(win, choice, item_x, item_str()[0]);
+ wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+ waddstr(win, (char *)item_str() + 1);
if (selected) {
wmove(win, choice, check_x + 1);
wrefresh(win);
@@ -62,11 +62,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
wmove(win, y, x);
if (scroll > 0) {
- wattrset(win, uarrow_attr);
+ wattrset(win, dlg.uarrow.atr);
waddch(win, ACS_UARROW);
waddstr(win, "(-)");
} else {
- wattrset(win, menubox_attr);
+ wattrset(win, dlg.menubox.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -77,11 +77,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
wmove(win, y, x);
if ((height < item_no) && (scroll + choice < item_no - 1)) {
- wattrset(win, darrow_attr);
+ wattrset(win, dlg.darrow.atr);
waddch(win, ACS_DARROW);
waddstr(win, "(+)");
} else {
- wattrset(win, menubox_border_attr);
+ wattrset(win, dlg.menubox_border.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -97,8 +97,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int x = width / 2 - 11;
int y = height - 2;
- print_button(dialog, "Select", y, x, selected == 0);
- print_button(dialog, " Help ", y, x + 14, selected == 1);
+ print_button(dialog, gettext("Select"), y, x, selected == 0);
+ print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
wmove(dialog, y, x + 1 + 14 * selected);
wrefresh(dialog);
@@ -109,32 +109,29 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
* in the style of radiolist (only one option turned on at a time).
*/
int dialog_checklist(const char *title, const char *prompt, int height,
- int width, int list_height, int item_no,
- const char *const *items)
+ int width, int list_height)
{
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;
- /* Allocate space for storing item on/off status */
- if ((status = malloc(sizeof(int) * item_no)) == NULL) {
- endwin();
- fprintf(stderr,
- "\nCan't allocate memory in dialog_checklist().\n");
- exit(-1);
+ /* which item to highlight */
+ item_foreach() {
+ if (item_is_tag('X'))
+ choice = item_n();
+ if (item_is_selected()) {
+ choice = item_n();
+ break;
+ }
}
- /* Initializes status */
- for (i = 0; i < item_no; i++) {
- status[i] = !strcasecmp(items[i * 3 + 2], "on");
- if ((!choice && status[i])
- || !strcasecmp(items[i * 3 + 2], "selected"))
- choice = i + 1;
- }
- if (choice)
- choice--;
+do_resize:
+ if (getmaxy(stdscr) < (height + 6))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) < (width + 6))
+ return -ERRDISPLAYTOOSMALL;
- max_choice = MIN(list_height, item_no);
+ max_choice = MIN(list_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -145,17 +142,18 @@ int dialog_checklist(const char *title, const char *prompt, int height,
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
- wattrset(dialog, border_attr);
+ 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, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
list_width = width - 6;
@@ -170,12 +168,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* 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);
+ dlg.menubox_border.atr, dlg.menubox.atr);
/* 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 * 3 + 1]) + 4);
+ item_foreach()
+ check_x = MAX(check_x, strlen(item_str()) + 4);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
@@ -187,11 +185,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Print the list */
for (i = 0; i < max_choice; i++) {
- print_item(list, items[(scroll + i) * 3 + 1],
- status[i + scroll], i, i == choice);
+ item_set(scroll + i);
+ print_item(list, i, i == choice);
}
- print_arrows(dialog, choice, item_no, scroll,
+ print_arrows(dialog, choice, item_count(), scroll,
box_y, box_x + check_x + 5, list_height);
print_buttons(dialog, height, width, 0);
@@ -200,13 +198,14 @@ int dialog_checklist(const char *title, const char *prompt, int height,
wnoutrefresh(list);
doupdate();
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
- for (i = 0; i < max_choice; i++)
- if (toupper(key) ==
- toupper(items[(scroll + i) * 3 + 1][0]))
+ 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 == '-') {
@@ -217,15 +216,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
/* Scroll list down */
if (list_height > 1) {
/* De-highlight current first item */
- print_item(list, items[scroll * 3 + 1],
- status[scroll], 0, FALSE);
+ item_set(scroll);
+ print_item(list, 0, FALSE);
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
- print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
- print_arrows(dialog, choice, item_no,
+ 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);
@@ -236,23 +236,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
i = choice - 1;
} else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
- if (scroll + choice >= item_no - 1)
+ if (scroll + choice >= item_count() - 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) * 3 + 1],
- status[scroll + max_choice - 1],
- max_choice - 1, FALSE);
+ item_set(scroll + max_choice - 1);
+ print_item(list,
+ max_choice - 1,
+ FALSE);
scrollok(list, TRUE);
wscrl(list, 1);
scrollok(list, FALSE);
}
scroll++;
- print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
- status[scroll + max_choice - 1], max_choice - 1, TRUE);
+ item_set(scroll + max_choice - 1);
+ print_item(list, max_choice - 1, TRUE);
- print_arrows(dialog, choice, item_no,
+ print_arrows(dialog, choice, item_count(),
scroll, box_y, box_x + check_x + 5, list_height);
wnoutrefresh(dialog);
@@ -264,12 +265,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
}
if (i != choice) {
/* De-highlight current item */
- print_item(list, items[(scroll + choice) * 3 + 1],
- status[scroll + choice], choice, FALSE);
+ item_set(scroll + choice);
+ print_item(list, choice, FALSE);
/* Highlight new item */
choice = i;
- print_item(list, items[(scroll + choice) * 3 + 1],
- status[scroll + choice], choice, TRUE);
+ item_set(scroll + choice);
+ print_item(list, choice, TRUE);
wnoutrefresh(dialog);
wrefresh(list);
}
@@ -279,10 +280,19 @@ int dialog_checklist(const char *title, const char *prompt, int height,
case 'H':
case 'h':
case '?':
- fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+ 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);
- free(status);
- return 1;
+ return button;
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
@@ -292,42 +302,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
print_buttons(dialog, height, width, button);
wrefresh(dialog);
break;
- case 'S':
- case 's':
- case ' ':
- case '\n':
- if (!button) {
- 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) * 3 + 1],
- status[scroll + i], i, i == choice);
- }
- wnoutrefresh(dialog);
- wrefresh(list);
-
- for (i = 0; i < item_no; i++)
- if (status[i])
- fprintf(stderr, "%s", items[i * 3]);
- } else
- fprintf(stderr, "%s", items[(scroll + choice) * 3]);
- delwin(dialog);
- free(status);
- return button;
case 'X':
case 'x':
- key = ESC;
- case ESC:
+ 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);
- free(status);
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/colors.h b/payloads/libpayload/util/kconfig/lxdialog/colors.h
deleted file mode 100644
index db071df12b..0000000000
--- a/payloads/libpayload/util/kconfig/lxdialog/colors.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * colors.h -- color attribute definitions
- *
- * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Default color definitions
- *
- * *_FG = foreground
- * *_BG = background
- * *_HL = highlight?
- */
-#define SCREEN_FG COLOR_CYAN
-#define SCREEN_BG COLOR_BLUE
-#define SCREEN_HL TRUE
-
-#define SHADOW_FG COLOR_BLACK
-#define SHADOW_BG COLOR_BLACK
-#define SHADOW_HL TRUE
-
-#define DIALOG_FG COLOR_BLACK
-#define DIALOG_BG COLOR_WHITE
-#define DIALOG_HL FALSE
-
-#define TITLE_FG COLOR_YELLOW
-#define TITLE_BG COLOR_WHITE
-#define TITLE_HL TRUE
-
-#define BORDER_FG COLOR_WHITE
-#define BORDER_BG COLOR_WHITE
-#define BORDER_HL TRUE
-
-#define BUTTON_ACTIVE_FG COLOR_WHITE
-#define BUTTON_ACTIVE_BG COLOR_BLUE
-#define BUTTON_ACTIVE_HL TRUE
-
-#define BUTTON_INACTIVE_FG COLOR_BLACK
-#define BUTTON_INACTIVE_BG COLOR_WHITE
-#define BUTTON_INACTIVE_HL FALSE
-
-#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
-#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
-#define BUTTON_KEY_ACTIVE_HL TRUE
-
-#define BUTTON_KEY_INACTIVE_FG COLOR_RED
-#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
-#define BUTTON_KEY_INACTIVE_HL FALSE
-
-#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
-#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
-#define BUTTON_LABEL_ACTIVE_HL TRUE
-
-#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
-#define BUTTON_LABEL_INACTIVE_HL TRUE
-
-#define INPUTBOX_FG COLOR_BLACK
-#define INPUTBOX_BG COLOR_WHITE
-#define INPUTBOX_HL FALSE
-
-#define INPUTBOX_BORDER_FG COLOR_BLACK
-#define INPUTBOX_BORDER_BG COLOR_WHITE
-#define INPUTBOX_BORDER_HL FALSE
-
-#define SEARCHBOX_FG COLOR_BLACK
-#define SEARCHBOX_BG COLOR_WHITE
-#define SEARCHBOX_HL FALSE
-
-#define SEARCHBOX_TITLE_FG COLOR_YELLOW
-#define SEARCHBOX_TITLE_BG COLOR_WHITE
-#define SEARCHBOX_TITLE_HL TRUE
-
-#define SEARCHBOX_BORDER_FG COLOR_WHITE
-#define SEARCHBOX_BORDER_BG COLOR_WHITE
-#define SEARCHBOX_BORDER_HL TRUE
-
-#define POSITION_INDICATOR_FG COLOR_YELLOW
-#define POSITION_INDICATOR_BG COLOR_WHITE
-#define POSITION_INDICATOR_HL TRUE
-
-#define MENUBOX_FG COLOR_BLACK
-#define MENUBOX_BG COLOR_WHITE
-#define MENUBOX_HL FALSE
-
-#define MENUBOX_BORDER_FG COLOR_WHITE
-#define MENUBOX_BORDER_BG COLOR_WHITE
-#define MENUBOX_BORDER_HL TRUE
-
-#define ITEM_FG COLOR_BLACK
-#define ITEM_BG COLOR_WHITE
-#define ITEM_HL FALSE
-
-#define ITEM_SELECTED_FG COLOR_WHITE
-#define ITEM_SELECTED_BG COLOR_BLUE
-#define ITEM_SELECTED_HL TRUE
-
-#define TAG_FG COLOR_YELLOW
-#define TAG_BG COLOR_WHITE
-#define TAG_HL TRUE
-
-#define TAG_SELECTED_FG COLOR_YELLOW
-#define TAG_SELECTED_BG COLOR_BLUE
-#define TAG_SELECTED_HL TRUE
-
-#define TAG_KEY_FG COLOR_YELLOW
-#define TAG_KEY_BG COLOR_WHITE
-#define TAG_KEY_HL TRUE
-
-#define TAG_KEY_SELECTED_FG COLOR_YELLOW
-#define TAG_KEY_SELECTED_BG COLOR_BLUE
-#define TAG_KEY_SELECTED_HL TRUE
-
-#define CHECK_FG COLOR_BLACK
-#define CHECK_BG COLOR_WHITE
-#define CHECK_HL FALSE
-
-#define CHECK_SELECTED_FG COLOR_WHITE
-#define CHECK_SELECTED_BG COLOR_BLUE
-#define CHECK_SELECTED_HL TRUE
-
-#define UARROW_FG COLOR_GREEN
-#define UARROW_BG COLOR_WHITE
-#define UARROW_HL TRUE
-
-#define DARROW_FG COLOR_GREEN
-#define DARROW_BG COLOR_WHITE
-#define DARROW_HL TRUE
-
-/* End of default color definitions */
-
-#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-#define COLOR_NAME_LEN 10
-#define COLOR_COUNT 8
-
-/*
- * Global variables
- */
-
-extern int color_table[][3];
diff --git a/payloads/libpayload/util/kconfig/lxdialog/dialog.h b/payloads/libpayload/util/kconfig/lxdialog/dialog.h
index af3cf716e2..b5211fce0d 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/dialog.h
+++ b/payloads/libpayload/util/kconfig/lxdialog/dialog.h
@@ -24,6 +24,13 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
+
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+#endif
#ifdef __sun__
#define CURS_MACROS
@@ -48,7 +55,7 @@
#define TR(params) _tracef params
-#define ESC 27
+#define KEY_ESC 27
#define TAB 9
#define MAX_LEN 2048
#define BUF_SIZE (10*1024)
@@ -86,63 +93,111 @@
#define ACS_DARROW 'v'
#endif
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
+
/*
- * Attribute names
+ * Color definitions
*/
-#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
+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
*/
-extern bool use_colors;
-extern bool use_shadow;
-
-extern chtype attributes[];
-
-extern const char *backtitle;
+extern struct dialog_info dlg;
+extern char dialog_input_result[];
/*
* Function prototypes
*/
-extern void create_rc(const char *filename);
-extern int parse_rc(void);
-void init_dialog(void);
-void end_dialog(void);
+/* item list as used by checklist and menubox */
+void item_reset(void);
+void item_make(const char *fmt, ...);
+void item_add_str(const char *fmt, ...);
+void item_set_tag(char tag);
+void item_set_data(void *p);
+void item_set_selected(int val);
+int item_activate_selected(void);
+void *item_data(void);
+char item_tag(void);
+
+/* item list manipulation for lxdialog use */
+#define MAXITEMSTR 200
+struct dialog_item {
+ char str[MAXITEMSTR]; /* promtp displayed */
+ char tag;
+ void *data; /* pointer to menu item - used by menubox+checklist */
+ int selected; /* Set to 1 by dialog_*() function if selected. */
+};
+
+/* list of lialog_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);
+
+int init_dialog(const char *backtitle);
+void set_dialog_backtitle(const char *backtitle);
+void end_dialog(int x, int y);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void);
-void color_setup(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);
@@ -155,12 +210,10 @@ 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, int height, int width,
- int menu_height, const char *choice, int item_no,
- const char *const *items);
+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, int item_no,
- const char *const *items);
+ 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);
diff --git a/payloads/libpayload/util/kconfig/lxdialog/inputbox.c b/payloads/libpayload/util/kconfig/lxdialog/inputbox.c
index 779503726b..4946bd02b4 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/inputbox.c
+++ b/payloads/libpayload/util/kconfig/lxdialog/inputbox.c
@@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int x = width / 2 - 11;
int y = height - 2;
- print_button(dialog, " Ok ", y, x, selected == 0);
- print_button(dialog, " Help ", y, x + 14, selected == 1);
+ print_button(dialog, gettext(" Ok "), y, x, selected == 0);
+ print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
wmove(dialog, y, x + 1 + 14 * selected);
wrefresh(dialog);
@@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
char *instr = dialog_input_result;
WINDOW *dialog;
+ if (!init)
+ instr[0] = '\0';
+ else
+ strcpy(instr, init);
+
+do_resize:
+ if (getmaxy(stdscr) <= (height - 2))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) <= (width - 2))
+ return -ERRDISPLAYTOOSMALL;
+
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
@@ -58,17 +69,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int 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);
+ 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, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
/* Draw the input field box */
@@ -76,18 +88,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
getyx(dialog, y, x);
box_y = y + 2;
box_x = (width - box_width) / 2;
- draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+ draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
+ dlg.border.atr, dlg.dialog.atr);
print_buttons(dialog, height, width, 0);
/* Set up the initial value */
wmove(dialog, box_y, box_x);
- wattrset(dialog, inputbox_attr);
-
- if (!init)
- instr[0] = '\0';
- else
- strcpy(instr, init);
+ wattrset(dialog, dlg.inputbox.atr);
input_x = strlen(instr);
@@ -104,7 +112,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
wrefresh(dialog);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
if (button == -1) { /* Input box selected */
@@ -120,7 +128,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
case KEY_BACKSPACE:
case 127:
if (input_x || scroll) {
- wattrset(dialog, inputbox_attr);
+ wattrset(dialog, dlg.inputbox.atr);
if (!input_x) {
scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
wmove(dialog, box_y, box_x);
@@ -140,7 +148,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
default:
if (key < 0x100 && isprint(key)) {
if (scroll + input_x < MAX_LEN) {
- wattrset(dialog, inputbox_attr);
+ wattrset(dialog, dlg.inputbox.atr);
instr[scroll + input_x] = key;
instr[scroll + input_x + 1] = '\0';
if (input_x == box_width - 1) {
@@ -213,12 +221,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
return (button == -1 ? 0 : button);
case 'X':
case 'x':
- key = ESC;
- case ESC:
+ key = KEY_ESC;
+ break;
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
delwin(dialog);
- return -1; /* ESC pressed */
+ return KEY_ESC; /* ESC pressed */
}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/lxdialog.c b/payloads/libpayload/util/kconfig/lxdialog/lxdialog.c
deleted file mode 100644
index 79f6c5fb5c..0000000000
--- a/payloads/libpayload/util/kconfig/lxdialog/lxdialog.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * dialog - Display simple dialog boxes from shell scripts
- *
- * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void Usage(const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
-
-struct Mode {
- char *name;
- int argmin, argmax, argmod;
- jumperFn *jumper;
-};
-
-jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] = {
- {"--menu", 9, 0, 3, j_menu},
- {"--radiolist", 9, 0, 3, j_radiolist},
- {"--yesno", 5, 5, 1, j_yesno},
- {"--textbox", 5, 5, 1, j_textbox},
- {"--inputbox", 5, 6, 1, j_inputbox},
- {"--msgbox", 5, 5, 1, j_msgbox},
- {"--infobox", 5, 5, 1, j_infobox},
- {NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int main(int argc, const char *const *argv)
-{
- int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
- const char *title = NULL;
-
-#ifdef LOCALE
- (void)setlocale(LC_ALL, "");
-#endif
-
-#ifdef TRACE
- trace(TRACE_CALLS | TRACE_UPDATE);
-#endif
- if (argc < 2) {
- Usage(argv[0]);
- exit(-1);
- }
-
- while (offset < argc - 1 && !end_common_opts) { /* Common options */
- if (!strcmp(argv[offset + 1], "--title")) {
- if (argc - offset < 3 || title != NULL) {
- Usage(argv[0]);
- exit(-1);
- } else {
- title = argv[offset + 2];
- offset += 2;
- }
- } else if (!strcmp(argv[offset + 1], "--backtitle")) {
- if (backtitle != NULL) {
- Usage(argv[0]);
- exit(-1);
- } else {
- backtitle = argv[offset + 2];
- offset += 2;
- }
- } else if (!strcmp(argv[offset + 1], "--clear")) {
- if (opt_clear) { /* Hey, "--clear" can't appear twice! */
- Usage(argv[0]);
- exit(-1);
- } else if (argc == 2) { /* we only want to clear the screen */
- init_dialog();
- refresh(); /* init_dialog() will clear the screen for us */
- end_dialog();
- return 0;
- } else {
- opt_clear = 1;
- offset++;
- }
- } else /* no more common options */
- end_common_opts = 1;
- }
-
- if (argc - 1 == offset) { /* no more options */
- Usage(argv[0]);
- exit(-1);
- }
- /* use a table to look for the requested mode, to avoid code duplication */
-
- for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
- if (!strcmp(argv[offset + 1], modePtr->name))
- break;
-
- if (!modePtr->name)
- Usage(argv[0]);
- if (argc - offset < modePtr->argmin)
- Usage(argv[0]);
- if (modePtr->argmax && argc - offset > modePtr->argmax)
- Usage(argv[0]);
-
- init_dialog();
- retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
- if (opt_clear) { /* clear screen before exit */
- attr_clear(stdscr, LINES, COLS, screen_attr);
- refresh();
- }
- end_dialog();
-
- exit(retval);
-}
-
-/*
- * Print program usage
- */
-static void Usage(const char *name)
-{
- fprintf(stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n modified/gutted for use as a Linux kernel config tool by \
-\n William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
-\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n --textbox <file> <height> <width>\
-\n --inputbox <text> <height> <width> [<init>]\
-\n --yesno <text> <height> <width>\
-\n", name, name);
- exit(-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int j_menu(const char *t, int ac, const char *const *av)
-{
- return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
- atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int j_radiolist(const char *t, int ac, const char *const *av)
-{
- return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
- atoi(av[5]), (ac - 6) / 3, av + 6);
-}
-
-int j_textbox(const char *t, int ac, const char *const *av)
-{
- return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_yesno(const char *t, int ac, const char *const *av)
-{
- return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_inputbox(const char *t, int ac, const char *const *av)
-{
- int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
- ac == 6 ? av[5] : (char *)NULL);
- if (ret == 0)
- fprintf(stderr, dialog_input_result);
- return ret;
-}
-
-int j_msgbox(const char *t, int ac, const char *const *av)
-{
- return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
-}
-
-int j_infobox(const char *t, int ac, const char *const *av)
-{
- return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
-}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/menubox.c b/payloads/libpayload/util/kconfig/lxdialog/menubox.c
index 1fd501b395..fa9d633f29 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/menubox.c
+++ b/payloads/libpayload/util/kconfig/lxdialog/menubox.c
@@ -26,7 +26,7 @@
*
* *) A bugfix for the Page-Down problem
*
- * *) Formerly when I used Page Down and Page Up, the cursor would be set
+ * *) Formerly when I used Page Down and Page Up, the cursor would be set
* to the first position in the menu box. Now lxdialog is a bit
* smarter and works more like other menu systems (just have a look at
* it).
@@ -63,19 +63,19 @@ static int menu_width, item_x;
/*
* Print menu item
*/
-static void do_print_item(WINDOW * win, const char *item, int choice,
+static void do_print_item(WINDOW * win, const char *item, int line_y,
int selected, int hotkey)
{
int j;
char *menu_item = malloc(menu_width + 1);
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");
/* Clear 'residue' of last item */
- wattrset(win, menubox_attr);
- wmove(win, choice, 0);
+ wattrset(win, dlg.menubox.atr);
+ wmove(win, line_y, 0);
#if OLD_NCURSES
{
int i;
@@ -85,23 +85,24 @@ static void do_print_item(WINDOW * win, const char *item, int choice,
#else
wclrtoeol(win);
#endif
- wattrset(win, selected ? item_selected_attr : item_attr);
- mvwaddstr(win, choice, item_x, menu_item);
+ wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+ mvwaddstr(win, line_y, item_x, menu_item);
if (hotkey) {
- wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
- mvwaddch(win, choice, item_x + j, menu_item[j]);
+ wattrset(win, selected ? dlg.tag_key_selected.atr
+ : dlg.tag_key.atr);
+ mvwaddch(win, line_y, item_x + j, menu_item[j]);
}
if (selected) {
- wmove(win, choice, item_x + 1);
+ wmove(win, line_y, item_x + 1);
}
free(menu_item);
wrefresh(win);
}
-#define print_item(index, choice, selected) \
-do {\
- int hotkey = (items[(index) * 2][0] != ':'); \
- do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+#define print_item(index, choice, selected) \
+do { \
+ item_set(index); \
+ do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
} while (0)
/*
@@ -117,11 +118,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
wmove(win, y, x);
if (scroll > 0) {
- wattrset(win, uarrow_attr);
+ wattrset(win, dlg.uarrow.atr);
waddch(win, ACS_UARROW);
waddstr(win, "(-)");
} else {
- wattrset(win, menubox_attr);
+ wattrset(win, dlg.menubox.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -133,11 +134,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
wrefresh(win);
if ((height < item_no) && (scroll + height < item_no)) {
- wattrset(win, darrow_attr);
+ wattrset(win, dlg.darrow.atr);
waddch(win, ACS_DARROW);
waddstr(win, "(+)");
} else {
- wattrset(win, menubox_border_attr);
+ wattrset(win, dlg.menubox_border.atr);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
waddch(win, ACS_HLINE);
@@ -156,9 +157,9 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
int x = width / 2 - 16;
int y = height - 2;
- print_button(win, "Select", y, x, selected == 0);
- print_button(win, " Exit ", y, x + 12, selected == 1);
- print_button(win, " Help ", y, x + 24, selected == 2);
+ print_button(win, gettext("Select"), y, x, selected == 0);
+ print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
+ print_button(win, gettext(" Help "), y, x + 24, selected == 2);
wmove(win, y, x + 1 + 12 * selected);
wrefresh(win);
@@ -178,17 +179,26 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
/*
* Display a menu for choosing among a number of options
*/
-int dialog_menu(const char *title, const char *prompt, int height, int width,
- int menu_height, const char *current, int item_no,
- const char *const *items)
+int dialog_menu(const char *title, const char *prompt,
+ const void *selected, int *s_scroll)
{
int i, j, x, y, box_x, box_y;
+ int height, width, menu_height;
int key = 0, button = 0, scroll = 0, choice = 0;
int first_item = 0, max_choice;
WINDOW *dialog, *menu;
- FILE *f;
- max_choice = MIN(menu_height, item_no);
+do_resize:
+ height = getmaxy(stdscr);
+ width = getmaxx(stdscr);
+ if (height < 15 || width < 65)
+ return -ERRDISPLAYTOOSMALL;
+
+ height -= 4;
+ width -= 5;
+ menu_height = height - 10;
+
+ max_choice = MIN(menu_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -199,18 +209,19 @@ int dialog_menu(const char *title, const char *prompt, int height, int 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);
+ 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, dialog_attr);
- wbkgdset(dialog, dialog_attr & A_COLOR);
+ wattrset(dialog, dlg.dialog.atr);
+ wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
menu_width = width - 6;
@@ -224,33 +235,29 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
/* draw a box around the menu items */
draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
- menubox_border_attr, menubox_attr);
+ dlg.menubox_border.atr, dlg.menubox.atr);
- item_x = (menu_width - 70) / 2;
+ if (menu_width >= 80)
+ item_x = (menu_width - 70) / 2;
+ else
+ item_x = 4;
/* Set choice to default item */
- for (i = 0; i < item_no; i++)
- if (strcmp(current, items[i * 2]) == 0)
- choice = i;
-
- /* 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;
- }
+ item_foreach()
+ if (selected && (selected == item_data()))
+ choice = item_n();
+ /* get the saved scroll info */
+ scroll = *s_scroll;
+ if ((scroll <= choice) && (scroll + max_choice > choice) &&
+ (scroll >= 0) && (scroll + max_choice <= item_count())) {
+ first_item = scroll;
+ choice = choice - scroll;
+ } else {
+ scroll = 0;
}
- if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
- if (choice >= item_no - max_choice / 2)
- scroll = first_item = item_no - max_choice;
+ if ((choice >= max_choice)) {
+ if (choice >= item_count() - max_choice / 2)
+ scroll = first_item = item_count() - max_choice;
else
scroll = first_item = choice - max_choice / 2;
choice = choice - scroll;
@@ -263,14 +270,14 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
wnoutrefresh(menu);
- print_arrows(dialog, item_no, scroll,
+ 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 != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(menu);
if (key < 256 && isalpha(key))
@@ -280,14 +287,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
i = max_choice;
else {
for (i = choice + 1; i < max_choice; i++) {
- j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
- if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+ 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++) {
- j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
- if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+ item_set(scroll + i);
+ j = first_alpha(item_str(), "YyNnMmHh");
+ if (key == tolower(item_str()[j]))
break;
}
}
@@ -312,7 +321,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
print_item(scroll+choice, choice, FALSE);
if ((choice > max_choice - 3) &&
- (scroll + max_choice < item_no)) {
+ (scroll + max_choice < item_count())) {
/* Scroll menu up */
do_scroll(menu, &scroll, 1);
@@ -335,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
} else if (key == KEY_NPAGE) {
for (i = 0; (i < max_choice); i++) {
- if (scroll + max_choice < item_no) {
+ if (scroll + max_choice < item_count()) {
do_scroll(menu, &scroll, 1);
print_item(scroll+max_choice-1,
max_choice - 1, FALSE);
@@ -349,7 +358,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
print_item(scroll + choice, choice, TRUE);
- print_arrows(dialog, item_no, scroll,
+ print_arrows(dialog, item_count(), scroll,
box_y, box_x + item_x + 1, menu_height);
wnoutrefresh(dialog);
@@ -375,12 +384,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case 'm':
case '/':
/* save scroll info */
- if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
- fprintf(f, "%d\n", scroll);
- fclose(f);
- }
+ *s_scroll = scroll;
+ delwin(menu);
delwin(dialog);
- fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+ item_set(scroll + choice);
+ item_set_selected(1);
switch (key) {
case 's':
return 3;
@@ -400,27 +408,27 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
case '?':
button = 2;
case '\n':
+ *s_scroll = scroll;
+ delwin(menu);
delwin(dialog);
- if (button == 2)
- fprintf(stderr, "%s \"%s\"\n",
- items[(scroll + choice) * 2],
- items[(scroll + choice) * 2 + 1] +
- first_alpha(items [(scroll + choice) * 2 + 1], ""));
- else
- fprintf(stderr, "%s\n",
- items[(scroll + choice) * 2]);
-
- remove("lxdialog.scrltmp");
+ item_set(scroll + choice);
+ item_set_selected(1);
return button;
case 'e':
case 'x':
- key = ESC;
- case ESC:
+ 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);
delwin(dialog);
- remove("lxdialog.scrltmp");
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/msgbox.c b/payloads/libpayload/util/kconfig/lxdialog/msgbox.c
deleted file mode 100644
index 7323f5471f..0000000000
--- a/payloads/libpayload/util/kconfig/lxdialog/msgbox.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * msgbox.c -- implements the message box and info box
- *
- * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int dialog_msgbox(const char *title, const char *prompt, int height, int width,
- int pause)
-{
- int i, x, y, key = 0;
- WINDOW *dialog;
-
- /* 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);
-
- print_title(dialog, title, width);
-
- wattrset(dialog, dialog_attr);
- print_autowrap(dialog, prompt, width - 2, 1, 2);
-
- if (pause) {
- 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);
-
- print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE);
-
- wrefresh(dialog);
- while (key != ESC && key != '\n' && key != ' ' &&
- key != 'O' && key != 'o' && key != 'X' && key != 'x')
- key = wgetch(dialog);
- } else {
- key = '\n';
- wrefresh(dialog);
- }
-
- delwin(dialog);
- return key == ESC ? -1 : 0;
-}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/textbox.c b/payloads/libpayload/util/kconfig/lxdialog/textbox.c
index 77848bb8e0..c704712d02 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/textbox.c
+++ b/payloads/libpayload/util/kconfig/lxdialog/textbox.c
@@ -25,56 +25,62 @@ static void back_lines(int n);
static void print_page(WINDOW * win, int height, int width);
static void print_line(WINDOW * win, int row, int width);
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.
*/
-int dialog_textbox(const char *title, const char *file, int height, int width)
+int dialog_textbox(const char *title, const char *tbuf,
+ 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 height, width, boxh, boxw;
int passed_end;
- char search_term[MAX_LEN + 1];
- WINDOW *dialog, *text;
-
- search_term[0] = '\0'; /* no search term entered yet */
+ WINDOW *dialog, *box;
- /* Open input file for reading */
- if ((fd = open(file, O_RDONLY)) == -1) {
- endwin();
- fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
- exit(-1);
- }
- /* Get file size. Actually, 'file_size' is the real file size - 1,
- since it's only the last byte offset from the beginning */
- if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
- endwin();
- fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
- exit(-1);
- }
- /* Restore file pointer to beginning of file after getting file size */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
- 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 */
+ 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 */
+
+do_resize:
+ getmaxyx(stdscr, height, width);
+ if (height < 8 || width < 8)
+ return -ERRDISPLAYTOOSMALL;
+ if (initial_height != 0)
+ height = initial_height;
+ else
+ if (height > 4)
+ height -= 4;
+ else
+ height = 0;
+ if (initial_width != 0)
+ width = initial_width;
+ else
+ if (width > 5)
+ width -= 5;
+ else
+ width = 0;
/* center dialog box on screen */
x = (COLS - width) / 2;
@@ -85,110 +91,65 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
dialog = newwin(height, width, y, x);
keypad(dialog, TRUE);
- /* Create window for text region, used for scrolling text */
- text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
- wattrset(text, dialog_attr);
- wbkgdset(text, dialog_attr & A_COLOR);
+ /* Create window for box region, used for scrolling text */
+ 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);
- keypad(text, TRUE);
+ keypad(box, TRUE);
/* register the new window, along with its borders */
- draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ draw_box(dialog, 0, 0, height, width,
+ dlg.dialog.atr, dlg.border.atr);
- wattrset(dialog, border_attr);
+ 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, dialog_attr);
- wbkgdset(dialog, dialog_attr & A_COLOR);
+ wattrset(dialog, dlg.dialog.atr);
+ wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+ print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
wnoutrefresh(dialog);
getyx(dialog, cur_y, cur_x); /* Save cursor position */
/* Print first page of text */
- attr_clear(text, height - 4, width - 2, dialog_attr);
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
+ attr_clear(box, boxh, boxw, dlg.dialog.atr);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
- while ((key != ESC) && (key != '\n')) {
+ while ((key != KEY_ESC) && (key != '\n')) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */
case 'e':
case 'X':
case 'x':
+ delwin(box);
delwin(dialog);
- free(buf);
- close(fd);
return 0;
case 'g': /* First page */
case KEY_HOME:
if (!begin_reached) {
begin_reached = 1;
- /* First 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 > 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);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
}
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);
+ /* point to last char in buf */
+ page = buf + strlen(buf);
+ back_lines(boxh);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case 'K': /* Previous line */
case 'k':
@@ -196,21 +157,23 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
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);
+ /* 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(box, TRUE);
+ wscrl(box, -1); /* Scroll box region down one line */
+ scrollok(box, FALSE);
page_length = 0;
passed_end = 0;
- for (i = 0; i < height - 4; i++) {
+ for (i = 0; i < boxh; i++) {
if (!i) {
/* print first line of page */
- print_line(text, 0, width - 2);
- wnoutrefresh(text);
+ print_line(box, 0, boxw);
+ wnoutrefresh(box);
} else
/* Called to update 'end_reached' and 'page' */
get_line();
@@ -220,7 +183,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
passed_end = 1;
}
- print_position(dialog, height, width);
+ print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
@@ -230,23 +193,21 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
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);
+ 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(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);
+ 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);
}
@@ -257,10 +218,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
break;
begin_reached = 0;
- print_page(text, height - 4, width - 2);
- print_position(dialog, height, width);
- wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
@@ -275,9 +234,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
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);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
case 'L': /* Scroll right */
case 'l':
@@ -287,131 +245,56 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
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);
+ refresh_text_box(dialog, box, boxh, boxw,
+ cur_y, cur_x);
break;
- case ESC:
+ 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;
}
}
-
+ delwin(box);
delwin(dialog);
- free(buf);
- close(fd);
- return -1; /* ESC pressed */
+ return key; /* 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'.
*/
static void back_lines(int n)
{
- int i, fpos;
+ int i;
begin_reached = 0;
- /* We have to distinguish between end_reached and !end_reached
- since at end of file, the line is not ended by a '\n'.
- The code inside 'if' basically does a '--page' to move one
- character backward so as to skip '\n' of the previous line */
- if (!end_reached) {
- /* Either beginning of buffer or beginning of file reached? */
- 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;
+ /* Go back 'n' lines */
+ for (i = 0; i < n; i++) {
+ if (*page == '\0') {
+ if (end_reached) {
+ end_reached = 0;
+ continue;
}
}
- if (*(--page) != '\n') { /* '--page' here */
- /* Something's wrong... */
- endwin();
- fprintf(stderr, "\nInternal error in back_lines().\n");
- exit(-1);
+ if (page == buf) {
+ begin_reached = 1;
+ return;
}
- }
- /* Go back 'n' lines */
- for (i = 0; i < n; i++)
+ page--;
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;
- }
+ begin_reached = 1;
+ return;
}
- } while (*(--page) != '\n');
- page++;
+ page--;
+ } while (*page != '\n');
+ page++;
+ }
}
/*
@@ -466,33 +349,14 @@ static void print_line(WINDOW * win, int row, int width)
*/
static char *get_line(void)
{
- int i = 0, fpos;
+ int i = 0;
static char line[MAX_LEN + 1];
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
- /* Either end of file or end of buffer reached */
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in "
- "get_line().\n");
- exit(-1);
- }
- if (fpos < file_size) { /* Not end of file yet */
- /* We've reached end of buffer, but not end of file yet,
- so read next part of file into buffer */
- if ((bytes_read =
- read(fd, buf, BUF_SIZE)) == -1) {
- 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;
+ if (!end_reached) {
+ end_reached = 1;
break;
}
} else if (i < MAX_LEN)
@@ -515,19 +379,13 @@ static char *get_line(void)
/*
* Print current position
*/
-static void print_position(WINDOW * win, int height, int width)
+static void print_position(WINDOW * win)
{
- int fpos, percent;
+ int percent;
- if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
- endwin();
- fprintf(stderr, "\nError moving file pointer in print_position().\n");
- exit(-1);
- }
- 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);
+ wattrset(win, dlg.position_indicator.atr);
+ wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
+ percent = (page - buf) * 100 / strlen(buf);
+ wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
wprintw(win, "(%3d%%)", percent);
}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/util.c b/payloads/libpayload/util/kconfig/lxdialog/util.c
index f82cebb9ff..86d95cca46 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/util.c
+++ b/payloads/libpayload/util/kconfig/lxdialog/util.c
@@ -21,85 +21,215 @@
#include "dialog.h"
-/* use colors by default? */
-bool use_colors = 1;
+struct dialog_info dlg;
-const char *backtitle = NULL;
+static void set_mono_theme(void)
+{
+ dlg.screen.atr = A_NORMAL;
+ dlg.shadow.atr = A_NORMAL;
+ dlg.dialog.atr = A_NORMAL;
+ dlg.title.atr = A_BOLD;
+ dlg.border.atr = A_NORMAL;
+ dlg.button_active.atr = A_REVERSE;
+ dlg.button_inactive.atr = A_DIM;
+ dlg.button_key_active.atr = A_REVERSE;
+ dlg.button_key_inactive.atr = A_BOLD;
+ dlg.button_label_active.atr = A_REVERSE;
+ dlg.button_label_inactive.atr = A_NORMAL;
+ dlg.inputbox.atr = A_NORMAL;
+ dlg.inputbox_border.atr = A_NORMAL;
+ dlg.searchbox.atr = A_NORMAL;
+ dlg.searchbox_title.atr = A_BOLD;
+ dlg.searchbox_border.atr = A_NORMAL;
+ dlg.position_indicator.atr = A_BOLD;
+ dlg.menubox.atr = A_NORMAL;
+ dlg.menubox_border.atr = A_NORMAL;
+ dlg.item.atr = A_NORMAL;
+ dlg.item_selected.atr = A_REVERSE;
+ dlg.tag.atr = A_BOLD;
+ dlg.tag_selected.atr = A_REVERSE;
+ dlg.tag_key.atr = A_BOLD;
+ dlg.tag_key_selected.atr = A_REVERSE;
+ dlg.check.atr = A_BOLD;
+ dlg.check_selected.atr = A_REVERSE;
+ dlg.uarrow.atr = A_BOLD;
+ dlg.darrow.atr = A_BOLD;
+}
+
+#define DLG_COLOR(dialog, f, b, h) \
+do { \
+ dlg.dialog.fg = (f); \
+ dlg.dialog.bg = (b); \
+ dlg.dialog.hl = (h); \
+} 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);
+
+}
/*
- * Attribute values, default is for mono display
+ * Select color theme
*/
-chtype attributes[] = {
- A_NORMAL, /* screen_attr */
- A_NORMAL, /* shadow_attr */
- A_NORMAL, /* dialog_attr */
- A_BOLD, /* title_attr */
- A_NORMAL, /* border_attr */
- A_REVERSE, /* button_active_attr */
- A_DIM, /* button_inactive_attr */
- A_REVERSE, /* button_key_active_attr */
- A_BOLD, /* button_key_inactive_attr */
- A_REVERSE, /* button_label_active_attr */
- A_NORMAL, /* button_label_inactive_attr */
- A_NORMAL, /* inputbox_attr */
- A_NORMAL, /* inputbox_border_attr */
- A_NORMAL, /* searchbox_attr */
- A_BOLD, /* searchbox_title_attr */
- A_NORMAL, /* searchbox_border_attr */
- A_BOLD, /* position_indicator_attr */
- A_NORMAL, /* menubox_attr */
- A_NORMAL, /* menubox_border_attr */
- A_NORMAL, /* item_attr */
- A_REVERSE, /* item_selected_attr */
- A_BOLD, /* tag_attr */
- A_REVERSE, /* tag_selected_attr */
- A_BOLD, /* tag_key_attr */
- A_REVERSE, /* tag_key_selected_attr */
- A_BOLD, /* check_attr */
- A_REVERSE, /* check_selected_attr */
- A_BOLD, /* uarrow_attr */
- A_BOLD /* darrow_attr */
-};
-
-#include "colors.h"
+static int set_theme(const char *theme)
+{
+ int use_color = 1;
+ if (!theme)
+ set_bluetitle_theme();
+ 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;
+}
+
+static void init_one_color(struct dialog_color *color)
+{
+ 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);
+}
+
+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);
+}
/*
- * Table of color values
+ * Setup for color display
*/
-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 */
+static void color_setup(const char *theme)
+{
+ int use_color;
+
+ use_color = set_theme(theme);
+ if (use_color && has_colors()) {
+ start_color();
+ init_dialog_colors();
+ } else
+ set_mono_theme();
+}
/*
* Set window to attribute 'attr'
@@ -119,13 +249,13 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr)
void dialog_clear(void)
{
- attr_clear(stdscr, LINES, COLS, screen_attr);
+ attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
/* Display background title if it exists ... - SLH */
- if (backtitle != NULL) {
+ if (dlg.backtitle != NULL) {
int i;
- wattrset(stdscr, screen_attr);
- mvwaddstr(stdscr, 0, 1, (char *)backtitle);
+ 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);
@@ -136,44 +266,41 @@ void dialog_clear(void)
/*
* Do some initialization for dialog
*/
-void init_dialog(void)
+int init_dialog(const char *backtitle)
{
+ int height, width;
+
initscr(); /* Init curses */
+ getmaxyx(stdscr, height, width);
+ if (height < 19 || width < 80) {
+ endwin();
+ return -ERRDISPLAYTOOSMALL;
+ }
+
+ dlg.backtitle = backtitle;
+ color_setup(getenv("MENUCONFIG_COLOR"));
+
keypad(stdscr, TRUE);
cbreak();
noecho();
-
- if (use_colors) /* Set up colors */
- color_setup();
-
dialog_clear();
+
+ return 0;
}
-/*
- * Setup for color display
- */
-void color_setup(void)
+void set_dialog_backtitle(const char *backtitle)
{
- int i;
-
- if (has_colors()) { /* Terminal supports color? */
- start_color();
-
- /* Initialize color pairs */
- for (i = 0; i < ATTRIBUTE_COUNT; i++)
- init_pair(i + 1, color_table[i][0], color_table[i][1]);
-
- /* Setup color attributes */
- for (i = 0; i < ATTRIBUTE_COUNT; i++)
- attributes[i] = C_ATTR(color_table[i][2], i + 1);
- }
+ dlg.backtitle = backtitle;
}
/*
* End using dialog functions.
*/
-void end_dialog(void)
+void end_dialog(int x, int y)
{
+ /* move cursor back to original position */
+ move(y, x);
+ refresh();
endwin();
}
@@ -184,7 +311,7 @@ void print_title(WINDOW *dialog, const char *title, int width)
{
if (title) {
int tlen = MIN(width - 2, strlen(title));
- wattrset(dialog, title_attr);
+ wattrset(dialog, dlg.title.atr);
mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
waddch(dialog, ' ');
@@ -224,7 +351,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
newl = 1;
word = tempstr;
while (word && *word) {
- sp = index(word, ' ');
+ sp = strchr(word, ' ');
if (sp)
*sp++ = 0;
@@ -236,7 +363,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
if (wlen > room ||
(newl && wlen < 4 && sp
&& wlen + 1 + strlen(sp) > room
- && (!(sp2 = index(sp, ' '))
+ && (!(sp2 = strchr(sp, ' '))
|| wlen + 1 + (sp2 - sp) > room))) {
cur_y++;
cur_x = x;
@@ -264,21 +391,23 @@ void print_button(WINDOW * win, const char *label, int y, int x, int selected)
int i, temp;
wmove(win, y, x);
- wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ wattrset(win, selected ? dlg.button_active.atr
+ : dlg.button_inactive.atr);
waddstr(win, "<");
temp = strspn(label, " ");
label += temp;
- wattrset(win, selected ? button_label_active_attr
- : button_label_inactive_attr);
+ wattrset(win, selected ? dlg.button_label_active.atr
+ : dlg.button_label_inactive.atr);
for (i = 0; i < temp; i++)
waddch(win, ' ');
- wattrset(win, selected ? button_key_active_attr
- : button_key_inactive_attr);
+ wattrset(win, selected ? dlg.button_key_active.atr
+ : dlg.button_key_inactive.atr);
waddch(win, label[0]);
- wattrset(win, selected ? button_label_active_attr
- : button_label_inactive_attr);
+ wattrset(win, selected ? dlg.button_label_active.atr
+ : dlg.button_label_inactive.atr);
waddstr(win, (char *)label + 1);
- wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ wattrset(win, selected ? dlg.button_active.atr
+ : dlg.button_inactive.atr);
waddstr(win, ">");
wmove(win, y, x + temp + 1);
}
@@ -326,7 +455,7 @@ void draw_shadow(WINDOW * win, int y, int x, int height, int width)
int i;
if (has_colors()) { /* Whether terminal supports color? */
- wattrset(win, shadow_attr);
+ wattrset(win, dlg.shadow.atr);
wmove(win, y + height, x + 2);
for (i = 0; i < width; i++)
waddch(win, winch(win) & A_CHARTEXT);
@@ -360,3 +489,167 @@ int first_alpha(const char *string, const char *exempt)
return 0;
}
+
+/*
+ * 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.
+ */
+int on_key_esc(WINDOW *win)
+{
+ int key;
+ int key2;
+ int key3;
+
+ nodelay(win, TRUE);
+ keypad(win, FALSE);
+ 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 -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);
+}
diff --git a/payloads/libpayload/util/kconfig/lxdialog/yesno.c b/payloads/libpayload/util/kconfig/lxdialog/yesno.c
index cb2568aae3..4e6e8090c2 100644
--- a/payloads/libpayload/util/kconfig/lxdialog/yesno.c
+++ b/payloads/libpayload/util/kconfig/lxdialog/yesno.c
@@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int x = width / 2 - 10;
int y = height - 2;
- print_button(dialog, " Yes ", y, x, selected == 0);
- print_button(dialog, " No ", y, x + 13, selected == 1);
+ print_button(dialog, gettext(" Yes "), y, x, selected == 0);
+ print_button(dialog, gettext(" No "), y, x + 13, selected == 1);
wmove(dialog, y, x + 1 + 13 * selected);
wrefresh(dialog);
@@ -44,6 +44,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
int i, x, y, key = 0, button = 0;
WINDOW *dialog;
+do_resize:
+ if (getmaxy(stdscr) < (height + 4))
+ return -ERRDISPLAYTOOSMALL;
+ if (getmaxx(stdscr) < (width + 4))
+ return -ERRDISPLAYTOOSMALL;
+
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
@@ -53,22 +59,23 @@ int dialog_yesno(const char *title, const char *prompt, int height, int 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);
+ 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, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
waddch(dialog, ACS_RTEE);
print_title(dialog, title, width);
- wattrset(dialog, dialog_attr);
+ wattrset(dialog, dlg.dialog.atr);
print_autowrap(dialog, prompt, width - 2, 1, 3);
print_buttons(dialog, height, width, 0);
- while (key != ESC) {
+ while (key != KEY_ESC) {
key = wgetch(dialog);
switch (key) {
case 'Y':
@@ -92,11 +99,16 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
case '\n':
delwin(dialog);
return button;
- case ESC:
+ case KEY_ESC:
+ key = on_key_esc(dialog);
break;
+ case KEY_RESIZE:
+ delwin(dialog);
+ on_key_resize();
+ goto do_resize;
}
}
delwin(dialog);
- return -1; /* ESC pressed */
+ return key; /* ESC pressed */
}
diff --git a/payloads/libpayload/util/kconfig/mconf.c b/payloads/libpayload/util/kconfig/mconf.c
index b39a964f9d..543a59a910 100644
--- a/payloads/libpayload/util/kconfig/mconf.c
+++ b/payloads/libpayload/util/kconfig/mconf.c
@@ -8,40 +8,41 @@
* i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
-#include <sys/ioctl.h>
-#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#include <termios.h>
#include <unistd.h>
#include <locale.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
+#include "lxdialog/dialog.h"
-static char menu_backtitle[128];
static const char mconf_readme[] = N_(
"Overview\n"
"--------\n"
"Some features may be built directly into libpayload.\n"
-"Some features may be completely removed altogether. \n"
-"There are also certain parameters which are not reallyn"
-"eatures, but must be entered in as decimal or hexadecimal\n"
-"numbers or possibly text.\n"
-"\n"
-"Menu items beginning with [*] or [ ] represent features\n"
-"configured to be built in or removed respectively.\n"
+"Some may be made into loadable runtime modules. Some features\n"
+"may be completely removed altogether. There are also certain\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 following braces represent features that\n"
+" [ ] can be built in or removed\n"
+" < > can be built in, modularized or removed\n"
+" { } can be built in or modularized (selected by other feature)\n"
+" - - are selected by other feature,\n"
+"while *, M or whitespace inside braces means to build in, build as\n"
+"a module or to exclude the feature respectively.\n"
"\n"
"To change any of these features, highlight it with the cursor\n"
-"keys and press <Y> to build it in or\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->Y).\n"
+"through the available options (ie. Y->N->M->Y).\n"
"\n"
"Some additional keyboard hints:\n"
"\n"
@@ -114,7 +115,7 @@ static const char mconf_readme[] = N_(
"-----------------------------\n"
"Menuconfig supports the use of alternate configuration files for\n"
"those who, for various reasons, find it necessary to switch\n"
-"between different libpayload 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"
@@ -147,7 +148,7 @@ static const char mconf_readme[] = N_(
"\n"
"Optional personality available\n"
"------------------------------\n"
-"If you prefer to have all of the libpayload 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"
@@ -158,7 +159,21 @@ static const char mconf_readme[] = N_(
"\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"
-"default mode.\n"),
+"default mode.\n"
+"\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. "
"<Enter> selects submenus --->. "
@@ -192,11 +207,11 @@ load_config_text[] = N_(
"last retrieved. Leave blank to abort."),
load_config_help[] = N_(
"\n"
- "For various reasons, one may wish to keep several different libpayload\n"
+ "For various reasons, one may wish to keep several different\n"
"configurations available on a single machine.\n"
"\n"
- "If you have saved a previous configuration in a file other than \n"
- "libpayload default, entering the name of the file here will allow you\n"
+ "If you have saved a previous configuration in a file other than the\n"
+ "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"
@@ -206,7 +221,7 @@ save_config_text[] = N_(
"as an alternate. Leave blank to abort."),
save_config_help[] = N_(
"\n"
- "For various reasons, one may wish to keep different libpayload\n"
+ "For various reasons, one may wish to keep different\n"
"configurations available on a single machine.\n"
"\n"
"Entering a file name here will allow you to later retrieve, modify\n"
@@ -255,16 +270,9 @@ search_help[] = N_(
" USB$ => find all CONFIG_ symbols ending with USB\n"
"\n");
-static char buf[4096], *bufptr = buf;
-static char input_buf[4096];
-static char filename[PATH_MAX+1] = ".config";
-static char *args[1024], **argptr = args;
static int indent;
-static struct termios ios_org;
-static int rows = 0, cols = 0;
static struct menu *current_menu;
static int child_count;
-static int do_resize;
static int single_menu_mode;
static void conf(struct menu *menu);
@@ -275,106 +283,17 @@ static void conf_save(void);
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_help(struct menu *menu);
-static void show_file(const char *filename, const char *title, int r, int c);
-
-static void cprint_init(void);
-static int cprint1(const char *fmt, ...);
-static void cprint_done(void);
-static int cprint(const char *fmt, ...);
-
-static void init_wsize(void)
-{
- struct winsize ws;
- char *env;
-
- if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
- rows = ws.ws_row;
- cols = ws.ws_col;
- }
-
- if (!rows) {
- env = getenv("LINES");
- if (env)
- rows = atoi(env);
- if (!rows)
- rows = 24;
- }
- if (!cols) {
- env = getenv("COLUMNS");
- if (env)
- cols = atoi(env);
- if (!cols)
- cols = 80;
- }
-
- if (rows < 19 || cols < 80) {
- fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
- fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
- exit(1);
- }
-
- rows -= 4;
- cols -= 5;
-}
-
-static void cprint_init(void)
-{
- bufptr = buf;
- argptr = args;
- memset(args, 0, sizeof(args));
- indent = 0;
- child_count = 0;
- cprint("./util/kconfig/lxdialog/lxdialog");
- cprint("--backtitle");
- cprint(menu_backtitle);
-}
-
-static int cprint1(const char *fmt, ...)
-{
- va_list ap;
- int res;
-
- if (!*argptr)
- *argptr = bufptr;
- va_start(ap, fmt);
- res = vsprintf(bufptr, fmt, ap);
- va_end(ap);
- bufptr += res;
-
- return res;
-}
-
-static void cprint_done(void)
-{
- *bufptr++ = 0;
- argptr++;
-}
-
-static int cprint(const char *fmt, ...)
-{
- va_list ap;
- int res;
-
- *argptr++ = bufptr;
- va_start(ap, fmt);
- res = vsprintf(bufptr, fmt, ap);
- va_end(ap);
- bufptr += res;
- *bufptr++ = 0;
-
- return res;
-}
static void get_prompt_str(struct gstr *r, struct property *prop)
{
int i, j;
struct menu *submenu[8], *menu;
- str_printf(r, "Prompt: %s\n", prop->text);
- str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
+ str_printf(r, _("Prompt: %s\n"), _(prop->text));
+ str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
prop->menu->lineno);
if (!expr_is_yes(prop->visible.expr)) {
- str_append(r, " Depends on: ");
+ str_append(r, _(" Depends on: "));
expr_gstr_print(prop->visible.expr, r);
str_append(r, "\n");
}
@@ -382,13 +301,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
submenu[i++] = menu;
if (i > 0) {
- str_printf(r, " Location:\n");
+ str_printf(r, _(" Location:\n"));
for (j = 4; --i >= 0; j += 2) {
menu = submenu[i];
- str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+ str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
if (menu->sym) {
str_printf(r, " (%s [=%s])", menu->sym->name ?
- menu->sym->name : "<choice>",
+ menu->sym->name : _("<choice>"),
sym_get_string_value(menu->sym));
}
str_append(r, "\n");
@@ -401,8 +320,9 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
bool hit;
struct property *prop;
- str_printf(r, "Symbol: %s [=%s]\n", sym->name,
- sym_get_string_value(sym));
+ if (sym && sym->name)
+ str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+ sym_get_string_value(sym));
for_all_prompts(sym, prop)
get_prompt_str(r, prop);
hit = false;
@@ -417,7 +337,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
if (hit)
str_append(r, "\n");
if (sym->rev_dep.expr) {
- str_append(r, " Selected by: ");
+ str_append(r, _(" Selected by: "));
expr_gstr_print(sym->rev_dep.expr, r);
str_append(r, "\n");
}
@@ -433,112 +353,45 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
get_symbol_str(&res, sym);
if (!i)
- str_append(&res, "No matches found.\n");
+ str_append(&res, _("No matches found.\n"));
return res;
}
-pid_t pid;
-
-static void winch_handler(int sig)
+static char filename[PATH_MAX+1];
+static void set_config_filename(const char *config_filename)
{
- if (!do_resize) {
- kill(pid, SIGINT);
- do_resize = 1;
- }
-}
-
-static int exec_conf(void)
-{
- int pipefd[2], stat, size;
- struct sigaction sa;
- sigset_t sset, osset;
-
- sigemptyset(&sset);
- sigaddset(&sset, SIGINT);
- sigprocmask(SIG_BLOCK, &sset, &osset);
-
- signal(SIGINT, SIG_DFL);
-
- sa.sa_handler = winch_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
- sigaction(SIGWINCH, &sa, NULL);
-
- *argptr++ = NULL;
-
- pipe(pipefd);
- pid = fork();
- if (pid == 0) {
- sigprocmask(SIG_SETMASK, &osset, NULL);
- dup2(pipefd[1], 2);
- close(pipefd[0]);
- close(pipefd[1]);
- execv(args[0], args);
- _exit(EXIT_FAILURE);
- }
-
- close(pipefd[1]);
- bufptr = input_buf;
- while (1) {
- size = input_buf + sizeof(input_buf) - bufptr;
- size = read(pipefd[0], bufptr, size);
- if (size <= 0) {
- if (size < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- perror("read");
- }
- break;
- }
- bufptr += size;
- }
- *bufptr++ = 0;
- close(pipefd[0]);
- waitpid(pid, &stat, 0);
-
- if (do_resize) {
- init_wsize();
- do_resize = 0;
- sigprocmask(SIG_SETMASK, &osset, NULL);
- return -1;
- }
- if (WIFSIGNALED(stat)) {
- printf("\finterrupted(%d)\n", WTERMSIG(stat));
- exit(1);
- }
-#if 0
- printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
- sleep(1);
-#endif
- sigpending(&sset);
- if (sigismember(&sset, SIGINT)) {
- printf("\finterrupted\n");
- exit(1);
- }
- sigprocmask(SIG_SETMASK, &osset, NULL);
+ static char menu_backtitle[PATH_MAX+128];
+ int size;
+ struct symbol *sym;
- return WEXITSTATUS(stat);
+ sym = sym_lookup("KERNELVERSION", 0);
+ sym_calc_value(sym);
+ size = snprintf(menu_backtitle, sizeof(menu_backtitle),
+ _("%s - libpayload v%s Configuration"),
+ config_filename, getenv("KERNELVERSION"));
+ if (size >= sizeof(menu_backtitle))
+ menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
+ set_dialog_backtitle(menu_backtitle);
+
+ size = snprintf(filename, sizeof(filename), "%s", config_filename);
+ if (size >= sizeof(filename))
+ filename[sizeof(filename)-1] = '\0';
}
+
static void search_conf(void)
{
struct symbol **sym_arr;
- int stat;
struct gstr res;
-
+ char *dialog_input;
+ int dres;
again:
- cprint_init();
- cprint("--title");
- cprint(_("Search Configuration Parameter"));
- cprint("--inputbox");
- cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
- cprint("10");
- cprint("75");
- cprint("");
- stat = exec_conf();
- if (stat < 0)
- goto again;
- switch (stat) {
+ dialog_clear();
+ dres = dialog_inputbox(_("Search Configuration Parameter"),
+ _("Enter CONFIG_ (sub)string to search for "
+ "(with or without \"CONFIG\")"),
+ 10, 75, "");
+ switch (dres) {
case 0:
break;
case 1:
@@ -548,7 +401,12 @@ again:
return;
}
- sym_arr = sym_re_search(input_buf);
+ /* strip CONFIG_ if necessary */
+ dialog_input = dialog_input_result;
+ if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
+ dialog_input += 7;
+
+ sym_arr = sym_re_search(dialog_input);
res = get_relations_str(sym_arr);
free(sym_arr);
show_textbox(_("Search Results"), str_get(&res), 0, 0);
@@ -575,24 +433,33 @@ static void build_conf(struct menu *menu)
switch (prop->type) {
case P_MENU:
child_count++;
- cprint("m%p", menu);
-
+ prompt = _(prompt);
if (single_menu_mode) {
- cprint1("%s%*c%s",
- menu->data ? "-->" : "++>",
- indent + 1, ' ', prompt);
+ item_make("%s%*c%s",
+ menu->data ? "-->" : "++>",
+ indent + 1, ' ', prompt);
} else
- cprint1(" %*c%s --->", indent + 1, ' ', prompt);
+ item_make(" %*c%s --->", indent + 1, ' ', prompt);
- cprint_done();
+ item_set_tag('m');
+ item_set_data(menu);
if (single_menu_mode && menu->data)
goto conf_childs;
return;
+ case P_COMMENT:
+ if (prompt) {
+ child_count++;
+ item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
+ item_set_tag(':');
+ item_set_data(menu);
+ }
+ break;
default:
if (prompt) {
child_count++;
- cprint(":%p", menu);
- cprint("---%*c%s", indent + 1, ' ', prompt);
+ item_make("---%*c%s", indent + 1, ' ', _(prompt));
+ item_set_tag(':');
+ item_set_data(menu);
}
}
} else
@@ -613,10 +480,9 @@ static void build_conf(struct menu *menu)
val = sym_get_tristate_value(sym);
if (sym_is_changable(sym)) {
- cprint("t%p", menu);
switch (type) {
case S_BOOLEAN:
- cprint1("[%c]", val == no ? ' ' : '*');
+ item_make("[%c]", val == no ? ' ' : '*');
break;
case S_TRISTATE:
switch (val) {
@@ -624,84 +490,90 @@ static void build_conf(struct menu *menu)
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
- cprint1("<%c>", ch);
+ item_make("<%c>", ch);
break;
}
+ item_set_tag('t');
+ item_set_data(menu);
} else {
- cprint("%c%p", def_menu ? 't' : ':', menu);
- cprint1(" ");
+ item_make(" ");
+ item_set_tag(def_menu ? 't' : ':');
+ item_set_data(menu);
}
- cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
if (val == yes) {
if (def_menu) {
- cprint1(" (%s)", menu_get_prompt(def_menu));
- cprint1(" --->");
- cprint_done();
+ item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
+ item_add_str(" --->");
if (def_menu->list) {
indent += 2;
build_conf(def_menu);
indent -= 2;
}
- } else
- cprint_done();
+ }
return;
}
- cprint_done();
} else {
if (menu == current_menu) {
- cprint(":%p", menu);
- cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+ item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
+ item_set_tag(':');
+ item_set_data(menu);
goto conf_childs;
}
child_count++;
val = sym_get_tristate_value(sym);
if (sym_is_choice_value(sym) && val == yes) {
- cprint(":%p", menu);
- cprint1(" ");
+ item_make(" ");
+ item_set_tag(':');
+ item_set_data(menu);
} else {
switch (type) {
case S_BOOLEAN:
- cprint("t%p", menu);
if (sym_is_changable(sym))
- cprint1("[%c]", val == no ? ' ' : '*');
+ item_make("[%c]", val == no ? ' ' : '*');
else
- cprint1("---");
+ item_make("-%c-", val == no ? ' ' : '*');
+ item_set_tag('t');
+ item_set_data(menu);
break;
case S_TRISTATE:
- cprint("t%p", menu);
switch (val) {
case yes: ch = '*'; break;
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
- if (sym_is_changable(sym))
- cprint1("<%c>", ch);
- else
- cprint1("---");
+ if (sym_is_changable(sym)) {
+ if (sym->rev_dep.tri == mod)
+ item_make("{%c}", ch);
+ else
+ item_make("<%c>", ch);
+ } else
+ item_make("-%c-", ch);
+ item_set_tag('t');
+ item_set_data(menu);
break;
default:
- cprint("s%p", menu);
- tmp = cprint1("(%s)", sym_get_string_value(sym));
+ tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
+ item_make("(%s)", sym_get_string_value(sym));
tmp = indent - tmp + 4;
if (tmp < 0)
tmp = 0;
- cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
- (sym_has_value(sym) || !sym_is_changable(sym)) ?
- "" : " (NEW)");
- cprint_done();
+ item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : _(" (NEW)"));
+ item_set_tag('s');
+ item_set_data(menu);
goto conf_childs;
}
}
- cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
- (sym_has_value(sym) || !sym_is_changable(sym)) ?
- "" : " (NEW)");
+ item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
+ (sym_has_value(sym) || !sym_is_changable(sym)) ?
+ "" : _(" (NEW)"));
if (menu->prompt->type == P_MENU) {
- cprint1(" --->");
- cprint_done();
+ item_add_str(" --->");
return;
}
- cprint_done();
}
conf_childs:
@@ -716,59 +588,45 @@ static void conf(struct menu *menu)
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
- char active_entry[40];
- int stat, type, i;
+ struct menu *active_menu = NULL;
+ int res;
+ int s_scroll = 0;
- unlink("lxdialog.scrltmp");
- active_entry[0] = 0;
while (1) {
- cprint_init();
- cprint("--title");
- cprint("%s", prompt ? prompt : _("Main Menu"));
- cprint("--menu");
- cprint(_(menu_instructions));
- cprint("%d", rows);
- cprint("%d", cols);
- cprint("%d", rows - 10);
- cprint("%s", active_entry);
+ item_reset();
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
if (menu == &rootmenu) {
- cprint(":");
- cprint("--- ");
- cprint("L");
- cprint(_(" Load an Alternate Configuration File"));
- cprint("S");
- cprint(_(" Save Configuration to an Alternate File"));
+ item_make("--- ");
+ item_set_tag(':');
+ item_make(_(" Load an Alternate Configuration File"));
+ item_set_tag('L');
+ item_make(_(" Save an Alternate Configuration File"));
+ item_set_tag('S');
}
- stat = exec_conf();
- if (stat < 0)
- continue;
-
- if (stat == 1 || stat == 255)
+ dialog_clear();
+ res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
+ _(menu_instructions),
+ active_menu, &s_scroll);
+ if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break;
-
- type = input_buf[0];
- if (!type)
+ if (!item_activate_selected())
+ continue;
+ if (!item_tag())
continue;
- for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
- ;
- if (i >= sizeof(active_entry))
- i = sizeof(active_entry) - 1;
- input_buf[i] = 0;
- strcpy(active_entry, input_buf);
-
- sym = NULL;
- submenu = NULL;
- if (sscanf(input_buf + 1, "%p", &submenu) == 1)
+ submenu = item_data();
+ active_menu = item_data();
+ if (submenu)
sym = submenu->sym;
+ else
+ sym = NULL;
- switch (stat) {
+ switch (res) {
case 0:
- switch (type) {
+ switch (item_tag()) {
case 'm':
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
@@ -796,10 +654,10 @@ static void conf(struct menu *menu)
if (sym)
show_help(submenu);
else
- show_helptext("README", _(mconf_readme));
+ show_helptext(_("README"), _(mconf_readme));
break;
case 3:
- if (type == 't') {
+ if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
@@ -807,17 +665,17 @@ static void conf(struct menu *menu)
}
break;
case 4:
- if (type == 't')
+ if (item_is_tag('t'))
sym_set_tristate_value(sym, no);
break;
case 5:
- if (type == 't')
+ if (item_is_tag('t'))
sym_set_tristate_value(sym, mod);
break;
case 6:
- if (type == 't')
+ if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
- else if (type == 'm')
+ else if (item_is_tag('m'))
conf(submenu);
break;
case 7:
@@ -829,13 +687,8 @@ static void conf(struct menu *menu)
static void show_textbox(const char *title, const char *text, int r, int c)
{
- int fd;
-
- fd = creat(".help.tmp", 0777);
- write(fd, text, strlen(text));
- close(fd);
- show_file(".help.tmp", title, r, c);
- unlink(".help.tmp");
+ dialog_clear();
+ dialog_textbox(title, text, r, c);
}
static void show_helptext(const char *title, const char *text)
@@ -848,83 +701,67 @@ static void show_help(struct menu *menu)
struct gstr help = str_new();
struct symbol *sym = menu->sym;
- if (sym->help)
+ if (menu_has_help(menu))
{
if (sym->name) {
str_printf(&help, "CONFIG_%s:\n\n", sym->name);
- str_append(&help, _(sym->help));
+ str_append(&help, _(menu_get_help(menu)));
str_append(&help, "\n");
}
} else {
str_append(&help, nohelp_text);
}
get_symbol_str(&help, sym);
- show_helptext(menu_get_prompt(menu), str_get(&help));
+ show_helptext(_(menu_get_prompt(menu)), str_get(&help));
str_free(&help);
}
-static void show_file(const char *filename, const char *title, int r, int c)
-{
- do {
- cprint_init();
- if (title) {
- cprint("--title");
- cprint("%s", title);
- }
- cprint("--textbox");
- cprint("%s", filename);
- cprint("%d", r ? r : rows);
- cprint("%d", c ? c : cols);
- } while (exec_conf() < 0);
-}
-
static void conf_choice(struct menu *menu)
{
- const char *prompt = menu_get_prompt(menu);
+ const char *prompt = _(menu_get_prompt(menu));
struct menu *child;
struct symbol *active;
- int stat;
active = sym_get_choice_value(menu->sym);
while (1) {
- cprint_init();
- cprint("--title");
- cprint("%s", prompt ? prompt : _("Main Menu"));
- cprint("--radiolist");
- cprint(_(radiolist_instructions));
- cprint("15");
- cprint("70");
- cprint("6");
+ int res;
+ int selected;
+ item_reset();
current_menu = menu;
for (child = menu->list; child; child = child->next) {
if (!menu_is_visible(child))
continue;
- cprint("%p", child);
- cprint("%s", menu_get_prompt(child));
+ item_make("%s", _(menu_get_prompt(child)));
+ item_set_data(child);
+ if (child->sym == active)
+ item_set_selected(1);
if (child->sym == sym_get_choice_value(menu->sym))
- cprint("ON");
- else if (child->sym == active)
- cprint("SELECTED");
- else
- cprint("OFF");
+ item_set_tag('X');
}
-
- stat = exec_conf();
- switch (stat) {
+ dialog_clear();
+ res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
+ _(radiolist_instructions),
+ 15, 70, 6);
+ selected = item_activate_selected();
+ switch (res) {
case 0:
- if (sscanf(input_buf, "%p", &child) != 1)
- break;
- sym_set_tristate_value(child->sym, yes);
+ if (selected) {
+ child = item_data();
+ sym_set_tristate_value(child->sym, yes);
+ }
return;
case 1:
- if (sscanf(input_buf, "%p", &child) == 1) {
+ if (selected) {
+ child = item_data();
show_help(child);
active = child->sym;
} else
show_help(menu);
break;
- case 255:
+ case KEY_ESC:
+ return;
+ case -ERRDISPLAYTOOSMALL:
return;
}
}
@@ -933,40 +770,38 @@ static void conf_choice(struct menu *menu)
static void conf_string(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
- int stat;
while (1) {
- cprint_init();
- cprint("--title");
- cprint("%s", prompt ? prompt : _("Main Menu"));
- cprint("--inputbox");
+ int res;
+ char *heading;
+
switch (sym_get_type(menu->sym)) {
case S_INT:
- cprint(_(inputbox_instructions_int));
+ heading = _(inputbox_instructions_int);
break;
case S_HEX:
- cprint(_(inputbox_instructions_hex));
+ heading = _(inputbox_instructions_hex);
break;
case S_STRING:
- cprint(_(inputbox_instructions_string));
+ heading = _(inputbox_instructions_string);
break;
default:
- /* panic? */;
+ heading = _("Internal mconf error!");
}
- cprint("10");
- cprint("75");
- cprint("%s", sym_get_string_value(menu->sym));
- stat = exec_conf();
- switch (stat) {
+ dialog_clear();
+ res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
+ heading, 10, 75,
+ sym_get_string_value(menu->sym));
+ switch (res) {
case 0:
- if (sym_set_string_value(menu->sym, input_buf))
+ if (sym_set_string_value(menu->sym, dialog_input_result))
return;
show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
break;
case 1:
show_help(menu);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -974,28 +809,27 @@ static void conf_string(struct menu *menu)
static void conf_load(void)
{
- int stat;
while (1) {
- cprint_init();
- cprint("--inputbox");
- cprint(load_config_text);
- cprint("11");
- cprint("55");
- cprint("%s", filename);
- stat = exec_conf();
- switch(stat) {
+ int res;
+ dialog_clear();
+ res = dialog_inputbox(NULL, load_config_text,
+ 11, 55, filename);
+ switch(res) {
case 0:
- if (!input_buf[0])
+ if (!dialog_input_result[0])
return;
- if (!conf_read(input_buf))
+ if (!conf_read(dialog_input_result)) {
+ set_config_filename(dialog_input_result);
+ sym_set_change_count(1);
return;
+ }
show_textbox(NULL, _("File does not exist!"), 5, 38);
break;
case 1:
show_helptext(_("Load Alternate Configuration"), load_config_help);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
@@ -1003,45 +837,35 @@ static void conf_load(void)
static void conf_save(void)
{
- int stat;
-
while (1) {
- cprint_init();
- cprint("--inputbox");
- cprint(save_config_text);
- cprint("11");
- cprint("55");
- cprint("%s", filename);
- stat = exec_conf();
- switch(stat) {
+ int res;
+ dialog_clear();
+ res = dialog_inputbox(NULL, save_config_text,
+ 11, 55, filename);
+ switch(res) {
case 0:
- if (!input_buf[0])
+ if (!dialog_input_result[0])
return;
- if (!conf_write(input_buf))
+ if (!conf_write(dialog_input_result)) {
+ set_config_filename(dialog_input_result);
return;
+ }
show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
break;
case 1:
show_helptext(_("Save Alternate Configuration"), save_config_help);
break;
- case 255:
+ case KEY_ESC:
return;
}
}
}
-static void conf_cleanup(void)
-{
- tcsetattr(1, TCSAFLUSH, &ios_org);
- unlink(".help.tmp");
- unlink("lxdialog.scrltmp");
-}
-
int main(int ac, char **av)
{
- struct symbol *sym;
+ int saved_x, saved_y;
char *mode;
- int stat;
+ int res;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1050,46 +874,56 @@ int main(int ac, char **av)
conf_parse(av[1]);
conf_read(NULL);
- sym = sym_lookup("KERNELVERSION", 0);
- sym_calc_value(sym);
- sprintf(menu_backtitle, _("libpayload %s Configuration"),
- sym_get_string_value(sym));
-
mode = getenv("MENUCONFIG_MODE");
if (mode) {
if (!strcasecmp(mode, "single_menu"))
single_menu_mode = 1;
}
- tcgetattr(1, &ios_org);
- atexit(conf_cleanup);
- init_wsize();
- conf(&rootmenu);
+ getyx(stdscr, saved_y, saved_x);
+ if (init_dialog(NULL)) {
+ fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
+ fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
+ return 1;
+ }
+ set_config_filename(conf_get_configname());
do {
- cprint_init();
- cprint("--yesno");
- cprint(_("Do you wish to save your new libpayload configuration?"));
- cprint("5");
- cprint("60");
- stat = exec_conf();
- } while (stat < 0);
-
- if (stat == 0) {
- if (conf_write(NULL)) {
+ conf(&rootmenu);
+ dialog_clear();
+ if (conf_get_changed())
+ res = dialog_yesno(NULL,
+ _("Do you wish to save your "
+ "new configuration?\n"
+ "<ESC><ESC> to continue."),
+ 6, 60);
+ else
+ res = -1;
+ } while (res == KEY_ESC);
+ end_dialog(saved_x, saved_y);
+
+ switch (res) {
+ case 0:
+ if (conf_write(filename)) {
fprintf(stderr, _("\n\n"
- "Error during writing of the libpayload configuration.\n"
- "Your libpayload configuration changes were NOT saved."
+ "Error during writing of the configuration.\n"
+ "Your configuration changes were NOT saved."
"\n\n"));
return 1;
}
+ if (conf_write_autoconf()) {
+ fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+ return 1;
+ }
+ case -1:
printf(_("\n\n"
"*** End of libpayload configuration.\n"
- "*** Execute 'make' to build libpayload or try 'make help'."
+ "*** Execute 'make' to build or try 'make help'."
"\n\n"));
- } else {
+ break;
+ default:
fprintf(stderr, _("\n\n"
- "Your libpayload configuration changes were NOT saved."
+ "Your configuration changes were NOT saved."
"\n\n"));
}
diff --git a/payloads/libpayload/util/kconfig/menu.c b/payloads/libpayload/util/kconfig/menu.c
index 0fce20cb7f..606ceb9e74 100644
--- a/payloads/libpayload/util/kconfig/menu.c
+++ b/payloads/libpayload/util/kconfig/menu.c
@@ -15,7 +15,7 @@ static struct menu **last_entry_ptr;
struct file *file_list;
struct file *current_file;
-static void menu_warn(struct menu *menu, const char *fmt, ...)
+void menu_warn(struct menu *menu, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -114,7 +114,7 @@ void menu_set_type(int type)
sym->type = type;
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_type_name(sym->type), sym_type_name(type));
}
@@ -124,15 +124,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
struct property *prop = prop_alloc(type, current_entry->sym);
prop->menu = current_entry;
- prop->text = prompt;
prop->expr = expr;
prop->visible.expr = menu_check_dep(dep);
if (prompt) {
+ if (isspace(*prompt)) {
+ prop_warn(prop, "leading whitespace ignored");
+ while (isspace(*prompt))
+ prompt++;
+ }
if (current_entry->prompt)
- menu_warn(current_entry, "prompt redefined\n");
+ prop_warn(prop, "prompt redefined");
current_entry->prompt = prop;
}
+ prop->text = prompt;
return prop;
}
@@ -152,6 +157,27 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *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;
+ case T_OPT_ENV:
+ prop_add_env(arg);
+ break;
+ }
+}
+
static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
{
return sym2->type == S_INT || sym2->type == S_HEX ||
@@ -177,12 +203,9 @@ void sym_check_prop(struct symbol *sym)
prop_warn(prop,
"config symbol '%s' uses select, but is "
"not boolean or tristate", sym->name);
- else if (sym2->type == S_UNKNOWN)
- prop_warn(prop,
- "'select' used by config symbol '%s' "
- "refer to undefined symbol '%s'",
- sym->name, sym2->name);
- else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
+ else if (sym2->type != S_UNKNOWN &&
+ sym2->type != S_BOOLEAN &&
+ sym2->type != S_TRISTATE)
prop_warn(prop,
"'%s' has wrong type. 'select' only "
"accept arguments of boolean and "
@@ -216,9 +239,11 @@ void menu_finalize(struct menu *parent)
for (menu = parent->list; menu; menu = menu->next) {
if (menu->sym) {
current_entry = parent;
- menu_set_type(menu->sym->type);
+ if (sym->type == S_UNKNOWN)
+ menu_set_type(menu->sym->type);
current_entry = menu;
- menu_set_type(sym->type);
+ if (menu->sym->type == S_UNKNOWN)
+ menu_set_type(sym->type);
break;
}
}
@@ -303,12 +328,42 @@ void menu_finalize(struct menu *parent)
"values not supported");
}
current_entry = menu;
- menu_set_type(sym->type);
+ if (menu->sym->type == S_UNKNOWN)
+ menu_set_type(sym->type);
+ /* Non-tristate choice values of tristate choices must
+ * depend on the choice being set to Y. The choice
+ * values' dependencies were propagated to their
+ * properties above, so the change here must be re-
+ * propagated. */
+ if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
+ basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
+ basedep = expr_alloc_and(basedep, menu->dep);
+ basedep = expr_eliminate_dups(basedep);
+ menu->dep = basedep;
+ for (prop = menu->sym->prop; prop; prop = prop->next) {
+ if (prop->menu != menu)
+ continue;
+ dep = expr_alloc_and(expr_copy(basedep),
+ prop->visible.expr);
+ dep = expr_eliminate_dups(dep);
+ dep = expr_trans_bool(dep);
+ prop->visible.expr = dep;
+ if (prop->type == P_SELECT) {
+ struct symbol *es = prop_get_symbol(prop);
+ dep2 = expr_alloc_symbol(menu->sym);
+ dep = expr_alloc_and(dep2,
+ expr_copy(dep));
+ dep = expr_alloc_or(es->rev_dep.expr, dep);
+ dep = expr_eliminate_dups(dep);
+ es->rev_dep.expr = dep;
+ }
+ }
+ }
menu_add_symbol(P_CHOICE, sym, NULL);
prop = sym_get_choice_prop(sym);
for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
;
- *ep = expr_alloc_one(E_CHOICE, NULL);
+ *ep = expr_alloc_one(E_LIST, NULL);
(*ep)->right.sym = menu->sym;
}
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
@@ -325,11 +380,10 @@ void menu_finalize(struct menu *parent)
if (sym && !(sym->flags & SYMBOL_WARNED)) {
if (sym->type == S_UNKNOWN)
- menu_warn(parent, "config symbol defined "
- "without type\n");
+ menu_warn(parent, "config symbol defined without type");
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 */
sym_check_prop(sym);
@@ -372,9 +426,9 @@ bool menu_is_visible(struct menu *menu)
const char *menu_get_prompt(struct menu *menu)
{
if (menu->prompt)
- return _(menu->prompt->text);
+ return menu->prompt->text;
else if (menu->sym)
- return _(menu->sym->name);
+ return menu->sym->name;
return NULL;
}
@@ -395,3 +449,15 @@ struct menu *menu_get_parent_menu(struct menu *menu)
return menu;
}
+bool menu_has_help(struct menu *menu)
+{
+ return menu->help != NULL;
+}
+
+const char *menu_get_help(struct menu *menu)
+{
+ if (menu->help)
+ return menu->help;
+ else
+ return "";
+}
diff --git a/payloads/libpayload/util/kconfig/qconf.cc b/payloads/libpayload/util/kconfig/qconf.cc
new file mode 100644
index 0000000000..c3003602d2
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/qconf.cc
@@ -0,0 +1,1764 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qtoolbar.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <qsplitter.h>
+#include <qlistview.h>
+#include <qtextbrowser.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qmenubar.h>
+#include <qmessagebox.h>
+#include <qaction.h>
+#include <qheader.h>
+#include <qfiledialog.h>
+#include <qdragobject.h>
+#include <qregexp.h>
+
+#include <stdlib.h>
+
+#include "lkc.h"
+#include "qconf.h"
+
+#include "qconf.moc"
+#include "images.c"
+
+#ifdef _
+# undef _
+# define _ qgettext
+#endif
+
+static QApplication *configApp;
+static ConfigSettings *configSettings;
+
+QAction *ConfigMainWindow::saveAction;
+
+static inline QString qgettext(const char* str)
+{
+ return QString::fromLocal8Bit(gettext(str));
+}
+
+static inline QString qgettext(const QString& str)
+{
+ return QString::fromLocal8Bit(gettext(str.latin1()));
+}
+
+/**
+ * Reads a list of integer values from the application settings.
+ */
+QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
+{
+ QValueList<int> result;
+ QStringList entryList = readListEntry(key, ok);
+ if (ok) {
+ QStringList::Iterator it;
+ for (it = entryList.begin(); it != entryList.end(); ++it)
+ result.push_back((*it).toInt());
+ }
+
+ return result;
+}
+
+/**
+ * Writes a list of integer values to the application settings.
+ */
+bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
+{
+ QStringList stringList;
+ QValueList<int>::ConstIterator it;
+
+ for (it = value.begin(); it != value.end(); ++it)
+ stringList.push_back(QString::number(*it));
+ return writeEntry(key, stringList);
+}
+
+
+#if QT_VERSION >= 300
+/*
+ * set the new data
+ * TODO check the value
+ */
+void ConfigItem::okRename(int col)
+{
+ Parent::okRename(col);
+ sym_set_string_value(menu->sym, text(dataColIdx).latin1());
+ listView()->updateList(this);
+}
+#endif
+
+/*
+ * update the displayed of a menu entry
+ */
+void ConfigItem::updateMenu(void)
+{
+ ConfigList* list;
+ struct symbol* sym;
+ struct property *prop;
+ QString prompt;
+ int type;
+ tristate expr;
+
+ list = listView();
+ if (goParent) {
+ setPixmap(promptColIdx, list->menuBackPix);
+ prompt = "..";
+ goto set_prompt;
+ }
+
+ sym = menu->sym;
+ prop = menu->prompt;
+ prompt = _(menu_get_prompt(menu));
+
+ if (prop) switch (prop->type) {
+ case P_MENU:
+ if (list->mode == singleMode || list->mode == symbolMode) {
+ /* a menuconfig entry is displayed differently
+ * depending whether it's at the view root or a child.
+ */
+ if (sym && list->rootEntry == menu)
+ break;
+ setPixmap(promptColIdx, list->menuPix);
+ } else {
+ if (sym)
+ break;
+ setPixmap(promptColIdx, 0);
+ }
+ goto set_prompt;
+ case P_COMMENT:
+ setPixmap(promptColIdx, 0);
+ goto set_prompt;
+ default:
+ ;
+ }
+ if (!sym)
+ goto set_prompt;
+
+ setText(nameColIdx, QString::fromLocal8Bit(sym->name));
+
+ type = sym_get_type(sym);
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ char ch;
+
+ if (!sym_is_changable(sym) && !list->showAll) {
+ setPixmap(promptColIdx, 0);
+ setText(noColIdx, QString::null);
+ setText(modColIdx, QString::null);
+ setText(yesColIdx, QString::null);
+ break;
+ }
+ expr = sym_get_tristate_value(sym);
+ switch (expr) {
+ case yes:
+ if (sym_is_choice_value(sym) && type == S_BOOLEAN)
+ setPixmap(promptColIdx, list->choiceYesPix);
+ else
+ setPixmap(promptColIdx, list->symbolYesPix);
+ setText(yesColIdx, "Y");
+ ch = 'Y';
+ break;
+ case mod:
+ setPixmap(promptColIdx, list->symbolModPix);
+ setText(modColIdx, "M");
+ ch = 'M';
+ break;
+ default:
+ if (sym_is_choice_value(sym) && type == S_BOOLEAN)
+ setPixmap(promptColIdx, list->choiceNoPix);
+ else
+ setPixmap(promptColIdx, list->symbolNoPix);
+ setText(noColIdx, "N");
+ ch = 'N';
+ break;
+ }
+ if (expr != no)
+ setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
+ if (expr != mod)
+ setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
+ if (expr != yes)
+ setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
+
+ setText(dataColIdx, QChar(ch));
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+ const char* data;
+
+ data = sym_get_string_value(sym);
+
+#if QT_VERSION >= 300
+ int i = list->mapIdx(dataColIdx);
+ if (i >= 0)
+ setRenameEnabled(i, TRUE);
+#endif
+ setText(dataColIdx, data);
+ if (type == S_STRING)
+ prompt = QString("%1: %2").arg(prompt).arg(data);
+ else
+ prompt = QString("(%2) %1").arg(prompt).arg(data);
+ break;
+ }
+ if (!sym_has_value(sym) && visible)
+ prompt += _(" (NEW)");
+set_prompt:
+ setText(promptColIdx, prompt);
+}
+
+void ConfigItem::testUpdateMenu(bool v)
+{
+ ConfigItem* i;
+
+ visible = v;
+ if (!menu)
+ return;
+
+ sym_calc_value(menu->sym);
+ if (menu->flags & MENU_CHANGED) {
+ /* the menu entry changed, so update all list items */
+ menu->flags &= ~MENU_CHANGED;
+ for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
+ i->updateMenu();
+ } else if (listView()->updateAll)
+ updateMenu();
+}
+
+void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
+{
+ ConfigList* list = listView();
+
+ if (visible) {
+ if (isSelected() && !list->hasFocus() && list->mode == menuMode)
+ Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
+ else
+ Parent::paintCell(p, cg, column, width, align);
+ } else
+ Parent::paintCell(p, list->disabledColorGroup, column, width, align);
+}
+
+/*
+ * construct a menu entry
+ */
+void ConfigItem::init(void)
+{
+ if (menu) {
+ ConfigList* list = listView();
+ nextItem = (ConfigItem*)menu->data;
+ menu->data = this;
+
+ if (list->mode != fullMode)
+ setOpen(TRUE);
+ sym_calc_value(menu->sym);
+ }
+ updateMenu();
+}
+
+/*
+ * destruct a menu entry
+ */
+ConfigItem::~ConfigItem(void)
+{
+ if (menu) {
+ ConfigItem** ip = (ConfigItem**)&menu->data;
+ for (; *ip; ip = &(*ip)->nextItem) {
+ if (*ip == this) {
+ *ip = nextItem;
+ break;
+ }
+ }
+ }
+}
+
+ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
+ : Parent(parent)
+{
+ connect(this, SIGNAL(lostFocus()), SLOT(hide()));
+}
+
+void ConfigLineEdit::show(ConfigItem* i)
+{
+ item = i;
+ if (sym_get_string_value(item->menu->sym))
+ setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
+ else
+ setText(QString::null);
+ Parent::show();
+ setFocus();
+}
+
+void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
+{
+ switch (e->key()) {
+ case Key_Escape:
+ break;
+ case Key_Return:
+ case Key_Enter:
+ sym_set_string_value(item->menu->sym, text().latin1());
+ parent()->updateList(item);
+ break;
+ default:
+ Parent::keyPressEvent(e);
+ return;
+ }
+ e->accept();
+ parent()->list->setFocus();
+ hide();
+}
+
+ConfigList::ConfigList(ConfigView* p, const char *name)
+ : Parent(p, name),
+ updateAll(false),
+ symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
+ choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
+ menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
+ showAll(false), showName(false), showRange(false), showData(false),
+ rootEntry(0), headerPopup(0)
+{
+ int i;
+
+ setSorting(-1);
+ setRootIsDecorated(TRUE);
+ disabledColorGroup = palette().active();
+ disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
+ inactivedColorGroup = palette().active();
+ inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
+
+ connect(this, SIGNAL(selectionChanged(void)),
+ SLOT(updateSelection(void)));
+
+ if (name) {
+ configSettings->beginGroup(name);
+ showAll = configSettings->readBoolEntry("/showAll", false);
+ showName = configSettings->readBoolEntry("/showName", false);
+ showRange = configSettings->readBoolEntry("/showRange", false);
+ showData = configSettings->readBoolEntry("/showData", false);
+ configSettings->endGroup();
+ connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
+ }
+
+ for (i = 0; i < colNr; i++)
+ colMap[i] = colRevMap[i] = -1;
+ addColumn(promptColIdx, _("Option"));
+
+ reinit();
+}
+
+void ConfigList::reinit(void)
+{
+ removeColumn(dataColIdx);
+ removeColumn(yesColIdx);
+ removeColumn(modColIdx);
+ removeColumn(noColIdx);
+ removeColumn(nameColIdx);
+
+ if (showName)
+ addColumn(nameColIdx, _("Name"));
+ if (showRange) {
+ addColumn(noColIdx, "N");
+ addColumn(modColIdx, "M");
+ addColumn(yesColIdx, "Y");
+ }
+ if (showData)
+ addColumn(dataColIdx, _("Value"));
+
+ updateListAll();
+}
+
+void ConfigList::saveSettings(void)
+{
+ if (name()) {
+ configSettings->beginGroup(name());
+ configSettings->writeEntry("/showName", showName);
+ configSettings->writeEntry("/showRange", showRange);
+ configSettings->writeEntry("/showData", showData);
+ configSettings->writeEntry("/showAll", showAll);
+ configSettings->endGroup();
+ }
+}
+
+ConfigItem* ConfigList::findConfigItem(struct menu *menu)
+{
+ ConfigItem* item = (ConfigItem*)menu->data;
+
+ for (; item; item = item->nextItem) {
+ if (this == item->listView())
+ break;
+ }
+
+ return item;
+}
+
+void ConfigList::updateSelection(void)
+{
+ struct menu *menu;
+ enum prop_type type;
+
+ ConfigItem* item = (ConfigItem*)selectedItem();
+ if (!item)
+ return;
+
+ menu = item->menu;
+ emit menuChanged(menu);
+ if (!menu)
+ return;
+ type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (mode == menuMode && type == P_MENU)
+ emit menuSelected(menu);
+}
+
+void ConfigList::updateList(ConfigItem* item)
+{
+ ConfigItem* last = 0;
+
+ if (!rootEntry) {
+ if (mode != listMode)
+ goto update;
+ QListViewItemIterator it(this);
+ ConfigItem* item;
+
+ for (; it.current(); ++it) {
+ item = (ConfigItem*)it.current();
+ if (!item->menu)
+ continue;
+ item->testUpdateMenu(menu_is_visible(item->menu));
+ }
+ return;
+ }
+
+ if (rootEntry != &rootmenu && (mode == singleMode ||
+ (mode == symbolMode && rootEntry->parent != &rootmenu))) {
+ item = firstChild();
+ if (!item)
+ item = new ConfigItem(this, 0, true);
+ last = item;
+ }
+ if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
+ rootEntry->sym && rootEntry->prompt) {
+ item = last ? last->nextSibling() : firstChild();
+ if (!item)
+ item = new ConfigItem(this, last, rootEntry, true);
+ else
+ item->testUpdateMenu(true);
+
+ updateMenuList(item, rootEntry);
+ triggerUpdate();
+ return;
+ }
+update:
+ updateMenuList(this, rootEntry);
+ triggerUpdate();
+}
+
+void ConfigList::setValue(ConfigItem* item, tristate val)
+{
+ struct symbol* sym;
+ int type;
+ tristate oldval;
+
+ sym = item->menu ? item->menu->sym : 0;
+ if (!sym)
+ return;
+
+ type = sym_get_type(sym);
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ oldval = sym_get_tristate_value(sym);
+
+ if (!sym_set_tristate_value(sym, val))
+ return;
+ if (oldval == no && item->menu->list)
+ item->setOpen(TRUE);
+ parent()->updateList(item);
+ break;
+ }
+}
+
+void ConfigList::changeValue(ConfigItem* item)
+{
+ struct symbol* sym;
+ struct menu* menu;
+ int type, oldexpr, newexpr;
+
+ menu = item->menu;
+ if (!menu)
+ return;
+ sym = menu->sym;
+ if (!sym) {
+ if (item->menu->list)
+ item->setOpen(!item->isOpen());
+ return;
+ }
+
+ type = sym_get_type(sym);
+ switch (type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ oldexpr = sym_get_tristate_value(sym);
+ newexpr = sym_toggle_tristate_value(sym);
+ if (item->menu->list) {
+ if (oldexpr == newexpr)
+ item->setOpen(!item->isOpen());
+ else if (oldexpr == no)
+ item->setOpen(TRUE);
+ }
+ if (oldexpr != newexpr)
+ parent()->updateList(item);
+ break;
+ case S_INT:
+ case S_HEX:
+ case S_STRING:
+#if QT_VERSION >= 300
+ if (colMap[dataColIdx] >= 0)
+ item->startRename(colMap[dataColIdx]);
+ else
+#endif
+ parent()->lineEdit->show(item);
+ break;
+ }
+}
+
+void ConfigList::setRootMenu(struct menu *menu)
+{
+ enum prop_type type;
+
+ if (rootEntry == menu)
+ return;
+ type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (type != P_MENU)
+ return;
+ updateMenuList(this, 0);
+ rootEntry = menu;
+ updateListAll();
+ setSelected(currentItem(), hasFocus());
+ ensureItemVisible(currentItem());
+}
+
+void ConfigList::setParentMenu(void)
+{
+ ConfigItem* item;
+ struct menu *oldroot;
+
+ oldroot = rootEntry;
+ if (rootEntry == &rootmenu)
+ return;
+ setRootMenu(menu_get_parent_menu(rootEntry->parent));
+
+ QListViewItemIterator it(this);
+ for (; (item = (ConfigItem*)it.current()); it++) {
+ if (item->menu == oldroot) {
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ break;
+ }
+ }
+}
+
+/*
+ * update all the children of a menu entry
+ * removes/adds the entries from the parent widget as necessary
+ *
+ * parent: either the menu list widget or a menu entry widget
+ * menu: entry to be updated
+ */
+template <class P>
+void ConfigList::updateMenuList(P* parent, struct menu* menu)
+{
+ struct menu* child;
+ ConfigItem* item;
+ ConfigItem* last;
+ bool visible;
+ enum prop_type type;
+
+ if (!menu) {
+ while ((item = parent->firstChild()))
+ delete item;
+ return;
+ }
+
+ last = parent->firstChild();
+ if (last && !last->goParent)
+ last = 0;
+ for (child = menu->list; child; child = child->next) {
+ item = last ? last->nextSibling() : parent->firstChild();
+ type = child->prompt ? child->prompt->type : P_UNKNOWN;
+
+ switch (mode) {
+ case menuMode:
+ if (!(child->flags & MENU_ROOT))
+ goto hide;
+ break;
+ case symbolMode:
+ if (child->flags & MENU_ROOT)
+ goto hide;
+ break;
+ default:
+ break;
+ }
+
+ visible = menu_is_visible(child);
+ if (showAll || visible) {
+ if (!child->sym && !child->list && !child->prompt)
+ continue;
+ if (!item || item->menu != child)
+ item = new ConfigItem(parent, last, child, visible);
+ else
+ item->testUpdateMenu(visible);
+
+ if (mode == fullMode || mode == menuMode || type != P_MENU)
+ updateMenuList(item, child);
+ else
+ updateMenuList(item, 0);
+ last = item;
+ continue;
+ }
+ hide:
+ if (item && item->menu == child) {
+ last = parent->firstChild();
+ if (last == item)
+ last = 0;
+ else while (last->nextSibling() != item)
+ last = last->nextSibling();
+ delete item;
+ }
+ }
+}
+
+void ConfigList::keyPressEvent(QKeyEvent* ev)
+{
+ QListViewItem* i = currentItem();
+ ConfigItem* item;
+ struct menu *menu;
+ enum prop_type type;
+
+ if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
+ emit parentSelected();
+ ev->accept();
+ return;
+ }
+
+ if (!i) {
+ Parent::keyPressEvent(ev);
+ return;
+ }
+ item = (ConfigItem*)i;
+
+ switch (ev->key()) {
+ case Key_Return:
+ case Key_Enter:
+ if (item->goParent) {
+ emit parentSelected();
+ break;
+ }
+ menu = item->menu;
+ if (!menu)
+ break;
+ type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (type == P_MENU && rootEntry != menu &&
+ mode != fullMode && mode != menuMode) {
+ emit menuSelected(menu);
+ break;
+ }
+ case Key_Space:
+ changeValue(item);
+ break;
+ case Key_N:
+ setValue(item, no);
+ break;
+ case Key_M:
+ setValue(item, mod);
+ break;
+ case Key_Y:
+ setValue(item, yes);
+ break;
+ default:
+ Parent::keyPressEvent(ev);
+ return;
+ }
+ ev->accept();
+}
+
+void ConfigList::contentsMousePressEvent(QMouseEvent* e)
+{
+ //QPoint p(contentsToViewport(e->pos()));
+ //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMousePressEvent(e);
+}
+
+void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
+{
+ QPoint p(contentsToViewport(e->pos()));
+ ConfigItem* item = (ConfigItem*)itemAt(p);
+ struct menu *menu;
+ enum prop_type ptype;
+ const QPixmap* pm;
+ int idx, x;
+
+ if (!item)
+ goto skip;
+
+ menu = item->menu;
+ x = header()->offset() + p.x();
+ idx = colRevMap[header()->sectionAt(x)];
+ switch (idx) {
+ case promptColIdx:
+ pm = item->pixmap(promptColIdx);
+ if (pm) {
+ int off = header()->sectionPos(0) + itemMargin() +
+ treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
+ if (x >= off && x < off + pm->width()) {
+ if (item->goParent) {
+ emit parentSelected();
+ break;
+ } else if (!menu)
+ break;
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (ptype == P_MENU && rootEntry != menu &&
+ mode != fullMode && mode != menuMode)
+ emit menuSelected(menu);
+ else
+ changeValue(item);
+ }
+ }
+ break;
+ case noColIdx:
+ setValue(item, no);
+ break;
+ case modColIdx:
+ setValue(item, mod);
+ break;
+ case yesColIdx:
+ setValue(item, yes);
+ break;
+ case dataColIdx:
+ changeValue(item);
+ break;
+ }
+
+skip:
+ //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMouseReleaseEvent(e);
+}
+
+void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ //QPoint p(contentsToViewport(e->pos()));
+ //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMouseMoveEvent(e);
+}
+
+void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
+{
+ QPoint p(contentsToViewport(e->pos()));
+ ConfigItem* item = (ConfigItem*)itemAt(p);
+ struct menu *menu;
+ enum prop_type ptype;
+
+ if (!item)
+ goto skip;
+ if (item->goParent) {
+ emit parentSelected();
+ goto skip;
+ }
+ menu = item->menu;
+ if (!menu)
+ goto skip;
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
+ if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
+ emit menuSelected(menu);
+ else if (menu->sym)
+ changeValue(item);
+
+skip:
+ //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
+ Parent::contentsMouseDoubleClickEvent(e);
+}
+
+void ConfigList::focusInEvent(QFocusEvent *e)
+{
+ struct menu *menu = NULL;
+
+ Parent::focusInEvent(e);
+
+ ConfigItem* item = (ConfigItem *)currentItem();
+ if (item) {
+ setSelected(item, TRUE);
+ menu = item->menu;
+ }
+ emit gotFocus(menu);
+}
+
+void ConfigList::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (e->y() <= header()->geometry().bottom()) {
+ if (!headerPopup) {
+ QAction *action;
+
+ headerPopup = new QPopupMenu(this);
+ action = new QAction(NULL, _("Show Name"), 0, this);
+ action->setToggleAction(TRUE);
+ connect(action, SIGNAL(toggled(bool)),
+ parent(), SLOT(setShowName(bool)));
+ connect(parent(), SIGNAL(showNameChanged(bool)),
+ action, SLOT(setOn(bool)));
+ action->setOn(showName);
+ action->addTo(headerPopup);
+ action = new QAction(NULL, _("Show Range"), 0, this);
+ action->setToggleAction(TRUE);
+ connect(action, SIGNAL(toggled(bool)),
+ parent(), SLOT(setShowRange(bool)));
+ connect(parent(), SIGNAL(showRangeChanged(bool)),
+ action, SLOT(setOn(bool)));
+ action->setOn(showRange);
+ action->addTo(headerPopup);
+ action = new QAction(NULL, _("Show Data"), 0, this);
+ action->setToggleAction(TRUE);
+ connect(action, SIGNAL(toggled(bool)),
+ parent(), SLOT(setShowData(bool)));
+ connect(parent(), SIGNAL(showDataChanged(bool)),
+ action, SLOT(setOn(bool)));
+ action->setOn(showData);
+ action->addTo(headerPopup);
+ }
+ headerPopup->exec(e->globalPos());
+ e->accept();
+ } else
+ e->ignore();
+}
+
+ConfigView* ConfigView::viewList;
+
+ConfigView::ConfigView(QWidget* parent, const char *name)
+ : Parent(parent, name)
+{
+ list = new ConfigList(this, name);
+ lineEdit = new ConfigLineEdit(this);
+ lineEdit->hide();
+
+ this->nextView = viewList;
+ viewList = this;
+}
+
+ConfigView::~ConfigView(void)
+{
+ ConfigView** vp;
+
+ for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
+ if (*vp == this) {
+ *vp = nextView;
+ break;
+ }
+ }
+}
+
+void ConfigView::setShowAll(bool b)
+{
+ if (list->showAll != b) {
+ list->showAll = b;
+ list->updateListAll();
+ emit showAllChanged(b);
+ }
+}
+
+void ConfigView::setShowName(bool b)
+{
+ if (list->showName != b) {
+ list->showName = b;
+ list->reinit();
+ emit showNameChanged(b);
+ }
+}
+
+void ConfigView::setShowRange(bool b)
+{
+ if (list->showRange != b) {
+ list->showRange = b;
+ list->reinit();
+ emit showRangeChanged(b);
+ }
+}
+
+void ConfigView::setShowData(bool b)
+{
+ if (list->showData != b) {
+ list->showData = b;
+ list->reinit();
+ emit showDataChanged(b);
+ }
+}
+
+void ConfigList::setAllOpen(bool open)
+{
+ QListViewItemIterator it(this);
+
+ for (; it.current(); it++)
+ it.current()->setOpen(open);
+}
+
+void ConfigView::updateList(ConfigItem* item)
+{
+ ConfigView* v;
+
+ for (v = viewList; v; v = v->nextView)
+ v->list->updateList(item);
+}
+
+void ConfigView::updateListAll(void)
+{
+ ConfigView* v;
+
+ for (v = viewList; v; v = v->nextView)
+ v->list->updateListAll();
+}
+
+ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
+ : Parent(parent, name), menu(0), sym(0)
+{
+ if (name) {
+ configSettings->beginGroup(name);
+ _showDebug = configSettings->readBoolEntry("/showDebug", false);
+ configSettings->endGroup();
+ connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
+ }
+}
+
+void ConfigInfoView::saveSettings(void)
+{
+ if (name()) {
+ configSettings->beginGroup(name());
+ configSettings->writeEntry("/showDebug", showDebug());
+ configSettings->endGroup();
+ }
+}
+
+void ConfigInfoView::setShowDebug(bool b)
+{
+ if (_showDebug != b) {
+ _showDebug = b;
+ if (menu)
+ menuInfo();
+ else if (sym)
+ symbolInfo();
+ emit showDebugChanged(b);
+ }
+}
+
+void ConfigInfoView::setInfo(struct menu *m)
+{
+ if (menu == m)
+ return;
+ menu = m;
+ sym = NULL;
+ if (!menu)
+ clear();
+ else
+ menuInfo();
+}
+
+void ConfigInfoView::setSource(const QString& name)
+{
+ const char *p = name.latin1();
+
+ menu = NULL;
+ sym = NULL;
+
+ switch (p[0]) {
+ case 'm':
+ struct menu *m;
+
+ if (sscanf(p, "m%p", &m) == 1 && menu != m) {
+ menu = m;
+ menuInfo();
+ emit menuSelected(menu);
+ }
+ break;
+ case 's':
+ struct symbol *s;
+
+ if (sscanf(p, "s%p", &s) == 1 && sym != s) {
+ sym = s;
+ symbolInfo();
+ }
+ break;
+ }
+}
+
+void ConfigInfoView::symbolInfo(void)
+{
+ QString str;
+
+ str += "<big>Symbol: <b>";
+ str += print_filter(sym->name);
+ str += "</b></big><br><br>value: ";
+ str += print_filter(sym_get_string_value(sym));
+ str += "<br>visibility: ";
+ str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
+ str += "<br>";
+ str += debug_info(sym);
+
+ setText(str);
+}
+
+void ConfigInfoView::menuInfo(void)
+{
+ struct symbol* sym;
+ QString head, debug, help;
+
+ sym = menu->sym;
+ if (sym) {
+ if (menu->prompt) {
+ head += "<big><b>";
+ head += print_filter(_(menu->prompt->text));
+ head += "</b></big>";
+ if (sym->name) {
+ head += " (";
+ if (showDebug())
+ head += QString().sprintf("<a href=\"s%p\">", sym);
+ head += print_filter(sym->name);
+ if (showDebug())
+ head += "</a>";
+ head += ")";
+ }
+ } else if (sym->name) {
+ head += "<big><b>";
+ if (showDebug())
+ head += QString().sprintf("<a href=\"s%p\">", sym);
+ head += print_filter(sym->name);
+ if (showDebug())
+ head += "</a>";
+ head += "</b></big>";
+ }
+ head += "<br><br>";
+
+ if (showDebug())
+ debug = debug_info(sym);
+
+ help = menu_get_help(menu);
+ /* Gettextize if the help text not empty */
+ if (help.isEmpty())
+ help = print_filter(menu_get_help(menu));
+ else
+ help = print_filter(_(menu_get_help(menu)));
+ } else if (menu->prompt) {
+ head += "<big><b>";
+ head += print_filter(_(menu->prompt->text));
+ head += "</b></big><br><br>";
+ if (showDebug()) {
+ if (menu->prompt->visible.expr) {
+ debug += "&nbsp;&nbsp;dep: ";
+ expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
+ debug += "<br><br>";
+ }
+ }
+ }
+ if (showDebug())
+ debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
+
+ setText(head + debug + help);
+}
+
+QString ConfigInfoView::debug_info(struct symbol *sym)
+{
+ QString debug;
+
+ debug += "type: ";
+ debug += print_filter(sym_type_name(sym->type));
+ if (sym_is_choice(sym))
+ debug += " (choice)";
+ debug += "<br>";
+ if (sym->rev_dep.expr) {
+ debug += "reverse dep: ";
+ expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ }
+ for (struct property *prop = sym->prop; prop; prop = prop->next) {
+ switch (prop->type) {
+ case P_PROMPT:
+ case P_MENU:
+ debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
+ debug += print_filter(_(prop->text));
+ debug += "</a><br>";
+ break;
+ case P_DEFAULT:
+ case P_SELECT:
+ case P_RANGE:
+ case P_ENV:
+ debug += prop_get_type_name(prop->type);
+ debug += ": ";
+ expr_print(prop->expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ break;
+ case P_CHOICE:
+ if (sym_is_choice(sym)) {
+ debug += "choice: ";
+ expr_print(prop->expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ }
+ break;
+ default:
+ debug += "unknown property: ";
+ debug += prop_get_type_name(prop->type);
+ debug += "<br>";
+ }
+ if (prop->visible.expr) {
+ debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
+ expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
+ debug += "<br>";
+ }
+ }
+ debug += "<br>";
+
+ return debug;
+}
+
+QString ConfigInfoView::print_filter(const QString &str)
+{
+ QRegExp re("[<>&\"\\n]");
+ QString res = str;
+ for (int i = 0; (i = res.find(re, i)) >= 0;) {
+ switch (res[i].latin1()) {
+ case '<':
+ res.replace(i, 1, "&lt;");
+ i += 4;
+ break;
+ case '>':
+ res.replace(i, 1, "&gt;");
+ i += 4;
+ break;
+ case '&':
+ res.replace(i, 1, "&amp;");
+ i += 5;
+ break;
+ case '"':
+ res.replace(i, 1, "&quot;");
+ i += 6;
+ break;
+ case '\n':
+ res.replace(i, 1, "<br>");
+ i += 4;
+ break;
+ }
+ }
+ return res;
+}
+
+void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
+{
+ QString* text = reinterpret_cast<QString*>(data);
+ QString str2 = print_filter(str);
+
+ if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
+ *text += QString().sprintf("<a href=\"s%p\">", sym);
+ *text += str2;
+ *text += "</a>";
+ } else
+ *text += str2;
+}
+
+QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
+{
+ QPopupMenu* popup = Parent::createPopupMenu(pos);
+ QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
+ action->setToggleAction(TRUE);
+ connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
+ connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
+ action->setOn(showDebug());
+ popup->insertSeparator();
+ action->addTo(popup);
+ return popup;
+}
+
+void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
+{
+ Parent::contentsContextMenuEvent(e);
+}
+
+ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
+ : Parent(parent, name), result(NULL)
+{
+ setCaption("Search Config");
+
+ QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
+ QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
+ layout2->addWidget(new QLabel(_("Find:"), this));
+ editField = new QLineEdit(this);
+ connect(editField, SIGNAL(returnPressed()), SLOT(search()));
+ layout2->addWidget(editField);
+ searchButton = new QPushButton(_("Search"), this);
+ searchButton->setAutoDefault(FALSE);
+ connect(searchButton, SIGNAL(clicked()), SLOT(search()));
+ layout2->addWidget(searchButton);
+ layout1->addLayout(layout2);
+
+ split = new QSplitter(this);
+ split->setOrientation(QSplitter::Vertical);
+ list = new ConfigView(split, name);
+ list->list->mode = listMode;
+ info = new ConfigInfoView(split, name);
+ connect(list->list, SIGNAL(menuChanged(struct menu *)),
+ info, SLOT(setInfo(struct menu *)));
+ connect(list->list, SIGNAL(menuChanged(struct menu *)),
+ parent, SLOT(setMenuLink(struct menu *)));
+
+ layout1->addWidget(split);
+
+ if (name) {
+ int x, y, width, height;
+ bool ok;
+
+ configSettings->beginGroup(name);
+ width = configSettings->readNumEntry("/window width", parent->width() / 2);
+ height = configSettings->readNumEntry("/window height", parent->height() / 2);
+ resize(width, height);
+ x = configSettings->readNumEntry("/window x", 0, &ok);
+ if (ok)
+ y = configSettings->readNumEntry("/window y", 0, &ok);
+ if (ok)
+ move(x, y);
+ QValueList<int> sizes = configSettings->readSizes("/split", &ok);
+ if (ok)
+ split->setSizes(sizes);
+ configSettings->endGroup();
+ connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
+ }
+}
+
+void ConfigSearchWindow::saveSettings(void)
+{
+ if (name()) {
+ configSettings->beginGroup(name());
+ configSettings->writeEntry("/window x", pos().x());
+ configSettings->writeEntry("/window y", pos().y());
+ configSettings->writeEntry("/window width", size().width());
+ configSettings->writeEntry("/window height", size().height());
+ configSettings->writeSizes("/split", split->sizes());
+ configSettings->endGroup();
+ }
+}
+
+void ConfigSearchWindow::search(void)
+{
+ struct symbol **p;
+ struct property *prop;
+ ConfigItem *lastItem = NULL;
+
+ free(result);
+ list->list->clear();
+ info->clear();
+
+ result = sym_re_search(editField->text().latin1());
+ if (!result)
+ return;
+ for (p = result; *p; p++) {
+ for_all_prompts((*p), prop)
+ lastItem = new ConfigItem(list->list, lastItem, prop->menu,
+ menu_is_visible(prop->menu));
+ }
+}
+
+/*
+ * Construct the complete config widget
+ */
+ConfigMainWindow::ConfigMainWindow(void)
+ : searchWindow(0)
+{
+ QMenuBar* menu;
+ bool ok;
+ int x, y, width, height;
+ char title[256];
+
+ QWidget *d = configApp->desktop();
+ snprintf(title, sizeof(title), _("libpayload v%s Configuration"),
+ getenv("KERNELVERSION"));
+ setCaption(title);
+
+ width = configSettings->readNumEntry("/window width", d->width() - 64);
+ height = configSettings->readNumEntry("/window height", d->height() - 64);
+ resize(width, height);
+ x = configSettings->readNumEntry("/window x", 0, &ok);
+ if (ok)
+ y = configSettings->readNumEntry("/window y", 0, &ok);
+ if (ok)
+ move(x, y);
+
+ split1 = new QSplitter(this);
+ split1->setOrientation(QSplitter::Horizontal);
+ setCentralWidget(split1);
+
+ menuView = new ConfigView(split1, "menu");
+ menuList = menuView->list;
+
+ split2 = new QSplitter(split1);
+ split2->setOrientation(QSplitter::Vertical);
+
+ // create config tree
+ configView = new ConfigView(split2, "config");
+ configList = configView->list;
+
+ helpText = new ConfigInfoView(split2, "help");
+ helpText->setTextFormat(Qt::RichText);
+
+ setTabOrder(configList, helpText);
+ configList->setFocus();
+
+ menu = menuBar();
+ toolBar = new QToolBar("Tools", this);
+
+ backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
+ connect(backAction, SIGNAL(activated()), SLOT(goBack()));
+ backAction->setEnabled(FALSE);
+ QAction *quitAction = new QAction("Quit", _("&Quit"), CTRL+Key_Q, this);
+ connect(quitAction, SIGNAL(activated()), SLOT(close()));
+ QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), CTRL+Key_L, this);
+ connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
+ saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), CTRL+Key_S, this);
+ connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
+ conf_set_changed_callback(conf_changed);
+ // Set saveAction's initial state
+ conf_changed();
+ QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
+ connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
+ QAction *searchAction = new QAction("Find", _("&Find"), CTRL+Key_F, this);
+ connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
+ QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
+ connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
+ QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
+ connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
+ QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
+ connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
+
+ QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
+ showNameAction->setToggleAction(TRUE);
+ connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
+ connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
+ showNameAction->setOn(configView->showName());
+ QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
+ showRangeAction->setToggleAction(TRUE);
+ connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
+ connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
+ showRangeAction->setOn(configList->showRange);
+ QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
+ showDataAction->setToggleAction(TRUE);
+ connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
+ connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
+ showDataAction->setOn(configList->showData);
+ QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
+ showAllAction->setToggleAction(TRUE);
+ connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
+ connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
+ showAllAction->setOn(configList->showAll);
+ QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
+ showDebugAction->setToggleAction(TRUE);
+ connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
+ connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
+ showDebugAction->setOn(helpText->showDebug());
+
+ QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
+ connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
+ QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
+ connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
+
+ // init tool bar
+ backAction->addTo(toolBar);
+ toolBar->addSeparator();
+ loadAction->addTo(toolBar);
+ saveAction->addTo(toolBar);
+ toolBar->addSeparator();
+ singleViewAction->addTo(toolBar);
+ splitViewAction->addTo(toolBar);
+ fullViewAction->addTo(toolBar);
+
+ // create config menu
+ QPopupMenu* config = new QPopupMenu(this);
+ menu->insertItem(_("&File"), config);
+ loadAction->addTo(config);
+ saveAction->addTo(config);
+ saveAsAction->addTo(config);
+ config->insertSeparator();
+ quitAction->addTo(config);
+
+ // create edit menu
+ QPopupMenu* editMenu = new QPopupMenu(this);
+ menu->insertItem(_("&Edit"), editMenu);
+ searchAction->addTo(editMenu);
+
+ // create options menu
+ QPopupMenu* optionMenu = new QPopupMenu(this);
+ menu->insertItem(_("&Option"), optionMenu);
+ showNameAction->addTo(optionMenu);
+ showRangeAction->addTo(optionMenu);
+ showDataAction->addTo(optionMenu);
+ optionMenu->insertSeparator();
+ showAllAction->addTo(optionMenu);
+ showDebugAction->addTo(optionMenu);
+
+ // create help menu
+ QPopupMenu* helpMenu = new QPopupMenu(this);
+ menu->insertSeparator();
+ menu->insertItem(_("&Help"), helpMenu);
+ showIntroAction->addTo(helpMenu);
+ showAboutAction->addTo(helpMenu);
+
+ connect(configList, SIGNAL(menuChanged(struct menu *)),
+ helpText, SLOT(setInfo(struct menu *)));
+ connect(configList, SIGNAL(menuSelected(struct menu *)),
+ SLOT(changeMenu(struct menu *)));
+ connect(configList, SIGNAL(parentSelected()),
+ SLOT(goBack()));
+ connect(menuList, SIGNAL(menuChanged(struct menu *)),
+ helpText, SLOT(setInfo(struct menu *)));
+ connect(menuList, SIGNAL(menuSelected(struct menu *)),
+ SLOT(changeMenu(struct menu *)));
+
+ connect(configList, SIGNAL(gotFocus(struct menu *)),
+ helpText, SLOT(setInfo(struct menu *)));
+ connect(menuList, SIGNAL(gotFocus(struct menu *)),
+ helpText, SLOT(setInfo(struct menu *)));
+ connect(menuList, SIGNAL(gotFocus(struct menu *)),
+ SLOT(listFocusChanged(void)));
+ connect(helpText, SIGNAL(menuSelected(struct menu *)),
+ SLOT(setMenuLink(struct menu *)));
+
+ QString listMode = configSettings->readEntry("/listMode", "symbol");
+ if (listMode == "single")
+ showSingleView();
+ else if (listMode == "full")
+ showFullView();
+ else /*if (listMode == "split")*/
+ showSplitView();
+
+ // UI setup done, restore splitter positions
+ QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
+ if (ok)
+ split1->setSizes(sizes);
+
+ sizes = configSettings->readSizes("/split2", &ok);
+ if (ok)
+ split2->setSizes(sizes);
+}
+
+void ConfigMainWindow::loadConfig(void)
+{
+ QString s = QFileDialog::getOpenFileName(".config", NULL, this);
+ if (s.isNull())
+ return;
+ if (conf_read(QFile::encodeName(s)))
+ QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
+ ConfigView::updateListAll();
+}
+
+void ConfigMainWindow::saveConfig(void)
+{
+ if (conf_write(NULL))
+ QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
+ if (conf_write_autoconf())
+ QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
+}
+
+void ConfigMainWindow::saveConfigAs(void)
+{
+ QString s = QFileDialog::getSaveFileName(".config", NULL, this);
+ if (s.isNull())
+ return;
+ if (conf_write(QFile::encodeName(s)))
+ QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
+ if (conf_write_autoconf())
+ QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
+}
+
+void ConfigMainWindow::searchConfig(void)
+{
+ if (!searchWindow)
+ searchWindow = new ConfigSearchWindow(this, "search");
+ searchWindow->show();
+}
+
+void ConfigMainWindow::changeMenu(struct menu *menu)
+{
+ configList->setRootMenu(menu);
+ if (configList->rootEntry->parent == &rootmenu)
+ backAction->setEnabled(FALSE);
+ else
+ backAction->setEnabled(TRUE);
+}
+
+void ConfigMainWindow::setMenuLink(struct menu *menu)
+{
+ struct menu *parent;
+ ConfigList* list = NULL;
+ ConfigItem* item;
+
+ if (!menu_is_visible(menu) && !configView->showAll())
+ return;
+
+ switch (configList->mode) {
+ case singleMode:
+ list = configList;
+ parent = menu_get_parent_menu(menu);
+ if (!parent)
+ return;
+ list->setRootMenu(parent);
+ break;
+ case symbolMode:
+ if (menu->flags & MENU_ROOT) {
+ configList->setRootMenu(menu);
+ configList->clearSelection();
+ list = menuList;
+ } else {
+ list = configList;
+ parent = menu_get_parent_menu(menu->parent);
+ if (!parent)
+ return;
+ item = menuList->findConfigItem(parent);
+ if (item) {
+ menuList->setSelected(item, TRUE);
+ menuList->ensureItemVisible(item);
+ }
+ list->setRootMenu(parent);
+ }
+ break;
+ case fullMode:
+ list = configList;
+ break;
+ }
+
+ if (list) {
+ item = list->findConfigItem(menu);
+ if (item) {
+ list->setSelected(item, TRUE);
+ list->ensureItemVisible(item);
+ list->setFocus();
+ }
+ }
+}
+
+void ConfigMainWindow::listFocusChanged(void)
+{
+ if (menuList->mode == menuMode)
+ configList->clearSelection();
+}
+
+void ConfigMainWindow::goBack(void)
+{
+ ConfigItem* item;
+
+ configList->setParentMenu();
+ if (configList->rootEntry == &rootmenu)
+ backAction->setEnabled(FALSE);
+ item = (ConfigItem*)menuList->selectedItem();
+ while (item) {
+ if (item->menu == configList->rootEntry) {
+ menuList->setSelected(item, TRUE);
+ break;
+ }
+ item = (ConfigItem*)item->parent();
+ }
+}
+
+void ConfigMainWindow::showSingleView(void)
+{
+ menuView->hide();
+ menuList->setRootMenu(0);
+ configList->mode = singleMode;
+ if (configList->rootEntry == &rootmenu)
+ configList->updateListAll();
+ else
+ configList->setRootMenu(&rootmenu);
+ configList->setAllOpen(TRUE);
+ configList->setFocus();
+}
+
+void ConfigMainWindow::showSplitView(void)
+{
+ configList->mode = symbolMode;
+ if (configList->rootEntry == &rootmenu)
+ configList->updateListAll();
+ else
+ configList->setRootMenu(&rootmenu);
+ configList->setAllOpen(TRUE);
+ configApp->processEvents();
+ menuList->mode = menuMode;
+ menuList->setRootMenu(&rootmenu);
+ menuList->setAllOpen(TRUE);
+ menuView->show();
+ menuList->setFocus();
+}
+
+void ConfigMainWindow::showFullView(void)
+{
+ menuView->hide();
+ menuList->setRootMenu(0);
+ configList->mode = fullMode;
+ if (configList->rootEntry == &rootmenu)
+ configList->updateListAll();
+ else
+ configList->setRootMenu(&rootmenu);
+ configList->setAllOpen(FALSE);
+ configList->setFocus();
+}
+
+/*
+ * ask for saving configuration before quitting
+ * TODO ask only when something changed
+ */
+void ConfigMainWindow::closeEvent(QCloseEvent* e)
+{
+ if (!conf_get_changed()) {
+ e->accept();
+ return;
+ }
+ QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
+ QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
+ mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
+ mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
+ mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
+ switch (mb.exec()) {
+ case QMessageBox::Yes:
+ conf_write(NULL);
+ conf_write_autoconf();
+ case QMessageBox::No:
+ e->accept();
+ break;
+ case QMessageBox::Cancel:
+ e->ignore();
+ break;
+ }
+}
+
+void ConfigMainWindow::showIntro(void)
+{
+ static const QString str = _("Welcome to the qconf graphical configuration tool for libpayload.\n\n"
+ "For each option, a blank box indicates the feature is disabled, a check\n"
+ "indicates it is enabled, and a dot indicates that it is to be compiled\n"
+ "as a module. Clicking on the box will cycle through the three states.\n\n"
+ "If you do not see an option (e.g., a device driver) that you believe\n"
+ "should be present, try turning on Show All Options under the Options menu.\n"
+ "Although there is no cross reference yet to help you figure out what other\n"
+ "options must be enabled to support the option you are interested in, you can\n"
+ "still view the help of a grayed-out option.\n\n"
+ "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
+ "which you can then match by examining other options.\n\n");
+
+ QMessageBox::information(this, "qconf", str);
+}
+
+void ConfigMainWindow::showAbout(void)
+{
+ static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
+ "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
+
+ QMessageBox::information(this, "qconf", str);
+}
+
+void ConfigMainWindow::saveSettings(void)
+{
+ configSettings->writeEntry("/window x", pos().x());
+ configSettings->writeEntry("/window y", pos().y());
+ configSettings->writeEntry("/window width", size().width());
+ configSettings->writeEntry("/window height", size().height());
+
+ QString entry;
+ switch(configList->mode) {
+ case singleMode :
+ entry = "single";
+ break;
+
+ case symbolMode :
+ entry = "split";
+ break;
+
+ case fullMode :
+ entry = "full";
+ break;
+ }
+ configSettings->writeEntry("/listMode", entry);
+
+ configSettings->writeSizes("/split1", split1->sizes());
+ configSettings->writeSizes("/split2", split2->sizes());
+}
+
+void ConfigMainWindow::conf_changed(void)
+{
+ if (saveAction)
+ saveAction->setEnabled(conf_get_changed());
+}
+
+void fixup_rootmenu(struct menu *menu)
+{
+ struct menu *child;
+ static int menu_cnt = 0;
+
+ menu->flags |= MENU_ROOT;
+ for (child = menu->list; child; child = child->next) {
+ if (child->prompt && child->prompt->type == P_MENU) {
+ menu_cnt++;
+ fixup_rootmenu(child);
+ menu_cnt--;
+ } else if (!menu_cnt)
+ fixup_rootmenu(child);
+ }
+}
+
+static const char *progname;
+
+static void usage(void)
+{
+ printf(_("%s <config>\n"), progname);
+ exit(0);
+}
+
+int main(int ac, char** av)
+{
+ ConfigMainWindow* v;
+ const char *name;
+
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+#ifndef LKC_DIRECT_LINK
+ kconfig_load();
+#endif
+
+ progname = av[0];
+ configApp = new QApplication(ac, av);
+ if (ac > 1 && av[1][0] == '-') {
+ switch (av[1][1]) {
+ case 'h':
+ case '?':
+ usage();
+ }
+ name = av[2];
+ } else
+ name = av[1];
+ if (!name)
+ usage();
+
+ conf_parse(name);
+ fixup_rootmenu(&rootmenu);
+ conf_read(NULL);
+ //zconfdump(stdout);
+
+ configSettings = new ConfigSettings();
+ configSettings->beginGroup("/kconfig/qconf");
+ v = new ConfigMainWindow();
+
+ //zconfdump(stdout);
+ configApp->setMainWidget(v);
+ configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
+ configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
+ v->show();
+ configApp->exec();
+
+ configSettings->endGroup();
+ delete configSettings;
+
+ return 0;
+}
diff --git a/payloads/libpayload/util/kconfig/qconf.h b/payloads/libpayload/util/kconfig/qconf.h
new file mode 100644
index 0000000000..b3b5657b6b
--- /dev/null
+++ b/payloads/libpayload/util/kconfig/qconf.h
@@ -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(ConfigMainWindow* 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;
+};
diff --git a/payloads/libpayload/util/kconfig/symbol.c b/payloads/libpayload/util/kconfig/symbol.c
index 3d7877afcc..4a03191ad1 100644
--- a/payloads/libpayload/util/kconfig/symbol.c
+++ b/payloads/libpayload/util/kconfig/symbol.c
@@ -15,25 +15,27 @@
struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
- .flags = SYMBOL_YES|SYMBOL_VALID,
+ .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_mod = {
.name = "m",
.curr = { "m", mod },
- .flags = SYMBOL_MOD|SYMBOL_VALID,
+ .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_no = {
.name = "n",
.curr = { "n", no },
- .flags = SYMBOL_NO|SYMBOL_VALID,
+ .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
};
-int sym_change_count;
+struct symbol *sym_defconfig_list;
struct symbol *modules_sym;
tristate modules_val;
+struct expr *sym_env_list;
+
void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = prop_alloc(P_DEFAULT, sym);
@@ -45,7 +47,6 @@ void sym_init(void)
{
struct symbol *sym;
struct utsname uts;
- char *p;
static bool inited = false;
if (inited)
@@ -54,20 +55,6 @@ void sym_init(void)
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("KERNELVERSION", 0);
- sym->type = S_STRING;
- sym->flags |= SYMBOL_AUTO;
- p = getenv("KERNELVERSION");
- if (p)
- sym_add_default(sym, p);
-
sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
@@ -117,6 +104,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
return NULL;
}
+struct property *sym_get_env_prop(struct symbol *sym)
+{
+ struct property *prop;
+
+ for_all_properties(sym, prop, P_ENV)
+ return prop;
+ return NULL;
+}
+
struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
@@ -199,7 +195,7 @@ static void sym_calc_visibility(struct symbol *sym)
tri = no;
for_all_prompts(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr);
- tri = E_OR(tri, prop->visible.tri);
+ tri = EXPR_OR(tri, prop->visible.tri);
}
if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
tri = yes;
@@ -227,7 +223,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
struct expr *e;
/* is the user choice visible? */
- def_sym = sym->user.val;
+ def_sym = sym->def[S_DEF_USER].val;
if (def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
@@ -247,8 +243,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
/* just get the first visible value */
prop = sym_get_choice_prop(sym);
- for (e = prop->expr; e; e = e->left.expr) {
- def_sym = e->right.sym;
+ expr_list_for_each_sym(prop->expr, e, def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
return def_sym;
@@ -303,22 +298,30 @@ void sym_calc_value(struct symbol *sym)
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
- } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
- sym->flags |= SYMBOL_WRITE;
- if (sym_has_value(sym))
- newval.tri = sym->user.tri;
- else if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop)
- newval.tri = expr_calc_value(prop->expr);
+ } else {
+ if (sym->visible != no) {
+ /* if the symbol is visible use the user value
+ * if available, otherwise try the default value
+ */
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
+ sym->visible);
+ goto calc_newval;
+ }
}
- newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
- } else if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop) {
+ if (sym->rev_dep.tri != no)
sym->flags |= SYMBOL_WRITE;
- newval.tri = expr_calc_value(prop->expr);
+ if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = EXPR_AND(expr_calc_value(prop->expr),
+ prop->visible.tri);
+ }
}
+ calc_newval:
+ newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
@@ -329,7 +332,7 @@ void sym_calc_value(struct symbol *sym)
if (sym->visible != no) {
sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) {
- newval.val = sym->user.val;
+ newval.val = sym->def[S_DEF_USER].val;
break;
}
}
@@ -347,23 +350,31 @@ void sym_calc_value(struct symbol *sym)
;
}
+ if (sym->flags & SYMBOL_AUTO)
+ sym->flags &= ~SYMBOL_WRITE;
+
sym->curr = newval;
if (sym_is_choice(sym) && newval.tri == yes)
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);
- if (modules_sym == sym)
- modules_val = modules_sym->curr.tri;
+ if (modules_sym == sym) {
+ sym_set_all_changed();
+ modules_val = modules_sym->curr.tri;
+ }
+ }
if (sym_is_choice(sym)) {
+ struct symbol *choice_sym;
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
+
prop = sym_get_choice_prop(sym);
- for (e = prop->expr; e; e = e->left.expr) {
- e->right.sym->flags |= flags;
+ expr_list_for_each_sym(prop->expr, e, choice_sym) {
+ choice_sym->flags |= flags;
if (flags & SYMBOL_CHANGED)
- sym_set_changed(e->right.sym);
+ sym_set_changed(choice_sym);
}
}
}
@@ -375,7 +386,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
- sym_change_count++;
+ sym_add_change_count(1);
if (modules_sym)
sym_calc_value(modules_sym);
}
@@ -426,8 +437,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
if (oldval != val && !sym_tristate_within_range(sym, val))
return false;
- if (sym->flags & SYMBOL_NEW) {
- sym->flags &= ~SYMBOL_NEW;
+ if (!(sym->flags & SYMBOL_DEF_USER)) {
+ sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym);
}
/*
@@ -439,21 +450,18 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
struct property *prop;
struct expr *e;
- cs->user.val = sym;
- cs->flags &= ~SYMBOL_NEW;
+ cs->def[S_DEF_USER].val = sym;
+ 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_NEW;
+ e->right.sym->flags |= SYMBOL_DEF_USER;
}
}
- sym->user.tri = val;
- if (oldval != val) {
+ sym->def[S_DEF_USER].tri = val;
+ if (oldval != val)
sym_clear_all_valid();
- if (sym == modules_sym)
- sym_set_all_changed();
- }
return true;
}
@@ -591,20 +599,20 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
if (!sym_string_within_range(sym, newval))
return false;
- if (sym->flags & SYMBOL_NEW) {
- sym->flags &= ~SYMBOL_NEW;
+ if (!(sym->flags & SYMBOL_DEF_USER)) {
+ sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym);
}
- oldval = sym->user.val;
+ oldval = sym->def[S_DEF_USER].val;
size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2;
- sym->user.val = val = malloc(size);
+ sym->def[S_DEF_USER].val = val = malloc(size);
*val++ = '0';
*val++ = 'x';
} else if (!oldval || strcmp(oldval, newval))
- sym->user.val = val = malloc(size);
+ sym->def[S_DEF_USER].val = val = malloc(size);
else
return true;
@@ -679,7 +687,6 @@ struct symbol *sym_lookup(const char *name, int isconst)
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
- symbol->flags = SYMBOL_NEW;
if (isconst)
symbol->flags |= SYMBOL_CONST;
@@ -787,13 +794,15 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
return NULL;
}
+/* return NULL when dependencies are OK */
struct symbol *sym_check_deps(struct symbol *sym)
{
struct symbol *sym2;
struct property *prop;
if (sym->flags & SYMBOL_CHECK) {
- printf("Warning! Found recursive dependency: %s", sym->name);
+ fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
+ sym->prop->file->name, sym->prop->lineno, sym->name);
return sym;
}
if (sym->flags & SYMBOL_CHECKED)
@@ -817,13 +826,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
goto out;
}
out:
- if (sym2) {
- printf(" %s", sym->name);
- if (sym2 == sym) {
- printf("\n");
- sym2 = NULL;
- }
- }
+ if (sym2)
+ fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": "");
sym->flags &= ~SYMBOL_CHECK;
return sym2;
}
@@ -853,7 +857,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym)
struct symbol *prop_get_symbol(struct property *prop)
{
if (prop->expr && (prop->expr->type == E_SYMBOL ||
- prop->expr->type == E_CHOICE))
+ prop->expr->type == E_LIST))
return prop->expr->left.sym;
return NULL;
}
@@ -863,6 +867,8 @@ const char *prop_get_type_name(enum prop_type type)
switch (type) {
case P_PROMPT:
return "prompt";
+ case P_ENV:
+ return "env";
case P_COMMENT:
return "comment";
case P_MENU:
@@ -880,3 +886,32 @@ const char *prop_get_type_name(enum prop_type type)
}
return "unknown";
}
+
+void prop_add_env(const char *env)
+{
+ struct symbol *sym, *sym2;
+ struct property *prop;
+ char *p;
+
+ sym = current_entry->sym;
+ sym->flags |= SYMBOL_AUTO;
+ for_all_properties(sym, prop, P_ENV) {
+ sym2 = prop_get_symbol(prop);
+ if (strcmp(sym2->name, env))
+ menu_warn(current_entry, "redefining environment symbol from %s",
+ sym2->name);
+ return;
+ }
+
+ prop = prop_alloc(P_ENV, sym);
+ prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
+
+ sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
+ sym_env_list->right.sym = sym;
+
+ p = getenv(env);
+ if (p)
+ sym_add_default(sym, p);
+ else
+ menu_warn(current_entry, "environment variable %s undefined", env);
+}
diff --git a/payloads/libpayload/util/kconfig/util.c b/payloads/libpayload/util/kconfig/util.c
index aea8d56ce4..a47d5e0fdc 100644
--- a/payloads/libpayload/util/kconfig/util.c
+++ b/payloads/libpayload/util/kconfig/util.c
@@ -29,6 +29,8 @@ struct file *file_lookup(const char *name)
/* write a dependency file as used by kbuild to track dependencies */
int file_write_dep(const char *name)
{
+ struct symbol *sym, *env_sym;
+ struct expr *e;
struct file *file;
FILE *out;
@@ -44,7 +46,26 @@ int file_write_dep(const char *name)
else
fprintf(out, "\t%s\n", file->name);
}
- fprintf(out, "\n.config include/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
+ fprintf(out, "\nbuild/auto.conf: \\\n"
+ "\t$(deps_config)\n\n");
+
+ expr_list_for_each_sym(sym_env_list, e, sym) {
+ struct property *prop;
+ const char *value;
+
+ prop = sym_get_env_prop(sym);
+ env_sym = prop_get_symbol(prop);
+ if (!env_sym)
+ continue;
+ value = getenv(env_sym->name);
+ if (!value)
+ value = "";
+ fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
+ fprintf(out, "build/auto.conf: FORCE\n");
+ fprintf(out, "endif\n");
+ }
+
+ fprintf(out, "\n$(deps_config): ;\n");
fclose(out);
rename("..config.tmp", name);
return 0;
@@ -82,12 +103,15 @@ void str_free(struct gstr *gs)
/* Append to growable string */
void str_append(struct gstr *gs, const char *s)
{
- size_t l = strlen(gs->s) + strlen(s) + 1;
- if (l > gs->len) {
- gs->s = realloc(gs->s, l);
- gs->len = l;
+ size_t l;
+ if (s) {
+ l = strlen(gs->s) + strlen(s) + 1;
+ if (l > gs->len) {
+ gs->s = realloc(gs->s, l);
+ gs->len = l;
+ }
+ strcat(gs->s, s);
}
- strcat(gs->s, s);
}
/* Append printf formatted string to growable string */
diff --git a/payloads/libpayload/util/kconfig/zconf.gperf b/payloads/libpayload/util/kconfig/zconf.gperf
index b03220600b..25ef5d01c0 100644
--- a/payloads/libpayload/util/kconfig/zconf.gperf
+++ b/payloads/libpayload/util/kconfig/zconf.gperf
@@ -23,7 +23,6 @@ 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
@@ -32,12 +31,14 @@ 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
+env, T_OPT_ENV, TF_OPTION
%%
diff --git a/payloads/libpayload/util/kconfig/zconf.hash.c b/payloads/libpayload/util/kconfig/zconf.hash.c
deleted file mode 100644
index 345f0fc07c..0000000000
--- a/payloads/libpayload/util/kconfig/zconf.hash.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* 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, 10, 15,
- 0, 0, 5, 47, 0, 0, 47, 47, 0, 10,
- 0, 20, 20, 20, 5, 0, 0, 20, 47, 47,
- 20, 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("if")];
- char kconf_id_strings_str3[sizeof("int")];
- char kconf_id_strings_str4[sizeof("help")];
- char kconf_id_strings_str5[sizeof("endif")];
- char kconf_id_strings_str6[sizeof("select")];
- char kconf_id_strings_str7[sizeof("endmenu")];
- char kconf_id_strings_str8[sizeof("tristate")];
- char kconf_id_strings_str9[sizeof("endchoice")];
- char kconf_id_strings_str10[sizeof("range")];
- char kconf_id_strings_str11[sizeof("string")];
- char kconf_id_strings_str12[sizeof("default")];
- char kconf_id_strings_str13[sizeof("def_bool")];
- char kconf_id_strings_str14[sizeof("menu")];
- char kconf_id_strings_str16[sizeof("def_boolean")];
- char kconf_id_strings_str17[sizeof("def_tristate")];
- char kconf_id_strings_str18[sizeof("mainmenu")];
- char kconf_id_strings_str20[sizeof("menuconfig")];
- char kconf_id_strings_str21[sizeof("config")];
- char kconf_id_strings_str22[sizeof("on")];
- char kconf_id_strings_str23[sizeof("hex")];
- char kconf_id_strings_str26[sizeof("source")];
- char kconf_id_strings_str27[sizeof("depends")];
- char kconf_id_strings_str28[sizeof("optional")];
- char kconf_id_strings_str31[sizeof("enable")];
- char kconf_id_strings_str32[sizeof("comment")];
- char kconf_id_strings_str33[sizeof("requires")];
- char kconf_id_strings_str34[sizeof("bool")];
- char kconf_id_strings_str37[sizeof("boolean")];
- char kconf_id_strings_str41[sizeof("choice")];
- char kconf_id_strings_str46[sizeof("prompt")];
- };
-static struct kconf_id_strings_t kconf_id_strings_contents =
- {
- "if",
- "int",
- "help",
- "endif",
- "select",
- "endmenu",
- "tristate",
- "endchoice",
- "range",
- "string",
- "default",
- "def_bool",
- "menu",
- "def_boolean",
- "def_tristate",
- "mainmenu",
- "menuconfig",
- "config",
- "on",
- "hex",
- "source",
- "depends",
- "optional",
- "enable",
- "comment",
- "requires",
- "bool",
- "boolean",
- "choice",
- "prompt"
- };
-#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 = 30,
- MIN_WORD_LENGTH = 2,
- MAX_WORD_LENGTH = 12,
- 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_IF, TF_COMMAND|TF_PARAM},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND},
- {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND},
- {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {-1}, {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND},
- {-1}, {-1}, {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, 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;
-}
-
diff --git a/payloads/libpayload/util/kconfig/zconf.hash.c_shipped b/payloads/libpayload/util/kconfig/zconf.hash.c_shipped
index 345f0fc07c..5c73d51339 100644
--- a/payloads/libpayload/util/kconfig/zconf.hash.c_shipped
+++ b/payloads/libpayload/util/kconfig/zconf.hash.c_shipped
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.1 */
+/* ANSI-C code produced by gperf version 3.0.3 */
/* Command-line: gperf */
/* Computed positions: -k'1,3' */
@@ -30,7 +30,7 @@
#endif
struct kconf_id;
-/* maximum key range = 45, duplicates = 0 */
+/* maximum key range = 47, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -44,32 +44,32 @@ 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, 10, 15,
- 0, 0, 5, 47, 0, 0, 47, 47, 0, 10,
- 0, 20, 20, 20, 5, 0, 0, 20, 47, 47,
- 20, 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
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 11, 5,
+ 0, 0, 5, 49, 5, 20, 49, 49, 5, 20,
+ 5, 0, 30, 49, 0, 15, 0, 10, 0, 49,
+ 25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49
};
register int hval = len;
@@ -88,126 +88,132 @@ kconf_id_hash (register const char *str, register unsigned int len)
struct kconf_id_strings_t
{
- char kconf_id_strings_str2[sizeof("if")];
- char kconf_id_strings_str3[sizeof("int")];
- char kconf_id_strings_str4[sizeof("help")];
+ char kconf_id_strings_str2[sizeof("on")];
+ char kconf_id_strings_str3[sizeof("env")];
char kconf_id_strings_str5[sizeof("endif")];
- char kconf_id_strings_str6[sizeof("select")];
+ char kconf_id_strings_str6[sizeof("option")];
char kconf_id_strings_str7[sizeof("endmenu")];
- char kconf_id_strings_str8[sizeof("tristate")];
+ char kconf_id_strings_str8[sizeof("optional")];
char kconf_id_strings_str9[sizeof("endchoice")];
char kconf_id_strings_str10[sizeof("range")];
- char kconf_id_strings_str11[sizeof("string")];
+ char kconf_id_strings_str11[sizeof("choice")];
char kconf_id_strings_str12[sizeof("default")];
char kconf_id_strings_str13[sizeof("def_bool")];
- char kconf_id_strings_str14[sizeof("menu")];
- char kconf_id_strings_str16[sizeof("def_boolean")];
+ char kconf_id_strings_str14[sizeof("help")];
+ char kconf_id_strings_str15[sizeof("bool")];
+ char kconf_id_strings_str16[sizeof("config")];
char kconf_id_strings_str17[sizeof("def_tristate")];
- char kconf_id_strings_str18[sizeof("mainmenu")];
- char kconf_id_strings_str20[sizeof("menuconfig")];
- char kconf_id_strings_str21[sizeof("config")];
- char kconf_id_strings_str22[sizeof("on")];
- char kconf_id_strings_str23[sizeof("hex")];
- char kconf_id_strings_str26[sizeof("source")];
- char kconf_id_strings_str27[sizeof("depends")];
- char kconf_id_strings_str28[sizeof("optional")];
- char kconf_id_strings_str31[sizeof("enable")];
+ char kconf_id_strings_str18[sizeof("boolean")];
+ char kconf_id_strings_str19[sizeof("defconfig_list")];
+ char kconf_id_strings_str21[sizeof("string")];
+ char kconf_id_strings_str22[sizeof("if")];
+ char kconf_id_strings_str23[sizeof("int")];
+ char kconf_id_strings_str26[sizeof("select")];
+ char kconf_id_strings_str27[sizeof("modules")];
+ char kconf_id_strings_str28[sizeof("tristate")];
+ char kconf_id_strings_str29[sizeof("menu")];
+ char kconf_id_strings_str31[sizeof("source")];
char kconf_id_strings_str32[sizeof("comment")];
- char kconf_id_strings_str33[sizeof("requires")];
- char kconf_id_strings_str34[sizeof("bool")];
- char kconf_id_strings_str37[sizeof("boolean")];
- char kconf_id_strings_str41[sizeof("choice")];
- char kconf_id_strings_str46[sizeof("prompt")];
+ char kconf_id_strings_str33[sizeof("hex")];
+ char kconf_id_strings_str35[sizeof("menuconfig")];
+ char kconf_id_strings_str36[sizeof("prompt")];
+ char kconf_id_strings_str37[sizeof("depends")];
+ char kconf_id_strings_str48[sizeof("mainmenu")];
};
static struct kconf_id_strings_t kconf_id_strings_contents =
{
- "if",
- "int",
- "help",
+ "on",
+ "env",
"endif",
- "select",
+ "option",
"endmenu",
- "tristate",
+ "optional",
"endchoice",
"range",
- "string",
+ "choice",
"default",
"def_bool",
- "menu",
- "def_boolean",
- "def_tristate",
- "mainmenu",
- "menuconfig",
+ "help",
+ "bool",
"config",
- "on",
- "hex",
+ "def_tristate",
+ "boolean",
+ "defconfig_list",
+ "string",
+ "if",
+ "int",
+ "select",
+ "modules",
+ "tristate",
+ "menu",
"source",
- "depends",
- "optional",
- "enable",
"comment",
- "requires",
- "bool",
- "boolean",
- "choice",
- "prompt"
+ "hex",
+ "menuconfig",
+ "prompt",
+ "depends",
+ "mainmenu"
};
#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
#ifdef __GNUC__
__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
struct kconf_id *
kconf_id_lookup (register const char *str, register unsigned int len)
{
enum
{
- TOTAL_KEYWORDS = 30,
+ TOTAL_KEYWORDS = 31,
MIN_WORD_LENGTH = 2,
- MAX_WORD_LENGTH = 12,
+ MAX_WORD_LENGTH = 14,
MIN_HASH_VALUE = 2,
- MAX_HASH_VALUE = 46
+ MAX_HASH_VALUE = 48
};
static struct kconf_id wordlist[] =
{
{-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_OPT_ENV, TF_OPTION},
+ {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_OPTIONAL, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_CHOICE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND},
- {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
{-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
+ {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {-1}, {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND},
- {-1}, {-1}, {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, TF_COMMAND}
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX},
+ {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+ {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/payloads/libpayload/util/kconfig/zconf.l b/payloads/libpayload/util/kconfig/zconf.l
index cfa46077c6..4cea5c85cd 100644
--- a/payloads/libpayload/util/kconfig/zconf.l
+++ b/payloads/libpayload/util/kconfig/zconf.l
@@ -217,6 +217,11 @@ n [A-Za-z0-9_]
append_string("\n", 1);
}
[^ \t\n].* {
+ while (yyleng) {
+ if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
+ break;
+ yyleng--;
+ }
append_string(yytext, yyleng);
if (!first_ts)
first_ts = last_ts;
@@ -265,7 +270,7 @@ FILE *zconf_fopen(const char *name)
FILE *f;
f = fopen(name, "r");
- if (!f && name[0] != '/') {
+ if (!f && name != NULL && name[0] != '/') {
env = getenv(SRCTREE);
if (env) {
sprintf(fullname, "%s/%s", env, name);
diff --git a/payloads/libpayload/util/kconfig/zconf.tab.c_shipped b/payloads/libpayload/util/kconfig/zconf.tab.c_shipped
index 560f5284e1..346c416856 100644
--- a/payloads/libpayload/util/kconfig/zconf.tab.c_shipped
+++ b/payloads/libpayload/util/kconfig/zconf.tab.c_shipped
@@ -1,7 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.0. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,16 +17,24 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
-/* Written by Richard Stallman by simplifying the original so called
- ``semantic'' parser. */
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
@@ -36,6 +46,9 @@
/* Identify Bison output. */
#define YYBISON 1
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -75,13 +88,13 @@
T_IF = 269,
T_ENDIF = 270,
T_DEPENDS = 271,
- T_REQUIRES = 272,
- T_OPTIONAL = 273,
- T_PROMPT = 274,
- T_TYPE = 275,
- T_DEFAULT = 276,
- T_SELECT = 277,
- T_RANGE = 278,
+ T_OPTIONAL = 272,
+ T_PROMPT = 273,
+ T_TYPE = 274,
+ T_DEFAULT = 275,
+ T_SELECT = 276,
+ T_RANGE = 277,
+ T_OPTION = 278,
T_ON = 279,
T_WORD = 280,
T_WORD_QUOTE = 281,
@@ -95,6 +108,7 @@
T_NOT = 289
};
#endif
+/* Tokens. */
#define T_MAINMENU 258
#define T_MENU 259
#define T_ENDMENU 260
@@ -109,13 +123,13 @@
#define T_IF 269
#define T_ENDIF 270
#define T_DEPENDS 271
-#define T_REQUIRES 272
-#define T_OPTIONAL 273
-#define T_PROMPT 274
-#define T_TYPE 275
-#define T_DEFAULT 276
-#define T_SELECT 277
-#define T_RANGE 278
+#define T_OPTIONAL 272
+#define T_PROMPT 273
+#define T_TYPE 274
+#define T_DEFAULT 275
+#define T_SELECT 276
+#define T_RANGE 277
+#define T_OPTION 278
#define T_ON 279
#define T_WORD 280
#define T_WORD_QUOTE 281
@@ -187,18 +201,25 @@ static struct menu *current_menu, *current_entry;
# define YYERROR_VERBOSE 0
#endif
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
-typedef union YYSTYPE {
+{
char *string;
struct file *file;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
struct kconf_id *id;
-} YYSTYPE;
-/* Line 190 of yacc.c. */
+}
+/* Line 187 of yacc.c. */
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
@@ -209,17 +230,94 @@ typedef union YYSTYPE {
/* Copy the second part of user declarations. */
-/* Line 213 of yacc.c. */
+/* Line 216 of yacc.c. */
+
+
+#ifdef short
+# undef short
+#endif
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
-# ifndef YYFREE
-# define YYFREE free
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
+# ifndef YY_
+# define YY_(msgid) msgid
# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -227,34 +325,76 @@ typedef union YYSTYPE {
# if YYSTACK_USE_ALLOCA
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
# endif
+# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-#if (! defined (yyoverflow) \
- && (! defined (__cplusplus) \
- || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short int yyss;
+ yytype_int16 yyss;
YYSTYPE yyvs;
};
@@ -264,24 +404,24 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if defined (__GNUC__) && 1 < __GNUC__
+# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
- register YYSIZE_T yyi; \
+ YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
- while (0)
+ while (YYID (0))
# endif
# endif
@@ -299,39 +439,33 @@ union yyalloc
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
- while (0)
+ while (YYID (0))
#endif
-#if defined (__STDC__) || defined (__cplusplus)
- typedef signed char yysigned_char;
-#else
- typedef short int yysigned_char;
-#endif
-
-/* YYFINAL -- State number of the termination state. */
+/* YYFINAL -- State number of the termination state. */
#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 264
+#define YYLAST 258
-/* YYNTOKENS -- Number of terminals. */
+/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 35
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 42
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 104
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 175
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 45
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 108
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 178
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 289
-#define YYTRANSLATE(YYX) \
+#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
+static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -367,102 +501,103 @@ static const unsigned char yytranslate[] =
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned short int yyprhs[] =
+static const yytype_uint16 yyprhs[] =
{
0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
- 81, 84, 85, 88, 91, 94, 97, 100, 104, 109,
- 114, 119, 125, 128, 131, 133, 137, 138, 141, 144,
- 147, 150, 153, 158, 162, 165, 170, 171, 174, 178,
- 180, 184, 185, 188, 191, 194, 198, 201, 203, 207,
- 208, 211, 214, 217, 221, 225, 228, 231, 234, 235,
- 238, 241, 244, 249, 253, 257, 258, 261, 263, 265,
- 268, 271, 274, 276, 279, 280, 283, 285, 289, 293,
- 297, 300, 304, 308, 310
+ 81, 84, 85, 88, 91, 94, 97, 100, 103, 107,
+ 112, 117, 122, 128, 132, 133, 137, 138, 141, 144,
+ 147, 149, 153, 154, 157, 160, 163, 166, 169, 174,
+ 178, 181, 186, 187, 190, 194, 196, 200, 201, 204,
+ 207, 210, 214, 217, 219, 223, 224, 227, 230, 233,
+ 237, 241, 244, 247, 250, 251, 254, 257, 260, 265,
+ 266, 269, 271, 273, 276, 279, 282, 284, 287, 288,
+ 291, 293, 297, 301, 305, 308, 312, 316, 318
};
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
{
36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
- 50, -1, 37, 61, -1, 37, 3, 71, 73, -1,
- 37, 72, -1, 37, 25, 1, 30, -1, 37, 38,
- 1, 30, -1, 37, 1, 30, -1, 16, -1, 19,
- -1, 20, -1, 22, -1, 18, -1, 23, -1, 21,
- -1, 30, -1, 56, -1, 65, -1, 42, -1, 44,
- -1, 63, -1, 25, 1, 30, -1, 1, 30, -1,
+ 53, -1, 37, 64, -1, 37, 3, 74, 76, -1,
+ 37, 75, -1, 37, 25, 1, 30, -1, 37, 38,
+ 1, 30, -1, 37, 1, 30, -1, 16, -1, 18,
+ -1, 19, -1, 21, -1, 17, -1, 22, -1, 20,
+ -1, 30, -1, 59, -1, 68, -1, 42, -1, 44,
+ -1, 66, -1, 25, 1, 30, -1, 1, 30, -1,
10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
- -1, 43, 45, -1, -1, 45, 46, -1, 45, 69,
- -1, 45, 67, -1, 45, 40, -1, 45, 30, -1,
- 20, 70, 30, -1, 19, 71, 74, 30, -1, 21,
- 75, 74, 30, -1, 22, 25, 74, 30, -1, 23,
- 76, 76, 74, 30, -1, 7, 30, -1, 47, 51,
- -1, 72, -1, 48, 53, 49, -1, -1, 51, 52,
- -1, 51, 69, -1, 51, 67, -1, 51, 30, -1,
- 51, 40, -1, 19, 71, 74, 30, -1, 20, 70,
- 30, -1, 18, 30, -1, 21, 25, 74, 30, -1,
- -1, 53, 39, -1, 14, 75, 73, -1, 72, -1,
- 54, 57, 55, -1, -1, 57, 39, -1, 57, 61,
- -1, 57, 50, -1, 4, 71, 30, -1, 58, 68,
- -1, 72, -1, 59, 62, 60, -1, -1, 62, 39,
- -1, 62, 61, -1, 62, 50, -1, 6, 71, 30,
- -1, 9, 71, 30, -1, 64, 68, -1, 12, 30,
- -1, 66, 13, -1, -1, 68, 69, -1, 68, 30,
- -1, 68, 40, -1, 16, 24, 75, 30, -1, 16,
- 75, 30, -1, 17, 75, 30, -1, -1, 71, 74,
- -1, 25, -1, 26, -1, 5, 30, -1, 8, 30,
- -1, 15, 30, -1, 30, -1, 73, 30, -1, -1,
- 14, 75, -1, 76, -1, 76, 33, 76, -1, 76,
- 27, 76, -1, 29, 75, 28, -1, 34, 75, -1,
- 75, 31, 75, -1, 75, 32, 75, -1, 25, -1,
- 26, -1
+ -1, 43, 45, -1, -1, 45, 46, -1, 45, 47,
+ -1, 45, 72, -1, 45, 70, -1, 45, 40, -1,
+ 45, 30, -1, 19, 73, 30, -1, 18, 74, 77,
+ 30, -1, 20, 78, 77, 30, -1, 21, 25, 77,
+ 30, -1, 22, 79, 79, 77, 30, -1, 23, 48,
+ 30, -1, -1, 48, 25, 49, -1, -1, 33, 74,
+ -1, 7, 30, -1, 50, 54, -1, 75, -1, 51,
+ 56, 52, -1, -1, 54, 55, -1, 54, 72, -1,
+ 54, 70, -1, 54, 30, -1, 54, 40, -1, 18,
+ 74, 77, 30, -1, 19, 73, 30, -1, 17, 30,
+ -1, 20, 25, 77, 30, -1, -1, 56, 39, -1,
+ 14, 78, 76, -1, 75, -1, 57, 60, 58, -1,
+ -1, 60, 39, -1, 60, 64, -1, 60, 53, -1,
+ 4, 74, 30, -1, 61, 71, -1, 75, -1, 62,
+ 65, 63, -1, -1, 65, 39, -1, 65, 64, -1,
+ 65, 53, -1, 6, 74, 30, -1, 9, 74, 30,
+ -1, 67, 71, -1, 12, 30, -1, 69, 13, -1,
+ -1, 71, 72, -1, 71, 30, -1, 71, 40, -1,
+ 16, 24, 78, 30, -1, -1, 74, 77, -1, 25,
+ -1, 26, -1, 5, 30, -1, 8, 30, -1, 15,
+ 30, -1, 30, -1, 76, 30, -1, -1, 14, 78,
+ -1, 79, -1, 79, 33, 79, -1, 79, 27, 79,
+ -1, 29, 78, 28, -1, 34, 78, -1, 78, 31,
+ 78, -1, 78, 32, 78, -1, 25, -1, 26, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short int yyrline[] =
+static const yytype_uint16 yyrline[] =
{
- 0, 103, 103, 105, 107, 108, 109, 110, 111, 112,
- 113, 117, 121, 121, 121, 121, 121, 121, 121, 125,
- 126, 127, 128, 129, 130, 134, 135, 141, 149, 155,
- 163, 173, 175, 176, 177, 178, 179, 182, 190, 196,
- 206, 212, 220, 229, 234, 242, 245, 247, 248, 249,
- 250, 251, 254, 260, 271, 277, 287, 289, 294, 302,
- 310, 313, 315, 316, 317, 322, 329, 334, 342, 345,
- 347, 348, 349, 352, 360, 367, 374, 380, 387, 389,
- 390, 391, 394, 399, 404, 412, 414, 419, 420, 423,
- 424, 425, 429, 430, 433, 434, 437, 438, 439, 440,
- 441, 442, 443, 446, 447
+ 0, 104, 104, 106, 108, 109, 110, 111, 112, 113,
+ 114, 118, 122, 122, 122, 122, 122, 122, 122, 126,
+ 127, 128, 129, 130, 131, 135, 136, 142, 150, 156,
+ 164, 174, 176, 177, 178, 179, 180, 181, 184, 192,
+ 198, 208, 214, 220, 223, 225, 236, 237, 242, 251,
+ 256, 264, 267, 269, 270, 271, 272, 273, 276, 282,
+ 293, 299, 309, 311, 316, 324, 332, 335, 337, 338,
+ 339, 344, 351, 356, 364, 367, 369, 370, 371, 374,
+ 382, 389, 396, 402, 409, 411, 412, 413, 416, 424,
+ 426, 431, 432, 435, 436, 437, 441, 442, 445, 446,
+ 449, 450, 451, 452, 453, 454, 455, 458, 459
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
"T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
"T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
- "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
- "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+ "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
+ "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
"T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
"T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
"option_error", "config_entry_start", "config_stmt",
"menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
- "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
- "choice_option_list", "choice_option", "choice_block", "if_entry",
- "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end",
- "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt",
- "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
- "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
+ "config_option", "symbol_option", "symbol_option_list",
+ "symbol_option_arg", "choice", "choice_entry", "choice_end",
+ "choice_stmt", "choice_option_list", "choice_option", "choice_block",
+ "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry",
+ "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment",
+ "comment_stmt", "help_start", "help", "depends_list", "depends",
+ "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
};
#endif
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short int yytoknum[] =
+static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
@@ -472,214 +607,196 @@ static const unsigned short int yytoknum[] =
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const unsigned char yyr1[] =
+static const yytype_uint8 yyr1[] =
{
0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
- 44, 45, 45, 45, 45, 45, 45, 46, 46, 46,
- 46, 46, 47, 48, 49, 50, 51, 51, 51, 51,
- 51, 51, 52, 52, 52, 52, 53, 53, 54, 55,
- 56, 57, 57, 57, 57, 58, 59, 60, 61, 62,
- 62, 62, 62, 63, 64, 65, 66, 67, 68, 68,
- 68, 68, 69, 69, 69, 70, 70, 71, 71, 72,
- 72, 72, 73, 73, 74, 74, 75, 75, 75, 75,
- 75, 75, 75, 76, 76
+ 44, 45, 45, 45, 45, 45, 45, 45, 46, 46,
+ 46, 46, 46, 47, 48, 48, 49, 49, 50, 51,
+ 52, 53, 54, 54, 54, 54, 54, 54, 55, 55,
+ 55, 55, 56, 56, 57, 58, 59, 60, 60, 60,
+ 60, 61, 62, 63, 64, 65, 65, 65, 65, 66,
+ 67, 68, 69, 70, 71, 71, 71, 71, 72, 73,
+ 73, 74, 74, 75, 75, 75, 76, 76, 77, 77,
+ 78, 78, 78, 78, 78, 78, 78, 79, 79
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const unsigned char yyr2[] =
+static const yytype_uint8 yyr2[] =
{
0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
- 2, 0, 2, 2, 2, 2, 2, 3, 4, 4,
- 4, 5, 2, 2, 1, 3, 0, 2, 2, 2,
- 2, 2, 4, 3, 2, 4, 0, 2, 3, 1,
- 3, 0, 2, 2, 2, 3, 2, 1, 3, 0,
- 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
- 2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
- 2, 2, 1, 2, 0, 2, 1, 3, 3, 3,
- 2, 3, 3, 1, 1
+ 2, 0, 2, 2, 2, 2, 2, 2, 3, 4,
+ 4, 4, 5, 3, 0, 3, 0, 2, 2, 2,
+ 1, 3, 0, 2, 2, 2, 2, 2, 4, 3,
+ 2, 4, 0, 2, 3, 1, 3, 0, 2, 2,
+ 2, 3, 2, 1, 3, 0, 2, 2, 2, 3,
+ 3, 2, 2, 2, 0, 2, 2, 2, 4, 0,
+ 2, 1, 1, 2, 2, 2, 1, 2, 0, 2,
+ 1, 3, 3, 3, 2, 3, 3, 1, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
-static const unsigned char yydefact[] =
+static const yytype_uint8 yydefact[] =
{
3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
- 23, 46, 56, 5, 61, 20, 78, 69, 6, 24,
- 78, 21, 8, 11, 87, 88, 0, 0, 89, 0,
- 42, 90, 0, 0, 0, 103, 104, 0, 0, 0,
- 96, 91, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 92, 7, 65, 73, 74, 27, 29, 0,
- 100, 0, 0, 58, 0, 0, 9, 10, 0, 0,
- 0, 0, 0, 85, 0, 0, 0, 0, 36, 35,
- 32, 0, 34, 33, 0, 0, 85, 0, 50, 51,
- 47, 49, 48, 57, 45, 44, 62, 64, 60, 63,
- 59, 80, 81, 79, 70, 72, 68, 71, 67, 93,
- 99, 101, 102, 98, 97, 26, 76, 0, 0, 0,
- 94, 0, 94, 94, 94, 0, 0, 77, 54, 94,
- 0, 94, 0, 83, 84, 0, 0, 37, 86, 0,
- 0, 94, 25, 0, 53, 0, 82, 95, 38, 39,
- 40, 0, 52, 55, 41
+ 23, 52, 62, 5, 67, 20, 84, 75, 6, 24,
+ 84, 21, 8, 11, 91, 92, 0, 0, 93, 0,
+ 48, 94, 0, 0, 0, 107, 108, 0, 0, 0,
+ 100, 95, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 96, 7, 71, 79, 80, 27, 29, 0,
+ 104, 0, 0, 64, 0, 0, 9, 10, 0, 0,
+ 0, 0, 89, 0, 0, 0, 44, 0, 37, 36,
+ 32, 33, 0, 35, 34, 0, 0, 89, 0, 56,
+ 57, 53, 55, 54, 63, 51, 50, 68, 70, 66,
+ 69, 65, 86, 87, 85, 76, 78, 74, 77, 73,
+ 97, 103, 105, 106, 102, 101, 26, 82, 0, 98,
+ 0, 98, 98, 98, 0, 0, 0, 83, 60, 98,
+ 0, 98, 0, 0, 0, 38, 90, 0, 0, 98,
+ 46, 43, 25, 0, 59, 0, 88, 99, 39, 40,
+ 41, 0, 0, 45, 58, 61, 42, 47
};
-/* YYDEFGOTO[NTERM-NUM]. */
-static const short int yydefgoto[] =
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
{
-1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
- 64, 100, 31, 32, 114, 33, 66, 110, 67, 34,
- 118, 35, 68, 36, 37, 126, 38, 70, 39, 40,
- 41, 101, 102, 69, 103, 141, 142, 42, 73, 156,
- 59, 60
+ 64, 100, 101, 145, 173, 31, 32, 115, 33, 66,
+ 111, 67, 34, 119, 35, 68, 36, 37, 127, 38,
+ 70, 39, 40, 41, 102, 103, 69, 104, 140, 141,
+ 42, 73, 154, 59, 60
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
#define YYPACT_NINF -78
-static const short int yypact[] =
+static const yytype_int16 yypact[] =
{
- -78, 2, 159, -78, -21, 0, 0, -12, 0, 1,
- 4, 0, 27, 38, 60, 58, -78, -78, -78, -78,
- -78, -78, -78, 100, -78, 104, -78, -78, -78, -78,
+ -78, 33, 130, -78, -28, 73, 73, 7, 73, 36,
+ 41, 73, 26, 52, -4, 58, -78, -78, -78, -78,
+ -78, -78, -78, 90, -78, 94, -78, -78, -78, -78,
-78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, 86, 113, -78, 114,
- -78, -78, 125, 127, 128, -78, -78, 60, 60, 210,
- 65, -78, 141, 142, 39, 103, 182, 200, 6, 66,
- 6, 131, -78, 146, -78, -78, -78, -78, -78, 196,
- -78, 60, 60, 146, 40, 40, -78, -78, 155, 156,
- -2, 60, 0, 0, 60, 105, 40, 194, -78, -78,
- -78, 206, -78, -78, 183, 0, 0, 195, -78, -78,
+ -78, -78, -78, -78, -78, -78, 74, 85, -78, 96,
+ -78, -78, 131, 134, 147, -78, -78, -4, -4, 193,
+ -10, -78, 162, 164, 38, 102, 64, 148, 5, 192,
+ 5, 165, -78, 174, -78, -78, -78, -78, -78, 65,
+ -78, -4, -4, 174, 103, 103, -78, -78, 175, 185,
+ 197, 73, 73, -4, 194, 103, -78, 231, -78, -78,
+ -78, -78, 220, -78, -78, 204, 73, 73, 210, -78,
-78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
-78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, 197, -78, -78, -78, -78, -78, 60, 213, 216,
- 212, 203, 212, 190, 212, 40, 208, -78, -78, 212,
- 222, 212, 219, -78, -78, 60, 223, -78, -78, 224,
- 225, 212, -78, 226, -78, 227, -78, 47, -78, -78,
- -78, 228, -78, -78, -78
+ -78, -78, 205, -78, -78, -78, -78, -78, -4, 222,
+ 208, 222, 195, 222, 103, 2, 209, -78, -78, 222,
+ 211, 222, 199, -4, 212, -78, -78, 213, 214, 222,
+ 207, -78, -78, 215, -78, 216, -78, 111, -78, -78,
+ -78, 217, 73, -78, -78, -78, -78, -78
};
/* YYPGOTO[NTERM-NUM]. */
-static const short int yypgoto[] =
+static const yytype_int16 yypgoto[] =
{
- -78, -78, -78, -78, 164, -36, -78, -78, -78, -78,
- 230, -78, -78, -78, -78, 29, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, 59, -78, -78, -78,
- -78, -78, 198, 220, 24, 157, -5, 169, 202, 74,
- -53, -77
+ -78, -78, -78, -78, 121, -35, -78, -78, -78, -78,
+ 219, -78, -78, -78, -78, -78, -78, -78, -44, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -6,
+ -78, -78, -78, -78, -78, 183, 218, 21, 143, -5,
+ 146, 196, 69, -53, -77
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -76
-static const short int yytable[] =
+#define YYTABLE_NINF -82
+static const yytype_int16 yytable[] =
{
- 46, 47, 3, 49, 79, 80, 52, 133, 134, 43,
- 6, 7, 8, 9, 10, 11, 12, 13, 48, 145,
- 14, 15, 137, 55, 56, 44, 45, 57, 131, 132,
- 109, 50, 58, 122, 51, 122, 24, 138, 139, -28,
- 88, 143, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, 89, 53, -28, -28, 90, 91, -28, 92, 93,
- 94, 95, 96, 54, 97, 55, 56, 88, 161, 98,
- -66, -66, -66, -66, -66, -66, -66, -66, 81, 82,
- -66, -66, 90, 91, 152, 55, 56, 140, 61, 57,
- 112, 97, 84, 123, 58, 123, 121, 117, 85, 125,
- 149, 62, 167, -30, 88, 63, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, 89, 72, -30, -30, 90,
- 91, -30, 92, 93, 94, 95, 96, 119, 97, 127,
- 144, -75, 88, 98, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, 74, 75, -75, -75, 90, 91, -75,
- -75, -75, -75, -75, -75, 76, 97, 77, 78, -2,
- 4, 121, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 86, 87, 14, 15, 16, 129, 17, 18, 19,
- 20, 21, 22, 88, 23, 135, 136, -43, -43, 24,
- -43, -43, -43, -43, 89, 146, -43, -43, 90, 91,
- 104, 105, 106, 107, 155, 7, 8, 97, 10, 11,
- 12, 13, 108, 148, 14, 15, 158, 159, 160, 147,
- 151, 81, 82, 163, 130, 165, 155, 81, 82, 82,
- 24, 113, 116, 157, 124, 171, 115, 120, 162, 128,
- 72, 81, 82, 153, 81, 82, 154, 81, 82, 166,
- 81, 82, 164, 168, 169, 170, 172, 173, 174, 65,
- 71, 83, 0, 150, 111
+ 46, 47, 43, 49, 79, 80, 52, 134, 135, 6,
+ 7, 8, 9, 10, 11, 12, 13, 84, 144, 14,
+ 15, 55, 56, 85, 118, 57, 126, 160, 132, 133,
+ 58, 110, 161, 3, 123, 24, 123, 48, -28, 88,
+ 142, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ 89, 53, -28, -28, 90, -28, 91, 92, 93, 94,
+ 95, 96, 120, 97, 128, 88, 50, 159, 98, -49,
+ -49, 51, -49, -49, -49, -49, 89, 54, -49, -49,
+ 90, 105, 106, 107, 108, 152, 139, 113, 61, 97,
+ 124, 62, 124, 131, 109, 63, 81, 82, 44, 45,
+ 167, 149, -30, 88, 72, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, 89, 74, -30, -30, 90, -30,
+ 91, 92, 93, 94, 95, 96, 75, 97, 55, 56,
+ -2, 4, 98, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 81, 82, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 7, 8, 23, 10, 11, 12, 13,
+ 24, 76, 14, 15, 77, -81, 88, 177, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, 78, 24, -81,
+ -81, 90, -81, -81, -81, -81, -81, -81, 114, 117,
+ 97, 125, 86, 88, 87, 122, -72, -72, -72, -72,
+ -72, -72, -72, -72, 130, 136, -72, -72, 90, 153,
+ 156, 157, 158, 116, 121, 137, 129, 97, 163, 143,
+ 165, 138, 122, 72, 81, 82, 81, 82, 171, 166,
+ 81, 82, 146, 147, 148, 151, 153, 82, 155, 162,
+ 172, 164, 168, 169, 170, 174, 175, 176, 65, 112,
+ 150, 0, 0, 0, 0, 83, 0, 0, 71
};
-static const short int yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 5, 6, 0, 8, 57, 58, 11, 84, 85, 30,
- 4, 5, 6, 7, 8, 9, 10, 11, 30, 96,
- 14, 15, 24, 25, 26, 25, 26, 29, 81, 82,
- 66, 30, 34, 69, 30, 71, 30, 90, 91, 0,
- 1, 94, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 25, 25, 25, 26, 1, 145, 30,
- 4, 5, 6, 7, 8, 9, 10, 11, 31, 32,
- 14, 15, 16, 17, 137, 25, 26, 92, 30, 29,
- 66, 25, 27, 69, 34, 71, 30, 68, 33, 70,
- 105, 1, 155, 0, 1, 1, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 30, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 68, 25, 70,
- 25, 0, 1, 30, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 30, 30, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 30, 25, 30, 30, 0,
- 1, 30, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 30, 30, 14, 15, 16, 30, 18, 19, 20,
- 21, 22, 23, 1, 25, 30, 30, 5, 6, 30,
- 8, 9, 10, 11, 12, 1, 14, 15, 16, 17,
- 18, 19, 20, 21, 14, 5, 6, 25, 8, 9,
- 10, 11, 30, 30, 14, 15, 142, 143, 144, 13,
- 25, 31, 32, 149, 28, 151, 14, 31, 32, 32,
- 30, 67, 68, 30, 70, 161, 67, 68, 30, 70,
- 30, 31, 32, 30, 31, 32, 30, 31, 32, 30,
- 31, 32, 30, 30, 30, 30, 30, 30, 30, 29,
- 40, 59, -1, 106, 66
+ 5, 6, 30, 8, 57, 58, 11, 84, 85, 4,
+ 5, 6, 7, 8, 9, 10, 11, 27, 95, 14,
+ 15, 25, 26, 33, 68, 29, 70, 25, 81, 82,
+ 34, 66, 30, 0, 69, 30, 71, 30, 0, 1,
+ 93, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 25, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 68, 25, 70, 1, 30, 144, 30, 5,
+ 6, 30, 8, 9, 10, 11, 12, 25, 14, 15,
+ 16, 17, 18, 19, 20, 138, 91, 66, 30, 25,
+ 69, 1, 71, 28, 30, 1, 31, 32, 25, 26,
+ 153, 106, 0, 1, 30, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 30, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 30, 25, 25, 26,
+ 0, 1, 30, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 31, 32, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 5, 6, 25, 8, 9, 10, 11,
+ 30, 30, 14, 15, 30, 0, 1, 172, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 30, 30, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 67, 68,
+ 25, 70, 30, 1, 30, 30, 4, 5, 6, 7,
+ 8, 9, 10, 11, 30, 30, 14, 15, 16, 14,
+ 141, 142, 143, 67, 68, 30, 70, 25, 149, 25,
+ 151, 24, 30, 30, 31, 32, 31, 32, 159, 30,
+ 31, 32, 1, 13, 30, 25, 14, 32, 30, 30,
+ 33, 30, 30, 30, 30, 30, 30, 30, 29, 66,
+ 107, -1, -1, -1, -1, 59, -1, -1, 40
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
-static const unsigned char yystos[] =
+static const yytype_uint8 yystos[] =
{
0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 14, 15, 16, 18, 19, 20,
- 21, 22, 23, 25, 30, 38, 39, 41, 42, 43,
- 44, 47, 48, 50, 54, 56, 58, 59, 61, 63,
- 64, 65, 72, 30, 25, 26, 71, 71, 30, 71,
- 30, 30, 71, 25, 25, 25, 26, 29, 34, 75,
- 76, 30, 1, 1, 45, 45, 51, 53, 57, 68,
- 62, 68, 30, 73, 30, 30, 30, 30, 30, 75,
- 75, 31, 32, 73, 27, 33, 30, 30, 1, 12,
- 16, 17, 19, 20, 21, 22, 23, 25, 30, 40,
- 46, 66, 67, 69, 18, 19, 20, 21, 30, 40,
- 52, 67, 69, 39, 49, 72, 39, 50, 55, 61,
- 72, 30, 40, 69, 39, 50, 60, 61, 72, 30,
- 28, 75, 75, 76, 76, 30, 30, 24, 75, 75,
- 71, 70, 71, 75, 25, 76, 1, 13, 30, 71,
- 70, 25, 75, 30, 30, 14, 74, 30, 74, 74,
- 74, 76, 30, 74, 30, 74, 30, 75, 30, 30,
- 30, 74, 30, 30, 30
+ 8, 9, 10, 11, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 25, 30, 38, 39, 41, 42, 43,
+ 44, 50, 51, 53, 57, 59, 61, 62, 64, 66,
+ 67, 68, 75, 30, 25, 26, 74, 74, 30, 74,
+ 30, 30, 74, 25, 25, 25, 26, 29, 34, 78,
+ 79, 30, 1, 1, 45, 45, 54, 56, 60, 71,
+ 65, 71, 30, 76, 30, 30, 30, 30, 30, 78,
+ 78, 31, 32, 76, 27, 33, 30, 30, 1, 12,
+ 16, 18, 19, 20, 21, 22, 23, 25, 30, 40,
+ 46, 47, 69, 70, 72, 17, 18, 19, 20, 30,
+ 40, 55, 70, 72, 39, 52, 75, 39, 53, 58,
+ 64, 75, 30, 40, 72, 39, 53, 63, 64, 75,
+ 30, 28, 78, 78, 79, 79, 30, 30, 24, 74,
+ 73, 74, 78, 25, 79, 48, 1, 13, 30, 74,
+ 73, 25, 78, 14, 77, 30, 77, 77, 77, 79,
+ 25, 30, 30, 77, 30, 77, 30, 78, 30, 30,
+ 30, 77, 33, 49, 30, 30, 30, 74
};
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
-#endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
-#endif
-
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
@@ -705,15 +822,15 @@ do \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
+ YYPOPSTACK (1); \
goto yybackup; \
} \
else \
- { \
- yyerror ("syntax error: cannot back up");\
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
-while (0)
+while (YYID (0))
#define YYTERROR 1
@@ -728,7 +845,7 @@ while (0)
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
- if (N) \
+ if (YYID (N)) \
{ \
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
@@ -742,7 +859,7 @@ while (0)
(Current).first_column = (Current).last_column = \
YYRHSLOC (Rhs, 0).last_column; \
} \
- while (0)
+ while (YYID (0))
#endif
@@ -754,8 +871,8 @@ while (0)
# if YYLTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
@@ -782,36 +899,96 @@ while (0)
do { \
if (yydebug) \
YYFPRINTF Args; \
-} while (0)
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included). |
`------------------------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
yy_stack_print (bottom, top)
- short int *bottom;
- short int *top;
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (/* Nothing. */; bottom <= top; ++bottom)
+ for (; bottom <= top; ++bottom)
YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -820,37 +997,45 @@ yy_stack_print (bottom, top)
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
-} while (0)
+} while (YYID (0))
/*------------------------------------------------.
| Report that the YYRULE is going to be reduced. |
`------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
#else
static void
-yy_reduce_print (yyrule)
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
int yyrule;
#endif
{
+ int yynrhs = yyr2[yyrule];
int yyi;
- unsigned int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
- yyrule - 1, yylno);
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (Rule); \
-} while (0)
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -872,7 +1057,7 @@ int yydebug;
if the built-in stack extension method is used).
Do not make this value too large; the results are undefined if
- SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
#ifndef YYMAXDEPTH
@@ -884,45 +1069,47 @@ int yydebug;
#if YYERROR_VERBOSE
# ifndef yystrlen
-# if defined (__GLIBC__) && defined (_STRING_H)
+# if defined __GLIBC__ && defined _STRING_H
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
-# if defined (__STDC__) || defined (__cplusplus)
yystrlen (const char *yystr)
-# else
+#else
+static YYSIZE_T
yystrlen (yystr)
- const char *yystr;
-# endif
+ const char *yystr;
+#endif
{
- register const char *yys = yystr;
-
- while (*yys++ != '\0')
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
continue;
-
- return yys - yystr - 1;
+ return yylen;
}
# endif
# endif
# ifndef yystpcpy
-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
# define yystpcpy stpcpy
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static char *
-# if defined (__STDC__) || defined (__cplusplus)
yystpcpy (char *yydest, const char *yysrc)
-# else
+#else
+static char *
yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-# endif
+ char *yydest;
+ const char *yysrc;
+#endif
{
- register char *yyd = yydest;
- register const char *yys = yysrc;
+ char *yyd = yydest;
+ const char *yys = yysrc;
while ((*yyd++ = *yys++) != '\0')
continue;
@@ -932,53 +1119,171 @@ yystpcpy (yydest, yysrc)
# endif
# endif
-#endif /* !YYERROR_VERBOSE */
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
-
+ if (! yyres)
+ return yystrlen (yystr);
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ int yyn = yypact[yystate];
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
-
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- switch (yytype)
{
- default:
- break;
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
}
- YYFPRINTF (yyoutput, ")");
}
+#endif /* YYERROR_VERBOSE */
+
-#endif /* ! YYDEBUG */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
@@ -989,8 +1294,7 @@ yydestruct (yymsg, yytype, yyvaluep)
YYSTYPE *yyvaluep;
#endif
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ YYUSE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
@@ -998,39 +1302,39 @@ yydestruct (yymsg, yytype, yyvaluep)
switch (yytype)
{
- case 48: /* choice_entry */
+ case 51: /* "choice_entry" */
- {
+ {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
if (current_menu == (yyvaluep->menu))
menu_end_menu();
};
- break;
- case 54: /* if_entry */
+ break;
+ case 57: /* "if_entry" */
- {
+ {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
if (current_menu == (yyvaluep->menu))
menu_end_menu();
};
- break;
- case 59: /* menu_entry */
+ break;
+ case 62: /* "menu_entry" */
- {
+ {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
if (current_menu == (yyvaluep->menu))
menu_end_menu();
};
- break;
+ break;
default:
- break;
+ break;
}
}
@@ -1038,13 +1342,13 @@ yydestruct (yymsg, yytype, yyvaluep)
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
-# else
+#else
int yyparse ();
-# endif
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
@@ -1069,14 +1373,18 @@ int yynerrs;
`----------*/
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-# endif
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
#else
@@ -1086,14 +1394,20 @@ yyparse ()
#endif
#endif
{
-
- register int yystate;
- register int yyn;
+
+ int yystate;
+ int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
/* Three stacks and their tools:
`yyss': related to states,
@@ -1104,18 +1418,18 @@ yyparse ()
to reallocate them elsewhere. */
/* The state stack. */
- short int yyssa[YYINITDEPTH];
- short int *yyss = yyssa;
- register short int *yyssp;
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
- register YYSTYPE *yyvsp;
+ YYSTYPE *yyvsp;
-#define YYPOPSTACK (yyvsp--, yyssp--)
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
YYSIZE_T yystacksize = YYINITDEPTH;
@@ -1124,9 +1438,9 @@ yyparse ()
YYSTYPE yyval;
- /* When reducing, the number of symbols on the RHS of the reduced
- rule. */
- int yylen;
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1143,9 +1457,6 @@ yyparse ()
yyssp = yyss;
yyvsp = yyvs;
-
- yyvsp[0] = yylval;
-
goto yysetstate;
/*------------------------------------------------------------.
@@ -1153,8 +1464,7 @@ yyparse ()
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks.
- */
+ have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
yysetstate:
@@ -1167,18 +1477,18 @@ yyparse ()
#ifdef yyoverflow
{
- /* Give user a chance to reallocate the stack. Use copies of
+ /* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
+ yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
@@ -1189,21 +1499,21 @@ yyparse ()
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
- goto yyoverflowlab;
+ goto yyexhaustedlab;
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyoverflowlab;
+ goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
- goto yyoverflowlab;
+ goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
@@ -1234,12 +1544,10 @@ yyparse ()
`-----------*/
yybackup:
-/* Do appropriate processing given the current state. */
-/* Read a look-ahead token if we need one and don't already have one. */
-/* yyresume: */
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
-
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
@@ -1281,22 +1589,21 @@ yybackup:
if (yyn == YYFINAL)
YYACCEPT;
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
/* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the token being shifted unless it is eof. */
+ /* Discard the shifted token unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
+ yystate = yyn;
*++yyvsp = yylval;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- yystate = yyn;
goto yynewstate;
@@ -1338,13 +1645,13 @@ yyreduce:
case 9:
- { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
+ { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;}
break;
case 10:
{
- zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+ zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name);
;}
break;
@@ -1355,7 +1662,7 @@ yyreduce:
case 25:
- { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
+ { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
break;
case 26:
@@ -1366,10 +1673,10 @@ yyreduce:
case 27:
{
- struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+ struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
;}
break;
@@ -1384,10 +1691,10 @@ yyreduce:
case 29:
{
- struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+ struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
;}
break;
@@ -1403,53 +1710,75 @@ yyreduce:
;}
break;
- case 37:
+ case 38:
{
- menu_set_type((yyvsp[-2].id)->stype);
+ menu_set_type((yyvsp[(1) - (3)].id)->stype);
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
zconf_curname(), zconf_lineno(),
- (yyvsp[-2].id)->stype);
+ (yyvsp[(1) - (3)].id)->stype);
;}
break;
- case 38:
+ case 39:
{
- menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+ menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
- case 39:
+ case 40:
{
- menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
- if ((yyvsp[-3].id)->stype != S_UNKNOWN)
- menu_set_type((yyvsp[-3].id)->stype);
+ menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
+ if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN)
+ menu_set_type((yyvsp[(1) - (4)].id)->stype);
printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
zconf_curname(), zconf_lineno(),
- (yyvsp[-3].id)->stype);
+ (yyvsp[(1) - (4)].id)->stype);
;}
break;
- case 40:
+ case 41:
{
- menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+ menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
;}
break;
- case 41:
+ case 42:
{
- menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
;}
break;
- case 42:
+ case 45:
+
+ {
+ struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
+ if (id && id->flags & TF_OPTION)
+ menu_add_option(id->token, (yyvsp[(3) - (3)].string));
+ else
+ zconfprint("warning: ignoring unknown option %s", (yyvsp[(2) - (3)].string));
+ free((yyvsp[(2) - (3)].string));
+;}
+ break;
+
+ case 46:
+
+ { (yyval.string) = NULL; ;}
+ break;
+
+ case 47:
+
+ { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
+ break;
+
+ case 48:
{
struct symbol *sym = sym_lookup(NULL, 0);
@@ -1460,45 +1789,45 @@ yyreduce:
;}
break;
- case 43:
+ case 49:
{
(yyval.menu) = menu_add_menu();
;}
break;
- case 44:
+ case 50:
{
- if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
+ if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 52:
+ case 58:
{
- menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+ menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
- case 53:
+ case 59:
{
- if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
- menu_set_type((yyvsp[-2].id)->stype);
+ if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
+ menu_set_type((yyvsp[(1) - (3)].id)->stype);
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
zconf_curname(), zconf_lineno(),
- (yyvsp[-2].id)->stype);
+ (yyvsp[(1) - (3)].id)->stype);
} else
YYERROR;
;}
break;
- case 54:
+ case 60:
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1506,11 +1835,11 @@ yyreduce:
;}
break;
- case 55:
+ case 61:
{
- if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
- menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+ if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
+ menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:default\n",
zconf_curname(), zconf_lineno());
} else
@@ -1518,77 +1847,77 @@ yyreduce:
;}
break;
- case 58:
+ case 64:
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
- menu_add_dep((yyvsp[-1].expr));
+ menu_add_dep((yyvsp[(2) - (3)].expr));
(yyval.menu) = menu_add_menu();
;}
break;
- case 59:
+ case 65:
{
- if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
+ if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 65:
+ case 71:
{
menu_add_entry(NULL);
- menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
+ menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
;}
break;
- case 66:
+ case 72:
{
(yyval.menu) = menu_add_menu();
;}
break;
- case 67:
+ case 73:
{
- if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
+ if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 73:
+ case 79:
{
- printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
- zconf_nextfile((yyvsp[-1].string));
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
+ zconf_nextfile((yyvsp[(2) - (3)].string));
;}
break;
- case 74:
+ case 80:
{
menu_add_entry(NULL);
- menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
+ menu_add_prompt(P_COMMENT, (yyvsp[(2) - (3)].string), NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
;}
break;
- case 75:
+ case 81:
{
menu_end_entry();
;}
break;
- case 76:
+ case 82:
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1596,124 +1925,107 @@ yyreduce:
;}
break;
- case 77:
-
- {
- current_entry->sym->help = (yyvsp[0].string);
-;}
- break;
-
- case 82:
-
- {
- menu_add_dep((yyvsp[-1].expr));
- printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
case 83:
{
- menu_add_dep((yyvsp[-1].expr));
- printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+ current_entry->help = (yyvsp[(2) - (2)].string);
;}
break;
- case 84:
+ case 88:
{
- menu_add_dep((yyvsp[-1].expr));
- printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
+ menu_add_dep((yyvsp[(3) - (4)].expr));
+ printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
;}
break;
- case 86:
+ case 90:
{
- menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
+ menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
;}
break;
- case 89:
+ case 93:
- { (yyval.id) = (yyvsp[-1].id); ;}
+ { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 90:
+ case 94:
- { (yyval.id) = (yyvsp[-1].id); ;}
+ { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 91:
+ case 95:
- { (yyval.id) = (yyvsp[-1].id); ;}
+ { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 94:
+ case 98:
{ (yyval.expr) = NULL; ;}
break;
- case 95:
+ case 99:
- { (yyval.expr) = (yyvsp[0].expr); ;}
+ { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
break;
- case 96:
+ case 100:
- { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
+ { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
break;
- case 97:
+ case 101:
- { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
+ { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
break;
- case 98:
+ case 102:
- { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
+ { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
break;
- case 99:
+ case 103:
- { (yyval.expr) = (yyvsp[-1].expr); ;}
+ { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
break;
- case 100:
+ case 104:
- { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
+ { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
break;
- case 101:
+ case 105:
- { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+ { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
break;
- case 102:
+ case 106:
- { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+ { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
break;
- case 103:
+ case 107:
- { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
break;
- case 104:
+ case 108:
- { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 1); free((yyvsp[(1) - (1)].string)); ;}
break;
- }
-
-/* Line 1037 of yacc.c. */
-
-
- yyvsp -= yylen;
- yyssp -= yylen;
+/* Line 1267 of yacc.c. */
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+ YYPOPSTACK (yylen);
+ yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
@@ -1742,66 +2054,41 @@ yyerrlab:
if (!yyerrstatus)
{
++yynerrs;
-#if YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (YYPACT_NINF < yyn && yyn < YYLAST)
- {
- YYSIZE_T yysize = 0;
- int yytype = YYTRANSLATE (yychar);
- const char* yyprefix;
- char *yymsg;
- int yyx;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 0;
-
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
{
- yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
- yycount += 1;
- if (yycount == 5)
- {
- yysize = 0;
- break;
- }
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
}
- yysize += (sizeof ("syntax error, unexpected ")
- + yystrlen (yytname[yytype]));
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg != 0)
- {
- char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
- yyp = yystpcpy (yyp, yytname[yytype]);
+ }
- if (yycount < 5)
- {
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- yyp = yystpcpy (yyp, yyprefix);
- yyp = yystpcpy (yyp, yytname[yyx]);
- yyprefix = " or ";
- }
- }
- yyerror (yymsg);
- YYSTACK_FREE (yymsg);
- }
- else
- yyerror ("syntax error; also virtual memory exhausted");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror ("syntax error");
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
}
@@ -1812,23 +2099,15 @@ yyerrlab:
error, discard it. */
if (yychar <= YYEOF)
- {
- /* If at end of input, pop the error token,
- then the rest of the stack, then return failure. */
+ {
+ /* Return failure if at end of input. */
if (yychar == YYEOF)
- for (;;)
- {
-
- YYPOPSTACK;
- if (yyssp == yyss)
- YYABORT;
- yydestruct ("Error: popping",
- yystos[*yyssp], yyvsp);
- }
- }
+ YYABORT;
+ }
else
{
- yydestruct ("Error: discarding", yytoken, &yylval);
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
yychar = YYEMPTY;
}
}
@@ -1843,15 +2122,17 @@ yyerrlab:
`---------------------------------------------------*/
yyerrorlab:
-#ifdef __GNUC__
- /* Pacify GCC when the user code never invokes YYERROR and the label
- yyerrorlab therefore never appears in user code. */
- if (0)
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
goto yyerrorlab;
-#endif
-yyvsp -= yylen;
- yyssp -= yylen;
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
@@ -1881,8 +2162,9 @@ yyerrlab1:
YYABORT;
- yydestruct ("Error: popping", yystos[yystate], yyvsp);
- YYPOPSTACK;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
@@ -1893,7 +2175,7 @@ yyerrlab1:
*++yyvsp = yylval;
- /* Shift the error token. */
+ /* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
yystate = yyn;
@@ -1911,28 +2193,43 @@ yyacceptlab:
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
- yydestruct ("Error: discarding lookahead",
- yytoken, &yylval);
- yychar = YYEMPTY;
yyresult = 1;
goto yyreturn;
#ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here. |
-`----------------------------------------------*/
-yyoverflowlab:
- yyerror ("parser stack overflow");
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
- return yyresult;
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
}
@@ -1948,8 +2245,10 @@ void conf_parse(const char *name)
sym_init();
menu_init();
- modules_sym = sym_lookup("MODULES", 0);
- rootmenu.prompt = menu_add_prompt(P_MENU, "Libpayload Configuration", NULL);
+ modules_sym = sym_lookup(NULL, 0);
+ modules_sym->type = S_BOOLEAN;
+ modules_sym->flags |= SYMBOL_AUTO;
+ rootmenu.prompt = menu_add_prompt(P_MENU, "libpayload Configuration", NULL);
#if YYDEBUG
if (getenv("ZCONF_DEBUG"))
@@ -1958,12 +2257,20 @@ void conf_parse(const char *name)
zconfparse();
if (zconfnerrs)
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);
for_all_symbols(i, sym) {
- sym_check_deps(sym);
+ if (sym_check_deps(sym))
+ zconfnerrs++;
}
-
- sym_change_count = 1;
+ if (zconfnerrs)
+ exit(1);
+ sym_set_change_count(1);
}
const char *zconf_tokenname(int token)
@@ -2106,11 +2413,11 @@ void print_symbol(FILE *out, struct menu *menu)
break;
}
}
- if (sym->help) {
- int len = strlen(sym->help);
- while (sym->help[--len] == '\n')
- sym->help[len] = 0;
- fprintf(out, " help\n%s\n", sym->help);
+ if (menu->help) {
+ int len = strlen(menu->help);
+ while (menu->help[--len] == '\n')
+ menu->help[len] = 0;
+ fprintf(out, " help\n%s\n", menu->help);
}
fputc('\n', out);
}
@@ -2170,4 +2477,3 @@ void zconfdump(FILE *out)
#include "symbol.c"
#include "menu.c"
-
diff --git a/payloads/libpayload/util/kconfig/zconf.y b/payloads/libpayload/util/kconfig/zconf.y
index ab8c1377f0..9f211e81d7 100644
--- a/payloads/libpayload/util/kconfig/zconf.y
+++ b/payloads/libpayload/util/kconfig/zconf.y
@@ -64,13 +64,13 @@ static struct menu *current_menu, *current_entry;
%token <id>T_IF
%token <id>T_ENDIF
%token <id>T_DEPENDS
-%token <id>T_REQUIRES
%token <id>T_OPTIONAL
%token <id>T_PROMPT
%token <id>T_TYPE
%token <id>T_DEFAULT
%token <id>T_SELECT
%token <id>T_RANGE
+%token <id>T_OPTION
%token <id>T_ON
%token <string> T_WORD
%token <string> T_WORD_QUOTE
@@ -91,6 +91,7 @@ static struct menu *current_menu, *current_entry;
%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",
@@ -173,6 +174,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
config_option_list:
/* empty */
| config_option_list config_option
+ | config_option_list symbol_option
| config_option_list depends
| config_option_list help
| config_option_list option_error
@@ -215,6 +217,26 @@ config_option: T_RANGE symbol symbol if_expr T_EOL
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: T_CHOICE T_EOL
@@ -379,7 +401,7 @@ help_start: T_HELP T_EOL
help: help_start T_HELPTEXT
{
- current_entry->sym->help = $2;
+ current_entry->help = $2;
};
/* depends option */
@@ -395,16 +417,6 @@ depends: T_DEPENDS T_ON expr T_EOL
{
menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
-}
- | T_DEPENDS expr T_EOL
-{
- menu_add_dep($2);
- printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
-}
- | T_REQUIRES expr T_EOL
-{
- menu_add_dep($2);
- printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
};
/* prompt statement */
@@ -458,8 +470,10 @@ void conf_parse(const char *name)
sym_init();
menu_init();
- modules_sym = sym_lookup("MODULES", 0);
- rootmenu.prompt = menu_add_prompt(P_MENU, "Libpayload Configuration", NULL);
+ modules_sym = sym_lookup(NULL, 0);
+ modules_sym->type = S_BOOLEAN;
+ modules_sym->flags |= SYMBOL_AUTO;
+ rootmenu.prompt = menu_add_prompt(P_MENU, "libpayload Configuration", NULL);
#if YYDEBUG
if (getenv("ZCONF_DEBUG"))
@@ -468,12 +482,20 @@ void conf_parse(const char *name)
zconfparse();
if (zconfnerrs)
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);
for_all_symbols(i, sym) {
- sym_check_deps(sym);
+ if (sym_check_deps(sym))
+ zconfnerrs++;
}
-
- sym_change_count = 1;
+ if (zconfnerrs)
+ exit(1);
+ sym_set_change_count(1);
}
const char *zconf_tokenname(int token)
@@ -616,11 +638,11 @@ void print_symbol(FILE *out, struct menu *menu)
break;
}
}
- if (sym->help) {
- int len = strlen(sym->help);
- while (sym->help[--len] == '\n')
- sym->help[len] = 0;
- fprintf(out, " help\n%s\n", sym->help);
+ if (menu->help) {
+ int len = strlen(menu->help);
+ while (menu->help[--len] == '\n')
+ menu->help[len] = 0;
+ fprintf(out, " help\n%s\n", menu->help);
}
fputc('\n', out);
}