mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-18 13:26:34 +00:00
build: scripts/config - update to kconfig-v6.6.16
The main goal here is to keep this close to upstream. Changes include: - allow symbols implied by y to become m - make 'imply' obey the direct dependency - allow only 'config', 'comment', and 'if' inside 'choice' - qconf: make search fully work again on split mode - qconf: navigate menus on hyperlinks - remove '---help---' support - qconf: allow to edit "int", "hex", "string" menus in-place - qconf: drop Qt4 support - nconf: fix core dump when searching in empty menu - nconf: stop endless search loops - Create links to main menu items in search - fix segmentation fault in menuconfig search - nconf: Add search jump feature - port qconf to work with Qt6 in addition to Qt5 - fix possible buffer overflow - fix memory leak from range properties Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
This commit is contained in:
parent
ff6df9ac9f
commit
65a3eb28d5
18
scripts/config/.gitignore
vendored
18
scripts/config/.gitignore
vendored
@ -1,16 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
/conf
|
||||
/[gmnq]conf
|
||||
/[gmnq]conf-cfg
|
||||
/[gmnq]conf-bin
|
||||
/[gmnq]conf-cflags
|
||||
/[gmnq]conf-libs
|
||||
/qconf-moc.cc
|
||||
|
||||
# From linux kconfig parent directories
|
||||
.*
|
||||
|
||||
# OpenWrt-generated files
|
||||
#
|
||||
# Added by openwrt
|
||||
#
|
||||
mconf_check
|
||||
|
||||
# Temporary files from older versions. They should be removed after the
|
||||
# end of support for OpenWrt 19.07.
|
||||
zconf.???.c
|
||||
zconf.hash.c
|
||||
# The next line should be removed after 23.05 is EOL
|
||||
*conf-cfg
|
||||
|
279
scripts/config/Kbuild.include
Normal file
279
scripts/config/Kbuild.include
Normal file
@ -0,0 +1,279 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
####
|
||||
# kbuild: Generic definitions
|
||||
|
||||
# Convenient variables
|
||||
comma := ,
|
||||
quote := "
|
||||
squote := '
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
space_escape := _-_SPACE_-_
|
||||
pound := \#
|
||||
define newline
|
||||
|
||||
|
||||
endef
|
||||
|
||||
###
|
||||
# Comparison macros.
|
||||
# Usage: $(call test-lt, $(CONFIG_LLD_VERSION), 150000)
|
||||
#
|
||||
# Use $(intcmp ...) if supported. (Make >= 4.4)
|
||||
# Otherwise, fall back to the 'test' shell command.
|
||||
ifeq ($(intcmp 1,0,,,y),y)
|
||||
test-ge = $(intcmp $(strip $1)0, $(strip $2)0,,y,y)
|
||||
test-gt = $(intcmp $(strip $1)0, $(strip $2)0,,,y)
|
||||
else
|
||||
test-ge = $(shell test $(strip $1)0 -ge $(strip $2)0 && echo y)
|
||||
test-gt = $(shell test $(strip $1)0 -gt $(strip $2)0 && echo y)
|
||||
endif
|
||||
test-le = $(call test-ge, $2, $1)
|
||||
test-lt = $(call test-gt, $2, $1)
|
||||
|
||||
###
|
||||
# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
|
||||
dot-target = $(dir $@).$(notdir $@)
|
||||
|
||||
###
|
||||
# Name of target with a '.tmp_' as filename prefix. foo/bar.o => foo/.tmp_bar.o
|
||||
tmp-target = $(dir $@).tmp_$(notdir $@)
|
||||
|
||||
###
|
||||
# The temporary file to save gcc -MMD generated dependencies must not
|
||||
# contain a comma
|
||||
depfile = $(subst $(comma),_,$(dot-target).d)
|
||||
|
||||
###
|
||||
# filename of target with directory and extension stripped
|
||||
basetarget = $(basename $(notdir $@))
|
||||
|
||||
###
|
||||
# real prerequisites without phony targets
|
||||
real-prereqs = $(filter-out $(PHONY), $^)
|
||||
|
||||
###
|
||||
# Escape single quote for use in echo statements
|
||||
escsq = $(subst $(squote),'\$(squote)',$1)
|
||||
|
||||
###
|
||||
# Quote a string to pass it to C files. foo => '"foo"'
|
||||
stringify = $(squote)$(quote)$1$(quote)$(squote)
|
||||
|
||||
###
|
||||
# The path to Kbuild or Makefile. Kbuild has precedence over Makefile.
|
||||
kbuild-dir = $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
|
||||
kbuild-file = $(or $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Makefile)
|
||||
|
||||
###
|
||||
# Read a file, replacing newlines with spaces
|
||||
#
|
||||
# Make 4.2 or later can read a file by using its builtin function.
|
||||
ifneq ($(filter-out 3.% 4.0 4.1, $(MAKE_VERSION)),)
|
||||
read-file = $(subst $(newline),$(space),$(file < $1))
|
||||
else
|
||||
read-file = $(shell cat $1 2>/dev/null)
|
||||
endif
|
||||
|
||||
###
|
||||
# Easy method for doing a status message
|
||||
kecho := :
|
||||
quiet_kecho := echo
|
||||
silent_kecho := :
|
||||
kecho := $($(quiet)kecho)
|
||||
|
||||
###
|
||||
# filechk is used to check if the content of a generated file is updated.
|
||||
# Sample usage:
|
||||
#
|
||||
# filechk_sample = echo $(KERNELRELEASE)
|
||||
# version.h: FORCE
|
||||
# $(call filechk,sample)
|
||||
#
|
||||
# The rule defined shall write to stdout the content of the new file.
|
||||
# The existing file will be compared with the new one.
|
||||
# - If no file exist it is created
|
||||
# - If the content differ the new file is used
|
||||
# - If they are equal no change, and no timestamp update
|
||||
define filechk
|
||||
$(check-FORCE)
|
||||
$(Q)set -e; \
|
||||
mkdir -p $(dir $@); \
|
||||
trap "rm -f $(tmp-target)" EXIT; \
|
||||
{ $(filechk_$(1)); } > $(tmp-target); \
|
||||
if [ ! -r $@ ] || ! cmp -s $@ $(tmp-target); then \
|
||||
$(kecho) ' UPD $@'; \
|
||||
mv -f $(tmp-target) $@; \
|
||||
fi
|
||||
endef
|
||||
|
||||
###
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(build)=dir
|
||||
build := -f $(srctree)/scripts/Makefile.build obj
|
||||
|
||||
###
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(dtbinst)=dir
|
||||
dtbinst := -f $(srctree)/scripts/Makefile.dtbinst obj
|
||||
|
||||
###
|
||||
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
|
||||
# Usage:
|
||||
# $(Q)$(MAKE) $(clean)=dir
|
||||
clean := -f $(srctree)/scripts/Makefile.clean obj
|
||||
|
||||
# pring log
|
||||
#
|
||||
# If quiet is "silent_", print nothing and sink stdout
|
||||
# If quiet is "quiet_", print short log
|
||||
# If quiet is empty, print short log and whole command
|
||||
silent_log_print = exec >/dev/null;
|
||||
quiet_log_print = $(if $(quiet_cmd_$1), echo ' $(call escsq,$(quiet_cmd_$1)$(why))';)
|
||||
log_print = echo '$(pound) $(call escsq,$(or $(quiet_cmd_$1),cmd_$1 $@)$(why))'; \
|
||||
echo ' $(call escsq,$(cmd_$1))';
|
||||
|
||||
# Delete the target on interruption
|
||||
#
|
||||
# GNU Make automatically deletes the target if it has already been changed by
|
||||
# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make
|
||||
# will delete incomplete targets), and resume it later.
|
||||
#
|
||||
# However, this does not work when the stderr is piped to another program, like
|
||||
# $ make >&2 | tee log
|
||||
# Make dies with SIGPIPE before cleaning the targets.
|
||||
#
|
||||
# To address it, we clean the target in signal traps.
|
||||
#
|
||||
# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM.
|
||||
# So, we cover them, and also SIGPIPE just in case.
|
||||
#
|
||||
# Of course, this is unneeded for phony targets.
|
||||
delete-on-interrupt = \
|
||||
$(if $(filter-out $(PHONY), $@), \
|
||||
$(foreach sig, HUP INT QUIT TERM PIPE, \
|
||||
trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
|
||||
|
||||
# print and execute commands
|
||||
cmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
|
||||
|
||||
###
|
||||
# if_changed - execute command if any prerequisite is newer than
|
||||
# target, or command line has changed
|
||||
# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies
|
||||
# including used config symbols
|
||||
# if_changed_rule - as if_changed but execute rule instead
|
||||
# See Documentation/kbuild/makefiles.rst for more info
|
||||
|
||||
ifneq ($(KBUILD_NOCMDDEP),1)
|
||||
# Check if both commands are the same including their order. Result is empty
|
||||
# string if equal. User may override this check using make KBUILD_NOCMDDEP=1
|
||||
# If the target does not exist, the *.cmd file should not be included so
|
||||
# $(savedcmd_$@) gets empty. Then, target will be built even if $(newer-prereqs)
|
||||
# happens to become empty.
|
||||
cmd-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(savedcmd_$@))), \
|
||||
$(subst $(space),$(space_escape),$(strip $(cmd_$1))))
|
||||
else
|
||||
# We still need to detect missing targets.
|
||||
cmd-check = $(if $(strip $(savedcmd_$@)),,1)
|
||||
endif
|
||||
|
||||
# Replace >$< with >$$< to preserve $ when reloading the .cmd file
|
||||
# (needed for make)
|
||||
# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file
|
||||
# (needed for make)
|
||||
# Replace >'< with >'\''< to be able to enclose the whole string in '...'
|
||||
# (needed for the shell)
|
||||
make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
|
||||
|
||||
# Find any prerequisites that are newer than target or that do not exist.
|
||||
# PHONY targets skipped in both cases.
|
||||
# If there is no prerequisite other than phony targets, $(newer-prereqs) becomes
|
||||
# empty even if the target does not exist. cmd-check saves this corner case.
|
||||
newer-prereqs = $(filter-out $(PHONY),$?)
|
||||
|
||||
# It is a typical mistake to forget the FORCE prerequisite. Check it here so
|
||||
# no more breakage will slip in.
|
||||
check-FORCE = $(if $(filter FORCE, $^),,$(warning FORCE prerequisite is missing))
|
||||
|
||||
if-changed-cond = $(newer-prereqs)$(cmd-check)$(check-FORCE)
|
||||
|
||||
# Execute command if command has changed or prerequisite(s) are updated.
|
||||
if_changed = $(if $(if-changed-cond),$(cmd_and_savecmd),@:)
|
||||
|
||||
cmd_and_savecmd = \
|
||||
$(cmd); \
|
||||
printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd
|
||||
|
||||
# Execute the command and also postprocess generated .d dependencies file.
|
||||
if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:)
|
||||
|
||||
cmd_and_fixdep = \
|
||||
$(cmd); \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
|
||||
rm -f $(depfile)
|
||||
|
||||
# Usage: $(call if_changed_rule,foo)
|
||||
# Will check if $(cmd_foo) or any of the prerequisites changed,
|
||||
# and if so will execute $(rule_foo).
|
||||
if_changed_rule = $(if $(if-changed-cond),$(rule_$(1)),@:)
|
||||
|
||||
###
|
||||
# why - tell why a target got built
|
||||
# enabled by make V=2
|
||||
# Output (listed in the order they are checked):
|
||||
# (1) - due to target is PHONY
|
||||
# (2) - due to target missing
|
||||
# (3) - due to: file1.h file2.h
|
||||
# (4) - due to command line change
|
||||
# (5) - due to missing .cmd file
|
||||
# (6) - due to target not in $(targets)
|
||||
# (1) PHONY targets are always build
|
||||
# (2) No target, so we better build it
|
||||
# (3) Prerequisite is newer than target
|
||||
# (4) The command line stored in the file named dir/.target.cmd
|
||||
# differed from actual command line. This happens when compiler
|
||||
# options changes
|
||||
# (5) No dir/.target.cmd file (used to store command line)
|
||||
# (6) No dir/.target.cmd file and target not listed in $(targets)
|
||||
# This is a good hint that there is a bug in the kbuild file
|
||||
ifneq ($(findstring 2, $(KBUILD_VERBOSE)),)
|
||||
_why = \
|
||||
$(if $(filter $@, $(PHONY)),- due to target is PHONY, \
|
||||
$(if $(wildcard $@), \
|
||||
$(if $(newer-prereqs),- due to: $(newer-prereqs), \
|
||||
$(if $(cmd-check), \
|
||||
$(if $(savedcmd_$@),- due to command line change, \
|
||||
$(if $(filter $@, $(targets)), \
|
||||
- due to missing .cmd file, \
|
||||
- due to $(notdir $@) not in $$(targets) \
|
||||
) \
|
||||
) \
|
||||
) \
|
||||
), \
|
||||
- due to target missing \
|
||||
) \
|
||||
)
|
||||
|
||||
why = $(space)$(strip $(_why))
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
|
||||
# delete partially updated (i.e. corrupted) files on error
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# do not delete intermediate files automatically
|
||||
#
|
||||
# .NOTINTERMEDIATE is more correct, but only available on newer Make versions.
|
||||
# Make 4.4 introduced .NOTINTERMEDIATE, and it appears in .FEATURES, but the
|
||||
# global .NOTINTERMEDIATE does not work. We can use it on Make > 4.4.
|
||||
# Use .SECONDARY for older Make versions, but "newer-prereq" cannot detect
|
||||
# deleted files.
|
||||
ifneq ($(and $(filter notintermediate, $(.FEATURES)),$(filter-out 4.4,$(MAKE_VERSION))),)
|
||||
.NOTINTERMEDIATE:
|
||||
else
|
||||
.SECONDARY:
|
||||
endif
|
@ -5,46 +5,21 @@
|
||||
.PHONY: clean all
|
||||
all: conf mconf
|
||||
clean:
|
||||
rm -f *.o lxdialog/*.o *.moc .*.cmd $(clean-files)
|
||||
rm -f $(clean-files) $(hostprogs)
|
||||
|
||||
# This clean-files definition is here to ensure that temporary files from the
|
||||
# previous version are removed by make config-clean.
|
||||
# It should be emptied after the end of support for OpenWrt 19.07.
|
||||
clean-files := zconf.tab.c zconf.lex.c zconf.hash.c .tmp_qtcheck
|
||||
clean-files := *.o lxdialog/*.o *.moc qconf-moc.cc \
|
||||
*conf-cfg # <- This should be removed after 23.05 is EOL
|
||||
|
||||
# ===========================================================================
|
||||
# Variables needed by the upstream Makefile
|
||||
|
||||
# Avoids displaying 'UPD mconf-cfg' in an otherwise quiet make menuconfig
|
||||
kecho:=true
|
||||
|
||||
export HOSTPKG_CONFIG=pkg-config
|
||||
CONFIG_SHELL:=$(SHELL)
|
||||
srctree:=.
|
||||
src:=.
|
||||
src:=$(CURDIR)
|
||||
obj:=.
|
||||
Q:=$(if $V,,@)
|
||||
cmd = $(cmd_$(1))
|
||||
|
||||
# some definitions taken from ../Kbuild.include
|
||||
dot-target = $(dir $@).$(notdir $@)
|
||||
squote := '
|
||||
escsq = $(subst $(squote),'\$(squote)',$1)
|
||||
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
|
||||
cmd-check = $(if $(strip $(cmd_$@)),,1)
|
||||
make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
|
||||
newer-prereqs = $(filter-out $(PHONY),$?)
|
||||
if_changed = $(if $(newer-prereqs)$(cmd-check), \
|
||||
$(cmd); \
|
||||
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
|
||||
quiet:=$(if $V,,_silent)
|
||||
include Kbuild.include
|
||||
|
||||
### Stripped down upstream Makefile follows:
|
||||
# ===========================================================================
|
||||
@ -64,11 +39,12 @@ conf-objs := conf.o $(common-objs)
|
||||
hostprogs += nconf
|
||||
nconf-objs := nconf.o nconf.gui.o $(common-objs)
|
||||
|
||||
HOSTLDLIBS_nconf = $(shell . $(obj)/nconf-cfg && echo $$libs)
|
||||
HOSTCFLAGS_nconf.o = $(shell . $(obj)/nconf-cfg && echo $$cflags)
|
||||
HOSTCFLAGS_nconf.gui.o = $(shell . $(obj)/nconf-cfg && echo $$cflags)
|
||||
HOSTLDLIBS_nconf = $(call read-file, $(obj)/nconf-libs)
|
||||
HOSTCFLAGS_nconf.o = $(call read-file, $(obj)/nconf-cflags)
|
||||
HOSTCFLAGS_nconf.gui.o = $(call read-file, $(obj)/nconf-cflags)
|
||||
|
||||
$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/nconf-cfg
|
||||
$(obj)/nconf: | $(obj)/nconf-libs
|
||||
$(obj)/nconf.o $(obj)/nconf.gui.o: | $(obj)/nconf-cflags
|
||||
|
||||
# mconf: Used for the menuconfig target based on lxdialog
|
||||
hostprogs += mconf
|
||||
@ -76,45 +52,44 @@ lxdialog := $(addprefix lxdialog/, \
|
||||
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)
|
||||
HOSTLDLIBS_mconf = $(call read-file, $(obj)/mconf-libs)
|
||||
$(foreach f, mconf.o $(lxdialog), \
|
||||
$(eval HOSTCFLAGS_$f = $$(shell . $(obj)/mconf-cfg && echo $$$$cflags)))
|
||||
$(eval HOSTCFLAGS_$f = $$(call read-file, $(obj)/mconf-cflags)))
|
||||
|
||||
$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg
|
||||
$(obj)/mconf: | $(obj)/mconf-libs
|
||||
$(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags
|
||||
|
||||
# qconf: Used for the xconfig target based on Qt
|
||||
hostprogs += qconf
|
||||
qconf-cxxobjs := qconf.o qconf-moc.o
|
||||
qconf-objs := images.o $(common-objs)
|
||||
|
||||
HOSTLDLIBS_qconf = $(shell . $(obj)/qconf-cfg && echo $$libs)
|
||||
HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
|
||||
HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
|
||||
|
||||
$(obj)/qconf.o: $(obj)/qconf-cfg
|
||||
HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs)
|
||||
HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags)
|
||||
HOSTCXXFLAGS_qconf-moc.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags)
|
||||
$(obj)/qconf: | $(obj)/qconf-libs
|
||||
$(obj)/qconf.o $(obj)/qconf-moc.o: | $(obj)/qconf-cflags
|
||||
|
||||
quiet_cmd_moc = MOC $@
|
||||
cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@
|
||||
cmd_moc = $(call read-file, $(obj)/qconf-bin)/moc $< -o $@
|
||||
|
||||
$(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE
|
||||
$(obj)/qconf-moc.cc: $(src)/qconf.h FORCE | $(obj)/qconf-bin
|
||||
$(call if_changed,moc)
|
||||
|
||||
targets += qconf-moc.cc
|
||||
|
||||
# check if necessary packages are available, and configure build flags
|
||||
filechk_conf_cfg = $(CONFIG_SHELL) $<
|
||||
cmd_conf_cfg = $< $(addprefix $(obj)/$*conf-, cflags libs bin); touch $(obj)/$*conf-bin
|
||||
|
||||
$(obj)/%conf-cfg: $(src)/%conf-cfg.sh FORCE
|
||||
$(call filechk,conf_cfg)
|
||||
$(obj)/%conf-cflags $(obj)/%conf-libs $(obj)/%conf-bin: $(src)/%conf-cfg.sh
|
||||
$(call cmd,conf_cfg)
|
||||
|
||||
clean-files += *conf-cfg
|
||||
clean-files += *conf-cflags *conf-libs *conf-bin
|
||||
|
||||
# ===========================================================================
|
||||
# OpenWrt rules and final adjustments that need to be made after reading the
|
||||
# full upstream Makefile
|
||||
|
||||
clean-files += $(targets) $(hostprogs)
|
||||
|
||||
FORCE:
|
||||
|
||||
ifdef BUILD_SHIPPED_FILES
|
||||
@ -130,25 +105,21 @@ clean-files += $(shipped-files)
|
||||
flex -L -o$@ $<
|
||||
endif
|
||||
|
||||
$(foreach f,$(conf-objs) $(filter-out $(common-objs),$(mconf-objs) \
|
||||
$(qconf-objs) \
|
||||
$(nconf-objs)), \
|
||||
$(eval $(obj)/$f: CFLAGS+=$$(HOSTCFLAGS_$f)))
|
||||
define link_rule
|
||||
$(1): LDLIBS+=$$(HOSTLDLIBS_$(1))
|
||||
$(1): $($(1)-objs) $$($(1)-cxxobjs)
|
||||
$(if $($(1)-cxxobjs), $(CXX) $$(LDFLAGS) -o $$@ $$^ $$(LDLIBS))
|
||||
all-objs += $($(1)-objs)
|
||||
all-cxxobjs += $($(1)-cxxobjs)
|
||||
endef
|
||||
|
||||
$(foreach f,$(qconf-cxxobjs), \
|
||||
$(eval $(obj)/$f: CXXFLAGS+=$$(HOSTCXXFLAGS_$f)))
|
||||
all-objs:=
|
||||
all-cxxobjs:=
|
||||
$(foreach f,$(hostprogs),$(eval $(call link_rule,$f)))
|
||||
|
||||
$(obj)/conf: $(addprefix $(obj)/,$(conf-objs))
|
||||
|
||||
# The *conf-cfg file is used (then filtered out) as the first prerequisite to
|
||||
# avoid sourcing it before the script is built, when trying to compute CFLAGS
|
||||
# for the actual first prerequisite. This avoids errors like:
|
||||
# '/bin/sh: ./mconf-cfg: No such file or directory'
|
||||
$(obj)/mconf: mconf-cfg $(addprefix $(obj)/,$(mconf-objs))
|
||||
$(CC) -o $@ $(filter-out mconf-cfg,$^) $(HOSTLDLIBS_mconf)
|
||||
$(foreach f,$(sort $(all-objs)), \
|
||||
$(eval $f: CFLAGS+=$$(HOSTCFLAGS_$f)))
|
||||
|
||||
$(obj)/nconf: nconf-cfg $(addprefix $(obj)/,$(nconf-objs))
|
||||
$(CC) -o $@ $(filter-out nconf-cfg,$^) $(HOSTLDLIBS_nconf)
|
||||
|
||||
$(obj)/qconf: qconf-cfg $(addprefix $(obj)/,$(qconf-cxxobjs) $(qconf-objs))
|
||||
$(CXX) -o $@ $(filter-out qconf-cfg,$^) $(HOSTLDLIBS_qconf)
|
||||
$(foreach f,$(sort $(all-cxxobjs)), \
|
||||
$(eval $f: CXXFLAGS+=$$(HOSTCXXFLAGS_$f)))
|
||||
|
@ -1,6 +1,7 @@
|
||||
These files were taken from the Linux 5.14 Kernel Configuration System and
|
||||
modified for the OpenWrt Buildroot:
|
||||
- Removed nconf, gconf, tests and kernel configuration targets.
|
||||
These files were taken from the Linux Kernel Configuration System v6.6.16,
|
||||
at commit eb3e299184cc4f40d4bd84fda269b3a20ddcff80 (Feb 5, 2024), and modified
|
||||
for the OpenWrt Buildroot:
|
||||
- Removed 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.
|
||||
@ -23,4 +24,4 @@ modified for the OpenWrt Buildroot:
|
||||
BUILD_SHIPPED_FILES defined
|
||||
|
||||
For a full list of changes, see the repository at:
|
||||
https://github.com/cotequeiroz/linux/commits/openwrt-5.14/scripts/kconfig
|
||||
https://github.com/cotequeiroz/linux/commits/openwrt-v6.6.16/scripts/kconfig
|
||||
|
@ -35,6 +35,7 @@ enum input_mode {
|
||||
olddefconfig,
|
||||
yes2modconfig,
|
||||
mod2yesconfig,
|
||||
mod2noconfig,
|
||||
fatalrecursive,
|
||||
};
|
||||
static enum input_mode input_mode = oldaskconfig;
|
||||
@ -164,8 +165,6 @@ enum conf_def_mode {
|
||||
def_default,
|
||||
def_yes,
|
||||
def_mod,
|
||||
def_y2m,
|
||||
def_m2y,
|
||||
def_no,
|
||||
def_random
|
||||
};
|
||||
@ -303,12 +302,10 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
|
||||
return has_changed;
|
||||
}
|
||||
|
||||
static void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
|
||||
static void conf_rewrite_tristates(tristate old_val, tristate new_val)
|
||||
{
|
||||
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 &&
|
||||
@ -555,7 +552,7 @@ static int conf_choice(struct menu *menu)
|
||||
print_help(child);
|
||||
continue;
|
||||
}
|
||||
sym_set_choice_value(sym, child->sym);
|
||||
sym_set_tristate_value(child->sym, yes);
|
||||
for (child = child->list; child; child = child->next) {
|
||||
indent += 2;
|
||||
conf(child);
|
||||
@ -647,19 +644,8 @@ static void check_conf(struct menu *menu)
|
||||
|
||||
switch (input_mode) {
|
||||
case listnewconfig:
|
||||
if (sym->name) {
|
||||
const char *str;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (sym->name)
|
||||
print_symbol_for_listconfig(sym);
|
||||
break;
|
||||
case helpnewconfig:
|
||||
printf("-----\n");
|
||||
@ -697,7 +683,8 @@ static const struct option long_opts[] = {
|
||||
{"olddefconfig", no_argument, &input_mode_opt, olddefconfig},
|
||||
{"yes2modconfig", no_argument, &input_mode_opt, yes2modconfig},
|
||||
{"mod2yesconfig", no_argument, &input_mode_opt, mod2yesconfig},
|
||||
{"fatalrecursive",no_argument, NULL, fatalrecursive},
|
||||
{"mod2noconfig", no_argument, &input_mode_opt, mod2noconfig},
|
||||
{"fatalrecursive",no_argument, &input_mode_opt, fatalrecursive},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
@ -707,8 +694,10 @@ static void conf_usage(const char *progname)
|
||||
printf("\n");
|
||||
printf("Generic options:\n");
|
||||
printf(" -h, --help Print this message and exit.\n");
|
||||
printf(" -r <file> Read <file> as input.\n");
|
||||
printf(" -s, --silent Do not print log.\n");
|
||||
printf(" --fatalrecursive Treat recursive depenendencies as a fatal error\n");
|
||||
printf(" -w <file> Write config to <file>.\n");
|
||||
printf(" --fatalrecursive Treat recursive dependency as error.\n");
|
||||
printf("\n");
|
||||
printf("Mode options:\n");
|
||||
printf(" --listnewconfig List new options\n");
|
||||
@ -727,6 +716,7 @@ static void conf_usage(const char *progname)
|
||||
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");
|
||||
printf(" --mod2noconfig Change answers from mod to no if possible\n");
|
||||
printf(" (If none of the above is given, --oldaskconfig is the default)\n");
|
||||
}
|
||||
|
||||
@ -740,27 +730,23 @@ int main(int ac, char **av)
|
||||
|
||||
tty_stdio = isatty(0) && isatty(1);
|
||||
|
||||
while ((opt = getopt_long(ac, av, "hr:sw:", long_opts, NULL)) != -1) {
|
||||
while ((opt = getopt_long(ac, av, "hr:w:s", long_opts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
conf_usage(progname);
|
||||
exit(1);
|
||||
break;
|
||||
case 's':
|
||||
conf_set_message_callback(NULL);
|
||||
break;
|
||||
case fatalrecursive:
|
||||
recursive_is_error = 1;
|
||||
continue;
|
||||
case 'r':
|
||||
input_file = optarg;
|
||||
break;
|
||||
case 's':
|
||||
conf_set_message_callback(NULL);
|
||||
break;
|
||||
case 'w':
|
||||
output_file = optarg;
|
||||
break;
|
||||
case 0:
|
||||
input_mode = input_mode_opt;
|
||||
switch (input_mode) {
|
||||
switch (input_mode_opt) {
|
||||
case syncconfig:
|
||||
/*
|
||||
* syncconfig is invoked during the build stage.
|
||||
@ -777,9 +763,13 @@ int main(int ac, char **av)
|
||||
case randconfig:
|
||||
set_randconfig_seed();
|
||||
break;
|
||||
case fatalrecursive:
|
||||
recursive_is_error = 1;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
input_mode = input_mode_opt;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -812,6 +802,7 @@ int main(int ac, char **av)
|
||||
case olddefconfig:
|
||||
case yes2modconfig:
|
||||
case mod2yesconfig:
|
||||
case mod2noconfig:
|
||||
case allnoconfig:
|
||||
case allyesconfig:
|
||||
case allmodconfig:
|
||||
@ -858,10 +849,13 @@ int main(int ac, char **av)
|
||||
case savedefconfig:
|
||||
break;
|
||||
case yes2modconfig:
|
||||
conf_rewrite_mod_or_yes(def_y2m);
|
||||
conf_rewrite_tristates(yes, mod);
|
||||
break;
|
||||
case mod2yesconfig:
|
||||
conf_rewrite_mod_or_yes(def_m2y);
|
||||
conf_rewrite_tristates(mod, yes);
|
||||
break;
|
||||
case mod2noconfig:
|
||||
conf_rewrite_tristates(mod, no);
|
||||
break;
|
||||
case oldaskconfig:
|
||||
rootEntry = &rootmenu;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -129,41 +130,22 @@ static size_t depfile_prefix_len;
|
||||
/* touch depfile for symbol 'name' */
|
||||
static int conf_touch_dep(const char *name)
|
||||
{
|
||||
int fd, ret;
|
||||
char *d;
|
||||
int fd;
|
||||
|
||||
/* check overflow: prefix + name + '\0' must fit in buffer. */
|
||||
if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
|
||||
return -1;
|
||||
|
||||
d = depfile_path + depfile_prefix_len;
|
||||
strcpy(d, name);
|
||||
strcpy(depfile_path + depfile_prefix_len, name);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct conf_printer {
|
||||
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
|
||||
void (*print_comment)(FILE *, const char *, void *);
|
||||
};
|
||||
|
||||
static void conf_warning(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
@ -227,6 +209,20 @@ static const char *conf_get_autoconfig_name(void)
|
||||
return name ? name : "include/config/auto.conf";
|
||||
}
|
||||
|
||||
static const char *conf_get_autoheader_name(void)
|
||||
{
|
||||
char *name = getenv("KCONFIG_AUTOHEADER");
|
||||
|
||||
return name ? name : "include/generated/autoconf.h";
|
||||
}
|
||||
|
||||
static const char *conf_get_rustccfg_name(void)
|
||||
{
|
||||
char *name = getenv("KCONFIG_RUSTCCFG");
|
||||
|
||||
return name ? name : "include/generated/rustc_cfg";
|
||||
}
|
||||
|
||||
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
|
||||
{
|
||||
char *p2;
|
||||
@ -255,19 +251,21 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
|
||||
p, sym->name);
|
||||
return 1;
|
||||
case S_STRING:
|
||||
if (*p++ != '"')
|
||||
break;
|
||||
for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
|
||||
if (*p2 == '"') {
|
||||
*p2 = 0;
|
||||
/* No escaping for S_DEF_AUTO (include/config/auto.conf) */
|
||||
if (def != S_DEF_AUTO) {
|
||||
if (*p++ != '"')
|
||||
break;
|
||||
for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
|
||||
if (*p2 == '"') {
|
||||
*p2 = 0;
|
||||
break;
|
||||
}
|
||||
memmove(p2, p2 + 1, strlen(p2));
|
||||
}
|
||||
memmove(p2, p2 + 1, strlen(p2));
|
||||
}
|
||||
if (!p2) {
|
||||
if (def != S_DEF_AUTO)
|
||||
if (!p2) {
|
||||
conf_warning("invalid string found");
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
case S_INT:
|
||||
@ -376,7 +374,11 @@ int conf_read_simple(const char *name, int def)
|
||||
char *p, *p2;
|
||||
struct symbol *sym;
|
||||
int def_flags;
|
||||
const char *warn_unknown;
|
||||
const char *werror;
|
||||
|
||||
warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
|
||||
werror = getenv("KCONFIG_WERROR");
|
||||
if (name) {
|
||||
in = zconf_fopen(name);
|
||||
} else {
|
||||
@ -448,6 +450,10 @@ load:
|
||||
if (def == S_DEF_USER) {
|
||||
sym = sym_find(line + 2 + strlen(CONFIG_));
|
||||
if (!sym) {
|
||||
if (warn_unknown)
|
||||
conf_warning("unknown symbol: %s",
|
||||
line + 2 + strlen(CONFIG_));
|
||||
|
||||
conf_set_changed(true);
|
||||
continue;
|
||||
}
|
||||
@ -479,7 +485,7 @@ load:
|
||||
|
||||
sym = sym_find(line + strlen(CONFIG_));
|
||||
if (!sym) {
|
||||
if (def == S_DEF_AUTO)
|
||||
if (def == S_DEF_AUTO) {
|
||||
/*
|
||||
* Reading from include/config/auto.conf
|
||||
* If CONFIG_FOO previously existed in
|
||||
@ -487,8 +493,13 @@ load:
|
||||
* include/config/FOO must be touched.
|
||||
*/
|
||||
conf_touch_dep(line + strlen(CONFIG_));
|
||||
else
|
||||
} else {
|
||||
if (warn_unknown)
|
||||
conf_warning("unknown symbol: %s",
|
||||
line + strlen(CONFIG_));
|
||||
|
||||
conf_set_changed(true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -524,6 +535,10 @@ load:
|
||||
}
|
||||
free(line);
|
||||
fclose(in);
|
||||
|
||||
if (conf_warnings && werror)
|
||||
exit(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -597,169 +612,226 @@ int conf_read(const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kconfig configuration printer
|
||||
*
|
||||
* This printer is used when generating the resulting configuration after
|
||||
* kconfig invocation and `defconfig' files. Unset symbol might be omitted by
|
||||
* passing a non-NULL argument to the printer.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
|
||||
struct comment_style {
|
||||
const char *decoration;
|
||||
const char *prefix;
|
||||
const char *postfix;
|
||||
};
|
||||
|
||||
static const struct comment_style comment_style_pound = {
|
||||
.decoration = "#",
|
||||
.prefix = "#",
|
||||
.postfix = "#",
|
||||
};
|
||||
|
||||
static const struct comment_style comment_style_c = {
|
||||
.decoration = " *",
|
||||
.prefix = "/*",
|
||||
.postfix = " */",
|
||||
};
|
||||
|
||||
static void conf_write_heading(FILE *fp, const struct comment_style *cs)
|
||||
{
|
||||
if (!cs)
|
||||
return;
|
||||
|
||||
fprintf(fp, "%s\n", cs->prefix);
|
||||
|
||||
fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
|
||||
cs->decoration);
|
||||
|
||||
fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text);
|
||||
|
||||
fprintf(fp, "%s\n", cs->postfix);
|
||||
}
|
||||
|
||||
/* The returned pointer must be freed on the caller side */
|
||||
static char *escape_string_value(const char *in)
|
||||
{
|
||||
const char *p;
|
||||
char *out;
|
||||
size_t len;
|
||||
|
||||
len = strlen(in) + strlen("\"\"") + 1;
|
||||
|
||||
p = in;
|
||||
while (1) {
|
||||
p += strcspn(p, "\"\\");
|
||||
|
||||
if (p[0] == '\0')
|
||||
break;
|
||||
|
||||
len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
out = xmalloc(len);
|
||||
out[0] = '\0';
|
||||
|
||||
strcat(out, "\"");
|
||||
|
||||
p = in;
|
||||
while (1) {
|
||||
len = strcspn(p, "\"\\");
|
||||
strncat(out, p, len);
|
||||
p += len;
|
||||
|
||||
if (p[0] == '\0')
|
||||
break;
|
||||
|
||||
strcat(out, "\\");
|
||||
strncat(out, p++, 1);
|
||||
}
|
||||
|
||||
strcat(out, "\"");
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
|
||||
|
||||
static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
|
||||
bool escape_string)
|
||||
{
|
||||
const char *val;
|
||||
char *escaped = NULL;
|
||||
|
||||
if (sym->type == S_UNKNOWN)
|
||||
return;
|
||||
|
||||
val = sym_get_string_value(sym);
|
||||
|
||||
if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
|
||||
output_n != OUTPUT_N && *val == 'n') {
|
||||
if (output_n == OUTPUT_N_AS_UNSET)
|
||||
fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sym->type == S_STRING && escape_string) {
|
||||
escaped = escape_string_value(val);
|
||||
val = escaped;
|
||||
}
|
||||
|
||||
fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
|
||||
|
||||
free(escaped);
|
||||
}
|
||||
|
||||
static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
|
||||
{
|
||||
__print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
|
||||
}
|
||||
|
||||
static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
|
||||
{
|
||||
__print_symbol(fp, sym, OUTPUT_N_NONE, false);
|
||||
}
|
||||
|
||||
void print_symbol_for_listconfig(struct symbol *sym)
|
||||
{
|
||||
__print_symbol(stdout, sym, OUTPUT_N, true);
|
||||
}
|
||||
|
||||
static void print_symbol_for_c(FILE *fp, struct symbol *sym)
|
||||
{
|
||||
const char *val;
|
||||
const char *sym_suffix = "";
|
||||
const char *val_prefix = "";
|
||||
char *escaped = NULL;
|
||||
|
||||
if (sym->type == S_UNKNOWN)
|
||||
return;
|
||||
|
||||
val = sym_get_string_value(sym);
|
||||
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
if (*value == 'n') {
|
||||
bool skip_unset = (arg != NULL);
|
||||
|
||||
if (!skip_unset)
|
||||
fprintf(fp, "# %s%s is not set\n",
|
||||
CONFIG_, sym->name);
|
||||
switch (*val) {
|
||||
case 'n':
|
||||
return;
|
||||
case 'm':
|
||||
sym_suffix = "_MODULE";
|
||||
/* fall through */
|
||||
default:
|
||||
val = "1";
|
||||
}
|
||||
break;
|
||||
case S_HEX:
|
||||
if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
|
||||
val_prefix = "0x";
|
||||
break;
|
||||
case S_STRING:
|
||||
escaped = escape_string_value(val);
|
||||
val = escaped;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
|
||||
fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix,
|
||||
val_prefix, val);
|
||||
|
||||
free(escaped);
|
||||
}
|
||||
|
||||
static void
|
||||
kconfig_print_comment(FILE *fp, const char *value, void *arg)
|
||||
static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
|
||||
{
|
||||
const char *p = value;
|
||||
size_t l;
|
||||
const char *val;
|
||||
const char *val_prefix = "";
|
||||
char *val_prefixed = NULL;
|
||||
size_t val_prefixed_len;
|
||||
char *escaped = NULL;
|
||||
|
||||
for (;;) {
|
||||
l = strcspn(p, "\n");
|
||||
fprintf(fp, "#");
|
||||
if (l) {
|
||||
fprintf(fp, " ");
|
||||
xfwrite(p, l, 1, fp);
|
||||
p += l;
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
if (*p++ == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sym->type == S_UNKNOWN)
|
||||
return;
|
||||
|
||||
static struct conf_printer kconfig_printer_cb =
|
||||
{
|
||||
.print_symbol = kconfig_print_symbol,
|
||||
.print_comment = kconfig_print_comment,
|
||||
};
|
||||
|
||||
/*
|
||||
* Header printer
|
||||
*
|
||||
* This printer is used when generating the `include/generated/autoconf.h' file.
|
||||
*/
|
||||
static void
|
||||
header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
|
||||
{
|
||||
val = sym_get_string_value(sym);
|
||||
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE: {
|
||||
const char *suffix = "";
|
||||
case S_TRISTATE:
|
||||
/*
|
||||
* We do not care about disabled ones, i.e. no need for
|
||||
* what otherwise are "comments" in other printers.
|
||||
*/
|
||||
if (*val == 'n')
|
||||
return;
|
||||
|
||||
switch (*value) {
|
||||
case 'n':
|
||||
break;
|
||||
case 'm':
|
||||
suffix = "_MODULE";
|
||||
/* fall through */
|
||||
default:
|
||||
fprintf(fp, "#define %s%s%s 1\n",
|
||||
CONFIG_, sym->name, suffix);
|
||||
}
|
||||
/*
|
||||
* To have similar functionality to the C macro `IS_ENABLED()`
|
||||
* we provide an empty `--cfg CONFIG_X` here in both `y`
|
||||
* and `m` cases.
|
||||
*
|
||||
* Then, the common `fprintf()` below will also give us
|
||||
* a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
|
||||
* be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
|
||||
*/
|
||||
fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
|
||||
break;
|
||||
}
|
||||
case S_HEX: {
|
||||
const char *prefix = "";
|
||||
|
||||
if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
|
||||
prefix = "0x";
|
||||
fprintf(fp, "#define %s%s %s%s\n",
|
||||
CONFIG_, sym->name, prefix, value);
|
||||
break;
|
||||
}
|
||||
case S_STRING:
|
||||
case S_INT:
|
||||
fprintf(fp, "#define %s%s %s\n",
|
||||
CONFIG_, sym->name, value);
|
||||
case S_HEX:
|
||||
if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
|
||||
val_prefix = "0x";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
header_print_comment(FILE *fp, const char *value, void *arg)
|
||||
{
|
||||
const char *p = value;
|
||||
size_t l;
|
||||
|
||||
fprintf(fp, "/*\n");
|
||||
for (;;) {
|
||||
l = strcspn(p, "\n");
|
||||
fprintf(fp, " *");
|
||||
if (l) {
|
||||
fprintf(fp, " ");
|
||||
xfwrite(p, l, 1, fp);
|
||||
p += l;
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
if (*p++ == '\0')
|
||||
break;
|
||||
if (strlen(val_prefix) > 0) {
|
||||
val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
|
||||
val_prefixed = xmalloc(val_prefixed_len);
|
||||
snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
|
||||
val = val_prefixed;
|
||||
}
|
||||
fprintf(fp, " */\n");
|
||||
}
|
||||
|
||||
static struct conf_printer header_printer_cb =
|
||||
{
|
||||
.print_symbol = header_print_symbol,
|
||||
.print_comment = header_print_comment,
|
||||
};
|
||||
/* All values get escaped: the `--cfg` option only takes strings */
|
||||
escaped = escape_string_value(val);
|
||||
val = escaped;
|
||||
|
||||
static void conf_write_symbol(FILE *fp, struct symbol *sym,
|
||||
struct conf_printer *printer, void *printer_arg)
|
||||
{
|
||||
const char *str;
|
||||
fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
|
||||
|
||||
switch (sym->type) {
|
||||
case S_UNKNOWN:
|
||||
break;
|
||||
case S_STRING:
|
||||
str = sym_get_string_value(sym);
|
||||
str = sym_escape_string_value(str);
|
||||
printer->print_symbol(fp, sym, str, printer_arg);
|
||||
free((void *)str);
|
||||
break;
|
||||
default:
|
||||
str = sym_get_string_value(sym);
|
||||
printer->print_symbol(fp, sym, str, printer_arg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\n"
|
||||
"Automatically generated file; DO NOT EDIT.\n"
|
||||
"%s\n",
|
||||
rootmenu.prompt->text);
|
||||
|
||||
printer->print_comment(fp, buf, printer_arg);
|
||||
free(escaped);
|
||||
free(val_prefixed);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -818,7 +890,7 @@ int conf_write_defconfig(const char *filename)
|
||||
goto next_menu;
|
||||
}
|
||||
}
|
||||
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
|
||||
print_symbol_for_dotconfig(out, sym);
|
||||
}
|
||||
next_menu:
|
||||
if (menu->list != NULL) {
|
||||
@ -878,7 +950,7 @@ int conf_write(const char *name)
|
||||
if (!out)
|
||||
return 1;
|
||||
|
||||
conf_write_heading(out, &kconfig_printer_cb, NULL);
|
||||
conf_write_heading(out, &comment_style_pound);
|
||||
|
||||
if (!conf_get_changed())
|
||||
sym_clear_all_valid();
|
||||
@ -905,7 +977,7 @@ int conf_write(const char *name)
|
||||
need_newline = false;
|
||||
}
|
||||
sym->flags |= SYMBOL_WRITTEN;
|
||||
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
|
||||
print_symbol_for_dotconfig(out, sym);
|
||||
}
|
||||
|
||||
next:
|
||||
@ -913,19 +985,20 @@ next:
|
||||
menu = menu->list;
|
||||
continue;
|
||||
}
|
||||
if (menu->next)
|
||||
|
||||
end_check:
|
||||
if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
|
||||
menu->prompt->type == P_MENU) {
|
||||
fprintf(out, "# end of %s\n", menu_get_prompt(menu));
|
||||
need_newline = true;
|
||||
}
|
||||
|
||||
if (menu->next) {
|
||||
menu = menu->next;
|
||||
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) {
|
||||
menu = menu->next;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
menu = menu->parent;
|
||||
if (menu)
|
||||
goto end_check;
|
||||
}
|
||||
}
|
||||
fclose(out);
|
||||
@ -955,45 +1028,69 @@ next:
|
||||
}
|
||||
|
||||
/* write a dependency file as used by kbuild to track dependencies */
|
||||
static int conf_write_dep(const char *name)
|
||||
static int conf_write_autoconf_cmd(const char *autoconf_name)
|
||||
{
|
||||
char name[PATH_MAX], tmp[PATH_MAX];
|
||||
struct file *file;
|
||||
FILE *out;
|
||||
int ret;
|
||||
|
||||
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);
|
||||
ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
|
||||
if (ret >= sizeof(name)) /* check truncation */
|
||||
return -1;
|
||||
|
||||
if (make_parent_dir(name))
|
||||
return 1;
|
||||
rename("..config.tmp", name);
|
||||
return -1;
|
||||
|
||||
ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
|
||||
if (ret >= sizeof(tmp)) /* check truncation */
|
||||
return -1;
|
||||
|
||||
out = fopen(tmp, "w");
|
||||
if (!out) {
|
||||
perror("fopen");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(out, "deps_config := \\\n");
|
||||
for (file = file_list; file; file = file->next)
|
||||
fprintf(out, "\t%s \\\n", file->name);
|
||||
|
||||
fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name);
|
||||
|
||||
env_write_dep(out, autoconf_name);
|
||||
|
||||
fprintf(out, "\n$(deps_config): ;\n");
|
||||
|
||||
fflush(out);
|
||||
ret = ferror(out); /* error check for all fprintf() calls */
|
||||
fclose(out);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
if (rename(tmp, name)) {
|
||||
perror("rename");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int conf_touch_deps(void)
|
||||
{
|
||||
const char *name;
|
||||
const char *name, *tmp;
|
||||
struct symbol *sym;
|
||||
int res, i;
|
||||
|
||||
strcpy(depfile_path, "include/config/");
|
||||
depfile_prefix_len = strlen(depfile_path);
|
||||
|
||||
name = conf_get_autoconfig_name();
|
||||
tmp = strrchr(name, '/');
|
||||
depfile_prefix_len = tmp ? tmp - name + 1 : 0;
|
||||
if (depfile_prefix_len + 1 > sizeof(depfile_path))
|
||||
return -1;
|
||||
|
||||
strncpy(depfile_path, name, depfile_prefix_len);
|
||||
depfile_path[depfile_prefix_len] = 0;
|
||||
|
||||
conf_read_simple(name, S_DEF_AUTO);
|
||||
sym_calc_value(modules_sym);
|
||||
|
||||
@ -1056,13 +1153,54 @@ static int conf_touch_deps(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __conf_write_autoconf(const char *filename,
|
||||
void (*print_symbol)(FILE *, struct symbol *),
|
||||
const struct comment_style *comment_style)
|
||||
{
|
||||
char tmp[PATH_MAX];
|
||||
FILE *file;
|
||||
struct symbol *sym;
|
||||
int ret, i;
|
||||
|
||||
if (make_parent_dir(filename))
|
||||
return -1;
|
||||
|
||||
ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
|
||||
if (ret >= sizeof(tmp)) /* check truncation */
|
||||
return -1;
|
||||
|
||||
file = fopen(tmp, "w");
|
||||
if (!file) {
|
||||
perror("fopen");
|
||||
return -1;
|
||||
}
|
||||
|
||||
conf_write_heading(file, comment_style);
|
||||
|
||||
for_all_symbols(i, sym)
|
||||
if ((sym->flags & SYMBOL_WRITE) && sym->name)
|
||||
print_symbol(file, sym);
|
||||
|
||||
fflush(file);
|
||||
/* check possible errors in conf_write_heading() and print_symbol() */
|
||||
ret = ferror(file);
|
||||
fclose(file);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
if (rename(tmp, filename)) {
|
||||
perror("rename");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conf_write_autoconf(int overwrite)
|
||||
{
|
||||
struct symbol *sym;
|
||||
const char *name;
|
||||
const char *autoconf_name = conf_get_autoconfig_name();
|
||||
FILE *out, *out_h;
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
#ifndef OPENWRT_DOES_NOT_WANT_THIS
|
||||
return 0;
|
||||
@ -1070,52 +1208,38 @@ int conf_write_autoconf(int overwrite)
|
||||
if (!overwrite && is_present(autoconf_name))
|
||||
return 0;
|
||||
|
||||
conf_write_dep("include/config/auto.conf.cmd");
|
||||
ret = conf_write_autoconf_cmd(autoconf_name);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
if (conf_touch_deps())
|
||||
return 1;
|
||||
|
||||
out = fopen(".tmpconfig", "w");
|
||||
if (!out)
|
||||
return 1;
|
||||
|
||||
out_h = fopen(".tmpconfig.h", "w");
|
||||
if (!out_h) {
|
||||
fclose(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
conf_write_heading(out, &kconfig_printer_cb, NULL);
|
||||
conf_write_heading(out_h, &header_printer_cb, NULL);
|
||||
|
||||
for_all_symbols(i, sym) {
|
||||
for_all_symbols(i, sym)
|
||||
sym_calc_value(sym);
|
||||
if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
|
||||
continue;
|
||||
|
||||
/* write symbols to auto.conf and autoconf.h */
|
||||
conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
|
||||
conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
|
||||
}
|
||||
fclose(out);
|
||||
fclose(out_h);
|
||||
ret = __conf_write_autoconf(conf_get_autoheader_name(),
|
||||
print_symbol_for_c,
|
||||
&comment_style_c);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
name = getenv("KCONFIG_AUTOHEADER");
|
||||
if (!name)
|
||||
name = "include/generated/autoconf.h";
|
||||
if (make_parent_dir(name))
|
||||
return 1;
|
||||
if (rename(".tmpconfig.h", name))
|
||||
return 1;
|
||||
ret = __conf_write_autoconf(conf_get_rustccfg_name(),
|
||||
print_symbol_for_rustccfg,
|
||||
NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (make_parent_dir(autoconf_name))
|
||||
return 1;
|
||||
/*
|
||||
* This must be the last step, kbuild has a dependency on auto.conf
|
||||
* and this marks the successful completion of the previous steps.
|
||||
* Create include/config/auto.conf. This must be the last step because
|
||||
* Kbuild has a dependency on auto.conf and this marks the successful
|
||||
* completion of the previous steps.
|
||||
*/
|
||||
if (rename(".tmpconfig", autoconf_name))
|
||||
return 1;
|
||||
ret = __conf_write_autoconf(conf_get_autoconfig_name(),
|
||||
print_symbol_for_autoconf,
|
||||
&comment_style_pound);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1125,10 +1249,12 @@ static void (*conf_changed_callback)(void);
|
||||
|
||||
void conf_set_changed(bool val)
|
||||
{
|
||||
if (conf_changed_callback && conf_changed != val)
|
||||
conf_changed_callback();
|
||||
bool changed = conf_changed != val;
|
||||
|
||||
conf_changed = val;
|
||||
|
||||
if (conf_changed_callback && changed)
|
||||
conf_changed_callback();
|
||||
}
|
||||
|
||||
bool conf_get_changed(void)
|
||||
|
@ -276,7 +276,6 @@ struct jump_key {
|
||||
struct list_head entries;
|
||||
size_t offset;
|
||||
struct menu *target;
|
||||
int index;
|
||||
};
|
||||
|
||||
extern struct file *file_list;
|
||||
|
@ -86,8 +86,7 @@ static void warn_ignored_character(char chr)
|
||||
n [A-Za-z0-9_-]
|
||||
|
||||
%%
|
||||
int str = 0;
|
||||
int ts, i;
|
||||
char open_quote = 0;
|
||||
|
||||
#.* /* ignore comment */
|
||||
[ \t]* /* whitespaces */
|
||||
@ -137,7 +136,7 @@ n [A-Za-z0-9_-]
|
||||
":=" return T_COLON_EQUAL;
|
||||
"+=" return T_PLUS_EQUAL;
|
||||
\"|\' {
|
||||
str = yytext[0];
|
||||
open_quote = yytext[0];
|
||||
new_string();
|
||||
BEGIN(STRING);
|
||||
}
|
||||
@ -174,7 +173,7 @@ n [A-Za-z0-9_-]
|
||||
append_string(yytext + 1, yyleng - 1);
|
||||
}
|
||||
\'|\" {
|
||||
if (str == yytext[0]) {
|
||||
if (open_quote == yytext[0]) {
|
||||
BEGIN(INITIAL);
|
||||
yylval.string = text;
|
||||
return T_WORD_QUOTE;
|
||||
@ -199,6 +198,8 @@ n [A-Za-z0-9_-]
|
||||
|
||||
<HELP>{
|
||||
[ \t]+ {
|
||||
int ts, i;
|
||||
|
||||
ts = 0;
|
||||
for (i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\t')
|
||||
|
@ -14,6 +14,7 @@
|
||||
/* First, we deal with platform-specific or compiler-specific issues. */
|
||||
|
||||
/* begin standard C headers. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@ -30,8 +31,8 @@
|
||||
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
/* C++ systems might need __STDC_LIMIT_MACROS defined before including
|
||||
* <stdint.h>, if you want the limit (max/min) macros for int types.
|
||||
*/
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
@ -2538,8 +2539,7 @@ YY_DECL
|
||||
|
||||
{
|
||||
|
||||
int str = 0;
|
||||
int ts, i;
|
||||
char open_quote = 0;
|
||||
|
||||
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
|
||||
{
|
||||
@ -2772,7 +2772,7 @@ return T_PLUS_EQUAL;
|
||||
case 48:
|
||||
YY_RULE_SETUP
|
||||
{
|
||||
str = yytext[0];
|
||||
open_quote = yytext[0];
|
||||
new_string();
|
||||
BEGIN(STRING);
|
||||
}
|
||||
@ -2837,7 +2837,7 @@ YY_RULE_SETUP
|
||||
case 58:
|
||||
YY_RULE_SETUP
|
||||
{
|
||||
if (str == yytext[0]) {
|
||||
if (open_quote == yytext[0]) {
|
||||
BEGIN(INITIAL);
|
||||
yylval.string = text;
|
||||
return T_WORD_QUOTE;
|
||||
@ -2869,6 +2869,8 @@ case YY_STATE_EOF(STRING):
|
||||
case 60:
|
||||
YY_RULE_SETUP
|
||||
{
|
||||
int ts, i;
|
||||
|
||||
ts = 0;
|
||||
for (i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\t')
|
||||
|
@ -77,7 +77,7 @@ struct gstr str_new(void);
|
||||
void str_free(struct gstr *gs);
|
||||
void str_append(struct gstr *gs, const char *s);
|
||||
void str_printf(struct gstr *gs, const char *fmt, ...);
|
||||
const char *str_get(struct gstr *gs);
|
||||
char *str_get(struct gstr *gs);
|
||||
|
||||
/* menu.c */
|
||||
void _menu_init(void);
|
||||
@ -100,10 +100,10 @@ bool menu_is_empty(struct menu *menu);
|
||||
bool menu_is_visible(struct menu *menu);
|
||||
bool menu_has_prompt(struct menu *menu);
|
||||
const char *menu_get_prompt(struct menu *menu);
|
||||
struct menu *menu_get_root_menu(struct menu *menu);
|
||||
struct menu *menu_get_parent_menu(struct menu *menu);
|
||||
bool menu_has_help(struct menu *menu);
|
||||
const char *menu_get_help(struct menu *menu);
|
||||
int get_jump_key_char(void);
|
||||
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
|
||||
void menu_get_ext_help(struct menu *menu, struct gstr *help);
|
||||
|
||||
@ -126,11 +126,6 @@ static inline struct symbol *sym_get_choice_value(struct symbol *sym)
|
||||
return (struct symbol *)sym->curr.val;
|
||||
}
|
||||
|
||||
static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
|
||||
{
|
||||
return sym_set_tristate_value(chval, yes);
|
||||
}
|
||||
|
||||
static inline bool sym_is_choice(struct symbol *sym)
|
||||
{
|
||||
return sym->flags & SYMBOL_CHOICE ? true : false;
|
||||
|
@ -19,7 +19,7 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
|
||||
|
||||
struct symbol * sym_lookup(const char *name, int flags);
|
||||
struct symbol * sym_find(const char *name);
|
||||
const char * sym_escape_string_value(const char *in);
|
||||
void print_symbol_for_listconfig(struct symbol *sym);
|
||||
struct symbol ** sym_re_search(const char *pattern);
|
||||
const char * sym_type_name(enum symbol_type type);
|
||||
void sym_calc_value(struct symbol *sym);
|
||||
|
@ -18,22 +18,6 @@
|
||||
#endif
|
||||
#include <ncurses.h>
|
||||
|
||||
/*
|
||||
* Colors in ncurses 1.9.9e do not work properly since foreground and
|
||||
* background colors are OR'd rather than separately masked. This version
|
||||
* of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
|
||||
* with standard curses. The simplest fix (to make this work with standard
|
||||
* curses) uses the wbkgdset() function, not used in the original hack.
|
||||
* Turn it off if we're building with 1.9.9e, since it just confuses things.
|
||||
*/
|
||||
#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
|
||||
#define OLD_NCURSES 1
|
||||
#undef wbkgdset
|
||||
#define wbkgdset(w,p) /*nothing */
|
||||
#else
|
||||
#define OLD_NCURSES 0
|
||||
#endif
|
||||
|
||||
#define TR(params) _tracef params
|
||||
|
||||
#define KEY_ESC 27
|
||||
@ -212,27 +196,12 @@ int first_alpha(const char *string, const char *exempt);
|
||||
int dialog_yesno(const char *title, const char *prompt, int height, int width);
|
||||
int dialog_msgbox(const char *title, const char *prompt, int height,
|
||||
int width, int pause);
|
||||
|
||||
|
||||
typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void
|
||||
*_data);
|
||||
int dialog_textbox(const char *title, char *tbuf, int initial_height,
|
||||
int initial_width, int *keys, int *_vscroll, int *_hscroll,
|
||||
update_text_fn update_text, void *data);
|
||||
int dialog_textbox(const char *title, const char *tbuf, int initial_height,
|
||||
int initial_width, int *_vscroll, int *_hscroll,
|
||||
int (*extra_key_cb)(int, size_t, size_t, void *), void *data);
|
||||
int dialog_menu(const char *title, const char *prompt,
|
||||
const void *selected, int *s_scroll);
|
||||
int dialog_checklist(const char *title, const char *prompt, int height,
|
||||
int width, int list_height);
|
||||
int dialog_inputbox(const char *title, const char *prompt, int height,
|
||||
int width, const char *init);
|
||||
|
||||
/*
|
||||
* This is the base for fictitious keys, which activate
|
||||
* the buttons.
|
||||
*
|
||||
* Mouse-generated keys are the following:
|
||||
* -- the first 32 are used as numbers, in addition to '0'-'9'
|
||||
* -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
|
||||
* -- uppercase chars are used to invoke the button (M_EVENT + 'O')
|
||||
*/
|
||||
#define M_EVENT (KEY_MAX+1)
|
||||
|
@ -63,15 +63,7 @@ static void do_print_item(WINDOW * win, const char *item, int line_y,
|
||||
/* Clear 'residue' of last item */
|
||||
wattrset(win, dlg.menubox.atr);
|
||||
wmove(win, line_y, 0);
|
||||
#if OLD_NCURSES
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < menu_width; i++)
|
||||
waddch(win, ' ');
|
||||
}
|
||||
#else
|
||||
wclrtoeol(win);
|
||||
#endif
|
||||
wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
|
||||
mvwaddstr(win, line_y, item_x, menu_item);
|
||||
if (hotkey) {
|
||||
|
@ -8,41 +8,149 @@
|
||||
|
||||
#include "dialog.h"
|
||||
|
||||
static void back_lines(int n);
|
||||
static void print_page(WINDOW *win, int height, int width, update_text_fn
|
||||
update_text, void *data);
|
||||
static void print_line(WINDOW *win, int row, int width);
|
||||
static char *get_line(void);
|
||||
static void print_position(WINDOW * win);
|
||||
|
||||
static int hscroll;
|
||||
static int begin_reached, end_reached, page_length;
|
||||
static char *buf;
|
||||
static char *page;
|
||||
static const char *buf, *page;
|
||||
static size_t start, end;
|
||||
|
||||
/*
|
||||
* Go back 'n' lines in text. Called by dialog_textbox().
|
||||
* 'page' will be updated to point to the desired line in 'buf'.
|
||||
*/
|
||||
static void back_lines(int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
begin_reached = 0;
|
||||
/* Go back 'n' lines */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (*page == '\0') {
|
||||
if (end_reached) {
|
||||
end_reached = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (page == buf) {
|
||||
begin_reached = 1;
|
||||
return;
|
||||
}
|
||||
page--;
|
||||
do {
|
||||
if (page == buf) {
|
||||
begin_reached = 1;
|
||||
return;
|
||||
}
|
||||
page--;
|
||||
} while (*page != '\n');
|
||||
page++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return current line of text. Called by dialog_textbox() and print_line().
|
||||
* 'page' should point to start of current line before calling, and will be
|
||||
* updated to point to start of next line.
|
||||
*/
|
||||
static char *get_line(void)
|
||||
{
|
||||
int i = 0;
|
||||
static char line[MAX_LEN + 1];
|
||||
|
||||
end_reached = 0;
|
||||
while (*page != '\n') {
|
||||
if (*page == '\0') {
|
||||
end_reached = 1;
|
||||
break;
|
||||
} else if (i < MAX_LEN)
|
||||
line[i++] = *(page++);
|
||||
else {
|
||||
/* Truncate lines longer than MAX_LEN characters */
|
||||
if (i == MAX_LEN)
|
||||
line[i++] = '\0';
|
||||
page++;
|
||||
}
|
||||
}
|
||||
if (i <= MAX_LEN)
|
||||
line[i] = '\0';
|
||||
if (!end_reached)
|
||||
page++; /* move past '\n' */
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a new line of text.
|
||||
*/
|
||||
static void print_line(WINDOW *win, int row, int width)
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = get_line();
|
||||
line += MIN(strlen(line), hscroll); /* Scroll horizontally */
|
||||
wmove(win, row, 0); /* move cursor to correct line */
|
||||
waddch(win, ' ');
|
||||
waddnstr(win, line, MIN(strlen(line), width - 2));
|
||||
|
||||
/* Clear 'residue' of previous line */
|
||||
wclrtoeol(win);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a new page of text.
|
||||
*/
|
||||
static void print_page(WINDOW *win, int height, int width)
|
||||
{
|
||||
int i, passed_end = 0;
|
||||
|
||||
page_length = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
print_line(win, i, width);
|
||||
if (!passed_end)
|
||||
page_length++;
|
||||
if (end_reached && !passed_end)
|
||||
passed_end = 1;
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print current position
|
||||
*/
|
||||
static void print_position(WINDOW *win)
|
||||
{
|
||||
int percent;
|
||||
|
||||
wattrset(win, dlg.position_indicator.atr);
|
||||
wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
|
||||
percent = (page - buf) * 100 / strlen(buf);
|
||||
wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
|
||||
wprintw(win, "(%3d%%)", percent);
|
||||
}
|
||||
|
||||
/*
|
||||
* refresh window content
|
||||
*/
|
||||
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
|
||||
int cur_y, int cur_x, update_text_fn update_text,
|
||||
void *data)
|
||||
int cur_y, int cur_x)
|
||||
{
|
||||
print_page(box, boxh, boxw, update_text, data);
|
||||
start = page - buf;
|
||||
|
||||
print_page(box, boxh, boxw);
|
||||
print_position(dialog);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
|
||||
end = page - buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display text from a file in a dialog box.
|
||||
*
|
||||
* keys is a null-terminated array
|
||||
* update_text() may not add or remove any '\n' or '\0' in tbuf
|
||||
*/
|
||||
int dialog_textbox(const char *title, char *tbuf, int initial_height,
|
||||
int initial_width, int *keys, int *_vscroll, int *_hscroll,
|
||||
update_text_fn update_text, void *data)
|
||||
int dialog_textbox(const char *title, const char *tbuf, int initial_height,
|
||||
int initial_width, int *_vscroll, int *_hscroll,
|
||||
int (*extra_key_cb)(int, size_t, size_t, void *), void *data)
|
||||
{
|
||||
int i, x, y, cur_x, cur_y, key = 0;
|
||||
int height, width, boxh, boxw;
|
||||
@ -122,8 +230,7 @@ do_resize:
|
||||
|
||||
/* Print first page of text */
|
||||
attr_clear(box, boxh, boxw, dlg.dialog.atr);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
|
||||
data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
|
||||
while (!done) {
|
||||
key = wgetch(dialog);
|
||||
@ -142,8 +249,7 @@ do_resize:
|
||||
begin_reached = 1;
|
||||
page = buf;
|
||||
refresh_text_box(dialog, box, boxh, boxw,
|
||||
cur_y, cur_x, update_text,
|
||||
data);
|
||||
cur_y, cur_x);
|
||||
}
|
||||
break;
|
||||
case 'G': /* Last page */
|
||||
@ -153,8 +259,7 @@ do_resize:
|
||||
/* point to last char in buf */
|
||||
page = buf + strlen(buf);
|
||||
back_lines(boxh);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case 'K': /* Previous line */
|
||||
case 'k':
|
||||
@ -163,8 +268,7 @@ do_resize:
|
||||
break;
|
||||
|
||||
back_lines(page_length + 1);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case 'B': /* Previous page */
|
||||
case 'b':
|
||||
@ -173,8 +277,7 @@ do_resize:
|
||||
if (begin_reached)
|
||||
break;
|
||||
back_lines(page_length + boxh);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case 'J': /* Next line */
|
||||
case 'j':
|
||||
@ -183,8 +286,7 @@ do_resize:
|
||||
break;
|
||||
|
||||
back_lines(page_length - 1);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case KEY_NPAGE: /* Next page */
|
||||
case ' ':
|
||||
@ -193,8 +295,7 @@ do_resize:
|
||||
break;
|
||||
|
||||
begin_reached = 0;
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case '0': /* Beginning of line */
|
||||
case 'H': /* Scroll left */
|
||||
@ -209,8 +310,7 @@ do_resize:
|
||||
hscroll--;
|
||||
/* Reprint current page to scroll horizontally */
|
||||
back_lines(page_length);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case 'L': /* Scroll right */
|
||||
case 'l':
|
||||
@ -220,8 +320,7 @@ do_resize:
|
||||
hscroll++;
|
||||
/* Reprint current page to scroll horizontally */
|
||||
back_lines(page_length);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y,
|
||||
cur_x, update_text, data);
|
||||
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
|
||||
break;
|
||||
case KEY_ESC:
|
||||
if (on_key_esc(dialog) == KEY_ESC)
|
||||
@ -234,11 +333,9 @@ do_resize:
|
||||
on_key_resize();
|
||||
goto do_resize;
|
||||
default:
|
||||
for (i = 0; keys[i]; i++) {
|
||||
if (key == keys[i]) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
if (extra_key_cb && extra_key_cb(key, start, end, data)) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,137 +356,3 @@ do_resize:
|
||||
*_hscroll = hscroll;
|
||||
return key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go back 'n' lines in text. Called by dialog_textbox().
|
||||
* 'page' will be updated to point to the desired line in 'buf'.
|
||||
*/
|
||||
static void back_lines(int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
begin_reached = 0;
|
||||
/* Go back 'n' lines */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (*page == '\0') {
|
||||
if (end_reached) {
|
||||
end_reached = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (page == buf) {
|
||||
begin_reached = 1;
|
||||
return;
|
||||
}
|
||||
page--;
|
||||
do {
|
||||
if (page == buf) {
|
||||
begin_reached = 1;
|
||||
return;
|
||||
}
|
||||
page--;
|
||||
} while (*page != '\n');
|
||||
page++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a new page of text.
|
||||
*/
|
||||
static void print_page(WINDOW *win, int height, int width, update_text_fn
|
||||
update_text, void *data)
|
||||
{
|
||||
int i, passed_end = 0;
|
||||
|
||||
if (update_text) {
|
||||
char *end;
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
get_line();
|
||||
end = page;
|
||||
back_lines(height);
|
||||
update_text(buf, page - buf, end - buf, data);
|
||||
}
|
||||
|
||||
page_length = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
print_line(win, i, width);
|
||||
if (!passed_end)
|
||||
page_length++;
|
||||
if (end_reached && !passed_end)
|
||||
passed_end = 1;
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a new line of text.
|
||||
*/
|
||||
static void print_line(WINDOW * win, int row, int width)
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = get_line();
|
||||
line += MIN(strlen(line), hscroll); /* Scroll horizontally */
|
||||
wmove(win, row, 0); /* move cursor to correct line */
|
||||
waddch(win, ' ');
|
||||
waddnstr(win, line, MIN(strlen(line), width - 2));
|
||||
|
||||
/* Clear 'residue' of previous line */
|
||||
#if OLD_NCURSES
|
||||
{
|
||||
int x = getcurx(win);
|
||||
int i;
|
||||
for (i = 0; i < width - x; i++)
|
||||
waddch(win, ' ');
|
||||
}
|
||||
#else
|
||||
wclrtoeol(win);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Return current line of text. Called by dialog_textbox() and print_line().
|
||||
* 'page' should point to start of current line before calling, and will be
|
||||
* updated to point to start of next line.
|
||||
*/
|
||||
static char *get_line(void)
|
||||
{
|
||||
int i = 0;
|
||||
static char line[MAX_LEN + 1];
|
||||
|
||||
end_reached = 0;
|
||||
while (*page != '\n') {
|
||||
if (*page == '\0') {
|
||||
end_reached = 1;
|
||||
break;
|
||||
} else if (i < MAX_LEN)
|
||||
line[i++] = *(page++);
|
||||
else {
|
||||
/* Truncate lines longer than MAX_LEN characters */
|
||||
if (i == MAX_LEN)
|
||||
line[i++] = '\0';
|
||||
page++;
|
||||
}
|
||||
}
|
||||
if (i <= MAX_LEN)
|
||||
line[i] = '\0';
|
||||
if (!end_reached)
|
||||
page++; /* move past '\n' */
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print current position
|
||||
*/
|
||||
static void print_position(WINDOW * win)
|
||||
{
|
||||
int percent;
|
||||
|
||||
wattrset(win, dlg.position_indicator.atr);
|
||||
wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
|
||||
percent = (page - buf) * 100 / strlen(buf);
|
||||
wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
|
||||
wprintw(win, "(%3d%%)", percent);
|
||||
}
|
||||
|
@ -1,19 +1,22 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
cflags=$1
|
||||
libs=$2
|
||||
|
||||
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)\"
|
||||
if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then
|
||||
if ${HOSTPKG_CONFIG} --exists $PKG; then
|
||||
${HOSTPKG_CONFIG} --cflags ${PKG} > ${cflags}
|
||||
${HOSTPKG_CONFIG} --libs ${PKG} > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if pkg-config --exists $PKG2; then
|
||||
echo cflags=\"$(pkg-config --cflags $PKG2)\"
|
||||
echo libs=\"$(pkg-config --libs $PKG2)\"
|
||||
if ${HOSTPKG_CONFIG} --exists ${PKG2}; then
|
||||
${HOSTPKG_CONFIG} --cflags ${PKG2} > ${cflags}
|
||||
${HOSTPKG_CONFIG} --libs ${PKG2} > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
@ -22,22 +25,22 @@ fi
|
||||
# (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\"
|
||||
echo -D_GNU_SOURCE -I/usr/include/ncursesw > ${cflags}
|
||||
echo -lncursesw > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f /usr/include/ncurses/ncurses.h ]; then
|
||||
echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
|
||||
echo libs=\"-lncurses\"
|
||||
echo -D_GNU_SOURCE -I/usr/include/ncurses > ${cflags}
|
||||
echo -lncurses > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# As a final fallback before giving up, check if $HOSTCC knows of a default
|
||||
# ncurses installation (e.g. from a vendor-specific sysroot).
|
||||
if echo '#include <ncurses.h>' | ${HOSTCC} -E - >/dev/null 2>&1; then
|
||||
echo cflags=\"-D_GNU_SOURCE\"
|
||||
echo libs=\"-lncurses\"
|
||||
echo -D_GNU_SOURCE > ${cflags}
|
||||
echo -lncurses > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@ -46,7 +49,7 @@ 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 "* You may also need to install ${HOSTPKG_CONFIG} to find the"
|
||||
echo >&2 "* ncurses installed in a non-default location."
|
||||
echo >&2 "*"
|
||||
exit 1
|
||||
|
@ -22,8 +22,6 @@
|
||||
#include "lkc.h"
|
||||
#include "lxdialog/dialog.h"
|
||||
|
||||
#define JUMP_NB 9
|
||||
|
||||
static const char mconf_readme[] =
|
||||
"OpenWrt config is based on Kernel kconfig\n"
|
||||
"so ipkg packages are referred here as modules.\n"
|
||||
@ -164,6 +162,12 @@ static const char mconf_readme[] =
|
||||
"(especially with a larger number of unrolled categories) than the\n"
|
||||
"default mode.\n"
|
||||
"\n"
|
||||
|
||||
"Search\n"
|
||||
"-------\n"
|
||||
"Pressing the forward-slash (/) anywhere brings up a search dialog box.\n"
|
||||
"\n"
|
||||
|
||||
"Different color themes available\n"
|
||||
"--------------------------------\n"
|
||||
"It is possible to select different color themes using the variable\n"
|
||||
@ -285,18 +289,9 @@ static int single_menu_mode;
|
||||
static int show_all_options;
|
||||
static int save_and_exit;
|
||||
static int silent;
|
||||
static int jump_key_char;
|
||||
|
||||
static void conf(struct menu *menu, struct menu *active_menu);
|
||||
static void conf_choice(struct menu *menu);
|
||||
static void conf_string(struct menu *menu);
|
||||
static void conf_load(void);
|
||||
static void conf_save(void);
|
||||
static int show_textbox_ext(const char *title, char *text, int r, int c,
|
||||
int *keys, int *vscroll, int *hscroll,
|
||||
update_text_fn update_text, void *data);
|
||||
static void show_textbox(const char *title, const char *text, int r, int c);
|
||||
static void show_helptext(const char *title, const char *text);
|
||||
static void show_help(struct menu *menu);
|
||||
|
||||
static char filename[PATH_MAX+1];
|
||||
static void set_config_filename(const char *config_filename)
|
||||
@ -355,37 +350,87 @@ static void reset_subtitle(void)
|
||||
set_dialog_subtitles(subtitles);
|
||||
}
|
||||
|
||||
static int show_textbox_ext(const char *title, const char *text, int r, int c,
|
||||
int *vscroll, int *hscroll,
|
||||
int (*extra_key_cb)(int, size_t, size_t, void *),
|
||||
void *data)
|
||||
{
|
||||
dialog_clear();
|
||||
return dialog_textbox(title, text, r, c, vscroll, hscroll,
|
||||
extra_key_cb, data);
|
||||
}
|
||||
|
||||
static void show_textbox(const char *title, const char *text, int r, int c)
|
||||
{
|
||||
show_textbox_ext(title, text, r, c, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void show_helptext(const char *title, const char *text)
|
||||
{
|
||||
show_textbox(title, text, 0, 0);
|
||||
}
|
||||
|
||||
static void show_help(struct menu *menu)
|
||||
{
|
||||
struct gstr help = str_new();
|
||||
|
||||
help.max_width = getmaxx(stdscr) - 10;
|
||||
menu_get_ext_help(menu, &help);
|
||||
|
||||
show_helptext(menu_get_prompt(menu), str_get(&help));
|
||||
str_free(&help);
|
||||
}
|
||||
|
||||
struct search_data {
|
||||
struct list_head *head;
|
||||
struct menu **targets;
|
||||
int *keys;
|
||||
struct menu *target;
|
||||
};
|
||||
|
||||
static void update_text(char *buf, size_t start, size_t end, void *_data)
|
||||
static int next_jump_key(int key)
|
||||
{
|
||||
if (key < '1' || key > '9')
|
||||
return '1';
|
||||
|
||||
key++;
|
||||
|
||||
if (key > '9')
|
||||
key = '1';
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static int handle_search_keys(int key, size_t start, size_t end, void *_data)
|
||||
{
|
||||
struct search_data *data = _data;
|
||||
struct jump_key *pos;
|
||||
int k = 0;
|
||||
int index = 0;
|
||||
|
||||
if (key < '1' || key > '9')
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(pos, data->head, entries) {
|
||||
if (pos->offset >= start && pos->offset < end) {
|
||||
char header[4];
|
||||
index = next_jump_key(index);
|
||||
|
||||
if (k < JUMP_NB) {
|
||||
int key = '0' + (pos->index % JUMP_NB) + 1;
|
||||
if (pos->offset < start)
|
||||
continue;
|
||||
|
||||
sprintf(header, "(%c)", key);
|
||||
data->keys[k] = key;
|
||||
data->targets[k] = pos->target;
|
||||
k++;
|
||||
} else {
|
||||
sprintf(header, " ");
|
||||
}
|
||||
if (pos->offset >= end)
|
||||
break;
|
||||
|
||||
memcpy(buf + pos->offset, header, sizeof(header) - 1);
|
||||
if (key == index) {
|
||||
data->target = pos->target;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
data->keys[k] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_jump_key_char(void)
|
||||
{
|
||||
jump_key_char = next_jump_key(jump_key_char);
|
||||
|
||||
return jump_key_char;
|
||||
}
|
||||
|
||||
static void search_conf(void)
|
||||
@ -432,27 +477,23 @@ again:
|
||||
sym_arr = sym_re_search(dialog_input);
|
||||
do {
|
||||
LIST_HEAD(head);
|
||||
struct menu *targets[JUMP_NB];
|
||||
int keys[JUMP_NB + 1], i;
|
||||
struct search_data data = {
|
||||
.head = &head,
|
||||
.targets = targets,
|
||||
.keys = keys,
|
||||
};
|
||||
struct jump_key *pos, *tmp;
|
||||
|
||||
jump_key_char = 0;
|
||||
res = get_relations_str(sym_arr, &head);
|
||||
set_subtitle();
|
||||
dres = show_textbox_ext("Search Results", (char *)
|
||||
str_get(&res), 0, 0, keys, &vscroll,
|
||||
&hscroll, &update_text, (void *)
|
||||
&data);
|
||||
dres = show_textbox_ext("Search Results", str_get(&res), 0, 0,
|
||||
&vscroll, &hscroll,
|
||||
handle_search_keys, &data);
|
||||
again = false;
|
||||
for (i = 0; i < JUMP_NB && keys[i]; i++)
|
||||
if (dres == keys[i]) {
|
||||
conf(targets[i]->parent, targets[i]);
|
||||
again = true;
|
||||
}
|
||||
if (dres >= '1' && dres <= '9') {
|
||||
assert(data.target != NULL);
|
||||
conf(data.target->parent, data.target);
|
||||
again = true;
|
||||
}
|
||||
str_free(&res);
|
||||
list_for_each_entry_safe(pos, tmp, &head, entries)
|
||||
free(pos);
|
||||
@ -641,158 +682,6 @@ conf_childs:
|
||||
indent -= doint;
|
||||
}
|
||||
|
||||
static void conf(struct menu *menu, struct menu *active_menu)
|
||||
{
|
||||
struct menu *submenu;
|
||||
const char *prompt = menu_get_prompt(menu);
|
||||
struct subtitle_part stpart;
|
||||
struct symbol *sym;
|
||||
int res;
|
||||
int s_scroll = 0;
|
||||
|
||||
if (menu != &rootmenu)
|
||||
stpart.text = menu_get_prompt(menu);
|
||||
else
|
||||
stpart.text = NULL;
|
||||
list_add_tail(&stpart.entries, &trail);
|
||||
|
||||
while (1) {
|
||||
item_reset();
|
||||
current_menu = menu;
|
||||
build_conf(menu);
|
||||
if (!child_count)
|
||||
break;
|
||||
set_subtitle();
|
||||
dialog_clear();
|
||||
res = dialog_menu(prompt ? prompt : "Main Menu",
|
||||
menu_instructions,
|
||||
active_menu, &s_scroll);
|
||||
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
|
||||
break;
|
||||
if (item_count() != 0) {
|
||||
if (!item_activate_selected())
|
||||
continue;
|
||||
if (!item_tag())
|
||||
continue;
|
||||
}
|
||||
submenu = item_data();
|
||||
active_menu = item_data();
|
||||
if (submenu)
|
||||
sym = submenu->sym;
|
||||
else
|
||||
sym = NULL;
|
||||
|
||||
switch (res) {
|
||||
case 0:
|
||||
switch (item_tag()) {
|
||||
case 'm':
|
||||
if (single_menu_mode)
|
||||
submenu->data = (void *) (long) !submenu->data;
|
||||
else
|
||||
conf(submenu, NULL);
|
||||
break;
|
||||
case 't':
|
||||
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
|
||||
conf_choice(submenu);
|
||||
else if (submenu->prompt->type == P_MENU)
|
||||
conf(submenu, NULL);
|
||||
break;
|
||||
case 's':
|
||||
conf_string(submenu);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (sym)
|
||||
show_help(submenu);
|
||||
else {
|
||||
reset_subtitle();
|
||||
show_helptext("README", mconf_readme);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
reset_subtitle();
|
||||
conf_save();
|
||||
break;
|
||||
case 4:
|
||||
reset_subtitle();
|
||||
conf_load();
|
||||
break;
|
||||
case 5:
|
||||
if (item_is_tag('t')) {
|
||||
if (sym_set_tristate_value(sym, yes))
|
||||
break;
|
||||
if (sym_set_tristate_value(sym, mod))
|
||||
show_textbox(NULL, setmod_text, 6, 74);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (item_is_tag('t'))
|
||||
sym_set_tristate_value(sym, no);
|
||||
break;
|
||||
case 7:
|
||||
if (item_is_tag('t'))
|
||||
sym_set_tristate_value(sym, mod);
|
||||
break;
|
||||
case 8:
|
||||
if (item_is_tag('t'))
|
||||
sym_toggle_tristate_value(sym);
|
||||
else if (item_is_tag('m'))
|
||||
conf(submenu, NULL);
|
||||
break;
|
||||
case 9:
|
||||
search_conf();
|
||||
break;
|
||||
case 10:
|
||||
show_all_options = !show_all_options;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_del(trail.prev);
|
||||
}
|
||||
|
||||
static int show_textbox_ext(const char *title, char *text, int r, int c, int
|
||||
*keys, int *vscroll, int *hscroll, update_text_fn
|
||||
update_text, void *data)
|
||||
{
|
||||
dialog_clear();
|
||||
return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
|
||||
update_text, data);
|
||||
}
|
||||
|
||||
static void show_textbox(const char *title, const char *text, int r, int c)
|
||||
{
|
||||
show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void show_helptext(const char *title, const char *text)
|
||||
{
|
||||
show_textbox(title, text, 0, 0);
|
||||
}
|
||||
|
||||
static void conf_message_callback(const char *s)
|
||||
{
|
||||
if (save_and_exit) {
|
||||
if (!silent)
|
||||
printf("%s", s);
|
||||
} else {
|
||||
show_textbox(NULL, s, 6, 60);
|
||||
}
|
||||
}
|
||||
|
||||
static void show_help(struct menu *menu)
|
||||
{
|
||||
struct gstr help = str_new();
|
||||
|
||||
help.max_width = getmaxx(stdscr) - 10;
|
||||
menu_get_ext_help(menu, &help);
|
||||
|
||||
show_helptext(menu_get_prompt(menu), str_get(&help));
|
||||
str_free(&help);
|
||||
}
|
||||
|
||||
static void conf_choice(struct menu *menu)
|
||||
{
|
||||
const char *prompt = menu_get_prompt(menu);
|
||||
@ -958,6 +847,127 @@ static void conf_save(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void conf(struct menu *menu, struct menu *active_menu)
|
||||
{
|
||||
struct menu *submenu;
|
||||
const char *prompt = menu_get_prompt(menu);
|
||||
struct subtitle_part stpart;
|
||||
struct symbol *sym;
|
||||
int res;
|
||||
int s_scroll = 0;
|
||||
|
||||
if (menu != &rootmenu)
|
||||
stpart.text = menu_get_prompt(menu);
|
||||
else
|
||||
stpart.text = NULL;
|
||||
list_add_tail(&stpart.entries, &trail);
|
||||
|
||||
while (1) {
|
||||
item_reset();
|
||||
current_menu = menu;
|
||||
build_conf(menu);
|
||||
if (!child_count)
|
||||
break;
|
||||
set_subtitle();
|
||||
dialog_clear();
|
||||
res = dialog_menu(prompt ? prompt : "Main Menu",
|
||||
menu_instructions,
|
||||
active_menu, &s_scroll);
|
||||
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
|
||||
break;
|
||||
if (item_count() != 0) {
|
||||
if (!item_activate_selected())
|
||||
continue;
|
||||
if (!item_tag())
|
||||
continue;
|
||||
}
|
||||
submenu = item_data();
|
||||
active_menu = item_data();
|
||||
if (submenu)
|
||||
sym = submenu->sym;
|
||||
else
|
||||
sym = NULL;
|
||||
|
||||
switch (res) {
|
||||
case 0:
|
||||
switch (item_tag()) {
|
||||
case 'm':
|
||||
if (single_menu_mode)
|
||||
submenu->data = (void *) (long) !submenu->data;
|
||||
else
|
||||
conf(submenu, NULL);
|
||||
break;
|
||||
case 't':
|
||||
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
|
||||
conf_choice(submenu);
|
||||
else if (submenu->prompt->type == P_MENU)
|
||||
conf(submenu, NULL);
|
||||
break;
|
||||
case 's':
|
||||
conf_string(submenu);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (sym)
|
||||
show_help(submenu);
|
||||
else {
|
||||
reset_subtitle();
|
||||
show_helptext("README", mconf_readme);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
reset_subtitle();
|
||||
conf_save();
|
||||
break;
|
||||
case 4:
|
||||
reset_subtitle();
|
||||
conf_load();
|
||||
break;
|
||||
case 5:
|
||||
if (item_is_tag('t')) {
|
||||
if (sym_set_tristate_value(sym, yes))
|
||||
break;
|
||||
if (sym_set_tristate_value(sym, mod))
|
||||
show_textbox(NULL, setmod_text, 6, 74);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (item_is_tag('t'))
|
||||
sym_set_tristate_value(sym, no);
|
||||
break;
|
||||
case 7:
|
||||
if (item_is_tag('t'))
|
||||
sym_set_tristate_value(sym, mod);
|
||||
break;
|
||||
case 8:
|
||||
if (item_is_tag('t'))
|
||||
sym_toggle_tristate_value(sym);
|
||||
else if (item_is_tag('m'))
|
||||
conf(submenu, NULL);
|
||||
break;
|
||||
case 9:
|
||||
search_conf();
|
||||
break;
|
||||
case 10:
|
||||
show_all_options = !show_all_options;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_del(trail.prev);
|
||||
}
|
||||
|
||||
static void conf_message_callback(const char *s)
|
||||
{
|
||||
if (save_and_exit) {
|
||||
if (!silent)
|
||||
printf("%s", s);
|
||||
} else {
|
||||
show_textbox(NULL, s, 6, 60);
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_exit(void)
|
||||
{
|
||||
int res;
|
||||
|
@ -661,11 +661,6 @@ const char *menu_get_prompt(struct menu *menu)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct menu *menu_get_root_menu(struct menu *menu)
|
||||
{
|
||||
return &rootmenu;
|
||||
}
|
||||
|
||||
struct menu *menu_get_parent_menu(struct menu *menu)
|
||||
{
|
||||
enum prop_type type;
|
||||
@ -706,6 +701,11 @@ static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
|
||||
}
|
||||
}
|
||||
|
||||
int __attribute__((weak)) get_jump_key_char(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void get_prompt_str(struct gstr *r, struct property *prop,
|
||||
struct list_head *head)
|
||||
{
|
||||
@ -727,52 +727,41 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
|
||||
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;
|
||||
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
|
||||
bool accessible = menu_is_visible(menu);
|
||||
|
||||
submenu[i++] = menu;
|
||||
if (location == NULL && accessible)
|
||||
if (location == NULL && menu_is_visible(menu))
|
||||
location = menu;
|
||||
}
|
||||
if (head && location) {
|
||||
jump = xmalloc(sizeof(struct jump_key));
|
||||
|
||||
if (menu_is_visible(prop->menu)) {
|
||||
/*
|
||||
* There is not enough room to put the hint at the
|
||||
* beginning of the "Prompt" line. Put the hint on the
|
||||
* last "Location" line even when it would belong on
|
||||
* the former.
|
||||
*/
|
||||
jump->target = prop->menu;
|
||||
} else
|
||||
jump->target = location;
|
||||
|
||||
if (list_empty(head))
|
||||
jump->index = 0;
|
||||
else
|
||||
jump->index = list_entry(head->prev, struct jump_key,
|
||||
entries)->index + 1;
|
||||
|
||||
jump->target = location;
|
||||
list_add_tail(&jump->entries, head);
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
str_printf(r, " Location:\n");
|
||||
for (j = 4; --i >= 0; j += 2) {
|
||||
menu = submenu[i];
|
||||
if (jump && menu == location)
|
||||
jump->offset = strlen(r->s);
|
||||
str_printf(r, "%*c-> %s", j, ' ',
|
||||
menu_get_prompt(menu));
|
||||
if (menu->sym) {
|
||||
str_printf(r, " (%s [=%s])", menu->sym->name ?
|
||||
menu->sym->name : "<choice>",
|
||||
sym_get_string_value(menu->sym));
|
||||
}
|
||||
str_append(r, "\n");
|
||||
str_printf(r, " Location:\n");
|
||||
for (j = 0; --i >= 0; j++) {
|
||||
int jk = -1;
|
||||
int indent = 2 * j + 4;
|
||||
|
||||
menu = submenu[i];
|
||||
if (jump && menu == location) {
|
||||
jump->offset = strlen(r->s);
|
||||
jk = get_jump_key_char();
|
||||
}
|
||||
|
||||
if (jk >= 0) {
|
||||
str_printf(r, "(%c)", jk);
|
||||
indent -= 3;
|
||||
}
|
||||
|
||||
str_printf(r, "%*c-> %s", indent, ' ', menu_get_prompt(menu));
|
||||
if (menu->sym) {
|
||||
str_printf(r, " (%s [=%s])", menu->sym->name ?
|
||||
menu->sym->name : "<choice>",
|
||||
sym_get_string_value(menu->sym));
|
||||
}
|
||||
str_append(r, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,22 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
cflags=$1
|
||||
libs=$2
|
||||
|
||||
PKG="ncursesw menuw panelw"
|
||||
PKG2="ncurses menu panel"
|
||||
|
||||
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)\"
|
||||
if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then
|
||||
if ${HOSTPKG_CONFIG} --exists $PKG; then
|
||||
${HOSTPKG_CONFIG} --cflags ${PKG} > ${cflags}
|
||||
${HOSTPKG_CONFIG} --libs ${PKG} > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if pkg-config --exists $PKG2; then
|
||||
echo cflags=\"$(pkg-config --cflags $PKG2)\"
|
||||
echo libs=\"$(pkg-config --libs $PKG2)\"
|
||||
if ${HOSTPKG_CONFIG} --exists $PKG2; then
|
||||
${HOSTPKG_CONFIG} --cflags ${PKG2} > ${cflags}
|
||||
${HOSTPKG_CONFIG} --libs ${PKG2} > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
@ -22,20 +25,20 @@ fi
|
||||
# (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 -lmenuw -lpanelw\"
|
||||
echo -D_GNU_SOURCE -I/usr/include/ncursesw > ${cflags}
|
||||
echo -lncursesw -lmenuw -lpanelw > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f /usr/include/ncurses/ncurses.h ]; then
|
||||
echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
|
||||
echo libs=\"-lncurses -lmenu -lpanel\"
|
||||
echo -D_GNU_SOURCE -I/usr/include/ncurses > ${cflags}
|
||||
echo -lncurses -lmenu -lpanel > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f /usr/include/ncurses.h ]; then
|
||||
echo cflags=\"-D_GNU_SOURCE\"
|
||||
echo libs=\"-lncurses -lmenu -lpanel\"
|
||||
echo -D_GNU_SOURCE > ${cflags}
|
||||
echo -lncurses -lmenu -lpanel > ${libs}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@ -44,7 +47,7 @@ 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 "* You may also need to install ${HOSTPKG_CONFIG} to find the"
|
||||
echo >&2 "* ncurses installed in a non-default location."
|
||||
echo >&2 "*"
|
||||
exit 1
|
||||
|
@ -55,8 +55,8 @@ static const char nconf_global_help[] =
|
||||
"\n"
|
||||
"Menu navigation keys\n"
|
||||
"----------------------------------------------------------------------\n"
|
||||
"Linewise up <Up>\n"
|
||||
"Linewise down <Down>\n"
|
||||
"Linewise up <Up> <k>\n"
|
||||
"Linewise down <Down> <j>\n"
|
||||
"Pagewise up <Page Up>\n"
|
||||
"Pagewise down <Page Down>\n"
|
||||
"First entry <Home>\n"
|
||||
@ -223,7 +223,7 @@ search_help[] =
|
||||
"Location:\n"
|
||||
" -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
|
||||
" -> PCI support (PCI [ = y])\n"
|
||||
" -> PCI access mode (<choice> [ = y])\n"
|
||||
"(1) -> PCI access mode (<choice> [ = y])\n"
|
||||
"Selects: LIBCRC32\n"
|
||||
"Selected by: BAR\n"
|
||||
"-----------------------------------------------------------------\n"
|
||||
@ -234,9 +234,13 @@ search_help[] =
|
||||
"o The 'Depends on:' line lists symbols that need to be defined for\n"
|
||||
" this symbol to be visible and selectable in the menu.\n"
|
||||
"o The 'Location:' lines tell, where in the menu structure this symbol\n"
|
||||
" is located. A location followed by a [ = y] indicates that this is\n"
|
||||
" a selectable menu item, and the current value is displayed inside\n"
|
||||
" brackets.\n"
|
||||
" is located.\n"
|
||||
" A location followed by a [ = y] indicates that this is\n"
|
||||
" a selectable menu item, and the current value is displayed inside\n"
|
||||
" brackets.\n"
|
||||
" Press the key in the (#) prefix to jump directly to that\n"
|
||||
" location. You will be returned to the current search results\n"
|
||||
" after exiting this new menu.\n"
|
||||
"o The 'Selects:' line tells, what symbol will be automatically selected\n"
|
||||
" if this symbol is selected (y or m).\n"
|
||||
"o The 'Selected by' line tells what symbol has selected this symbol.\n"
|
||||
@ -278,7 +282,9 @@ static const char *current_instructions = menu_instructions;
|
||||
|
||||
static char *dialog_input_result;
|
||||
static int dialog_input_result_len;
|
||||
static int jump_key_char;
|
||||
|
||||
static void selected_conf(struct menu *menu, struct menu *active_menu);
|
||||
static void conf(struct menu *menu);
|
||||
static void conf_choice(struct menu *menu);
|
||||
static void conf_string(struct menu *menu);
|
||||
@ -688,6 +694,57 @@ static int do_exit(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct search_data {
|
||||
struct list_head *head;
|
||||
struct menu *target;
|
||||
};
|
||||
|
||||
static int next_jump_key(int key)
|
||||
{
|
||||
if (key < '1' || key > '9')
|
||||
return '1';
|
||||
|
||||
key++;
|
||||
|
||||
if (key > '9')
|
||||
key = '1';
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static int handle_search_keys(int key, size_t start, size_t end, void *_data)
|
||||
{
|
||||
struct search_data *data = _data;
|
||||
struct jump_key *pos;
|
||||
int index = 0;
|
||||
|
||||
if (key < '1' || key > '9')
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(pos, data->head, entries) {
|
||||
index = next_jump_key(index);
|
||||
|
||||
if (pos->offset < start)
|
||||
continue;
|
||||
|
||||
if (pos->offset >= end)
|
||||
break;
|
||||
|
||||
if (key == index) {
|
||||
data->target = pos->target;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_jump_key_char(void)
|
||||
{
|
||||
jump_key_char = next_jump_key(jump_key_char);
|
||||
|
||||
return jump_key_char;
|
||||
}
|
||||
|
||||
static void search_conf(void)
|
||||
{
|
||||
@ -695,7 +752,8 @@ static void search_conf(void)
|
||||
struct gstr res;
|
||||
struct gstr title;
|
||||
char *dialog_input;
|
||||
int dres;
|
||||
int dres, vscroll = 0, hscroll = 0;
|
||||
bool again;
|
||||
|
||||
title = str_new();
|
||||
str_printf( &title, "Enter (sub)string or regexp to search for "
|
||||
@ -724,11 +782,28 @@ again:
|
||||
dialog_input += strlen(CONFIG_);
|
||||
|
||||
sym_arr = sym_re_search(dialog_input);
|
||||
res = get_relations_str(sym_arr, NULL);
|
||||
|
||||
do {
|
||||
LIST_HEAD(head);
|
||||
struct search_data data = {
|
||||
.head = &head,
|
||||
.target = NULL,
|
||||
};
|
||||
jump_key_char = 0;
|
||||
res = get_relations_str(sym_arr, &head);
|
||||
dres = show_scroll_win_ext(main_window,
|
||||
"Search Results", str_get(&res),
|
||||
&vscroll, &hscroll,
|
||||
handle_search_keys, &data);
|
||||
again = false;
|
||||
if (dres >= '1' && dres <= '9') {
|
||||
assert(data.target != NULL);
|
||||
selected_conf(data.target->parent, data.target);
|
||||
again = true;
|
||||
}
|
||||
str_free(&res);
|
||||
} while (again);
|
||||
free(sym_arr);
|
||||
show_scroll_win(main_window,
|
||||
"Search Results", str_get(&res));
|
||||
str_free(&res);
|
||||
str_free(&title);
|
||||
}
|
||||
|
||||
@ -1065,10 +1140,15 @@ static int do_match(int key, struct match_state *state, int *ans)
|
||||
}
|
||||
|
||||
static void conf(struct menu *menu)
|
||||
{
|
||||
selected_conf(menu, NULL);
|
||||
}
|
||||
|
||||
static void selected_conf(struct menu *menu, struct menu *active_menu)
|
||||
{
|
||||
struct menu *submenu = NULL;
|
||||
struct symbol *sym;
|
||||
int res;
|
||||
int i, res;
|
||||
int current_index = 0;
|
||||
int last_top_row = 0;
|
||||
struct match_state match_state = {
|
||||
@ -1084,6 +1164,19 @@ static void conf(struct menu *menu)
|
||||
if (!child_count)
|
||||
break;
|
||||
|
||||
if (active_menu != NULL) {
|
||||
for (i = 0; i < items_num; i++) {
|
||||
struct mitem *mcur;
|
||||
|
||||
mcur = (struct mitem *) item_userptr(curses_menu_items[i]);
|
||||
if ((struct menu *) mcur->usrptr == active_menu) {
|
||||
current_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
active_menu = NULL;
|
||||
}
|
||||
|
||||
show_menu(menu_get_prompt(menu), menu_instructions,
|
||||
current_index, &last_top_row);
|
||||
keypad((menu_win(curses_menu)), TRUE);
|
||||
@ -1108,9 +1201,11 @@ static void conf(struct menu *menu)
|
||||
break;
|
||||
switch (res) {
|
||||
case KEY_DOWN:
|
||||
case 'j':
|
||||
menu_driver(curses_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
case 'k':
|
||||
menu_driver(curses_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
@ -1291,9 +1386,11 @@ static void conf_choice(struct menu *menu)
|
||||
break;
|
||||
switch (res) {
|
||||
case KEY_DOWN:
|
||||
case 'j':
|
||||
menu_driver(curses_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
case 'k':
|
||||
menu_driver(curses_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
|
@ -497,10 +497,17 @@ void refresh_all_windows(WINDOW *main_window)
|
||||
refresh();
|
||||
}
|
||||
|
||||
/* layman's scrollable window... */
|
||||
void show_scroll_win(WINDOW *main_window,
|
||||
const char *title,
|
||||
const char *text)
|
||||
{
|
||||
(void)show_scroll_win_ext(main_window, title, (char *)text, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* layman's scrollable window... */
|
||||
int show_scroll_win_ext(WINDOW *main_window, const char *title, char *text,
|
||||
int *vscroll, int *hscroll,
|
||||
extra_key_cb_fn extra_key_cb, void *data)
|
||||
{
|
||||
int res;
|
||||
int total_lines = get_line_no(text);
|
||||
@ -514,6 +521,12 @@ void show_scroll_win(WINDOW *main_window,
|
||||
WINDOW *win;
|
||||
WINDOW *pad;
|
||||
PANEL *panel;
|
||||
bool done = false;
|
||||
|
||||
if (hscroll)
|
||||
start_x = *hscroll;
|
||||
if (vscroll)
|
||||
start_y = *vscroll;
|
||||
|
||||
getmaxyx(stdscr, lines, columns);
|
||||
|
||||
@ -549,8 +562,7 @@ void show_scroll_win(WINDOW *main_window,
|
||||
panel = new_panel(win);
|
||||
|
||||
/* handle scrolling */
|
||||
do {
|
||||
|
||||
while (!done) {
|
||||
copywin(pad, win, start_y, start_x, 2, 2, text_lines,
|
||||
text_cols, 0);
|
||||
print_in_middle(win,
|
||||
@ -593,8 +605,18 @@ void show_scroll_win(WINDOW *main_window,
|
||||
case 'l':
|
||||
start_x++;
|
||||
break;
|
||||
default:
|
||||
if (extra_key_cb) {
|
||||
size_t start = (get_line(text, start_y) - text);
|
||||
size_t end = (get_line(text, start_y + text_lines) - text);
|
||||
|
||||
if (extra_key_cb(res, start, end, data)) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res == 10 || res == 27 || res == 'q' ||
|
||||
if (res == 0 || res == 10 || res == 27 || res == 'q' ||
|
||||
res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
|
||||
res == KEY_F(F_EXIT))
|
||||
break;
|
||||
@ -606,9 +628,14 @@ void show_scroll_win(WINDOW *main_window,
|
||||
start_x = 0;
|
||||
if (start_x >= total_cols-text_cols)
|
||||
start_x = total_cols-text_cols;
|
||||
} while (res);
|
||||
}
|
||||
|
||||
if (hscroll)
|
||||
*hscroll = start_x;
|
||||
if (vscroll)
|
||||
*vscroll = start_y;
|
||||
del_panel(panel);
|
||||
delwin(win);
|
||||
refresh_all_windows(main_window);
|
||||
return res;
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ typedef enum {
|
||||
|
||||
void set_colors(void);
|
||||
|
||||
typedef int (*extra_key_cb_fn)(int, size_t, size_t, void *);
|
||||
|
||||
/* this changes the windows attributes !!! */
|
||||
void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs);
|
||||
int get_line_length(const char *line);
|
||||
@ -78,6 +80,9 @@ int dialog_inputbox(WINDOW *main_window,
|
||||
const char *title, const char *prompt,
|
||||
const char *init, char **resultp, int *result_len);
|
||||
void refresh_all_windows(WINDOW *main_window);
|
||||
int show_scroll_win_ext(WINDOW *main_window, const char *title, char *text,
|
||||
int *vscroll, int *hscroll,
|
||||
extra_key_cb_fn extra_key_cb, void *data);
|
||||
void show_scroll_win(WINDOW *main_window,
|
||||
const char *title,
|
||||
const char *text);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.7.6. */
|
||||
/* A Bison parser, made by GNU Bison 3.8.2. */
|
||||
|
||||
/* Bison implementation for Yacc-like parsers in C
|
||||
|
||||
@ -46,10 +46,10 @@
|
||||
USER NAME SPACE" below. */
|
||||
|
||||
/* Identify Bison output, and Bison version. */
|
||||
#define YYBISON 30706
|
||||
#define YYBISON 30802
|
||||
|
||||
/* Bison version string. */
|
||||
#define YYBISON_VERSION "3.7.6"
|
||||
#define YYBISON_VERSION "3.8.2"
|
||||
|
||||
/* Skeleton name. */
|
||||
#define YYSKELETON_NAME "yacc.c"
|
||||
@ -379,12 +379,18 @@ typedef int yy_state_fast_t;
|
||||
# define YY_USE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
|
||||
# else
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
# endif
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
#else
|
||||
@ -603,7 +609,7 @@ static const yytype_int8 yytranslate[] =
|
||||
};
|
||||
|
||||
#if YYDEBUG
|
||||
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
||||
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
||||
static const yytype_int16 yyrline[] =
|
||||
{
|
||||
0, 110, 110, 110, 114, 119, 121, 122, 123, 124,
|
||||
@ -661,20 +667,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef YYPRINT
|
||||
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
|
||||
(internal) symbol number NUM (which must be that of a token). */
|
||||
static const yytype_int16 yytoknum[] =
|
||||
{
|
||||
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
|
||||
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
|
||||
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
|
||||
285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
|
||||
295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
|
||||
305
|
||||
};
|
||||
#endif
|
||||
|
||||
#define YYPACT_NINF (-105)
|
||||
|
||||
#define yypact_value_is_default(Yyn) \
|
||||
@ -685,8 +677,8 @@ static const yytype_int16 yytoknum[] =
|
||||
#define yytable_value_is_error(Yyn) \
|
||||
0
|
||||
|
||||
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
|
||||
STATE-NUM. */
|
||||
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
|
||||
STATE-NUM. */
|
||||
static const yytype_int16 yypact[] =
|
||||
{
|
||||
-5, 17, 37, -105, 57, 8, -105, 91, 39, 15,
|
||||
@ -710,9 +702,9 @@ static const yytype_int16 yypact[] =
|
||||
-105, 136, -105, -105, -105, -105, -105
|
||||
};
|
||||
|
||||
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
|
||||
Performed when YYTABLE does not specify something else to do. Zero
|
||||
means the default is an error. */
|
||||
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
|
||||
Performed when YYTABLE does not specify something else to do. Zero
|
||||
means the default is an error. */
|
||||
static const yytype_int8 yydefact[] =
|
||||
{
|
||||
5, 0, 0, 5, 0, 0, 1, 0, 0, 0,
|
||||
@ -736,7 +728,7 @@ static const yytype_int8 yydefact[] =
|
||||
30, 0, 32, 31, 48, 44, 34
|
||||
};
|
||||
|
||||
/* YYPGOTO[NTERM-NUM]. */
|
||||
/* YYPGOTO[NTERM-NUM]. */
|
||||
static const yytype_int16 yypgoto[] =
|
||||
{
|
||||
-105, -105, -105, 3, 38, -105, -55, -105, -105, 138,
|
||||
@ -746,7 +738,7 @@ static const yytype_int16 yypgoto[] =
|
||||
-46, -8, -65, -105, -105, -105, -105
|
||||
};
|
||||
|
||||
/* YYDEFGOTO[NTERM-NUM]. */
|
||||
/* YYDEFGOTO[NTERM-NUM]. */
|
||||
static const yytype_uint8 yydefgoto[] =
|
||||
{
|
||||
0, 2, 3, 4, 57, 17, 18, 19, 20, 54,
|
||||
@ -756,9 +748,9 @@ static const yytype_uint8 yydefgoto[] =
|
||||
48, 49, 50, 41, 32, 39, 64
|
||||
};
|
||||
|
||||
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
|
||||
positive, shift that token. If negative, reduce the rule whose
|
||||
number is the opposite. If YYTABLE_NINF, syntax error. */
|
||||
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
|
||||
positive, shift that token. If negative, reduce the rule whose
|
||||
number is the opposite. If YYTABLE_NINF, syntax error. */
|
||||
static const yytype_int16 yytable[] =
|
||||
{
|
||||
68, 69, 116, 118, 44, 120, 7, 52, 134, 135,
|
||||
@ -807,8 +799,8 @@ static const yytype_int16 yycheck[] =
|
||||
34, -1, -1, -1, 38
|
||||
};
|
||||
|
||||
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
|
||||
symbol of state STATE-NUM. */
|
||||
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
|
||||
state STATE-NUM. */
|
||||
static const yytype_int8 yystos[] =
|
||||
{
|
||||
0, 24, 52, 53, 54, 5, 0, 54, 1, 4,
|
||||
@ -832,7 +824,7 @@ static const yytype_int8 yystos[] =
|
||||
40, 90, 40, 40, 40, 40, 40
|
||||
};
|
||||
|
||||
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
|
||||
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
|
||||
static const yytype_int8 yyr1[] =
|
||||
{
|
||||
0, 51, 52, 52, 53, 54, 54, 54, 54, 54,
|
||||
@ -848,7 +840,7 @@ static const yytype_int8 yyr1[] =
|
||||
94, 95, 96, 96, 96, 97, 97
|
||||
};
|
||||
|
||||
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
|
||||
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
|
||||
static const yytype_int8 yyr2[] =
|
||||
{
|
||||
0, 2, 2, 1, 3, 0, 2, 2, 2, 2,
|
||||
@ -873,6 +865,7 @@ enum { YYENOMEM = -2 };
|
||||
#define YYACCEPT goto yyacceptlab
|
||||
#define YYABORT goto yyabortlab
|
||||
#define YYERROR goto yyerrorlab
|
||||
#define YYNOMEM goto yyexhaustedlab
|
||||
|
||||
|
||||
#define YYRECOVERING() (!!yyerrstatus)
|
||||
@ -913,10 +906,7 @@ do { \
|
||||
YYFPRINTF Args; \
|
||||
} while (0)
|
||||
|
||||
/* This macro is provided for backward compatibility. */
|
||||
# ifndef YY_LOCATION_PRINT
|
||||
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
|
||||
@ -943,10 +933,6 @@ yy_symbol_value_print (FILE *yyo,
|
||||
YY_USE (yyoutput);
|
||||
if (!yyvaluep)
|
||||
return;
|
||||
# ifdef YYPRINT
|
||||
if (yykind < YYNTOKENS)
|
||||
YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
|
||||
# endif
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
YY_USE (yykind);
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
@ -1162,6 +1148,7 @@ yyparse (void)
|
||||
YYDPRINTF ((stderr, "Starting parse\n"));
|
||||
|
||||
yychar = YYEMPTY; /* Cause a token to be read. */
|
||||
|
||||
goto yysetstate;
|
||||
|
||||
|
||||
@ -1187,7 +1174,7 @@ yysetstate:
|
||||
|
||||
if (yyss + yystacksize - 1 <= yyssp)
|
||||
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
#else
|
||||
{
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
@ -1215,7 +1202,7 @@ yysetstate:
|
||||
# else /* defined YYSTACK_RELOCATE */
|
||||
/* Extend the stack our own way. */
|
||||
if (YYMAXDEPTH <= yystacksize)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
yystacksize *= 2;
|
||||
if (YYMAXDEPTH < yystacksize)
|
||||
yystacksize = YYMAXDEPTH;
|
||||
@ -1226,7 +1213,7 @@ yysetstate:
|
||||
YY_CAST (union yyalloc *,
|
||||
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
|
||||
if (! yyptr)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
YYSTACK_RELOCATE (yyss_alloc, yyss);
|
||||
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
|
||||
# undef YYSTACK_RELOCATE
|
||||
@ -1248,6 +1235,7 @@ yysetstate:
|
||||
}
|
||||
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
|
||||
|
||||
|
||||
if (yystate == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
@ -1832,6 +1820,7 @@ yyerrorlab:
|
||||
label yyerrorlab therefore never appears in user code. */
|
||||
if (0)
|
||||
YYERROR;
|
||||
++yynerrs;
|
||||
|
||||
/* Do not reclaim the symbols of the rule whose action triggered
|
||||
this YYERROR. */
|
||||
@ -1892,7 +1881,7 @@ yyerrlab1:
|
||||
`-------------------------------------*/
|
||||
yyacceptlab:
|
||||
yyresult = 0;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
/*-----------------------------------.
|
||||
@ -1900,24 +1889,22 @@ yyacceptlab:
|
||||
`-----------------------------------*/
|
||||
yyabortlab:
|
||||
yyresult = 1;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
#if !defined yyoverflow
|
||||
/*-------------------------------------------------.
|
||||
| yyexhaustedlab -- memory exhaustion comes here. |
|
||||
`-------------------------------------------------*/
|
||||
/*-----------------------------------------------------------.
|
||||
| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
|
||||
`-----------------------------------------------------------*/
|
||||
yyexhaustedlab:
|
||||
yyerror (YY_("memory exhausted"));
|
||||
yyresult = 2;
|
||||
goto yyreturn;
|
||||
#endif
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
/*-------------------------------------------------------.
|
||||
| yyreturn -- parsing is finished, clean up and return. |
|
||||
`-------------------------------------------------------*/
|
||||
yyreturn:
|
||||
/*----------------------------------------------------------.
|
||||
| yyreturnlab -- parsing is finished, clean up and return. |
|
||||
`----------------------------------------------------------*/
|
||||
yyreturnlab:
|
||||
if (yychar != YYEMPTY)
|
||||
{
|
||||
/* Make sure we have latest lookahead translation. See comments at
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.7.6. */
|
||||
/* A Bison parser, made by GNU Bison 3.8.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
@ -128,6 +128,8 @@ typedef union YYSTYPE YYSTYPE;
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
|
||||
#endif /* !YY_YY_PARSER_TAB_H_INCLUDED */
|
||||
|
@ -141,7 +141,7 @@ static char *do_lineno(int argc, char *argv[])
|
||||
static char *do_shell(int argc, char *argv[])
|
||||
{
|
||||
FILE *p;
|
||||
char buf[256];
|
||||
char buf[4096];
|
||||
char *cmd;
|
||||
size_t nread;
|
||||
int i;
|
||||
@ -396,6 +396,9 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (new_argc >= FUNCTION_MAX_ARGS)
|
||||
pperror("too many function arguments");
|
||||
new_argv[new_argc++] = prev;
|
||||
|
||||
/*
|
||||
|
@ -1,24 +1,40 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
PKG="Qt5Core Qt5Gui Qt5Widgets"
|
||||
cflags=$1
|
||||
libs=$2
|
||||
bin=$3
|
||||
|
||||
if [ -z "$(command -v pkg-config)" ]; then
|
||||
PKG5="Qt5Core Qt5Gui Qt5Widgets"
|
||||
PKG6="Qt6Core Qt6Gui Qt6Widgets"
|
||||
|
||||
if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then
|
||||
echo >&2 "*"
|
||||
echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it."
|
||||
echo >&2 "* 'make xconfig' requires '${HOSTPKG_CONFIG}'. Please install it."
|
||||
echo >&2 "*"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if pkg-config --exists $PKG; then
|
||||
echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags $PKG)\"
|
||||
echo libs=\"$(pkg-config --libs $PKG)\"
|
||||
echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\"
|
||||
if ${HOSTPKG_CONFIG} --exists $PKG6; then
|
||||
${HOSTPKG_CONFIG} --cflags ${PKG6} > ${cflags}
|
||||
# Qt6 requires C++17.
|
||||
echo -std=c++17 >> ${cflags}
|
||||
${HOSTPKG_CONFIG} --libs ${PKG6} > ${libs}
|
||||
${HOSTPKG_CONFIG} --variable=libexecdir Qt6Core > ${bin}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ${HOSTPKG_CONFIG} --exists $PKG5; then
|
||||
${HOSTPKG_CONFIG} --cflags ${PKG5} > ${cflags}
|
||||
${HOSTPKG_CONFIG} --libs ${PKG5} > ${libs}
|
||||
${HOSTPKG_CONFIG} --variable=host_bins Qt5Core > ${bin}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo >&2 "*"
|
||||
echo >&2 "* Could not find Qt5 via pkg-config."
|
||||
echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"
|
||||
echo >&2 "* Could not find Qt6 or Qt5 via ${HOSTPKG_CONFIG}."
|
||||
echo >&2 "* Please install Qt6 or Qt5 and make sure it's in PKG_CONFIG_PATH"
|
||||
echo >&2 "* You need $PKG6 for Qt6"
|
||||
echo >&2 "* You need $PKG5 for Qt5"
|
||||
echo >&2 "*"
|
||||
exit 1
|
||||
|
@ -5,10 +5,10 @@
|
||||
*/
|
||||
|
||||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
#include <QApplication>
|
||||
#include <QCloseEvent>
|
||||
#include <QDebug>
|
||||
#include <QDesktopWidget>
|
||||
#include <QFileDialog>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
@ -16,6 +16,8 @@
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QScreen>
|
||||
#include <QToolBar>
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -1126,7 +1128,7 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
|
||||
|
||||
QString ConfigInfoView::print_filter(const QString &str)
|
||||
{
|
||||
QRegExp re("[<>&\"\\n]");
|
||||
QRegularExpression re("[<>&\"\\n]");
|
||||
QString res = str;
|
||||
for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
|
||||
switch (res[i].toLatin1()) {
|
||||
@ -1322,15 +1324,15 @@ ConfigMainWindow::ConfigMainWindow(void)
|
||||
int width, height;
|
||||
char title[256];
|
||||
|
||||
QDesktopWidget *d = configApp->desktop();
|
||||
snprintf(title, sizeof(title), "%s%s",
|
||||
rootmenu.prompt->text,
|
||||
""
|
||||
);
|
||||
setWindowTitle(title);
|
||||
|
||||
width = configSettings->value("/window width", d->width() - 64).toInt();
|
||||
height = configSettings->value("/window height", d->height() - 64).toInt();
|
||||
QRect g = configApp->primaryScreen()->geometry();
|
||||
width = configSettings->value("/window width", g.width() - 64).toInt();
|
||||
height = configSettings->value("/window height", g.height() - 64).toInt();
|
||||
resize(width, height);
|
||||
x = configSettings->value("/window x");
|
||||
y = configSettings->value("/window y");
|
||||
@ -1379,17 +1381,17 @@ ConfigMainWindow::ConfigMainWindow(void)
|
||||
this, &ConfigMainWindow::goBack);
|
||||
|
||||
QAction *quitAction = new QAction("&Quit", this);
|
||||
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
|
||||
quitAction->setShortcut(Qt::CTRL | Qt::Key_Q);
|
||||
connect(quitAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::close);
|
||||
|
||||
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, &QAction::triggered,
|
||||
this, &ConfigMainWindow::loadConfig);
|
||||
|
||||
saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
|
||||
saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
|
||||
saveAction->setShortcut(Qt::CTRL | Qt::Key_S);
|
||||
connect(saveAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::saveConfig);
|
||||
|
||||
@ -1403,7 +1405,7 @@ ConfigMainWindow::ConfigMainWindow(void)
|
||||
connect(saveAsAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::saveConfigAs);
|
||||
QAction *searchAction = new QAction("&Find", this);
|
||||
searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
|
||||
searchAction->setShortcut(Qt::CTRL | Qt::Key_F);
|
||||
connect(searchAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::searchConfig);
|
||||
singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
|
||||
@ -1750,11 +1752,21 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
|
||||
QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
|
||||
mb.setButtonText(QMessageBox::Yes, "&Save Changes");
|
||||
mb.setButtonText(QMessageBox::No, "&Discard Changes");
|
||||
mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
|
||||
|
||||
QMessageBox mb(QMessageBox::Icon::Warning, "qconf",
|
||||
"Save configuration?");
|
||||
|
||||
QPushButton *yb = mb.addButton(QMessageBox::Yes);
|
||||
QPushButton *db = mb.addButton(QMessageBox::No);
|
||||
QPushButton *cb = mb.addButton(QMessageBox::Cancel);
|
||||
|
||||
yb->setText("&Save Changes");
|
||||
db->setText("&Discard Changes");
|
||||
cb->setText("Cancel Exit");
|
||||
|
||||
mb.setDefaultButton(yb);
|
||||
mb.setEscapeButton(cb);
|
||||
|
||||
switch (mb.exec()) {
|
||||
case QMessageBox::Yes:
|
||||
if (saveConfig())
|
||||
|
@ -123,9 +123,9 @@ static long long sym_get_range_val(struct symbol *sym, int base)
|
||||
static void sym_validate_range(struct symbol *sym)
|
||||
{
|
||||
struct property *prop;
|
||||
struct symbol *range_sym;
|
||||
int base;
|
||||
long long val, val2;
|
||||
char str[64];
|
||||
|
||||
switch (sym->type) {
|
||||
case S_INT:
|
||||
@ -141,17 +141,15 @@ static void sym_validate_range(struct symbol *sym)
|
||||
if (!prop)
|
||||
return;
|
||||
val = strtoll(sym->curr.val, NULL, base);
|
||||
val2 = sym_get_range_val(prop->expr->left.sym, base);
|
||||
range_sym = prop->expr->left.sym;
|
||||
val2 = sym_get_range_val(range_sym, base);
|
||||
if (val >= val2) {
|
||||
val2 = sym_get_range_val(prop->expr->right.sym, base);
|
||||
range_sym = prop->expr->right.sym;
|
||||
val2 = sym_get_range_val(range_sym, base);
|
||||
if (val <= val2)
|
||||
return;
|
||||
}
|
||||
if (sym->type == S_INT)
|
||||
sprintf(str, "%lld", val2);
|
||||
else
|
||||
sprintf(str, "0x%llx", val2);
|
||||
sym->curr.val = xstrdup(str);
|
||||
sym->curr.val = range_sym->curr.val;
|
||||
}
|
||||
|
||||
static void sym_set_changed(struct symbol *sym)
|
||||
@ -851,49 +849,6 @@ struct symbol *sym_find(const char *name)
|
||||
return symbol;
|
||||
}
|
||||
|
||||
const char *sym_escape_string_value(const char *in)
|
||||
{
|
||||
const char *p;
|
||||
size_t reslen;
|
||||
char *res;
|
||||
size_t l;
|
||||
|
||||
reslen = strlen(in) + strlen("\"\"") + 1;
|
||||
|
||||
p = in;
|
||||
for (;;) {
|
||||
l = strcspn(p, "\"\\");
|
||||
p += l;
|
||||
|
||||
if (p[0] == '\0')
|
||||
break;
|
||||
|
||||
reslen++;
|
||||
p++;
|
||||
}
|
||||
|
||||
res = xmalloc(reslen);
|
||||
res[0] = '\0';
|
||||
|
||||
strcat(res, "\"");
|
||||
|
||||
p = in;
|
||||
for (;;) {
|
||||
l = strcspn(p, "\"\\");
|
||||
strncat(res, p, l);
|
||||
p += l;
|
||||
|
||||
if (p[0] == '\0')
|
||||
break;
|
||||
|
||||
strcat(res, "\\");
|
||||
strncat(res, p++, 1);
|
||||
}
|
||||
|
||||
strcat(res, "\"");
|
||||
return res;
|
||||
}
|
||||
|
||||
struct sym_match {
|
||||
struct symbol *sym;
|
||||
off_t so, eo;
|
||||
|
@ -74,7 +74,7 @@ void str_printf(struct gstr *gs, const char *fmt, ...)
|
||||
}
|
||||
|
||||
/* Retrieve value of growable string */
|
||||
const char *str_get(struct gstr *gs)
|
||||
char *str_get(struct gstr *gs)
|
||||
{
|
||||
return gs->s;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user