mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-09 02:43:53 +08:00
Merge Official Source
This commit is contained in:
commit
5e0473f6c5
4
.gitignore
vendored
4
.gitignore
vendored
@ -16,10 +16,6 @@
|
|||||||
/overlay
|
/overlay
|
||||||
/package/feeds
|
/package/feeds
|
||||||
/package/openwrt-packages
|
/package/openwrt-packages
|
||||||
scripts/config/mconf_check
|
|
||||||
scripts/config/zconf.hash.c
|
|
||||||
scripts/config/zconf.lex.c
|
|
||||||
scripts/config/zconf.tab.c
|
|
||||||
/*.patch
|
/*.patch
|
||||||
key-build*
|
key-build*
|
||||||
*.orig
|
*.orig
|
||||||
|
@ -102,7 +102,7 @@ prepare-tmpinfo: FORCE
|
|||||||
ifneq ($(DISTRO_PKG_CONFIG),)
|
ifneq ($(DISTRO_PKG_CONFIG),)
|
||||||
scripts/config/%onf: export PATH:=$(dir $(DISTRO_PKG_CONFIG)):$(PATH)
|
scripts/config/%onf: export PATH:=$(dir $(DISTRO_PKG_CONFIG)):$(PATH)
|
||||||
endif
|
endif
|
||||||
scripts/config/%onf: CFLAGS+= -O2 $(if $(WARN_RECURSIVE_DEP),-DWARN_RECURSIVE_DEP)
|
scripts/config/%onf: CFLAGS+= -O2
|
||||||
scripts/config/%onf:
|
scripts/config/%onf:
|
||||||
@$(_SINGLE)$(SUBMAKE) -s -C scripts/config $(notdir $@) CC="$(HOSTCC_WRAPPER)"
|
@$(_SINGLE)$(SUBMAKE) -s -C scripts/config $(notdir $@) CC="$(HOSTCC_WRAPPER)"
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=iproute2
|
PKG_NAME:=iproute2
|
||||||
PKG_VERSION:=5.5.0
|
PKG_VERSION:=5.6.0
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||||
PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2
|
PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2
|
||||||
PKG_HASH:=bac543435cac208a11db44c9cc8e35aa902befef8750594654ee71941c388f7b
|
PKG_HASH:=1b5b0e25ce6e23da7526ea1da044e814ad85ba761b10dd29c2b027c056b04692
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
PKG_BUILD_DEPENDS:=iptables
|
PKG_BUILD_DEPENDS:=iptables
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/tc/Makefile
|
--- a/tc/Makefile
|
||||||
+++ b/tc/Makefile
|
+++ b/tc/Makefile
|
||||||
@@ -124,6 +124,9 @@ CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PR
|
@@ -126,6 +126,9 @@ CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PR
|
||||||
ifneq ($(IPT_LIB_DIR),)
|
ifneq ($(IPT_LIB_DIR),)
|
||||||
CFLAGS += -DIPT_LIB_DIR=\"$(IPT_LIB_DIR)\"
|
CFLAGS += -DIPT_LIB_DIR=\"$(IPT_LIB_DIR)\"
|
||||||
endif
|
endif
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/tc/Makefile
|
--- a/tc/Makefile
|
||||||
+++ b/tc/Makefile
|
+++ b/tc/Makefile
|
||||||
@@ -111,7 +111,7 @@ LDLIBS += -L. -lm
|
@@ -113,7 +113,7 @@ LDLIBS += -L. -lm
|
||||||
|
|
||||||
ifeq ($(SHARED_LIBS),y)
|
ifeq ($(SHARED_LIBS),y)
|
||||||
LDLIBS += -ldl
|
LDLIBS += -ldl
|
||||||
@ -9,7 +9,7 @@
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
TCLIB := tc_core.o
|
TCLIB := tc_core.o
|
||||||
@@ -140,7 +140,7 @@ MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc
|
@@ -142,7 +142,7 @@ MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc
|
||||||
all: tc $(TCSO)
|
all: tc $(TCSO)
|
||||||
|
|
||||||
tc: $(TCOBJ) $(LIBNETLINK) libtc.a
|
tc: $(TCOBJ) $(LIBNETLINK) libtc.a
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
libtc.a: $(TCLIB)
|
libtc.a: $(TCLIB)
|
||||||
$(QUIET_AR)$(AR) rcs $@ $^
|
$(QUIET_AR)$(AR) rcs $@ $^
|
||||||
@@ -162,6 +162,7 @@ install: all
|
@@ -164,6 +164,7 @@ install: all
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TCOBJ) $(TCLIB) libtc.a tc *.so emp_ematch.tab.h; \
|
rm -f $(TCOBJ) $(TCLIB) libtc.a tc *.so emp_ematch.tab.h; \
|
||||||
rm -f emp_ematch.tab.*
|
rm -f emp_ematch.tab.*
|
||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
q_atm.so: q_atm.c
|
q_atm.so: q_atm.c
|
||||||
$(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm
|
$(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm
|
||||||
@@ -201,4 +202,15 @@ static-syms.h: $(wildcard *.c)
|
@@ -203,4 +204,15 @@ static-syms.h: $(wildcard *.c)
|
||||||
sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
|
sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
|
||||||
done > $@
|
done > $@
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ Subject: [PATCH] add support for dropping with FAILED_POLICY
|
|||||||
if (!end || end == arg || *end || res > 255)
|
if (!end || end == arg || *end || res > 255)
|
||||||
--- a/include/uapi/linux/rtnetlink.h
|
--- a/include/uapi/linux/rtnetlink.h
|
||||||
+++ b/include/uapi/linux/rtnetlink.h
|
+++ b/include/uapi/linux/rtnetlink.h
|
||||||
@@ -242,6 +242,7 @@ enum {
|
@@ -249,6 +249,7 @@ enum {
|
||||||
RTN_THROW, /* Not in this table */
|
RTN_THROW, /* Not in this table */
|
||||||
RTN_NAT, /* Translate this address */
|
RTN_NAT, /* Translate this address */
|
||||||
RTN_XRESOLVE, /* Use external resolver */
|
RTN_XRESOLVE, /* Use external resolver */
|
||||||
|
29
scripts/config/.gitignore
vendored
29
scripts/config/.gitignore
vendored
@ -1,14 +1,15 @@
|
|||||||
#
|
*.o
|
||||||
# Generated files
|
conf*
|
||||||
#
|
!conf*.c
|
||||||
*.moc
|
!conf*.h
|
||||||
*conf-cfg
|
mconf*
|
||||||
|
!mconf*.c
|
||||||
#
|
!mconf*.h
|
||||||
# configuration programs
|
mconf_check
|
||||||
#
|
*.*.c
|
||||||
conf
|
qconf*
|
||||||
mconf
|
qconf*.moc
|
||||||
nconf
|
!qconf*.cc
|
||||||
qconf
|
!qconf*.h
|
||||||
gconf
|
!images*.c
|
||||||
|
.tmp_qtcheck
|
||||||
|
@ -1,124 +1,102 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# OpenWrt configuration targets
|
# OpenWrt configuration targets
|
||||||
|
# These targets are used from top-level makefile
|
||||||
.PHONY: clean all
|
|
||||||
all: conf mconf
|
|
||||||
clean:
|
|
||||||
rm -f *.o lxdialog/*.o *.moc $(clean-files) conf mconf qconf
|
|
||||||
|
|
||||||
clean-files :=
|
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# Variables needed by the upstream Makefile
|
# Shared Makefile for the various kconfig executables:
|
||||||
|
# conf: Used for defconfig, oldconfig and related targets
|
||||||
# Avoids displaying 'UPD mconf-cfg' in an otherwise quiet make menuconfig
|
# mconf: Used for the mconfig target.
|
||||||
kecho:=true
|
# Utilizes the lxdialog package
|
||||||
|
# qconf: Used for the xconfig target
|
||||||
CONFIG_SHELL:=$(SHELL)
|
# Based on Qt which needs to be installed to compile it
|
||||||
srctree:=.
|
|
||||||
src:=.
|
|
||||||
obj:=.
|
|
||||||
Q:=$(if $V,,@)
|
|
||||||
cmd = $(cmd_$(1))
|
|
||||||
dot-target = $(dir $@).$(notdir $@)
|
|
||||||
|
|
||||||
# taken from ../Kbuild.include
|
|
||||||
define filechk
|
|
||||||
$(Q)set -e; \
|
|
||||||
mkdir -p $(dir $@); \
|
|
||||||
trap "rm -f $(dot-target).tmp" EXIT; \
|
|
||||||
{ $(filechk_$(1)); } > $(dot-target).tmp; \
|
|
||||||
if [ ! -r $@ ] || ! cmp -s $@ $(dot-target).tmp; then \
|
|
||||||
$(kecho) ' UPD $@'; \
|
|
||||||
mv -f $(dot-target).tmp $@; \
|
|
||||||
fi
|
|
||||||
endef
|
|
||||||
|
|
||||||
### Stripped down upstream Makefile follows:
|
|
||||||
# ===========================================================================
|
|
||||||
# object files used by all kconfig flavours
|
# object files used by all kconfig flavours
|
||||||
common-objs := confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \
|
|
||||||
symbol.o util.o
|
|
||||||
|
|
||||||
$(obj)/lexer.lex.o: $(obj)/parser.tab.h
|
|
||||||
HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src)
|
|
||||||
HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src)
|
|
||||||
|
|
||||||
# conf: Used for defconfig, oldconfig and related targets
|
# Platform specific fixes
|
||||||
hostprogs-y += conf
|
#
|
||||||
conf-objs := conf.o $(common-objs)
|
# FreeBSD
|
||||||
|
|
||||||
# mconf: Used for the menuconfig target based on lxdialog
|
check_lxdialog = $(shell $(SHELL) $(CURDIR)/lxdialog/check-lxdialog.sh -$(1))
|
||||||
hostprogs-y += mconf
|
export CFLAGS += -DKBUILD_NO_NLS -I. $(call check_lxdialog,ccflags)
|
||||||
lxdialog := $(addprefix lxdialog/, \
|
export CXXFLAGS += -DKBUILD_NO_NLS
|
||||||
checklist.o inputbox.o menubox.o textbox.o util.o yesno.o)
|
|
||||||
mconf-objs := mconf.o $(lxdialog) $(common-objs)
|
|
||||||
|
|
||||||
HOSTLDLIBS_mconf = $(shell . $(obj)/mconf-cfg && echo $$libs)
|
conf-objs := conf.o zconf.tab.o
|
||||||
$(foreach f, mconf.o $(lxdialog), \
|
mconf-objs := mconf.o zconf.tab.o
|
||||||
$(eval HOSTCFLAGS_$f = $$(shell . $(obj)/mconf-cfg && echo $$$$cflags)))
|
|
||||||
|
|
||||||
$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg
|
|
||||||
|
|
||||||
# qconf: Used for the xconfig target based on Qt
|
|
||||||
hostprogs-y += qconf
|
|
||||||
qconf-cxxobjs := qconf.o
|
qconf-cxxobjs := qconf.o
|
||||||
qconf-objs := images.o $(common-objs)
|
qconf-objs := zconf.tab.o
|
||||||
|
|
||||||
HOSTLDLIBS_qconf = $(shell . $(obj)/qconf-cfg && echo $$libs)
|
lxdialog-objs := \
|
||||||
HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
|
lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o \
|
||||||
|
lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
|
||||||
|
|
||||||
$(obj)/qconf.o: $(obj)/qconf-cfg $(obj)/qconf.moc
|
clean-files := zconf.tab.c zconf.lex.c zconf.hash.c
|
||||||
|
# Remove qconf junk files
|
||||||
|
clean-files += $(qconf-cxxobjs) qconf.moc .tmp_qtcheck qconf
|
||||||
|
|
||||||
quiet_cmd_moc = MOC $@
|
all: conf mconf
|
||||||
cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) -i $< -o $@
|
|
||||||
|
|
||||||
$(obj)/%.moc: $(src)/%.h $(obj)/qconf-cfg
|
|
||||||
$(call cmd,moc)
|
|
||||||
|
|
||||||
# check if necessary packages are available, and configure build flags
|
|
||||||
filechk_conf_cfg = $(CONFIG_SHELL) $<
|
|
||||||
|
|
||||||
$(obj)/%conf-cfg: $(src)/%conf-cfg.sh FORCE
|
|
||||||
$(call filechk,conf_cfg)
|
|
||||||
|
|
||||||
clean-files += *conf-cfg
|
|
||||||
|
|
||||||
# ===========================================================================
|
|
||||||
# OpenWrt rules and final adjustments that need to be made after reading the
|
|
||||||
# full upstream Makefile
|
|
||||||
|
|
||||||
FORCE:
|
|
||||||
|
|
||||||
ifdef BUILD_SHIPPED_FILES
|
|
||||||
shipped-files := lexer.lex.c parser.tab.c parser.tab.h
|
|
||||||
clean-files += $(shipped-files)
|
|
||||||
|
|
||||||
.SECONDARY: $(shipped-files)
|
|
||||||
|
|
||||||
%.tab.c %.tab.h: %.y
|
|
||||||
bison -l -d -b $* $<
|
|
||||||
|
|
||||||
%.lex.c: %.l
|
|
||||||
flex -L -o$@ $<
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(foreach f, mconf.o $(lxdialog), \
|
|
||||||
$(eval $f: CFLAGS+=$$(HOSTCFLAGS_$f)))
|
|
||||||
|
|
||||||
$(obj)/lexer.lex.o: CFLAGS += $(HOSTCFLAGS_lexer.lex.o)
|
|
||||||
$(obj)/parser.tab.o: CFLAGS += $(HOSTCFLAGS_parser.tab.o)
|
|
||||||
$(obj)/qconf.o: CXXFLAGS+=$(HOSTCXXFLAGS_qconf.o)
|
|
||||||
|
|
||||||
conf: $(conf-objs)
|
conf: $(conf-objs)
|
||||||
|
mconf: $(mconf-objs) $(lxdialog-objs)
|
||||||
|
$(CC) -o $@ $^ $(call check_lxdialog,ldflags $(CC))
|
||||||
|
qconf: $(qconf-cxxobjs) $(qconf-objs)
|
||||||
|
$(CXX) -o $@ $^ $(HOSTLOADLIBES_qconf)
|
||||||
|
|
||||||
# The *conf-cfg file is used (then filtered out) as the first prerequisite to
|
clean:
|
||||||
# avoid sourcing it before the script is built, when trying to compute CFLAGS
|
rm -f *.o lxdialog/*.o $(clean-files) conf mconf
|
||||||
# for the actual first prerequisite. This avoids errors like:
|
|
||||||
# '/bin/sh: ./mconf-cfg: No such file or directory'
|
|
||||||
mconf: mconf-cfg $(mconf-objs)
|
|
||||||
$(CC) -o $@ $(filter-out mconf-cfg,$^) $(HOSTLDLIBS_mconf)
|
|
||||||
|
|
||||||
qconf: qconf-cfg $(qconf-cxxobjs) $(qconf-objs)
|
zconf.tab.o: zconf.lex.c zconf.hash.c confdata.c
|
||||||
$(CXX) -o $@ $(filter-out qconf-cfg,$^) $(HOSTLDLIBS_qconf)
|
|
||||||
|
kconfig_load.o: lkc_defs.h
|
||||||
|
|
||||||
|
zconf.tab.c: zconf.y $(wildcard zconf.tab.c_shipped)
|
||||||
|
zconf.lex.c: zconf.l $(wildcard zconf.lex.c_shipped)
|
||||||
|
zconf.hash.c: zconf.gperf $(wildcard zconf.hash.c_shipped)
|
||||||
|
|
||||||
|
%.tab.c: %.y
|
||||||
|
cp $@_shipped $@ || bison -l -b $* -p $(notdir $*) $<
|
||||||
|
|
||||||
|
%.lex.c: %.l
|
||||||
|
cp $@_shipped $@ || flex -L -P$(notdir $*) -o$@ $<
|
||||||
|
|
||||||
|
%.hash.c: %.gperf
|
||||||
|
cp $@_shipped $@ || gperf < $< > $@
|
||||||
|
|
||||||
|
ifeq ($(MAKECMDGOALS),qconf)
|
||||||
|
qconf.o: .tmp_qtcheck
|
||||||
|
.tmp_qtcheck: Makefile
|
||||||
|
-include .tmp_qtcheck
|
||||||
|
|
||||||
|
# Qt needs some extra effort...
|
||||||
|
.tmp_qtcheck:
|
||||||
|
@set -e; echo " CHECK qt"; \
|
||||||
|
if pkg-config --exists Qt5Core; then \
|
||||||
|
cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
|
||||||
|
libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
|
||||||
|
moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
|
||||||
|
elif pkg-config --exists QtCore; then \
|
||||||
|
cflags=`pkg-config --cflags QtCore QtGui`; \
|
||||||
|
libs=`pkg-config --libs QtCore QtGui`; \
|
||||||
|
moc=`pkg-config --variable=moc_location QtCore`; \
|
||||||
|
else \
|
||||||
|
echo >&2 "*"; \
|
||||||
|
echo >&2 "* Could not find Qt via pkg-config."; \
|
||||||
|
echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
|
||||||
|
echo >&2 "*"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "KC_QT_CFLAGS=$$cflags" > $@; \
|
||||||
|
echo "KC_QT_LIBS=$$libs" >> $@; \
|
||||||
|
echo "KC_QT_MOC=$$moc" >> $@
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Define compiler flags to build qconf
|
||||||
|
HOSTLOADLIBES_qconf = $(KC_QT_LIBS)
|
||||||
|
HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS)
|
||||||
|
|
||||||
|
qconf.o: qconf.moc
|
||||||
|
qconf.o: CXXFLAGS+=$(HOSTCXXFLAGS_qconf.o)
|
||||||
|
|
||||||
|
moc = $(KC_QT_MOC) -i $< -o $@
|
||||||
|
|
||||||
|
%.moc: %.h .tmp_qtcheck
|
||||||
|
$(call moc)
|
||||||
|
@ -1,28 +1,2 @@
|
|||||||
These files were taken from the Linux Kernel Configuration System at commit
|
These files were taken from the Linux 3.9 Kernel
|
||||||
089b7d890f972f6b649fedc9259f6b93a18fb970 (Feb 4, 2020) and modified for the
|
Configuration System and modified for the OpenWrt Buildroot.
|
||||||
OpenWrt Buildroot:
|
|
||||||
- removed nconf, gconf, tests and kernel configuration targets
|
|
||||||
- adjusted the Makefile to compile outside the kernel
|
|
||||||
- always use default file when running make all{no,mod,yes}config
|
|
||||||
- added a 'reset' command to reset config when the target changes
|
|
||||||
- allow config reading from & writing to a different file
|
|
||||||
- allow 'source' command to use globs to include multiple files
|
|
||||||
- don't write auto.conf and other files under include/ directory
|
|
||||||
- reverted a commit to allow use of '/' & '.' in unquoted config symbols.
|
|
||||||
There are too many of those in OpenWrt right now.
|
|
||||||
- reverted a commit that was issuing a warning when there were more than
|
|
||||||
one help text. This is used in a few packages to use different texts
|
|
||||||
for the menuconfig help, and the ipkg package description.
|
|
||||||
- reverted an upstream change that avoids writing symbols that are not
|
|
||||||
visible to .config, which breaks OpenWrt busybox's '.config' generation
|
|
||||||
logic.
|
|
||||||
- add a compilation option (-DWARN_RECURSIVE_DEP) to treat recursive deps
|
|
||||||
as a warning, avoiding a complete build failure because of unrelated or
|
|
||||||
minor recursive deps, or making a scrict check before commiting a change
|
|
||||||
that may cause one.
|
|
||||||
- use pre-built *.lex.c *.tab.[ch] files by default, to avoid depending on
|
|
||||||
flex & bison. Rebuild/remove these files only if running make with
|
|
||||||
BUILD_SHIPPED_FILES defined
|
|
||||||
|
|
||||||
For a full list of changes, see the repository at:
|
|
||||||
https://github.com/cotequeiroz/linux/commits/openwrt/scripts/kconfig
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -19,10 +20,11 @@
|
|||||||
|
|
||||||
static void conf(struct menu *menu);
|
static void conf(struct menu *menu);
|
||||||
static void check_conf(struct menu *menu);
|
static void check_conf(struct menu *menu);
|
||||||
|
static void xfgets(char *str, int size, FILE *in);
|
||||||
|
|
||||||
enum input_mode {
|
enum input_mode {
|
||||||
oldaskconfig,
|
oldaskconfig,
|
||||||
syncconfig,
|
silentoldconfig,
|
||||||
oldconfig,
|
oldconfig,
|
||||||
allnoconfig,
|
allnoconfig,
|
||||||
allyesconfig,
|
allyesconfig,
|
||||||
@ -32,15 +34,12 @@ enum input_mode {
|
|||||||
defconfig,
|
defconfig,
|
||||||
savedefconfig,
|
savedefconfig,
|
||||||
listnewconfig,
|
listnewconfig,
|
||||||
helpnewconfig,
|
|
||||||
olddefconfig,
|
olddefconfig,
|
||||||
yes2modconfig,
|
} input_mode = oldaskconfig;
|
||||||
mod2yesconfig,
|
|
||||||
};
|
|
||||||
static enum input_mode input_mode = oldaskconfig;
|
|
||||||
|
|
||||||
static int indent = 1;
|
static int indent = 1;
|
||||||
static int tty_stdio;
|
static int tty_stdio;
|
||||||
|
static int valid_stdin = 1;
|
||||||
static int sync_kconfig;
|
static int sync_kconfig;
|
||||||
static int conf_cnt;
|
static int conf_cnt;
|
||||||
static char line[PATH_MAX];
|
static char line[PATH_MAX];
|
||||||
@ -73,14 +72,14 @@ static void strip(char *str)
|
|||||||
*p-- = 0;
|
*p-- = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function to facilitate fgets() by Jean Sacren. */
|
static void check_stdin(void)
|
||||||
static void xfgets(char *str, int size, FILE *in)
|
|
||||||
{
|
{
|
||||||
if (!fgets(str, size, in))
|
if (!valid_stdin) {
|
||||||
fprintf(stderr, "\nError in reading or end of file.\n");
|
printf("%s",_("aborted!\n\n"));
|
||||||
|
printf("%s",_("Console input/output is redirected. "));
|
||||||
if (!tty_stdio)
|
printf("%s",_("Run 'make oldconfig' to update configuration.\n\n"));
|
||||||
printf("%s", str);
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conf_askvalue(struct symbol *sym, const char *def)
|
static int conf_askvalue(struct symbol *sym, const char *def)
|
||||||
@ -88,12 +87,12 @@ static int conf_askvalue(struct symbol *sym, const char *def)
|
|||||||
enum symbol_type type = sym_get_type(sym);
|
enum symbol_type type = sym_get_type(sym);
|
||||||
|
|
||||||
if (!sym_has_value(sym))
|
if (!sym_has_value(sym))
|
||||||
printf("(NEW) ");
|
printf("%s",_("(NEW) "));
|
||||||
|
|
||||||
line[0] = '\n';
|
line[0] = '\n';
|
||||||
line[1] = 0;
|
line[1] = 0;
|
||||||
|
|
||||||
if (!sym_is_changeable(sym)) {
|
if (!sym_is_changable(sym)) {
|
||||||
printf("%s\n", def);
|
printf("%s\n", def);
|
||||||
line[0] = '\n';
|
line[0] = '\n';
|
||||||
line[1] = 0;
|
line[1] = 0;
|
||||||
@ -102,15 +101,18 @@ static int conf_askvalue(struct symbol *sym, const char *def)
|
|||||||
|
|
||||||
switch (input_mode) {
|
switch (input_mode) {
|
||||||
case oldconfig:
|
case oldconfig:
|
||||||
case syncconfig:
|
case silentoldconfig:
|
||||||
if (sym_has_value(sym)) {
|
if (sym_has_value(sym)) {
|
||||||
printf("%s\n", def);
|
printf("%s\n", def);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
check_stdin();
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case oldaskconfig:
|
case oldaskconfig:
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
xfgets(line, sizeof(line), stdin);
|
xfgets(line, sizeof(line), stdin);
|
||||||
|
if (!tty_stdio)
|
||||||
|
printf("\n");
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -135,7 +137,7 @@ static int conf_string(struct menu *menu)
|
|||||||
const char *def;
|
const char *def;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("%*s%s ", indent - 1, "", menu->prompt->text);
|
printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
|
||||||
printf("(%s) ", sym->name);
|
printf("(%s) ", sym->name);
|
||||||
def = sym_get_string_value(sym);
|
def = sym_get_string_value(sym);
|
||||||
if (sym_get_string_value(sym))
|
if (sym_get_string_value(sym))
|
||||||
@ -168,7 +170,7 @@ static int conf_sym(struct menu *menu)
|
|||||||
tristate oldval, newval;
|
tristate oldval, newval;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("%*s%s ", indent - 1, "", menu->prompt->text);
|
printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
|
||||||
if (sym->name)
|
if (sym->name)
|
||||||
printf("(%s) ", sym->name);
|
printf("(%s) ", sym->name);
|
||||||
putchar('[');
|
putchar('[');
|
||||||
@ -190,7 +192,9 @@ static int conf_sym(struct menu *menu)
|
|||||||
printf("/m");
|
printf("/m");
|
||||||
if (oldval != yes && sym_tristate_within_range(sym, yes))
|
if (oldval != yes && sym_tristate_within_range(sym, yes))
|
||||||
printf("/y");
|
printf("/y");
|
||||||
printf("/?] ");
|
if (menu_has_help(menu))
|
||||||
|
printf("/?");
|
||||||
|
printf("] ");
|
||||||
if (!conf_askvalue(sym, sym_get_string_value(sym)))
|
if (!conf_askvalue(sym, sym_get_string_value(sym)))
|
||||||
return 0;
|
return 0;
|
||||||
strip(line);
|
strip(line);
|
||||||
@ -237,7 +241,7 @@ static int conf_choice(struct menu *menu)
|
|||||||
|
|
||||||
sym = menu->sym;
|
sym = menu->sym;
|
||||||
is_new = !sym_has_value(sym);
|
is_new = !sym_has_value(sym);
|
||||||
if (sym_is_changeable(sym)) {
|
if (sym_is_changable(sym)) {
|
||||||
conf_sym(menu);
|
conf_sym(menu);
|
||||||
sym_calc_value(sym);
|
sym_calc_value(sym);
|
||||||
switch (sym_get_tristate_value(sym)) {
|
switch (sym_get_tristate_value(sym)) {
|
||||||
@ -253,7 +257,7 @@ static int conf_choice(struct menu *menu)
|
|||||||
case no:
|
case no:
|
||||||
return 1;
|
return 1;
|
||||||
case mod:
|
case mod:
|
||||||
printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
|
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
|
||||||
return 0;
|
return 0;
|
||||||
case yes:
|
case yes:
|
||||||
break;
|
break;
|
||||||
@ -263,7 +267,7 @@ static int conf_choice(struct menu *menu)
|
|||||||
while (1) {
|
while (1) {
|
||||||
int cnt, def;
|
int cnt, def;
|
||||||
|
|
||||||
printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
|
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
|
||||||
def_sym = sym_get_choice_value(sym);
|
def_sym = sym_get_choice_value(sym);
|
||||||
cnt = def = 0;
|
cnt = def = 0;
|
||||||
line[0] = 0;
|
line[0] = 0;
|
||||||
@ -271,7 +275,7 @@ static int conf_choice(struct menu *menu)
|
|||||||
if (!menu_is_visible(child))
|
if (!menu_is_visible(child))
|
||||||
continue;
|
continue;
|
||||||
if (!child->sym) {
|
if (!child->sym) {
|
||||||
printf("%*c %s\n", indent, '*', menu_get_prompt(child));
|
printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
@ -280,27 +284,31 @@ static int conf_choice(struct menu *menu)
|
|||||||
printf("%*c", indent, '>');
|
printf("%*c", indent, '>');
|
||||||
} else
|
} else
|
||||||
printf("%*c", indent, ' ');
|
printf("%*c", indent, ' ');
|
||||||
printf(" %d. %s", cnt, menu_get_prompt(child));
|
printf(" %d. %s", cnt, _(menu_get_prompt(child)));
|
||||||
if (child->sym->name)
|
if (child->sym->name)
|
||||||
printf(" (%s)", child->sym->name);
|
printf(" (%s)", child->sym->name);
|
||||||
if (!sym_has_value(child->sym))
|
if (!sym_has_value(child->sym))
|
||||||
printf(" (NEW)");
|
printf("%s",_(" (NEW)"));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("%*schoice", indent - 1, "");
|
printf(_("%*schoice"), indent - 1, "");
|
||||||
if (cnt == 1) {
|
if (cnt == 1) {
|
||||||
printf("[1]: 1\n");
|
printf("[1]: 1\n");
|
||||||
goto conf_childs;
|
goto conf_childs;
|
||||||
}
|
}
|
||||||
printf("[1-%d?]: ", cnt);
|
printf("[1-%d", cnt);
|
||||||
|
if (menu_has_help(menu))
|
||||||
|
printf("?");
|
||||||
|
printf("]: ");
|
||||||
switch (input_mode) {
|
switch (input_mode) {
|
||||||
case oldconfig:
|
case oldconfig:
|
||||||
case syncconfig:
|
case silentoldconfig:
|
||||||
if (!is_new) {
|
if (!is_new) {
|
||||||
cnt = def;
|
cnt = def;
|
||||||
printf("%d\n", cnt);
|
printf("%d\n", cnt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
check_stdin();
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case oldaskconfig:
|
case oldaskconfig:
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -360,11 +368,10 @@ static void conf(struct menu *menu)
|
|||||||
|
|
||||||
switch (prop->type) {
|
switch (prop->type) {
|
||||||
case P_MENU:
|
case P_MENU:
|
||||||
/*
|
if ((input_mode == silentoldconfig ||
|
||||||
* Except in oldaskconfig mode, we show only menus that
|
input_mode == listnewconfig ||
|
||||||
* contain new symbols.
|
input_mode == olddefconfig) &&
|
||||||
*/
|
rootEntry != menu) {
|
||||||
if (input_mode != oldaskconfig && rootEntry != menu) {
|
|
||||||
check_conf(menu);
|
check_conf(menu);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -374,7 +381,7 @@ static void conf(struct menu *menu)
|
|||||||
if (prompt)
|
if (prompt)
|
||||||
printf("%*c\n%*c %s\n%*c\n",
|
printf("%*c\n%*c %s\n%*c\n",
|
||||||
indent, '*',
|
indent, '*',
|
||||||
indent, '*', prompt,
|
indent, '*', _(prompt),
|
||||||
indent, '*');
|
indent, '*');
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
@ -421,30 +428,15 @@ static void check_conf(struct menu *menu)
|
|||||||
|
|
||||||
sym = menu->sym;
|
sym = menu->sym;
|
||||||
if (sym && !sym_has_value(sym)) {
|
if (sym && !sym_has_value(sym)) {
|
||||||
if (sym_is_changeable(sym) ||
|
if (sym_is_changable(sym) ||
|
||||||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
|
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
|
||||||
if (input_mode == listnewconfig) {
|
if (input_mode == listnewconfig) {
|
||||||
if (sym->name) {
|
if (sym->name && !sym_is_choice_value(sym)) {
|
||||||
const char *str;
|
printf("%s%s\n", CONFIG_, sym->name);
|
||||||
|
|
||||||
if (sym->type == S_STRING) {
|
|
||||||
str = sym_get_string_value(sym);
|
|
||||||
str = sym_escape_string_value(str);
|
|
||||||
printf("%s%s=%s\n", CONFIG_, sym->name, str);
|
|
||||||
free((void *)str);
|
|
||||||
} else {
|
|
||||||
str = sym_get_string_value(sym);
|
|
||||||
printf("%s%s=%s\n", CONFIG_, sym->name, str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (input_mode == helpnewconfig) {
|
} else if (input_mode != olddefconfig) {
|
||||||
printf("-----\n");
|
|
||||||
print_help(menu);
|
|
||||||
printf("-----\n");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!conf_cnt++)
|
if (!conf_cnt++)
|
||||||
printf("*\n* Restart config...\n*\n");
|
printf("%s",_("*\n* Restart config...\n*\n"));
|
||||||
rootEntry = menu_get_parent_menu(menu);
|
rootEntry = menu_get_parent_menu(menu);
|
||||||
conf(rootEntry);
|
conf(rootEntry);
|
||||||
}
|
}
|
||||||
@ -458,8 +450,8 @@ static void check_conf(struct menu *menu)
|
|||||||
static struct option long_opts[] = {
|
static struct option long_opts[] = {
|
||||||
{"oldaskconfig", no_argument, NULL, oldaskconfig},
|
{"oldaskconfig", no_argument, NULL, oldaskconfig},
|
||||||
{"oldconfig", no_argument, NULL, oldconfig},
|
{"oldconfig", no_argument, NULL, oldconfig},
|
||||||
{"syncconfig", no_argument, NULL, syncconfig},
|
{"silentoldconfig", no_argument, NULL, silentoldconfig},
|
||||||
{"defconfig", required_argument, NULL, defconfig},
|
{"defconfig", optional_argument, NULL, defconfig},
|
||||||
{"savedefconfig", required_argument, NULL, savedefconfig},
|
{"savedefconfig", required_argument, NULL, savedefconfig},
|
||||||
{"allnoconfig", no_argument, NULL, allnoconfig},
|
{"allnoconfig", no_argument, NULL, allnoconfig},
|
||||||
{"allyesconfig", no_argument, NULL, allyesconfig},
|
{"allyesconfig", no_argument, NULL, allyesconfig},
|
||||||
@ -467,10 +459,13 @@ static struct option long_opts[] = {
|
|||||||
{"alldefconfig", no_argument, NULL, alldefconfig},
|
{"alldefconfig", no_argument, NULL, alldefconfig},
|
||||||
{"randconfig", no_argument, NULL, randconfig},
|
{"randconfig", no_argument, NULL, randconfig},
|
||||||
{"listnewconfig", no_argument, NULL, listnewconfig},
|
{"listnewconfig", no_argument, NULL, listnewconfig},
|
||||||
{"helpnewconfig", no_argument, NULL, helpnewconfig},
|
|
||||||
{"olddefconfig", no_argument, NULL, olddefconfig},
|
{"olddefconfig", no_argument, NULL, olddefconfig},
|
||||||
{"yes2modconfig", no_argument, NULL, yes2modconfig},
|
/*
|
||||||
{"mod2yesconfig", no_argument, NULL, mod2yesconfig},
|
* oldnoconfig is an alias of olddefconfig, because people already
|
||||||
|
* are dependent on its behavior(sets new symbols to their default
|
||||||
|
* value but not 'n') with the counter-intuitive name.
|
||||||
|
*/
|
||||||
|
{"oldnoconfig", no_argument, NULL, olddefconfig},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -480,12 +475,11 @@ static void conf_usage(const char *progname)
|
|||||||
printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
|
printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
|
||||||
printf("[option] is _one_ of the following:\n");
|
printf("[option] is _one_ of the following:\n");
|
||||||
printf(" --listnewconfig List new options\n");
|
printf(" --listnewconfig List new options\n");
|
||||||
printf(" --helpnewconfig List new options and help text\n");
|
|
||||||
printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
|
printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
|
||||||
printf(" --oldconfig Update a configuration using a provided .config as base\n");
|
printf(" --oldconfig Update a configuration using a provided .config as base\n");
|
||||||
printf(" --syncconfig Similar to oldconfig but generates configuration in\n"
|
printf(" --silentoldconfig Same as oldconfig, but quietly, additionally update deps\n");
|
||||||
" include/{generated/,config/}\n");
|
printf(" --olddefconfig Same as silentoldconfig but sets new symbols to their default value\n");
|
||||||
printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n");
|
printf(" --oldnoconfig An alias of olddefconfig\n");
|
||||||
printf(" --defconfig <file> New config with default defined in <file>\n");
|
printf(" --defconfig <file> New config with default defined in <file>\n");
|
||||||
printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
|
printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
|
||||||
printf(" --allnoconfig New config where all options are answered with no\n");
|
printf(" --allnoconfig New config where all options are answered with no\n");
|
||||||
@ -493,8 +487,6 @@ static void conf_usage(const char *progname)
|
|||||||
printf(" --allmodconfig New config where all options are answered with mod\n");
|
printf(" --allmodconfig New config where all options are answered with mod\n");
|
||||||
printf(" --alldefconfig New config with all symbols set to default\n");
|
printf(" --alldefconfig New config with all symbols set to default\n");
|
||||||
printf(" --randconfig New config with random answer to all options\n");
|
printf(" --randconfig New config with random answer to all options\n");
|
||||||
printf(" --yes2modconfig Change answers from yes to mod if possible\n");
|
|
||||||
printf(" --mod2yesconfig Change answers from mod to yes if possible\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
@ -502,10 +494,14 @@ int main(int ac, char **av)
|
|||||||
const char *progname = av[0];
|
const char *progname = av[0];
|
||||||
int opt;
|
int opt;
|
||||||
const char *name, *defconfig_file = NULL /* gcc uninit */;
|
const char *name, *defconfig_file = NULL /* gcc uninit */;
|
||||||
|
struct stat tmpstat;
|
||||||
const char *input_file = NULL, *output_file = NULL;
|
const char *input_file = NULL, *output_file = NULL;
|
||||||
int no_conf_write = 0;
|
|
||||||
|
|
||||||
tty_stdio = isatty(0) && isatty(1);
|
setlocale(LC_ALL, "");
|
||||||
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
|
tty_stdio = isatty(0) && isatty(1) && isatty(2);
|
||||||
|
|
||||||
while ((opt = getopt_long(ac, av, "r:w:s", long_opts, NULL)) != -1) {
|
while ((opt = getopt_long(ac, av, "r:w:s", long_opts, NULL)) != -1) {
|
||||||
if (opt == 's') {
|
if (opt == 's') {
|
||||||
@ -513,12 +509,7 @@ int main(int ac, char **av)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case syncconfig:
|
case silentoldconfig:
|
||||||
/*
|
|
||||||
* syncconfig is invoked during the build stage.
|
|
||||||
* Suppress distracting "configuration written to ..."
|
|
||||||
*/
|
|
||||||
conf_set_message_callback(NULL);
|
|
||||||
sync_kconfig = 1;
|
sync_kconfig = 1;
|
||||||
break;
|
break;
|
||||||
case defconfig:
|
case defconfig:
|
||||||
@ -557,10 +548,7 @@ int main(int ac, char **av)
|
|||||||
case allmodconfig:
|
case allmodconfig:
|
||||||
case alldefconfig:
|
case alldefconfig:
|
||||||
case listnewconfig:
|
case listnewconfig:
|
||||||
case helpnewconfig:
|
|
||||||
case olddefconfig:
|
case olddefconfig:
|
||||||
case yes2modconfig:
|
|
||||||
case mod2yesconfig:
|
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
input_file = optarg;
|
input_file = optarg;
|
||||||
@ -576,34 +564,43 @@ int main(int ac, char **av)
|
|||||||
input_mode = (enum input_mode)opt;
|
input_mode = (enum input_mode)opt;
|
||||||
}
|
}
|
||||||
if (ac == optind) {
|
if (ac == optind) {
|
||||||
fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
|
printf(_("%s: Kconfig file missing\n"), av[0]);
|
||||||
conf_usage(progname);
|
conf_usage(progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
name = av[optind];
|
name = av[optind];
|
||||||
conf_parse(name);
|
conf_parse(name);
|
||||||
//zconfdump(stdout);
|
//zconfdump(stdout);
|
||||||
|
if (sync_kconfig) {
|
||||||
|
name = conf_get_configname();
|
||||||
|
if (stat(name, &tmpstat)) {
|
||||||
|
fprintf(stderr, _("***\n"
|
||||||
|
"*** Configuration file \"%s\" not found!\n"
|
||||||
|
"***\n"
|
||||||
|
"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
|
||||||
|
"*** \"make menuconfig\" or \"make xconfig\").\n"
|
||||||
|
"***\n"), name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (input_mode) {
|
switch (input_mode) {
|
||||||
case defconfig:
|
case defconfig:
|
||||||
|
if (!defconfig_file)
|
||||||
|
defconfig_file = conf_get_default_confname();
|
||||||
if (conf_read(defconfig_file)) {
|
if (conf_read(defconfig_file)) {
|
||||||
fprintf(stderr,
|
printf(_("***\n"
|
||||||
"***\n"
|
"*** Can't find default configuration \"%s\"!\n"
|
||||||
"*** Can't find default configuration \"%s\"!\n"
|
"***\n"), defconfig_file);
|
||||||
"***\n",
|
|
||||||
defconfig_file);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case savedefconfig:
|
case savedefconfig:
|
||||||
case syncconfig:
|
case silentoldconfig:
|
||||||
case oldaskconfig:
|
case oldaskconfig:
|
||||||
case oldconfig:
|
case oldconfig:
|
||||||
case listnewconfig:
|
case listnewconfig:
|
||||||
case helpnewconfig:
|
|
||||||
case olddefconfig:
|
case olddefconfig:
|
||||||
case yes2modconfig:
|
|
||||||
case mod2yesconfig:
|
|
||||||
case allnoconfig:
|
case allnoconfig:
|
||||||
case allyesconfig:
|
case allyesconfig:
|
||||||
case allmodconfig:
|
case allmodconfig:
|
||||||
@ -616,15 +613,15 @@ int main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sync_kconfig) {
|
if (sync_kconfig) {
|
||||||
name = getenv("KCONFIG_NOSILENTUPDATE");
|
if (conf_get_changed()) {
|
||||||
if (name && *name) {
|
name = getenv("KCONFIG_NOSILENTUPDATE");
|
||||||
if (conf_get_changed()) {
|
if (name && *name) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n*** The configuration requires explicit update.\n\n");
|
_("\n*** The configuration requires explicit update.\n\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
no_conf_write = 1;
|
|
||||||
}
|
}
|
||||||
|
valid_stdin = tty_stdio;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (input_mode) {
|
switch (input_mode) {
|
||||||
@ -649,59 +646,58 @@ int main(int ac, char **av)
|
|||||||
break;
|
break;
|
||||||
case savedefconfig:
|
case savedefconfig:
|
||||||
break;
|
break;
|
||||||
case yes2modconfig:
|
|
||||||
conf_rewrite_mod_or_yes(def_y2m);
|
|
||||||
break;
|
|
||||||
case mod2yesconfig:
|
|
||||||
conf_rewrite_mod_or_yes(def_m2y);
|
|
||||||
break;
|
|
||||||
case oldaskconfig:
|
case oldaskconfig:
|
||||||
rootEntry = &rootmenu;
|
rootEntry = &rootmenu;
|
||||||
conf(&rootmenu);
|
conf(&rootmenu);
|
||||||
input_mode = oldconfig;
|
input_mode = silentoldconfig;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case oldconfig:
|
case oldconfig:
|
||||||
case listnewconfig:
|
case listnewconfig:
|
||||||
case helpnewconfig:
|
case olddefconfig:
|
||||||
case syncconfig:
|
case silentoldconfig:
|
||||||
/* Update until a loop caused no more changes */
|
/* Update until a loop caused no more changes */
|
||||||
do {
|
do {
|
||||||
conf_cnt = 0;
|
conf_cnt = 0;
|
||||||
check_conf(&rootmenu);
|
check_conf(&rootmenu);
|
||||||
} while (conf_cnt);
|
} while (conf_cnt &&
|
||||||
break;
|
(input_mode != listnewconfig &&
|
||||||
case olddefconfig:
|
input_mode != olddefconfig));
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_mode == savedefconfig) {
|
if (sync_kconfig) {
|
||||||
|
/* silentoldconfig is used during the build so we shall update autoconf.
|
||||||
|
* All other commands are only used to generate a config.
|
||||||
|
*/
|
||||||
|
if ((output_file || conf_get_changed()) &&
|
||||||
|
conf_write(output_file)) {
|
||||||
|
fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (conf_write_autoconf()) {
|
||||||
|
fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (input_mode == savedefconfig) {
|
||||||
if (conf_write_defconfig(defconfig_file)) {
|
if (conf_write_defconfig(defconfig_file)) {
|
||||||
fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
|
fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
|
||||||
defconfig_file);
|
defconfig_file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (input_mode != listnewconfig && input_mode != helpnewconfig) {
|
} else if (input_mode != listnewconfig) {
|
||||||
if ((output_file || !no_conf_write) &&
|
if (conf_write(output_file)) {
|
||||||
conf_write(output_file)) {
|
fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
|
||||||
fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create auto.conf if it does not exist.
|
|
||||||
* This prevents GNU Make 4.1 or older from emitting
|
|
||||||
* "include/config/auto.conf: No such file or directory"
|
|
||||||
* in the top-level Makefile
|
|
||||||
*
|
|
||||||
* syncconfig always creates or updates auto.conf because it is
|
|
||||||
* used during the build.
|
|
||||||
*/
|
|
||||||
if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"\n*** Error during sync of the configuration.\n\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function to facilitate fgets() by Jean Sacren.
|
||||||
|
*/
|
||||||
|
void xfgets(char *str, int size, FILE *in)
|
||||||
|
{
|
||||||
|
if (fgets(str, size, in) == NULL)
|
||||||
|
fprintf(stderr, "\nError in reading or end of file.\n");
|
||||||
|
}
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -18,151 +16,6 @@
|
|||||||
|
|
||||||
#include "lkc.h"
|
#include "lkc.h"
|
||||||
|
|
||||||
/* return true if 'path' exists, false otherwise */
|
|
||||||
static bool is_present(const char *path)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
return !stat(path, &st);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return true if 'path' exists and it is a directory, false otherwise */
|
|
||||||
static bool is_dir(const char *path)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(path, &st))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return S_ISDIR(st.st_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return true if the given two files are the same, false otherwise */
|
|
||||||
static bool is_same(const char *file1, const char *file2)
|
|
||||||
{
|
|
||||||
int fd1, fd2;
|
|
||||||
struct stat st1, st2;
|
|
||||||
void *map1, *map2;
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
fd1 = open(file1, O_RDONLY);
|
|
||||||
if (fd1 < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
fd2 = open(file2, O_RDONLY);
|
|
||||||
if (fd2 < 0)
|
|
||||||
goto close1;
|
|
||||||
|
|
||||||
ret = fstat(fd1, &st1);
|
|
||||||
if (ret)
|
|
||||||
goto close2;
|
|
||||||
ret = fstat(fd2, &st2);
|
|
||||||
if (ret)
|
|
||||||
goto close2;
|
|
||||||
|
|
||||||
if (st1.st_size != st2.st_size)
|
|
||||||
goto close2;
|
|
||||||
|
|
||||||
map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
|
|
||||||
if (map1 == MAP_FAILED)
|
|
||||||
goto close2;
|
|
||||||
|
|
||||||
map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
|
|
||||||
if (map2 == MAP_FAILED)
|
|
||||||
goto close2;
|
|
||||||
|
|
||||||
if (bcmp(map1, map2, st1.st_size))
|
|
||||||
goto close2;
|
|
||||||
|
|
||||||
ret = true;
|
|
||||||
close2:
|
|
||||||
close(fd2);
|
|
||||||
close1:
|
|
||||||
close(fd1);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the parent directory of the given path.
|
|
||||||
*
|
|
||||||
* For example, if 'include/config/auto.conf' is given, create 'include/config'.
|
|
||||||
*/
|
|
||||||
static int make_parent_dir(const char *path)
|
|
||||||
{
|
|
||||||
char tmp[PATH_MAX + 1];
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
strncpy(tmp, path, sizeof(tmp));
|
|
||||||
tmp[sizeof(tmp) - 1] = 0;
|
|
||||||
|
|
||||||
/* Remove the base name. Just return if nothing is left */
|
|
||||||
p = strrchr(tmp, '/');
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
*(p + 1) = 0;
|
|
||||||
|
|
||||||
/* Just in case it is an absolute path */
|
|
||||||
p = tmp;
|
|
||||||
while (*p == '/')
|
|
||||||
p++;
|
|
||||||
|
|
||||||
while ((p = strchr(p, '/'))) {
|
|
||||||
*p = 0;
|
|
||||||
|
|
||||||
/* skip if the directory exists */
|
|
||||||
if (!is_dir(tmp) && mkdir(tmp, 0755))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
*p = '/';
|
|
||||||
while (*p == '/')
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char depfile_path[PATH_MAX];
|
|
||||||
static size_t depfile_prefix_len;
|
|
||||||
|
|
||||||
/* touch depfile for symbol 'name' */
|
|
||||||
static int conf_touch_dep(const char *name)
|
|
||||||
{
|
|
||||||
int fd, ret;
|
|
||||||
const char *s;
|
|
||||||
char *d, c;
|
|
||||||
|
|
||||||
/* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */
|
|
||||||
if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
d = depfile_path + depfile_prefix_len;
|
|
||||||
s = name;
|
|
||||||
|
|
||||||
while ((c = *s++))
|
|
||||||
*d++ = (c == '_') ? '/' : tolower(c);
|
|
||||||
strcpy(d, ".h");
|
|
||||||
|
|
||||||
/* Assume directory path already exists. */
|
|
||||||
fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
||||||
if (fd == -1) {
|
|
||||||
if (errno != ENOENT)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = make_parent_dir(depfile_path);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Try it again. */
|
|
||||||
fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
||||||
if (fd == -1)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct conf_printer {
|
struct conf_printer {
|
||||||
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
|
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
|
||||||
void (*print_comment)(FILE *, const char *, void *);
|
void (*print_comment)(FILE *, const char *, void *);
|
||||||
@ -175,7 +28,9 @@ static void conf_message(const char *fmt, ...)
|
|||||||
__attribute__ ((format (printf, 1, 2)));
|
__attribute__ ((format (printf, 1, 2)));
|
||||||
|
|
||||||
static const char *conf_filename;
|
static const char *conf_filename;
|
||||||
static int conf_lineno, conf_warnings;
|
static int conf_lineno, conf_warnings, conf_unsaved;
|
||||||
|
|
||||||
|
const char conf_defname[] = "arch/$ARCH/defconfig";
|
||||||
|
|
||||||
static void conf_warning(const char *fmt, ...)
|
static void conf_warning(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -188,16 +43,16 @@ static void conf_warning(const char *fmt, ...)
|
|||||||
conf_warnings++;
|
conf_warnings++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conf_default_message_callback(const char *s)
|
static void conf_default_message_callback(const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
printf("#\n# ");
|
printf("#\n# ");
|
||||||
printf("%s", s);
|
vprintf(fmt, ap);
|
||||||
printf("\n#\n");
|
printf("\n#\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*conf_message_callback)(const char *s) =
|
static void (*conf_message_callback) (const char *fmt, va_list ap) =
|
||||||
conf_default_message_callback;
|
conf_default_message_callback;
|
||||||
void conf_set_message_callback(void (*fn)(const char *s))
|
void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
|
||||||
{
|
{
|
||||||
conf_message_callback = fn;
|
conf_message_callback = fn;
|
||||||
}
|
}
|
||||||
@ -205,15 +60,10 @@ void conf_set_message_callback(void (*fn)(const char *s))
|
|||||||
static void conf_message(const char *fmt, ...)
|
static void conf_message(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char buf[4096];
|
|
||||||
|
|
||||||
if (!conf_message_callback)
|
|
||||||
return;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
if (conf_message_callback)
|
||||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
conf_message_callback(fmt, ap);
|
||||||
conf_message_callback(buf);
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,13 +74,55 @@ const char *conf_get_configname(void)
|
|||||||
return name ? name : ".config";
|
return name ? name : ".config";
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *conf_get_autoconfig_name(void)
|
const char *conf_get_autoconfig_name(void)
|
||||||
{
|
{
|
||||||
char *name = getenv("KCONFIG_AUTOCONFIG");
|
char *name = getenv("KCONFIG_AUTOCONFIG");
|
||||||
|
|
||||||
return name ? name : "include/config/auto.conf";
|
return name ? name : "include/config/auto.conf";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *conf_expand_value(const char *in)
|
||||||
|
{
|
||||||
|
struct symbol *sym;
|
||||||
|
const char *src;
|
||||||
|
static char res_value[SYMBOL_MAXLENGTH];
|
||||||
|
char *dst, name[SYMBOL_MAXLENGTH];
|
||||||
|
|
||||||
|
res_value[0] = 0;
|
||||||
|
dst = name;
|
||||||
|
while ((src = strchr(in, '$'))) {
|
||||||
|
strncat(res_value, in, src - in);
|
||||||
|
src++;
|
||||||
|
dst = name;
|
||||||
|
while (isalnum(*src) || *src == '_')
|
||||||
|
*dst++ = *src++;
|
||||||
|
*dst = 0;
|
||||||
|
sym = sym_lookup(name, 0);
|
||||||
|
sym_calc_value(sym);
|
||||||
|
strcat(res_value, sym_get_string_value(sym));
|
||||||
|
in = src;
|
||||||
|
}
|
||||||
|
strcat(res_value, in);
|
||||||
|
|
||||||
|
return res_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *conf_get_default_confname(void)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
static char fullname[PATH_MAX+1];
|
||||||
|
char *env, *name;
|
||||||
|
|
||||||
|
name = conf_expand_value(conf_defname);
|
||||||
|
env = getenv(SRCTREE);
|
||||||
|
if (env) {
|
||||||
|
sprintf(fullname, "%s/%s", env, name);
|
||||||
|
if (!stat(fullname, &buf))
|
||||||
|
return fullname;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
|
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
|
||||||
{
|
{
|
||||||
char *p2;
|
char *p2;
|
||||||
@ -258,6 +150,14 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
|
|||||||
conf_warning("symbol value '%s' invalid for %s",
|
conf_warning("symbol value '%s' invalid for %s",
|
||||||
p, sym->name);
|
p, sym->name);
|
||||||
return 1;
|
return 1;
|
||||||
|
case S_OTHER:
|
||||||
|
if (*p != '"') {
|
||||||
|
for (p2 = p; *p2 && !isspace(*p2); p2++)
|
||||||
|
;
|
||||||
|
sym->type = S_STRING;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
if (*p++ != '"')
|
if (*p++ != '"')
|
||||||
break;
|
break;
|
||||||
@ -276,8 +176,9 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
case S_INT:
|
case S_INT:
|
||||||
case S_HEX:
|
case S_HEX:
|
||||||
|
done:
|
||||||
if (sym_string_valid(sym, p)) {
|
if (sym_string_valid(sym, p)) {
|
||||||
sym->def[def].val = xstrdup(p);
|
sym->def[def].val = strdup(p);
|
||||||
sym->flags |= def_flags;
|
sym->flags |= def_flags;
|
||||||
} else {
|
} else {
|
||||||
if (def != S_DEF_AUTO)
|
if (def != S_DEF_AUTO)
|
||||||
@ -300,7 +201,7 @@ static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
|
|||||||
if (new_size > *n) {
|
if (new_size > *n) {
|
||||||
new_size += LINE_GROWTH - 1;
|
new_size += LINE_GROWTH - 1;
|
||||||
new_size *= 2;
|
new_size *= 2;
|
||||||
nline = xrealloc(*lineptr, new_size);
|
nline = realloc(*lineptr, new_size);
|
||||||
if (!nline)
|
if (!nline)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -398,11 +299,10 @@ int conf_read_simple(const char *name, int def)
|
|||||||
if (expr_calc_value(prop->visible.expr) == no ||
|
if (expr_calc_value(prop->visible.expr) == no ||
|
||||||
prop->expr->type != E_SYMBOL)
|
prop->expr->type != E_SYMBOL)
|
||||||
continue;
|
continue;
|
||||||
sym_calc_value(prop->expr->left.sym);
|
name = conf_expand_value(prop->expr->left.sym->name);
|
||||||
name = sym_get_string_value(prop->expr->left.sym);
|
|
||||||
in = zconf_fopen(name);
|
in = zconf_fopen(name);
|
||||||
if (in) {
|
if (in) {
|
||||||
conf_message("using defaults found in %s",
|
conf_message(_("using defaults found in %s"),
|
||||||
name);
|
name);
|
||||||
goto load;
|
goto load;
|
||||||
}
|
}
|
||||||
@ -415,6 +315,7 @@ load:
|
|||||||
conf_filename = name;
|
conf_filename = name;
|
||||||
conf_lineno = 0;
|
conf_lineno = 0;
|
||||||
conf_warnings = 0;
|
conf_warnings = 0;
|
||||||
|
conf_unsaved = 0;
|
||||||
|
|
||||||
def_flags = SYMBOL_DEF << def;
|
def_flags = SYMBOL_DEF << def;
|
||||||
conf_reset(def);
|
conf_reset(def);
|
||||||
@ -435,7 +336,7 @@ load:
|
|||||||
sym = sym_find(line + 2 + strlen(CONFIG_));
|
sym = sym_find(line + 2 + strlen(CONFIG_));
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym_add_change_count(1);
|
sym_add_change_count(1);
|
||||||
continue;
|
goto setsym;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
|
sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
|
||||||
@ -462,22 +363,17 @@ load:
|
|||||||
if (*p2 == '\r')
|
if (*p2 == '\r')
|
||||||
*p2 = 0;
|
*p2 = 0;
|
||||||
}
|
}
|
||||||
|
if (def == S_DEF_USER) {
|
||||||
sym = sym_find(line + strlen(CONFIG_));
|
sym = sym_find(line + strlen(CONFIG_));
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
if (def == S_DEF_AUTO)
|
|
||||||
/*
|
|
||||||
* Reading from include/config/auto.conf
|
|
||||||
* If CONFIG_FOO previously existed in
|
|
||||||
* auto.conf but it is missing now,
|
|
||||||
* include/config/foo.h must be touched.
|
|
||||||
*/
|
|
||||||
conf_touch_dep(line + strlen(CONFIG_));
|
|
||||||
else
|
|
||||||
sym_add_change_count(1);
|
sym_add_change_count(1);
|
||||||
continue;
|
goto setsym;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sym = sym_lookup(line + strlen(CONFIG_), 0);
|
||||||
|
if (sym->type == S_UNKNOWN)
|
||||||
|
sym->type = S_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf_set_sym_val(sym, def, def_flags, p))
|
if (conf_set_sym_val(sym, def, def_flags, p))
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@ -487,7 +383,7 @@ load:
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
setsym:
|
||||||
if (sym && sym_is_choice_value(sym)) {
|
if (sym && sym_is_choice_value(sym)) {
|
||||||
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
|
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
|
||||||
switch (sym->def[def].tri) {
|
switch (sym->def[def].tri) {
|
||||||
@ -516,7 +412,6 @@ load:
|
|||||||
int conf_read(const char *name)
|
int conf_read(const char *name)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
int conf_unsaved = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sym_set_change_count(0);
|
sym_set_change_count(0);
|
||||||
@ -530,16 +425,18 @@ int conf_read(const char *name)
|
|||||||
|
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
sym_calc_value(sym);
|
sym_calc_value(sym);
|
||||||
if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
|
if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
|
||||||
continue;
|
continue;
|
||||||
if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
|
if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
|
||||||
/* check that calculated value agrees with saved value */
|
/* check that calculated value agrees with saved value */
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
case S_TRISTATE:
|
case S_TRISTATE:
|
||||||
if (sym->def[S_DEF_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))
|
||||||
continue;
|
continue;
|
||||||
break;
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
|
if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
|
||||||
continue;
|
continue;
|
||||||
@ -713,12 +610,32 @@ static struct conf_printer header_printer_cb =
|
|||||||
.print_comment = header_print_comment,
|
.print_comment = header_print_comment,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tristate printer
|
||||||
|
*
|
||||||
|
* This printer is used when generating the `include/config/tristate.conf' file.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (sym->type == S_TRISTATE && *value != 'n')
|
||||||
|
fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct conf_printer tristate_printer_cb =
|
||||||
|
{
|
||||||
|
.print_symbol = tristate_print_symbol,
|
||||||
|
.print_comment = kconfig_print_comment,
|
||||||
|
};
|
||||||
|
|
||||||
static void conf_write_symbol(FILE *fp, struct symbol *sym,
|
static void conf_write_symbol(FILE *fp, struct symbol *sym,
|
||||||
struct conf_printer *printer, void *printer_arg)
|
struct conf_printer *printer, void *printer_arg)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
|
case S_OTHER:
|
||||||
case S_UNKNOWN:
|
case S_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
@ -778,7 +695,7 @@ int conf_write_defconfig(const char *filename)
|
|||||||
goto next_menu;
|
goto next_menu;
|
||||||
sym->flags &= ~SYMBOL_WRITE;
|
sym->flags &= ~SYMBOL_WRITE;
|
||||||
/* If we cannot change the symbol - skip */
|
/* If we cannot change the symbol - skip */
|
||||||
if (!sym_is_changeable(sym))
|
if (!sym_is_changable(sym))
|
||||||
goto next_menu;
|
goto next_menu;
|
||||||
/* If symbol equals to default value - skip */
|
/* If symbol equals to default value - skip */
|
||||||
if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
|
if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
|
||||||
@ -829,36 +746,41 @@ int conf_write(const char *name)
|
|||||||
FILE *out;
|
FILE *out;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
|
const char *basename;
|
||||||
const char *str;
|
const char *str;
|
||||||
char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
|
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
|
||||||
char *env;
|
char *env;
|
||||||
int i;
|
|
||||||
bool need_newline = false;
|
|
||||||
|
|
||||||
if (!name)
|
dirname[0] = 0;
|
||||||
name = conf_get_configname();
|
if (name && name[0]) {
|
||||||
|
struct stat st;
|
||||||
|
char *slash;
|
||||||
|
|
||||||
if (!*name) {
|
if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
|
||||||
fprintf(stderr, "config name is empty\n");
|
strcpy(dirname, name);
|
||||||
return -1;
|
strcat(dirname, "/");
|
||||||
}
|
basename = conf_get_configname();
|
||||||
|
} else if ((slash = strrchr(name, '/'))) {
|
||||||
if (is_dir(name)) {
|
int size = slash - name + 1;
|
||||||
fprintf(stderr, "%s: Is a directory\n", name);
|
memcpy(dirname, name, size);
|
||||||
return -1;
|
dirname[size] = 0;
|
||||||
}
|
if (slash[1])
|
||||||
|
basename = slash + 1;
|
||||||
if (make_parent_dir(name))
|
else
|
||||||
return -1;
|
basename = conf_get_configname();
|
||||||
|
} else
|
||||||
|
basename = name;
|
||||||
|
} else
|
||||||
|
basename = conf_get_configname();
|
||||||
|
|
||||||
|
sprintf(newname, "%s%s", dirname, basename);
|
||||||
env = getenv("KCONFIG_OVERWRITECONFIG");
|
env = getenv("KCONFIG_OVERWRITECONFIG");
|
||||||
if (env && *env) {
|
if (!env || !*env) {
|
||||||
*tmpname = 0;
|
sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
|
||||||
out = fopen(name, "w");
|
|
||||||
} else {
|
|
||||||
snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
|
|
||||||
name, (int)getpid());
|
|
||||||
out = fopen(tmpname, "w");
|
out = fopen(tmpname, "w");
|
||||||
|
} else {
|
||||||
|
*tmpname = 0;
|
||||||
|
out = fopen(newname, "w");
|
||||||
}
|
}
|
||||||
if (!out)
|
if (!out)
|
||||||
return 1;
|
return 1;
|
||||||
@ -879,17 +801,12 @@ int conf_write(const char *name)
|
|||||||
"#\n"
|
"#\n"
|
||||||
"# %s\n"
|
"# %s\n"
|
||||||
"#\n", str);
|
"#\n", str);
|
||||||
need_newline = false;
|
} else if (!(sym->flags & SYMBOL_CHOICE)) {
|
||||||
} else if (!(sym->flags & SYMBOL_CHOICE) &&
|
|
||||||
!(sym->flags & SYMBOL_WRITTEN)) {
|
|
||||||
sym_calc_value(sym);
|
sym_calc_value(sym);
|
||||||
if (!(sym->flags & SYMBOL_WRITE))
|
if (!(sym->flags & SYMBOL_WRITE))
|
||||||
goto next;
|
goto next;
|
||||||
if (need_newline) {
|
sym->flags &= ~SYMBOL_WRITE;
|
||||||
fprintf(out, "\n");
|
|
||||||
need_newline = false;
|
|
||||||
}
|
|
||||||
sym->flags |= SYMBOL_WRITTEN;
|
|
||||||
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
|
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,12 +818,6 @@ next:
|
|||||||
if (menu->next)
|
if (menu->next)
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
else while ((menu = menu->parent)) {
|
else while ((menu = menu->parent)) {
|
||||||
if (!menu->sym && menu_is_visible(menu) &&
|
|
||||||
menu != &rootmenu) {
|
|
||||||
str = menu_get_prompt(menu);
|
|
||||||
fprintf(out, "# end of %s\n", str);
|
|
||||||
need_newline = true;
|
|
||||||
}
|
|
||||||
if (menu->next) {
|
if (menu->next) {
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
break;
|
break;
|
||||||
@ -915,76 +826,41 @@ next:
|
|||||||
}
|
}
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
|
||||||
for_all_symbols(i, sym)
|
|
||||||
sym->flags &= ~SYMBOL_WRITTEN;
|
|
||||||
|
|
||||||
if (*tmpname) {
|
if (*tmpname) {
|
||||||
if (is_same(name, tmpname)) {
|
strcat(dirname, basename);
|
||||||
conf_message("No change to %s", name);
|
strcat(dirname, ".old");
|
||||||
unlink(tmpname);
|
rename(newname, dirname);
|
||||||
sym_set_change_count(0);
|
if (rename(tmpname, newname))
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(oldname, sizeof(oldname), "%s.old", name);
|
|
||||||
rename(name, oldname);
|
|
||||||
if (rename(tmpname, name))
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf_message("configuration written to %s", name);
|
conf_message(_("configuration written to %s"), newname);
|
||||||
|
|
||||||
sym_set_change_count(0);
|
sym_set_change_count(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write a dependency file as used by kbuild to track dependencies */
|
static int conf_split_config(void)
|
||||||
static int conf_write_dep(const char *name)
|
|
||||||
{
|
|
||||||
struct file *file;
|
|
||||||
FILE *out;
|
|
||||||
|
|
||||||
out = fopen("..config.tmp", "w");
|
|
||||||
if (!out)
|
|
||||||
return 1;
|
|
||||||
fprintf(out, "deps_config := \\\n");
|
|
||||||
for (file = file_list; file; file = file->next) {
|
|
||||||
if (file->next)
|
|
||||||
fprintf(out, "\t%s \\\n", file->name);
|
|
||||||
else
|
|
||||||
fprintf(out, "\t%s\n", file->name);
|
|
||||||
}
|
|
||||||
fprintf(out, "\n%s: \\\n"
|
|
||||||
"\t$(deps_config)\n\n", conf_get_autoconfig_name());
|
|
||||||
|
|
||||||
env_write_dep(out, conf_get_autoconfig_name());
|
|
||||||
|
|
||||||
fprintf(out, "\n$(deps_config): ;\n");
|
|
||||||
fclose(out);
|
|
||||||
|
|
||||||
if (make_parent_dir(name))
|
|
||||||
return 1;
|
|
||||||
rename("..config.tmp", name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int conf_touch_deps(void)
|
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
char path[PATH_MAX+1];
|
||||||
|
char *s, *d, c;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
int res, i;
|
struct stat sb;
|
||||||
|
int res, i, fd;
|
||||||
strcpy(depfile_path, "include/config/");
|
|
||||||
depfile_prefix_len = strlen(depfile_path);
|
|
||||||
|
|
||||||
name = conf_get_autoconfig_name();
|
name = conf_get_autoconfig_name();
|
||||||
conf_read_simple(name, S_DEF_AUTO);
|
conf_read_simple(name, S_DEF_AUTO);
|
||||||
sym_calc_value(modules_sym);
|
sym_calc_value(modules_sym);
|
||||||
|
|
||||||
|
if (chdir("include/config"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
res = 0;
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
sym_calc_value(sym);
|
sym_calc_value(sym);
|
||||||
if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
|
if ((sym->flags & SYMBOL_AUTO) || !sym->name)
|
||||||
continue;
|
continue;
|
||||||
if (sym->flags & SYMBOL_WRITE) {
|
if (sym->flags & SYMBOL_WRITE) {
|
||||||
if (sym->flags & SYMBOL_DEF_AUTO) {
|
if (sym->flags & SYMBOL_DEF_AUTO) {
|
||||||
@ -1033,44 +909,86 @@ static int conf_touch_deps(void)
|
|||||||
* different from 'no').
|
* different from 'no').
|
||||||
*/
|
*/
|
||||||
|
|
||||||
res = conf_touch_dep(sym->name);
|
/* Replace all '_' and append ".h" */
|
||||||
if (res)
|
s = sym->name;
|
||||||
return res;
|
d = path;
|
||||||
}
|
while ((c = *s++)) {
|
||||||
|
c = tolower(c);
|
||||||
|
*d++ = (c == '_') ? '/' : c;
|
||||||
|
}
|
||||||
|
strcpy(d, ".h");
|
||||||
|
|
||||||
return 0;
|
/* Assume directory path already exists. */
|
||||||
|
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if (fd == -1) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
res = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Create directory components,
|
||||||
|
* unless they exist already.
|
||||||
|
*/
|
||||||
|
d = path;
|
||||||
|
while ((d = strchr(d, '/'))) {
|
||||||
|
*d = 0;
|
||||||
|
if (stat(path, &sb) && mkdir(path, 0755)) {
|
||||||
|
res = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
*d++ = '/';
|
||||||
|
}
|
||||||
|
/* Try it again. */
|
||||||
|
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if (fd == -1) {
|
||||||
|
res = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
if (chdir("../.."))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int conf_write_autoconf(int overwrite)
|
int conf_write_autoconf(void)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *autoconf_name = conf_get_autoconfig_name();
|
FILE *out, *tristate, *out_h;
|
||||||
FILE *out, *out_h;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifndef OPENWRT_DOES_NOT_WANT_THIS
|
sym_clear_all_valid();
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
if (!overwrite && is_present(autoconf_name))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
conf_write_dep("include/config/auto.conf.cmd");
|
file_write_dep("include/config/auto.conf.cmd");
|
||||||
|
|
||||||
if (conf_touch_deps())
|
if (conf_split_config())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out = fopen(".tmpconfig", "w");
|
out = fopen(".tmpconfig", "w");
|
||||||
if (!out)
|
if (!out)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out_h = fopen(".tmpconfig.h", "w");
|
tristate = fopen(".tmpconfig_tristate", "w");
|
||||||
if (!out_h) {
|
if (!tristate) {
|
||||||
fclose(out);
|
fclose(out);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_h = fopen(".tmpconfig.h", "w");
|
||||||
|
if (!out_h) {
|
||||||
|
fclose(out);
|
||||||
|
fclose(tristate);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
conf_write_heading(out, &kconfig_printer_cb, NULL);
|
conf_write_heading(out, &kconfig_printer_cb, NULL);
|
||||||
|
|
||||||
|
conf_write_heading(tristate, &tristate_printer_cb, NULL);
|
||||||
|
|
||||||
conf_write_heading(out_h, &header_printer_cb, NULL);
|
conf_write_heading(out_h, &header_printer_cb, NULL);
|
||||||
|
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
@ -1078,28 +996,33 @@ int conf_write_autoconf(int overwrite)
|
|||||||
if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
|
if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* write symbols to auto.conf and autoconf.h */
|
/* write symbol to auto.conf, tristate and header files */
|
||||||
conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
|
conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
|
||||||
|
|
||||||
|
conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
|
||||||
|
|
||||||
conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
|
conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
|
||||||
}
|
}
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
fclose(tristate);
|
||||||
fclose(out_h);
|
fclose(out_h);
|
||||||
|
|
||||||
name = getenv("KCONFIG_AUTOHEADER");
|
name = getenv("KCONFIG_AUTOHEADER");
|
||||||
if (!name)
|
if (!name)
|
||||||
name = "include/generated/autoconf.h";
|
name = "include/generated/autoconf.h";
|
||||||
if (make_parent_dir(name))
|
|
||||||
return 1;
|
|
||||||
if (rename(".tmpconfig.h", name))
|
if (rename(".tmpconfig.h", name))
|
||||||
return 1;
|
return 1;
|
||||||
|
name = getenv("KCONFIG_TRISTATE");
|
||||||
if (make_parent_dir(autoconf_name))
|
if (!name)
|
||||||
|
name = "include/config/tristate.conf";
|
||||||
|
if (rename(".tmpconfig_tristate", name))
|
||||||
return 1;
|
return 1;
|
||||||
|
name = conf_get_autoconfig_name();
|
||||||
/*
|
/*
|
||||||
* This must be the last step, kbuild has a dependency on 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.
|
* and this marks the successful completion of the previous steps.
|
||||||
*/
|
*/
|
||||||
if (rename(".tmpconfig", autoconf_name))
|
if (rename(".tmpconfig", name))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1203,7 +1126,7 @@ void set_all_choice_values(struct symbol *csym)
|
|||||||
bool conf_set_all_new_symbols(enum conf_def_mode mode)
|
bool conf_set_all_new_symbols(enum conf_def_mode mode)
|
||||||
{
|
{
|
||||||
struct symbol *sym, *csym;
|
struct symbol *sym, *csym;
|
||||||
int i, cnt, pby, pty, ptm; /* pby: probability of bool = y
|
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
|
||||||
* pty: probability of tristate = y
|
* pty: probability of tristate = y
|
||||||
* ptm: probability of tristate = m
|
* ptm: probability of tristate = m
|
||||||
*/
|
*/
|
||||||
@ -1327,19 +1250,3 @@ bool conf_set_all_new_symbols(enum conf_def_mode mode)
|
|||||||
|
|
||||||
return has_changed;
|
return has_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
|
|
||||||
{
|
|
||||||
struct symbol *sym;
|
|
||||||
int i;
|
|
||||||
tristate old_val = (mode == def_y2m) ? yes : mod;
|
|
||||||
tristate new_val = (mode == def_y2m) ? mod : yes;
|
|
||||||
|
|
||||||
for_all_symbols(i, sym) {
|
|
||||||
if (sym_get_type(sym) == S_TRISTATE &&
|
|
||||||
sym->def[S_DEF_USER].tri == old_val) {
|
|
||||||
sym->def[S_DEF_USER].tri = new_val;
|
|
||||||
sym_add_change_count(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -13,6 +11,7 @@
|
|||||||
|
|
||||||
#define DEBUG_EXPR 0
|
#define DEBUG_EXPR 0
|
||||||
|
|
||||||
|
static int expr_eq(struct expr *e1, struct expr *e2);
|
||||||
static struct expr *expr_eliminate_yn(struct expr *e);
|
static struct expr *expr_eliminate_yn(struct expr *e);
|
||||||
|
|
||||||
struct expr *expr_alloc_symbol(struct symbol *sym)
|
struct expr *expr_alloc_symbol(struct symbol *sym)
|
||||||
@ -95,7 +94,7 @@ struct expr *expr_copy(const struct expr *org)
|
|||||||
e->right.expr = expr_copy(org->right.expr);
|
e->right.expr = expr_copy(org->right.expr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "can't copy type %d\n", e->type);
|
printf("can't copy type %d\n", e->type);
|
||||||
free(e);
|
free(e);
|
||||||
e = NULL;
|
e = NULL;
|
||||||
break;
|
break;
|
||||||
@ -114,7 +113,7 @@ void expr_free(struct expr *e)
|
|||||||
break;
|
break;
|
||||||
case E_NOT:
|
case E_NOT:
|
||||||
expr_free(e->left.expr);
|
expr_free(e->left.expr);
|
||||||
break;
|
return;
|
||||||
case E_EQUAL:
|
case E_EQUAL:
|
||||||
case E_GEQ:
|
case E_GEQ:
|
||||||
case E_GTH:
|
case E_GTH:
|
||||||
@ -128,7 +127,7 @@ void expr_free(struct expr *e)
|
|||||||
expr_free(e->right.expr);
|
expr_free(e->right.expr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "how to free type %d?\n", e->type);
|
printf("how to free type %d?\n", e->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(e);
|
free(e);
|
||||||
@ -139,18 +138,8 @@ static int trans_count;
|
|||||||
#define e1 (*ep1)
|
#define e1 (*ep1)
|
||||||
#define e2 (*ep2)
|
#define e2 (*ep2)
|
||||||
|
|
||||||
/*
|
|
||||||
* expr_eliminate_eq() helper.
|
|
||||||
*
|
|
||||||
* Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
|
|
||||||
* not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
|
|
||||||
* against all other leaves. Two equal leaves are both replaced with either 'y'
|
|
||||||
* or 'n' as appropriate for 'type', to be eliminated later.
|
|
||||||
*/
|
|
||||||
static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
|
static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
|
||||||
{
|
{
|
||||||
/* Recurse down to leaves */
|
|
||||||
|
|
||||||
if (e1->type == type) {
|
if (e1->type == type) {
|
||||||
__expr_eliminate_eq(type, &e1->left.expr, &e2);
|
__expr_eliminate_eq(type, &e1->left.expr, &e2);
|
||||||
__expr_eliminate_eq(type, &e1->right.expr, &e2);
|
__expr_eliminate_eq(type, &e1->right.expr, &e2);
|
||||||
@ -161,18 +150,12 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
|
|||||||
__expr_eliminate_eq(type, &e1, &e2->right.expr);
|
__expr_eliminate_eq(type, &e1, &e2->right.expr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* e1 and e2 are leaves. Compare them. */
|
|
||||||
|
|
||||||
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
|
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
|
||||||
e1->left.sym == e2->left.sym &&
|
e1->left.sym == e2->left.sym &&
|
||||||
(e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
|
(e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
|
||||||
return;
|
return;
|
||||||
if (!expr_eq(e1, e2))
|
if (!expr_eq(e1, e2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* e1 and e2 are equal leaves. Prepare them for elimination. */
|
|
||||||
|
|
||||||
trans_count++;
|
trans_count++;
|
||||||
expr_free(e1); expr_free(e2);
|
expr_free(e1); expr_free(e2);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -189,35 +172,6 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
|
|
||||||
* Example reductions:
|
|
||||||
*
|
|
||||||
* ep1: A && B -> ep1: y
|
|
||||||
* ep2: A && B && C -> ep2: C
|
|
||||||
*
|
|
||||||
* ep1: A || B -> ep1: n
|
|
||||||
* ep2: A || B || C -> ep2: C
|
|
||||||
*
|
|
||||||
* ep1: A && (B && FOO) -> ep1: FOO
|
|
||||||
* ep2: (BAR && B) && A -> ep2: BAR
|
|
||||||
*
|
|
||||||
* ep1: A && (B || C) -> ep1: y
|
|
||||||
* ep2: (C || B) && A -> ep2: y
|
|
||||||
*
|
|
||||||
* Comparisons are done between all operands at the same "level" of && or ||.
|
|
||||||
* For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
|
|
||||||
* following operands will be compared:
|
|
||||||
*
|
|
||||||
* - 'e1', 'e2 || e3', and 'e4 || e5', against each other
|
|
||||||
* - e2 against e3
|
|
||||||
* - e4 against e5
|
|
||||||
*
|
|
||||||
* Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
|
|
||||||
* '(e1 && e2) && e3' are both a single level.
|
|
||||||
*
|
|
||||||
* See __expr_eliminate_eq() as well.
|
|
||||||
*/
|
|
||||||
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
|
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
|
||||||
{
|
{
|
||||||
if (!e1 || !e2)
|
if (!e1 || !e2)
|
||||||
@ -243,23 +197,10 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
|
|||||||
#undef e1
|
#undef e1
|
||||||
#undef e2
|
#undef e2
|
||||||
|
|
||||||
/*
|
static int expr_eq(struct expr *e1, struct expr *e2)
|
||||||
* Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
|
|
||||||
* &&/|| expressions are considered equal if every operand in one expression
|
|
||||||
* equals some operand in the other (operands do not need to appear in the same
|
|
||||||
* order), recursively.
|
|
||||||
*/
|
|
||||||
int expr_eq(struct expr *e1, struct expr *e2)
|
|
||||||
{
|
{
|
||||||
int res, old_count;
|
int res, old_count;
|
||||||
|
|
||||||
/*
|
|
||||||
* A NULL expr is taken to be yes, but there's also a different way to
|
|
||||||
* represent yes. expr_is_yes() checks for either representation.
|
|
||||||
*/
|
|
||||||
if (!e1 || !e2)
|
|
||||||
return expr_is_yes(e1) && expr_is_yes(e2);
|
|
||||||
|
|
||||||
if (e1->type != e2->type)
|
if (e1->type != e2->type)
|
||||||
return 0;
|
return 0;
|
||||||
switch (e1->type) {
|
switch (e1->type) {
|
||||||
@ -302,17 +243,6 @@ int expr_eq(struct expr *e1, struct expr *e2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Recursively performs the following simplifications in-place (as well as the
|
|
||||||
* corresponding simplifications with swapped operands):
|
|
||||||
*
|
|
||||||
* expr && n -> n
|
|
||||||
* expr && y -> expr
|
|
||||||
* expr || n -> expr
|
|
||||||
* expr || y -> y
|
|
||||||
*
|
|
||||||
* Returns the optimized expression.
|
|
||||||
*/
|
|
||||||
static struct expr *expr_eliminate_yn(struct expr *e)
|
static struct expr *expr_eliminate_yn(struct expr *e)
|
||||||
{
|
{
|
||||||
struct expr *tmp;
|
struct expr *tmp;
|
||||||
@ -586,21 +516,12 @@ static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* expr_eliminate_dups() helper.
|
|
||||||
*
|
|
||||||
* Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
|
|
||||||
* not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
|
|
||||||
* against all other leaves to look for simplifications.
|
|
||||||
*/
|
|
||||||
static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
|
static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
|
||||||
{
|
{
|
||||||
#define e1 (*ep1)
|
#define e1 (*ep1)
|
||||||
#define e2 (*ep2)
|
#define e2 (*ep2)
|
||||||
struct expr *tmp;
|
struct expr *tmp;
|
||||||
|
|
||||||
/* Recurse down to leaves */
|
|
||||||
|
|
||||||
if (e1->type == type) {
|
if (e1->type == type) {
|
||||||
expr_eliminate_dups1(type, &e1->left.expr, &e2);
|
expr_eliminate_dups1(type, &e1->left.expr, &e2);
|
||||||
expr_eliminate_dups1(type, &e1->right.expr, &e2);
|
expr_eliminate_dups1(type, &e1->right.expr, &e2);
|
||||||
@ -611,9 +532,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
|
|||||||
expr_eliminate_dups1(type, &e1, &e2->right.expr);
|
expr_eliminate_dups1(type, &e1, &e2->right.expr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* e1 and e2 are leaves. Compare and process them. */
|
|
||||||
|
|
||||||
if (e1 == e2)
|
if (e1 == e2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -650,17 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
|
|||||||
#undef e2
|
#undef e2
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Rewrites 'e' in-place to remove ("join") duplicate and other redundant
|
|
||||||
* operands.
|
|
||||||
*
|
|
||||||
* Example simplifications:
|
|
||||||
*
|
|
||||||
* A || B || A -> A || B
|
|
||||||
* A && B && A=y -> A=y && B
|
|
||||||
*
|
|
||||||
* Returns the deduplicated expression.
|
|
||||||
*/
|
|
||||||
struct expr *expr_eliminate_dups(struct expr *e)
|
struct expr *expr_eliminate_dups(struct expr *e)
|
||||||
{
|
{
|
||||||
int oldcount;
|
int oldcount;
|
||||||
@ -677,7 +584,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (!trans_count)
|
if (!trans_count)
|
||||||
/* No simplifications done in this pass. We're done */
|
|
||||||
break;
|
break;
|
||||||
e = expr_eliminate_yn(e);
|
e = expr_eliminate_yn(e);
|
||||||
}
|
}
|
||||||
@ -685,12 +591,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Performs various simplifications involving logical operators and
|
|
||||||
* comparisons.
|
|
||||||
*
|
|
||||||
* Allocates and returns a new expression.
|
|
||||||
*/
|
|
||||||
struct expr *expr_transform(struct expr *e)
|
struct expr *expr_transform(struct expr *e)
|
||||||
{
|
{
|
||||||
struct expr *tmp;
|
struct expr *tmp;
|
||||||
@ -905,20 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Inserts explicit comparisons of type 'type' to symbol 'sym' into the
|
|
||||||
* expression 'e'.
|
|
||||||
*
|
|
||||||
* Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
|
|
||||||
*
|
|
||||||
* A -> A!=n
|
|
||||||
* !A -> A=n
|
|
||||||
* A && B -> !(A=n || B=n)
|
|
||||||
* A || B -> !(A=n && B=n)
|
|
||||||
* A && (B || C) -> !(A=n || (B=n && C=n))
|
|
||||||
*
|
|
||||||
* Allocates and returns a new expression.
|
|
||||||
*/
|
|
||||||
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
|
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
|
||||||
{
|
{
|
||||||
struct expr *e1, *e2;
|
struct expr *e1, *e2;
|
||||||
@ -988,6 +874,7 @@ enum string_value_kind {
|
|||||||
k_string,
|
k_string,
|
||||||
k_signed,
|
k_signed,
|
||||||
k_unsigned,
|
k_unsigned,
|
||||||
|
k_invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
union string_value {
|
union string_value {
|
||||||
@ -1018,10 +905,13 @@ static enum string_value_kind expr_parse_string(const char *str,
|
|||||||
val->u = strtoull(str, &tail, 16);
|
val->u = strtoull(str, &tail, 16);
|
||||||
kind = k_unsigned;
|
kind = k_unsigned;
|
||||||
break;
|
break;
|
||||||
default:
|
case S_STRING:
|
||||||
|
case S_UNKNOWN:
|
||||||
val->s = strtoll(str, &tail, 0);
|
val->s = strtoll(str, &tail, 0);
|
||||||
kind = k_signed;
|
kind = k_signed;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return k_invalid;
|
||||||
}
|
}
|
||||||
return !errno && !*tail && tail > str && isxdigit(tail[-1])
|
return !errno && !*tail && tail > str && isxdigit(tail[-1])
|
||||||
? kind : k_string;
|
? kind : k_string;
|
||||||
@ -1077,7 +967,13 @@ tristate expr_calc_value(struct expr *e)
|
|||||||
|
|
||||||
if (k1 == k_string || k2 == k_string)
|
if (k1 == k_string || k2 == k_string)
|
||||||
res = strcmp(str1, str2);
|
res = strcmp(str1, str2);
|
||||||
else if (k1 == k_unsigned || k2 == k_unsigned)
|
else if (k1 == k_invalid || k2 == k_invalid) {
|
||||||
|
if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
|
||||||
|
printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
|
||||||
|
return no;
|
||||||
|
}
|
||||||
|
res = strcmp(str1, str2);
|
||||||
|
} else if (k1 == k_unsigned || k2 == k_unsigned)
|
||||||
res = (lval.u > rval.u) - (lval.u < rval.u);
|
res = (lval.u > rval.u) - (lval.u < rval.u);
|
||||||
else /* if (k1 == k_signed && k2 == k_signed) */
|
else /* if (k1 == k_signed && k2 == k_signed) */
|
||||||
res = (lval.s > rval.s) - (lval.s < rval.s);
|
res = (lval.s > rval.s) - (lval.s < rval.s);
|
||||||
@ -1135,9 +1031,49 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void expr_print(struct expr *e,
|
static inline struct expr *
|
||||||
void (*fn)(void *, struct symbol *, const char *),
|
expr_get_leftmost_symbol(const struct expr *e)
|
||||||
void *data, int prevtoken)
|
{
|
||||||
|
|
||||||
|
if (e == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (e->type != E_SYMBOL)
|
||||||
|
e = e->left.expr;
|
||||||
|
|
||||||
|
return expr_copy(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given expression `e1' and `e2', returns the leaf of the longest
|
||||||
|
* sub-expression of `e1' not containing 'e2.
|
||||||
|
*/
|
||||||
|
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
|
||||||
|
{
|
||||||
|
struct expr *ret;
|
||||||
|
|
||||||
|
switch (e1->type) {
|
||||||
|
case E_OR:
|
||||||
|
return expr_alloc_and(
|
||||||
|
expr_simplify_unmet_dep(e1->left.expr, e2),
|
||||||
|
expr_simplify_unmet_dep(e1->right.expr, e2));
|
||||||
|
case E_AND: {
|
||||||
|
struct expr *e;
|
||||||
|
e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
|
||||||
|
e = expr_eliminate_dups(e);
|
||||||
|
ret = (!expr_eq(e, e1)) ? e1 : NULL;
|
||||||
|
expr_free(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ret = e1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr_get_leftmost_symbol(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
|
||||||
{
|
{
|
||||||
if (!e) {
|
if (!e) {
|
||||||
fn(data, NULL, "y");
|
fn(data, NULL, "y");
|
||||||
@ -1271,33 +1207,3 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
|
|||||||
{
|
{
|
||||||
expr_print(e, expr_print_gstr_helper, gs, E_NONE);
|
expr_print(e, expr_print_gstr_helper, gs, E_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Transform the top level "||" tokens into newlines and prepend each
|
|
||||||
* line with a minus. This makes expressions much easier to read.
|
|
||||||
* Suitable for reverse dependency expressions.
|
|
||||||
*/
|
|
||||||
static void expr_print_revdep(struct expr *e,
|
|
||||||
void (*fn)(void *, struct symbol *, const char *),
|
|
||||||
void *data, tristate pr_type, const char **title)
|
|
||||||
{
|
|
||||||
if (e->type == E_OR) {
|
|
||||||
expr_print_revdep(e->left.expr, fn, data, pr_type, title);
|
|
||||||
expr_print_revdep(e->right.expr, fn, data, pr_type, title);
|
|
||||||
} else if (expr_calc_value(e) == pr_type) {
|
|
||||||
if (*title) {
|
|
||||||
fn(data, NULL, *title);
|
|
||||||
*title = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn(data, NULL, " - ");
|
|
||||||
expr_print(e, fn, data, E_NONE);
|
|
||||||
fn(data, NULL, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
|
|
||||||
tristate pr_type, const char *title)
|
|
||||||
{
|
|
||||||
expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EXPR_H
|
#ifndef EXPR_H
|
||||||
@ -62,7 +62,7 @@ struct symbol_value {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum symbol_type {
|
enum symbol_type {
|
||||||
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING
|
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
|
||||||
};
|
};
|
||||||
|
|
||||||
/* enum values are used as index to symbol.def[] */
|
/* enum values are used as index to symbol.def[] */
|
||||||
@ -74,64 +74,20 @@ enum {
|
|||||||
S_DEF_COUNT
|
S_DEF_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Represents a configuration symbol.
|
|
||||||
*
|
|
||||||
* Choices are represented as a special kind of symbol and have the
|
|
||||||
* SYMBOL_CHOICE bit set in 'flags'.
|
|
||||||
*/
|
|
||||||
struct symbol {
|
struct symbol {
|
||||||
/* The next symbol in the same bucket in the symbol hash table */
|
|
||||||
struct symbol *next;
|
struct symbol *next;
|
||||||
|
|
||||||
/* The name of the symbol, e.g. "FOO" for 'config FOO' */
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
/* S_BOOLEAN, S_TRISTATE, ... */
|
|
||||||
enum symbol_type type;
|
enum symbol_type type;
|
||||||
|
|
||||||
/*
|
|
||||||
* The calculated value of the symbol. The SYMBOL_VALID bit is set in
|
|
||||||
* 'flags' when this is up to date. Note that this value might differ
|
|
||||||
* from the user value set in e.g. a .config file, due to visibility.
|
|
||||||
*/
|
|
||||||
struct symbol_value curr;
|
struct symbol_value curr;
|
||||||
|
|
||||||
/*
|
|
||||||
* Values for the symbol provided from outside. def[S_DEF_USER] holds
|
|
||||||
* the .config value.
|
|
||||||
*/
|
|
||||||
struct symbol_value def[S_DEF_COUNT];
|
struct symbol_value def[S_DEF_COUNT];
|
||||||
|
|
||||||
/*
|
|
||||||
* An upper bound on the tristate value the user can set for the symbol
|
|
||||||
* if it is a boolean or tristate. Calculated from prompt dependencies,
|
|
||||||
* which also inherit dependencies from enclosing menus, choices, and
|
|
||||||
* ifs. If 'n', the user value will be ignored.
|
|
||||||
*
|
|
||||||
* Symbols lacking prompts always have visibility 'n'.
|
|
||||||
*/
|
|
||||||
tristate visible;
|
tristate visible;
|
||||||
|
|
||||||
/* SYMBOL_* flags */
|
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
/* List of properties. See prop_type. */
|
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
|
|
||||||
/* Dependencies from enclosing menus, choices, and ifs */
|
|
||||||
struct expr_value dir_dep;
|
struct expr_value dir_dep;
|
||||||
|
|
||||||
/* Reverse dependencies through being selected by other symbols */
|
|
||||||
struct expr_value rev_dep;
|
struct expr_value rev_dep;
|
||||||
|
|
||||||
/*
|
|
||||||
* "Weak" reverse dependencies through being implied by other symbols
|
|
||||||
*/
|
|
||||||
struct expr_value implied;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next)
|
#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
|
||||||
|
|
||||||
#define SYMBOL_CONST 0x0001 /* symbol is const */
|
#define SYMBOL_CONST 0x0001 /* symbol is const */
|
||||||
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
|
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
|
||||||
@ -141,8 +97,7 @@ struct symbol {
|
|||||||
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
|
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
|
||||||
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
|
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
|
||||||
#define SYMBOL_CHANGED 0x0400 /* ? */
|
#define SYMBOL_CHANGED 0x0400 /* ? */
|
||||||
#define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */
|
#define SYMBOL_AUTO 0x1000 /* value from environment variable */
|
||||||
#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */
|
|
||||||
#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
|
#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
|
||||||
#define SYMBOL_WARNED 0x8000 /* warning has been issued */
|
#define SYMBOL_WARNED 0x8000 /* warning has been issued */
|
||||||
|
|
||||||
@ -172,26 +127,24 @@ struct symbol {
|
|||||||
* config BAZ
|
* config BAZ
|
||||||
* int "BAZ Value"
|
* int "BAZ Value"
|
||||||
* range 1..255
|
* range 1..255
|
||||||
*
|
|
||||||
* Please, also check parser.y:print_symbol() when modifying the
|
|
||||||
* list of property types!
|
|
||||||
*/
|
*/
|
||||||
enum prop_type {
|
enum prop_type {
|
||||||
P_UNKNOWN,
|
P_UNKNOWN,
|
||||||
P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */
|
P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */
|
||||||
P_COMMENT, /* text associated with a comment */
|
P_COMMENT, /* text associated with a comment */
|
||||||
P_MENU, /* prompt associated with a menu or menuconfig symbol */
|
P_MENU, /* prompt associated with a menuconfig option */
|
||||||
P_DEFAULT, /* default y */
|
P_DEFAULT, /* default y */
|
||||||
P_CHOICE, /* choice value */
|
P_CHOICE, /* choice value */
|
||||||
P_SELECT, /* select BAR */
|
P_SELECT, /* select BAR */
|
||||||
P_IMPLY, /* imply BAR */
|
|
||||||
P_RANGE, /* range 7..100 (for a symbol) */
|
P_RANGE, /* range 7..100 (for a symbol) */
|
||||||
|
P_ENV, /* value from environment variable */
|
||||||
P_SYMBOL, /* where a symbol is defined */
|
P_SYMBOL, /* where a symbol is defined */
|
||||||
P_RESET, /* reset to defaults condition */
|
P_RESET, /* reset to defaults condition */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct property {
|
struct property {
|
||||||
struct property *next; /* next property - null if last */
|
struct property *next; /* next property - null if last */
|
||||||
|
struct symbol *sym; /* the symbol for which the property is associated */
|
||||||
enum prop_type type; /* type of property */
|
enum prop_type type; /* type of property */
|
||||||
const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */
|
const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */
|
||||||
struct expr_value visible;
|
struct expr_value visible;
|
||||||
@ -212,67 +165,22 @@ struct property {
|
|||||||
for (st = sym->prop; st; st = st->next) \
|
for (st = sym->prop; st; st = st->next) \
|
||||||
if (st->text)
|
if (st->text)
|
||||||
|
|
||||||
/*
|
|
||||||
* Represents a node in the menu tree, as seen in e.g. menuconfig (though used
|
|
||||||
* for all front ends). Each symbol, menu, etc. defined in the Kconfig files
|
|
||||||
* gets a node. A symbol defined in multiple locations gets one node at each
|
|
||||||
* location.
|
|
||||||
*/
|
|
||||||
struct menu {
|
struct menu {
|
||||||
/* The next menu node at the same level */
|
|
||||||
struct menu *next;
|
struct menu *next;
|
||||||
|
|
||||||
/* The parent menu node, corresponding to e.g. a menu or choice */
|
|
||||||
struct menu *parent;
|
struct menu *parent;
|
||||||
|
|
||||||
/* The first child menu node, for e.g. menus and choices */
|
|
||||||
struct menu *list;
|
struct menu *list;
|
||||||
|
|
||||||
/*
|
|
||||||
* The symbol associated with the menu node. Choices are implemented as
|
|
||||||
* a special kind of symbol. NULL for menus, comments, and ifs.
|
|
||||||
*/
|
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
/*
|
|
||||||
* The prompt associated with the node. This holds the prompt for a
|
|
||||||
* symbol as well as the text for a menu or comment, along with the
|
|
||||||
* type (P_PROMPT, P_MENU, etc.)
|
|
||||||
*/
|
|
||||||
struct property *prompt;
|
struct property *prompt;
|
||||||
|
|
||||||
/*
|
|
||||||
* 'visible if' dependencies. If more than one is given, they will be
|
|
||||||
* ANDed together.
|
|
||||||
*/
|
|
||||||
struct expr *visibility;
|
struct expr *visibility;
|
||||||
|
|
||||||
/*
|
|
||||||
* Ordinary dependencies from e.g. 'depends on' and 'if', ANDed
|
|
||||||
* together
|
|
||||||
*/
|
|
||||||
struct expr *dep;
|
struct expr *dep;
|
||||||
|
|
||||||
/* MENU_* flags */
|
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
/* Any help text associated with the node */
|
|
||||||
char *help;
|
char *help;
|
||||||
|
|
||||||
/* The location where the menu node appears in the Kconfig files */
|
|
||||||
struct file *file;
|
struct file *file;
|
||||||
int lineno;
|
int lineno;
|
||||||
|
|
||||||
/* For use by front ends that need to store auxiliary data */
|
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Set on a menu node when the corresponding symbol changes state in some way.
|
|
||||||
* Can be checked by front ends.
|
|
||||||
*/
|
|
||||||
#define MENU_CHANGED 0x0001
|
#define MENU_CHANGED 0x0001
|
||||||
|
|
||||||
#define MENU_ROOT 0x0002
|
#define MENU_ROOT 0x0002
|
||||||
|
|
||||||
struct jump_key {
|
struct jump_key {
|
||||||
@ -301,7 +209,6 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
|
|||||||
struct expr *expr_copy(const struct expr *org);
|
struct expr *expr_copy(const struct expr *org);
|
||||||
void expr_free(struct expr *e);
|
void expr_free(struct expr *e);
|
||||||
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
|
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
|
||||||
int expr_eq(struct expr *e1, struct expr *e2);
|
|
||||||
tristate expr_calc_value(struct expr *e);
|
tristate expr_calc_value(struct expr *e);
|
||||||
struct expr *expr_trans_bool(struct expr *e);
|
struct expr *expr_trans_bool(struct expr *e);
|
||||||
struct expr *expr_eliminate_dups(struct expr *e);
|
struct expr *expr_eliminate_dups(struct expr *e);
|
||||||
@ -309,12 +216,11 @@ struct expr *expr_transform(struct expr *e);
|
|||||||
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
|
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
|
||||||
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
|
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
|
||||||
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
|
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
|
||||||
|
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
|
||||||
|
|
||||||
void expr_fprint(struct expr *e, FILE *out);
|
void expr_fprint(struct expr *e, FILE *out);
|
||||||
struct gstr; /* forward */
|
struct gstr; /* forward */
|
||||||
void expr_gstr_print(struct expr *e, struct gstr *gs);
|
void expr_gstr_print(struct expr *e, struct gstr *gs);
|
||||||
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
|
|
||||||
tristate pr_type, const char *title);
|
|
||||||
|
|
||||||
static inline int expr_is_yes(struct expr *e)
|
static inline int expr_is_yes(struct expr *e)
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "images.h"
|
static const char *xpm_load[] = {
|
||||||
|
|
||||||
const char *xpm_load[] = {
|
|
||||||
"22 22 5 1",
|
"22 22 5 1",
|
||||||
". c None",
|
". c None",
|
||||||
"# c #000000",
|
"# c #000000",
|
||||||
@ -35,7 +33,7 @@ const char *xpm_load[] = {
|
|||||||
"###############.......",
|
"###############.......",
|
||||||
"......................"};
|
"......................"};
|
||||||
|
|
||||||
const char *xpm_save[] = {
|
static const char *xpm_save[] = {
|
||||||
"22 22 5 1",
|
"22 22 5 1",
|
||||||
". c None",
|
". c None",
|
||||||
"# c #000000",
|
"# c #000000",
|
||||||
@ -65,7 +63,7 @@ const char *xpm_save[] = {
|
|||||||
"..##################..",
|
"..##################..",
|
||||||
"......................"};
|
"......................"};
|
||||||
|
|
||||||
const char *xpm_back[] = {
|
static const char *xpm_back[] = {
|
||||||
"22 22 3 1",
|
"22 22 3 1",
|
||||||
". c None",
|
". c None",
|
||||||
"# c #000083",
|
"# c #000083",
|
||||||
@ -93,7 +91,7 @@ const char *xpm_back[] = {
|
|||||||
"......................",
|
"......................",
|
||||||
"......................"};
|
"......................"};
|
||||||
|
|
||||||
const char *xpm_tree_view[] = {
|
static const char *xpm_tree_view[] = {
|
||||||
"22 22 2 1",
|
"22 22 2 1",
|
||||||
". c None",
|
". c None",
|
||||||
"# c #000000",
|
"# c #000000",
|
||||||
@ -120,7 +118,7 @@ const char *xpm_tree_view[] = {
|
|||||||
"......................",
|
"......................",
|
||||||
"......................"};
|
"......................"};
|
||||||
|
|
||||||
const char *xpm_single_view[] = {
|
static const char *xpm_single_view[] = {
|
||||||
"22 22 2 1",
|
"22 22 2 1",
|
||||||
". c None",
|
". c None",
|
||||||
"# c #000000",
|
"# c #000000",
|
||||||
@ -147,7 +145,7 @@ const char *xpm_single_view[] = {
|
|||||||
"......................",
|
"......................",
|
||||||
"......................"};
|
"......................"};
|
||||||
|
|
||||||
const char *xpm_split_view[] = {
|
static const char *xpm_split_view[] = {
|
||||||
"22 22 2 1",
|
"22 22 2 1",
|
||||||
". c None",
|
". c None",
|
||||||
"# c #000000",
|
"# c #000000",
|
||||||
@ -174,7 +172,7 @@ const char *xpm_split_view[] = {
|
|||||||
"......................",
|
"......................",
|
||||||
"......................"};
|
"......................"};
|
||||||
|
|
||||||
const char *xpm_symbol_no[] = {
|
static const char *xpm_symbol_no[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -191,7 +189,7 @@ const char *xpm_symbol_no[] = {
|
|||||||
" .......... ",
|
" .......... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_symbol_mod[] = {
|
static const char *xpm_symbol_mod[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -208,7 +206,7 @@ const char *xpm_symbol_mod[] = {
|
|||||||
" .......... ",
|
" .......... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_symbol_yes[] = {
|
static const char *xpm_symbol_yes[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -225,7 +223,7 @@ const char *xpm_symbol_yes[] = {
|
|||||||
" .......... ",
|
" .......... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_choice_no[] = {
|
static const char *xpm_choice_no[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -242,7 +240,7 @@ const char *xpm_choice_no[] = {
|
|||||||
" .... ",
|
" .... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_choice_yes[] = {
|
static const char *xpm_choice_yes[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -259,7 +257,7 @@ const char *xpm_choice_yes[] = {
|
|||||||
" .... ",
|
" .... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_menu[] = {
|
static const char *xpm_menu[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -276,7 +274,7 @@ const char *xpm_menu[] = {
|
|||||||
" .......... ",
|
" .......... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_menu_inv[] = {
|
static const char *xpm_menu_inv[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -293,7 +291,7 @@ const char *xpm_menu_inv[] = {
|
|||||||
" .......... ",
|
" .......... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_menuback[] = {
|
static const char *xpm_menuback[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
@ -310,7 +308,7 @@ const char *xpm_menuback[] = {
|
|||||||
" .......... ",
|
" .......... ",
|
||||||
" "};
|
" "};
|
||||||
|
|
||||||
const char *xpm_void[] = {
|
static const char *xpm_void[] = {
|
||||||
"12 12 2 1",
|
"12 12 2 1",
|
||||||
" c white",
|
" c white",
|
||||||
". c black",
|
". c black",
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IMAGES_H
|
|
||||||
#define IMAGES_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const char *xpm_load[];
|
|
||||||
extern const char *xpm_save[];
|
|
||||||
extern const char *xpm_back[];
|
|
||||||
extern const char *xpm_tree_view[];
|
|
||||||
extern const char *xpm_single_view[];
|
|
||||||
extern const char *xpm_split_view[];
|
|
||||||
extern const char *xpm_symbol_no[];
|
|
||||||
extern const char *xpm_symbol_mod[];
|
|
||||||
extern const char *xpm_symbol_yes[];
|
|
||||||
extern const char *xpm_choice_no[];
|
|
||||||
extern const char *xpm_choice_yes[];
|
|
||||||
extern const char *xpm_menu[];
|
|
||||||
extern const char *xpm_menu_inv[];
|
|
||||||
extern const char *xpm_menuback[];
|
|
||||||
extern const char *xpm_void[];
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* IMAGES_H */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LKC_H
|
#ifndef LKC_H
|
||||||
@ -8,6 +8,15 @@
|
|||||||
|
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
|
#ifndef KBUILD_NO_NLS
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
static inline const char *gettext(const char *txt) { return txt; }
|
||||||
|
static inline void textdomain(const char *domainname) {}
|
||||||
|
static inline void bindtextdomain(const char *name, const char *dir) {}
|
||||||
|
static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -20,6 +29,11 @@ extern "C" {
|
|||||||
#define PACKAGE "linux"
|
#define PACKAGE "linux"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LOCALEDIR "/usr/share/locale"
|
||||||
|
|
||||||
|
#define _(text) gettext(text)
|
||||||
|
#define N_(text) (text)
|
||||||
|
|
||||||
#ifndef CONFIG_
|
#ifndef CONFIG_
|
||||||
#define CONFIG_ "CONFIG_"
|
#define CONFIG_ "CONFIG_"
|
||||||
#endif
|
#endif
|
||||||
@ -30,17 +44,30 @@ static inline const char *CONFIG_prefix(void)
|
|||||||
#undef CONFIG_
|
#undef CONFIG_
|
||||||
#define CONFIG_ CONFIG_prefix()
|
#define CONFIG_ CONFIG_prefix()
|
||||||
|
|
||||||
|
#define TF_COMMAND 0x0001
|
||||||
|
#define TF_PARAM 0x0002
|
||||||
|
#define TF_OPTION 0x0004
|
||||||
|
|
||||||
enum conf_def_mode {
|
enum conf_def_mode {
|
||||||
def_default,
|
def_default,
|
||||||
def_yes,
|
def_yes,
|
||||||
def_mod,
|
def_mod,
|
||||||
def_y2m,
|
|
||||||
def_m2y,
|
|
||||||
def_no,
|
def_no,
|
||||||
def_random
|
def_random
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int yylineno;
|
#define T_OPT_MODULES 1
|
||||||
|
#define T_OPT_DEFCONFIG_LIST 2
|
||||||
|
#define T_OPT_ENV 3
|
||||||
|
#define T_OPT_ALLNOCONFIG_Y 4
|
||||||
|
|
||||||
|
struct kconf_id {
|
||||||
|
int name;
|
||||||
|
int token;
|
||||||
|
unsigned int flags;
|
||||||
|
enum symbol_type stype;
|
||||||
|
};
|
||||||
|
|
||||||
void zconfdump(FILE *out);
|
void zconfdump(FILE *out);
|
||||||
void zconf_starthelp(void);
|
void zconf_starthelp(void);
|
||||||
FILE *zconf_fopen(const char *name);
|
FILE *zconf_fopen(const char *name);
|
||||||
@ -51,10 +78,11 @@ const char *zconf_curname(void);
|
|||||||
|
|
||||||
/* confdata.c */
|
/* confdata.c */
|
||||||
const char *conf_get_configname(void);
|
const char *conf_get_configname(void);
|
||||||
|
const char *conf_get_autoconfig_name(void);
|
||||||
|
char *conf_get_default_confname(void);
|
||||||
void sym_set_change_count(int count);
|
void sym_set_change_count(int count);
|
||||||
void sym_add_change_count(int count);
|
void sym_add_change_count(int count);
|
||||||
bool conf_set_all_new_symbols(enum conf_def_mode mode);
|
bool conf_set_all_new_symbols(enum conf_def_mode mode);
|
||||||
void conf_rewrite_mod_or_yes(enum conf_def_mode mode);
|
|
||||||
void set_all_choice_values(struct symbol *csym);
|
void set_all_choice_values(struct symbol *csym);
|
||||||
|
|
||||||
/* confdata.c and expr.c */
|
/* confdata.c and expr.c */
|
||||||
@ -72,28 +100,22 @@ void menu_warn(struct menu *menu, const char *fmt, ...);
|
|||||||
struct menu *menu_add_menu(void);
|
struct menu *menu_add_menu(void);
|
||||||
void menu_end_menu(void);
|
void menu_end_menu(void);
|
||||||
void menu_add_entry(struct symbol *sym);
|
void menu_add_entry(struct symbol *sym);
|
||||||
|
void menu_end_entry(void);
|
||||||
void menu_add_dep(struct expr *dep);
|
void menu_add_dep(struct expr *dep);
|
||||||
void menu_add_visibility(struct expr *dep);
|
void menu_add_visibility(struct expr *dep);
|
||||||
struct property *menu_add_prop(enum prop_type type, struct expr *expr, struct expr *dep);
|
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
|
||||||
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
|
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
|
||||||
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
|
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
|
||||||
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
|
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
|
||||||
void menu_add_option_modules(void);
|
void menu_add_option(int token, char *arg);
|
||||||
void menu_add_option_defconfig_list(void);
|
|
||||||
void menu_add_option_allnoconfig_y(void);
|
|
||||||
void menu_finalize(struct menu *parent);
|
void menu_finalize(struct menu *parent);
|
||||||
void menu_set_type(int type);
|
void menu_set_type(int type);
|
||||||
|
|
||||||
/* util.c */
|
/* util.c */
|
||||||
struct file *file_lookup(const char *name);
|
struct file *file_lookup(const char *name);
|
||||||
|
int file_write_dep(const char *name);
|
||||||
void *xmalloc(size_t size);
|
void *xmalloc(size_t size);
|
||||||
void *xcalloc(size_t nmemb, size_t size);
|
void *xcalloc(size_t nmemb, size_t size);
|
||||||
void *xrealloc(void *p, size_t size);
|
|
||||||
char *xstrdup(const char *s);
|
|
||||||
char *xstrndup(const char *s, size_t n);
|
|
||||||
|
|
||||||
/* lexer.l */
|
|
||||||
int yylex(void);
|
|
||||||
|
|
||||||
struct gstr {
|
struct gstr {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -111,12 +133,16 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
|
|||||||
const char *str_get(struct gstr *gs);
|
const char *str_get(struct gstr *gs);
|
||||||
|
|
||||||
/* symbol.c */
|
/* symbol.c */
|
||||||
|
extern struct expr *sym_env_list;
|
||||||
|
|
||||||
|
void sym_init(void);
|
||||||
void sym_clear_all_valid(void);
|
void sym_clear_all_valid(void);
|
||||||
struct symbol *sym_choice_default(struct symbol *sym);
|
struct symbol *sym_choice_default(struct symbol *sym);
|
||||||
struct property *sym_get_range_prop(struct symbol *sym);
|
|
||||||
const char *sym_get_string_default(struct symbol *sym);
|
const char *sym_get_string_default(struct symbol *sym);
|
||||||
struct symbol *sym_check_deps(struct symbol *sym);
|
struct symbol *sym_check_deps(struct symbol *sym);
|
||||||
|
struct property *prop_alloc(enum prop_type type, struct symbol *sym);
|
||||||
struct symbol *prop_get_symbol(struct property *prop);
|
struct symbol *prop_get_symbol(struct property *prop);
|
||||||
|
struct property *sym_get_env_prop(struct symbol *sym);
|
||||||
|
|
||||||
static inline tristate sym_get_tristate_value(struct symbol *sym)
|
static inline tristate sym_get_tristate_value(struct symbol *sym)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* confdata.c */
|
/* confdata.c */
|
||||||
@ -8,10 +7,10 @@ int conf_read_simple(const char *name, int);
|
|||||||
void conf_reset(int def);
|
void conf_reset(int def);
|
||||||
int conf_write_defconfig(const char *name);
|
int conf_write_defconfig(const char *name);
|
||||||
int conf_write(const char *name);
|
int conf_write(const char *name);
|
||||||
int conf_write_autoconf(int overwrite);
|
int conf_write_autoconf(void);
|
||||||
bool conf_get_changed(void);
|
bool conf_get_changed(void);
|
||||||
void conf_set_changed_callback(void (*fn)(void));
|
void conf_set_changed_callback(void (*fn)(void));
|
||||||
void conf_set_message_callback(void (*fn)(const char *s));
|
void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap));
|
||||||
|
|
||||||
/* menu.c */
|
/* menu.c */
|
||||||
extern struct menu rootmenu;
|
extern struct menu rootmenu;
|
||||||
@ -32,6 +31,7 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
|
|||||||
|
|
||||||
struct symbol * sym_lookup(const char *name, int flags);
|
struct symbol * sym_lookup(const char *name, int flags);
|
||||||
struct symbol * sym_find(const char *name);
|
struct symbol * sym_find(const char *name);
|
||||||
|
const char * sym_expand_string_value(const char *in);
|
||||||
const char * sym_escape_string_value(const char *in);
|
const char * sym_escape_string_value(const char *in);
|
||||||
struct symbol ** sym_re_search(const char *pattern);
|
struct symbol ** sym_re_search(const char *pattern);
|
||||||
const char * sym_type_name(enum symbol_type type);
|
const char * sym_type_name(enum symbol_type type);
|
||||||
@ -43,24 +43,11 @@ tristate sym_toggle_tristate_value(struct symbol *sym);
|
|||||||
bool sym_string_valid(struct symbol *sym, const char *newval);
|
bool sym_string_valid(struct symbol *sym, const char *newval);
|
||||||
bool sym_string_within_range(struct symbol *sym, const char *str);
|
bool sym_string_within_range(struct symbol *sym, const char *str);
|
||||||
bool sym_set_string_value(struct symbol *sym, const char *newval);
|
bool sym_set_string_value(struct symbol *sym, const char *newval);
|
||||||
bool sym_is_changeable(struct symbol *sym);
|
bool sym_is_changable(struct symbol *sym);
|
||||||
struct property * sym_get_choice_prop(struct symbol *sym);
|
struct property * sym_get_choice_prop(struct symbol *sym);
|
||||||
const char * sym_get_string_value(struct symbol *sym);
|
const char * sym_get_string_value(struct symbol *sym);
|
||||||
|
|
||||||
const char * prop_get_type_name(enum prop_type type);
|
const char * prop_get_type_name(enum prop_type type);
|
||||||
|
|
||||||
/* preprocess.c */
|
|
||||||
enum variable_flavor {
|
|
||||||
VAR_SIMPLE,
|
|
||||||
VAR_RECURSIVE,
|
|
||||||
VAR_APPEND,
|
|
||||||
};
|
|
||||||
void env_write_dep(FILE *f, const char *auto_conf_name);
|
|
||||||
void variable_add(const char *name, const char *value,
|
|
||||||
enum variable_flavor flavor);
|
|
||||||
void variable_all_del(void);
|
|
||||||
char *expand_dollar(const char **str);
|
|
||||||
char *expand_one_token(const char **str);
|
|
||||||
|
|
||||||
/* expr.c */
|
/* expr.c */
|
||||||
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
|
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
|
||||||
|
2
scripts/config/lxdialog/.gitignore
vendored
Normal file
2
scripts/config/lxdialog/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
lxdialog
|
||||||
|
*.o
|
91
scripts/config/lxdialog/check-lxdialog.sh
Normal file
91
scripts/config/lxdialog/check-lxdialog.sh
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Check ncurses compatibility
|
||||||
|
|
||||||
|
# What library to link
|
||||||
|
ldflags()
|
||||||
|
{
|
||||||
|
pkg-config --libs ncursesw 2>/dev/null && exit
|
||||||
|
pkg-config --libs ncurses 2>/dev/null && exit
|
||||||
|
for ext in so a dll.a dylib ; do
|
||||||
|
for lib in ncursesw ncurses curses ; do
|
||||||
|
$cc -print-file-name=lib${lib}.${ext} | grep -q /
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "-l${lib}"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Where is ncurses.h?
|
||||||
|
ccflags()
|
||||||
|
{
|
||||||
|
if pkg-config --cflags ncursesw 2>/dev/null; then
|
||||||
|
echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
|
||||||
|
elif pkg-config --cflags ncurses 2>/dev/null; then
|
||||||
|
echo '-DCURSES_LOC="<ncurses.h>"'
|
||||||
|
elif [ -f /usr/include/ncursesw/curses.h ]; then
|
||||||
|
echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
|
||||||
|
echo ' -DNCURSES_WIDECHAR=1'
|
||||||
|
elif [ -f /usr/include/ncurses/ncurses.h ]; then
|
||||||
|
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
|
||||||
|
elif [ -f /usr/include/ncurses/curses.h ]; then
|
||||||
|
echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
|
||||||
|
elif [ -f /usr/include/ncurses.h ]; then
|
||||||
|
echo '-DCURSES_LOC="<ncurses.h>"'
|
||||||
|
else
|
||||||
|
echo '-DCURSES_LOC="<curses.h>"'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Temp file, try to clean up after us
|
||||||
|
tmp=.lxdialog.tmp
|
||||||
|
trap "rm -f $tmp" 0 1 2 3 15
|
||||||
|
|
||||||
|
# Check if we can link to ncurses
|
||||||
|
check() {
|
||||||
|
$cc -x c - -o $tmp 2>/dev/null <<'EOF'
|
||||||
|
#include CURSES_LOC
|
||||||
|
main() {}
|
||||||
|
EOF
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
echo " *** Unable to find the ncurses libraries or the" 1>&2
|
||||||
|
echo " *** required header files." 1>&2
|
||||||
|
echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
|
||||||
|
echo " *** " 1>&2
|
||||||
|
echo " *** Install ncurses (ncurses-devel) and try again." 1>&2
|
||||||
|
echo " *** " 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cc=""
|
||||||
|
case "$1" in
|
||||||
|
"-check")
|
||||||
|
shift
|
||||||
|
cc="$@"
|
||||||
|
check
|
||||||
|
;;
|
||||||
|
"-ccflags")
|
||||||
|
ccflags
|
||||||
|
;;
|
||||||
|
"-ldflags")
|
||||||
|
shift
|
||||||
|
cc="$@"
|
||||||
|
ldflags
|
||||||
|
;;
|
||||||
|
"*")
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@ -1,4 +1,3 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
/*
|
||||||
* checklist.c -- implements the checklist box
|
* checklist.c -- implements the checklist box
|
||||||
*
|
*
|
||||||
@ -6,6 +5,20 @@
|
|||||||
* Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
|
* Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
|
||||||
* Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
|
* Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
|
||||||
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
|
* 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"
|
#include "dialog.h"
|
||||||
@ -90,8 +103,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
|
|||||||
int x = width / 2 - 11;
|
int x = width / 2 - 11;
|
||||||
int y = height - 2;
|
int y = height - 2;
|
||||||
|
|
||||||
print_button(dialog, "Select", y, x, selected == 0);
|
print_button(dialog, gettext("Select"), y, x, selected == 0);
|
||||||
print_button(dialog, " Help ", y, x + 14, selected == 1);
|
print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
|
||||||
|
|
||||||
wmove(dialog, y, x + 1 + 14 * selected);
|
wmove(dialog, y, x + 1 + 14 * selected);
|
||||||
wrefresh(dialog);
|
wrefresh(dialog);
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
||||||
/*
|
/*
|
||||||
* dialog.h -- common declarations for all dialog modules
|
* dialog.h -- common declarations for all dialog modules
|
||||||
*
|
*
|
||||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -13,10 +26,16 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifndef KBUILD_NO_NLS
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# define gettext(Msgid) ((const char *) (Msgid))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __sun__
|
#ifdef __sun__
|
||||||
#define CURS_MACROS
|
#define CURS_MACROS
|
||||||
#endif
|
#endif
|
||||||
#include <ncurses.h>
|
#include CURSES_LOC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Colors in ncurses 1.9.9e do not work properly since foreground and
|
* Colors in ncurses 1.9.9e do not work properly since foreground and
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
/*
|
||||||
* inputbox.c -- implements the input box
|
* inputbox.c -- implements the input box
|
||||||
*
|
*
|
||||||
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||||
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
|
* 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"
|
#include "dialog.h"
|
||||||
@ -18,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
|
|||||||
int x = width / 2 - 11;
|
int x = width / 2 - 11;
|
||||||
int y = height - 2;
|
int y = height - 2;
|
||||||
|
|
||||||
print_button(dialog, " Ok ", y, x, selected == 0);
|
print_button(dialog, gettext(" Ok "), y, x, selected == 0);
|
||||||
print_button(dialog, " Help ", y, x + 14, selected == 1);
|
print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
|
||||||
|
|
||||||
wmove(dialog, y, x + 1 + 14 * selected);
|
wmove(dialog, y, x + 1 + 14 * selected);
|
||||||
wrefresh(dialog);
|
wrefresh(dialog);
|
||||||
@ -113,8 +126,7 @@ do_resize:
|
|||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
break;
|
break;
|
||||||
case KEY_BACKSPACE:
|
case KEY_BACKSPACE:
|
||||||
case 8: /* ^H */
|
case 127:
|
||||||
case 127: /* ^? */
|
|
||||||
if (pos) {
|
if (pos) {
|
||||||
wattrset(dialog, dlg.inputbox.atr);
|
wattrset(dialog, dlg.inputbox.atr);
|
||||||
if (input_x == 0) {
|
if (input_x == 0) {
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
/*
|
||||||
* menubox.c -- implements the menu box
|
* menubox.c -- implements the menu box
|
||||||
*
|
*
|
||||||
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||||
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
|
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -144,11 +157,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
|
|||||||
int x = width / 2 - 28;
|
int x = width / 2 - 28;
|
||||||
int y = height - 2;
|
int y = height - 2;
|
||||||
|
|
||||||
print_button(win, "Select", y, x, selected == 0);
|
print_button(win, gettext("Select"), y, x, selected == 0);
|
||||||
print_button(win, " Exit ", y, x + 12, selected == 1);
|
print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
|
||||||
print_button(win, " Help ", y, x + 24, selected == 2);
|
print_button(win, gettext(" Help "), y, x + 24, selected == 2);
|
||||||
print_button(win, " Save ", y, x + 36, selected == 3);
|
print_button(win, gettext(" Save "), y, x + 36, selected == 3);
|
||||||
print_button(win, " Load ", y, x + 48, selected == 4);
|
print_button(win, gettext(" Load "), y, x + 48, selected == 4);
|
||||||
|
|
||||||
wmove(win, y, x + 1 + 12 * selected);
|
wmove(win, y, x + 1 + 12 * selected);
|
||||||
wrefresh(win);
|
wrefresh(win);
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
/*
|
||||||
* textbox.c -- implements the text box
|
* textbox.c -- implements the text box
|
||||||
*
|
*
|
||||||
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||||
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
|
* 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"
|
#include "dialog.h"
|
||||||
@ -116,7 +129,7 @@ do_resize:
|
|||||||
|
|
||||||
print_title(dialog, title, width);
|
print_title(dialog, title, width);
|
||||||
|
|
||||||
print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
|
print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
|
||||||
wnoutrefresh(dialog);
|
wnoutrefresh(dialog);
|
||||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||||
|
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
/*
|
||||||
* util.c
|
* util.c
|
||||||
*
|
*
|
||||||
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||||
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
|
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
/*
|
||||||
* yesno.c -- implements the yes/no box
|
* yesno.c -- implements the yes/no box
|
||||||
*
|
*
|
||||||
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||||
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
|
* 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"
|
#include "dialog.h"
|
||||||
@ -16,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
|
|||||||
int x = width / 2 - 10;
|
int x = width / 2 - 10;
|
||||||
int y = height - 2;
|
int y = height - 2;
|
||||||
|
|
||||||
print_button(dialog, " Yes ", y, x, selected == 0);
|
print_button(dialog, gettext(" Yes "), y, x, selected == 0);
|
||||||
print_button(dialog, " No ", y, x + 13, selected == 1);
|
print_button(dialog, gettext(" No "), y, x + 13, selected == 1);
|
||||||
|
|
||||||
wmove(dialog, y, x + 1 + 13 * selected);
|
wmove(dialog, y, x + 1 + 13 * selected);
|
||||||
wrefresh(dialog);
|
wrefresh(dialog);
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
PKG="ncursesw"
|
|
||||||
PKG2="ncurses"
|
|
||||||
|
|
||||||
if [ -n "$(command -v pkg-config)" ]; then
|
|
||||||
if pkg-config --exists $PKG; then
|
|
||||||
echo cflags=\"$(pkg-config --cflags $PKG)\"
|
|
||||||
echo libs=\"$(pkg-config --libs $PKG)\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if pkg-config --exists $PKG2; then
|
|
||||||
echo cflags=\"$(pkg-config --cflags $PKG2)\"
|
|
||||||
echo libs=\"$(pkg-config --libs $PKG2)\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the default paths in case pkg-config is not installed.
|
|
||||||
# (Even if it is installed, some distributions such as openSUSE cannot
|
|
||||||
# find ncurses by pkg-config.)
|
|
||||||
if [ -f /usr/include/ncursesw/ncurses.h ]; then
|
|
||||||
echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
|
|
||||||
echo libs=\"-lncursesw\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f /usr/include/ncurses/ncurses.h ]; then
|
|
||||||
echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
|
|
||||||
echo libs=\"-lncurses\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f /usr/include/ncurses.h ]; then
|
|
||||||
echo cflags=\"-D_GNU_SOURCE\"
|
|
||||||
echo libs=\"-lncurses\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo >&2 "*"
|
|
||||||
echo >&2 "* Unable to find the ncurses package."
|
|
||||||
echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
|
|
||||||
echo >&2 "* depending on your distribution)."
|
|
||||||
echo >&2 "*"
|
|
||||||
echo >&2 "* You may also need to install pkg-config to find the"
|
|
||||||
echo >&2 "* ncurses installed in a non-default location."
|
|
||||||
echo >&2 "*"
|
|
||||||
exit 1
|
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*
|
*
|
||||||
* Introduced single menu mode (show all sub-menus in one large tree).
|
* Introduced single menu mode (show all sub-menus in one large tree).
|
||||||
* 2002-11-06 Petr Baudis <pasky@ucw.cz>
|
* 2002-11-06 Petr Baudis <pasky@ucw.cz>
|
||||||
@ -15,27 +15,23 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#include "lkc.h"
|
#include "lkc.h"
|
||||||
#include "lxdialog/dialog.h"
|
#include "lxdialog/dialog.h"
|
||||||
|
|
||||||
static const char mconf_readme[] =
|
static const char mconf_readme[] = N_(
|
||||||
"Overview\n"
|
"Overview\n"
|
||||||
"--------\n"
|
"--------\n"
|
||||||
"Some OpenWrt features may be built directly into the image.\n"
|
"Some OpenWrt features may be built directly into the image.\n"
|
||||||
"Some may be made into installable ipkg packages (referred here as\n"
|
"Some may be made into installable ipkg packages. Some features\n"
|
||||||
"modules). Some features may be completely removed altogether.\n"
|
"may be completely removed altogether.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Menu items beginning with following braces represent features that\n"
|
"Menu items beginning with [*], <M> or [ ] represent features\n"
|
||||||
" [ ] can be built in or removed\n"
|
"configured to be included, built as package or removed respectively.\n"
|
||||||
" < > can be built in, modularized or removed\n"
|
"Pointed brackets <> represent packaging capable features.\n"
|
||||||
" { } can be built in or modularized (selected by other feature)\n"
|
|
||||||
" - - are selected by other feature,\n"
|
|
||||||
"while *, M or whitespace inside braces means to build in, build as\n"
|
|
||||||
"a module or to exclude the feature respectively.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"To change any of these features, highlight it with the cursor\n"
|
"To change any of these features, highlight it with the cursor\n"
|
||||||
"keys and press <Y> to build it in, <M> to make it a module or\n"
|
"keys and press <Y> to build it in, <M> to make it a module or\n"
|
||||||
@ -171,37 +167,37 @@ static const char mconf_readme[] =
|
|||||||
" blackbg => selects a color scheme with black background\n"
|
" blackbg => selects a color scheme with black background\n"
|
||||||
" classic => theme with blue background. The classic look\n"
|
" classic => theme with blue background. The classic look\n"
|
||||||
" bluetitle => an LCD friendly version of classic. (default)\n"
|
" bluetitle => an LCD friendly version of classic. (default)\n"
|
||||||
"\n",
|
"\n"),
|
||||||
menu_instructions[] =
|
menu_instructions[] = N_(
|
||||||
"Arrow keys navigate the menu. "
|
"Arrow keys navigate the menu. "
|
||||||
"<Enter> selects submenus ---> (or empty submenus ----). "
|
"<Enter> selects submenus ---> (or empty submenus ----). "
|
||||||
"Highlighted letters are hotkeys. "
|
"Highlighted letters are hotkeys. "
|
||||||
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
|
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
|
||||||
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
|
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
|
||||||
"Legend: [*] built-in [ ] excluded <M> module < > module capable",
|
"Legend: [*] built-in [ ] excluded <M> module < > module capable"),
|
||||||
radiolist_instructions[] =
|
radiolist_instructions[] = N_(
|
||||||
"Use the arrow keys to navigate this window or "
|
"Use the arrow keys to navigate this window or "
|
||||||
"press the hotkey of the item you wish to select "
|
"press the hotkey of the item you wish to select "
|
||||||
"followed by the <SPACE BAR>. "
|
"followed by the <SPACE BAR>. "
|
||||||
"Press <?> for additional information about this option.",
|
"Press <?> for additional information about this option."),
|
||||||
inputbox_instructions_int[] =
|
inputbox_instructions_int[] = N_(
|
||||||
"Please enter a decimal value. "
|
"Please enter a decimal value. "
|
||||||
"Fractions will not be accepted. "
|
"Fractions will not be accepted. "
|
||||||
"Use the <TAB> key to move from the input field to the buttons below it.",
|
"Use the <TAB> key to move from the input field to the buttons below it."),
|
||||||
inputbox_instructions_hex[] =
|
inputbox_instructions_hex[] = N_(
|
||||||
"Please enter a hexadecimal value. "
|
"Please enter a hexadecimal value. "
|
||||||
"Use the <TAB> key to move from the input field to the buttons below it.",
|
"Use the <TAB> key to move from the input field to the buttons below it."),
|
||||||
inputbox_instructions_string[] =
|
inputbox_instructions_string[] = N_(
|
||||||
"Please enter a string value. "
|
"Please enter a string value. "
|
||||||
"Use the <TAB> key to move from the input field to the buttons below it.",
|
"Use the <TAB> key to move from the input field to the buttons below it."),
|
||||||
setmod_text[] =
|
setmod_text[] = N_(
|
||||||
"This feature depends on another which has been configured as a module.\n"
|
"This feature depends on another which has been configured as a module.\n"
|
||||||
"As a result, this feature will be built as a module.",
|
"As a result, this feature will be built as a module."),
|
||||||
load_config_text[] =
|
load_config_text[] = N_(
|
||||||
"Enter the name of the configuration file you wish to load. "
|
"Enter the name of the configuration file you wish to load. "
|
||||||
"Accept the name shown to restore the configuration you "
|
"Accept the name shown to restore the configuration you "
|
||||||
"last retrieved. Leave blank to abort.",
|
"last retrieved. Leave blank to abort."),
|
||||||
load_config_help[] =
|
load_config_help[] = N_(
|
||||||
"\n"
|
"\n"
|
||||||
"For various reasons, one may wish to keep several different\n"
|
"For various reasons, one may wish to keep several different\n"
|
||||||
"configurations available on a single machine.\n"
|
"configurations available on a single machine.\n"
|
||||||
@ -211,11 +207,11 @@ load_config_help[] =
|
|||||||
"configuration.\n"
|
"configuration.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If you are uncertain, then you have probably never used alternate\n"
|
"If you are uncertain, then you have probably never used alternate\n"
|
||||||
"configuration files. You should therefore leave this blank to abort.\n",
|
"configuration files. You should therefore leave this blank to abort.\n"),
|
||||||
save_config_text[] =
|
save_config_text[] = N_(
|
||||||
"Enter a filename to which this configuration should be saved "
|
"Enter a filename to which this configuration should be saved "
|
||||||
"as an alternate. Leave blank to abort.",
|
"as an alternate. Leave blank to abort."),
|
||||||
save_config_help[] =
|
save_config_help[] = N_(
|
||||||
"\n"
|
"\n"
|
||||||
"For various reasons, one may wish to keep different configurations\n"
|
"For various reasons, one may wish to keep different configurations\n"
|
||||||
"available on a single machine.\n"
|
"available on a single machine.\n"
|
||||||
@ -225,8 +221,8 @@ save_config_help[] =
|
|||||||
"configuration options you have selected at that time.\n"
|
"configuration options you have selected at that time.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If you are uncertain what all this means then you should probably\n"
|
"If you are uncertain what all this means then you should probably\n"
|
||||||
"leave this blank.\n",
|
"leave this blank.\n"),
|
||||||
search_help[] =
|
search_help[] = N_(
|
||||||
"\n"
|
"\n"
|
||||||
"Search for symbols and display their relations.\n"
|
"Search for symbols and display their relations.\n"
|
||||||
"Regular expressions are allowed.\n"
|
"Regular expressions are allowed.\n"
|
||||||
@ -246,7 +242,7 @@ search_help[] =
|
|||||||
" Selected by: BAR [=n]\n"
|
" Selected by: BAR [=n]\n"
|
||||||
"-----------------------------------------------------------------\n"
|
"-----------------------------------------------------------------\n"
|
||||||
"o The line 'Type:' shows the type of the configuration option for\n"
|
"o The line 'Type:' shows the type of the configuration option for\n"
|
||||||
" this symbol (bool, tristate, string, ...)\n"
|
" this symbol (boolean, tristate, string, ...)\n"
|
||||||
"o The line 'Prompt:' shows the text used in the menu structure for\n"
|
"o The line 'Prompt:' shows the text used in the menu structure for\n"
|
||||||
" this symbol\n"
|
" this symbol\n"
|
||||||
"o The 'Defined at' line tells at what file / line number the symbol\n"
|
"o The 'Defined at' line tells at what file / line number the symbol\n"
|
||||||
@ -271,7 +267,7 @@ search_help[] =
|
|||||||
"Examples: USB => find all symbols containing USB\n"
|
"Examples: USB => find all symbols containing USB\n"
|
||||||
" ^USB => find all symbols starting with USB\n"
|
" ^USB => find all symbols starting with USB\n"
|
||||||
" USB$ => find all symbols ending with USB\n"
|
" USB$ => find all symbols ending with USB\n"
|
||||||
"\n";
|
"\n");
|
||||||
|
|
||||||
static int indent;
|
static int indent;
|
||||||
static struct menu *current_menu;
|
static struct menu *current_menu;
|
||||||
@ -400,19 +396,19 @@ static void search_conf(void)
|
|||||||
struct subtitle_part stpart;
|
struct subtitle_part stpart;
|
||||||
|
|
||||||
title = str_new();
|
title = str_new();
|
||||||
str_printf( &title, "Enter (sub)string or regexp to search for "
|
str_printf( &title, _("Enter (sub)string or regexp to search for "
|
||||||
"(with or without \"%s\")", CONFIG_);
|
"(with or without \"%s\")"), CONFIG_);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
dialog_clear();
|
dialog_clear();
|
||||||
dres = dialog_inputbox("Search Configuration Parameter",
|
dres = dialog_inputbox(_("Search Configuration Parameter"),
|
||||||
str_get(&title),
|
str_get(&title),
|
||||||
10, 75, "");
|
10, 75, "");
|
||||||
switch (dres) {
|
switch (dres) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
show_helptext("Search Configuration", search_help);
|
show_helptext(_("Search Configuration"), search_help);
|
||||||
goto again;
|
goto again;
|
||||||
default:
|
default:
|
||||||
str_free(&title);
|
str_free(&title);
|
||||||
@ -443,7 +439,7 @@ again:
|
|||||||
|
|
||||||
res = get_relations_str(sym_arr, &head);
|
res = get_relations_str(sym_arr, &head);
|
||||||
set_subtitle();
|
set_subtitle();
|
||||||
dres = show_textbox_ext("Search Results", (char *)
|
dres = show_textbox_ext(_("Search Results"), (char *)
|
||||||
str_get(&res), 0, 0, keys, &vscroll,
|
str_get(&res), 0, 0, keys, &vscroll,
|
||||||
&hscroll, &update_text, (void *)
|
&hscroll, &update_text, (void *)
|
||||||
&data);
|
&data);
|
||||||
@ -491,6 +487,7 @@ static void build_conf(struct menu *menu)
|
|||||||
switch (prop->type) {
|
switch (prop->type) {
|
||||||
case P_MENU:
|
case P_MENU:
|
||||||
child_count++;
|
child_count++;
|
||||||
|
prompt = _(prompt);
|
||||||
if (single_menu_mode) {
|
if (single_menu_mode) {
|
||||||
item_make("%s%*c%s",
|
item_make("%s%*c%s",
|
||||||
menu->data ? "-->" : "++>",
|
menu->data ? "-->" : "++>",
|
||||||
@ -507,7 +504,7 @@ static void build_conf(struct menu *menu)
|
|||||||
case P_COMMENT:
|
case P_COMMENT:
|
||||||
if (prompt) {
|
if (prompt) {
|
||||||
child_count++;
|
child_count++;
|
||||||
item_make(" %*c*** %s ***", indent + 1, ' ', prompt);
|
item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
|
||||||
item_set_tag(':');
|
item_set_tag(':');
|
||||||
item_set_data(menu);
|
item_set_data(menu);
|
||||||
}
|
}
|
||||||
@ -515,7 +512,7 @@ static void build_conf(struct menu *menu)
|
|||||||
default:
|
default:
|
||||||
if (prompt) {
|
if (prompt) {
|
||||||
child_count++;
|
child_count++;
|
||||||
item_make("---%*c%s", indent + 1, ' ', prompt);
|
item_make("---%*c%s", indent + 1, ' ', _(prompt));
|
||||||
item_set_tag(':');
|
item_set_tag(':');
|
||||||
item_set_data(menu);
|
item_set_data(menu);
|
||||||
}
|
}
|
||||||
@ -537,7 +534,7 @@ static void build_conf(struct menu *menu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
val = sym_get_tristate_value(sym);
|
val = sym_get_tristate_value(sym);
|
||||||
if (sym_is_changeable(sym)) {
|
if (sym_is_changable(sym)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
item_make("[%c]", val == no ? ' ' : '*');
|
item_make("[%c]", val == no ? ' ' : '*');
|
||||||
@ -559,10 +556,10 @@ static void build_conf(struct menu *menu)
|
|||||||
item_set_data(menu);
|
item_set_data(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
|
item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
|
||||||
if (val == yes) {
|
if (val == yes) {
|
||||||
if (def_menu) {
|
if (def_menu) {
|
||||||
item_add_str(" (%s)", menu_get_prompt(def_menu));
|
item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
|
||||||
item_add_str(" --->");
|
item_add_str(" --->");
|
||||||
if (def_menu->list) {
|
if (def_menu->list) {
|
||||||
indent += 2;
|
indent += 2;
|
||||||
@ -574,7 +571,7 @@ static void build_conf(struct menu *menu)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (menu == current_menu) {
|
if (menu == current_menu) {
|
||||||
item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
|
item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
|
||||||
item_set_tag(':');
|
item_set_tag(':');
|
||||||
item_set_data(menu);
|
item_set_data(menu);
|
||||||
goto conf_childs;
|
goto conf_childs;
|
||||||
@ -588,7 +585,7 @@ static void build_conf(struct menu *menu)
|
|||||||
} else {
|
} else {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
if (sym_is_changeable(sym))
|
if (sym_is_changable(sym))
|
||||||
item_make("[%c]", val == no ? ' ' : '*');
|
item_make("[%c]", val == no ? ' ' : '*');
|
||||||
else
|
else
|
||||||
item_make("-%c-", val == no ? ' ' : '*');
|
item_make("-%c-", val == no ? ' ' : '*');
|
||||||
@ -601,7 +598,7 @@ static void build_conf(struct menu *menu)
|
|||||||
case mod: ch = 'M'; break;
|
case mod: ch = 'M'; break;
|
||||||
default: ch = ' '; break;
|
default: ch = ' '; break;
|
||||||
}
|
}
|
||||||
if (sym_is_changeable(sym)) {
|
if (sym_is_changable(sym)) {
|
||||||
if (sym->rev_dep.tri == mod)
|
if (sym->rev_dep.tri == mod)
|
||||||
item_make("{%c}", ch);
|
item_make("{%c}", ch);
|
||||||
else
|
else
|
||||||
@ -617,17 +614,17 @@ static void build_conf(struct menu *menu)
|
|||||||
tmp = indent - tmp + 4;
|
tmp = indent - tmp + 4;
|
||||||
if (tmp < 0)
|
if (tmp < 0)
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
|
item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
|
||||||
(sym_has_value(sym) || !sym_is_changeable(sym)) ?
|
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
||||||
"" : " (NEW)");
|
"" : _(" (NEW)"));
|
||||||
item_set_tag('s');
|
item_set_tag('s');
|
||||||
item_set_data(menu);
|
item_set_data(menu);
|
||||||
goto conf_childs;
|
goto conf_childs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
|
item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
|
||||||
(sym_has_value(sym) || !sym_is_changeable(sym)) ?
|
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
||||||
"" : " (NEW)");
|
"" : _(" (NEW)"));
|
||||||
if (menu->prompt->type == P_MENU) {
|
if (menu->prompt->type == P_MENU) {
|
||||||
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
|
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
|
||||||
return;
|
return;
|
||||||
@ -664,8 +661,8 @@ static void conf(struct menu *menu, struct menu *active_menu)
|
|||||||
break;
|
break;
|
||||||
set_subtitle();
|
set_subtitle();
|
||||||
dialog_clear();
|
dialog_clear();
|
||||||
res = dialog_menu(prompt ? prompt : "Main Menu",
|
res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
|
||||||
menu_instructions,
|
_(menu_instructions),
|
||||||
active_menu, &s_scroll);
|
active_menu, &s_scroll);
|
||||||
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
|
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
|
||||||
break;
|
break;
|
||||||
@ -707,7 +704,7 @@ static void conf(struct menu *menu, struct menu *active_menu)
|
|||||||
show_help(submenu);
|
show_help(submenu);
|
||||||
else {
|
else {
|
||||||
reset_subtitle();
|
reset_subtitle();
|
||||||
show_helptext("README", mconf_readme);
|
show_helptext(_("README"), _(mconf_readme));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
@ -772,13 +769,16 @@ static void show_helptext(const char *title, const char *text)
|
|||||||
show_textbox(title, text, 0, 0);
|
show_textbox(title, text, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conf_message_callback(const char *s)
|
static void conf_message_callback(const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
|
char buf[PATH_MAX+1];
|
||||||
|
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
if (save_and_exit) {
|
if (save_and_exit) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
printf("%s", s);
|
printf("%s", buf);
|
||||||
} else {
|
} else {
|
||||||
show_textbox(NULL, s, 6, 60);
|
show_textbox(NULL, buf, 6, 60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,13 +789,13 @@ static void show_help(struct menu *menu)
|
|||||||
help.max_width = getmaxx(stdscr) - 10;
|
help.max_width = getmaxx(stdscr) - 10;
|
||||||
menu_get_ext_help(menu, &help);
|
menu_get_ext_help(menu, &help);
|
||||||
|
|
||||||
show_helptext(menu_get_prompt(menu), str_get(&help));
|
show_helptext(_(menu_get_prompt(menu)), str_get(&help));
|
||||||
str_free(&help);
|
str_free(&help);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conf_choice(struct menu *menu)
|
static void conf_choice(struct menu *menu)
|
||||||
{
|
{
|
||||||
const char *prompt = menu_get_prompt(menu);
|
const char *prompt = _(menu_get_prompt(menu));
|
||||||
struct menu *child;
|
struct menu *child;
|
||||||
struct symbol *active;
|
struct symbol *active;
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
@ -811,9 +811,9 @@ static void conf_choice(struct menu *menu)
|
|||||||
if (!menu_is_visible(child))
|
if (!menu_is_visible(child))
|
||||||
continue;
|
continue;
|
||||||
if (child->sym)
|
if (child->sym)
|
||||||
item_make("%s", menu_get_prompt(child));
|
item_make("%s", _(menu_get_prompt(child)));
|
||||||
else {
|
else {
|
||||||
item_make("*** %s ***", menu_get_prompt(child));
|
item_make("*** %s ***", _(menu_get_prompt(child)));
|
||||||
item_set_tag(':');
|
item_set_tag(':');
|
||||||
}
|
}
|
||||||
item_set_data(child);
|
item_set_data(child);
|
||||||
@ -823,8 +823,8 @@ static void conf_choice(struct menu *menu)
|
|||||||
item_set_tag('X');
|
item_set_tag('X');
|
||||||
}
|
}
|
||||||
dialog_clear();
|
dialog_clear();
|
||||||
res = dialog_checklist(prompt ? prompt : "Main Menu",
|
res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
|
||||||
radiolist_instructions,
|
_(radiolist_instructions),
|
||||||
MENUBOX_HEIGTH_MIN,
|
MENUBOX_HEIGTH_MIN,
|
||||||
MENUBOX_WIDTH_MIN,
|
MENUBOX_WIDTH_MIN,
|
||||||
CHECKLIST_HEIGTH_MIN);
|
CHECKLIST_HEIGTH_MIN);
|
||||||
@ -874,26 +874,26 @@ static void conf_string(struct menu *menu)
|
|||||||
|
|
||||||
switch (sym_get_type(menu->sym)) {
|
switch (sym_get_type(menu->sym)) {
|
||||||
case S_INT:
|
case S_INT:
|
||||||
heading = inputbox_instructions_int;
|
heading = _(inputbox_instructions_int);
|
||||||
break;
|
break;
|
||||||
case S_HEX:
|
case S_HEX:
|
||||||
heading = inputbox_instructions_hex;
|
heading = _(inputbox_instructions_hex);
|
||||||
break;
|
break;
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
heading = inputbox_instructions_string;
|
heading = _(inputbox_instructions_string);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
heading = "Internal mconf error!";
|
heading = _("Internal mconf error!");
|
||||||
}
|
}
|
||||||
dialog_clear();
|
dialog_clear();
|
||||||
res = dialog_inputbox(prompt ? prompt : "Main Menu",
|
res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
|
||||||
heading, 10, 75,
|
heading, 10, 75,
|
||||||
sym_get_string_value(menu->sym));
|
sym_get_string_value(menu->sym));
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case 0:
|
case 0:
|
||||||
if (sym_set_string_value(menu->sym, dialog_input_result))
|
if (sym_set_string_value(menu->sym, dialog_input_result))
|
||||||
return;
|
return;
|
||||||
show_textbox(NULL, "You have made an invalid entry.", 5, 43);
|
show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
show_help(menu);
|
show_help(menu);
|
||||||
@ -921,10 +921,10 @@ static void conf_load(void)
|
|||||||
sym_set_change_count(1);
|
sym_set_change_count(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
show_textbox(NULL, "File does not exist!", 5, 38);
|
show_textbox(NULL, _("File does not exist!"), 5, 38);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
show_helptext("Load Alternate Configuration", load_config_help);
|
show_helptext(_("Load Alternate Configuration"), load_config_help);
|
||||||
break;
|
break;
|
||||||
case KEY_ESC:
|
case KEY_ESC:
|
||||||
return;
|
return;
|
||||||
@ -947,10 +947,10 @@ static void conf_save(void)
|
|||||||
set_config_filename(dialog_input_result);
|
set_config_filename(dialog_input_result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
show_textbox(NULL, "Can't create file!", 5, 60);
|
show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
show_helptext("Save Alternate Configuration", save_config_help);
|
show_helptext(_("Save Alternate Configuration"), save_config_help);
|
||||||
break;
|
break;
|
||||||
case KEY_ESC:
|
case KEY_ESC:
|
||||||
return;
|
return;
|
||||||
@ -967,8 +967,8 @@ static int handle_exit(void)
|
|||||||
dialog_clear();
|
dialog_clear();
|
||||||
if (conf_get_changed())
|
if (conf_get_changed())
|
||||||
res = dialog_yesno(NULL,
|
res = dialog_yesno(NULL,
|
||||||
"Do you wish to save your new configuration?\n"
|
_("Do you wish to save your new configuration?\n"
|
||||||
"(Press <ESC><ESC> to continue kernel configuration.)",
|
"(Press <ESC><ESC> to continue kernel configuration.)"),
|
||||||
6, 60);
|
6, 60);
|
||||||
else
|
else
|
||||||
res = -1;
|
res = -1;
|
||||||
@ -978,27 +978,26 @@ static int handle_exit(void)
|
|||||||
switch (res) {
|
switch (res) {
|
||||||
case 0:
|
case 0:
|
||||||
if (conf_write(filename)) {
|
if (conf_write(filename)) {
|
||||||
fprintf(stderr, "\n\n"
|
fprintf(stderr, _("\n\n"
|
||||||
"Error while writing of the configuration.\n"
|
"Error while writing of the configuration.\n"
|
||||||
"Your configuration changes were NOT saved."
|
"Your configuration changes were NOT saved."
|
||||||
"\n\n");
|
"\n\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
conf_write_autoconf(0);
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case -1:
|
case -1:
|
||||||
if (!silent)
|
if (!silent)
|
||||||
printf("\n\n"
|
printf(_("\n\n"
|
||||||
"*** End of the configuration.\n"
|
"*** End of the configuration.\n"
|
||||||
"*** Execute 'make' to start the build or try 'make help'."
|
"*** Execute 'make' to start the build or try 'make help'."
|
||||||
"\n\n");
|
"\n\n"));
|
||||||
res = 0;
|
res = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!silent)
|
if (!silent)
|
||||||
fprintf(stderr, "\n\n"
|
fprintf(stderr, _("\n\n"
|
||||||
"Your configuration changes were NOT saved."
|
"Your configuration changes were NOT saved."
|
||||||
"\n\n");
|
"\n\n"));
|
||||||
if (res != KEY_ESC)
|
if (res != KEY_ESC)
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
@ -1016,6 +1015,10 @@ int main(int ac, char **av)
|
|||||||
char *mode;
|
char *mode;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
signal(SIGINT, sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
|
|
||||||
if (ac > 1 && strcmp(av[1], "-s") == 0) {
|
if (ac > 1 && strcmp(av[1], "-s") == 0) {
|
||||||
@ -1034,8 +1037,8 @@ int main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (init_dialog(NULL)) {
|
if (init_dialog(NULL)) {
|
||||||
fprintf(stderr, "Your display is too small to run Menuconfig!\n");
|
fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
|
||||||
fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
|
fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -62,8 +62,13 @@ void menu_add_entry(struct symbol *sym)
|
|||||||
menu_add_symbol(P_SYMBOL, sym, NULL);
|
menu_add_symbol(P_SYMBOL, sym, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void menu_end_entry(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
struct menu *menu_add_menu(void)
|
struct menu *menu_add_menu(void)
|
||||||
{
|
{
|
||||||
|
menu_end_entry();
|
||||||
last_entry_ptr = ¤t_entry->list;
|
last_entry_ptr = ¤t_entry->list;
|
||||||
return current_menu = current_entry;
|
return current_menu = current_entry;
|
||||||
}
|
}
|
||||||
@ -74,23 +79,19 @@ void menu_end_menu(void)
|
|||||||
current_menu = current_menu->parent;
|
current_menu = current_menu->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static struct expr *menu_check_dep(struct expr *e)
|
||||||
* Rewrites 'm' to 'm' && MODULES, so that it evaluates to 'n' when running
|
|
||||||
* without modules
|
|
||||||
*/
|
|
||||||
static struct expr *rewrite_m(struct expr *e)
|
|
||||||
{
|
{
|
||||||
if (!e)
|
if (!e)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case E_NOT:
|
case E_NOT:
|
||||||
e->left.expr = rewrite_m(e->left.expr);
|
e->left.expr = menu_check_dep(e->left.expr);
|
||||||
break;
|
break;
|
||||||
case E_OR:
|
case E_OR:
|
||||||
case E_AND:
|
case E_AND:
|
||||||
e->left.expr = rewrite_m(e->left.expr);
|
e->left.expr = menu_check_dep(e->left.expr);
|
||||||
e->right.expr = rewrite_m(e->right.expr);
|
e->right.expr = menu_check_dep(e->right.expr);
|
||||||
break;
|
break;
|
||||||
case E_SYMBOL:
|
case E_SYMBOL:
|
||||||
/* change 'm' into 'm' && MODULES */
|
/* change 'm' into 'm' && MODULES */
|
||||||
@ -105,7 +106,7 @@ static struct expr *rewrite_m(struct expr *e)
|
|||||||
|
|
||||||
void menu_add_dep(struct expr *dep)
|
void menu_add_dep(struct expr *dep)
|
||||||
{
|
{
|
||||||
current_entry->dep = expr_alloc_and(current_entry->dep, dep);
|
current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_set_type(int type)
|
void menu_set_type(int type)
|
||||||
@ -124,74 +125,59 @@ void menu_set_type(int type)
|
|||||||
sym_type_name(sym->type), sym_type_name(type));
|
sym_type_name(sym->type), sym_type_name(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct property *menu_add_prop(enum prop_type type, struct expr *expr,
|
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
|
||||||
struct expr *dep)
|
|
||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop = prop_alloc(type, current_entry->sym);
|
||||||
|
|
||||||
prop = xmalloc(sizeof(*prop));
|
|
||||||
memset(prop, 0, sizeof(*prop));
|
|
||||||
prop->type = type;
|
|
||||||
prop->file = current_file;
|
|
||||||
prop->lineno = zconf_lineno();
|
|
||||||
prop->menu = current_entry;
|
prop->menu = current_entry;
|
||||||
prop->expr = expr;
|
prop->expr = expr;
|
||||||
prop->visible.expr = dep;
|
prop->visible.expr = menu_check_dep(dep);
|
||||||
|
|
||||||
/* append property to the prop list of symbol */
|
if (prompt) {
|
||||||
if (current_entry->sym) {
|
if (isspace(*prompt)) {
|
||||||
struct property **propp;
|
prop_warn(prop, "leading whitespace ignored");
|
||||||
|
while (isspace(*prompt))
|
||||||
|
prompt++;
|
||||||
|
}
|
||||||
|
if (current_entry->prompt && current_entry != &rootmenu)
|
||||||
|
prop_warn(prop, "prompt redefined");
|
||||||
|
|
||||||
for (propp = ¤t_entry->sym->prop;
|
/* Apply all upper menus' visibilities to actual prompts. */
|
||||||
*propp;
|
if(type == P_PROMPT) {
|
||||||
propp = &(*propp)->next)
|
struct menu *menu = current_entry;
|
||||||
;
|
|
||||||
*propp = prop;
|
while ((menu = menu->parent) != NULL) {
|
||||||
|
struct expr *dup_expr;
|
||||||
|
|
||||||
|
if (!menu->visibility)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Do not add a reference to the
|
||||||
|
* menu's visibility expression but
|
||||||
|
* use a copy of it. Otherwise the
|
||||||
|
* expression reduction functions
|
||||||
|
* will modify expressions that have
|
||||||
|
* multiple references which can
|
||||||
|
* cause unwanted side effects.
|
||||||
|
*/
|
||||||
|
dup_expr = expr_copy(menu->visibility);
|
||||||
|
|
||||||
|
prop->visible.expr
|
||||||
|
= expr_alloc_and(prop->visible.expr,
|
||||||
|
dup_expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current_entry->prompt = prop;
|
||||||
}
|
}
|
||||||
|
prop->text = prompt;
|
||||||
|
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct property *menu_add_prompt(enum prop_type type, char *prompt,
|
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
|
||||||
struct expr *dep)
|
|
||||||
{
|
{
|
||||||
struct property *prop = menu_add_prop(type, NULL, dep);
|
return menu_add_prop(type, prompt, NULL, dep);
|
||||||
|
|
||||||
if (isspace(*prompt)) {
|
|
||||||
prop_warn(prop, "leading whitespace ignored");
|
|
||||||
while (isspace(*prompt))
|
|
||||||
prompt++;
|
|
||||||
}
|
|
||||||
if (current_entry->prompt)
|
|
||||||
prop_warn(prop, "prompt redefined");
|
|
||||||
|
|
||||||
/* Apply all upper menus' visibilities to actual prompts. */
|
|
||||||
if (type == P_PROMPT) {
|
|
||||||
struct menu *menu = current_entry;
|
|
||||||
|
|
||||||
while ((menu = menu->parent) != NULL) {
|
|
||||||
struct expr *dup_expr;
|
|
||||||
|
|
||||||
if (!menu->visibility)
|
|
||||||
continue;
|
|
||||||
/*
|
|
||||||
* Do not add a reference to the menu's visibility
|
|
||||||
* expression but use a copy of it. Otherwise the
|
|
||||||
* expression reduction functions will modify
|
|
||||||
* expressions that have multiple references which
|
|
||||||
* can cause unwanted side effects.
|
|
||||||
*/
|
|
||||||
dup_expr = expr_copy(menu->visibility);
|
|
||||||
|
|
||||||
prop->visible.expr = expr_alloc_and(prop->visible.expr,
|
|
||||||
dup_expr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_entry->prompt = prop;
|
|
||||||
prop->text = prompt;
|
|
||||||
|
|
||||||
return prop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_add_visibility(struct expr *expr)
|
void menu_add_visibility(struct expr *expr)
|
||||||
@ -202,34 +188,39 @@ void menu_add_visibility(struct expr *expr)
|
|||||||
|
|
||||||
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
|
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
|
||||||
{
|
{
|
||||||
menu_add_prop(type, expr, dep);
|
menu_add_prop(type, NULL, expr, dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
|
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
|
||||||
{
|
{
|
||||||
menu_add_prop(type, expr_alloc_symbol(sym), dep);
|
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_add_option_modules(void)
|
void menu_add_option(int token, char *arg)
|
||||||
{
|
{
|
||||||
if (modules_sym)
|
switch (token) {
|
||||||
zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'",
|
case T_OPT_MODULES:
|
||||||
current_entry->sym->name, modules_sym->name);
|
if (modules_sym)
|
||||||
modules_sym = current_entry->sym;
|
zconf_error("symbol '%s' redefines option 'modules'"
|
||||||
}
|
" already defined by symbol '%s'",
|
||||||
|
current_entry->sym->name,
|
||||||
void menu_add_option_defconfig_list(void)
|
modules_sym->name
|
||||||
{
|
);
|
||||||
if (!sym_defconfig_list)
|
modules_sym = current_entry->sym;
|
||||||
sym_defconfig_list = current_entry->sym;
|
break;
|
||||||
else if (sym_defconfig_list != current_entry->sym)
|
case T_OPT_DEFCONFIG_LIST:
|
||||||
zconf_error("trying to redefine defconfig symbol");
|
if (!sym_defconfig_list)
|
||||||
sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
|
sym_defconfig_list = current_entry->sym;
|
||||||
}
|
else if (sym_defconfig_list != current_entry->sym)
|
||||||
|
zconf_error("trying to redefine defconfig symbol");
|
||||||
void menu_add_option_allnoconfig_y(void)
|
break;
|
||||||
{
|
case T_OPT_ENV:
|
||||||
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
|
prop_add_env(arg);
|
||||||
|
break;
|
||||||
|
case T_OPT_ALLNOCONFIG_Y:
|
||||||
|
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
|
static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
|
||||||
@ -242,8 +233,6 @@ static void sym_check_prop(struct symbol *sym)
|
|||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
struct symbol *sym2;
|
struct symbol *sym2;
|
||||||
char *use;
|
|
||||||
|
|
||||||
for (prop = sym->prop; prop; prop = prop->next) {
|
for (prop = sym->prop; prop; prop = prop->next) {
|
||||||
switch (prop->type) {
|
switch (prop->type) {
|
||||||
case P_DEFAULT:
|
case P_DEFAULT:
|
||||||
@ -261,32 +250,20 @@ static void sym_check_prop(struct symbol *sym)
|
|||||||
"'%s': number is invalid",
|
"'%s': number is invalid",
|
||||||
sym->name);
|
sym->name);
|
||||||
}
|
}
|
||||||
if (sym_is_choice(sym)) {
|
|
||||||
struct property *choice_prop =
|
|
||||||
sym_get_choice_prop(sym2);
|
|
||||||
|
|
||||||
if (!choice_prop ||
|
|
||||||
prop_get_symbol(choice_prop) != sym)
|
|
||||||
prop_warn(prop,
|
|
||||||
"choice default symbol '%s' is not contained in the choice",
|
|
||||||
sym2->name);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case P_SELECT:
|
case P_SELECT:
|
||||||
case P_IMPLY:
|
|
||||||
use = prop->type == P_SELECT ? "select" : "imply";
|
|
||||||
sym2 = prop_get_symbol(prop);
|
sym2 = prop_get_symbol(prop);
|
||||||
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
|
if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
|
||||||
prop_warn(prop,
|
prop_warn(prop,
|
||||||
"config symbol '%s' uses %s, but is "
|
"config symbol '%s' uses select, but is "
|
||||||
"not bool or tristate", sym->name, use);
|
"not boolean or tristate", sym->name);
|
||||||
else if (sym2->type != S_UNKNOWN &&
|
else if (sym2->type != S_UNKNOWN &&
|
||||||
sym2->type != S_BOOLEAN &&
|
sym2->type != S_BOOLEAN &&
|
||||||
sym2->type != S_TRISTATE)
|
sym2->type != S_TRISTATE)
|
||||||
prop_warn(prop,
|
prop_warn(prop,
|
||||||
"'%s' has wrong type. '%s' only "
|
"'%s' has wrong type. 'select' only "
|
||||||
"accept arguments of bool and "
|
"accept arguments of boolean and "
|
||||||
"tristate type", sym2->name, use);
|
"tristate type", sym2->name);
|
||||||
break;
|
break;
|
||||||
case P_RANGE:
|
case P_RANGE:
|
||||||
if (sym->type != S_INT && sym->type != S_HEX)
|
if (sym->type != S_INT && sym->type != S_HEX)
|
||||||
@ -311,11 +288,6 @@ void menu_finalize(struct menu *parent)
|
|||||||
|
|
||||||
sym = parent->sym;
|
sym = parent->sym;
|
||||||
if (parent->list) {
|
if (parent->list) {
|
||||||
/*
|
|
||||||
* This menu node has children. We (recursively) process them
|
|
||||||
* and propagate parent dependencies before moving on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (sym && sym_is_choice(sym)) {
|
if (sym && sym_is_choice(sym)) {
|
||||||
if (sym->type == S_UNKNOWN) {
|
if (sym->type == S_UNKNOWN) {
|
||||||
/* find the first choice value to find out choice type */
|
/* find the first choice value to find out choice type */
|
||||||
@ -333,167 +305,65 @@ void menu_finalize(struct menu *parent)
|
|||||||
if (menu->sym && menu->sym->type == S_UNKNOWN)
|
if (menu->sym && menu->sym->type == S_UNKNOWN)
|
||||||
menu_set_type(sym->type);
|
menu_set_type(sym->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Use the choice itself as the parent dependency of
|
|
||||||
* the contained items. This turns the mode of the
|
|
||||||
* choice into an upper bound on the visibility of the
|
|
||||||
* choice value symbols.
|
|
||||||
*/
|
|
||||||
parentdep = expr_alloc_symbol(sym);
|
parentdep = expr_alloc_symbol(sym);
|
||||||
} else {
|
} else if (parent->prompt)
|
||||||
/* Menu node for 'menu', 'if' */
|
parentdep = parent->prompt->visible.expr;
|
||||||
|
else
|
||||||
parentdep = parent->dep;
|
parentdep = parent->dep;
|
||||||
}
|
|
||||||
|
|
||||||
/* For each child menu node... */
|
|
||||||
for (menu = parent->list; menu; menu = menu->next) {
|
for (menu = parent->list; menu; menu = menu->next) {
|
||||||
/*
|
basedep = expr_transform(menu->dep);
|
||||||
* Propagate parent dependencies to the child menu
|
|
||||||
* node, also rewriting and simplifying expressions
|
|
||||||
*/
|
|
||||||
basedep = rewrite_m(menu->dep);
|
|
||||||
basedep = expr_transform(basedep);
|
|
||||||
basedep = expr_alloc_and(expr_copy(parentdep), basedep);
|
basedep = expr_alloc_and(expr_copy(parentdep), basedep);
|
||||||
basedep = expr_eliminate_dups(basedep);
|
basedep = expr_eliminate_dups(basedep);
|
||||||
menu->dep = basedep;
|
menu->dep = basedep;
|
||||||
|
|
||||||
if (menu->sym)
|
if (menu->sym)
|
||||||
/*
|
|
||||||
* Note: For symbols, all prompts are included
|
|
||||||
* too in the symbol's own property list
|
|
||||||
*/
|
|
||||||
prop = menu->sym->prop;
|
prop = menu->sym->prop;
|
||||||
else
|
else
|
||||||
/*
|
|
||||||
* For non-symbol menu nodes, we just need to
|
|
||||||
* handle the prompt
|
|
||||||
*/
|
|
||||||
prop = menu->prompt;
|
prop = menu->prompt;
|
||||||
|
|
||||||
/* For each property... */
|
|
||||||
for (; prop; prop = prop->next) {
|
for (; prop; prop = prop->next) {
|
||||||
if (prop->menu != menu)
|
if (prop->menu != menu)
|
||||||
/*
|
|
||||||
* Two possibilities:
|
|
||||||
*
|
|
||||||
* 1. The property lacks dependencies
|
|
||||||
* and so isn't location-specific,
|
|
||||||
* e.g. an 'option'
|
|
||||||
*
|
|
||||||
* 2. The property belongs to a symbol
|
|
||||||
* defined in multiple locations and
|
|
||||||
* is from some other location. It
|
|
||||||
* will be handled there in that
|
|
||||||
* case.
|
|
||||||
*
|
|
||||||
* Skip the property.
|
|
||||||
*/
|
|
||||||
continue;
|
continue;
|
||||||
|
dep = expr_transform(prop->visible.expr);
|
||||||
/*
|
|
||||||
* Propagate parent dependencies to the
|
|
||||||
* property's condition, rewriting and
|
|
||||||
* simplifying expressions at the same time
|
|
||||||
*/
|
|
||||||
dep = rewrite_m(prop->visible.expr);
|
|
||||||
dep = expr_transform(dep);
|
|
||||||
dep = expr_alloc_and(expr_copy(basedep), dep);
|
dep = expr_alloc_and(expr_copy(basedep), dep);
|
||||||
dep = expr_eliminate_dups(dep);
|
dep = expr_eliminate_dups(dep);
|
||||||
if (menu->sym && menu->sym->type != S_TRISTATE)
|
if (menu->sym && menu->sym->type != S_TRISTATE)
|
||||||
dep = expr_trans_bool(dep);
|
dep = expr_trans_bool(dep);
|
||||||
prop->visible.expr = dep;
|
prop->visible.expr = dep;
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle selects and implies, which modify the
|
|
||||||
* dependencies of the selected/implied symbol
|
|
||||||
*/
|
|
||||||
if (prop->type == P_SELECT) {
|
if (prop->type == P_SELECT) {
|
||||||
struct symbol *es = prop_get_symbol(prop);
|
struct symbol *es = prop_get_symbol(prop);
|
||||||
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
|
es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
|
||||||
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
||||||
} else if (prop->type == P_IMPLY) {
|
|
||||||
struct symbol *es = prop_get_symbol(prop);
|
|
||||||
es->implied.expr = expr_alloc_or(es->implied.expr,
|
|
||||||
expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym && sym_is_choice(sym))
|
|
||||||
expr_free(parentdep);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Recursively process children in the same fashion before
|
|
||||||
* moving on
|
|
||||||
*/
|
|
||||||
for (menu = parent->list; menu; menu = menu->next)
|
for (menu = parent->list; menu; menu = menu->next)
|
||||||
menu_finalize(menu);
|
menu_finalize(menu);
|
||||||
} else if (sym) {
|
} else if (sym) {
|
||||||
/*
|
|
||||||
* Automatic submenu creation. If sym is a symbol and A, B, C,
|
|
||||||
* ... are consecutive items (symbols, menus, ifs, etc.) that
|
|
||||||
* all depend on sym, then the following menu structure is
|
|
||||||
* created:
|
|
||||||
*
|
|
||||||
* sym
|
|
||||||
* +-A
|
|
||||||
* +-B
|
|
||||||
* +-C
|
|
||||||
* ...
|
|
||||||
*
|
|
||||||
* This also works recursively, giving the following structure
|
|
||||||
* if A is a symbol and B depends on A:
|
|
||||||
*
|
|
||||||
* sym
|
|
||||||
* +-A
|
|
||||||
* | +-B
|
|
||||||
* +-C
|
|
||||||
* ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
|
basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
|
||||||
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
|
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
|
||||||
basedep = expr_eliminate_dups(expr_transform(basedep));
|
basedep = expr_eliminate_dups(expr_transform(basedep));
|
||||||
|
|
||||||
/* Examine consecutive elements after sym */
|
|
||||||
last_menu = NULL;
|
last_menu = NULL;
|
||||||
for (menu = parent->next; menu; menu = menu->next) {
|
for (menu = parent->next; menu; menu = menu->next) {
|
||||||
dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
|
dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
|
||||||
if (!expr_contains_symbol(dep, sym))
|
if (!expr_contains_symbol(dep, sym))
|
||||||
/* No dependency, quit */
|
|
||||||
break;
|
break;
|
||||||
if (expr_depends_symbol(dep, sym))
|
if (expr_depends_symbol(dep, sym))
|
||||||
/* Absolute dependency, put in submenu */
|
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
/*
|
|
||||||
* Also consider it a dependency on sym if our
|
|
||||||
* dependencies contain sym and are a "superset" of
|
|
||||||
* sym's dependencies, e.g. '(sym || Q) && R' when sym
|
|
||||||
* depends on R.
|
|
||||||
*
|
|
||||||
* Note that 'R' might be from an enclosing menu or if,
|
|
||||||
* making this a more common case than it might seem.
|
|
||||||
*/
|
|
||||||
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
|
dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
|
||||||
dep = expr_eliminate_dups(expr_transform(dep));
|
dep = expr_eliminate_dups(expr_transform(dep));
|
||||||
dep2 = expr_copy(basedep);
|
dep2 = expr_copy(basedep);
|
||||||
expr_eliminate_eq(&dep, &dep2);
|
expr_eliminate_eq(&dep, &dep2);
|
||||||
expr_free(dep);
|
expr_free(dep);
|
||||||
if (!expr_is_yes(dep2)) {
|
if (!expr_is_yes(dep2)) {
|
||||||
/* Not superset, quit */
|
|
||||||
expr_free(dep2);
|
expr_free(dep2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Superset, put in submenu */
|
|
||||||
expr_free(dep2);
|
expr_free(dep2);
|
||||||
next:
|
next:
|
||||||
menu_finalize(menu);
|
menu_finalize(menu);
|
||||||
menu->parent = parent;
|
menu->parent = parent;
|
||||||
last_menu = menu;
|
last_menu = menu;
|
||||||
}
|
}
|
||||||
expr_free(basedep);
|
|
||||||
if (last_menu) {
|
if (last_menu) {
|
||||||
parent->list = parent->next;
|
parent->list = parent->next;
|
||||||
parent->next = last_menu->next;
|
parent->next = last_menu->next;
|
||||||
@ -542,35 +412,6 @@ void menu_finalize(struct menu *parent)
|
|||||||
*ep = expr_alloc_one(E_LIST, NULL);
|
*ep = expr_alloc_one(E_LIST, NULL);
|
||||||
(*ep)->right.sym = menu->sym;
|
(*ep)->right.sym = menu->sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This code serves two purposes:
|
|
||||||
*
|
|
||||||
* (1) Flattening 'if' blocks, which do not specify a submenu
|
|
||||||
* and only add dependencies.
|
|
||||||
*
|
|
||||||
* (Automatic submenu creation might still create a submenu
|
|
||||||
* from an 'if' before this code runs.)
|
|
||||||
*
|
|
||||||
* (2) "Undoing" any automatic submenus created earlier below
|
|
||||||
* promptless symbols.
|
|
||||||
*
|
|
||||||
* Before:
|
|
||||||
*
|
|
||||||
* A
|
|
||||||
* if ... (or promptless symbol)
|
|
||||||
* +-B
|
|
||||||
* +-C
|
|
||||||
* D
|
|
||||||
*
|
|
||||||
* After:
|
|
||||||
*
|
|
||||||
* A
|
|
||||||
* if ... (or promptless symbol)
|
|
||||||
* B
|
|
||||||
* C
|
|
||||||
* D
|
|
||||||
*/
|
|
||||||
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
|
if (menu->list && (!menu->prompt || !menu->prompt->text)) {
|
||||||
for (last_menu = menu->list; ; last_menu = last_menu->next) {
|
for (last_menu = menu->list; ; last_menu = last_menu->next) {
|
||||||
last_menu->parent = parent;
|
last_menu->parent = parent;
|
||||||
@ -595,15 +436,6 @@ void menu_finalize(struct menu *parent)
|
|||||||
sym->flags |= SYMBOL_WARNED;
|
sym->flags |= SYMBOL_WARNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* For non-optional choices, add a reverse dependency (corresponding to
|
|
||||||
* a select) of '<visibility> && m'. This prevents the user from
|
|
||||||
* setting the choice mode to 'n' when the choice is visible.
|
|
||||||
*
|
|
||||||
* This would also work for non-choice symbols, but only non-optional
|
|
||||||
* choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented
|
|
||||||
* as a type of symbol.
|
|
||||||
*/
|
|
||||||
if (sym && !sym_is_optional(sym) && parent->prompt) {
|
if (sym && !sym_is_optional(sym) && parent->prompt) {
|
||||||
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
|
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
|
||||||
expr_alloc_and(parent->prompt->visible.expr,
|
expr_alloc_and(parent->prompt->visible.expr,
|
||||||
@ -711,21 +543,6 @@ const char *menu_get_help(struct menu *menu)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_def_str(struct gstr *r, struct menu *menu)
|
|
||||||
{
|
|
||||||
str_printf(r, "Defined at %s:%d\n",
|
|
||||||
menu->file->name, menu->lineno);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
|
|
||||||
{
|
|
||||||
if (!expr_is_yes(expr)) {
|
|
||||||
str_append(r, prefix);
|
|
||||||
expr_gstr_print(expr, r);
|
|
||||||
str_append(r, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_prompt_str(struct gstr *r, struct property *prop,
|
static void get_prompt_str(struct gstr *r, struct property *prop,
|
||||||
struct list_head *head)
|
struct list_head *head)
|
||||||
{
|
{
|
||||||
@ -733,20 +550,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
|
|||||||
struct menu *submenu[8], *menu, *location = NULL;
|
struct menu *submenu[8], *menu, *location = NULL;
|
||||||
struct jump_key *jump = NULL;
|
struct jump_key *jump = NULL;
|
||||||
|
|
||||||
str_printf(r, " Prompt: %s\n", prop->text);
|
str_printf(r, _("Prompt: %s\n"), _(prop->text));
|
||||||
|
|
||||||
get_dep_str(r, prop->menu->dep, " Depends on: ");
|
|
||||||
/*
|
|
||||||
* Most prompts in Linux have visibility that exactly matches their
|
|
||||||
* dependencies. For these, we print only the dependencies to improve
|
|
||||||
* readability. However, prompts with inline "if" expressions and
|
|
||||||
* prompts with a parent that has a "visible if" expression have
|
|
||||||
* differing dependencies and visibility. In these rare cases, we
|
|
||||||
* print both.
|
|
||||||
*/
|
|
||||||
if (!expr_eq(prop->menu->dep, prop->visible.expr))
|
|
||||||
get_dep_str(r, prop->visible.expr, " Visible if: ");
|
|
||||||
|
|
||||||
menu = prop->menu->parent;
|
menu = prop->menu->parent;
|
||||||
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
|
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
|
||||||
bool accessible = menu_is_visible(menu);
|
bool accessible = menu_is_visible(menu);
|
||||||
@ -779,16 +583,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
str_printf(r, " Location:\n");
|
str_printf(r, _(" Location:\n"));
|
||||||
for (j = 4; --i >= 0; j += 2) {
|
for (j = 4; --i >= 0; j += 2) {
|
||||||
menu = submenu[i];
|
menu = submenu[i];
|
||||||
if (jump && menu == location)
|
if (jump && menu == location)
|
||||||
jump->offset = strlen(r->s);
|
jump->offset = strlen(r->s);
|
||||||
str_printf(r, "%*c-> %s", j, ' ',
|
str_printf(r, "%*c-> %s", j, ' ',
|
||||||
menu_get_prompt(menu));
|
_(menu_get_prompt(menu)));
|
||||||
if (menu->sym) {
|
if (menu->sym) {
|
||||||
str_printf(r, " (%s [=%s])", menu->sym->name ?
|
str_printf(r, " (%s [=%s])", menu->sym->name ?
|
||||||
menu->sym->name : "<choice>",
|
menu->sym->name : _("<choice>"),
|
||||||
sym_get_string_value(menu->sym));
|
sym_get_string_value(menu->sym));
|
||||||
}
|
}
|
||||||
str_append(r, "\n");
|
str_append(r, "\n");
|
||||||
@ -796,22 +600,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
|
/*
|
||||||
enum prop_type tok, const char *prefix)
|
* get property of type P_SYMBOL
|
||||||
|
*/
|
||||||
|
static struct property *get_symbol_prop(struct symbol *sym)
|
||||||
{
|
{
|
||||||
bool hit = false;
|
struct property *prop = NULL;
|
||||||
struct property *prop;
|
|
||||||
|
|
||||||
for_all_properties(sym, prop, tok) {
|
for_all_properties(sym, prop, P_SYMBOL)
|
||||||
if (!hit) {
|
break;
|
||||||
str_append(r, prefix);
|
return prop;
|
||||||
hit = true;
|
|
||||||
} else
|
|
||||||
str_printf(r, " && ");
|
|
||||||
expr_gstr_print(prop->expr, r);
|
|
||||||
}
|
|
||||||
if (hit)
|
|
||||||
str_append(r, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -820,6 +618,7 @@ static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
|
|||||||
static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
||||||
struct list_head *head)
|
struct list_head *head)
|
||||||
{
|
{
|
||||||
|
bool hit;
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
|
|
||||||
if (sym && sym->name) {
|
if (sym && sym->name) {
|
||||||
@ -835,36 +634,36 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for_all_prompts(sym, prop)
|
||||||
|
get_prompt_str(r, prop, head);
|
||||||
|
|
||||||
/* Print the definitions with prompts before the ones without */
|
prop = get_symbol_prop(sym);
|
||||||
for_all_properties(sym, prop, P_SYMBOL) {
|
if (prop) {
|
||||||
if (prop->menu->prompt) {
|
str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
|
||||||
get_def_str(r, prop->menu);
|
prop->menu->lineno);
|
||||||
get_prompt_str(r, prop->menu->prompt, head);
|
if (!expr_is_yes(prop->visible.expr)) {
|
||||||
|
str_append(r, _(" Depends on: "));
|
||||||
|
expr_gstr_print(prop->visible.expr, r);
|
||||||
|
str_append(r, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for_all_properties(sym, prop, P_SYMBOL) {
|
hit = false;
|
||||||
if (!prop->menu->prompt) {
|
for_all_properties(sym, prop, P_SELECT) {
|
||||||
get_def_str(r, prop->menu);
|
if (!hit) {
|
||||||
get_dep_str(r, prop->menu->dep, " Depends on: ");
|
str_append(r, " Selects: ");
|
||||||
}
|
hit = true;
|
||||||
|
} else
|
||||||
|
str_printf(r, " && ");
|
||||||
|
expr_gstr_print(prop->expr, r);
|
||||||
}
|
}
|
||||||
|
if (hit)
|
||||||
get_symbol_props_str(r, sym, P_SELECT, "Selects: ");
|
str_append(r, "\n");
|
||||||
if (sym->rev_dep.expr) {
|
if (sym->rev_dep.expr) {
|
||||||
expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n");
|
str_append(r, _(" Selected by: "));
|
||||||
expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\n");
|
expr_gstr_print(sym->rev_dep.expr, r);
|
||||||
expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "Selected by [n]:\n");
|
str_append(r, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
get_symbol_props_str(r, sym, P_IMPLY, "Implies: ");
|
|
||||||
if (sym->implied.expr) {
|
|
||||||
expr_gstr_print_revdep(sym->implied.expr, r, yes, "Implied by [y]:\n");
|
|
||||||
expr_gstr_print_revdep(sym->implied.expr, r, mod, "Implied by [m]:\n");
|
|
||||||
expr_gstr_print_revdep(sym->implied.expr, r, no, "Implied by [n]:\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
str_append(r, "\n\n");
|
str_append(r, "\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,7 +676,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
|
|||||||
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
|
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
|
||||||
get_symbol_str(&res, sym, head);
|
get_symbol_str(&res, sym, head);
|
||||||
if (!i)
|
if (!i)
|
||||||
str_append(&res, "No matches found.\n");
|
str_append(&res, _("No matches found.\n"));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,7 +691,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
|
|||||||
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
|
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
|
||||||
help_text = menu_get_help(menu);
|
help_text = menu_get_help(menu);
|
||||||
}
|
}
|
||||||
str_printf(help, "%s\n", help_text);
|
str_printf(help, "%s\n", _(help_text));
|
||||||
if (sym)
|
if (sym)
|
||||||
get_symbol_str(help, sym, NULL);
|
get_symbol_str(help, sym, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
/* A Bison parser, made by GNU Bison 3.1. */
|
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* As a special exception, you may create a larger work that contains
|
|
||||||
part or all of the Bison parser skeleton and distribute that work
|
|
||||||
under terms of your choice, so long as that work isn't itself a
|
|
||||||
parser generator using the skeleton or a modified version thereof
|
|
||||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
|
||||||
the parser skeleton itself, you may (at your option) remove this
|
|
||||||
special exception, which will cause the skeleton and the resulting
|
|
||||||
Bison output files to be licensed under the GNU General Public
|
|
||||||
License without this special exception.
|
|
||||||
|
|
||||||
This special exception was added by the Free Software Foundation in
|
|
||||||
version 2.2 of Bison. */
|
|
||||||
|
|
||||||
#ifndef YY_YY_PARSER_TAB_H_INCLUDED
|
|
||||||
# define YY_YY_PARSER_TAB_H_INCLUDED
|
|
||||||
/* Debug traces. */
|
|
||||||
#ifndef YYDEBUG
|
|
||||||
# define YYDEBUG 0
|
|
||||||
#endif
|
|
||||||
#if YYDEBUG
|
|
||||||
extern int yydebug;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Token type. */
|
|
||||||
#ifndef YYTOKENTYPE
|
|
||||||
# define YYTOKENTYPE
|
|
||||||
enum yytokentype
|
|
||||||
{
|
|
||||||
T_HELPTEXT = 258,
|
|
||||||
T_WORD = 259,
|
|
||||||
T_WORD_QUOTE = 260,
|
|
||||||
T_ALLNOCONFIG_Y = 261,
|
|
||||||
T_BOOL = 262,
|
|
||||||
T_CHOICE = 263,
|
|
||||||
T_CLOSE_PAREN = 264,
|
|
||||||
T_COLON_EQUAL = 265,
|
|
||||||
T_COMMENT = 266,
|
|
||||||
T_CONFIG = 267,
|
|
||||||
T_DEFAULT = 268,
|
|
||||||
T_DEFCONFIG_LIST = 269,
|
|
||||||
T_DEF_BOOL = 270,
|
|
||||||
T_DEF_TRISTATE = 271,
|
|
||||||
T_DEPENDS = 272,
|
|
||||||
T_ENDCHOICE = 273,
|
|
||||||
T_ENDIF = 274,
|
|
||||||
T_ENDMENU = 275,
|
|
||||||
T_HELP = 276,
|
|
||||||
T_HEX = 277,
|
|
||||||
T_IF = 278,
|
|
||||||
T_IMPLY = 279,
|
|
||||||
T_INT = 280,
|
|
||||||
T_MAINMENU = 281,
|
|
||||||
T_MENU = 282,
|
|
||||||
T_MENUCONFIG = 283,
|
|
||||||
T_MODULES = 284,
|
|
||||||
T_ON = 285,
|
|
||||||
T_OPEN_PAREN = 286,
|
|
||||||
T_OPTION = 287,
|
|
||||||
T_OPTIONAL = 288,
|
|
||||||
T_PLUS_EQUAL = 289,
|
|
||||||
T_PROMPT = 290,
|
|
||||||
T_RANGE = 291,
|
|
||||||
T_RESET = 292,
|
|
||||||
T_SELECT = 293,
|
|
||||||
T_SOURCE = 294,
|
|
||||||
T_STRING = 295,
|
|
||||||
T_TRISTATE = 296,
|
|
||||||
T_VISIBLE = 297,
|
|
||||||
T_EOL = 298,
|
|
||||||
T_ASSIGN_VAL = 299,
|
|
||||||
T_OR = 300,
|
|
||||||
T_AND = 301,
|
|
||||||
T_EQUAL = 302,
|
|
||||||
T_UNEQUAL = 303,
|
|
||||||
T_LESS = 304,
|
|
||||||
T_LESS_EQUAL = 305,
|
|
||||||
T_GREATER = 306,
|
|
||||||
T_GREATER_EQUAL = 307,
|
|
||||||
T_NOT = 308
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Value type. */
|
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
|
||||||
|
|
||||||
union YYSTYPE
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
char *string;
|
|
||||||
struct symbol *symbol;
|
|
||||||
struct expr *expr;
|
|
||||||
struct menu *menu;
|
|
||||||
enum symbol_type type;
|
|
||||||
enum variable_flavor flavor;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
|
||||||
|
|
||||||
int yyparse (void);
|
|
||||||
|
|
||||||
#endif /* !YY_YY_PARSER_TAB_H_INCLUDED */
|
|
@ -1,575 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
//
|
|
||||||
// Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "list.h"
|
|
||||||
#include "lkc.h"
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
||||||
|
|
||||||
static char *expand_string_with_args(const char *in, int argc, char *argv[]);
|
|
||||||
static char *expand_string(const char *in);
|
|
||||||
|
|
||||||
static void __attribute__((noreturn)) pperror(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
|
|
||||||
va_start(ap, format);
|
|
||||||
vfprintf(stderr, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Environment variables
|
|
||||||
*/
|
|
||||||
static LIST_HEAD(env_list);
|
|
||||||
|
|
||||||
struct env {
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
struct list_head node;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void env_add(const char *name, const char *value)
|
|
||||||
{
|
|
||||||
struct env *e;
|
|
||||||
|
|
||||||
e = xmalloc(sizeof(*e));
|
|
||||||
e->name = xstrdup(name);
|
|
||||||
e->value = xstrdup(value);
|
|
||||||
|
|
||||||
list_add_tail(&e->node, &env_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void env_del(struct env *e)
|
|
||||||
{
|
|
||||||
list_del(&e->node);
|
|
||||||
free(e->name);
|
|
||||||
free(e->value);
|
|
||||||
free(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The returned pointer must be freed when done */
|
|
||||||
static char *env_expand(const char *name)
|
|
||||||
{
|
|
||||||
struct env *e;
|
|
||||||
const char *value;
|
|
||||||
|
|
||||||
if (!*name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
list_for_each_entry(e, &env_list, node) {
|
|
||||||
if (!strcmp(name, e->name))
|
|
||||||
return xstrdup(e->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
value = getenv(name);
|
|
||||||
if (!value)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need to remember all referenced environment variables.
|
|
||||||
* They will be written out to include/config/auto.conf.cmd
|
|
||||||
*/
|
|
||||||
env_add(name, value);
|
|
||||||
|
|
||||||
return xstrdup(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void env_write_dep(FILE *f, const char *autoconfig_name)
|
|
||||||
{
|
|
||||||
struct env *e, *tmp;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(e, tmp, &env_list, node) {
|
|
||||||
fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
|
|
||||||
fprintf(f, "%s: FORCE\n", autoconfig_name);
|
|
||||||
fprintf(f, "endif\n");
|
|
||||||
env_del(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Built-in functions
|
|
||||||
*/
|
|
||||||
struct function {
|
|
||||||
const char *name;
|
|
||||||
unsigned int min_args;
|
|
||||||
unsigned int max_args;
|
|
||||||
char *(*func)(int argc, char *argv[]);
|
|
||||||
};
|
|
||||||
|
|
||||||
static char *do_error_if(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (!strcmp(argv[0], "y"))
|
|
||||||
pperror("%s", argv[1]);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *do_filename(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
return xstrdup(current_file->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *do_info(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
printf("%s\n", argv[0]);
|
|
||||||
|
|
||||||
return xstrdup("");
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *do_lineno(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char buf[16];
|
|
||||||
|
|
||||||
sprintf(buf, "%d", yylineno);
|
|
||||||
|
|
||||||
return xstrdup(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *do_shell(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
FILE *p;
|
|
||||||
char buf[256];
|
|
||||||
char *cmd;
|
|
||||||
size_t nread;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
cmd = argv[0];
|
|
||||||
|
|
||||||
p = popen(cmd, "r");
|
|
||||||
if (!p) {
|
|
||||||
perror(cmd);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nread = fread(buf, 1, sizeof(buf), p);
|
|
||||||
if (nread == sizeof(buf))
|
|
||||||
nread--;
|
|
||||||
|
|
||||||
/* remove trailing new lines */
|
|
||||||
while (nread > 0 && buf[nread - 1] == '\n')
|
|
||||||
nread--;
|
|
||||||
|
|
||||||
buf[nread] = 0;
|
|
||||||
|
|
||||||
/* replace a new line with a space */
|
|
||||||
for (i = 0; i < nread; i++) {
|
|
||||||
if (buf[i] == '\n')
|
|
||||||
buf[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pclose(p) == -1) {
|
|
||||||
perror(cmd);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return xstrdup(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *do_warning_if(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (!strcmp(argv[0], "y"))
|
|
||||||
fprintf(stderr, "%s:%d: %s\n",
|
|
||||||
current_file->name, yylineno, argv[1]);
|
|
||||||
|
|
||||||
return xstrdup("");
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct function function_table[] = {
|
|
||||||
/* Name MIN MAX Function */
|
|
||||||
{ "error-if", 2, 2, do_error_if },
|
|
||||||
{ "filename", 0, 0, do_filename },
|
|
||||||
{ "info", 1, 1, do_info },
|
|
||||||
{ "lineno", 0, 0, do_lineno },
|
|
||||||
{ "shell", 1, 1, do_shell },
|
|
||||||
{ "warning-if", 2, 2, do_warning_if },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FUNCTION_MAX_ARGS 16
|
|
||||||
|
|
||||||
static char *function_expand(const char *name, int argc, char *argv[])
|
|
||||||
{
|
|
||||||
const struct function *f;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(function_table); i++) {
|
|
||||||
f = &function_table[i];
|
|
||||||
if (strcmp(f->name, name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (argc < f->min_args)
|
|
||||||
pperror("too few function arguments passed to '%s'",
|
|
||||||
name);
|
|
||||||
|
|
||||||
if (argc > f->max_args)
|
|
||||||
pperror("too many function arguments passed to '%s'",
|
|
||||||
name);
|
|
||||||
|
|
||||||
return f->func(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Variables (and user-defined functions)
|
|
||||||
*/
|
|
||||||
static LIST_HEAD(variable_list);
|
|
||||||
|
|
||||||
struct variable {
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
enum variable_flavor flavor;
|
|
||||||
int exp_count;
|
|
||||||
struct list_head node;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct variable *variable_lookup(const char *name)
|
|
||||||
{
|
|
||||||
struct variable *v;
|
|
||||||
|
|
||||||
list_for_each_entry(v, &variable_list, node) {
|
|
||||||
if (!strcmp(name, v->name))
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *variable_expand(const char *name, int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct variable *v;
|
|
||||||
char *res;
|
|
||||||
|
|
||||||
v = variable_lookup(name);
|
|
||||||
if (!v)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (argc == 0 && v->exp_count)
|
|
||||||
pperror("Recursive variable '%s' references itself (eventually)",
|
|
||||||
name);
|
|
||||||
|
|
||||||
if (v->exp_count > 1000)
|
|
||||||
pperror("Too deep recursive expansion");
|
|
||||||
|
|
||||||
v->exp_count++;
|
|
||||||
|
|
||||||
if (v->flavor == VAR_RECURSIVE)
|
|
||||||
res = expand_string_with_args(v->value, argc, argv);
|
|
||||||
else
|
|
||||||
res = xstrdup(v->value);
|
|
||||||
|
|
||||||
v->exp_count--;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void variable_add(const char *name, const char *value,
|
|
||||||
enum variable_flavor flavor)
|
|
||||||
{
|
|
||||||
struct variable *v;
|
|
||||||
char *new_value;
|
|
||||||
bool append = false;
|
|
||||||
|
|
||||||
v = variable_lookup(name);
|
|
||||||
if (v) {
|
|
||||||
/* For defined variables, += inherits the existing flavor */
|
|
||||||
if (flavor == VAR_APPEND) {
|
|
||||||
flavor = v->flavor;
|
|
||||||
append = true;
|
|
||||||
} else {
|
|
||||||
free(v->value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* For undefined variables, += assumes the recursive flavor */
|
|
||||||
if (flavor == VAR_APPEND)
|
|
||||||
flavor = VAR_RECURSIVE;
|
|
||||||
|
|
||||||
v = xmalloc(sizeof(*v));
|
|
||||||
v->name = xstrdup(name);
|
|
||||||
v->exp_count = 0;
|
|
||||||
list_add_tail(&v->node, &variable_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
v->flavor = flavor;
|
|
||||||
|
|
||||||
if (flavor == VAR_SIMPLE)
|
|
||||||
new_value = expand_string(value);
|
|
||||||
else
|
|
||||||
new_value = xstrdup(value);
|
|
||||||
|
|
||||||
if (append) {
|
|
||||||
v->value = xrealloc(v->value,
|
|
||||||
strlen(v->value) + strlen(new_value) + 2);
|
|
||||||
strcat(v->value, " ");
|
|
||||||
strcat(v->value, new_value);
|
|
||||||
free(new_value);
|
|
||||||
} else {
|
|
||||||
v->value = new_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void variable_del(struct variable *v)
|
|
||||||
{
|
|
||||||
list_del(&v->node);
|
|
||||||
free(v->name);
|
|
||||||
free(v->value);
|
|
||||||
free(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void variable_all_del(void)
|
|
||||||
{
|
|
||||||
struct variable *v, *tmp;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(v, tmp, &variable_list, node)
|
|
||||||
variable_del(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Evaluate a clause with arguments. argc/argv are arguments from the upper
|
|
||||||
* function call.
|
|
||||||
*
|
|
||||||
* Returned string must be freed when done
|
|
||||||
*/
|
|
||||||
static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *tmp, *name, *res, *endptr, *prev, *p;
|
|
||||||
int new_argc = 0;
|
|
||||||
char *new_argv[FUNCTION_MAX_ARGS];
|
|
||||||
int nest = 0;
|
|
||||||
int i;
|
|
||||||
unsigned long n;
|
|
||||||
|
|
||||||
tmp = xstrndup(str, len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If variable name is '1', '2', etc. It is generally an argument
|
|
||||||
* from a user-function call (i.e. local-scope variable). If not
|
|
||||||
* available, then look-up global-scope variables.
|
|
||||||
*/
|
|
||||||
n = strtoul(tmp, &endptr, 10);
|
|
||||||
if (!*endptr && n > 0 && n <= argc) {
|
|
||||||
res = xstrdup(argv[n - 1]);
|
|
||||||
goto free_tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = p = tmp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Split into tokens
|
|
||||||
* The function name and arguments are separated by a comma.
|
|
||||||
* For example, if the function call is like this:
|
|
||||||
* $(foo,$(x),$(y))
|
|
||||||
*
|
|
||||||
* The input string for this helper should be:
|
|
||||||
* foo,$(x),$(y)
|
|
||||||
*
|
|
||||||
* and split into:
|
|
||||||
* new_argv[0] = 'foo'
|
|
||||||
* new_argv[1] = '$(x)'
|
|
||||||
* new_argv[2] = '$(y)'
|
|
||||||
*/
|
|
||||||
while (*p) {
|
|
||||||
if (nest == 0 && *p == ',') {
|
|
||||||
*p = 0;
|
|
||||||
if (new_argc >= FUNCTION_MAX_ARGS)
|
|
||||||
pperror("too many function arguments");
|
|
||||||
new_argv[new_argc++] = prev;
|
|
||||||
prev = p + 1;
|
|
||||||
} else if (*p == '(') {
|
|
||||||
nest++;
|
|
||||||
} else if (*p == ')') {
|
|
||||||
nest--;
|
|
||||||
}
|
|
||||||
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
new_argv[new_argc++] = prev;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Shift arguments
|
|
||||||
* new_argv[0] represents a function name or a variable name. Put it
|
|
||||||
* into 'name', then shift the rest of the arguments. This simplifies
|
|
||||||
* 'const' handling.
|
|
||||||
*/
|
|
||||||
name = expand_string_with_args(new_argv[0], argc, argv);
|
|
||||||
new_argc--;
|
|
||||||
for (i = 0; i < new_argc; i++)
|
|
||||||
new_argv[i] = expand_string_with_args(new_argv[i + 1],
|
|
||||||
argc, argv);
|
|
||||||
|
|
||||||
/* Search for variables */
|
|
||||||
res = variable_expand(name, new_argc, new_argv);
|
|
||||||
if (res)
|
|
||||||
goto free;
|
|
||||||
|
|
||||||
/* Look for built-in functions */
|
|
||||||
res = function_expand(name, new_argc, new_argv);
|
|
||||||
if (res)
|
|
||||||
goto free;
|
|
||||||
|
|
||||||
/* Last, try environment variable */
|
|
||||||
if (new_argc == 0) {
|
|
||||||
res = env_expand(name);
|
|
||||||
if (res)
|
|
||||||
goto free;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = xstrdup("");
|
|
||||||
free:
|
|
||||||
for (i = 0; i < new_argc; i++)
|
|
||||||
free(new_argv[i]);
|
|
||||||
free(name);
|
|
||||||
free_tmp:
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Expand a string that follows '$'
|
|
||||||
*
|
|
||||||
* For example, if the input string is
|
|
||||||
* ($(FOO)$($(BAR)))$(BAZ)
|
|
||||||
* this helper evaluates
|
|
||||||
* $($(FOO)$($(BAR)))
|
|
||||||
* and returns a new string containing the expansion (note that the string is
|
|
||||||
* recursively expanded), also advancing 'str' to point to the next character
|
|
||||||
* after the corresponding closing parenthesis, in this case, *str will be
|
|
||||||
* $(BAR)
|
|
||||||
*/
|
|
||||||
static char *expand_dollar_with_args(const char **str, int argc, char *argv[])
|
|
||||||
{
|
|
||||||
const char *p = *str;
|
|
||||||
const char *q;
|
|
||||||
int nest = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In Kconfig, variable/function references always start with "$(".
|
|
||||||
* Neither single-letter variables as in $A nor curly braces as in ${CC}
|
|
||||||
* are supported. '$' not followed by '(' loses its special meaning.
|
|
||||||
*/
|
|
||||||
if (*p != '(') {
|
|
||||||
*str = p;
|
|
||||||
return xstrdup("$");
|
|
||||||
}
|
|
||||||
|
|
||||||
p++;
|
|
||||||
q = p;
|
|
||||||
while (*q) {
|
|
||||||
if (*q == '(') {
|
|
||||||
nest++;
|
|
||||||
} else if (*q == ')') {
|
|
||||||
if (nest-- == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
q++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*q)
|
|
||||||
pperror("unterminated reference to '%s': missing ')'", p);
|
|
||||||
|
|
||||||
/* Advance 'str' to after the expanded initial portion of the string */
|
|
||||||
*str = q + 1;
|
|
||||||
|
|
||||||
return eval_clause(p, q - p, argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *expand_dollar(const char **str)
|
|
||||||
{
|
|
||||||
return expand_dollar_with_args(str, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *__expand_string(const char **str, bool (*is_end)(char c),
|
|
||||||
int argc, char *argv[])
|
|
||||||
{
|
|
||||||
const char *in, *p;
|
|
||||||
char *expansion, *out;
|
|
||||||
size_t in_len, out_len;
|
|
||||||
|
|
||||||
out = xmalloc(1);
|
|
||||||
*out = 0;
|
|
||||||
out_len = 1;
|
|
||||||
|
|
||||||
p = in = *str;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (*p == '$') {
|
|
||||||
in_len = p - in;
|
|
||||||
p++;
|
|
||||||
expansion = expand_dollar_with_args(&p, argc, argv);
|
|
||||||
out_len += in_len + strlen(expansion);
|
|
||||||
out = xrealloc(out, out_len);
|
|
||||||
strncat(out, in, in_len);
|
|
||||||
strcat(out, expansion);
|
|
||||||
free(expansion);
|
|
||||||
in = p;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_end(*p))
|
|
||||||
break;
|
|
||||||
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_len = p - in;
|
|
||||||
out_len += in_len;
|
|
||||||
out = xrealloc(out, out_len);
|
|
||||||
strncat(out, in, in_len);
|
|
||||||
|
|
||||||
/* Advance 'str' to the end character */
|
|
||||||
*str = p;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_end_of_str(char c)
|
|
||||||
{
|
|
||||||
return !c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Expand variables and functions in the given string. Undefined variables
|
|
||||||
* expand to an empty string.
|
|
||||||
* The returned string must be freed when done.
|
|
||||||
*/
|
|
||||||
static char *expand_string_with_args(const char *in, int argc, char *argv[])
|
|
||||||
{
|
|
||||||
return __expand_string(&in, is_end_of_str, argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *expand_string(const char *in)
|
|
||||||
{
|
|
||||||
return expand_string_with_args(in, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_end_of_token(char c)
|
|
||||||
{
|
|
||||||
/* Why are '.' and '/' valid characters for symbols? */
|
|
||||||
return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Expand variables in a token. The parsing stops when a token separater
|
|
||||||
* (in most cases, it is a whitespace) is encountered. 'str' is updated to
|
|
||||||
* point to the next character.
|
|
||||||
*
|
|
||||||
* The returned string must be freed when done.
|
|
||||||
*/
|
|
||||||
char *expand_one_token(const char **str)
|
|
||||||
{
|
|
||||||
return __expand_string(str, is_end_of_token, 0, NULL);
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
PKG="Qt5Core Qt5Gui Qt5Widgets"
|
|
||||||
PKG2="QtCore QtGui"
|
|
||||||
|
|
||||||
if [ -z "$(command -v pkg-config)" ]; then
|
|
||||||
echo >&2 "*"
|
|
||||||
echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it."
|
|
||||||
echo >&2 "*"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if pkg-config --exists $PKG; then
|
|
||||||
echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\"
|
|
||||||
echo libs=\"$(pkg-config --libs $PKG)\"
|
|
||||||
echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if pkg-config --exists $PKG2; then
|
|
||||||
echo cflags=\"$(pkg-config --cflags $PKG2)\"
|
|
||||||
echo libs=\"$(pkg-config --libs $PKG2)\"
|
|
||||||
echo moc=\"$(pkg-config --variable=moc_location QtCore)\"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo >&2 "*"
|
|
||||||
echo >&2 "* Could not find Qt via pkg-config."
|
|
||||||
echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"
|
|
||||||
echo >&2 "*"
|
|
||||||
exit 1
|
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
* Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
|
* Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
@ -32,8 +32,12 @@
|
|||||||
#include "qconf.h"
|
#include "qconf.h"
|
||||||
|
|
||||||
#include "qconf.moc"
|
#include "qconf.moc"
|
||||||
#include "images.h"
|
#include "images.c"
|
||||||
|
|
||||||
|
#ifdef _
|
||||||
|
# undef _
|
||||||
|
# define _ qgettext
|
||||||
|
#endif
|
||||||
|
|
||||||
static QApplication *configApp;
|
static QApplication *configApp;
|
||||||
static ConfigSettings *configSettings;
|
static ConfigSettings *configSettings;
|
||||||
@ -42,7 +46,12 @@ QAction *ConfigMainWindow::saveAction;
|
|||||||
|
|
||||||
static inline QString qgettext(const char* str)
|
static inline QString qgettext(const char* str)
|
||||||
{
|
{
|
||||||
return QString::fromLocal8Bit(str);
|
return QString::fromLocal8Bit(gettext(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QString qgettext(const QString& str)
|
||||||
|
{
|
||||||
|
return QString::fromLocal8Bit(gettext(str.toLatin1()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSettings::ConfigSettings()
|
ConfigSettings::ConfigSettings()
|
||||||
@ -56,19 +65,11 @@ ConfigSettings::ConfigSettings()
|
|||||||
QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
|
QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
|
||||||
{
|
{
|
||||||
QList<int> result;
|
QList<int> result;
|
||||||
|
QStringList entryList = value(key).toStringList();
|
||||||
|
QStringList::Iterator it;
|
||||||
|
|
||||||
if (contains(key))
|
for (it = entryList.begin(); it != entryList.end(); ++it)
|
||||||
{
|
result.push_back((*it).toInt());
|
||||||
QStringList entryList = value(key).toStringList();
|
|
||||||
QStringList::Iterator it;
|
|
||||||
|
|
||||||
for (it = entryList.begin(); it != entryList.end(); ++it)
|
|
||||||
result.push_back((*it).toInt());
|
|
||||||
|
|
||||||
*ok = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*ok = false;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -118,7 +119,7 @@ void ConfigItem::updateMenu(void)
|
|||||||
|
|
||||||
sym = menu->sym;
|
sym = menu->sym;
|
||||||
prop = menu->prompt;
|
prop = menu->prompt;
|
||||||
prompt = qgettext(menu_get_prompt(menu));
|
prompt = _(menu_get_prompt(menu));
|
||||||
|
|
||||||
if (prop) switch (prop->type) {
|
if (prop) switch (prop->type) {
|
||||||
case P_MENU:
|
case P_MENU:
|
||||||
@ -152,7 +153,7 @@ void ConfigItem::updateMenu(void)
|
|||||||
case S_TRISTATE:
|
case S_TRISTATE:
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
|
if (!sym_is_changable(sym) && list->optMode == normalOpt) {
|
||||||
setPixmap(promptColIdx, QIcon());
|
setPixmap(promptColIdx, QIcon());
|
||||||
setText(noColIdx, QString::null);
|
setText(noColIdx, QString::null);
|
||||||
setText(modColIdx, QString::null);
|
setText(modColIdx, QString::null);
|
||||||
@ -207,7 +208,7 @@ void ConfigItem::updateMenu(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!sym_has_value(sym) && visible)
|
if (!sym_has_value(sym) && visible)
|
||||||
prompt += " (NEW)";
|
prompt += _(" (NEW)");
|
||||||
set_prompt:
|
set_prompt:
|
||||||
setText(promptColIdx, prompt);
|
setText(promptColIdx, prompt);
|
||||||
}
|
}
|
||||||
@ -318,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
|
|||||||
setVerticalScrollMode(ScrollPerPixel);
|
setVerticalScrollMode(ScrollPerPixel);
|
||||||
setHorizontalScrollMode(ScrollPerPixel);
|
setHorizontalScrollMode(ScrollPerPixel);
|
||||||
|
|
||||||
setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
|
setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
|
||||||
|
|
||||||
connect(this, SIGNAL(itemSelectionChanged(void)),
|
connect(this, SIGNAL(itemSelectionChanged(void)),
|
||||||
SLOT(updateSelection(void)));
|
SLOT(updateSelection(void)));
|
||||||
@ -874,7 +875,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
QAction *action;
|
QAction *action;
|
||||||
|
|
||||||
headerPopup = new QMenu(this);
|
headerPopup = new QMenu(this);
|
||||||
action = new QAction("Show Name", this);
|
action = new QAction(_("Show Name"), this);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
connect(action, SIGNAL(toggled(bool)),
|
connect(action, SIGNAL(toggled(bool)),
|
||||||
parent(), SLOT(setShowName(bool)));
|
parent(), SLOT(setShowName(bool)));
|
||||||
@ -882,7 +883,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
action, SLOT(setOn(bool)));
|
action, SLOT(setOn(bool)));
|
||||||
action->setChecked(showName);
|
action->setChecked(showName);
|
||||||
headerPopup->addAction(action);
|
headerPopup->addAction(action);
|
||||||
action = new QAction("Show Range", this);
|
action = new QAction(_("Show Range"), this);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
connect(action, SIGNAL(toggled(bool)),
|
connect(action, SIGNAL(toggled(bool)),
|
||||||
parent(), SLOT(setShowRange(bool)));
|
parent(), SLOT(setShowRange(bool)));
|
||||||
@ -890,7 +891,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
action, SLOT(setOn(bool)));
|
action, SLOT(setOn(bool)));
|
||||||
action->setChecked(showRange);
|
action->setChecked(showRange);
|
||||||
headerPopup->addAction(action);
|
headerPopup->addAction(action);
|
||||||
action = new QAction("Show Data", this);
|
action = new QAction(_("Show Data"), this);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
connect(action, SIGNAL(toggled(bool)),
|
connect(action, SIGNAL(toggled(bool)),
|
||||||
parent(), SLOT(setShowData(bool)));
|
parent(), SLOT(setShowData(bool)));
|
||||||
@ -1013,7 +1014,7 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
|
|||||||
|
|
||||||
if (!objectName().isEmpty()) {
|
if (!objectName().isEmpty()) {
|
||||||
configSettings->beginGroup(objectName());
|
configSettings->beginGroup(objectName());
|
||||||
setShowDebug(configSettings->value("/showDebug", false).toBool());
|
_showDebug = configSettings->value("/showDebug", false).toBool();
|
||||||
configSettings->endGroup();
|
configSettings->endGroup();
|
||||||
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
|
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
|
||||||
}
|
}
|
||||||
@ -1077,7 +1078,7 @@ void ConfigInfoView::menuInfo(void)
|
|||||||
if (sym) {
|
if (sym) {
|
||||||
if (_menu->prompt) {
|
if (_menu->prompt) {
|
||||||
head += "<big><b>";
|
head += "<big><b>";
|
||||||
head += print_filter(_menu->prompt->text);
|
head += print_filter(_(_menu->prompt->text));
|
||||||
head += "</b></big>";
|
head += "</b></big>";
|
||||||
if (sym->name) {
|
if (sym->name) {
|
||||||
head += " (";
|
head += " (";
|
||||||
@ -1108,7 +1109,7 @@ void ConfigInfoView::menuInfo(void)
|
|||||||
str_free(&help_gstr);
|
str_free(&help_gstr);
|
||||||
} else if (_menu->prompt) {
|
} else if (_menu->prompt) {
|
||||||
head += "<big><b>";
|
head += "<big><b>";
|
||||||
head += print_filter(_menu->prompt->text);
|
head += print_filter(_(_menu->prompt->text));
|
||||||
head += "</b></big><br><br>";
|
head += "</b></big><br><br>";
|
||||||
if (showDebug()) {
|
if (showDebug()) {
|
||||||
if (_menu->prompt->visible.expr) {
|
if (_menu->prompt->visible.expr) {
|
||||||
@ -1143,12 +1144,13 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
|
|||||||
case P_PROMPT:
|
case P_PROMPT:
|
||||||
case P_MENU:
|
case P_MENU:
|
||||||
debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
|
debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
|
||||||
debug += print_filter(prop->text);
|
debug += print_filter(_(prop->text));
|
||||||
debug += "</a><br>";
|
debug += "</a><br>";
|
||||||
break;
|
break;
|
||||||
case P_DEFAULT:
|
case P_DEFAULT:
|
||||||
case P_SELECT:
|
case P_SELECT:
|
||||||
case P_RANGE:
|
case P_RANGE:
|
||||||
|
case P_ENV:
|
||||||
debug += prop_get_type_name(prop->type);
|
debug += prop_get_type_name(prop->type);
|
||||||
debug += ": ";
|
debug += ": ";
|
||||||
expr_print(prop->expr, expr_print_help, &debug, E_NONE);
|
expr_print(prop->expr, expr_print_help, &debug, E_NONE);
|
||||||
@ -1224,7 +1226,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
|
|||||||
QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
|
QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
|
||||||
{
|
{
|
||||||
QMenu* popup = Parent::createStandardContextMenu(pos);
|
QMenu* popup = Parent::createStandardContextMenu(pos);
|
||||||
QAction* action = new QAction("Show Debug Info", popup);
|
QAction* action = new QAction(_("Show Debug Info"), popup);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
|
connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
|
||||||
connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
|
connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
|
||||||
@ -1251,11 +1253,11 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
|
|||||||
QHBoxLayout* layout2 = new QHBoxLayout(0);
|
QHBoxLayout* layout2 = new QHBoxLayout(0);
|
||||||
layout2->setContentsMargins(0, 0, 0, 0);
|
layout2->setContentsMargins(0, 0, 0, 0);
|
||||||
layout2->setSpacing(6);
|
layout2->setSpacing(6);
|
||||||
layout2->addWidget(new QLabel("Find:", this));
|
layout2->addWidget(new QLabel(_("Find:"), this));
|
||||||
editField = new QLineEdit(this);
|
editField = new QLineEdit(this);
|
||||||
connect(editField, SIGNAL(returnPressed()), SLOT(search()));
|
connect(editField, SIGNAL(returnPressed()), SLOT(search()));
|
||||||
layout2->addWidget(editField);
|
layout2->addWidget(editField);
|
||||||
searchButton = new QPushButton("Search", this);
|
searchButton = new QPushButton(_("Search"), this);
|
||||||
searchButton->setAutoDefault(false);
|
searchButton->setAutoDefault(false);
|
||||||
connect(searchButton, SIGNAL(clicked()), SLOT(search()));
|
connect(searchButton, SIGNAL(clicked()), SLOT(search()));
|
||||||
layout2->addWidget(searchButton);
|
layout2->addWidget(searchButton);
|
||||||
@ -1377,46 +1379,44 @@ ConfigMainWindow::ConfigMainWindow(void)
|
|||||||
toolBar = new QToolBar("Tools", this);
|
toolBar = new QToolBar("Tools", this);
|
||||||
addToolBar(toolBar);
|
addToolBar(toolBar);
|
||||||
|
|
||||||
backAction = new QAction(QPixmap(xpm_back), "Back", this);
|
backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
|
||||||
connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
|
connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
|
||||||
backAction->setEnabled(false);
|
backAction->setEnabled(false);
|
||||||
QAction *quitAction = new QAction("&Quit", this);
|
QAction *quitAction = new QAction(_("&Quit"), this);
|
||||||
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
|
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
|
||||||
connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
|
connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
|
||||||
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
|
QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
|
||||||
loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
|
loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
|
||||||
connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
|
connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
|
||||||
saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
|
saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
|
||||||
saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
|
saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
|
||||||
connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
|
connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
|
||||||
conf_set_changed_callback(conf_changed);
|
conf_set_changed_callback(conf_changed);
|
||||||
// Set saveAction's initial state
|
// Set saveAction's initial state
|
||||||
conf_changed();
|
conf_changed();
|
||||||
configname = xstrdup(conf_get_configname());
|
QAction *saveAsAction = new QAction(_("Save &As..."), this);
|
||||||
|
|
||||||
QAction *saveAsAction = new QAction("Save &As...", this);
|
|
||||||
connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
|
connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
|
||||||
QAction *searchAction = new QAction("&Find", this);
|
QAction *searchAction = new QAction(_("&Find"), this);
|
||||||
searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
|
searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
|
||||||
connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
|
connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
|
||||||
singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
|
singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
|
||||||
singleViewAction->setCheckable(true);
|
singleViewAction->setCheckable(true);
|
||||||
connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
|
connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
|
||||||
splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
|
splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
|
||||||
splitViewAction->setCheckable(true);
|
splitViewAction->setCheckable(true);
|
||||||
connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
|
connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
|
||||||
fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
|
fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
|
||||||
fullViewAction->setCheckable(true);
|
fullViewAction->setCheckable(true);
|
||||||
connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
|
connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
|
||||||
|
|
||||||
QAction *showNameAction = new QAction("Show Name", this);
|
QAction *showNameAction = new QAction(_("Show Name"), this);
|
||||||
showNameAction->setCheckable(true);
|
showNameAction->setCheckable(true);
|
||||||
connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
|
connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
|
||||||
showNameAction->setChecked(configView->showName());
|
showNameAction->setChecked(configView->showName());
|
||||||
QAction *showRangeAction = new QAction("Show Range", this);
|
QAction *showRangeAction = new QAction(_("Show Range"), this);
|
||||||
showRangeAction->setCheckable(true);
|
showRangeAction->setCheckable(true);
|
||||||
connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
|
connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
|
||||||
QAction *showDataAction = new QAction("Show Data", this);
|
QAction *showDataAction = new QAction(_("Show Data"), this);
|
||||||
showDataAction->setCheckable(true);
|
showDataAction->setCheckable(true);
|
||||||
connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
|
connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
|
||||||
|
|
||||||
@ -1427,21 +1427,21 @@ ConfigMainWindow::ConfigMainWindow(void)
|
|||||||
connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
|
connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
|
||||||
SLOT(setOptionMode(QAction *)));
|
SLOT(setOptionMode(QAction *)));
|
||||||
|
|
||||||
configView->showNormalAction = new QAction("Show Normal Options", optGroup);
|
configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
|
||||||
configView->showAllAction = new QAction("Show All Options", optGroup);
|
configView->showAllAction = new QAction(_("Show All Options"), optGroup);
|
||||||
configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
|
configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
|
||||||
configView->showNormalAction->setCheckable(true);
|
configView->showNormalAction->setCheckable(true);
|
||||||
configView->showAllAction->setCheckable(true);
|
configView->showAllAction->setCheckable(true);
|
||||||
configView->showPromptAction->setCheckable(true);
|
configView->showPromptAction->setCheckable(true);
|
||||||
|
|
||||||
QAction *showDebugAction = new QAction("Show Debug Info", this);
|
QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
|
||||||
showDebugAction->setCheckable(true);
|
showDebugAction->setCheckable(true);
|
||||||
connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
|
connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
|
||||||
showDebugAction->setChecked(helpText->showDebug());
|
showDebugAction->setChecked(helpText->showDebug());
|
||||||
|
|
||||||
QAction *showIntroAction = new QAction("Introduction", this);
|
QAction *showIntroAction = new QAction( _("Introduction"), this);
|
||||||
connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
|
connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
|
||||||
QAction *showAboutAction = new QAction("About", this);
|
QAction *showAboutAction = new QAction( _("About"), this);
|
||||||
connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
|
connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
|
||||||
|
|
||||||
// init tool bar
|
// init tool bar
|
||||||
@ -1455,7 +1455,7 @@ ConfigMainWindow::ConfigMainWindow(void)
|
|||||||
toolBar->addAction(fullViewAction);
|
toolBar->addAction(fullViewAction);
|
||||||
|
|
||||||
// create config menu
|
// create config menu
|
||||||
QMenu* config = menu->addMenu("&File");
|
QMenu* config = menu->addMenu(_("&File"));
|
||||||
config->addAction(loadAction);
|
config->addAction(loadAction);
|
||||||
config->addAction(saveAction);
|
config->addAction(saveAction);
|
||||||
config->addAction(saveAsAction);
|
config->addAction(saveAsAction);
|
||||||
@ -1463,22 +1463,21 @@ ConfigMainWindow::ConfigMainWindow(void)
|
|||||||
config->addAction(quitAction);
|
config->addAction(quitAction);
|
||||||
|
|
||||||
// create edit menu
|
// create edit menu
|
||||||
QMenu* editMenu = menu->addMenu("&Edit");
|
QMenu* editMenu = menu->addMenu(_("&Edit"));
|
||||||
editMenu->addAction(searchAction);
|
editMenu->addAction(searchAction);
|
||||||
|
|
||||||
// create options menu
|
// create options menu
|
||||||
QMenu* optionMenu = menu->addMenu("&Option");
|
QMenu* optionMenu = menu->addMenu(_("&Option"));
|
||||||
optionMenu->addAction(showNameAction);
|
optionMenu->addAction(showNameAction);
|
||||||
optionMenu->addAction(showRangeAction);
|
optionMenu->addAction(showRangeAction);
|
||||||
optionMenu->addAction(showDataAction);
|
optionMenu->addAction(showDataAction);
|
||||||
optionMenu->addSeparator();
|
optionMenu->addSeparator();
|
||||||
optionMenu->addActions(optGroup->actions());
|
optionMenu->addActions(optGroup->actions());
|
||||||
optionMenu->addSeparator();
|
optionMenu->addSeparator();
|
||||||
optionMenu->addAction(showDebugAction);
|
|
||||||
|
|
||||||
// create help menu
|
// create help menu
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
QMenu* helpMenu = menu->addMenu("&Help");
|
QMenu* helpMenu = menu->addMenu(_("&Help"));
|
||||||
helpMenu->addAction(showIntroAction);
|
helpMenu->addAction(showIntroAction);
|
||||||
helpMenu->addAction(showAboutAction);
|
helpMenu->addAction(showAboutAction);
|
||||||
|
|
||||||
@ -1522,57 +1521,29 @@ ConfigMainWindow::ConfigMainWindow(void)
|
|||||||
|
|
||||||
void ConfigMainWindow::loadConfig(void)
|
void ConfigMainWindow::loadConfig(void)
|
||||||
{
|
{
|
||||||
QString str;
|
QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
|
||||||
QByteArray ba;
|
if (s.isNull())
|
||||||
const char *name;
|
|
||||||
|
|
||||||
str = QFileDialog::getOpenFileName(this, "", configname);
|
|
||||||
if (str.isNull())
|
|
||||||
return;
|
return;
|
||||||
|
if (conf_read(QFile::encodeName(s)))
|
||||||
ba = str.toLocal8Bit();
|
QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
|
||||||
name = ba.data();
|
|
||||||
|
|
||||||
if (conf_read(name))
|
|
||||||
QMessageBox::information(this, "qconf", "Unable to load configuration!");
|
|
||||||
|
|
||||||
free(configname);
|
|
||||||
configname = xstrdup(name);
|
|
||||||
|
|
||||||
ConfigView::updateListAll();
|
ConfigView::updateListAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigMainWindow::saveConfig(void)
|
bool ConfigMainWindow::saveConfig(void)
|
||||||
{
|
{
|
||||||
if (conf_write(configname)) {
|
if (conf_write(NULL)) {
|
||||||
QMessageBox::information(this, "qconf", "Unable to save configuration!");
|
QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
conf_write_autoconf(0);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigMainWindow::saveConfigAs(void)
|
void ConfigMainWindow::saveConfigAs(void)
|
||||||
{
|
{
|
||||||
QString str;
|
QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
|
||||||
QByteArray ba;
|
if (s.isNull())
|
||||||
const char *name;
|
|
||||||
|
|
||||||
str = QFileDialog::getSaveFileName(this, "", configname);
|
|
||||||
if (str.isNull())
|
|
||||||
return;
|
return;
|
||||||
|
saveConfig();
|
||||||
ba = str.toLocal8Bit();
|
|
||||||
name = ba.data();
|
|
||||||
|
|
||||||
if (conf_write(name)) {
|
|
||||||
QMessageBox::information(this, "qconf", "Unable to save configuration!");
|
|
||||||
}
|
|
||||||
conf_write_autoconf(0);
|
|
||||||
|
|
||||||
free(configname);
|
|
||||||
configname = xstrdup(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigMainWindow::searchConfig(void)
|
void ConfigMainWindow::searchConfig(void)
|
||||||
@ -1743,11 +1714,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
|
|||||||
e->accept();
|
e->accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
|
QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
|
||||||
QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
|
QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
|
||||||
mb.setButtonText(QMessageBox::Yes, "&Save Changes");
|
mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
|
||||||
mb.setButtonText(QMessageBox::No, "&Discard Changes");
|
mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
|
||||||
mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
|
mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
|
||||||
switch (mb.exec()) {
|
switch (mb.exec()) {
|
||||||
case QMessageBox::Yes:
|
case QMessageBox::Yes:
|
||||||
if (saveConfig())
|
if (saveConfig())
|
||||||
@ -1766,7 +1737,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
|
|||||||
|
|
||||||
void ConfigMainWindow::showIntro(void)
|
void ConfigMainWindow::showIntro(void)
|
||||||
{
|
{
|
||||||
static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
|
static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
|
||||||
"For each option, a blank box indicates the feature is disabled, a check\n"
|
"For each option, a blank box indicates the feature is disabled, a check\n"
|
||||||
"indicates it is enabled, and a dot indicates that it is to be compiled\n"
|
"indicates it is enabled, and a dot indicates that it is to be compiled\n"
|
||||||
"as a module. Clicking on the box will cycle through the three states.\n\n"
|
"as a module. Clicking on the box will cycle through the three states.\n\n"
|
||||||
@ -1776,16 +1747,16 @@ void ConfigMainWindow::showIntro(void)
|
|||||||
"options must be enabled to support the option you are interested in, you can\n"
|
"options must be enabled to support the option you are interested in, you can\n"
|
||||||
"still view the help of a grayed-out option.\n\n"
|
"still view the help of a grayed-out option.\n\n"
|
||||||
"Toggling Show Debug Info under the Options menu will show the dependencies,\n"
|
"Toggling Show Debug Info under the Options menu will show the dependencies,\n"
|
||||||
"which you can then match by examining other options.\n\n";
|
"which you can then match by examining other options.\n\n");
|
||||||
|
|
||||||
QMessageBox::information(this, "qconf", str);
|
QMessageBox::information(this, "qconf", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigMainWindow::showAbout(void)
|
void ConfigMainWindow::showAbout(void)
|
||||||
{
|
{
|
||||||
static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
|
static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
|
||||||
"Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
|
"Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
|
||||||
"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
|
"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
|
||||||
|
|
||||||
QMessageBox::information(this, "qconf", str);
|
QMessageBox::information(this, "qconf", str);
|
||||||
}
|
}
|
||||||
@ -1846,7 +1817,7 @@ static const char *progname;
|
|||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
printf("%s [-s] <config>\n", progname);
|
printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1855,6 +1826,9 @@ int main(int ac, char** av)
|
|||||||
ConfigMainWindow* v;
|
ConfigMainWindow* v;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
progname = av[0];
|
progname = av[0];
|
||||||
configApp = new QApplication(ac, av);
|
configApp = new QApplication(ac, av);
|
||||||
if (ac > 1 && av[1][0] == '-') {
|
if (ac > 1 && av[1][0] == '-') {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QTextBrowser>
|
#include <QTextBrowser>
|
||||||
@ -291,7 +291,6 @@ protected:
|
|||||||
class ConfigMainWindow : public QMainWindow {
|
class ConfigMainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
char *configname;
|
|
||||||
static QAction *saveAction;
|
static QAction *saveAction;
|
||||||
static void conf_changed(void);
|
static void conf_changed(void);
|
||||||
public:
|
public:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -33,6 +33,33 @@ struct symbol *sym_defconfig_list;
|
|||||||
struct symbol *modules_sym;
|
struct symbol *modules_sym;
|
||||||
tristate modules_val;
|
tristate modules_val;
|
||||||
|
|
||||||
|
struct expr *sym_env_list;
|
||||||
|
|
||||||
|
static void sym_add_default(struct symbol *sym, const char *def)
|
||||||
|
{
|
||||||
|
struct property *prop = prop_alloc(P_DEFAULT, sym);
|
||||||
|
|
||||||
|
prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sym_init(void)
|
||||||
|
{
|
||||||
|
struct symbol *sym;
|
||||||
|
struct utsname uts;
|
||||||
|
static bool inited = false;
|
||||||
|
|
||||||
|
if (inited)
|
||||||
|
return;
|
||||||
|
inited = true;
|
||||||
|
|
||||||
|
uname(&uts);
|
||||||
|
|
||||||
|
sym = sym_lookup("UNAME_RELEASE", 0);
|
||||||
|
sym->type = S_STRING;
|
||||||
|
sym->flags |= SYMBOL_AUTO;
|
||||||
|
sym_add_default(sym, uts.release);
|
||||||
|
}
|
||||||
|
|
||||||
enum symbol_type sym_get_type(struct symbol *sym)
|
enum symbol_type sym_get_type(struct symbol *sym)
|
||||||
{
|
{
|
||||||
enum symbol_type type = sym->type;
|
enum symbol_type type = sym->type;
|
||||||
@ -50,7 +77,7 @@ const char *sym_type_name(enum symbol_type type)
|
|||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
return "bool";
|
return "boolean";
|
||||||
case S_TRISTATE:
|
case S_TRISTATE:
|
||||||
return "tristate";
|
return "tristate";
|
||||||
case S_INT:
|
case S_INT:
|
||||||
@ -61,6 +88,8 @@ const char *sym_type_name(enum symbol_type type)
|
|||||||
return "string";
|
return "string";
|
||||||
case S_UNKNOWN:
|
case S_UNKNOWN:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
case S_OTHER:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
@ -74,6 +103,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct property *sym_get_env_prop(struct symbol *sym)
|
||||||
|
{
|
||||||
|
struct property *prop;
|
||||||
|
|
||||||
|
for_all_properties(sym, prop, P_ENV)
|
||||||
|
return prop;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct property *sym_get_default_prop(struct symbol *sym)
|
static struct property *sym_get_default_prop(struct symbol *sym)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
@ -86,7 +124,7 @@ static struct property *sym_get_default_prop(struct symbol *sym)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct property *sym_get_range_prop(struct symbol *sym)
|
static struct property *sym_get_range_prop(struct symbol *sym)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
|
|
||||||
@ -145,7 +183,7 @@ static void sym_validate_range(struct symbol *sym)
|
|||||||
sprintf(str, "%lld", val2);
|
sprintf(str, "%lld", val2);
|
||||||
else
|
else
|
||||||
sprintf(str, "0x%llx", val2);
|
sprintf(str, "0x%llx", val2);
|
||||||
sym->curr.val = xstrdup(str);
|
sym->curr.val = strdup(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sym_set_changed(struct symbol *sym)
|
static void sym_set_changed(struct symbol *sym)
|
||||||
@ -205,7 +243,7 @@ static void sym_calc_visibility(struct symbol *sym)
|
|||||||
tri = yes;
|
tri = yes;
|
||||||
if (sym->dir_dep.expr)
|
if (sym->dir_dep.expr)
|
||||||
tri = expr_calc_value(sym->dir_dep.expr);
|
tri = expr_calc_value(sym->dir_dep.expr);
|
||||||
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
if (tri == mod)
|
||||||
tri = yes;
|
tri = yes;
|
||||||
if (sym->dir_dep.tri != tri) {
|
if (sym->dir_dep.tri != tri) {
|
||||||
sym->dir_dep.tri = tri;
|
sym->dir_dep.tri = tri;
|
||||||
@ -220,15 +258,6 @@ static void sym_calc_visibility(struct symbol *sym)
|
|||||||
sym->rev_dep.tri = tri;
|
sym->rev_dep.tri = tri;
|
||||||
sym_set_changed(sym);
|
sym_set_changed(sym);
|
||||||
}
|
}
|
||||||
tri = no;
|
|
||||||
if (sym->implied.expr && sym->dir_dep.tri != no)
|
|
||||||
tri = expr_calc_value(sym->implied.expr);
|
|
||||||
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
|
||||||
tri = yes;
|
|
||||||
if (sym->implied.tri != tri) {
|
|
||||||
sym->implied.tri = tri;
|
|
||||||
sym_set_changed(sym);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -333,13 +362,11 @@ void sym_calc_value(struct symbol *sym)
|
|||||||
sym->curr.tri = no;
|
sym->curr.tri = no;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sym->flags &= ~SYMBOL_WRITE;
|
if (!sym_is_choice_value(sym))
|
||||||
|
sym->flags &= ~SYMBOL_WRITE;
|
||||||
|
|
||||||
sym_calc_visibility(sym);
|
sym_calc_visibility(sym);
|
||||||
|
|
||||||
if (sym->visible != no)
|
|
||||||
sym->flags |= SYMBOL_WRITE;
|
|
||||||
|
|
||||||
/* set default if recursively called */
|
/* set default if recursively called */
|
||||||
sym->curr = newval;
|
sym->curr = newval;
|
||||||
|
|
||||||
@ -354,6 +381,7 @@ void sym_calc_value(struct symbol *sym)
|
|||||||
/* if the symbol is visible use the user value
|
/* if the symbol is visible use the user value
|
||||||
* if available, otherwise try the default value
|
* if available, otherwise try the default value
|
||||||
*/
|
*/
|
||||||
|
sym->flags |= SYMBOL_WRITE;
|
||||||
if (sym_has_value(sym)) {
|
if (sym_has_value(sym)) {
|
||||||
newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
|
newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
|
||||||
sym->visible);
|
sym->visible);
|
||||||
@ -369,28 +397,26 @@ void sym_calc_value(struct symbol *sym)
|
|||||||
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
|
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
|
||||||
prop->visible.tri);
|
prop->visible.tri);
|
||||||
}
|
}
|
||||||
if (sym->implied.tri != no) {
|
|
||||||
sym->flags |= SYMBOL_WRITE;
|
|
||||||
newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
calc_newval:
|
calc_newval:
|
||||||
if (sym->dir_dep.tri < sym->rev_dep.tri) {
|
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
|
||||||
newval.tri = no;
|
newval.tri = no;
|
||||||
} else {
|
} else {
|
||||||
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
|
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newval.tri == mod &&
|
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
||||||
(sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes))
|
|
||||||
newval.tri = yes;
|
newval.tri = yes;
|
||||||
break;
|
break;
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
case S_HEX:
|
case S_HEX:
|
||||||
case S_INT:
|
case S_INT:
|
||||||
if (sym->visible != no && sym_has_value(sym)) {
|
if (sym->visible != no) {
|
||||||
newval.val = sym->def[S_DEF_USER].val;
|
sym->flags |= SYMBOL_WRITE;
|
||||||
break;
|
if (sym_has_value(sym)) {
|
||||||
|
newval.val = sym->def[S_DEF_USER].val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prop = sym_get_default_prop(sym);
|
prop = sym_get_default_prop(sym);
|
||||||
if (prop) {
|
if (prop) {
|
||||||
@ -432,7 +458,7 @@ void sym_calc_value(struct symbol *sym)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym->flags & SYMBOL_NO_WRITE)
|
if (sym->flags & SYMBOL_AUTO)
|
||||||
sym->flags &= ~SYMBOL_WRITE;
|
sym->flags &= ~SYMBOL_WRITE;
|
||||||
|
|
||||||
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
|
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
|
||||||
@ -464,8 +490,6 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
|
|||||||
return false;
|
return false;
|
||||||
if (sym->visible <= sym->rev_dep.tri)
|
if (sym->visible <= sym->rev_dep.tri)
|
||||||
return false;
|
return false;
|
||||||
if (sym->implied.tri == yes && val == mod)
|
|
||||||
return false;
|
|
||||||
if (sym_is_choice_value(sym) && sym->visible == yes)
|
if (sym_is_choice_value(sym) && sym->visible == yes)
|
||||||
return val == yes;
|
return val == yes;
|
||||||
return val >= sym->rev_dep.tri && val <= sym->visible;
|
return val >= sym->rev_dep.tri && val <= sym->visible;
|
||||||
@ -718,10 +742,6 @@ const char *sym_get_string_default(struct symbol *sym)
|
|||||||
if (sym->type == S_BOOLEAN && val == mod)
|
if (sym->type == S_BOOLEAN && val == mod)
|
||||||
val = yes;
|
val = yes;
|
||||||
|
|
||||||
/* adjust the default value if this symbol is implied by another */
|
|
||||||
if (val < sym->implied.tri)
|
|
||||||
val = sym->implied.tri;
|
|
||||||
|
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
case S_TRISTATE:
|
case S_TRISTATE:
|
||||||
@ -735,6 +755,7 @@ const char *sym_get_string_default(struct symbol *sym)
|
|||||||
return str;
|
return str;
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
return str;
|
return str;
|
||||||
|
case S_OTHER:
|
||||||
case S_UNKNOWN:
|
case S_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -765,7 +786,7 @@ const char *sym_get_string_value(struct symbol *sym)
|
|||||||
return (const char *)sym->curr.val;
|
return (const char *)sym->curr.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sym_is_changeable(struct symbol *sym)
|
bool sym_is_changable(struct symbol *sym)
|
||||||
{
|
{
|
||||||
return sym->visible > sym->rev_dep.tri;
|
return sym->visible > sym->rev_dep.tri;
|
||||||
}
|
}
|
||||||
@ -802,7 +823,7 @@ struct symbol *sym_lookup(const char *name, int flags)
|
|||||||
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
|
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
new_name = xstrdup(name);
|
new_name = strdup(name);
|
||||||
} else {
|
} else {
|
||||||
new_name = NULL;
|
new_name = NULL;
|
||||||
hash = 0;
|
hash = 0;
|
||||||
@ -847,6 +868,55 @@ struct symbol *sym_find(const char *name)
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand symbol's names embedded in the string given in argument. Symbols'
|
||||||
|
* name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
|
||||||
|
* the empty string.
|
||||||
|
*/
|
||||||
|
const char *sym_expand_string_value(const char *in)
|
||||||
|
{
|
||||||
|
const char *src;
|
||||||
|
char *res;
|
||||||
|
size_t reslen;
|
||||||
|
|
||||||
|
reslen = strlen(in) + 1;
|
||||||
|
res = xmalloc(reslen);
|
||||||
|
res[0] = '\0';
|
||||||
|
|
||||||
|
while ((src = strchr(in, '$'))) {
|
||||||
|
char *p, name[SYMBOL_MAXLENGTH];
|
||||||
|
const char *symval = "";
|
||||||
|
struct symbol *sym;
|
||||||
|
size_t newlen;
|
||||||
|
|
||||||
|
strncat(res, in, src - in);
|
||||||
|
src++;
|
||||||
|
|
||||||
|
p = name;
|
||||||
|
while (isalnum(*src) || *src == '_')
|
||||||
|
*p++ = *src++;
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
sym = sym_find(name);
|
||||||
|
if (sym != NULL) {
|
||||||
|
sym_calc_value(sym);
|
||||||
|
symval = sym_get_string_value(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
|
||||||
|
if (newlen > reslen) {
|
||||||
|
reslen = newlen;
|
||||||
|
res = realloc(res, reslen);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(res, symval);
|
||||||
|
in = src;
|
||||||
|
}
|
||||||
|
strcat(res, in);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
const char *sym_escape_string_value(const char *in)
|
const char *sym_escape_string_value(const char *in)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -963,7 +1033,7 @@ struct symbol **sym_re_search(const char *pattern)
|
|||||||
}
|
}
|
||||||
if (sym_match_arr) {
|
if (sym_match_arr) {
|
||||||
qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
|
qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
|
||||||
sym_arr = malloc((cnt+1) * sizeof(struct symbol *));
|
sym_arr = malloc((cnt+1) * sizeof(struct symbol));
|
||||||
if (!sym_arr)
|
if (!sym_arr)
|
||||||
goto sym_re_search_free;
|
goto sym_re_search_free;
|
||||||
for (i = 0; i < cnt; i++)
|
for (i = 0; i < cnt; i++)
|
||||||
@ -988,7 +1058,7 @@ static struct dep_stack {
|
|||||||
struct dep_stack *prev, *next;
|
struct dep_stack *prev, *next;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
struct expr **expr;
|
struct expr *expr;
|
||||||
} *check_top;
|
} *check_top;
|
||||||
|
|
||||||
static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
|
static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
|
||||||
@ -1052,8 +1122,20 @@ static void sym_check_print_recursive(struct symbol *last_sym)
|
|||||||
if (stack->sym == last_sym)
|
if (stack->sym == last_sym)
|
||||||
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
|
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
|
||||||
prop->file->name, prop->lineno);
|
prop->file->name, prop->lineno);
|
||||||
|
fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
|
||||||
if (sym_is_choice(sym)) {
|
fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
|
||||||
|
if (stack->expr) {
|
||||||
|
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
|
||||||
|
prop->file->name, prop->lineno,
|
||||||
|
sym->name ? sym->name : "<choice>",
|
||||||
|
prop_get_type_name(prop->type),
|
||||||
|
next_sym->name ? next_sym->name : "<choice>");
|
||||||
|
} else if (stack->prop) {
|
||||||
|
fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
|
||||||
|
prop->file->name, prop->lineno,
|
||||||
|
sym->name ? sym->name : "<choice>",
|
||||||
|
next_sym->name ? next_sym->name : "<choice>");
|
||||||
|
} else if (sym_is_choice(sym)) {
|
||||||
fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
|
fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
|
||||||
menu->file->name, menu->lineno,
|
menu->file->name, menu->lineno,
|
||||||
sym->name ? sym->name : "<choice>",
|
sym->name ? sym->name : "<choice>",
|
||||||
@ -1063,41 +1145,14 @@ static void sym_check_print_recursive(struct symbol *last_sym)
|
|||||||
menu->file->name, menu->lineno,
|
menu->file->name, menu->lineno,
|
||||||
sym->name ? sym->name : "<choice>",
|
sym->name ? sym->name : "<choice>",
|
||||||
next_sym->name ? next_sym->name : "<choice>");
|
next_sym->name ? next_sym->name : "<choice>");
|
||||||
} else if (stack->expr == &sym->dir_dep.expr) {
|
} else {
|
||||||
fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
|
|
||||||
prop->file->name, prop->lineno,
|
|
||||||
sym->name ? sym->name : "<choice>",
|
|
||||||
next_sym->name ? next_sym->name : "<choice>");
|
|
||||||
} else if (stack->expr == &sym->rev_dep.expr) {
|
|
||||||
fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
|
fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
|
||||||
prop->file->name, prop->lineno,
|
prop->file->name, prop->lineno,
|
||||||
sym->name ? sym->name : "<choice>",
|
sym->name ? sym->name : "<choice>",
|
||||||
next_sym->name ? next_sym->name : "<choice>");
|
next_sym->name ? next_sym->name : "<choice>");
|
||||||
} else if (stack->expr == &sym->implied.expr) {
|
|
||||||
fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
|
|
||||||
prop->file->name, prop->lineno,
|
|
||||||
sym->name ? sym->name : "<choice>",
|
|
||||||
next_sym->name ? next_sym->name : "<choice>");
|
|
||||||
} else if (stack->expr) {
|
|
||||||
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
|
|
||||||
prop->file->name, prop->lineno,
|
|
||||||
sym->name ? sym->name : "<choice>",
|
|
||||||
prop_get_type_name(prop->type),
|
|
||||||
next_sym->name ? next_sym->name : "<choice>");
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
|
|
||||||
prop->file->name, prop->lineno,
|
|
||||||
sym->name ? sym->name : "<choice>",
|
|
||||||
prop_get_type_name(prop->type),
|
|
||||||
next_sym->name ? next_sym->name : "<choice>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr,
|
|
||||||
"For a resolution refer to Documentation/kbuild/kconfig-language.rst\n"
|
|
||||||
"subsection \"Kconfig recursive dependency limitations\"\n"
|
|
||||||
"\n");
|
|
||||||
|
|
||||||
if (check_top == &cv_stack)
|
if (check_top == &cv_stack)
|
||||||
dep_stack_remove();
|
dep_stack_remove();
|
||||||
}
|
}
|
||||||
@ -1132,7 +1187,7 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Oops! How to check %d?\n", e->type);
|
printf("Oops! How to check %d?\n", e->type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,26 +1200,12 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
|
|||||||
|
|
||||||
dep_stack_insert(&stack, sym);
|
dep_stack_insert(&stack, sym);
|
||||||
|
|
||||||
stack.expr = &sym->dir_dep.expr;
|
|
||||||
sym2 = sym_check_expr_deps(sym->dir_dep.expr);
|
|
||||||
if (sym2)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
stack.expr = &sym->rev_dep.expr;
|
|
||||||
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
|
sym2 = sym_check_expr_deps(sym->rev_dep.expr);
|
||||||
if (sym2)
|
if (sym2)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
stack.expr = &sym->implied.expr;
|
|
||||||
sym2 = sym_check_expr_deps(sym->implied.expr);
|
|
||||||
if (sym2)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
stack.expr = NULL;
|
|
||||||
|
|
||||||
for (prop = sym->prop; prop; prop = prop->next) {
|
for (prop = sym->prop; prop; prop = prop->next) {
|
||||||
if (prop->type == P_CHOICE || prop->type == P_SELECT ||
|
if (prop->type == P_CHOICE || prop->type == P_SELECT)
|
||||||
prop->type == P_IMPLY)
|
|
||||||
continue;
|
continue;
|
||||||
stack.prop = prop;
|
stack.prop = prop;
|
||||||
sym2 = sym_check_expr_deps(prop->visible.expr);
|
sym2 = sym_check_expr_deps(prop->visible.expr);
|
||||||
@ -1172,7 +1213,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
|
|||||||
break;
|
break;
|
||||||
if (prop->type != P_DEFAULT || sym_is_choice(sym))
|
if (prop->type != P_DEFAULT || sym_is_choice(sym))
|
||||||
continue;
|
continue;
|
||||||
stack.expr = &prop->expr;
|
stack.expr = prop->expr;
|
||||||
sym2 = sym_check_expr_deps(prop->expr);
|
sym2 = sym_check_expr_deps(prop->expr);
|
||||||
if (sym2)
|
if (sym2)
|
||||||
break;
|
break;
|
||||||
@ -1250,14 +1291,34 @@ struct symbol *sym_check_deps(struct symbol *sym)
|
|||||||
sym->flags &= ~SYMBOL_CHECK;
|
sym->flags &= ~SYMBOL_CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WARN_RECURSIVE_DEP
|
|
||||||
if (sym2 && sym2 == sym)
|
if (sym2 && sym2 == sym)
|
||||||
sym2 = NULL;
|
sym2 = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
return sym2;
|
return sym2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct property *prop_alloc(enum prop_type type, struct symbol *sym)
|
||||||
|
{
|
||||||
|
struct property *prop;
|
||||||
|
struct property **propp;
|
||||||
|
|
||||||
|
prop = xmalloc(sizeof(*prop));
|
||||||
|
memset(prop, 0, sizeof(*prop));
|
||||||
|
prop->type = type;
|
||||||
|
prop->sym = sym;
|
||||||
|
prop->file = current_file;
|
||||||
|
prop->lineno = zconf_lineno();
|
||||||
|
|
||||||
|
/* append property to the prop list of symbol */
|
||||||
|
if (sym) {
|
||||||
|
for (propp = &sym->prop; *propp; propp = &(*propp)->next)
|
||||||
|
;
|
||||||
|
*propp = prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
struct symbol *prop_get_symbol(struct property *prop)
|
struct symbol *prop_get_symbol(struct property *prop)
|
||||||
{
|
{
|
||||||
if (prop->expr && (prop->expr->type == E_SYMBOL ||
|
if (prop->expr && (prop->expr->type == E_SYMBOL ||
|
||||||
@ -1271,6 +1332,8 @@ const char *prop_get_type_name(enum prop_type type)
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case P_PROMPT:
|
case P_PROMPT:
|
||||||
return "prompt";
|
return "prompt";
|
||||||
|
case P_ENV:
|
||||||
|
return "env";
|
||||||
case P_COMMENT:
|
case P_COMMENT:
|
||||||
return "comment";
|
return "comment";
|
||||||
case P_MENU:
|
case P_MENU:
|
||||||
@ -1281,8 +1344,6 @@ const char *prop_get_type_name(enum prop_type type)
|
|||||||
return "choice";
|
return "choice";
|
||||||
case P_SELECT:
|
case P_SELECT:
|
||||||
return "select";
|
return "select";
|
||||||
case P_IMPLY:
|
|
||||||
return "imply";
|
|
||||||
case P_RANGE:
|
case P_RANGE:
|
||||||
return "range";
|
return "range";
|
||||||
case P_SYMBOL:
|
case P_SYMBOL:
|
||||||
@ -1294,3 +1355,32 @@ const char *prop_get_type_name(enum prop_type type)
|
|||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void prop_add_env(const char *env)
|
||||||
|
{
|
||||||
|
struct symbol *sym, *sym2;
|
||||||
|
struct property *prop;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
sym = current_entry->sym;
|
||||||
|
sym->flags |= SYMBOL_AUTO;
|
||||||
|
for_all_properties(sym, prop, P_ENV) {
|
||||||
|
sym2 = prop_get_symbol(prop);
|
||||||
|
if (strcmp(sym2->name, env))
|
||||||
|
menu_warn(current_entry, "redefining environment symbol from %s",
|
||||||
|
sym2->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
prop = prop_alloc(P_ENV, sym);
|
||||||
|
prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
|
||||||
|
|
||||||
|
sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
|
||||||
|
sym_env_list->right.sym = sym;
|
||||||
|
|
||||||
|
p = getenv(env);
|
||||||
|
if (p)
|
||||||
|
sym_add_default(sym, p);
|
||||||
|
else
|
||||||
|
menu_warn(current_entry, "environment variable %s undefined", env);
|
||||||
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
|
||||||
* Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
|
* Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
|
||||||
|
*
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -13,21 +14,69 @@
|
|||||||
struct file *file_lookup(const char *name)
|
struct file *file_lookup(const char *name)
|
||||||
{
|
{
|
||||||
struct file *file;
|
struct file *file;
|
||||||
|
const char *file_name = sym_expand_string_value(name);
|
||||||
|
|
||||||
for (file = file_list; file; file = file->next) {
|
for (file = file_list; file; file = file->next) {
|
||||||
if (!strcmp(name, file->name)) {
|
if (!strcmp(name, file->name)) {
|
||||||
|
free((void *)file_name);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file = xmalloc(sizeof(*file));
|
file = xmalloc(sizeof(*file));
|
||||||
memset(file, 0, sizeof(*file));
|
memset(file, 0, sizeof(*file));
|
||||||
file->name = xstrdup(name);
|
file->name = file_name;
|
||||||
file->next = file_list;
|
file->next = file_list;
|
||||||
file_list = file;
|
file_list = file;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* write a dependency file as used by kbuild to track dependencies */
|
||||||
|
int file_write_dep(const char *name)
|
||||||
|
{
|
||||||
|
struct symbol *sym, *env_sym;
|
||||||
|
struct expr *e;
|
||||||
|
struct file *file;
|
||||||
|
FILE *out;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
name = ".kconfig.d";
|
||||||
|
out = fopen("..config.tmp", "w");
|
||||||
|
if (!out)
|
||||||
|
return 1;
|
||||||
|
fprintf(out, "deps_config := \\\n");
|
||||||
|
for (file = file_list; file; file = file->next) {
|
||||||
|
if (file->next)
|
||||||
|
fprintf(out, "\t%s \\\n", file->name);
|
||||||
|
else
|
||||||
|
fprintf(out, "\t%s\n", file->name);
|
||||||
|
}
|
||||||
|
fprintf(out, "\n%s: \\\n"
|
||||||
|
"\t$(deps_config)\n\n", conf_get_autoconfig_name());
|
||||||
|
|
||||||
|
expr_list_for_each_sym(sym_env_list, e, sym) {
|
||||||
|
struct property *prop;
|
||||||
|
const char *value;
|
||||||
|
|
||||||
|
prop = sym_get_env_prop(sym);
|
||||||
|
env_sym = prop_get_symbol(prop);
|
||||||
|
if (!env_sym)
|
||||||
|
continue;
|
||||||
|
value = getenv(env_sym->name);
|
||||||
|
if (!value)
|
||||||
|
value = "";
|
||||||
|
fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
|
||||||
|
fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());
|
||||||
|
fprintf(out, "endif\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "\n$(deps_config): ;\n");
|
||||||
|
fclose(out);
|
||||||
|
rename("..config.tmp", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Allocate initial growable string */
|
/* Allocate initial growable string */
|
||||||
struct gstr str_new(void)
|
struct gstr str_new(void)
|
||||||
{
|
{
|
||||||
@ -55,7 +104,7 @@ void str_append(struct gstr *gs, const char *s)
|
|||||||
if (s) {
|
if (s) {
|
||||||
l = strlen(gs->s) + strlen(s) + 1;
|
l = strlen(gs->s) + strlen(s) + 1;
|
||||||
if (l > gs->len) {
|
if (l > gs->len) {
|
||||||
gs->s = xrealloc(gs->s, l);
|
gs->s = realloc(gs->s, l);
|
||||||
gs->len = l;
|
gs->len = l;
|
||||||
}
|
}
|
||||||
strcat(gs->s, s);
|
strcat(gs->s, s);
|
||||||
@ -96,34 +145,3 @@ void *xcalloc(size_t nmemb, size_t size)
|
|||||||
fprintf(stderr, "Out of memory.\n");
|
fprintf(stderr, "Out of memory.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *xrealloc(void *p, size_t size)
|
|
||||||
{
|
|
||||||
p = realloc(p, size);
|
|
||||||
if (p)
|
|
||||||
return p;
|
|
||||||
fprintf(stderr, "Out of memory.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *xstrdup(const char *s)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
p = strdup(s);
|
|
||||||
if (p)
|
|
||||||
return p;
|
|
||||||
fprintf(stderr, "Out of memory.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *xstrndup(const char *s, size_t n)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
p = strndup(s, n);
|
|
||||||
if (p)
|
|
||||||
return p;
|
|
||||||
fprintf(stderr, "Out of memory.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
49
scripts/config/zconf.gperf
Normal file
49
scripts/config/zconf.gperf
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
%language=ANSI-C
|
||||||
|
%define hash-function-name kconf_id_hash
|
||||||
|
%define lookup-function-name kconf_id_lookup
|
||||||
|
%define string-pool-name kconf_id_strings
|
||||||
|
%compare-strncmp
|
||||||
|
%enum
|
||||||
|
%pic
|
||||||
|
%struct-type
|
||||||
|
|
||||||
|
struct kconf_id;
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
mainmenu, T_MAINMENU, TF_COMMAND
|
||||||
|
menu, T_MENU, TF_COMMAND
|
||||||
|
endmenu, T_ENDMENU, TF_COMMAND
|
||||||
|
source, T_SOURCE, TF_COMMAND
|
||||||
|
choice, T_CHOICE, TF_COMMAND
|
||||||
|
endchoice, T_ENDCHOICE, TF_COMMAND
|
||||||
|
comment, T_COMMENT, TF_COMMAND
|
||||||
|
config, T_CONFIG, TF_COMMAND
|
||||||
|
menuconfig, T_MENUCONFIG, TF_COMMAND
|
||||||
|
help, T_HELP, TF_COMMAND
|
||||||
|
---help---, T_HELP, TF_COMMAND
|
||||||
|
if, T_IF, TF_COMMAND|TF_PARAM
|
||||||
|
endif, T_ENDIF, TF_COMMAND
|
||||||
|
depends, T_DEPENDS, TF_COMMAND
|
||||||
|
optional, T_OPTIONAL, TF_COMMAND
|
||||||
|
default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
|
||||||
|
prompt, T_PROMPT, TF_COMMAND
|
||||||
|
tristate, T_TYPE, TF_COMMAND, S_TRISTATE
|
||||||
|
def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
|
||||||
|
bool, T_TYPE, TF_COMMAND, S_BOOLEAN
|
||||||
|
boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
|
||||||
|
def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
|
||||||
|
int, T_TYPE, TF_COMMAND, S_INT
|
||||||
|
hex, T_TYPE, TF_COMMAND, S_HEX
|
||||||
|
string, T_TYPE, TF_COMMAND, S_STRING
|
||||||
|
select, T_SELECT, TF_COMMAND
|
||||||
|
range, T_RANGE, TF_COMMAND
|
||||||
|
visible, T_VISIBLE, TF_COMMAND
|
||||||
|
option, T_OPTION, TF_COMMAND
|
||||||
|
on, T_ON, TF_PARAM
|
||||||
|
modules, T_OPT_MODULES, TF_OPTION
|
||||||
|
defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
|
||||||
|
env, T_OPT_ENV, TF_OPTION
|
||||||
|
allnoconfig_y, T_OPT_ALLNOCONFIG_Y,TF_OPTION
|
||||||
|
reset, T_RESET, TF_COMMAND
|
||||||
|
%%
|
250
scripts/config/zconf.hash.c_shipped
Normal file
250
scripts/config/zconf.hash.c_shipped
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/* ANSI-C code produced by gperf version 3.0.4 */
|
||||||
|
/* Command-line: gperf */
|
||||||
|
/* Computed positions: -k'1,3' */
|
||||||
|
|
||||||
|
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||||
|
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||||
|
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||||
|
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||||
|
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||||
|
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||||
|
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||||
|
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||||
|
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||||
|
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||||
|
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||||
|
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||||
|
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||||
|
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||||
|
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||||
|
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||||
|
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||||
|
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||||
|
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||||
|
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||||
|
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||||
|
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||||
|
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
||||||
|
/* The character set is not based on ISO-646. */
|
||||||
|
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct kconf_id;
|
||||||
|
/* maximum key range = 47, duplicates = 0 */
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__inline
|
||||||
|
#else
|
||||||
|
#ifdef __cplusplus
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
static unsigned int
|
||||||
|
kconf_id_hash (register const char *str, register unsigned int len)
|
||||||
|
{
|
||||||
|
static unsigned char asso_values[] =
|
||||||
|
{
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 10, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 20, 40, 5,
|
||||||
|
0, 0, 5, 49, 5, 20, 49, 49, 5, 20,
|
||||||
|
5, 0, 35, 49, 0, 15, 0, 10, 15, 49,
|
||||||
|
25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||||
|
49, 49, 49, 49, 49, 49
|
||||||
|
};
|
||||||
|
register int hval = len;
|
||||||
|
|
||||||
|
switch (hval)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
hval += asso_values[(unsigned char)str[2]];
|
||||||
|
/*FALLTHROUGH*/
|
||||||
|
case 2:
|
||||||
|
case 1:
|
||||||
|
hval += asso_values[(unsigned char)str[0]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return hval;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct kconf_id_strings_t
|
||||||
|
{
|
||||||
|
char kconf_id_strings_str2[sizeof("on")];
|
||||||
|
char kconf_id_strings_str5[sizeof("endif")];
|
||||||
|
char kconf_id_strings_str6[sizeof("option")];
|
||||||
|
char kconf_id_strings_str7[sizeof("endmenu")];
|
||||||
|
char kconf_id_strings_str8[sizeof("optional")];
|
||||||
|
char kconf_id_strings_str9[sizeof("endchoice")];
|
||||||
|
char kconf_id_strings_str10[sizeof("range")];
|
||||||
|
char kconf_id_strings_str11[sizeof("choice")];
|
||||||
|
char kconf_id_strings_str12[sizeof("default")];
|
||||||
|
char kconf_id_strings_str13[sizeof("def_bool")];
|
||||||
|
char kconf_id_strings_str14[sizeof("help")];
|
||||||
|
char kconf_id_strings_str16[sizeof("config")];
|
||||||
|
char kconf_id_strings_str17[sizeof("def_tristate")];
|
||||||
|
char kconf_id_strings_str18[sizeof("env")];
|
||||||
|
char kconf_id_strings_str19[sizeof("defconfig_list")];
|
||||||
|
char kconf_id_strings_str20[sizeof("reset")];
|
||||||
|
char kconf_id_strings_str21[sizeof("string")];
|
||||||
|
char kconf_id_strings_str22[sizeof("if")];
|
||||||
|
char kconf_id_strings_str23[sizeof("int")];
|
||||||
|
char kconf_id_strings_str26[sizeof("select")];
|
||||||
|
char kconf_id_strings_str27[sizeof("modules")];
|
||||||
|
char kconf_id_strings_str28[sizeof("tristate")];
|
||||||
|
char kconf_id_strings_str29[sizeof("menu")];
|
||||||
|
char kconf_id_strings_str30[sizeof("---help---")];
|
||||||
|
char kconf_id_strings_str31[sizeof("source")];
|
||||||
|
char kconf_id_strings_str32[sizeof("comment")];
|
||||||
|
char kconf_id_strings_str33[sizeof("hex")];
|
||||||
|
char kconf_id_strings_str35[sizeof("menuconfig")];
|
||||||
|
char kconf_id_strings_str37[sizeof("visible")];
|
||||||
|
char kconf_id_strings_str38[sizeof("allnoconfig_y")];
|
||||||
|
char kconf_id_strings_str41[sizeof("prompt")];
|
||||||
|
char kconf_id_strings_str42[sizeof("depends")];
|
||||||
|
char kconf_id_strings_str44[sizeof("bool")];
|
||||||
|
char kconf_id_strings_str47[sizeof("boolean")];
|
||||||
|
char kconf_id_strings_str48[sizeof("mainmenu")];
|
||||||
|
};
|
||||||
|
static struct kconf_id_strings_t kconf_id_strings_contents =
|
||||||
|
{
|
||||||
|
"on",
|
||||||
|
"endif",
|
||||||
|
"option",
|
||||||
|
"endmenu",
|
||||||
|
"optional",
|
||||||
|
"endchoice",
|
||||||
|
"range",
|
||||||
|
"choice",
|
||||||
|
"default",
|
||||||
|
"def_bool",
|
||||||
|
"help",
|
||||||
|
"config",
|
||||||
|
"def_tristate",
|
||||||
|
"env",
|
||||||
|
"defconfig_list",
|
||||||
|
"reset",
|
||||||
|
"string",
|
||||||
|
"if",
|
||||||
|
"int",
|
||||||
|
"select",
|
||||||
|
"modules",
|
||||||
|
"tristate",
|
||||||
|
"menu",
|
||||||
|
"---help---",
|
||||||
|
"source",
|
||||||
|
"comment",
|
||||||
|
"hex",
|
||||||
|
"menuconfig",
|
||||||
|
"visible",
|
||||||
|
"allnoconfig_y",
|
||||||
|
"prompt",
|
||||||
|
"depends",
|
||||||
|
"bool",
|
||||||
|
"boolean",
|
||||||
|
"mainmenu"
|
||||||
|
};
|
||||||
|
#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__inline
|
||||||
|
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
|
||||||
|
__attribute__ ((__gnu_inline__))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
struct kconf_id *
|
||||||
|
kconf_id_lookup (register const char *str, register unsigned int len)
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TOTAL_KEYWORDS = 35,
|
||||||
|
MIN_WORD_LENGTH = 2,
|
||||||
|
MAX_WORD_LENGTH = 14,
|
||||||
|
MIN_HASH_VALUE = 2,
|
||||||
|
MAX_HASH_VALUE = 48
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct kconf_id wordlist[] =
|
||||||
|
{
|
||||||
|
{-1}, {-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
|
||||||
|
{-1}, {-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_OPTIONAL, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_CHOICE, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND},
|
||||||
|
{-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPT_ENV, TF_OPTION},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_RESET, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
|
||||||
|
{-1}, {-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str30, T_HELP, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX},
|
||||||
|
{-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
|
||||||
|
{-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_VISIBLE, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str38, T_OPT_ALLNOCONFIG_Y,TF_OPTION},
|
||||||
|
{-1}, {-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_PROMPT, TF_COMMAND},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_DEPENDS, TF_COMMAND},
|
||||||
|
{-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44, T_TYPE, TF_COMMAND, S_BOOLEAN},
|
||||||
|
{-1}, {-1},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
|
||||||
|
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||||
|
{
|
||||||
|
register int key = kconf_id_hash (str, len);
|
||||||
|
|
||||||
|
if (key <= MAX_HASH_VALUE && key >= 0)
|
||||||
|
{
|
||||||
|
register int o = wordlist[key].name;
|
||||||
|
if (o >= 0)
|
||||||
|
{
|
||||||
|
register const char *s = o + kconf_id_strings;
|
||||||
|
|
||||||
|
if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
|
||||||
|
return &wordlist[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
%option nostdinit noyywrap never-interactive full ecs
|
||||||
|
%option 8bit nodefault perf-report perf-report
|
||||||
|
%option noinput
|
||||||
|
%x COMMAND HELP STRING PARAM
|
||||||
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
%option nostdinit noyywrap never-interactive full ecs
|
|
||||||
%option 8bit nodefault yylineno
|
|
||||||
%x ASSIGN_VAL HELP STRING
|
|
||||||
%{
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -17,9 +17,6 @@
|
|||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
#include "lkc.h"
|
#include "lkc.h"
|
||||||
#include "parser.tab.h"
|
|
||||||
|
|
||||||
#define YY_DECL static int yylex1(void)
|
|
||||||
|
|
||||||
#define START_STRSIZE 16
|
#define START_STRSIZE 16
|
||||||
|
|
||||||
@ -28,8 +25,6 @@ static struct {
|
|||||||
int lineno;
|
int lineno;
|
||||||
} current_pos;
|
} current_pos;
|
||||||
|
|
||||||
static int prev_prev_token = T_EOL;
|
|
||||||
static int prev_token = T_EOL;
|
|
||||||
static char *text;
|
static char *text;
|
||||||
static int text_size, text_asize;
|
static int text_size, text_asize;
|
||||||
|
|
||||||
@ -42,8 +37,6 @@ struct buffer *current_buf;
|
|||||||
|
|
||||||
static int last_ts, first_ts;
|
static int last_ts, first_ts;
|
||||||
|
|
||||||
static char *expand_token(const char *in, size_t n);
|
|
||||||
static void append_expanded_string(const char *in);
|
|
||||||
static void zconf_endhelp(void);
|
static void zconf_endhelp(void);
|
||||||
static void zconf_endfile(void);
|
static void zconf_endfile(void);
|
||||||
|
|
||||||
@ -61,7 +54,7 @@ static void append_string(const char *str, int size)
|
|||||||
if (new_size > text_asize) {
|
if (new_size > text_asize) {
|
||||||
new_size += START_STRSIZE - 1;
|
new_size += START_STRSIZE - 1;
|
||||||
new_size &= -START_STRSIZE;
|
new_size &= -START_STRSIZE;
|
||||||
text = xrealloc(text, new_size);
|
text = realloc(text, new_size);
|
||||||
text_asize = new_size;
|
text_asize = new_size;
|
||||||
}
|
}
|
||||||
memcpy(text + text_size, str, size);
|
memcpy(text + text_size, str, size);
|
||||||
@ -80,7 +73,7 @@ static void warn_ignored_character(char chr)
|
|||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s:%d:warning: ignoring unsupported character '%c'\n",
|
"%s:%d:warning: ignoring unsupported character '%c'\n",
|
||||||
current_file->name, yylineno, chr);
|
zconf_curname(), zconf_lineno(), chr);
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -90,114 +83,116 @@ n [A-Za-z0-9_-]
|
|||||||
int str = 0;
|
int str = 0;
|
||||||
int ts, i;
|
int ts, i;
|
||||||
|
|
||||||
#.* /* ignore comment */
|
[ \t]*#.*\n |
|
||||||
[ \t]* /* whitespaces */
|
[ \t]*\n {
|
||||||
\\\n /* escaped new line */
|
current_file->lineno++;
|
||||||
\n return T_EOL;
|
return T_EOL;
|
||||||
"allnoconfig_y" return T_ALLNOCONFIG_Y;
|
}
|
||||||
"bool" return T_BOOL;
|
[ \t]*#.*
|
||||||
"choice" return T_CHOICE;
|
|
||||||
"comment" return T_COMMENT;
|
|
||||||
"config" return T_CONFIG;
|
|
||||||
"def_bool" return T_DEF_BOOL;
|
|
||||||
"def_tristate" return T_DEF_TRISTATE;
|
|
||||||
"default" return T_DEFAULT;
|
|
||||||
"defconfig_list" return T_DEFCONFIG_LIST;
|
|
||||||
"depends" return T_DEPENDS;
|
|
||||||
"endchoice" return T_ENDCHOICE;
|
|
||||||
"endif" return T_ENDIF;
|
|
||||||
"endmenu" return T_ENDMENU;
|
|
||||||
"help"|"---help---" return T_HELP;
|
|
||||||
"hex" return T_HEX;
|
|
||||||
"if" return T_IF;
|
|
||||||
"imply" return T_IMPLY;
|
|
||||||
"int" return T_INT;
|
|
||||||
"mainmenu" return T_MAINMENU;
|
|
||||||
"menu" return T_MENU;
|
|
||||||
"menuconfig" return T_MENUCONFIG;
|
|
||||||
"modules" return T_MODULES;
|
|
||||||
"on" return T_ON;
|
|
||||||
"option" return T_OPTION;
|
|
||||||
"optional" return T_OPTIONAL;
|
|
||||||
"prompt" return T_PROMPT;
|
|
||||||
"range" return T_RANGE;
|
|
||||||
"reset" return T_RESET;
|
|
||||||
"select" return T_SELECT;
|
|
||||||
"source" return T_SOURCE;
|
|
||||||
"string" return T_STRING;
|
|
||||||
"tristate" return T_TRISTATE;
|
|
||||||
"visible" return T_VISIBLE;
|
|
||||||
"||" return T_OR;
|
|
||||||
"&&" return T_AND;
|
|
||||||
"=" return T_EQUAL;
|
|
||||||
"!=" return T_UNEQUAL;
|
|
||||||
"<" return T_LESS;
|
|
||||||
"<=" return T_LESS_EQUAL;
|
|
||||||
">" return T_GREATER;
|
|
||||||
">=" return T_GREATER_EQUAL;
|
|
||||||
"!" return T_NOT;
|
|
||||||
"(" return T_OPEN_PAREN;
|
|
||||||
")" return T_CLOSE_PAREN;
|
|
||||||
":=" return T_COLON_EQUAL;
|
|
||||||
"+=" return T_PLUS_EQUAL;
|
|
||||||
\"|\' {
|
|
||||||
str = yytext[0];
|
|
||||||
new_string();
|
|
||||||
BEGIN(STRING);
|
|
||||||
}
|
|
||||||
({n}|[/.])+ {
|
|
||||||
alloc_string(yytext, yyleng);
|
|
||||||
yylval.string = text;
|
|
||||||
return T_WORD;
|
|
||||||
}
|
|
||||||
({n}|[/.$])+ {
|
|
||||||
/* this token includes at least one '$' */
|
|
||||||
yylval.string = expand_token(yytext, yyleng);
|
|
||||||
if (strlen(yylval.string))
|
|
||||||
return T_WORD;
|
|
||||||
free(yylval.string);
|
|
||||||
}
|
|
||||||
. warn_ignored_character(*yytext);
|
|
||||||
|
|
||||||
<ASSIGN_VAL>{
|
|
||||||
[^[:blank:]\n]+.* {
|
[ \t]+ {
|
||||||
|
BEGIN(COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
. {
|
||||||
|
unput(yytext[0]);
|
||||||
|
BEGIN(COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<COMMAND>{
|
||||||
|
{n}+ {
|
||||||
|
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
||||||
|
BEGIN(PARAM);
|
||||||
|
current_pos.file = current_file;
|
||||||
|
current_pos.lineno = current_file->lineno;
|
||||||
|
if (id && id->flags & TF_COMMAND) {
|
||||||
|
zconflval.id = id;
|
||||||
|
return id->token;
|
||||||
|
}
|
||||||
alloc_string(yytext, yyleng);
|
alloc_string(yytext, yyleng);
|
||||||
yylval.string = text;
|
zconflval.string = text;
|
||||||
return T_ASSIGN_VAL;
|
return T_WORD;
|
||||||
|
}
|
||||||
|
. warn_ignored_character(*yytext);
|
||||||
|
\n {
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
current_file->lineno++;
|
||||||
|
return T_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<PARAM>{
|
||||||
|
"&&" return T_AND;
|
||||||
|
"||" return T_OR;
|
||||||
|
"(" return T_OPEN_PAREN;
|
||||||
|
")" return T_CLOSE_PAREN;
|
||||||
|
"!" return T_NOT;
|
||||||
|
"=" return T_EQUAL;
|
||||||
|
"!=" return T_UNEQUAL;
|
||||||
|
"<=" return T_LESS_EQUAL;
|
||||||
|
">=" return T_GREATER_EQUAL;
|
||||||
|
"<" return T_LESS;
|
||||||
|
">" return T_GREATER;
|
||||||
|
\"|\' {
|
||||||
|
str = yytext[0];
|
||||||
|
new_string();
|
||||||
|
BEGIN(STRING);
|
||||||
|
}
|
||||||
|
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
|
||||||
|
({n}|[/.])+ {
|
||||||
|
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
||||||
|
if (id && id->flags & TF_PARAM) {
|
||||||
|
zconflval.id = id;
|
||||||
|
return id->token;
|
||||||
|
}
|
||||||
|
alloc_string(yytext, yyleng);
|
||||||
|
zconflval.string = text;
|
||||||
|
return T_WORD;
|
||||||
|
}
|
||||||
|
#.* /* comment */
|
||||||
|
\\\n current_file->lineno++;
|
||||||
|
[[:blank:]]+
|
||||||
|
. warn_ignored_character(*yytext);
|
||||||
|
<<EOF>> {
|
||||||
|
BEGIN(INITIAL);
|
||||||
}
|
}
|
||||||
\n { BEGIN(INITIAL); return T_EOL; }
|
|
||||||
.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<STRING>{
|
<STRING>{
|
||||||
"$".* append_expanded_string(yytext);
|
[^'"\\\n]+/\n {
|
||||||
[^$'"\\\n]+ {
|
|
||||||
append_string(yytext, yyleng);
|
append_string(yytext, yyleng);
|
||||||
|
zconflval.string = text;
|
||||||
|
return T_WORD_QUOTE;
|
||||||
|
}
|
||||||
|
[^'"\\\n]+ {
|
||||||
|
append_string(yytext, yyleng);
|
||||||
|
}
|
||||||
|
\\.?/\n {
|
||||||
|
append_string(yytext + 1, yyleng - 1);
|
||||||
|
zconflval.string = text;
|
||||||
|
return T_WORD_QUOTE;
|
||||||
}
|
}
|
||||||
\\.? {
|
\\.? {
|
||||||
append_string(yytext + 1, yyleng - 1);
|
append_string(yytext + 1, yyleng - 1);
|
||||||
}
|
}
|
||||||
\'|\" {
|
\'|\" {
|
||||||
if (str == yytext[0]) {
|
if (str == yytext[0]) {
|
||||||
BEGIN(INITIAL);
|
BEGIN(PARAM);
|
||||||
yylval.string = text;
|
zconflval.string = text;
|
||||||
return T_WORD_QUOTE;
|
return T_WORD_QUOTE;
|
||||||
} else
|
} else
|
||||||
append_string(yytext, 1);
|
append_string(yytext, 1);
|
||||||
}
|
}
|
||||||
\n {
|
\n {
|
||||||
fprintf(stderr,
|
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
|
||||||
"%s:%d:warning: multi-line strings not supported\n",
|
current_file->lineno++;
|
||||||
zconf_curname(), zconf_lineno());
|
|
||||||
unput('\n');
|
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
yylval.string = text;
|
return T_EOL;
|
||||||
return T_WORD_QUOTE;
|
|
||||||
}
|
}
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
yylval.string = text;
|
|
||||||
return T_WORD_QUOTE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,10 +220,12 @@ n [A-Za-z0-9_-]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[ \t]*\n/[^ \t\n] {
|
[ \t]*\n/[^ \t\n] {
|
||||||
|
current_file->lineno++;
|
||||||
zconf_endhelp();
|
zconf_endhelp();
|
||||||
return T_HELPTEXT;
|
return T_HELPTEXT;
|
||||||
}
|
}
|
||||||
[ \t]*\n {
|
[ \t]*\n {
|
||||||
|
current_file->lineno++;
|
||||||
append_string("\n", 1);
|
append_string("\n", 1);
|
||||||
}
|
}
|
||||||
[^ \t\n].* {
|
[^ \t\n].* {
|
||||||
@ -248,12 +245,6 @@ n [A-Za-z0-9_-]
|
|||||||
}
|
}
|
||||||
|
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
BEGIN(INITIAL);
|
|
||||||
|
|
||||||
if (prev_token != T_EOL && prev_token != T_HELPTEXT)
|
|
||||||
fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
|
|
||||||
current_file->name, yylineno);
|
|
||||||
|
|
||||||
if (current_file) {
|
if (current_file) {
|
||||||
zconf_endfile();
|
zconf_endfile();
|
||||||
return T_EOL;
|
return T_EOL;
|
||||||
@ -263,93 +254,6 @@ n [A-Za-z0-9_-]
|
|||||||
}
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
/* second stage lexer */
|
|
||||||
int yylex(void)
|
|
||||||
{
|
|
||||||
int token;
|
|
||||||
|
|
||||||
repeat:
|
|
||||||
token = yylex1();
|
|
||||||
|
|
||||||
if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
|
|
||||||
if (token == T_EOL) {
|
|
||||||
/* Do not pass unneeded T_EOL to the parser. */
|
|
||||||
goto repeat;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* For the parser, update file/lineno at the first token
|
|
||||||
* of each statement. Generally, \n is a statement
|
|
||||||
* terminator in Kconfig, but it is not always true
|
|
||||||
* because \n could be escaped by a backslash.
|
|
||||||
*/
|
|
||||||
current_pos.file = current_file;
|
|
||||||
current_pos.lineno = yylineno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_prev_token == T_EOL && prev_token == T_WORD &&
|
|
||||||
(token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
|
|
||||||
BEGIN(ASSIGN_VAL);
|
|
||||||
|
|
||||||
prev_prev_token = prev_token;
|
|
||||||
prev_token = token;
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *expand_token(const char *in, size_t n)
|
|
||||||
{
|
|
||||||
char *out;
|
|
||||||
int c;
|
|
||||||
char c2;
|
|
||||||
const char *rest, *end;
|
|
||||||
|
|
||||||
new_string();
|
|
||||||
append_string(in, n);
|
|
||||||
|
|
||||||
/* get the whole line because we do not know the end of token. */
|
|
||||||
while ((c = input()) != EOF) {
|
|
||||||
if (c == '\n') {
|
|
||||||
unput(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c2 = c;
|
|
||||||
append_string(&c2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rest = text;
|
|
||||||
out = expand_one_token(&rest);
|
|
||||||
|
|
||||||
/* push back unused characters to the input stream */
|
|
||||||
end = rest + strlen(rest);
|
|
||||||
while (end > rest)
|
|
||||||
unput(*--end);
|
|
||||||
|
|
||||||
free(text);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void append_expanded_string(const char *str)
|
|
||||||
{
|
|
||||||
const char *end;
|
|
||||||
char *res;
|
|
||||||
|
|
||||||
str++;
|
|
||||||
|
|
||||||
res = expand_dollar(&str);
|
|
||||||
|
|
||||||
/* push back unused characters to the input stream */
|
|
||||||
end = str + strlen(str);
|
|
||||||
while (end > str)
|
|
||||||
unput(*--end);
|
|
||||||
|
|
||||||
append_string(res, strlen(res));
|
|
||||||
|
|
||||||
free(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
void zconf_starthelp(void)
|
void zconf_starthelp(void)
|
||||||
{
|
{
|
||||||
new_string();
|
new_string();
|
||||||
@ -359,7 +263,7 @@ void zconf_starthelp(void)
|
|||||||
|
|
||||||
static void zconf_endhelp(void)
|
static void zconf_endhelp(void)
|
||||||
{
|
{
|
||||||
yylval.string = text;
|
zconflval.string = text;
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,8 +285,7 @@ FILE *zconf_fopen(const char *name)
|
|||||||
if (!f && name != NULL && name[0] != '/') {
|
if (!f && name != NULL && name[0] != '/') {
|
||||||
env = getenv(SRCTREE);
|
env = getenv(SRCTREE);
|
||||||
if (env) {
|
if (env) {
|
||||||
snprintf(fullname, sizeof(fullname),
|
sprintf(fullname, "%s/%s", env, name);
|
||||||
"%s/%s", env, name);
|
|
||||||
f = fopen(fullname, "r");
|
f = fopen(fullname, "r");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,7 +296,7 @@ void zconf_initscan(const char *name)
|
|||||||
{
|
{
|
||||||
yyin = zconf_fopen(name);
|
yyin = zconf_fopen(name);
|
||||||
if (!yyin) {
|
if (!yyin) {
|
||||||
fprintf(stderr, "can't find file %s\n", name);
|
printf("can't find file %s\n", name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +304,7 @@ void zconf_initscan(const char *name)
|
|||||||
memset(current_buf, 0, sizeof(*current_buf));
|
memset(current_buf, 0, sizeof(*current_buf));
|
||||||
|
|
||||||
current_file = file_lookup(name);
|
current_file = file_lookup(name);
|
||||||
yylineno = 1;
|
current_file->lineno = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __zconf_nextfile(const char *name)
|
static void __zconf_nextfile(const char *name)
|
||||||
@ -414,34 +317,35 @@ static void __zconf_nextfile(const char *name)
|
|||||||
current_buf->state = YY_CURRENT_BUFFER;
|
current_buf->state = YY_CURRENT_BUFFER;
|
||||||
yyin = zconf_fopen(file->name);
|
yyin = zconf_fopen(file->name);
|
||||||
if (!yyin) {
|
if (!yyin) {
|
||||||
fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
|
printf("%s:%d: can't open file \"%s\"\n",
|
||||||
zconf_curname(), zconf_lineno(), file->name);
|
zconf_curname(), zconf_lineno(), file->name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
||||||
buf->parent = current_buf;
|
buf->parent = current_buf;
|
||||||
current_buf = buf;
|
current_buf = buf;
|
||||||
|
|
||||||
current_file->lineno = yylineno;
|
for (iter = current_file->parent; iter; iter = iter->parent ) {
|
||||||
file->parent = current_file;
|
if (!strcmp(current_file->name,iter->name) ) {
|
||||||
|
printf("%s:%d: recursive inclusion detected. "
|
||||||
for (iter = current_file; iter; iter = iter->parent) {
|
"Inclusion path:\n current file : '%s'\n",
|
||||||
if (!strcmp(iter->name, file->name)) {
|
zconf_curname(), zconf_lineno(),
|
||||||
fprintf(stderr,
|
zconf_curname());
|
||||||
"Recursive inclusion detected.\n"
|
iter = current_file->parent;
|
||||||
"Inclusion path:\n"
|
while (iter && \
|
||||||
" current file : %s\n", file->name);
|
strcmp(iter->name,current_file->name)) {
|
||||||
iter = file;
|
printf(" included from: '%s:%d'\n",
|
||||||
do {
|
iter->name, iter->lineno-1);
|
||||||
iter = iter->parent;
|
iter = iter->parent;
|
||||||
fprintf(stderr, " included from: %s:%d\n",
|
}
|
||||||
iter->name, iter->lineno - 1);
|
if (iter)
|
||||||
} while (strcmp(iter->name, file->name));
|
printf(" included from: '%s:%d'\n",
|
||||||
|
iter->name, iter->lineno+1);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file->lineno = 1;
|
||||||
yylineno = 1;
|
file->parent = current_file;
|
||||||
current_file = file;
|
current_file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,8 +405,6 @@ static void zconf_endfile(void)
|
|||||||
struct buffer *parent;
|
struct buffer *parent;
|
||||||
|
|
||||||
current_file = current_file->parent;
|
current_file = current_file->parent;
|
||||||
if (current_file)
|
|
||||||
yylineno = current_file->lineno;
|
|
||||||
|
|
||||||
parent = current_buf->parent;
|
parent = current_buf->parent;
|
||||||
if (parent) {
|
if (parent) {
|
2533
scripts/config/zconf.lex.c_shipped
Normal file
2533
scripts/config/zconf.lex.c_shipped
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
%{
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
||||||
|
* Released under the terms of the GNU GPL v2.0.
|
||||||
*/
|
*/
|
||||||
%{
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -20,70 +20,63 @@
|
|||||||
|
|
||||||
int cdebug = PRINTD;
|
int cdebug = PRINTD;
|
||||||
|
|
||||||
static void yyerror(const char *err);
|
extern int zconflex(void);
|
||||||
static void zconfprint(const char *err, ...);
|
static void zconfprint(const char *err, ...);
|
||||||
static void zconf_error(const char *err, ...);
|
static void zconf_error(const char *err, ...);
|
||||||
static bool zconf_endtoken(const char *tokenname,
|
static void zconferror(const char *err);
|
||||||
const char *expected_tokenname);
|
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
|
||||||
|
|
||||||
struct symbol *symbol_hash[SYMBOL_HASHSIZE];
|
struct symbol *symbol_hash[SYMBOL_HASHSIZE];
|
||||||
|
|
||||||
static struct menu *current_menu, *current_entry;
|
static struct menu *current_menu, *current_entry;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
%expect 30
|
||||||
|
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
char *string;
|
char *string;
|
||||||
|
struct file *file;
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
struct expr *expr;
|
struct expr *expr;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
enum symbol_type type;
|
const struct kconf_id *id;
|
||||||
enum variable_flavor flavor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%token <id>T_MAINMENU
|
||||||
|
%token <id>T_MENU
|
||||||
|
%token <id>T_ENDMENU
|
||||||
|
%token <id>T_SOURCE
|
||||||
|
%token <id>T_CHOICE
|
||||||
|
%token <id>T_ENDCHOICE
|
||||||
|
%token <id>T_COMMENT
|
||||||
|
%token <id>T_CONFIG
|
||||||
|
%token <id>T_MENUCONFIG
|
||||||
|
%token <id>T_HELP
|
||||||
%token <string> T_HELPTEXT
|
%token <string> T_HELPTEXT
|
||||||
|
%token <id>T_IF
|
||||||
|
%token <id>T_ENDIF
|
||||||
|
%token <id>T_DEPENDS
|
||||||
|
%token <id>T_OPTIONAL
|
||||||
|
%token <id>T_PROMPT
|
||||||
|
%token <id>T_TYPE
|
||||||
|
%token <id>T_DEFAULT
|
||||||
|
%token <id>T_SELECT
|
||||||
|
%token <id>T_RANGE
|
||||||
|
%token <id>T_VISIBLE
|
||||||
|
%token <id>T_OPTION
|
||||||
|
%token <id>T_ON
|
||||||
|
%token <id>T_RESET
|
||||||
%token <string> T_WORD
|
%token <string> T_WORD
|
||||||
%token <string> T_WORD_QUOTE
|
%token <string> T_WORD_QUOTE
|
||||||
%token T_ALLNOCONFIG_Y
|
%token T_UNEQUAL
|
||||||
%token T_BOOL
|
%token T_LESS
|
||||||
%token T_CHOICE
|
%token T_LESS_EQUAL
|
||||||
|
%token T_GREATER
|
||||||
|
%token T_GREATER_EQUAL
|
||||||
%token T_CLOSE_PAREN
|
%token T_CLOSE_PAREN
|
||||||
%token T_COLON_EQUAL
|
|
||||||
%token T_COMMENT
|
|
||||||
%token T_CONFIG
|
|
||||||
%token T_DEFAULT
|
|
||||||
%token T_DEFCONFIG_LIST
|
|
||||||
%token T_DEF_BOOL
|
|
||||||
%token T_DEF_TRISTATE
|
|
||||||
%token T_DEPENDS
|
|
||||||
%token T_ENDCHOICE
|
|
||||||
%token T_ENDIF
|
|
||||||
%token T_ENDMENU
|
|
||||||
%token T_HELP
|
|
||||||
%token T_HEX
|
|
||||||
%token T_IF
|
|
||||||
%token T_IMPLY
|
|
||||||
%token T_INT
|
|
||||||
%token T_MAINMENU
|
|
||||||
%token T_MENU
|
|
||||||
%token T_MENUCONFIG
|
|
||||||
%token T_MODULES
|
|
||||||
%token T_ON
|
|
||||||
%token T_OPEN_PAREN
|
%token T_OPEN_PAREN
|
||||||
%token T_OPTION
|
|
||||||
%token T_OPTIONAL
|
|
||||||
%token T_PLUS_EQUAL
|
|
||||||
%token T_PROMPT
|
|
||||||
%token T_RANGE
|
|
||||||
%token T_RESET
|
|
||||||
%token T_SELECT
|
|
||||||
%token T_SOURCE
|
|
||||||
%token T_STRING
|
|
||||||
%token T_TRISTATE
|
|
||||||
%token T_VISIBLE
|
|
||||||
%token T_EOL
|
%token T_EOL
|
||||||
%token <string> T_ASSIGN_VAL
|
|
||||||
|
|
||||||
%left T_OR
|
%left T_OR
|
||||||
%left T_AND
|
%left T_AND
|
||||||
@ -91,15 +84,14 @@ static struct menu *current_menu, *current_entry;
|
|||||||
%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
|
%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
|
||||||
%nonassoc T_NOT
|
%nonassoc T_NOT
|
||||||
|
|
||||||
%type <symbol> nonconst_symbol
|
%type <string> prompt
|
||||||
%type <symbol> symbol
|
%type <symbol> symbol
|
||||||
%type <type> type logic_type default
|
|
||||||
%type <expr> expr
|
%type <expr> expr
|
||||||
%type <expr> if_expr
|
%type <expr> if_expr
|
||||||
%type <string> end
|
%type <id> end
|
||||||
|
%type <id> option_name
|
||||||
%type <menu> if_entry menu_entry choice_entry
|
%type <menu> if_entry menu_entry choice_entry
|
||||||
%type <string> word_opt assign_val
|
%type <string> symbol_option_arg word_opt
|
||||||
%type <flavor> assign_op
|
|
||||||
|
|
||||||
%destructor {
|
%destructor {
|
||||||
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
|
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
|
||||||
@ -108,53 +100,71 @@ static struct menu *current_menu, *current_entry;
|
|||||||
menu_end_menu();
|
menu_end_menu();
|
||||||
} if_entry menu_entry choice_entry
|
} if_entry menu_entry choice_entry
|
||||||
|
|
||||||
|
%{
|
||||||
|
/* Include zconf.hash.c here so it can see the token constants. */
|
||||||
|
#include "zconf.hash.c"
|
||||||
|
%}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
input: mainmenu_stmt stmt_list | stmt_list;
|
input: nl start | start;
|
||||||
|
|
||||||
/* mainmenu entry */
|
start: mainmenu_stmt stmt_list | stmt_list;
|
||||||
|
|
||||||
mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL
|
|
||||||
{
|
|
||||||
menu_add_prompt(P_MENU, $2, NULL);
|
|
||||||
};
|
|
||||||
|
|
||||||
stmt_list:
|
stmt_list:
|
||||||
/* empty */
|
/* empty */
|
||||||
| stmt_list common_stmt
|
| stmt_list common_stmt
|
||||||
| stmt_list choice_stmt
|
| stmt_list choice_stmt
|
||||||
| stmt_list menu_stmt
|
| stmt_list menu_stmt
|
||||||
|
| stmt_list end { zconf_error("unexpected end statement"); }
|
||||||
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
|
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
|
||||||
|
| stmt_list option_name error T_EOL
|
||||||
|
{
|
||||||
|
zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
|
||||||
|
}
|
||||||
| stmt_list error T_EOL { zconf_error("invalid statement"); }
|
| stmt_list error T_EOL { zconf_error("invalid statement"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
option_name:
|
||||||
|
T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE | T_RESET
|
||||||
|
;
|
||||||
|
|
||||||
common_stmt:
|
common_stmt:
|
||||||
if_stmt
|
T_EOL
|
||||||
|
| if_stmt
|
||||||
| comment_stmt
|
| comment_stmt
|
||||||
| config_stmt
|
| config_stmt
|
||||||
| menuconfig_stmt
|
| menuconfig_stmt
|
||||||
| source_stmt
|
| source_stmt
|
||||||
| assignment_stmt
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
option_error:
|
||||||
|
T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
|
||||||
|
| error T_EOL { zconf_error("invalid option"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/* config/menuconfig entry */
|
/* config/menuconfig entry */
|
||||||
|
|
||||||
config_entry_start: T_CONFIG nonconst_symbol T_EOL
|
config_entry_start: T_CONFIG T_WORD T_EOL
|
||||||
{
|
{
|
||||||
$2->flags |= SYMBOL_OPTIONAL;
|
struct symbol *sym = sym_lookup($2, 0);
|
||||||
menu_add_entry($2);
|
sym->flags |= SYMBOL_OPTIONAL;
|
||||||
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
|
menu_add_entry(sym);
|
||||||
|
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
|
||||||
};
|
};
|
||||||
|
|
||||||
config_stmt: config_entry_start config_option_list
|
config_stmt: config_entry_start config_option_list
|
||||||
{
|
{
|
||||||
|
menu_end_entry();
|
||||||
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
|
menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
|
||||||
{
|
{
|
||||||
$2->flags |= SYMBOL_OPTIONAL;
|
struct symbol *sym = sym_lookup($2, 0);
|
||||||
menu_add_entry($2);
|
sym->flags |= SYMBOL_OPTIONAL;
|
||||||
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
|
menu_add_entry(sym);
|
||||||
|
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
|
||||||
};
|
};
|
||||||
|
|
||||||
menuconfig_stmt: menuconfig_entry_start config_option_list
|
menuconfig_stmt: menuconfig_entry_start config_option_list
|
||||||
@ -163,82 +173,84 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
|
|||||||
current_entry->prompt->type = P_MENU;
|
current_entry->prompt->type = P_MENU;
|
||||||
else
|
else
|
||||||
zconfprint("warning: menuconfig statement without prompt");
|
zconfprint("warning: menuconfig statement without prompt");
|
||||||
|
menu_end_entry();
|
||||||
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option_list:
|
config_option_list:
|
||||||
/* empty */
|
/* empty */
|
||||||
| config_option_list config_option
|
| config_option_list config_option
|
||||||
|
| config_option_list symbol_option
|
||||||
| config_option_list depends
|
| config_option_list depends
|
||||||
| config_option_list help
|
| config_option_list help
|
||||||
|
| config_option_list option_error
|
||||||
|
| config_option_list T_EOL
|
||||||
;
|
;
|
||||||
|
|
||||||
config_option: type prompt_stmt_opt T_EOL
|
config_option: T_TYPE prompt_stmt_opt T_EOL
|
||||||
{
|
{
|
||||||
menu_set_type($1);
|
menu_set_type($1->stype);
|
||||||
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
|
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
|
||||||
zconf_curname(), zconf_lineno(),
|
zconf_curname(), zconf_lineno(),
|
||||||
$1);
|
$1->stype);
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
|
config_option: T_PROMPT prompt if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_prompt(P_PROMPT, $2, $3);
|
menu_add_prompt(P_PROMPT, $2, $3);
|
||||||
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option: default expr if_expr T_EOL
|
config_option: T_DEFAULT expr if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_expr(P_DEFAULT, $2, $3);
|
menu_add_expr(P_DEFAULT, $2, $3);
|
||||||
if ($1 != S_UNKNOWN)
|
if ($1->stype != S_UNKNOWN)
|
||||||
menu_set_type($1);
|
menu_set_type($1->stype);
|
||||||
printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
|
printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
|
||||||
zconf_curname(), zconf_lineno(),
|
zconf_curname(), zconf_lineno(),
|
||||||
$1);
|
$1->stype);
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option: T_SELECT nonconst_symbol if_expr T_EOL
|
config_option: T_SELECT T_WORD if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_symbol(P_SELECT, $2, $3);
|
menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
|
||||||
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option: T_IMPLY nonconst_symbol if_expr T_EOL
|
|
||||||
{
|
|
||||||
menu_add_symbol(P_IMPLY, $2, $3);
|
|
||||||
printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
|
|
||||||
};
|
|
||||||
|
|
||||||
config_option: T_RANGE symbol symbol if_expr T_EOL
|
config_option: T_RANGE symbol symbol if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
|
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
|
||||||
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option: T_OPTION T_MODULES T_EOL
|
symbol_option: T_OPTION symbol_option_list T_EOL
|
||||||
|
;
|
||||||
|
|
||||||
|
symbol_option_list:
|
||||||
|
/* empty */
|
||||||
|
| symbol_option_list T_WORD symbol_option_arg
|
||||||
{
|
{
|
||||||
menu_add_option_modules();
|
const struct kconf_id *id = kconf_id_lookup($2, strlen($2));
|
||||||
|
if (id && id->flags & TF_OPTION)
|
||||||
|
menu_add_option(id->token, $3);
|
||||||
|
else
|
||||||
|
zconfprint("warning: ignoring unknown option %s", $2);
|
||||||
|
free($2);
|
||||||
};
|
};
|
||||||
|
|
||||||
config_option: T_OPTION T_DEFCONFIG_LIST T_EOL
|
symbol_option_arg:
|
||||||
{
|
/* empty */ { $$ = NULL; }
|
||||||
menu_add_option_defconfig_list();
|
| T_EQUAL prompt { $$ = $2; }
|
||||||
};
|
;
|
||||||
|
|
||||||
config_option: T_OPTION T_ALLNOCONFIG_Y T_EOL
|
|
||||||
{
|
|
||||||
menu_add_option_allnoconfig_y();
|
|
||||||
};
|
|
||||||
|
|
||||||
/* choice entry */
|
/* choice entry */
|
||||||
|
|
||||||
choice: T_CHOICE word_opt T_EOL
|
choice: T_CHOICE word_opt T_EOL
|
||||||
{
|
{
|
||||||
struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
|
struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
|
||||||
sym->flags |= SYMBOL_NO_WRITE;
|
sym->flags |= SYMBOL_AUTO;
|
||||||
menu_add_entry(sym);
|
menu_add_entry(sym);
|
||||||
menu_add_expr(P_CHOICE, NULL, NULL);
|
menu_add_expr(P_CHOICE, NULL, NULL);
|
||||||
free($2);
|
|
||||||
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -249,7 +261,7 @@ choice_entry: choice choice_option_list
|
|||||||
|
|
||||||
choice_end: end
|
choice_end: end
|
||||||
{
|
{
|
||||||
if (zconf_endtoken($1, "choice")) {
|
if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
|
||||||
menu_end_menu();
|
menu_end_menu();
|
||||||
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
|
||||||
}
|
}
|
||||||
@ -263,19 +275,25 @@ choice_option_list:
|
|||||||
| choice_option_list choice_option
|
| choice_option_list choice_option
|
||||||
| choice_option_list depends
|
| choice_option_list depends
|
||||||
| choice_option_list help
|
| choice_option_list help
|
||||||
|
| choice_option_list T_EOL
|
||||||
|
| choice_option_list option_error
|
||||||
;
|
;
|
||||||
|
|
||||||
choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
|
choice_option: T_PROMPT prompt if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_prompt(P_PROMPT, $2, $3);
|
menu_add_prompt(P_PROMPT, $2, $3);
|
||||||
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
choice_option: logic_type prompt_stmt_opt T_EOL
|
choice_option: T_TYPE prompt_stmt_opt T_EOL
|
||||||
{
|
{
|
||||||
menu_set_type($1);
|
if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
|
||||||
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
|
menu_set_type($1->stype);
|
||||||
zconf_curname(), zconf_lineno(), $1);
|
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
|
||||||
|
zconf_curname(), zconf_lineno(),
|
||||||
|
$1->stype);
|
||||||
|
} else
|
||||||
|
YYERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
choice_option: T_OPTIONAL T_EOL
|
choice_option: T_OPTIONAL T_EOL
|
||||||
@ -286,31 +304,19 @@ choice_option: T_OPTIONAL T_EOL
|
|||||||
|
|
||||||
choice_option: T_RESET if_expr T_EOL
|
choice_option: T_RESET if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_prop(P_RESET, NULL, $2);
|
menu_add_prop(P_RESET, NULL, NULL, $2);
|
||||||
};
|
};
|
||||||
|
|
||||||
choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
|
choice_option: T_DEFAULT T_WORD if_expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_symbol(P_DEFAULT, $2, $3);
|
if ($1->stype == S_UNKNOWN) {
|
||||||
printd(DEBUG_PARSE, "%s:%d:default\n",
|
menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
|
||||||
zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:default\n",
|
||||||
|
zconf_curname(), zconf_lineno());
|
||||||
|
} else
|
||||||
|
YYERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
type:
|
|
||||||
logic_type
|
|
||||||
| T_INT { $$ = S_INT; }
|
|
||||||
| T_HEX { $$ = S_HEX; }
|
|
||||||
| T_STRING { $$ = S_STRING; }
|
|
||||||
|
|
||||||
logic_type:
|
|
||||||
T_BOOL { $$ = S_BOOLEAN; }
|
|
||||||
| T_TRISTATE { $$ = S_TRISTATE; }
|
|
||||||
|
|
||||||
default:
|
|
||||||
T_DEFAULT { $$ = S_UNKNOWN; }
|
|
||||||
| T_DEF_BOOL { $$ = S_BOOLEAN; }
|
|
||||||
| T_DEF_TRISTATE { $$ = S_TRISTATE; }
|
|
||||||
|
|
||||||
choice_block:
|
choice_block:
|
||||||
/* empty */
|
/* empty */
|
||||||
| choice_block common_stmt
|
| choice_block common_stmt
|
||||||
@ -318,7 +324,7 @@ choice_block:
|
|||||||
|
|
||||||
/* if entry */
|
/* if entry */
|
||||||
|
|
||||||
if_entry: T_IF expr T_EOL
|
if_entry: T_IF expr nl
|
||||||
{
|
{
|
||||||
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
|
||||||
menu_add_entry(NULL);
|
menu_add_entry(NULL);
|
||||||
@ -328,69 +334,80 @@ if_entry: T_IF expr T_EOL
|
|||||||
|
|
||||||
if_end: end
|
if_end: end
|
||||||
{
|
{
|
||||||
if (zconf_endtoken($1, "if")) {
|
if (zconf_endtoken($1, T_IF, T_ENDIF)) {
|
||||||
menu_end_menu();
|
menu_end_menu();
|
||||||
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if_stmt: if_entry stmt_list if_end
|
if_stmt: if_entry if_block if_end
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if_block:
|
||||||
|
/* empty */
|
||||||
|
| if_block common_stmt
|
||||||
|
| if_block menu_stmt
|
||||||
|
| if_block choice_stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
/* mainmenu entry */
|
||||||
|
|
||||||
|
mainmenu_stmt: T_MAINMENU prompt nl
|
||||||
|
{
|
||||||
|
menu_add_prompt(P_MENU, $2, NULL);
|
||||||
|
};
|
||||||
|
|
||||||
/* menu entry */
|
/* menu entry */
|
||||||
|
|
||||||
menu: T_MENU T_WORD_QUOTE T_EOL
|
menu: T_MENU prompt T_EOL
|
||||||
{
|
{
|
||||||
menu_add_entry(NULL);
|
menu_add_entry(NULL);
|
||||||
menu_add_prompt(P_MENU, $2, NULL);
|
menu_add_prompt(P_MENU, $2, NULL);
|
||||||
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_entry: menu menu_option_list
|
menu_entry: menu visibility_list depends_list
|
||||||
{
|
{
|
||||||
$$ = menu_add_menu();
|
$$ = menu_add_menu();
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_end: end
|
menu_end: end
|
||||||
{
|
{
|
||||||
if (zconf_endtoken($1, "menu")) {
|
if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
|
||||||
menu_end_menu();
|
menu_end_menu();
|
||||||
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_stmt: menu_entry stmt_list menu_end
|
menu_stmt: menu_entry menu_block menu_end
|
||||||
;
|
;
|
||||||
|
|
||||||
menu_option_list:
|
menu_block:
|
||||||
/* empty */
|
/* empty */
|
||||||
| menu_option_list visible
|
| menu_block common_stmt
|
||||||
| menu_option_list depends
|
| menu_block menu_stmt
|
||||||
|
| menu_block choice_stmt
|
||||||
;
|
;
|
||||||
|
|
||||||
source_stmt: T_SOURCE T_WORD_QUOTE T_EOL
|
source_stmt: T_SOURCE prompt T_EOL
|
||||||
{
|
{
|
||||||
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
|
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
|
||||||
zconf_nextfile($2);
|
zconf_nextfile($2);
|
||||||
free($2);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* comment entry */
|
/* comment entry */
|
||||||
|
|
||||||
comment: T_COMMENT T_WORD_QUOTE T_EOL
|
comment: T_COMMENT prompt T_EOL
|
||||||
{
|
{
|
||||||
menu_add_entry(NULL);
|
menu_add_entry(NULL);
|
||||||
menu_add_prompt(P_COMMENT, $2, NULL);
|
menu_add_prompt(P_COMMENT, $2, NULL);
|
||||||
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
|
||||||
};
|
};
|
||||||
|
|
||||||
comment_stmt: comment comment_option_list
|
comment_stmt: comment depends_list
|
||||||
;
|
{
|
||||||
|
menu_end_entry();
|
||||||
comment_option_list:
|
};
|
||||||
/* empty */
|
|
||||||
| comment_option_list depends
|
|
||||||
;
|
|
||||||
|
|
||||||
/* help option */
|
/* help option */
|
||||||
|
|
||||||
@ -402,24 +419,37 @@ help_start: T_HELP T_EOL
|
|||||||
|
|
||||||
help: help_start T_HELPTEXT
|
help: help_start T_HELPTEXT
|
||||||
{
|
{
|
||||||
/* Is the help text empty or all whitespace? */
|
|
||||||
if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
|
|
||||||
zconfprint("warning: '%s' defined with blank help text",
|
|
||||||
current_entry->sym->name ?: "<choice>");
|
|
||||||
|
|
||||||
current_entry->help = $2;
|
current_entry->help = $2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* depends option */
|
/* depends option */
|
||||||
|
|
||||||
|
depends_list:
|
||||||
|
/* empty */
|
||||||
|
| depends_list depends
|
||||||
|
| depends_list T_EOL
|
||||||
|
| depends_list option_error
|
||||||
|
;
|
||||||
|
|
||||||
depends: T_DEPENDS T_ON expr T_EOL
|
depends: T_DEPENDS T_ON expr T_EOL
|
||||||
{
|
{
|
||||||
menu_add_dep($3);
|
menu_add_dep($3);
|
||||||
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
|
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
|
||||||
|
} | T_DEPENDS expr T_EOL
|
||||||
|
{
|
||||||
|
menu_add_dep($2);
|
||||||
|
zconfprint("warning: deprecated 'depends' syntax, use 'depends on' instead.");
|
||||||
};
|
};
|
||||||
|
|
||||||
/* visibility option */
|
/* visibility option */
|
||||||
visible: T_VISIBLE if_expr T_EOL
|
|
||||||
|
visibility_list:
|
||||||
|
/* empty */
|
||||||
|
| visibility_list visible
|
||||||
|
| visibility_list T_EOL
|
||||||
|
;
|
||||||
|
|
||||||
|
visible: T_VISIBLE if_expr
|
||||||
{
|
{
|
||||||
menu_add_visibility($2);
|
menu_add_visibility($2);
|
||||||
};
|
};
|
||||||
@ -428,14 +458,23 @@ visible: T_VISIBLE if_expr T_EOL
|
|||||||
|
|
||||||
prompt_stmt_opt:
|
prompt_stmt_opt:
|
||||||
/* empty */
|
/* empty */
|
||||||
| T_WORD_QUOTE if_expr
|
| prompt if_expr
|
||||||
{
|
{
|
||||||
menu_add_prompt(P_PROMPT, $1, $2);
|
menu_add_prompt(P_PROMPT, $1, $2);
|
||||||
};
|
};
|
||||||
|
|
||||||
end: T_ENDMENU T_EOL { $$ = "menu"; }
|
prompt: T_WORD
|
||||||
| T_ENDCHOICE T_EOL { $$ = "choice"; }
|
| T_WORD_QUOTE
|
||||||
| T_ENDIF T_EOL { $$ = "if"; }
|
;
|
||||||
|
|
||||||
|
end: T_ENDMENU T_EOL { $$ = $1; }
|
||||||
|
| T_ENDCHOICE T_EOL { $$ = $1; }
|
||||||
|
| T_ENDIF T_EOL { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
nl:
|
||||||
|
T_EOL
|
||||||
|
| nl T_EOL
|
||||||
;
|
;
|
||||||
|
|
||||||
if_expr: /* empty */ { $$ = NULL; }
|
if_expr: /* empty */ { $$ = NULL; }
|
||||||
@ -455,31 +494,13 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
|
|||||||
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
|
| expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* For symbol definitions, selects, etc., where quotes are not accepted */
|
symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
|
||||||
nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); };
|
|
||||||
|
|
||||||
symbol: nonconst_symbol
|
|
||||||
| T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
|
| T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
word_opt: /* empty */ { $$ = NULL; }
|
word_opt: /* empty */ { $$ = NULL; }
|
||||||
| T_WORD
|
| T_WORD
|
||||||
|
|
||||||
/* assignment statement */
|
|
||||||
|
|
||||||
assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); }
|
|
||||||
|
|
||||||
assign_op:
|
|
||||||
T_EQUAL { $$ = VAR_RECURSIVE; }
|
|
||||||
| T_COLON_EQUAL { $$ = VAR_SIMPLE; }
|
|
||||||
| T_PLUS_EQUAL { $$ = VAR_APPEND; }
|
|
||||||
;
|
|
||||||
|
|
||||||
assign_val:
|
|
||||||
/* empty */ { $$ = xstrdup(""); };
|
|
||||||
| T_ASSIGN_VAL
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
void conf_parse(const char *name)
|
void conf_parse(const char *name)
|
||||||
@ -489,53 +510,63 @@ void conf_parse(const char *name)
|
|||||||
|
|
||||||
zconf_initscan(name);
|
zconf_initscan(name);
|
||||||
|
|
||||||
|
sym_init();
|
||||||
_menu_init();
|
_menu_init();
|
||||||
|
rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
|
||||||
|
|
||||||
#if YYDEBUG
|
#if YYDEBUG
|
||||||
if (getenv("ZCONF_DEBUG"))
|
if (getenv("ZCONF_DEBUG"))
|
||||||
yydebug = 1;
|
zconfdebug = 1;
|
||||||
#endif
|
#endif
|
||||||
yyparse();
|
zconfparse();
|
||||||
|
if (zconfnerrs)
|
||||||
/* Variables are expanded in the parse phase. We can free them here. */
|
|
||||||
variable_all_del();
|
|
||||||
|
|
||||||
if (yynerrs)
|
|
||||||
exit(1);
|
exit(1);
|
||||||
if (!modules_sym)
|
if (!modules_sym)
|
||||||
modules_sym = sym_find( "n" );
|
modules_sym = sym_find( "n" );
|
||||||
|
|
||||||
if (!menu_has_prompt(&rootmenu)) {
|
rootmenu.prompt->text = _(rootmenu.prompt->text);
|
||||||
current_entry = &rootmenu;
|
rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
|
||||||
menu_add_prompt(P_MENU, "Main menu", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
menu_finalize(&rootmenu);
|
menu_finalize(&rootmenu);
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
if (sym_check_deps(sym))
|
if (sym_check_deps(sym))
|
||||||
yynerrs++;
|
zconfnerrs++;
|
||||||
}
|
}
|
||||||
if (yynerrs)
|
if (zconfnerrs)
|
||||||
exit(1);
|
exit(1);
|
||||||
sym_set_change_count(1);
|
sym_set_change_count(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zconf_endtoken(const char *tokenname,
|
static const char *zconf_tokenname(int token)
|
||||||
const char *expected_tokenname)
|
|
||||||
{
|
{
|
||||||
if (strcmp(tokenname, expected_tokenname)) {
|
switch (token) {
|
||||||
|
case T_MENU: return "menu";
|
||||||
|
case T_ENDMENU: return "endmenu";
|
||||||
|
case T_CHOICE: return "choice";
|
||||||
|
case T_ENDCHOICE: return "endchoice";
|
||||||
|
case T_IF: return "if";
|
||||||
|
case T_ENDIF: return "endif";
|
||||||
|
case T_DEPENDS: return "depends";
|
||||||
|
case T_VISIBLE: return "visible";
|
||||||
|
}
|
||||||
|
return "<token>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken)
|
||||||
|
{
|
||||||
|
if (id->token != endtoken) {
|
||||||
zconf_error("unexpected '%s' within %s block",
|
zconf_error("unexpected '%s' within %s block",
|
||||||
tokenname, expected_tokenname);
|
kconf_id_strings + id->name, zconf_tokenname(starttoken));
|
||||||
yynerrs++;
|
zconfnerrs++;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (current_menu->file != current_file) {
|
if (current_menu->file != current_file) {
|
||||||
zconf_error("'%s' in different file than '%s'",
|
zconf_error("'%s' in different file than '%s'",
|
||||||
tokenname, expected_tokenname);
|
kconf_id_strings + id->name, zconf_tokenname(starttoken));
|
||||||
fprintf(stderr, "%s:%d: location of the '%s'\n",
|
fprintf(stderr, "%s:%d: location of the '%s'\n",
|
||||||
current_menu->file->name, current_menu->lineno,
|
current_menu->file->name, current_menu->lineno,
|
||||||
expected_tokenname);
|
zconf_tokenname(starttoken));
|
||||||
yynerrs++;
|
zconfnerrs++;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -556,7 +587,7 @@ static void zconf_error(const char *err, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
yynerrs++;
|
zconfnerrs++;
|
||||||
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
|
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
|
||||||
va_start(ap, err);
|
va_start(ap, err);
|
||||||
vfprintf(stderr, err, ap);
|
vfprintf(stderr, err, ap);
|
||||||
@ -564,7 +595,7 @@ static void zconf_error(const char *err, ...)
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void yyerror(const char *err)
|
static void zconferror(const char *err)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
|
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
|
||||||
}
|
}
|
||||||
@ -597,7 +628,7 @@ static void print_symbol(FILE *out, struct menu *menu)
|
|||||||
fprintf(out, "\nconfig %s\n", sym->name);
|
fprintf(out, "\nconfig %s\n", sym->name);
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
fputs(" bool\n", out);
|
fputs(" boolean\n", out);
|
||||||
break;
|
break;
|
||||||
case S_TRISTATE:
|
case S_TRISTATE:
|
||||||
fputs(" tristate\n", out);
|
fputs(" tristate\n", out);
|
||||||
@ -645,11 +676,6 @@ static void print_symbol(FILE *out, struct menu *menu)
|
|||||||
expr_fprint(prop->expr, out);
|
expr_fprint(prop->expr, out);
|
||||||
fputc('\n', out);
|
fputc('\n', out);
|
||||||
break;
|
break;
|
||||||
case P_IMPLY:
|
|
||||||
fputs( " imply ", out);
|
|
||||||
expr_fprint(prop->expr, out);
|
|
||||||
fputc('\n', out);
|
|
||||||
break;
|
|
||||||
case P_RANGE:
|
case P_RANGE:
|
||||||
fputs( " range ", out);
|
fputs( " range ", out);
|
||||||
expr_fprint(prop->expr, out);
|
expr_fprint(prop->expr, out);
|
||||||
@ -660,10 +686,6 @@ static void print_symbol(FILE *out, struct menu *menu)
|
|||||||
print_quoted_string(out, prop->text);
|
print_quoted_string(out, prop->text);
|
||||||
fputc('\n', out);
|
fputc('\n', out);
|
||||||
break;
|
break;
|
||||||
case P_SYMBOL:
|
|
||||||
fputs( " symbol ", out);
|
|
||||||
fprintf(out, "%s\n", prop->menu->sym->name);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
fprintf(out, " unknown prop %d!\n", prop->type);
|
fprintf(out, " unknown prop %d!\n", prop->type);
|
||||||
break;
|
break;
|
||||||
@ -724,4 +746,9 @@ void zconfdump(FILE *out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "zconf.lex.c"
|
||||||
|
#include "util.c"
|
||||||
|
#include "confdata.c"
|
||||||
|
#include "expr.c"
|
||||||
|
#include "symbol.c"
|
||||||
#include "menu.c"
|
#include "menu.c"
|
@ -1,20 +0,0 @@
|
|||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Subject: kernel: add a small xfrm related performance optimization
|
|
||||||
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
---
|
|
||||||
net/netfilter/nf_nat_core.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
--- a/net/netfilter/nf_nat_core.c
|
|
||||||
+++ b/net/netfilter/nf_nat_core.c
|
|
||||||
@@ -90,6 +90,9 @@ int nf_xfrm_me_harder(struct net *net, s
|
|
||||||
struct dst_entry *dst;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
+ if (skb->dev && !dev_net(skb->dev)->xfrm.policy_count[XFRM_POLICY_OUT])
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
err = xfrm_decode_session(skb, &fl, family);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
@ -1,20 +0,0 @@
|
|||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Subject: kernel: add a small xfrm related performance optimization
|
|
||||||
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
---
|
|
||||||
net/netfilter/nf_nat_core.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
--- a/net/netfilter/nf_nat_core.c
|
|
||||||
+++ b/net/netfilter/nf_nat_core.c
|
|
||||||
@@ -110,6 +110,9 @@ int nf_xfrm_me_harder(struct net *net, s
|
|
||||||
struct sock *sk = skb->sk;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
+ if (skb->dev && !dev_net(skb->dev)->xfrm.policy_count[XFRM_POLICY_OUT])
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
err = xfrm_decode_session(skb, &fl, family);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
@ -1,20 +0,0 @@
|
|||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Subject: kernel: add a small xfrm related performance optimization
|
|
||||||
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
---
|
|
||||||
net/netfilter/nf_nat_core.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
--- a/net/netfilter/nf_nat_core.c
|
|
||||||
+++ b/net/netfilter/nf_nat_core.c
|
|
||||||
@@ -155,6 +155,9 @@ int nf_xfrm_me_harder(struct net *net, s
|
|
||||||
struct sock *sk = skb->sk;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
+ if (skb->dev && !dev_net(skb->dev)->xfrm.policy_count[XFRM_POLICY_OUT])
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
err = xfrm_decode_session(skb, &fl, family);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
Loading…
x
Reference in New Issue
Block a user