
Bring in this code wholesale, replacing the old U-Boot code.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/kconfig/.gitignore | 20 +- scripts/kconfig/Makefile | 211 ++-- scripts/kconfig/conf.c | 499 +++++--- scripts/kconfig/confdata.c | 1074 ++++++++-------- scripts/kconfig/expr.c | 30 +- scripts/kconfig/expr.h | 17 +- scripts/kconfig/gconf-cfg.sh | 15 +- scripts/kconfig/gconf.c | 47 +- scripts/kconfig/images.c | 34 +- scripts/kconfig/images.h | 33 + scripts/kconfig/internal.h | 9 + scripts/kconfig/kconf_id.c | 52 - scripts/kconfig/{zconf.l => lexer.l} | 247 ++-- scripts/kconfig/list.h | 2 +- scripts/kconfig/lkc.h | 91 +- scripts/kconfig/lkc_proto.h | 22 +- scripts/kconfig/lxdialog/.gitignore | 4 - scripts/kconfig/lxdialog/BIG.FAT.WARNING | 2 +- scripts/kconfig/lxdialog/inputbox.c | 3 +- scripts/kconfig/lxdialog/util.c | 4 +- scripts/kconfig/mconf-cfg.sh | 36 +- scripts/kconfig/mconf.c | 42 +- scripts/kconfig/menu.c | 263 ++-- scripts/kconfig/merge_config.sh | 75 +- scripts/kconfig/nconf-cfg.sh | 32 +- scripts/kconfig/nconf.c | 89 +- scripts/kconfig/nconf.gui.c | 292 ++--- scripts/kconfig/nconf.h | 56 +- scripts/kconfig/{zconf.y => parser.y} | 336 ++--- scripts/kconfig/preprocess.c | 12 +- scripts/kconfig/qconf-cfg.sh | 29 +- scripts/kconfig/qconf.cc | 1106 +++++++++-------- scripts/kconfig/qconf.h | 163 +-- scripts/kconfig/streamline_config.pl | 98 +- scripts/kconfig/symbol.c | 106 +- scripts/kconfig/tests/auto_submenu/Kconfig | 2 + .../kconfig/tests/auto_submenu/__init__.py | 1 + scripts/kconfig/tests/choice/Kconfig | 4 +- scripts/kconfig/tests/choice/__init__.py | 1 + .../tests/choice_value_with_m_dep/Kconfig | 4 +- .../tests/choice_value_with_m_dep/__init__.py | 1 + scripts/kconfig/tests/conftest.py | 4 + .../tests/err_recursive_dep/expected_stderr | 14 +- .../kconfig/tests/err_recursive_inc/Kconfig | 1 + .../tests/err_recursive_inc/Kconfig.inc1 | 1 + .../tests/err_recursive_inc/Kconfig.inc2 | 1 + .../tests/err_recursive_inc/Kconfig.inc3 | 1 + .../tests/err_recursive_inc/__init__.py | 1 + .../tests/err_recursive_inc/expected_stderr | 6 +- scripts/kconfig/tests/inter_choice/Kconfig | 4 +- .../kconfig/tests/inter_choice/__init__.py | 1 + .../kconfig/tests/new_choice_with_dep/Kconfig | 2 + .../tests/new_choice_with_dep/__init__.py | 1 + .../tests/no_write_if_dep_unmet/Kconfig | 2 + .../tests/no_write_if_dep_unmet/__init__.py | 1 + .../tests/preprocess/builtin_func/Kconfig | 27 + .../tests/preprocess/builtin_func/__init__.py | 9 + .../preprocess/builtin_func/expected_stderr | 5 + .../preprocess/builtin_func/expected_stdout | 1 + .../preprocess/circular_expansion/Kconfig | 5 + .../preprocess/circular_expansion/__init__.py | 11 + .../circular_expansion/expected_stderr | 1 + .../kconfig/tests/preprocess/escape/Kconfig | 44 + .../tests/preprocess/escape/__init__.py | 8 + .../tests/preprocess/escape/expected_stderr | 10 + .../kconfig/tests/preprocess/variable/Kconfig | 53 + .../tests/preprocess/variable/__init__.py | 8 + .../tests/preprocess/variable/expected_stderr | 9 + .../kconfig/tests/rand_nested_choice/Kconfig | 33 - .../tests/rand_nested_choice/__init__.py | 16 - .../tests/rand_nested_choice/expected_stdout0 | 2 - .../tests/rand_nested_choice/expected_stdout1 | 4 - .../tests/rand_nested_choice/expected_stdout2 | 5 - scripts/kconfig/util.c | 5 +- 74 files changed, 2786 insertions(+), 2674 deletions(-) create mode 100644 scripts/kconfig/images.h create mode 100644 scripts/kconfig/internal.h delete mode 100644 scripts/kconfig/kconf_id.c rename scripts/kconfig/{zconf.l => lexer.l} (67%) delete mode 100644 scripts/kconfig/lxdialog/.gitignore mode change 100644 => 100755 scripts/kconfig/nconf-cfg.sh rename scripts/kconfig/{zconf.y => parser.y} (70%) create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/builtin_func/expected_stdout create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/escape/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/escape/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/escape/expected_stderr create mode 100644 scripts/kconfig/tests/preprocess/variable/Kconfig create mode 100644 scripts/kconfig/tests/preprocess/variable/__init__.py create mode 100644 scripts/kconfig/tests/preprocess/variable/expected_stderr delete mode 100644 scripts/kconfig/tests/rand_nested_choice/Kconfig delete mode 100644 scripts/kconfig/tests/rand_nested_choice/__init__.py delete mode 100644 scripts/kconfig/tests/rand_nested_choice/expected_stdout0 delete mode 100644 scripts/kconfig/tests/rand_nested_choice/expected_stdout1 delete mode 100644 scripts/kconfig/tests/rand_nested_choice/expected_stdout2
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index 0aabc1d6a182..0b2ff775b2e3 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -1,13 +1,7 @@ -# -# Generated files -# -*.moc - -# -# configuration programs -# -conf -mconf -nconf -qconf -gconf +# SPDX-License-Identifier: GPL-2.0-only +/conf +/[gmnq]conf +/[gmnq]conf-bin +/[gmnq]conf-cflags +/[gmnq]conf-libs +/qconf-moc.cc diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 12e525ee31f1..af1c96198f49 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -3,62 +3,62 @@ # Kernel configuration targets # These targets are used from top-level makefile
-PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig \ - build_menuconfig build_nconfig build_gconfig build_xconfig - -# Added for U-Boot -# Linux has defconfig files in arch/$(SRCARCH)/configs/, -# on the other hand, U-Boot does in configs/. -# Set SRCARCH to .. fake this Makefile. -SRCARCH := .. - ifdef KBUILD_KCONFIG Kconfig := $(KBUILD_KCONFIG) else Kconfig := Kconfig endif
+ifndef KBUILD_DEFCONFIG +KBUILD_DEFCONFIG := defconfig +endif + ifeq ($(quiet),silent_) silent := -s endif
+export KCONFIG_DEFCONFIG_LIST := +ifndef cross_compiling +kernel-release := $(shell uname -r) +KCONFIG_DEFCONFIG_LIST += \ + /lib/modules/$(kernel-release)/.config \ + /etc/kernel-config \ + /boot/config-$(kernel-release) +endif +KCONFIG_DEFCONFIG_LIST += arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) + # We need this, in case the user has it in its environment unexport CONFIG_
-xconfig: $(obj)/qconf - $< $(silent) $(Kconfig) +config-prog := conf +menuconfig-prog := mconf +nconfig-prog := nconf +gconfig-prog := gconf +xconfig-prog := qconf
-gconfig: $(obj)/gconf - $< $(silent) $(Kconfig) +define config_rule +PHONY += $(1) +$(1): $(obj)/$($(1)-prog) + $(Q)$$< $(silent) $(Kconfig)
-menuconfig: $(obj)/mconf - $< $(silent) $(Kconfig) - -config: $(obj)/conf - $< $(silent) --oldaskconfig $(Kconfig) - -nconfig: $(obj)/nconf - $< $(silent) $(Kconfig) - -build_menuconfig: $(obj)/mconf - -build_nconfig: $(obj)/nconf - -build_gconfig: $(obj)/gconf +PHONY += build_$(1) +build_$(1): $(obj)/$($(1)-prog) +endef
-build_xconfig: $(obj)/qconf +$(foreach c, config menuconfig nconfig gconfig xconfig, $(eval $(call config_rule,$(c))))
+PHONY += localmodconfig localyesconfig localyesconfig localmodconfig: $(obj)/conf - $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config - $(Q)if [ -f .config ]; then \ - cmp -s .tmp.config .config || \ - (mv -f .config .config.old.1; \ - mv -f .tmp.config .config; \ - $< $(silent) --oldconfig $(Kconfig); \ - mv -f .config.old.1 .config.old) \ - else \ - mv -f .tmp.config .config; \ - $< $(silent) --oldconfig $(Kconfig); \ + $(Q)$(PERL) $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config + $(Q)if [ -f .config ]; then \ + cmp -s .tmp.config .config || \ + (mv -f .config .config.old.1; \ + mv -f .tmp.config .config; \ + $< $(silent) --oldconfig $(Kconfig); \ + mv -f .config.old.1 .config.old) \ + else \ + mv -f .tmp.config .config; \ + $< $(silent) --oldconfig $(Kconfig); \ fi $(Q)rm -f .tmp.config
@@ -68,21 +68,20 @@ localyesconfig localmodconfig: $(obj)/conf # syncconfig has become an internal implementation detail and is now # deprecated for external use simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ - alldefconfig randconfig listnewconfig olddefconfig syncconfig + alldefconfig randconfig listnewconfig olddefconfig syncconfig \ + helpnewconfig yes2modconfig mod2yesconfig mod2noconfig + PHONY += $(simple-targets)
$(simple-targets): $(obj)/conf - $< $(silent) --$@ $(Kconfig) + $(Q)$< $(silent) --$@ $(Kconfig)
PHONY += savedefconfig defconfig
savedefconfig: $(obj)/conf - $< $(silent) --$@=defconfig $(Kconfig) + $(Q)$< $(silent) --$@=defconfig $(Kconfig)
defconfig: $(obj)/conf -ifeq ($(KBUILD_DEFCONFIG),) - $< $(silent) --defconfig $(Kconfig) -else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) @@ -90,41 +89,29 @@ else @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) endif -endif
%_defconfig: $(obj)/conf $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
-# Added for U-Boot (backward compatibility) -%_config: %_defconfig - @: - configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
%.config: $(obj)/conf $(if $(call configfiles),, $(error No configuration exists for this target on this architecture)) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles) - +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig - -PHONY += kvmconfig -kvmconfig: kvm_guest.config - @: - -PHONY += xenconfig -xenconfig: xen.config - @: + $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
PHONY += tinyconfig tinyconfig: - $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config + $(Q)KCONFIG_ALLCONFIG=kernel/configs/tiny-base.config $(MAKE) -f $(srctree)/Makefile allnoconfig + $(Q)$(MAKE) -f $(srctree)/Makefile tiny.config
# CHECK: -o cache_dir=<path> working? PHONY += testconfig testconfig: $(obj)/conf - $(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ + $(Q)$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ -o cache_dir=$(abspath $(obj)/tests/.cache) \ $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) -clean-dirs += tests/.cache +clean-files += tests/.cache
# Help text used by make help help: @@ -135,7 +122,9 @@ help: @echo ' gconfig - Update current config utilising a GTK+ based front-end' @echo ' oldconfig - Update current config utilising a provided .config as base' @echo ' localmodconfig - Update current config disabling modules not loaded' + @echo ' except those preserved by LMC_KEEP environment variable' @echo ' localyesconfig - Update current config converting local mods to core' + @echo ' except those preserved by LMC_KEEP environment variable' @echo ' defconfig - New config with default from ARCH supplied defconfig' @echo ' savedefconfig - Save current config as ./defconfig (minimal config)' @echo ' allnoconfig - New config where all options are answered with no' @@ -143,84 +132,86 @@ help: @echo ' allmodconfig - New config selecting modules when possible' @echo ' alldefconfig - New config with all symbols set to default' @echo ' randconfig - New config with random answer to all options' + @echo ' yes2modconfig - Change answers from yes to mod if possible' + @echo ' mod2yesconfig - Change answers from mod to yes if possible' + @echo ' mod2noconfig - Change answers from mod to no if possible' @echo ' listnewconfig - List new options' + @echo ' helpnewconfig - List new options and help text' @echo ' olddefconfig - Same as oldconfig but sets new symbols to their' @echo ' default value without prompting' -# @echo ' kvmconfig - Enable additional options for kvm guest kernel support' -# @echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support' -# @echo ' tinyconfig - Configure the tiniest possible kernel' + @echo ' tinyconfig - Configure the tiniest possible kernel' @echo ' testconfig - Run Kconfig unit tests (requires python3 and pytest)'
# =========================================================================== -# Shared Makefile for the various kconfig executables: -# conf: Used for defconfig, oldconfig and related targets # object files used by all kconfig flavours +common-objs := confdata.o expr.o lexer.lex.o menu.o parser.tab.o \ + preprocess.o symbol.o util.o
-conf-objs := conf.o zconf.tab.o +$(obj)/lexer.lex.o: $(obj)/parser.tab.h +HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src) +HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src)
-hostprogs-y := conf - -targets += zconf.lex.c - -# generated files seem to need this to find local include files -HOSTCFLAGS_zconf.lex.o := -I$(src) -HOSTCFLAGS_zconf.tab.o := -I$(src) +# conf: Used for defconfig, oldconfig and related targets +hostprogs += conf +conf-objs := conf.o $(common-objs)
# nconf: Used for the nconfig target based on ncurses -hostprogs-y += nconf -nconf-objs := nconf.o zconf.tab.o nconf.gui.o +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-y += mconf -lxdialog := checklist.o inputbox.o menubox.o textbox.o util.o yesno.o -mconf-objs := mconf.o zconf.tab.o $(addprefix lxdialog/, $(lxdialog)) +hostprogs += mconf +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)))
-$(obj)/mconf.o: $(obj)/.mconf-cfg -$(addprefix $(obj)/lxdialog/, $(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-y += qconf -qconf-cxxobjs := qconf.o -qconf-objs := zconf.tab.o - -HOSTLDLIBS_qconf = $(shell . $(obj)/.qconf-cfg && echo $$libs) -HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/.qconf-cfg && echo $$cflags) +hostprogs += qconf +qconf-cxxobjs := qconf.o qconf-moc.o +qconf-objs := images.o $(common-objs)
-$(obj)/qconf.o: $(obj)/.qconf-cfg $(obj)/qconf.moc +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) -i $< -o $@ + cmd_moc = $(call read-file, $(obj)/qconf-bin)/moc $< -o $@
-$(obj)/%.moc: $(src)/%.h $(obj)/.qconf-cfg - $(call cmd,moc) +$(obj)/qconf-moc.cc: $(src)/qconf.h FORCE | $(obj)/qconf-bin + $(call if_changed,moc)
-# gconf: Used for the gconfig target based on GTK+ -hostprogs-y += gconf -gconf-objs := gconf.o zconf.tab.o +targets += qconf-moc.cc
-HOSTLDLIBS_gconf = $(shell . $(obj)/.gconf-cfg && echo $$libs) -HOSTCFLAGS_gconf.o = $(shell . $(obj)/.gconf-cfg && echo $$cflags) +# gconf: Used for the gconfig target based on GTK+ +hostprogs += gconf +gconf-objs := gconf.o images.o $(common-objs)
-$(obj)/gconf.o: $(obj)/.gconf-cfg +HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) +HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags)
-$(obj)/zconf.tab.o: $(obj)/zconf.lex.c +$(obj)/gconf: | $(obj)/gconf-libs +$(obj)/gconf.o: | $(obj)/gconf-cflags
# check if necessary packages are available, and configure build flags -define filechk_conf_cfg - $(CONFIG_SHELL) $< -endef +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 diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 376f796f6748..33d19e419908 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
#include <ctype.h> @@ -11,7 +11,6 @@ #include <time.h> #include <unistd.h> #include <getopt.h> -#include <sys/stat.h> #include <sys/time.h> #include <errno.h>
@@ -32,10 +31,14 @@ enum input_mode { defconfig, savedefconfig, listnewconfig, + helpnewconfig, olddefconfig, + yes2modconfig, + mod2yesconfig, + mod2noconfig, }; static enum input_mode input_mode = oldaskconfig; - +static int input_mode_opt; static int indent = 1; static int tty_stdio; static int sync_kconfig; @@ -80,17 +83,246 @@ static void xfgets(char *str, int size, FILE *in) printf("%s", str); }
-static int conf_askvalue(struct symbol *sym, const char *def) +static void set_randconfig_seed(void) +{ + unsigned int seed; + char *env; + bool seed_set = false; + + env = getenv("KCONFIG_SEED"); + if (env && *env) { + char *endp; + + seed = strtol(env, &endp, 0); + if (*endp == '\0') + seed_set = true; + } + + if (!seed_set) { + struct timeval now; + + /* + * Use microseconds derived seed, compensate for systems where it may + * be zero. + */ + gettimeofday(&now, NULL); + seed = (now.tv_sec + 1) * (now.tv_usec + 1); + } + + printf("KCONFIG_SEED=0x%X\n", seed); + srand(seed); +} + +static bool randomize_choice_values(struct symbol *csym) +{ + struct property *prop; + struct symbol *sym; + struct expr *e; + int cnt, def; + + /* + * If choice is mod then we may have more items selected + * and if no then no-one. + * In both cases stop. + */ + if (csym->curr.tri != yes) + return false; + + prop = sym_get_choice_prop(csym); + + /* count entries in choice block */ + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) + cnt++; + + /* + * find a random value and set it to yes, + * set the rest to no so we have only one set + */ + def = rand() % cnt; + + cnt = 0; + expr_list_for_each_sym(prop->expr, e, sym) { + if (def == cnt++) { + sym->def[S_DEF_USER].tri = yes; + csym->def[S_DEF_USER].val = sym; + } else { + sym->def[S_DEF_USER].tri = no; + } + sym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + sym->flags &= ~SYMBOL_VALID; + } + csym->flags |= SYMBOL_DEF_USER; + /* clear VALID to get value calculated */ + csym->flags &= ~SYMBOL_VALID; + + return true; +} + +enum conf_def_mode { + def_default, + def_yes, + def_mod, + def_no, + def_random +}; + +static bool conf_set_all_new_symbols(enum conf_def_mode mode) +{ + struct symbol *sym, *csym; + int i, cnt; + /* + * can't go as the default in switch-case below, otherwise gcc whines + * about -Wmaybe-uninitialized + */ + int pby = 50; /* probability of bool = y */ + int pty = 33; /* probability of tristate = y */ + int ptm = 33; /* probability of tristate = m */ + bool has_changed = false; + + if (mode == def_random) { + int n, p[3]; + char *env = getenv("KCONFIG_PROBABILITY"); + + n = 0; + while (env && *env) { + char *endp; + int tmp = strtol(env, &endp, 10); + + if (tmp >= 0 && tmp <= 100) { + p[n++] = tmp; + } else { + errno = ERANGE; + perror("KCONFIG_PROBABILITY"); + exit(1); + } + env = (*endp == ':') ? endp + 1 : endp; + if (n >= 3) + break; + } + switch (n) { + case 1: + pby = p[0]; + ptm = pby / 2; + pty = pby - ptm; + break; + case 2: + pty = p[0]; + ptm = p[1]; + pby = pty + ptm; + break; + case 3: + pby = p[0]; + pty = p[1]; + ptm = p[2]; + break; + } + + if (pty + ptm > 100) { + errno = ERANGE; + perror("KCONFIG_PROBABILITY"); + exit(1); + } + } + + for_all_symbols(i, sym) { + if (sym_has_value(sym) || sym->flags & SYMBOL_VALID) + continue; + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + has_changed = true; + switch (mode) { + case def_yes: + sym->def[S_DEF_USER].tri = yes; + break; + case def_mod: + sym->def[S_DEF_USER].tri = mod; + break; + case def_no: + sym->def[S_DEF_USER].tri = no; + break; + case def_random: + sym->def[S_DEF_USER].tri = no; + cnt = rand() % 100; + if (sym->type == S_TRISTATE) { + if (cnt < pty) + sym->def[S_DEF_USER].tri = yes; + else if (cnt < pty + ptm) + sym->def[S_DEF_USER].tri = mod; + } else if (cnt < pby) + sym->def[S_DEF_USER].tri = yes; + break; + default: + continue; + } + if (!(sym_is_choice(sym) && mode == def_random)) + sym->flags |= SYMBOL_DEF_USER; + break; + default: + break; + } + + } + + sym_clear_all_valid(); + + /* + * We have different type of choice blocks. + * If curr.tri equals to mod then we can select several + * choice symbols in one block. + * In this case we do nothing. + * If curr.tri equals yes then only one symbol can be + * selected in a choice block and we set it to yes, + * and the rest to no. + */ + if (mode != def_random) { + for_all_symbols(i, csym) { + if ((sym_is_choice(csym) && !sym_has_value(csym)) || + sym_is_choice_value(csym)) + csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; + } + } + + for_all_symbols(i, csym) { + if (sym_has_value(csym) || !sym_is_choice(csym)) + continue; + + sym_calc_value(csym); + if (mode == def_random) + has_changed |= randomize_choice_values(csym); + else { + set_all_choice_values(csym); + has_changed = true; + } + } + + return has_changed; +} + +static void conf_rewrite_tristates(tristate old_val, tristate new_val) { - enum symbol_type type = sym_get_type(sym); + struct symbol *sym; + int i; + + for_all_symbols(i, sym) { + if (sym_get_type(sym) == S_TRISTATE && + sym->def[S_DEF_USER].tri == old_val) + sym->def[S_DEF_USER].tri = new_val; + } + sym_clear_all_valid(); +}
+static int conf_askvalue(struct symbol *sym, const char *def) +{ if (!sym_has_value(sym)) printf("(NEW) ");
line[0] = '\n'; line[1] = 0;
- if (!sym_is_changable(sym)) { + if (!sym_is_changeable(sym)) { printf("%s\n", def); line[0] = '\n'; line[1] = 0; @@ -105,24 +337,12 @@ static int conf_askvalue(struct symbol *sym, const char *def) return 0; } /* fall through */ - case oldaskconfig: + default: fflush(stdout); xfgets(line, sizeof(line), stdin); - return 1; - default: break; }
- switch (type) { - case S_INT: - case S_HEX: - case S_STRING: - printf("%s\n", def); - return 1; - default: - ; - } - printf("%s", line); return 1; }
@@ -135,7 +355,7 @@ static int conf_string(struct menu *menu) printf("%*s%s ", indent - 1, "", menu->prompt->text); printf("(%s) ", sym->name); def = sym_get_string_value(sym); - if (sym_get_string_value(sym)) + if (def) printf("[%s] ", def); if (!conf_askvalue(sym, def)) return 0; @@ -234,7 +454,7 @@ static int conf_choice(struct menu *menu)
sym = menu->sym; is_new = !sym_has_value(sym); - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { conf_sym(menu); sym_calc_value(sym); switch (sym_get_tristate_value(sym)) { @@ -331,7 +551,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); @@ -417,29 +637,26 @@ static void check_conf(struct menu *menu) return;
sym = menu->sym; - if (sym && !sym_has_value(sym)) { - if (sym_is_changable(sym) || - (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { - if (input_mode == 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); - } - } - } else { - if (!conf_cnt++) - printf("*\n* Restart config...\n*\n"); - rootEntry = menu_get_parent_menu(menu); - conf(rootEntry); - } + if (sym && !sym_has_value(sym) && + (sym_is_changeable(sym) || + (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) { + + switch (input_mode) { + case listnewconfig: + if (sym->name) + print_symbol_for_listconfig(sym); + break; + case helpnewconfig: + printf("-----\n"); + print_help(menu); + printf("-----\n"); + break; + default: + if (!conf_cnt++) + printf("*\n* Restart config...\n*\n"); + rootEntry = menu_get_parent_menu(menu); + conf(rootEntry); + break; } }
@@ -447,28 +664,39 @@ static void check_conf(struct menu *menu) check_conf(child); }
-static struct option long_opts[] = { - {"oldaskconfig", no_argument, NULL, oldaskconfig}, - {"oldconfig", no_argument, NULL, oldconfig}, - {"syncconfig", no_argument, NULL, syncconfig}, - {"defconfig", optional_argument, NULL, defconfig}, - {"savedefconfig", required_argument, NULL, savedefconfig}, - {"allnoconfig", no_argument, NULL, allnoconfig}, - {"allyesconfig", no_argument, NULL, allyesconfig}, - {"allmodconfig", no_argument, NULL, allmodconfig}, - {"alldefconfig", no_argument, NULL, alldefconfig}, - {"randconfig", no_argument, NULL, randconfig}, - {"listnewconfig", no_argument, NULL, listnewconfig}, - {"olddefconfig", no_argument, NULL, olddefconfig}, +static const struct option long_opts[] = { + {"help", no_argument, NULL, 'h'}, + {"silent", no_argument, NULL, 's'}, + {"oldaskconfig", no_argument, &input_mode_opt, oldaskconfig}, + {"oldconfig", no_argument, &input_mode_opt, oldconfig}, + {"syncconfig", no_argument, &input_mode_opt, syncconfig}, + {"defconfig", required_argument, &input_mode_opt, defconfig}, + {"savedefconfig", required_argument, &input_mode_opt, savedefconfig}, + {"allnoconfig", no_argument, &input_mode_opt, allnoconfig}, + {"allyesconfig", no_argument, &input_mode_opt, allyesconfig}, + {"allmodconfig", no_argument, &input_mode_opt, allmodconfig}, + {"alldefconfig", no_argument, &input_mode_opt, alldefconfig}, + {"randconfig", no_argument, &input_mode_opt, randconfig}, + {"listnewconfig", no_argument, &input_mode_opt, listnewconfig}, + {"helpnewconfig", no_argument, &input_mode_opt, helpnewconfig}, + {"olddefconfig", no_argument, &input_mode_opt, olddefconfig}, + {"yes2modconfig", no_argument, &input_mode_opt, yes2modconfig}, + {"mod2yesconfig", no_argument, &input_mode_opt, mod2yesconfig}, + {"mod2noconfig", no_argument, &input_mode_opt, mod2noconfig}, {NULL, 0, NULL, 0} };
static void conf_usage(const char *progname) { - - printf("Usage: %s [-s] [option] <kconfig-file>\n", progname); - printf("[option] is _one_ of the following:\n"); + printf("Usage: %s [options] <kconfig-file>\n", progname); + printf("\n"); + printf("Generic options:\n"); + printf(" -h, --help Print this message and exit.\n"); + printf(" -s, --silent Do not print log.\n"); + printf("\n"); + printf("Mode options:\n"); printf(" --listnewconfig List new options\n"); + printf(" --helpnewconfig List new options and help text\n"); printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); printf(" --oldconfig Update a configuration using a provided .config as base\n"); printf(" --syncconfig Similar to oldconfig but generates configuration in\n" @@ -481,6 +709,10 @@ static void conf_usage(const char *progname) printf(" --allmodconfig New config where all options are answered with mod\n"); printf(" --alldefconfig New config with all symbols set to default\n"); printf(" --randconfig New config with random answer to all options\n"); + printf(" --yes2modconfig Change answers from yes to mod if possible\n"); + printf(" --mod2yesconfig Change answers from mod to yes if possible\n"); + printf(" --mod2noconfig Change answers from mod to no if possible\n"); + printf(" (If none of the above is given, --oldaskconfig is the default)\n"); }
int main(int ac, char **av) @@ -488,67 +720,42 @@ int main(int ac, char **av) const char *progname = av[0]; int opt; const char *name, *defconfig_file = NULL /* gcc uninit */; - struct stat tmpstat; int no_conf_write = 0;
tty_stdio = isatty(0) && isatty(1);
- while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) { - if (opt == 's') { - conf_set_message_callback(NULL); - continue; - } - input_mode = (enum input_mode)opt; + while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) { switch (opt) { - case syncconfig: - /* - * syncconfig is invoked during the build stage. - * Suppress distracting "configuration written to ..." - */ - conf_set_message_callback(NULL); - sync_kconfig = 1; + case 'h': + conf_usage(progname); + exit(1); break; - case defconfig: - case savedefconfig: - defconfig_file = optarg; + case 's': + conf_set_message_callback(NULL); break; - case randconfig: - { - struct timeval now; - unsigned int seed; - char *seed_env; - - /* - * Use microseconds derived seed, - * compensate for systems where it may be zero - */ - gettimeofday(&now, NULL); - seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); - - seed_env = getenv("KCONFIG_SEED"); - if( seed_env && *seed_env ) { - char *endp; - int tmp = (int)strtol(seed_env, &endp, 0); - if (*endp == '\0') { - seed = tmp; - } + case 0: + input_mode = input_mode_opt; + switch (input_mode) { + case syncconfig: + /* + * syncconfig is invoked during the build stage. + * Suppress distracting + * "configuration written to ..." + */ + conf_set_message_callback(NULL); + sync_kconfig = 1; + break; + case defconfig: + case savedefconfig: + defconfig_file = optarg; + break; + case randconfig: + set_randconfig_seed(); + break; + default: + break; } - fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed ); - srand(seed); - break; - } - case oldaskconfig: - case oldconfig: - case allnoconfig: - case allyesconfig: - case allmodconfig: - case alldefconfig: - case listnewconfig: - case olddefconfig: - break; - case '?': - conf_usage(progname); - exit(1); + default: break; } } @@ -557,26 +764,11 @@ int main(int ac, char **av) conf_usage(progname); exit(1); } - name = av[optind]; - conf_parse(name); + conf_parse(av[optind]); //zconfdump(stdout); - if (sync_kconfig) { - name = conf_get_configname(); - if (stat(name, &tmpstat)) { - fprintf(stderr, "***\n" - "*** Configuration file "%s" not found!\n" - "***\n" - "*** Please run some configurator (e.g. "make oldconfig" or\n" - "*** "make menuconfig" or "make xconfig").\n" - "***\n", name); - exit(1); - } - }
switch (input_mode) { case defconfig: - if (!defconfig_file) - defconfig_file = conf_get_default_confname(); if (conf_read(defconfig_file)) { fprintf(stderr, "***\n" @@ -591,7 +783,11 @@ int main(int ac, char **av) case oldaskconfig: case oldconfig: case listnewconfig: + case helpnewconfig: case olddefconfig: + case yes2modconfig: + case mod2yesconfig: + case mod2noconfig: conf_read(NULL); break; case allnoconfig: @@ -665,6 +861,15 @@ int main(int ac, char **av) break; case savedefconfig: break; + case yes2modconfig: + conf_rewrite_tristates(yes, mod); + break; + case mod2yesconfig: + conf_rewrite_tristates(mod, yes); + break; + case mod2noconfig: + conf_rewrite_tristates(mod, no); + break; case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); @@ -672,6 +877,7 @@ int main(int ac, char **av) /* fall through */ case oldconfig: case listnewconfig: + case helpnewconfig: case syncconfig: /* Update until a loop caused no more changes */ do { @@ -684,29 +890,32 @@ int main(int ac, char **av) break; }
- if (sync_kconfig) { - /* syncconfig is used during the build so we shall update autoconf. - * All other commands are only used to generate a config. - */ - if (!no_conf_write && conf_write(NULL)) { - fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); - exit(1); - } - if (conf_write_autoconf()) { - fprintf(stderr, "\n*** Error during update of the configuration.\n\n"); - return 1; - } - } else if (input_mode == savedefconfig) { + if (input_mode == savedefconfig) { if (conf_write_defconfig(defconfig_file)) { fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n", defconfig_file); return 1; } - } else if (input_mode != listnewconfig) { - if (conf_write(NULL)) { + } else if (input_mode != listnewconfig && input_mode != helpnewconfig) { + if (!no_conf_write && conf_write(NULL)) { fprintf(stderr, "\n*** Error during writing of the configuration.\n\n"); exit(1); } + + /* + * Create auto.conf if it does not exist. + * This prevents GNU Make 4.1 or older from emitting + * "include/config/auto.conf: No such file or directory" + * in the top-level Makefile + * + * syncconfig always creates or updates auto.conf because it is + * used during the build. + */ + if (conf_write_autoconf(sync_kconfig) && sync_kconfig) { + fprintf(stderr, + "\n*** Error during sync of the configuration.\n\n"); + return 1; + } } return 0; } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d587b10d7f8e..b7c9f1dd5e42 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -1,13 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
+#include <sys/mman.h> #include <sys/stat.h> +#include <sys/types.h> #include <ctype.h> #include <errno.h> #include <fcntl.h> +#include <limits.h> #include <stdarg.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -30,11 +34,57 @@ static bool is_dir(const char *path) struct stat st;
if (stat(path, &st)) - return 0; + return false;
return S_ISDIR(st.st_mode); }
+/* return true if the given two files are the same, false otherwise */ +static bool is_same(const char *file1, const char *file2) +{ + int fd1, fd2; + struct stat st1, st2; + void *map1, *map2; + bool ret = false; + + fd1 = open(file1, O_RDONLY); + if (fd1 < 0) + return ret; + + fd2 = open(file2, O_RDONLY); + if (fd2 < 0) + goto close1; + + ret = fstat(fd1, &st1); + if (ret) + goto close2; + ret = fstat(fd2, &st2); + if (ret) + goto close2; + + if (st1.st_size != st2.st_size) + goto close2; + + map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); + if (map1 == MAP_FAILED) + goto close2; + + map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); + if (map2 == MAP_FAILED) + goto close2; + + if (bcmp(map1, map2, st1.st_size)) + goto close2; + + ret = true; +close2: + close(fd2); +close1: + close(fd1); + + return ret; +} + /* * Create the parent directory of the given path. * @@ -74,10 +124,27 @@ static int make_parent_dir(const char *path) return 0; }
-struct conf_printer { - void (*print_symbol)(FILE *, struct symbol *, const char *, void *); - void (*print_comment)(FILE *, const char *, void *); -}; +static char depfile_path[PATH_MAX]; +static size_t depfile_prefix_len; + +/* touch depfile for symbol 'name' */ +static int conf_touch_dep(const char *name) +{ + int fd; + + /* check overflow: prefix + name + '\0' must fit in buffer. */ + if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) + return -1; + + strcpy(depfile_path + depfile_prefix_len, name); + + fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) + return -1; + close(fd); + + return 0; +}
static void conf_warning(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); @@ -88,8 +155,6 @@ static void conf_message(const char *fmt, ...) static const char *conf_filename; static int conf_lineno, conf_warnings;
-const char conf_defname[] = "arch/$(ARCH)/defconfig"; - static void conf_warning(const char *fmt, ...) { va_list ap; @@ -137,26 +202,25 @@ const char *conf_get_configname(void) return name ? name : ".config"; }
-const char *conf_get_autoconfig_name(void) +static const char *conf_get_autoconfig_name(void) { char *name = getenv("KCONFIG_AUTOCONFIG");
return name ? name : "include/config/auto.conf"; }
-char *conf_get_default_confname(void) +static const char *conf_get_autoheader_name(void) { - static char fullname[PATH_MAX+1]; - char *env, *name; - - name = expand_string(conf_defname); - env = getenv(SRCTREE); - if (env) { - sprintf(fullname, "%s/%s", env, name); - if (is_present(fullname)) - return fullname; - } - return name; + 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) @@ -186,29 +250,26 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) conf_warning("symbol value '%s' invalid for %s", p, sym->name); return 1; - case S_OTHER: - if (*p != '"') { - for (p2 = p; *p2 && !isspace(*p2); p2++) - ; - sym->type = S_STRING; - goto done; - } - /* fall through */ case S_STRING: - if (*p++ != '"') - break; - /* Last char has to be a '"' */ - if (p[strlen(p) - 1] != '"') { - if (def != S_DEF_AUTO) + /* 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)); + } + if (!p2) { conf_warning("invalid string found"); - return 1; + return 1; + } } - /* Overwrite '"' with \0 for string termination */ - p[strlen(p) - 1] = 0; /* fall through */ case S_INT: case S_HEX: - done: if (sym_string_valid(sym, p)) { sym->def[def].val = xstrdup(p); sym->flags |= def_flags; @@ -292,28 +353,46 @@ int conf_read_simple(const char *name, int def) if (name) { in = zconf_fopen(name); } else { - struct property *prop; + char *env;
name = conf_get_configname(); in = zconf_fopen(name); if (in) goto load; - sym_add_change_count(1); - if (!sym_defconfig_list) + conf_set_changed(true); + + env = getenv("KCONFIG_DEFCONFIG_LIST"); + if (!env) return 1;
- for_all_defaults(sym_defconfig_list, prop) { - if (expr_calc_value(prop->visible.expr) == no || - prop->expr->type != E_SYMBOL) - continue; - sym_calc_value(prop->expr->left.sym); - name = sym_get_string_value(prop->expr->left.sym); - in = zconf_fopen(name); + while (1) { + bool is_last; + + while (isspace(*env)) + env++; + + if (!*env) + break; + + p = env; + while (*p && !isspace(*p)) + p++; + + is_last = (*p == '\0'); + + *p = '\0'; + + in = zconf_fopen(env); if (in) { conf_message("using defaults found in %s", - name); + env); goto load; } + + if (is_last) + break; + + env = p + 1; } } if (!in) @@ -358,8 +437,8 @@ load: if (def == S_DEF_USER) { sym = sym_find(line + 2 + strlen(CONFIG_)); if (!sym) { - sym_add_change_count(1); - goto setsym; + conf_set_changed(true); + continue; } } else { sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); @@ -389,17 +468,22 @@ load: if (*p2 == '\r') *p2 = 0; } - if (def == S_DEF_USER) { - sym = sym_find(line + strlen(CONFIG_)); - if (!sym) { - sym_add_change_count(1); - goto setsym; - } - } else { - sym = sym_lookup(line + strlen(CONFIG_), 0); - if (sym->type == S_UNKNOWN) - sym->type = S_OTHER; + + sym = sym_find(line + strlen(CONFIG_)); + if (!sym) { + if (def == S_DEF_AUTO) + /* + * Reading from include/config/auto.conf + * If CONFIG_FOO previously existed in + * auto.conf but it is missing now, + * include/config/FOO must be touched. + */ + conf_touch_dep(line + strlen(CONFIG_)); + else + conf_set_changed(true); + continue; } + if (sym->flags & def_flags) { conf_warning("override: reassigning to symbol %s", sym->name); } @@ -412,7 +496,7 @@ load:
continue; } -setsym: + if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); switch (sym->def[def].tri) { @@ -444,7 +528,7 @@ int conf_read(const char *name) int conf_unsaved = 0; int i;
- sym_set_change_count(0); + conf_set_changed(false);
if (conf_read_simple(name, S_DEF_USER)) { sym_calc_value(modules_sym); @@ -462,11 +546,9 @@ int conf_read(const char *name) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) - break; - if (!sym_is_choice(sym)) + if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) continue; - /* fall through */ + break; default: if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) continue; @@ -504,196 +586,232 @@ int conf_read(const char *name) } }
- sym_add_change_count(conf_warnings || conf_unsaved); + if (conf_warnings || conf_unsaved) + conf_set_changed(true);
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;
- switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - if (*value == 'n') { - bool skip_unset = (arg != NULL); + fprintf(fp, "%s\n", cs->prefix);
- if (!skip_unset) - fprintf(fp, "# %s%s is not set\n", - CONFIG_, sym->name); - return; - } - break; - default: - break; - } + fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", + cs->decoration);
- fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value); + fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); + + fprintf(fp, "%s\n", cs->postfix); }
-static void -kconfig_print_comment(FILE *fp, const char *value, void *arg) +/* The returned pointer must be freed on the caller side */ +static char *escape_string_value(const char *in) { - const char *p = value; - size_t l; + const char *p; + char *out; + size_t len;
- for (;;) { - l = strcspn(p, "\n"); - fprintf(fp, "#"); - if (l) { - fprintf(fp, " "); - xfwrite(p, l, 1, fp); - p += l; - } - fprintf(fp, "\n"); - if (*p++ == '\0') + 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; }
-static struct conf_printer kconfig_printer_cb = +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) { - .print_symbol = kconfig_print_symbol, - .print_comment = kconfig_print_comment, -}; + const char *val; + char *escaped = NULL;
-/* - * 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) + 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: { - const char *suffix = ""; - - switch (*value) { + case S_TRISTATE: + switch (*val) { case 'n': - break; + return; case 'm': - suffix = "_MODULE"; + sym_suffix = "_MODULE"; /* fall through */ default: - fprintf(fp, "#define %s%s%s 1\n", - CONFIG_, sym->name, suffix); + val = "1"; } 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); + case S_HEX: + if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) + val_prefix = "0x"; break; - } case S_STRING: - case S_INT: - fprintf(fp, "#define %s%s %s\n", - CONFIG_, sym->name, value); - break; + escaped = escape_string_value(val); + val = escaped; default: break; }
-} + fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, + val_prefix, val);
-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; - } - fprintf(fp, " */\n"); + free(escaped); }
-static struct conf_printer header_printer_cb = -{ - .print_symbol = header_print_symbol, - .print_comment = header_print_comment, -}; - -/* - * Tristate printer - * - * This printer is used when generating the `include/config/tristate.conf' file. - */ -static void -tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) { + const char *val; + const char *val_prefix = ""; + char *val_prefixed = NULL; + size_t val_prefixed_len; + char *escaped = NULL;
- if (sym->type == S_TRISTATE && *value != 'n') - fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value)); -} - -static struct conf_printer tristate_printer_cb = -{ - .print_symbol = tristate_print_symbol, - .print_comment = kconfig_print_comment, -}; + if (sym->type == S_UNKNOWN) + return;
-static void conf_write_symbol(FILE *fp, struct symbol *sym, - struct conf_printer *printer, void *printer_arg) -{ - const char *str; - char *str2; + val = sym_get_string_value(sym);
switch (sym->type) { - case S_OTHER: - case S_UNKNOWN: + case S_BOOLEAN: + 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; + + /* + * 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_STRING: - str = sym_get_string_value(sym); - str2 = xmalloc(strlen(str) + 3); - sprintf(str2, ""%s"", str); - printer->print_symbol(fp, sym, str2, printer_arg); - free((void *)str2); + case S_HEX: + if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) + val_prefix = "0x"; break; default: - str = sym_get_string_value(sym); - printer->print_symbol(fp, sym, str, printer_arg); + break; } -}
-static void -conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg) -{ - char buf[256]; + 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; + }
- snprintf(buf, sizeof(buf), - "\n" - "Automatically generated file; DO NOT EDIT.\n" - "%s\n", - rootmenu.prompt->text); + /* All values get escaped: the `--cfg` option only takes strings */ + escaped = escape_string_value(val); + val = escaped;
- printer->print_comment(fp, buf, printer_arg); + fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); + + free(escaped); + free(val_prefixed); }
/* @@ -727,7 +845,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; sym->flags &= ~SYMBOL_WRITE; /* If we cannot change the symbol - skip */ - if (!sym_is_changable(sym)) + if (!sym_is_changeable(sym)) goto next_menu; /* If symbol equals to default value - skip */ if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) @@ -752,7 +870,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) { @@ -778,45 +896,41 @@ int conf_write(const char *name) FILE *out; struct symbol *sym; struct menu *menu; - const char *basename; const char *str; - char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; + char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; char *env; + int i; + bool need_newline = false; + + if (!name) + name = conf_get_configname(); + + if (!*name) { + fprintf(stderr, "config name is empty\n"); + return -1; + } + + if (is_dir(name)) { + fprintf(stderr, "%s: Is a directory\n", name); + return -1; + } + + if (make_parent_dir(name)) + return -1;
- dirname[0] = 0; - if (name && name[0]) { - char *slash; - - if (is_dir(name)) { - strcpy(dirname, name); - strcat(dirname, "/"); - basename = conf_get_configname(); - } else if ((slash = strrchr(name, '/'))) { - int size = slash - name + 1; - memcpy(dirname, name, size); - dirname[size] = 0; - if (slash[1]) - basename = slash + 1; - else - basename = conf_get_configname(); - } else - basename = name; - } else - basename = conf_get_configname(); - - sprintf(newname, "%s%s", dirname, basename); env = getenv("KCONFIG_OVERWRITECONFIG"); - if (!env || !*env) { - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(tmpname, "w"); - } else { + if (env && *env) { *tmpname = 0; - out = fopen(newname, "w"); + out = fopen(name, "w"); + } else { + snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", + name, (int)getpid()); + out = fopen(tmpname, "w"); } 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(); @@ -832,13 +946,18 @@ int conf_write(const char *name) "#\n" "# %s\n" "#\n", str); - } else if (!(sym->flags & SYMBOL_CHOICE)) { + need_newline = false; + } else if (!(sym->flags & SYMBOL_CHOICE) && + !(sym->flags & SYMBOL_WRITTEN)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) goto next; - sym->flags &= ~SYMBOL_WRITE; - - conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); + if (need_newline) { + fprintf(out, "\n"); + need_newline = false; + } + sym->flags |= SYMBOL_WRITTEN; + print_symbol_for_dotconfig(out, sym); }
next: @@ -846,82 +965,115 @@ 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->next) { - menu = menu->next; - break; - } + } else { + menu = menu->parent; + if (menu) + goto end_check; } } fclose(out);
+ for_all_symbols(i, sym) + sym->flags &= ~SYMBOL_WRITTEN; + if (*tmpname) { - strcat(dirname, basename); - strcat(dirname, ".old"); - rename(newname, dirname); - if (rename(tmpname, newname)) + if (is_same(name, tmpname)) { + conf_message("No change to %s", name); + unlink(tmpname); + conf_set_changed(false); + return 0; + } + + snprintf(oldname, sizeof(oldname), "%s.old", name); + rename(name, oldname); + if (rename(tmpname, name)) return 1; }
- conf_message("configuration written to %s", newname); + conf_message("configuration written to %s", name);
- sym_set_change_count(0); + conf_set_changed(false);
return 0; }
/* 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;
- if (!name) - name = ".kconfig.d"; - out = fopen("..config.tmp", "w"); - if (!out) - return 1; - fprintf(out, "deps_config := \\n"); - for (file = file_list; file; file = file->next) { - if (file->next) - fprintf(out, "\t%s \\n", file->name); - else - fprintf(out, "\t%s\n", file->name); + ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); + if (ret >= sizeof(name)) /* check truncation */ + return -1; + + if (make_parent_dir(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, "\n%s: \\n" - "\t$(deps_config)\n\n", conf_get_autoconfig_name());
- env_write_dep(out, conf_get_autoconfig_name()); + 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; + }
- if (make_parent_dir(name)) - return 1; - rename("..config.tmp", name); return 0; }
-static int conf_split_config(void) +static int conf_touch_deps(void) { - const char *name; - char path[PATH_MAX+1]; - char *s, *d, c; + const char *name, *tmp; struct symbol *sym; - int res, i, fd; + int res, i;
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);
- if (make_parent_dir("include/config/foo.h")) - return 1; - if (chdir("include/config")) - return 1; - - res = 0; for_all_symbols(i, sym) { sym_calc_value(sym); if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) @@ -973,146 +1125,116 @@ static int conf_split_config(void) * different from 'no'). */
- /* Replace all '_' and append ".h" */ - s = sym->name; - d = path; - while ((c = *s++)) { - c = tolower(c); - *d++ = (c == '_') ? '/' : c; - } - strcpy(d, ".h"); - - /* Assume directory path already exists. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - if (errno != ENOENT) { - res = 1; - break; - } - - if (make_parent_dir(path)) { - res = 1; - goto out; - } - - /* Try it again. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - res = 1; - break; - } - } - close(fd); + res = conf_touch_dep(sym->name); + if (res) + return res; } -out: - if (chdir("../..")) - return 1;
- return res; + return 0; }
-int conf_write_autoconf(void) +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; - const char *name; - FILE *out, *tristate, *out_h; - int i; - - sym_clear_all_valid(); + int ret, i;
- conf_write_dep("include/config/auto.conf.cmd"); - - if (conf_split_config()) - return 1; + if (make_parent_dir(filename)) + return -1;
- out = fopen(".tmpconfig", "w"); - if (!out) - return 1; + ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); + if (ret >= sizeof(tmp)) /* check truncation */ + return -1;
- tristate = fopen(".tmpconfig_tristate", "w"); - if (!tristate) { - fclose(out); - return 1; + file = fopen(tmp, "w"); + if (!file) { + perror("fopen"); + return -1; }
- out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) { - fclose(out); - fclose(tristate); - return 1; - } + conf_write_heading(file, comment_style);
- conf_write_heading(out, &kconfig_printer_cb, NULL); + for_all_symbols(i, sym) + if ((sym->flags & SYMBOL_WRITE) && sym->name) + print_symbol(file, sym);
- conf_write_heading(tristate, &tristate_printer_cb, NULL); + fflush(file); + /* check possible errors in conf_write_heading() and print_symbol() */ + ret = ferror(file); + fclose(file); + if (ret) + return -1;
- conf_write_heading(out_h, &header_printer_cb, NULL); + if (rename(tmp, filename)) { + perror("rename"); + return -1; + }
- for_all_symbols(i, sym) { - sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE) || !sym->name) - continue; + return 0; +}
- /* write symbol to auto.conf, tristate and header files */ - conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); +int conf_write_autoconf(int overwrite) +{ + struct symbol *sym; + const char *autoconf_name = conf_get_autoconfig_name(); + int ret, i;
- conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); + if (!overwrite && is_present(autoconf_name)) + return 0;
- conf_write_symbol(out_h, sym, &header_printer_cb, NULL); - } - fclose(out); - fclose(tristate); - fclose(out_h); + ret = conf_write_autoconf_cmd(autoconf_name); + if (ret) + return -1;
- name = getenv("KCONFIG_AUTOHEADER"); - if (!name) - name = "include/generated/autoconf.h"; - if (make_parent_dir(name)) - return 1; - if (rename(".tmpconfig.h", name)) + if (conf_touch_deps()) return 1;
- name = getenv("KCONFIG_TRISTATE"); - if (!name) - name = "include/config/tristate.conf"; - if (make_parent_dir(name)) - return 1; - if (rename(".tmpconfig_tristate", name)) - return 1; + for_all_symbols(i, sym) + sym_calc_value(sym); + + ret = __conf_write_autoconf(conf_get_autoheader_name(), + print_symbol_for_c, + &comment_style_c); + if (ret) + return ret; + + ret = __conf_write_autoconf(conf_get_rustccfg_name(), + print_symbol_for_rustccfg, + NULL); + if (ret) + return ret;
- name = conf_get_autoconfig_name(); - if (make_parent_dir(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", name)) - return 1; + ret = __conf_write_autoconf(conf_get_autoconfig_name(), + print_symbol_for_autoconf, + &comment_style_pound); + if (ret) + return ret;
return 0; }
-static int sym_change_count; +static bool conf_changed; static void (*conf_changed_callback)(void);
-void sym_set_change_count(int count) +void conf_set_changed(bool val) { - int _sym_change_count = sym_change_count; - sym_change_count = count; - if (conf_changed_callback && - (bool)_sym_change_count != (bool)count) + if (conf_changed_callback && conf_changed != val) conf_changed_callback(); -}
-void sym_add_change_count(int count) -{ - sym_set_change_count(count + sym_change_count); + conf_changed = val; }
bool conf_get_changed(void) { - return sym_change_count; + return conf_changed; }
void conf_set_changed_callback(void (*fn)(void)) @@ -1120,54 +1242,6 @@ void conf_set_changed_callback(void (*fn)(void)) conf_changed_callback = fn; }
-static bool randomize_choice_values(struct symbol *csym) -{ - struct property *prop; - struct symbol *sym; - struct expr *e; - int cnt, def; - - /* - * If choice is mod then we may have more items selected - * and if no then no-one. - * In both cases stop. - */ - if (csym->curr.tri != yes) - return false; - - prop = sym_get_choice_prop(csym); - - /* count entries in choice block */ - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) - cnt++; - - /* - * find a random value and set it to yes, - * set the rest to no so we have only one set - */ - def = (rand() % cnt); - - cnt = 0; - expr_list_for_each_sym(prop->expr, e, sym) { - if (def == cnt++) { - sym->def[S_DEF_USER].tri = yes; - csym->def[S_DEF_USER].val = sym; - } - else { - sym->def[S_DEF_USER].tri = no; - } - sym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - sym->flags &= ~SYMBOL_VALID; - } - csym->flags |= SYMBOL_DEF_USER; - /* clear VALID to get value calculated */ - csym->flags &= ~(SYMBOL_VALID); - - return true; -} - void set_all_choice_values(struct symbol *csym) { struct property *prop; @@ -1187,131 +1261,3 @@ void set_all_choice_values(struct symbol *csym) /* clear VALID to get value calculated */ csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); } - -bool conf_set_all_new_symbols(enum conf_def_mode mode) -{ - struct symbol *sym, *csym; - int i, cnt, pby, pty, ptm; /* pby: probability of bool = y - * pty: probability of tristate = y - * ptm: probability of tristate = m - */ - - pby = 50; pty = ptm = 33; /* can't go as the default in switch-case - * below, otherwise gcc whines about - * -Wmaybe-uninitialized */ - if (mode == def_random) { - int n, p[3]; - char *env = getenv("KCONFIG_PROBABILITY"); - n = 0; - while( env && *env ) { - char *endp; - int tmp = strtol( env, &endp, 10 ); - if( tmp >= 0 && tmp <= 100 ) { - p[n++] = tmp; - } else { - errno = ERANGE; - perror( "KCONFIG_PROBABILITY" ); - exit( 1 ); - } - env = (*endp == ':') ? endp+1 : endp; - if( n >=3 ) { - break; - } - } - switch( n ) { - case 1: - pby = p[0]; ptm = pby/2; pty = pby-ptm; - break; - case 2: - pty = p[0]; ptm = p[1]; pby = pty + ptm; - break; - case 3: - pby = p[0]; pty = p[1]; ptm = p[2]; - break; - } - - if( pty+ptm > 100 ) { - errno = ERANGE; - perror( "KCONFIG_PROBABILITY" ); - exit( 1 ); - } - } - bool has_changed = false; - - for_all_symbols(i, sym) { - if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) - continue; - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - has_changed = true; - switch (mode) { - case def_yes: - sym->def[S_DEF_USER].tri = yes; - break; - case def_mod: - sym->def[S_DEF_USER].tri = mod; - break; - case def_no: - if (sym->flags & SYMBOL_ALLNOCONFIG_Y) - sym->def[S_DEF_USER].tri = yes; - else - sym->def[S_DEF_USER].tri = no; - break; - case def_random: - sym->def[S_DEF_USER].tri = no; - cnt = rand() % 100; - if (sym->type == S_TRISTATE) { - if (cnt < pty) - sym->def[S_DEF_USER].tri = yes; - else if (cnt < (pty+ptm)) - sym->def[S_DEF_USER].tri = mod; - } else if (cnt < pby) - sym->def[S_DEF_USER].tri = yes; - break; - default: - continue; - } - if (!(sym_is_choice(sym) && mode == def_random)) - sym->flags |= SYMBOL_DEF_USER; - break; - default: - break; - } - - } - - sym_clear_all_valid(); - - /* - * We have different type of choice blocks. - * If curr.tri equals to mod then we can select several - * choice symbols in one block. - * In this case we do nothing. - * If curr.tri equals yes then only one symbol can be - * selected in a choice block and we set it to yes, - * and the rest to no. - */ - if (mode != def_random) { - for_all_symbols(i, csym) { - if ((sym_is_choice(csym) && !sym_has_value(csym)) || - sym_is_choice_value(csym)) - csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; - } - } - - for_all_symbols(i, csym) { - if (sym_has_value(csym) || !sym_is_choice(csym)) - continue; - - sym_calc_value(csym); - if (mode == def_random) - has_changed = randomize_choice_values(csym); - else { - set_all_choice_values(csym); - has_changed = true; - } - } - - return has_changed; -} diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 9f79bdfaaa5d..81ebf8108ca7 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1,8 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
+#include <ctype.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -11,7 +13,6 @@
#define DEBUG_EXPR 0
-static int expr_eq(struct expr *e1, struct expr *e2); static struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_alloc_symbol(struct symbol *sym) @@ -248,10 +249,17 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) * equals some operand in the other (operands do not need to appear in the same * order), recursively. */ -static int expr_eq(struct expr *e1, struct expr *e2) +int expr_eq(struct expr *e1, struct expr *e2) { int res, old_count;
+ /* + * A NULL expr is taken to be yes, but there's also a different way to + * represent yes. expr_is_yes() checks for either representation. + */ + if (!e1 || !e2) + return expr_is_yes(e1) && expr_is_yes(e2); + if (e1->type != e2->type) return 0; switch (e1->type) { @@ -894,7 +902,7 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym) default: ; } - return false; + return false; }
/* @@ -980,7 +988,6 @@ enum string_value_kind { k_string, k_signed, k_unsigned, - k_invalid };
union string_value { @@ -1011,13 +1018,10 @@ static enum string_value_kind expr_parse_string(const char *str, val->u = strtoull(str, &tail, 16); kind = k_unsigned; break; - case S_STRING: - case S_UNKNOWN: + default: val->s = strtoll(str, &tail, 0); kind = k_signed; break; - default: - return k_invalid; } return !errno && !*tail && tail > str && isxdigit(tail[-1]) ? kind : k_string; @@ -1073,13 +1077,7 @@ tristate expr_calc_value(struct expr *e)
if (k1 == k_string || k2 == k_string) res = strcmp(str1, str2); - else if (k1 == k_invalid || k2 == k_invalid) { - if (e->type != E_EQUAL && e->type != E_UNEQUAL) { - printf("Cannot compare "%s" and "%s"\n", str1, str2); - return no; - } - res = strcmp(str1, str2); - } else if (k1 == k_unsigned || k2 == k_unsigned) + else if (k1 == k_unsigned || k2 == k_unsigned) res = (lval.u > rval.u) - (lval.u < rval.u); else /* if (k1 == k_signed && k2 == k_signed) */ res = (lval.s > rval.s) - (lval.s < rval.s); diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 7c329e179007..9c9caca5bd5f 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -1,6 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
#ifndef EXPR_H @@ -62,7 +62,7 @@ struct symbol_value { };
enum symbol_type { - S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER + S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING };
/* enum values are used as index to symbol.def[] */ @@ -131,7 +131,7 @@ struct symbol { struct expr_value implied; };
-#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) +#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next)
#define SYMBOL_CONST 0x0001 /* symbol is const */ #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ @@ -141,6 +141,7 @@ struct symbol { #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_CHANGED 0x0400 /* ? */ +#define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */ #define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */ #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ #define SYMBOL_WARNED 0x8000 /* warning has been issued */ @@ -155,9 +156,6 @@ struct symbol { /* choice values need to be set before calculating this symbol value */ #define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
-/* Set symbol to y if allnoconfig; used for symbols that hide others */ -#define SYMBOL_ALLNOCONFIG_Y 0x200000 - #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 9973
@@ -172,7 +170,7 @@ struct symbol { * int "BAZ Value" * range 1..255 * - * Please, also check zconf.y:print_symbol() when modifying the + * Please, also check parser.y:print_symbol() when modifying the * list of property types! */ enum prop_type { @@ -190,7 +188,6 @@ enum prop_type {
struct property { struct property *next; /* next property - null if last */ - struct symbol *sym; /* the symbol for which the property is associated */ enum prop_type type; /* type of property */ const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ struct expr_value visible; @@ -281,15 +278,12 @@ struct jump_key { int index; };
-#define JUMP_NB 9 - extern struct file *file_list; extern struct file *current_file; struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol *modules_sym; -extern struct symbol *sym_defconfig_list; extern int cdebug; struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); @@ -300,6 +294,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); struct expr *expr_copy(const struct expr *org); void expr_free(struct expr *e); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); +int expr_eq(struct expr *e1, struct expr *e2); tristate expr_calc_value(struct expr *e); struct expr *expr_trans_bool(struct expr *e); struct expr *expr_eliminate_dups(struct expr *e); diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh index 480ecd8b9f41..040d8f338820 100755 --- a/scripts/kconfig/gconf-cfg.sh +++ b/scripts/kconfig/gconf-cfg.sh @@ -1,16 +1,19 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0
+cflags=$1 +libs=$2 + PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
-if [ -z "$(command -v pkg-config)" ]; then +if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then echo >&2 "*" - echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it." + echo >&2 "* 'make gconfig' requires '${HOSTPKG_CONFIG}'. Please install it." echo >&2 "*" exit 1 fi
-if ! pkg-config --exists $PKG; then +if ! ${HOSTPKG_CONFIG} --exists $PKG; then echo >&2 "*" echo >&2 "* Unable to find the GTK+ installation. Please make sure that" echo >&2 "* the GTK+ 2.0 development package is correctly installed." @@ -19,12 +22,12 @@ if ! pkg-config --exists $PKG; then exit 1 fi
-if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then +if ! ${HOSTPKG_CONFIG} --atleast-version=2.0.0 gtk+-2.0; then echo >&2 "*" echo >&2 "* GTK+ is present but version >= 2.0.0 is required." echo >&2 "*" exit 1 fi
-echo cflags="$(pkg-config --cflags $PKG)" -echo libs="$(pkg-config --libs $PKG)" +${HOSTPKG_CONFIG} --cflags ${PKG} > ${cflags} +${HOSTPKG_CONFIG} --libs ${PKG} > ${libs} diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 2ec7419301de..17adabfd6e6b 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -1,18 +1,11 @@ -/* Hey EMACS -*- linux-c -*- */ +// SPDX-License-Identifier: GPL-2.0 /* - * * Copyright (C) 2002-2003 Romain Lievin roms@tilp.info - * Released under the terms of the GNU GPL v2.0. - * */
-#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <stdlib.h> #include "lkc.h" -#include "images.c" +#include "images.h"
#include <glade/glade.h> #include <gtk/gtk.h> @@ -21,6 +14,7 @@
#include <stdio.h> #include <string.h> +#include <strings.h> #include <unistd.h> #include <time.h>
@@ -78,8 +72,8 @@ static gchar **fill_row(struct menu *menu); static void conf_changed(void);
/* Helping/Debugging Functions */ - -const char *dbg_sym_flags(int val) +#ifdef DEBUG +static const char *dbg_sym_flags(int val) { static char buf[256];
@@ -108,9 +102,10 @@ const char *dbg_sym_flags(int val)
return buf; } +#endif
-void replace_button_icon(GladeXML * xml, GdkDrawable * window, - GtkStyle * style, gchar * btn_name, gchar ** xpm) +static void replace_button_icon(GladeXML *xml, GdkDrawable *window, + GtkStyle *style, gchar *btn_name, gchar **xpm) { GdkPixmap *pixmap; GdkBitmap *mask; @@ -128,7 +123,7 @@ void replace_button_icon(GladeXML * xml, GdkDrawable * window, }
/* Main Window Initialization */ -void init_main_window(const gchar * glade_file) +static void init_main_window(const gchar *glade_file) { GladeXML *xml; GtkWidget *widget; @@ -190,7 +185,7 @@ void init_main_window(const gchar * glade_file) gtk_widget_show(main_wnd); }
-void init_tree_model(void) +static void init_tree_model(void) { gint i;
@@ -220,7 +215,7 @@ void init_tree_model(void) model1 = GTK_TREE_MODEL(tree1); }
-void init_left_tree(void) +static void init_left_tree(void) { GtkTreeView *view = GTK_TREE_VIEW(tree1_w); GtkCellRenderer *renderer; @@ -262,7 +257,7 @@ static void renderer_edited(GtkCellRendererText * cell, const gchar * path_string, const gchar * new_text, gpointer user_data);
-void init_right_tree(void) +static void init_right_tree(void) { GtkTreeView *view = GTK_TREE_VIEW(tree2_w); GtkCellRenderer *renderer; @@ -525,6 +520,7 @@ void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) { if (conf_write(NULL)) text_insert_msg("Error", "Unable to save configuration !"); + conf_write_autoconf(0); }
@@ -1048,8 +1044,13 @@ static gchar **fill_row(struct menu *menu) g_free(row[i]); bzero(row, sizeof(row));
+ ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + row[COL_OPTION] = - g_strdup_printf("%s %s", menu_get_prompt(menu), + g_strdup_printf("%s %s %s %s", + ptype == P_COMMENT ? "***" : "", + menu_get_prompt(menu), + ptype == P_COMMENT ? "***" : "", sym && !sym_has_value(sym) ? "(NEW)" : "");
if (opt_mode == OPT_ALL && !menu_is_visible(menu)) @@ -1060,7 +1061,6 @@ static gchar **fill_row(struct menu *menu) else row[COL_COLOR] = g_strdup("Black");
- ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; switch (ptype) { case P_MENU: row[COL_PIXBUF] = (gchar *) xpm_menu; @@ -1211,8 +1211,8 @@ static GtkTreeIter found; /* * Find a menu in the GtkTree starting at parent. */ -GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, - struct menu *tofind) +static GtkTreeIter *gtktree_iter_find_node(GtkTreeIter *parent, + struct menu *tofind) { GtkTreeIter iter; GtkTreeIter *child = &iter; @@ -1423,7 +1423,7 @@ static void display_list(void) tree = tree2; }
-void fixup_rootmenu(struct menu *menu) +static void fixup_rootmenu(struct menu *menu) { struct menu *child; static int menu_cnt = 0; @@ -1452,9 +1452,6 @@ int main(int ac, char *av[]) gtk_init(&ac, &av); glade_init();
- //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); - //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); - /* Determine GUI path */ env = getenv(SRCTREE); if (env) diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c index d4f84bd4a96b..2f9afffa5d79 100644 --- a/scripts/kconfig/images.c +++ b/scripts/kconfig/images.c @@ -1,9 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
-static const char *xpm_load[] = { +#include "images.h" + +const char * const xpm_load[] = { "22 22 5 1", ". c None", "# c #000000", @@ -33,7 +35,7 @@ static const char *xpm_load[] = { "###############.......", "......................"};
-static const char *xpm_save[] = { +const char * const xpm_save[] = { "22 22 5 1", ". c None", "# c #000000", @@ -63,7 +65,7 @@ static const char *xpm_save[] = { "..##################..", "......................"};
-static const char *xpm_back[] = { +const char * const xpm_back[] = { "22 22 3 1", ". c None", "# c #000083", @@ -91,7 +93,7 @@ static const char *xpm_back[] = { "......................", "......................"};
-static const char *xpm_tree_view[] = { +const char * const xpm_tree_view[] = { "22 22 2 1", ". c None", "# c #000000", @@ -118,7 +120,7 @@ static const char *xpm_tree_view[] = { "......................", "......................"};
-static const char *xpm_single_view[] = { +const char * const xpm_single_view[] = { "22 22 2 1", ". c None", "# c #000000", @@ -145,7 +147,7 @@ static const char *xpm_single_view[] = { "......................", "......................"};
-static const char *xpm_split_view[] = { +const char * const xpm_split_view[] = { "22 22 2 1", ". c None", "# c #000000", @@ -172,7 +174,7 @@ static const char *xpm_split_view[] = { "......................", "......................"};
-static const char *xpm_symbol_no[] = { +const char * const xpm_symbol_no[] = { "12 12 2 1", " c white", ". c black", @@ -189,7 +191,7 @@ static const char *xpm_symbol_no[] = { " .......... ", " "};
-static const char *xpm_symbol_mod[] = { +const char * const xpm_symbol_mod[] = { "12 12 2 1", " c white", ". c black", @@ -206,7 +208,7 @@ static const char *xpm_symbol_mod[] = { " .......... ", " "};
-static const char *xpm_symbol_yes[] = { +const char * const xpm_symbol_yes[] = { "12 12 2 1", " c white", ". c black", @@ -223,7 +225,7 @@ static const char *xpm_symbol_yes[] = { " .......... ", " "};
-static const char *xpm_choice_no[] = { +const char * const xpm_choice_no[] = { "12 12 2 1", " c white", ". c black", @@ -240,7 +242,7 @@ static const char *xpm_choice_no[] = { " .... ", " "};
-static const char *xpm_choice_yes[] = { +const char * const xpm_choice_yes[] = { "12 12 2 1", " c white", ". c black", @@ -257,7 +259,7 @@ static const char *xpm_choice_yes[] = { " .... ", " "};
-static const char *xpm_menu[] = { +const char * const xpm_menu[] = { "12 12 2 1", " c white", ". c black", @@ -274,7 +276,7 @@ static const char *xpm_menu[] = { " .......... ", " "};
-static const char *xpm_menu_inv[] = { +const char * const xpm_menu_inv[] = { "12 12 2 1", " c white", ". c black", @@ -291,7 +293,7 @@ static const char *xpm_menu_inv[] = { " .......... ", " "};
-static const char *xpm_menuback[] = { +const char * const xpm_menuback[] = { "12 12 2 1", " c white", ". c black", @@ -308,7 +310,7 @@ static const char *xpm_menuback[] = { " .......... ", " "};
-static const char *xpm_void[] = { +const char * const xpm_void[] = { "12 12 2 1", " c white", ". c black", diff --git a/scripts/kconfig/images.h b/scripts/kconfig/images.h new file mode 100644 index 000000000000..7212dec2006c --- /dev/null +++ b/scripts/kconfig/images.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org + */ + +#ifndef IMAGES_H +#define IMAGES_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char * const xpm_load[]; +extern const char * const xpm_save[]; +extern const char * const xpm_back[]; +extern const char * const xpm_tree_view[]; +extern const char * const xpm_single_view[]; +extern const char * const xpm_split_view[]; +extern const char * const xpm_symbol_no[]; +extern const char * const xpm_symbol_mod[]; +extern const char * const xpm_symbol_yes[]; +extern const char * const xpm_choice_no[]; +extern const char * const xpm_choice_yes[]; +extern const char * const xpm_menu[]; +extern const char * const xpm_menu_inv[]; +extern const char * const xpm_menuback[]; +extern const char * const xpm_void[]; + +#ifdef __cplusplus +} +#endif + +#endif /* IMAGES_H */ diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h new file mode 100644 index 000000000000..2f7298c21b64 --- /dev/null +++ b/scripts/kconfig/internal.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef INTERNAL_H +#define INTERNAL_H + +struct menu; + +extern struct menu *current_menu, *current_entry; + +#endif /* INTERNAL_H */ diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c deleted file mode 100644 index b3e0ea0ac732..000000000000 --- a/scripts/kconfig/kconf_id.c +++ /dev/null @@ -1,52 +0,0 @@ - -static struct kconf_id kconf_id_array[] = { - { "mainmenu", T_MAINMENU, TF_COMMAND }, - { "menu", T_MENU, TF_COMMAND }, - { "endmenu", T_ENDMENU, TF_COMMAND }, - { "source", T_SOURCE, TF_COMMAND }, - { "choice", T_CHOICE, TF_COMMAND }, - { "endchoice", T_ENDCHOICE, TF_COMMAND }, - { "comment", T_COMMENT, TF_COMMAND }, - { "config", T_CONFIG, TF_COMMAND }, - { "menuconfig", T_MENUCONFIG, TF_COMMAND }, - { "help", T_HELP, TF_COMMAND }, - { "---help---", T_HELP, TF_COMMAND }, - { "if", T_IF, TF_COMMAND|TF_PARAM }, - { "endif", T_ENDIF, TF_COMMAND }, - { "depends", T_DEPENDS, TF_COMMAND }, - { "optional", T_OPTIONAL, TF_COMMAND }, - { "default", T_DEFAULT, TF_COMMAND, S_UNKNOWN }, - { "prompt", T_PROMPT, TF_COMMAND }, - { "tristate", T_TYPE, TF_COMMAND, S_TRISTATE }, - { "def_tristate", T_DEFAULT, TF_COMMAND, S_TRISTATE }, - { "bool", T_TYPE, TF_COMMAND, S_BOOLEAN }, - { "def_bool", T_DEFAULT, TF_COMMAND, S_BOOLEAN }, - { "int", T_TYPE, TF_COMMAND, S_INT }, - { "hex", T_TYPE, TF_COMMAND, S_HEX }, - { "string", T_TYPE, TF_COMMAND, S_STRING }, - { "select", T_SELECT, TF_COMMAND }, - { "imply", T_IMPLY, TF_COMMAND }, - { "range", T_RANGE, TF_COMMAND }, - { "visible", T_VISIBLE, TF_COMMAND }, - { "option", T_OPTION, TF_COMMAND }, - { "on", T_ON, TF_PARAM }, - { "modules", T_OPT_MODULES, TF_OPTION }, - { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, - { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, -}; - -#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id)) - -static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len) -{ - int i; - - for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) { - struct kconf_id *id = kconf_id_array+i; - int l = strlen(id->name); - - if (len == l && !memcmp(str, id->name, len)) - return id; - } - return NULL; -} diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/lexer.l similarity index 67% rename from scripts/kconfig/zconf.l rename to scripts/kconfig/lexer.l index 25bd2b89fe3f..cc386e443683 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/lexer.l @@ -1,20 +1,22 @@ -%option nostdinit noyywrap never-interactive full ecs -%option 8bit nodefault yylineno -%x COMMAND HELP STRING PARAM ASSIGN_VAL -%{ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */ +%option nostdinit noyywrap never-interactive full ecs +%option 8bit nodefault yylineno +%x ASSIGN_VAL HELP STRING +%{
#include <assert.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h>
#include "lkc.h" +#include "parser.tab.h" + +#define YY_DECL static int yylex1(void)
#define START_STRSIZE 16
@@ -23,6 +25,8 @@ static struct { int lineno; } current_pos;
+static int prev_prev_token = T_EOL; +static int prev_token = T_EOL; static char *text; static int text_size, text_asize;
@@ -31,7 +35,7 @@ struct buffer { YY_BUFFER_STATE state; };
-struct buffer *current_buf; +static struct buffer *current_buf;
static int last_ts, first_ts;
@@ -73,64 +77,79 @@ static void warn_ignored_character(char chr) { fprintf(stderr, "%s:%d:warning: ignoring unsupported character '%c'\n", - zconf_curname(), zconf_lineno(), chr); + current_file->name, yylineno, chr); } %}
n [A-Za-z0-9_-]
%% - int str = 0; - int ts, i; - -[ \t]*#.*\n | -[ \t]*\n { - return T_EOL; -} -[ \t]*#.* - - -[ \t]+ { - BEGIN(COMMAND); -} - -. { - unput(yytext[0]); - BEGIN(COMMAND); -} - - -<COMMAND>{ - {n}+ { - const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - current_pos.file = current_file; - current_pos.lineno = yylineno; - if (id && id->flags & TF_COMMAND) { - BEGIN(PARAM); - yylval.id = id; - return id->token; - } - alloc_string(yytext, yyleng); - yylval.string = text; - return T_VARIABLE; - } - ({n}|$)+ { - /* this token includes at least one '$' */ - yylval.string = expand_token(yytext, yyleng); - if (strlen(yylval.string)) - return T_VARIABLE; - free(yylval.string); - } - "=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; } - ":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; } - "+=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; } - [[:blank:]]+ - . warn_ignored_character(*yytext); - \n { - BEGIN(INITIAL); - return T_EOL; - } -} + char open_quote = 0; + +#.* /* ignore comment */ +[ \t]* /* whitespaces */ +\\n /* escaped new line */ +\n return T_EOL; +"bool" return T_BOOL; +"choice" return T_CHOICE; +"comment" return T_COMMENT; +"config" return T_CONFIG; +"def_bool" return T_DEF_BOOL; +"def_tristate" return T_DEF_TRISTATE; +"default" return T_DEFAULT; +"depends" return T_DEPENDS; +"endchoice" return T_ENDCHOICE; +"endif" return T_ENDIF; +"endmenu" return T_ENDMENU; +"help" return T_HELP; +"hex" return T_HEX; +"if" return T_IF; +"imply" return T_IMPLY; +"int" return T_INT; +"mainmenu" return T_MAINMENU; +"menu" return T_MENU; +"menuconfig" return T_MENUCONFIG; +"modules" return T_MODULES; +"on" return T_ON; +"optional" return T_OPTIONAL; +"prompt" return T_PROMPT; +"range" return T_RANGE; +"select" return T_SELECT; +"source" return T_SOURCE; +"string" return T_STRING; +"tristate" return T_TRISTATE; +"visible" return T_VISIBLE; +"||" return T_OR; +"&&" return T_AND; +"=" return T_EQUAL; +"!=" return T_UNEQUAL; +"<" return T_LESS; +"<=" return T_LESS_EQUAL; +">" return T_GREATER; +">=" return T_GREATER_EQUAL; +"!" return T_NOT; +"(" return T_OPEN_PAREN; +")" return T_CLOSE_PAREN; +":=" return T_COLON_EQUAL; +"+=" return T_PLUS_EQUAL; +"|' { + open_quote = yytext[0]; + new_string(); + BEGIN(STRING); + } +{n}+ { + alloc_string(yytext, yyleng); + yylval.string = text; + return T_WORD; + } +({n}|$)+ { + /* this token includes at least one '$' */ + yylval.string = expand_token(yytext, yyleng); + if (strlen(yylval.string)) + return T_WORD; + free(yylval.string); + } +. warn_ignored_character(*yytext);
<ASSIGN_VAL>{ [^[:blank:]\n]+.* { @@ -142,71 +161,17 @@ n [A-Za-z0-9_-] . }
-<PARAM>{ - "&&" return T_AND; - "||" return T_OR; - "(" return T_OPEN_PAREN; - ")" return T_CLOSE_PAREN; - "!" return T_NOT; - "=" return T_EQUAL; - "!=" return T_UNEQUAL; - "<=" return T_LESS_EQUAL; - ">=" return T_GREATER_EQUAL; - "<" return T_LESS; - ">" return T_GREATER; - "|' { - str = yytext[0]; - new_string(); - BEGIN(STRING); - } - \n BEGIN(INITIAL); return T_EOL; - ({n}|[/.])+ { - const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); - if (id && id->flags & TF_PARAM) { - yylval.id = id; - return id->token; - } - alloc_string(yytext, yyleng); - yylval.string = text; - return T_WORD; - } - ({n}|[/.$])+ { - /* this token includes at least one '$' */ - yylval.string = expand_token(yytext, yyleng); - if (strlen(yylval.string)) - return T_WORD; - free(yylval.string); - } - #.* /* comment */ - \\n ; - [[:blank:]]+ - . warn_ignored_character(*yytext); - <<EOF>> { - BEGIN(INITIAL); - } -} - <STRING>{ "$".* append_expanded_string(yytext); - [^$'"\\n]+/\n { - append_string(yytext, yyleng); - yylval.string = text; - return T_WORD_QUOTE; - } [^$'"\\n]+ { append_string(yytext, yyleng); } - \.?/\n { - append_string(yytext + 1, yyleng - 1); - yylval.string = text; - return T_WORD_QUOTE; - } \.? { append_string(yytext + 1, yyleng - 1); } '|" { - if (str == yytext[0]) { - BEGIN(PARAM); + if (open_quote == yytext[0]) { + BEGIN(INITIAL); yylval.string = text; return T_WORD_QUOTE; } else @@ -216,16 +181,22 @@ n [A-Za-z0-9_-] fprintf(stderr, "%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + unput('\n'); BEGIN(INITIAL); - return T_EOL; + yylval.string = text; + return T_WORD_QUOTE; } <<EOF>> { BEGIN(INITIAL); + yylval.string = text; + return T_WORD_QUOTE; } }
<HELP>{ [ \t]+ { + int ts, i; + ts = 0; for (i = 0; i < yyleng; i++) { if (yytext[i] == '\t') @@ -271,6 +242,12 @@ n [A-Za-z0-9_-] }
<<EOF>> { + BEGIN(INITIAL); + + if (prev_token != T_EOL && prev_token != T_HELPTEXT) + fprintf(stderr, "%s:%d:warning: no new line at end of file\n", + current_file->name, yylineno); + if (current_file) { zconf_endfile(); return T_EOL; @@ -280,6 +257,41 @@ n [A-Za-z0-9_-] }
%% + +/* second stage lexer */ +int yylex(void) +{ + int token; + +repeat: + token = yylex1(); + + if (prev_token == T_EOL || prev_token == T_HELPTEXT) { + if (token == T_EOL) { + /* Do not pass unneeded T_EOL to the parser. */ + goto repeat; + } else { + /* + * For the parser, update file/lineno at the first token + * of each statement. Generally, \n is a statement + * terminator in Kconfig, but it is not always true + * because \n could be escaped by a backslash. + */ + current_pos.file = current_file; + current_pos.lineno = yylineno; + } + } + + if (prev_prev_token == T_EOL && prev_token == T_WORD && + (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL)) + BEGIN(ASSIGN_VAL); + + prev_prev_token = prev_token; + prev_token = token; + + return token; +} + static char *expand_token(const char *in, size_t n) { char *out; @@ -363,7 +375,8 @@ FILE *zconf_fopen(const char *name) if (!f && name != NULL && name[0] != '/') { env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), + "%s/%s", env, name); f = fopen(fullname, "r"); } } diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h index 06e8d555d8b0..45cb237ab7ef 100644 --- a/scripts/kconfig/list.h +++ b/scripts/kconfig/list.h @@ -48,7 +48,7 @@ struct list_head { */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member))
/** diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 9eb7c837cd8f..e7118d62a45f 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -1,11 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
#ifndef LKC_H #define LKC_H
+#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + #include "expr.h"
#ifdef __cplusplus @@ -16,10 +20,6 @@ extern "C" {
#define SRCTREE "srctree"
-#ifndef PACKAGE -#define PACKAGE "linux" -#endif - #ifndef CONFIG_ #define CONFIG_ "CONFIG_" #endif @@ -30,29 +30,6 @@ static inline const char *CONFIG_prefix(void) #undef CONFIG_ #define CONFIG_ CONFIG_prefix()
-#define TF_COMMAND 0x0001 -#define TF_PARAM 0x0002 -#define TF_OPTION 0x0004 - -enum conf_def_mode { - def_default, - def_yes, - def_mod, - def_no, - def_random -}; - -#define T_OPT_MODULES 1 -#define T_OPT_DEFCONFIG_LIST 2 -#define T_OPT_ALLNOCONFIG_Y 4 - -struct kconf_id { - const char *name; - int token; - unsigned int flags; - enum symbol_type stype; -}; - extern int yylineno; void zconfdump(FILE *out); void zconf_starthelp(void); @@ -64,11 +41,6 @@ const char *zconf_curname(void);
/* confdata.c */ const char *conf_get_configname(void); -const char *conf_get_autoconfig_name(void); -char *conf_get_default_confname(void); -void sym_set_change_count(int count); -void sym_add_change_count(int count); -bool conf_set_all_new_symbols(enum conf_def_mode mode); void set_all_choice_values(struct symbol *csym);
/* confdata.c and expr.c */ @@ -80,21 +52,6 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) fprintf(stderr, "Error in writing or end of file.\n"); }
-/* menu.c */ -void _menu_init(void); -void menu_warn(struct menu *menu, const char *fmt, ...); -struct menu *menu_add_menu(void); -void menu_end_menu(void); -void menu_add_entry(struct symbol *sym); -void menu_add_dep(struct expr *dep); -void menu_add_visibility(struct expr *dep); -struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); -void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); -void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); -void menu_add_option(int token, char *arg); -void menu_finalize(struct menu *parent); -void menu_set_type(int type); - /* util.c */ struct file *file_lookup(const char *name); void *xmalloc(size_t size); @@ -103,6 +60,9 @@ void *xrealloc(void *p, size_t size); char *xstrdup(const char *s); char *xstrndup(const char *s, size_t n);
+/* lexer.l */ +int yylex(void); + struct gstr { size_t len; char *s; @@ -116,14 +76,40 @@ 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); +void menu_warn(struct menu *menu, const char *fmt, ...); +struct menu *menu_add_menu(void); +void menu_end_menu(void); +void menu_add_entry(struct symbol *sym); +void menu_add_dep(struct expr *dep); +void menu_add_visibility(struct expr *dep); +struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); +void menu_finalize(struct menu *parent); +void menu_set_type(int type); + +extern struct menu rootmenu; + +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_parent_menu(struct menu *menu); +bool menu_has_help(struct menu *menu); +const char *menu_get_help(struct menu *menu); +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); +void menu_get_ext_help(struct menu *menu, struct gstr *help);
/* symbol.c */ void sym_clear_all_valid(void); struct symbol *sym_choice_default(struct symbol *sym); +struct property *sym_get_range_prop(struct symbol *sym); const char *sym_get_string_default(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); -struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct symbol *prop_get_symbol(struct property *prop);
static inline tristate sym_get_tristate_value(struct symbol *sym) @@ -137,11 +123,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; diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index cf4510a2bdc7..edd1e617b25c 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -7,31 +7,18 @@ int conf_read(const char *name); int conf_read_simple(const char *name, int); int conf_write_defconfig(const char *name); int conf_write(const char *name); -int conf_write_autoconf(void); +int conf_write_autoconf(int overwrite); +void conf_set_changed(bool val); bool conf_get_changed(void); void conf_set_changed_callback(void (*fn)(void)); void conf_set_message_callback(void (*fn)(const char *s));
-/* menu.c */ -extern struct menu rootmenu; - -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); -struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); -void menu_get_ext_help(struct menu *menu, struct gstr *help); - /* symbol.c */ 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); @@ -42,7 +29,7 @@ tristate sym_toggle_tristate_value(struct symbol *sym); bool sym_string_valid(struct symbol *sym, const char *newval); bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); -bool sym_is_changable(struct symbol *sym); +bool sym_is_changeable(struct symbol *sym); struct property * sym_get_choice_prop(struct symbol *sym); const char * sym_get_string_value(struct symbol *sym);
@@ -58,7 +45,6 @@ void env_write_dep(FILE *f, const char *auto_conf_name); void variable_add(const char *name, const char *value, enum variable_flavor flavor); void variable_all_del(void); -char *expand_string(const char *in); char *expand_dollar(const char **str); char *expand_one_token(const char **str);
diff --git a/scripts/kconfig/lxdialog/.gitignore b/scripts/kconfig/lxdialog/.gitignore deleted file mode 100644 index 90b08ff025a6..000000000000 --- a/scripts/kconfig/lxdialog/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# -# Generated files -# -lxdialog diff --git a/scripts/kconfig/lxdialog/BIG.FAT.WARNING b/scripts/kconfig/lxdialog/BIG.FAT.WARNING index a8999d82bdb3..7cb5a7ec93d2 100644 --- a/scripts/kconfig/lxdialog/BIG.FAT.WARNING +++ b/scripts/kconfig/lxdialog/BIG.FAT.WARNING @@ -1,4 +1,4 @@ This is NOT the official version of dialog. This version has been significantly modified from the original. It is for use by the Linux -kernel configuration script. Please do not bother Savio Lam with +kernel configuration script. Please do not bother Savio Lam with questions about this program. diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index 611945611bf8..1dcfb288ee63 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -113,7 +113,8 @@ do_resize: case KEY_DOWN: break; case KEY_BACKSPACE: - case 127: + case 8: /* ^H */ + case 127: /* ^? */ if (pos) { wattrset(dialog, dlg.inputbox.atr); if (input_x == 0) { diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index 1b490d4af0d3..3f78fb265136 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c @@ -363,7 +363,7 @@ void print_title(WINDOW *dialog, const char *title, int width) /* * Print a string of text in a window, automatically wrap around to the * next line if the string is too long to fit on one line. Newline - * characters '\n' are propperly processed. We start on a new line + * characters '\n' are properly processed. We start on a new line * if there is no room for at least 4 nonblanks following a double-space. */ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) @@ -541,7 +541,7 @@ int first_alpha(const char *string, const char *exempt) * lxdialog suggest <ESC> <ESC> which is correctly translated to two * times esc. But then we need to ignore the second esc to avoid stepping * out one menu too much. Filter away all escaped key sequences since - * keypad(FALSE) turn off ncurses support for escape sequences - and thats + * keypad(FALSE) turn off ncurses support for escape sequences - and that's * needed to make notimeout() do as expected. */ int on_key_esc(WINDOW *win) diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh index c812872d7f9d..1e61f50a5905 100755 --- a/scripts/kconfig/mconf-cfg.sh +++ b/scripts/kconfig/mconf-cfg.sh @@ -1,19 +1,22 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0
+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,20 +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
-if [ -f /usr/include/ncurses.h ]; then - echo cflags="-D_GNU_SOURCE" - echo libs="-lncurses" +# 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 -D_GNU_SOURCE > ${cflags} + echo -lncurses > ${libs} exit 0 fi
@@ -44,4 +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 ${HOSTPKG_CONFIG} to find the" +echo >&2 "* ncurses installed in a non-default location." +echo >&2 "*" exit 1 diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index c1b38747c147..e67e0db50b2e 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. * * Introduced single menu mode (show all sub-menus in one large tree). * 2002-11-06 Petr Baudis pasky@ucw.cz @@ -15,12 +15,15 @@ #include <stdarg.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <signal.h> #include <unistd.h>
#include "lkc.h" #include "lxdialog/dialog.h"
+#define JUMP_NB 9 + static const char mconf_readme[] = "Overview\n" "--------\n" @@ -158,6 +161,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" @@ -296,17 +305,12 @@ static char filename[PATH_MAX+1]; static void set_config_filename(const char *config_filename) { static char menu_backtitle[PATH_MAX+128]; - int size;
- size = snprintf(menu_backtitle, sizeof(menu_backtitle), - "%s - %s", config_filename, rootmenu.prompt->text); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; + snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", + config_filename, rootmenu.prompt->text); set_dialog_backtitle(menu_backtitle);
- size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; + snprintf(filename, sizeof(filename), "%s", config_filename); }
struct subtitle_part { @@ -442,9 +446,8 @@ again:
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 *) + dres = show_textbox_ext("Search Results", str_get(&res), 0, 0, + keys, &vscroll, &hscroll, &update_text, &data); again = false; for (i = 0; i < JUMP_NB && keys[i]; i++) @@ -536,7 +539,7 @@ static void build_conf(struct menu *menu) }
val = sym_get_tristate_value(sym); - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { switch (type) { case S_BOOLEAN: item_make("[%c]", val == no ? ' ' : '*'); @@ -587,7 +590,7 @@ static void build_conf(struct menu *menu) } else { switch (type) { case S_BOOLEAN: - if (sym_is_changable(sym)) + if (sym_is_changeable(sym)) item_make("[%c]", val == no ? ' ' : '*'); else item_make("-%c-", val == no ? ' ' : '*'); @@ -600,7 +603,7 @@ static void build_conf(struct menu *menu) case mod: ch = 'M'; break; default: ch = ' '; break; } - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { if (sym->rev_dep.tri == mod) item_make("{%c}", ch); else @@ -617,7 +620,7 @@ static void build_conf(struct menu *menu) if (tmp < 0) tmp = 0; item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? + (sym_has_value(sym) || !sym_is_changeable(sym)) ? "" : " (NEW)"); item_set_tag('s'); item_set_data(menu); @@ -625,7 +628,7 @@ static void build_conf(struct menu *menu) } } item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? + (sym_has_value(sym) || !sym_is_changeable(sym)) ? "" : " (NEW)"); if (menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); @@ -907,7 +910,7 @@ static void conf_load(void) return; if (!conf_read(dialog_input_result)) { set_config_filename(dialog_input_result); - sym_set_change_count(1); + conf_set_changed(true); return; } show_textbox(NULL, "File does not exist!", 5, 38); @@ -936,7 +939,7 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); + show_textbox(NULL, "Can't create file!", 5, 60); break; case 1: show_helptext("Save Alternate Configuration", save_config_help); @@ -973,6 +976,7 @@ static int handle_exit(void) "\n\n"); return 1; } + conf_write_autoconf(0); /* fall through */ case -1: if (!silent) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4cf15d449c05..b90fff833588 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
#include <ctype.h> @@ -9,6 +9,7 @@ #include <string.h>
#include "lkc.h" +#include "internal.h"
static const char nohelp_text[] = "There is no help available for this option.";
@@ -65,7 +66,8 @@ void menu_add_entry(struct symbol *sym) struct menu *menu_add_menu(void) { last_entry_ptr = ¤t_entry->list; - return current_menu = current_entry; + current_menu = current_entry; + return current_menu; }
void menu_end_menu(void) @@ -124,61 +126,76 @@ void menu_set_type(int type) sym_type_name(sym->type), sym_type_name(type)); }
-static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) +static struct property *menu_add_prop(enum prop_type type, struct expr *expr, + struct expr *dep) { - struct property *prop = prop_alloc(type, current_entry->sym); + struct property *prop;
+ prop = xmalloc(sizeof(*prop)); + memset(prop, 0, sizeof(*prop)); + prop->type = type; + prop->file = current_file; + prop->lineno = zconf_lineno(); prop->menu = current_entry; prop->expr = expr; prop->visible.expr = dep;
- if (prompt) { - if (isspace(*prompt)) { - prop_warn(prop, "leading whitespace ignored"); - while (isspace(*prompt)) - prompt++; - } - if (current_entry->prompt && current_entry != &rootmenu) - prop_warn(prop, "prompt redefined"); + /* append property to the prop list of symbol */ + if (current_entry->sym) { + struct property **propp;
- /* Apply all upper menus' visibilities to actual prompts. */ - if(type == P_PROMPT) { - struct menu *menu = current_entry; + for (propp = ¤t_entry->sym->prop; + *propp; + propp = &(*propp)->next) + ; + *propp = prop; + }
- while ((menu = menu->parent) != NULL) { - struct expr *dup_expr; + return prop; +}
- if (!menu->visibility) - continue; - /* - * Do not add a reference to the - * menu's visibility expression but - * use a copy of it. Otherwise the - * expression reduction functions - * will modify expressions that have - * multiple references which can - * cause unwanted side effects. - */ - dup_expr = expr_copy(menu->visibility); +struct property *menu_add_prompt(enum prop_type type, char *prompt, + struct expr *dep) +{ + struct property *prop = menu_add_prop(type, NULL, dep);
- prop->visible.expr - = expr_alloc_and(prop->visible.expr, - dup_expr); - } - } + if (isspace(*prompt)) { + prop_warn(prop, "leading whitespace ignored"); + while (isspace(*prompt)) + prompt++; + } + if (current_entry->prompt) + prop_warn(prop, "prompt redefined");
- current_entry->prompt = prop; + /* Apply all upper menus' visibilities to actual prompts. */ + if (type == P_PROMPT) { + struct menu *menu = current_entry; + + while ((menu = menu->parent) != NULL) { + struct expr *dup_expr; + + if (!menu->visibility) + continue; + /* + * Do not add a reference to the menu's visibility + * expression but use a copy of it. Otherwise the + * expression reduction functions will modify + * expressions that have multiple references which + * can cause unwanted side effects. + */ + dup_expr = expr_copy(menu->visibility); + + prop->visible.expr = expr_alloc_and(prop->visible.expr, + dup_expr); + } } + + current_entry->prompt = prop; prop->text = prompt;
return prop; }
-struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) -{ - return menu_add_prop(type, prompt, NULL, dep); -} - void menu_add_visibility(struct expr *expr) { current_entry->visibility = expr_alloc_and(current_entry->visibility, @@ -187,37 +204,12 @@ void menu_add_visibility(struct expr *expr)
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) { - menu_add_prop(type, NULL, expr, dep); + menu_add_prop(type, expr, dep); }
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) { - menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); -} - -void menu_add_option(int token, char *arg) -{ - switch (token) { - case T_OPT_MODULES: - if (modules_sym) - zconf_error("symbol '%s' redefines option 'modules'" - " already defined by symbol '%s'", - current_entry->sym->name, - modules_sym->name - ); - modules_sym = current_entry->sym; - break; - case T_OPT_DEFCONFIG_LIST: - if (!sym_defconfig_list) - sym_defconfig_list = current_entry->sym; - else if (sym_defconfig_list != current_entry->sym) - zconf_error("trying to redefine defconfig symbol"); - sym_defconfig_list->flags |= SYMBOL_NO_WRITE; - break; - case T_OPT_ALLNOCONFIG_Y: - current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; - break; - } + menu_add_prop(type, expr_alloc_symbol(sym), dep); }
static int menu_validate_number(struct symbol *sym, struct symbol *sym2) @@ -329,12 +321,10 @@ void menu_finalize(struct menu *parent) * choice value symbols. */ parentdep = expr_alloc_symbol(sym); - } else if (parent->prompt) - /* Menu node for 'menu' */ - parentdep = parent->prompt->visible.expr; - else - /* Menu node for 'if' */ + } else { + /* Menu node for 'menu', 'if' */ parentdep = parent->dep; + }
/* For each child menu node... */ for (menu = parent->list; menu; menu = menu->next) { @@ -671,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; @@ -701,6 +686,21 @@ const char *menu_get_help(struct menu *menu) return ""; }
+static void get_def_str(struct gstr *r, struct menu *menu) +{ + str_printf(r, "Defined at %s:%d\n", + menu->file->name, menu->lineno); +} + +static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix) +{ + if (!expr_is_yes(expr)) { + str_append(r, prefix); + expr_gstr_print(expr, r); + str_append(r, "\n"); + } +} + static void get_prompt_str(struct gstr *r, struct property *prop, struct list_head *head) { @@ -708,28 +708,30 @@ static void get_prompt_str(struct gstr *r, struct property *prop, struct menu *submenu[8], *menu, *location = NULL; struct jump_key *jump = NULL;
- str_printf(r, "Prompt: %s\n", prop->text); - menu = prop->menu->parent; - for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { - bool accessible = menu_is_visible(menu); + str_printf(r, " Prompt: %s\n", prop->text); + + get_dep_str(r, prop->menu->dep, " Depends on: "); + /* + * Most prompts in Linux have visibility that exactly matches their + * dependencies. For these, we print only the dependencies to improve + * readability. However, prompts with inline "if" expressions and + * prompts with a parent that has a "visible if" expression have + * differing dependencies and visibility. In these rare cases, we + * print both. + */ + if (!expr_eq(prop->menu->dep, prop->visible.expr)) + get_dep_str(r, prop->visible.expr, " Visible if: ");
+ menu = prop->menu; + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { 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; + jump->target = location;
if (list_empty(head)) jump->index = 0; @@ -740,36 +742,21 @@ static void get_prompt_str(struct gstr *r, struct property *prop, 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 = 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"); } }
-/* - * get property of type P_SYMBOL - */ -static struct property *get_symbol_prop(struct symbol *sym) -{ - struct property *prop = NULL; - - for_all_properties(sym, prop, P_SYMBOL) - break; - return prop; -} - static void get_symbol_props_str(struct gstr *r, struct symbol *sym, enum prop_type tok, const char *prefix) { @@ -809,32 +796,34 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym, } } } - for_all_prompts(sym, prop) - get_prompt_str(r, prop, head); - - prop = get_symbol_prop(sym); - if (prop) { - str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, - prop->menu->lineno); - if (!expr_is_yes(prop->visible.expr)) { - str_append(r, " Depends on: "); - expr_gstr_print(prop->visible.expr, r); - str_append(r, "\n"); + + /* Print the definitions with prompts before the ones without */ + for_all_properties(sym, prop, P_SYMBOL) { + if (prop->menu->prompt) { + get_def_str(r, prop->menu); + get_prompt_str(r, prop->menu->prompt, head); + } + } + + for_all_properties(sym, prop, P_SYMBOL) { + if (!prop->menu->prompt) { + get_def_str(r, prop->menu); + get_dep_str(r, prop->menu->dep, " Depends on: "); } }
- get_symbol_props_str(r, sym, P_SELECT, " Selects: "); + get_symbol_props_str(r, sym, P_SELECT, "Selects: "); if (sym->rev_dep.expr) { - expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n"); - expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n"); - expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "Selected by [n]:\n"); }
- get_symbol_props_str(r, sym, P_IMPLY, " Implies: "); + get_symbol_props_str(r, sym, P_IMPLY, "Implies: "); if (sym->implied.expr) { - expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n"); - expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n"); - expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, yes, "Implied by [y]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, mod, "Implied by [m]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, no, "Implied by [n]:\n"); }
str_append(r, "\n\n"); diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 0ef906499646..e5b46980c22a 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -1,4 +1,6 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# # merge_config.sh - Takes a list of config fragment values, and merges # them one by one. Provides warnings on overridden values, and specified # values that did not make it to the resulting .config file (due to missed @@ -10,21 +12,13 @@ # # Copyright (c) 2009-2010 Wind River Systems, Inc. # Copyright 2011 Linaro -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU General Public License for more details. + +set -e
clean_up() { rm -f $TMP_FILE - exit + rm -f $MERGE_FILE } -trap clean_up HUP INT TERM
usage() { echo "Usage: $0 [OPTIONS] [CONFIG [...]]" @@ -32,7 +26,9 @@ usage() { echo " -m only merge the fragments, do not execute the make command" echo " -n use allnoconfig instead of alldefconfig" echo " -r list redundant entries when merging fragments" + echo " -y make builtin have precedence over modules" echo " -O dir to put generated output files. Consider setting $KCONFIG_CONFIG instead." + echo " -s strict mode. Fail if the fragment redefines any value." echo echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with $CONFIG_ environment variable." } @@ -40,7 +36,9 @@ usage() { RUNMAKE=true ALLTARGET=alldefconfig WARNREDUN=false +BUILTIN=false OUTPUT=. +STRICT=false CONFIG_PREFIX=${CONFIG_-CONFIG_}
while true; do @@ -64,6 +62,11 @@ while true; do shift continue ;; + "-y") + BUILTIN=true + shift + continue + ;; "-O") if [ -d $2 ];then OUTPUT=$(echo $2 | sed 's//*$//') @@ -74,6 +77,11 @@ while true; do shift 2 continue ;; + "-s") + STRICT=true + shift + continue + ;; *) break ;; @@ -106,42 +114,65 @@ SED_CONFIG_EXP1="s/^(${CONFIG_PREFIX}[a-zA-Z0-9_]*)=.*/\1/p" SED_CONFIG_EXP2="s/^# (${CONFIG_PREFIX}[a-zA-Z0-9_]*) is not set$/\1/p"
TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) +MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX)
echo "Using $INITFILE as base" + +trap clean_up EXIT + cat $INITFILE > $TMP_FILE
# Merge files, printing warnings on overridden values -for MERGE_FILE in $MERGE_LIST ; do - echo "Merging $MERGE_FILE" - if [ ! -r "$MERGE_FILE" ]; then - echo "The merge file '$MERGE_FILE' does not exist. Exit." >&2 +for ORIG_MERGE_FILE in $MERGE_LIST ; do + echo "Merging $ORIG_MERGE_FILE" + if [ ! -r "$ORIG_MERGE_FILE" ]; then + echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 exit 1 fi + cat $ORIG_MERGE_FILE > $MERGE_FILE CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE)
for CFG in $CFG_LIST ; do grep -q -w $CFG $TMP_FILE || continue PREV_VAL=$(grep -w $CFG $TMP_FILE) NEW_VAL=$(grep -w $CFG $MERGE_FILE) - if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then - echo Value of $CFG is redefined by fragment $MERGE_FILE: + BUILTIN_FLAG=false + if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then + echo Previous value: $PREV_VAL + echo New value: $NEW_VAL + echo -y passed, will not demote y to m + echo + BUILTIN_FLAG=true + elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then + echo Value of $CFG is redefined by fragment $ORIG_MERGE_FILE: echo Previous value: $PREV_VAL echo New value: $NEW_VAL echo + if [ "$STRICT" = "true" ]; then + STRICT_MODE_VIOLATED=true + fi elif [ "$WARNREDUN" = "true" ]; then - echo Value of $CFG is redundant by fragment $MERGE_FILE: + echo Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: + fi + if [ "$BUILTIN_FLAG" = "false" ]; then + sed -i "/$CFG[ =]/d" $TMP_FILE + else + sed -i "/$CFG[ =]/d" $MERGE_FILE fi - sed -i "/$CFG[ =]/d" $TMP_FILE done cat $MERGE_FILE >> $TMP_FILE done
+if [ "$STRICT_MODE_VIOLATED" = "true" ]; then + echo "The fragment redefined a value and strict mode had been passed." + exit 1 +fi + if [ "$RUNMAKE" = "false" ]; then cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG" echo "#" echo "# merged configuration written to $KCONFIG_CONFIG (needs make)" echo "#" - clean_up exit fi
@@ -163,7 +194,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do
REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) - ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG") + ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then echo "Value requested for $CFG not in final .config" echo "Requested value: $REQUESTED_VAL" @@ -171,5 +202,3 @@ for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do echo "" fi done - -clean_up diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh old mode 100644 new mode 100755 index 001559ef0a60..f871a2160e36 --- a/scripts/kconfig/nconf-cfg.sh +++ b/scripts/kconfig/nconf-cfg.sh @@ -1,19 +1,22 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0
+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,4 +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 ${HOSTPKG_CONFIG} to find the" +echo >&2 "* ncurses installed in a non-default location." +echo >&2 "*" exit 1 diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 5cbdb92e11b3..3ba8b1af390f 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1,14 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? - * Released under the terms of the GNU GPL v2.0. + * Copyright (C) 2008 Nir Tzachar nir.tzachar@gmail.com * * Derived from menuconfig. - * */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <string.h> +#include <strings.h> #include <stdlib.h>
#include "lkc.h" @@ -52,8 +52,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" @@ -268,7 +268,7 @@ static int mwin_max_cols; static MENU *curses_menu; static ITEM *curses_menu_items[MAX_MENU_ITEMS]; static struct mitem k_menu_items[MAX_MENU_ITEMS]; -static int items_num; +static unsigned int items_num; static int global_exit; /* the currently selected button */ static const char *current_instructions = menu_instructions; @@ -370,18 +370,18 @@ static void print_function_line(void) int lines = getmaxy(stdscr);
for (i = 0; i < function_keys_num; i++) { - (void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); + wattrset(main_window, attr_function_highlight); mvwprintw(main_window, lines-3, offset, "%s", function_keys[i].key_str); - (void) wattrset(main_window, attributes[FUNCTION_TEXT]); + wattrset(main_window, attr_function_text); offset += strlen(function_keys[i].key_str); mvwprintw(main_window, lines-3, offset, "%s", function_keys[i].func); offset += strlen(function_keys[i].func) + skip; } - (void) wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attr_normal); }
/* help */ @@ -496,16 +496,20 @@ typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, /* return the index of the matched item, or -1 if no such item exists */ static int get_mext_match(const char *match_str, match_f flag) { - int match_start = item_index(current_item(curses_menu)); - int index; + int match_start, index; + + /* Do not search if the menu is empty (i.e. items_num == 0) */ + match_start = item_index(current_item(curses_menu)); + if (match_start == ERR) + return -1;
if (flag == FIND_NEXT_MATCH_DOWN) ++match_start; else if (flag == FIND_NEXT_MATCH_UP) --match_start;
+ match_start = (match_start + items_num) % items_num; index = match_start; - index = (index + items_num) % items_num; while (true) { char *str = k_menu_items[index].str; if (strcasestr(str, match_str) != NULL) @@ -627,19 +631,12 @@ static int item_is_tag(char tag)
static char filename[PATH_MAX+1]; static char menu_backtitle[PATH_MAX+128]; -static const char *set_config_filename(const char *config_filename) +static void set_config_filename(const char *config_filename) { - int size; + snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s", + config_filename, rootmenu.prompt->text);
- size = snprintf(menu_backtitle, sizeof(menu_backtitle), - "%s - %s", config_filename, rootmenu.prompt->text); - if (size >= sizeof(menu_backtitle)) - menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; - - size = snprintf(filename, sizeof(filename), "%s", config_filename); - if (size >= sizeof(filename)) - filename[sizeof(filename)-1] = '\0'; - return menu_backtitle; + snprintf(filename, sizeof(filename), "%s", config_filename); }
/* return = 0 means we are successful. @@ -674,6 +671,7 @@ static int do_exit(void) "Your configuration changes were NOT saved.", 1, "<OK>"); + conf_write_autoconf(0); break; default: btn_dialog( @@ -754,7 +752,6 @@ static void build_conf(struct menu *menu) switch (ptype) { case P_MENU: child_count++; - prompt = prompt; if (single_menu_mode) { item_make(menu, 'm', "%s%*c%s", @@ -803,7 +800,7 @@ static void build_conf(struct menu *menu) }
val = sym_get_tristate_value(sym); - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { switch (type) { case S_BOOLEAN: item_make(menu, 't', "[%c]", @@ -857,7 +854,7 @@ static void build_conf(struct menu *menu) } else { switch (type) { case S_BOOLEAN: - if (sym_is_changable(sym)) + if (sym_is_changeable(sym)) item_make(menu, 't', "[%c]", val == no ? ' ' : '*'); else @@ -876,7 +873,7 @@ static void build_conf(struct menu *menu) ch = ' '; break; } - if (sym_is_changable(sym)) { + if (sym_is_changeable(sym)) { if (sym->rev_dep.tri == mod) item_make(menu, 't', "{%c}", ch); @@ -896,14 +893,14 @@ static void build_conf(struct menu *menu) item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), (sym_has_value(sym) || - !sym_is_changable(sym)) ? "" : + !sym_is_changeable(sym)) ? "" : " (NEW)"); goto conf_childs; } } item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changable(sym)) ? + (sym_has_value(sym) || !sym_is_changeable(sym)) ? "" : " (NEW)"); if (menu->prompt && menu->prompt->type == P_MENU) { item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); @@ -956,16 +953,15 @@ static void show_menu(const char *prompt, const char *instructions, current_instructions = instructions;
clear(); - (void) wattrset(main_window, attributes[NORMAL]); - print_in_middle(stdscr, 1, 0, getmaxx(stdscr), + print_in_middle(stdscr, 1, getmaxx(stdscr), menu_backtitle, - attributes[MAIN_HEADING]); + attr_main_heading);
- (void) wattrset(main_window, attributes[MAIN_MENU_BOX]); + wattrset(main_window, attr_main_menu_box); box(main_window, 0, 0); - (void) wattrset(main_window, attributes[MAIN_MENU_HEADING]); + wattrset(main_window, attr_main_menu_heading); mvwprintw(main_window, 0, 3, " %s ", prompt); - (void) wattrset(main_window, attributes[NORMAL]); + wattrset(main_window, attr_normal);
set_menu_items(curses_menu, curses_menu_items);
@@ -1048,7 +1044,7 @@ static int do_match(int key, struct match_state *state, int *ans) state->match_direction = FIND_NEXT_MATCH_UP; *ans = get_mext_match(state->pattern, state->match_direction); - } else if (key == KEY_BACKSPACE || key == 127) { + } else if (key == KEY_BACKSPACE || key == 8 || key == 127) { state->pattern[strlen(state->pattern)-1] = '\0'; adj_match_dir(&state->match_direction); } else @@ -1068,7 +1064,6 @@ static int do_match(int key, struct match_state *state, int *ans) static void conf(struct menu *menu) { struct menu *submenu = NULL; - const char *prompt = menu_get_prompt(menu); struct symbol *sym; int res; int current_index = 0; @@ -1086,9 +1081,8 @@ static void conf(struct menu *menu) if (!child_count) break;
- show_menu(prompt ? prompt : "Main Menu", - menu_instructions, - current_index, &last_top_row); + show_menu(menu_get_prompt(menu), menu_instructions, + current_index, &last_top_row); keypad((menu_win(curses_menu)), TRUE); while (!global_exit) { if (match_state.in_search) { @@ -1111,9 +1105,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: @@ -1293,9 +1289,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: @@ -1404,7 +1402,7 @@ static void conf_load(void) return; if (!conf_read(dialog_input_result)) { set_config_filename(dialog_input_result); - sym_set_change_count(1); + conf_set_changed(true); return; } btn_dialog(main_window, "File does not exist!", 0); @@ -1438,8 +1436,7 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - btn_dialog(main_window, "Can't create file! " - "Probably a nonexistent directory.", + btn_dialog(main_window, "Can't create file!", 1, "<OK>"); break; case 1: @@ -1524,9 +1521,9 @@ int main(int ac, char **av) menu_opts_on(curses_menu, O_NONCYCLIC); menu_opts_on(curses_menu, O_IGNORECASE); set_menu_mark(curses_menu, " "); - set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); - set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); - set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); + set_menu_fore(curses_menu, attr_main_menu_fore); + set_menu_back(curses_menu, attr_main_menu_back); + set_menu_grey(curses_menu, attr_main_menu_grey);
set_config_filename(conf_get_configname()); setup_windows(); diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 88874acfda36..9aedf40f1dc0 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -1,176 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? - * Released under the terms of the GNU GPL v2.0. + * Copyright (C) 2008 Nir Tzachar nir.tzachar@gmail.com * * Derived from menuconfig. - * */ #include "nconf.h" #include "lkc.h"
-/* a list of all the different widgets we use */ -attributes_t attributes[ATTR_MAX+1] = {0}; - -/* available colors: - COLOR_BLACK 0 - COLOR_RED 1 - COLOR_GREEN 2 - COLOR_YELLOW 3 - COLOR_BLUE 4 - COLOR_MAGENTA 5 - COLOR_CYAN 6 - COLOR_WHITE 7 - */ -static void set_normal_colors(void) -{ - init_pair(NORMAL, -1, -1); - init_pair(MAIN_HEADING, COLOR_MAGENTA, -1); - - /* FORE is for the selected item */ - init_pair(MAIN_MENU_FORE, -1, -1); - /* BACK for all the rest */ - init_pair(MAIN_MENU_BACK, -1, -1); - init_pair(MAIN_MENU_GREY, -1, -1); - init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1); - init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1); - - init_pair(SCROLLWIN_TEXT, -1, -1); - init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1); - init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1); - - init_pair(DIALOG_TEXT, -1, -1); - init_pair(DIALOG_BOX, COLOR_YELLOW, -1); - init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1); - init_pair(DIALOG_MENU_FORE, COLOR_RED, -1); - - init_pair(INPUT_BOX, COLOR_YELLOW, -1); - init_pair(INPUT_HEADING, COLOR_GREEN, -1); - init_pair(INPUT_TEXT, -1, -1); - init_pair(INPUT_FIELD, -1, -1); - - init_pair(FUNCTION_HIGHLIGHT, -1, -1); - init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1); -} - -/* available attributes: - A_NORMAL Normal display (no highlight) - A_STANDOUT Best highlighting mode of the terminal. - A_UNDERLINE Underlining - A_REVERSE Reverse video - A_BLINK Blinking - A_DIM Half bright - A_BOLD Extra bright or bold - A_PROTECT Protected mode - A_INVIS Invisible or blank mode - A_ALTCHARSET Alternate character set - A_CHARTEXT Bit-mask to extract a character - COLOR_PAIR(n) Color-pair number n - */ -static void normal_color_theme(void) -{ - /* automatically add color... */ -#define mkattr(name, attr) do { \ -attributes[name] = attr | COLOR_PAIR(name); } while (0) - mkattr(NORMAL, NORMAL); - mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE); - - mkattr(MAIN_MENU_FORE, A_REVERSE); - mkattr(MAIN_MENU_BACK, A_NORMAL); - mkattr(MAIN_MENU_GREY, A_NORMAL); - mkattr(MAIN_MENU_HEADING, A_BOLD); - mkattr(MAIN_MENU_BOX, A_NORMAL); - - mkattr(SCROLLWIN_TEXT, A_NORMAL); - mkattr(SCROLLWIN_HEADING, A_BOLD); - mkattr(SCROLLWIN_BOX, A_BOLD); - - mkattr(DIALOG_TEXT, A_BOLD); - mkattr(DIALOG_BOX, A_BOLD); - mkattr(DIALOG_MENU_FORE, A_STANDOUT); - mkattr(DIALOG_MENU_BACK, A_NORMAL); - - mkattr(INPUT_BOX, A_NORMAL); - mkattr(INPUT_HEADING, A_BOLD); - mkattr(INPUT_TEXT, A_NORMAL); - mkattr(INPUT_FIELD, A_UNDERLINE); - - mkattr(FUNCTION_HIGHLIGHT, A_BOLD); - mkattr(FUNCTION_TEXT, A_REVERSE); -} - -static void no_colors_theme(void) -{ - /* automatically add highlight, no color */ -#define mkattrn(name, attr) { attributes[name] = attr; } - - mkattrn(NORMAL, NORMAL); - mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE); - - mkattrn(MAIN_MENU_FORE, A_STANDOUT); - mkattrn(MAIN_MENU_BACK, A_NORMAL); - mkattrn(MAIN_MENU_GREY, A_NORMAL); - mkattrn(MAIN_MENU_HEADING, A_BOLD); - mkattrn(MAIN_MENU_BOX, A_NORMAL); - - mkattrn(SCROLLWIN_TEXT, A_NORMAL); - mkattrn(SCROLLWIN_HEADING, A_BOLD); - mkattrn(SCROLLWIN_BOX, A_BOLD); - - mkattrn(DIALOG_TEXT, A_NORMAL); - mkattrn(DIALOG_BOX, A_BOLD); - mkattrn(DIALOG_MENU_FORE, A_STANDOUT); - mkattrn(DIALOG_MENU_BACK, A_NORMAL); - - mkattrn(INPUT_BOX, A_BOLD); - mkattrn(INPUT_HEADING, A_BOLD); - mkattrn(INPUT_TEXT, A_NORMAL); - mkattrn(INPUT_FIELD, A_UNDERLINE); - - mkattrn(FUNCTION_HIGHLIGHT, A_BOLD); - mkattrn(FUNCTION_TEXT, A_REVERSE); -} +int attr_normal; +int attr_main_heading; +int attr_main_menu_box; +int attr_main_menu_fore; +int attr_main_menu_back; +int attr_main_menu_grey; +int attr_main_menu_heading; +int attr_scrollwin_text; +int attr_scrollwin_heading; +int attr_scrollwin_box; +int attr_dialog_text; +int attr_dialog_menu_fore; +int attr_dialog_menu_back; +int attr_dialog_box; +int attr_input_box; +int attr_input_heading; +int attr_input_text; +int attr_input_field; +int attr_function_text; +int attr_function_highlight; + +#define COLOR_ATTR(_at, _fg, _bg, _hl) \ + { .attr = &(_at), .has_color = true, .color_fg = _fg, .color_bg = _bg, .highlight = _hl } +#define NO_COLOR_ATTR(_at, _hl) \ + { .attr = &(_at), .has_color = false, .highlight = _hl } +#define COLOR_DEFAULT -1 + +struct nconf_attr_param { + int *attr; + bool has_color; + int color_fg; + int color_bg; + int highlight; +}; + +static const struct nconf_attr_param color_theme_params[] = { + COLOR_ATTR(attr_normal, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_heading, COLOR_MAGENTA, COLOR_DEFAULT, A_BOLD | A_UNDERLINE), + COLOR_ATTR(attr_main_menu_box, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_menu_fore, COLOR_DEFAULT, COLOR_DEFAULT, A_REVERSE), + COLOR_ATTR(attr_main_menu_back, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_menu_grey, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_main_menu_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_scrollwin_text, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_scrollwin_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_scrollwin_box, COLOR_YELLOW, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_dialog_text, COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_dialog_menu_fore, COLOR_RED, COLOR_DEFAULT, A_STANDOUT), + COLOR_ATTR(attr_dialog_menu_back, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_dialog_box, COLOR_YELLOW, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_input_box, COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_input_heading, COLOR_GREEN, COLOR_DEFAULT, A_BOLD), + COLOR_ATTR(attr_input_text, COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), + COLOR_ATTR(attr_input_field, COLOR_DEFAULT, COLOR_DEFAULT, A_UNDERLINE), + COLOR_ATTR(attr_function_text, COLOR_YELLOW, COLOR_DEFAULT, A_REVERSE), + COLOR_ATTR(attr_function_highlight, COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD), + { /* sentinel */ } +}; + +static const struct nconf_attr_param no_color_theme_params[] = { + NO_COLOR_ATTR(attr_normal, A_NORMAL), + NO_COLOR_ATTR(attr_main_heading, A_BOLD | A_UNDERLINE), + NO_COLOR_ATTR(attr_main_menu_box, A_NORMAL), + NO_COLOR_ATTR(attr_main_menu_fore, A_STANDOUT), + NO_COLOR_ATTR(attr_main_menu_back, A_NORMAL), + NO_COLOR_ATTR(attr_main_menu_grey, A_NORMAL), + NO_COLOR_ATTR(attr_main_menu_heading, A_BOLD), + NO_COLOR_ATTR(attr_scrollwin_text, A_NORMAL), + NO_COLOR_ATTR(attr_scrollwin_heading, A_BOLD), + NO_COLOR_ATTR(attr_scrollwin_box, A_BOLD), + NO_COLOR_ATTR(attr_dialog_text, A_NORMAL), + NO_COLOR_ATTR(attr_dialog_menu_fore, A_STANDOUT), + NO_COLOR_ATTR(attr_dialog_menu_back, A_NORMAL), + NO_COLOR_ATTR(attr_dialog_box, A_BOLD), + NO_COLOR_ATTR(attr_input_box, A_BOLD), + NO_COLOR_ATTR(attr_input_heading, A_BOLD), + NO_COLOR_ATTR(attr_input_text, A_NORMAL), + NO_COLOR_ATTR(attr_input_field, A_UNDERLINE), + NO_COLOR_ATTR(attr_function_text, A_REVERSE), + NO_COLOR_ATTR(attr_function_highlight, A_BOLD), + { /* sentinel */ } +};
void set_colors(void) { - start_color(); - use_default_colors(); - set_normal_colors(); + const struct nconf_attr_param *p; + int pair = 0; + if (has_colors()) { - normal_color_theme(); + start_color(); + use_default_colors(); + p = color_theme_params; } else { - /* give defaults */ - no_colors_theme(); + p = no_color_theme_params; } -}
+ for (; p->attr; p++) { + int attr = p->highlight; + + if (p->has_color) { + pair++; + init_pair(pair, p->color_fg, p->color_bg); + attr |= COLOR_PAIR(pair); + } + + *p->attr = attr; + } +}
/* this changes the windows attributes !!! */ -void print_in_middle(WINDOW *win, - int starty, - int startx, - int width, - const char *string, - chtype color) -{ int length, x, y; - float temp; - - - if (win == NULL) - win = stdscr; - getyx(win, y, x); - if (startx != 0) - x = startx; - if (starty != 0) - y = starty; - if (width == 0) - width = 80; - - length = strlen(string); - temp = (width - length) / 2; - x = startx + (int)temp; - (void) wattrset(win, color); - mvwprintw(win, y, x, "%s", string); - refresh(); +void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs) +{ + wattrset(win, attrs); + mvwprintw(win, y, (width - strlen(str)) / 2, "%s", str); }
int get_line_no(const char *text) @@ -295,14 +245,14 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) msg_win = derwin(win, win_rows-2, msg_width, 1, 1+(total_width+2-msg_width)/2);
- set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); - set_menu_back(menu, attributes[DIALOG_MENU_BACK]); + set_menu_fore(menu, attr_dialog_menu_fore); + set_menu_back(menu, attr_dialog_menu_back);
- (void) wattrset(win, attributes[DIALOG_BOX]); + wattrset(win, attr_dialog_box); box(win, 0, 0);
/* print message */ - (void) wattrset(msg_win, attributes[DIALOG_TEXT]); + wattrset(msg_win, attr_dialog_text); fill_window(msg_win, msg);
set_menu_win(menu, win); @@ -406,16 +356,16 @@ int dialog_inputbox(WINDOW *main_window, form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE);
- (void) wattrset(form_win, attributes[INPUT_FIELD]); + wattrset(form_win, attr_input_field);
- (void) wattrset(win, attributes[INPUT_BOX]); + wattrset(win, attr_input_box); box(win, 0, 0); - (void) wattrset(win, attributes[INPUT_HEADING]); + wattrset(win, attr_input_heading); if (title) mvwprintw(win, 0, 3, "%s", title);
/* print message */ - (void) wattrset(prompt_win, attributes[INPUT_TEXT]); + wattrset(prompt_win, attr_input_text); fill_window(prompt_win, prompt);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); @@ -440,7 +390,8 @@ int dialog_inputbox(WINDOW *main_window, case KEY_F(F_EXIT): case KEY_F(F_BACK): break; - case 127: + case 8: /* ^H */ + case 127: /* ^? */ case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], @@ -576,7 +527,7 @@ void show_scroll_win(WINDOW *main_window,
/* create the pad */ pad = newpad(total_lines+10, total_cols+10); - (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); + wattrset(pad, attr_scrollwin_text); fill_window(pad, text);
win_lines = min(total_lines+4, lines-2); @@ -591,9 +542,9 @@ void show_scroll_win(WINDOW *main_window, win = newwin(win_lines, win_cols, y, x); keypad(win, TRUE); /* show the help in the help window, and show the help panel */ - (void) wattrset(win, attributes[SCROLLWIN_BOX]); + wattrset(win, attr_scrollwin_box); box(win, 0, 0); - (void) wattrset(win, attributes[SCROLLWIN_HEADING]); + wattrset(win, attr_scrollwin_heading); mvwprintw(win, 0, 3, " %s ", title); panel = new_panel(win);
@@ -604,10 +555,9 @@ void show_scroll_win(WINDOW *main_window, text_cols, 0); print_in_middle(win, text_lines+2, - 0, text_cols, "<OK>", - attributes[DIALOG_MENU_FORE]); + attr_dialog_menu_fore); wrefresh(win);
res = wgetch(win); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index 2b9e19f603c4..6f925bc74eb3 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -1,9 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? - * Released under the terms of the GNU GPL v2.0. + * Copyright (C) 2008 Nir Tzachar nir.tzachar@gmail.com * * Derived from menuconfig. - * */
#include <ctype.h> @@ -33,30 +32,26 @@ typeof(b) _b = b;\ _a < _b ? _a : _b; })
-typedef enum { - NORMAL = 1, - MAIN_HEADING, - MAIN_MENU_BOX, - MAIN_MENU_FORE, - MAIN_MENU_BACK, - MAIN_MENU_GREY, - MAIN_MENU_HEADING, - SCROLLWIN_TEXT, - SCROLLWIN_HEADING, - SCROLLWIN_BOX, - DIALOG_TEXT, - DIALOG_MENU_FORE, - DIALOG_MENU_BACK, - DIALOG_BOX, - INPUT_BOX, - INPUT_HEADING, - INPUT_TEXT, - INPUT_FIELD, - FUNCTION_TEXT, - FUNCTION_HIGHLIGHT, - ATTR_MAX -} attributes_t; -extern attributes_t attributes[]; +extern int attr_normal; +extern int attr_main_heading; +extern int attr_main_menu_box; +extern int attr_main_menu_fore; +extern int attr_main_menu_back; +extern int attr_main_menu_grey; +extern int attr_main_menu_heading; +extern int attr_scrollwin_text; +extern int attr_scrollwin_heading; +extern int attr_scrollwin_box; +extern int attr_dialog_text; +extern int attr_dialog_menu_fore; +extern int attr_dialog_menu_back; +extern int attr_dialog_box; +extern int attr_input_box; +extern int attr_input_heading; +extern int attr_input_text; +extern int attr_input_field; +extern int attr_function_text; +extern int attr_function_highlight;
typedef enum { F_HELP = 1, @@ -73,12 +68,7 @@ typedef enum { void set_colors(void);
/* this changes the windows attributes !!! */ -void print_in_middle(WINDOW *win, - int starty, - int startx, - int width, - const char *string, - chtype color); +void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs); int get_line_length(const char *line); int get_line_no(const char *text); const char *get_line(const char *text, int line_no); diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/parser.y similarity index 70% rename from scripts/kconfig/zconf.y rename to scripts/kconfig/parser.y index 22fceb264cf5..2af7ce4e1531 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/parser.y @@ -1,8 +1,8 @@ -%{ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */ +%{
#include <ctype.h> #include <stdarg.h> @@ -12,6 +12,7 @@ #include <stdbool.h>
#include "lkc.h" +#include "internal.h"
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
@@ -20,66 +21,65 @@
int cdebug = PRINTD;
-int yylex(void); static void yyerror(const char *err); static void zconfprint(const char *err, ...); static void zconf_error(const char *err, ...); -static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken); +static bool zconf_endtoken(const char *tokenname, + const char *expected_tokenname);
struct symbol *symbol_hash[SYMBOL_HASHSIZE];
-static struct menu *current_menu, *current_entry; +struct menu *current_menu, *current_entry;
%} -%expect 30
%union { char *string; - struct file *file; struct symbol *symbol; struct expr *expr; struct menu *menu; - const struct kconf_id *id; + enum symbol_type type; enum variable_flavor flavor; }
-%token <id>T_MAINMENU -%token <id>T_MENU -%token <id>T_ENDMENU -%token <id>T_SOURCE -%token <id>T_CHOICE -%token <id>T_ENDCHOICE -%token <id>T_COMMENT -%token <id>T_CONFIG -%token <id>T_MENUCONFIG -%token <id>T_HELP %token <string> T_HELPTEXT -%token <id>T_IF -%token <id>T_ENDIF -%token <id>T_DEPENDS -%token <id>T_OPTIONAL -%token <id>T_PROMPT -%token <id>T_TYPE -%token <id>T_DEFAULT -%token <id>T_SELECT -%token <id>T_IMPLY -%token <id>T_RANGE -%token <id>T_VISIBLE -%token <id>T_OPTION -%token <id>T_ON %token <string> T_WORD %token <string> T_WORD_QUOTE -%token T_UNEQUAL -%token T_LESS -%token T_LESS_EQUAL -%token T_GREATER -%token T_GREATER_EQUAL +%token T_BOOL +%token T_CHOICE %token T_CLOSE_PAREN +%token T_COLON_EQUAL +%token T_COMMENT +%token T_CONFIG +%token T_DEFAULT +%token T_DEF_BOOL +%token T_DEF_TRISTATE +%token T_DEPENDS +%token T_ENDCHOICE +%token T_ENDIF +%token T_ENDMENU +%token T_HELP +%token T_HEX +%token T_IF +%token T_IMPLY +%token T_INT +%token T_MAINMENU +%token T_MENU +%token T_MENUCONFIG +%token T_MODULES +%token T_ON %token T_OPEN_PAREN +%token T_OPTIONAL +%token T_PLUS_EQUAL +%token T_PROMPT +%token T_RANGE +%token T_SELECT +%token T_SOURCE +%token T_STRING +%token T_TRISTATE +%token T_VISIBLE %token T_EOL -%token <string> T_VARIABLE -%token <flavor> T_ASSIGN %token <string> T_ASSIGN_VAL
%left T_OR @@ -88,15 +88,15 @@ static struct menu *current_menu, *current_entry; %left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL %nonassoc T_NOT
-%type <string> prompt %type <symbol> nonconst_symbol %type <symbol> symbol +%type <type> type logic_type default %type <expr> expr %type <expr> if_expr -%type <id> end -%type <id> option_name +%type <string> end %type <menu> if_entry menu_entry choice_entry -%type <string> symbol_option_arg word_opt assign_val +%type <string> word_opt assign_val +%type <flavor> assign_op
%destructor { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -105,57 +105,38 @@ static struct menu *current_menu, *current_entry; menu_end_menu(); } if_entry menu_entry choice_entry
-%{ -/* Include kconf_id.c here so it can see the token constants. */ -#include "kconf_id.c" -%} - %% -input: nl start | start; - -start: mainmenu_stmt stmt_list | stmt_list; +input: mainmenu_stmt stmt_list | stmt_list;
/* mainmenu entry */
-mainmenu_stmt: T_MAINMENU prompt T_EOL +mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL { menu_add_prompt(P_MENU, $2, NULL); };
stmt_list: /* empty */ - | stmt_list common_stmt + | stmt_list assignment_stmt | stmt_list choice_stmt + | stmt_list comment_stmt + | stmt_list config_stmt + | stmt_list if_stmt | stmt_list menu_stmt - | stmt_list end { zconf_error("unexpected end statement"); } + | stmt_list menuconfig_stmt + | stmt_list source_stmt | stmt_list T_WORD error T_EOL { zconf_error("unknown statement "%s"", $2); } - | stmt_list option_name error T_EOL -{ - zconf_error("unexpected option "%s"", $2->name); -} | stmt_list error T_EOL { zconf_error("invalid statement"); } ;
-option_name: - T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_IMPLY | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE -; - -common_stmt: - T_EOL - | if_stmt - | comment_stmt - | config_stmt - | menuconfig_stmt - | source_stmt - | assignment_stmt -; - -option_error: - T_WORD error T_EOL { zconf_error("unknown option "%s"", $1); } - | error T_EOL { zconf_error("invalid option"); } +stmt_list_in_choice: + /* empty */ + | stmt_list_in_choice comment_stmt + | stmt_list_in_choice config_stmt + | stmt_list_in_choice if_stmt_in_choice + | stmt_list_in_choice error T_EOL { zconf_error("invalid statement"); } ;
- /* config/menuconfig entry */
config_entry_start: T_CONFIG nonconst_symbol T_EOL @@ -189,35 +170,32 @@ menuconfig_stmt: menuconfig_entry_start config_option_list config_option_list: /* empty */ | config_option_list config_option - | config_option_list symbol_option | config_option_list depends | config_option_list help - | config_option_list option_error - | config_option_list T_EOL ;
-config_option: T_TYPE prompt_stmt_opt T_EOL +config_option: type prompt_stmt_opt T_EOL { - menu_set_type($1->stype); + menu_set_type($1); printd(DEBUG_PARSE, "%s:%d:type(%u)\n", zconf_curname(), zconf_lineno(), - $1->stype); + $1); };
-config_option: T_PROMPT prompt if_expr T_EOL +config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL { menu_add_prompt(P_PROMPT, $2, $3); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); };
-config_option: T_DEFAULT expr if_expr T_EOL +config_option: default expr if_expr T_EOL { menu_add_expr(P_DEFAULT, $2, $3); - if ($1->stype != S_UNKNOWN) - menu_set_type($1->stype); + if ($1 != S_UNKNOWN) + menu_set_type($1); printd(DEBUG_PARSE, "%s:%d:default(%u)\n", zconf_curname(), zconf_lineno(), - $1->stype); + $1); };
config_option: T_SELECT nonconst_symbol if_expr T_EOL @@ -238,28 +216,14 @@ config_option: T_RANGE symbol symbol if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); };
-symbol_option: T_OPTION symbol_option_list T_EOL -; - -symbol_option_list: - /* empty */ - | symbol_option_list T_WORD symbol_option_arg +config_option: T_MODULES T_EOL { - const struct kconf_id *id = kconf_id_lookup($2, strlen($2)); - if (id && id->flags & TF_OPTION) { - menu_add_option(id->token, $3); - free($3); - } - else - zconfprint("warning: ignoring unknown option %s", $2); - free($2); + if (modules_sym) + zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'", + current_entry->sym->name, modules_sym->name); + modules_sym = current_entry->sym; };
-symbol_option_arg: - /* empty */ { $$ = NULL; } - | T_EQUAL prompt { $$ = $2; } -; - /* choice entry */
choice: T_CHOICE word_opt T_EOL @@ -279,13 +243,13 @@ choice_entry: choice choice_option_list
choice_end: end { - if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { + if (zconf_endtoken($1, "choice")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); } };
-choice_stmt: choice_entry choice_block choice_end +choice_stmt: choice_entry stmt_list_in_choice choice_end ;
choice_option_list: @@ -293,25 +257,19 @@ choice_option_list: | choice_option_list choice_option | choice_option_list depends | choice_option_list help - | choice_option_list T_EOL - | choice_option_list option_error ;
-choice_option: T_PROMPT prompt if_expr T_EOL +choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL { menu_add_prompt(P_PROMPT, $2, $3); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); };
-choice_option: T_TYPE prompt_stmt_opt T_EOL +choice_option: logic_type prompt_stmt_opt T_EOL { - if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { - menu_set_type($1->stype); - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", - zconf_curname(), zconf_lineno(), - $1->stype); - } else - YYERROR; + menu_set_type($1); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), $1); };
choice_option: T_OPTIONAL T_EOL @@ -322,18 +280,25 @@ choice_option: T_OPTIONAL T_EOL
choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL { - if ($1->stype == S_UNKNOWN) { - menu_add_symbol(P_DEFAULT, $2, $3); - printd(DEBUG_PARSE, "%s:%d:default\n", - zconf_curname(), zconf_lineno()); - } else - YYERROR; + menu_add_symbol(P_DEFAULT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); };
-choice_block: - /* empty */ - | choice_block common_stmt -; +type: + logic_type + | T_INT { $$ = S_INT; } + | T_HEX { $$ = S_HEX; } + | T_STRING { $$ = S_STRING; } + +logic_type: + T_BOOL { $$ = S_BOOLEAN; } + | T_TRISTATE { $$ = S_TRISTATE; } + +default: + T_DEFAULT { $$ = S_UNKNOWN; } + | T_DEF_BOOL { $$ = S_BOOLEAN; } + | T_DEF_TRISTATE { $$ = S_TRISTATE; }
/* if entry */
@@ -347,55 +312,50 @@ if_entry: T_IF expr T_EOL
if_end: end { - if (zconf_endtoken($1, T_IF, T_ENDIF)) { + if (zconf_endtoken($1, "if")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); } };
-if_stmt: if_entry if_block if_end +if_stmt: if_entry stmt_list if_end ;
-if_block: - /* empty */ - | if_block common_stmt - | if_block menu_stmt - | if_block choice_stmt +if_stmt_in_choice: if_entry stmt_list_in_choice if_end ;
/* menu entry */
-menu: T_MENU prompt T_EOL +menu: T_MENU T_WORD_QUOTE T_EOL { menu_add_entry(NULL); menu_add_prompt(P_MENU, $2, NULL); printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); };
-menu_entry: menu visibility_list depends_list +menu_entry: menu menu_option_list { $$ = menu_add_menu(); };
menu_end: end { - if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { + if (zconf_endtoken($1, "menu")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); } };
-menu_stmt: menu_entry menu_block menu_end +menu_stmt: menu_entry stmt_list menu_end ;
-menu_block: +menu_option_list: /* empty */ - | menu_block common_stmt - | menu_block menu_stmt - | menu_block choice_stmt + | menu_option_list visible + | menu_option_list depends ;
-source_stmt: T_SOURCE prompt T_EOL +source_stmt: T_SOURCE T_WORD_QUOTE T_EOL { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); zconf_nextfile($2); @@ -404,14 +364,19 @@ source_stmt: T_SOURCE prompt T_EOL
/* comment entry */
-comment: T_COMMENT prompt T_EOL +comment: T_COMMENT T_WORD_QUOTE T_EOL { menu_add_entry(NULL); menu_add_prompt(P_COMMENT, $2, NULL); printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); };
-comment_stmt: comment depends_list +comment_stmt: comment comment_option_list +; + +comment_option_list: + /* empty */ + | comment_option_list depends ;
/* help option */ @@ -440,13 +405,6 @@ help: help_start T_HELPTEXT
/* depends option */
-depends_list: - /* empty */ - | depends_list depends - | depends_list T_EOL - | depends_list option_error -; - depends: T_DEPENDS T_ON expr T_EOL { menu_add_dep($3); @@ -454,14 +412,7 @@ depends: T_DEPENDS T_ON expr T_EOL };
/* visibility option */ - -visibility_list: - /* empty */ - | visibility_list visible - | visibility_list T_EOL -; - -visible: T_VISIBLE if_expr +visible: T_VISIBLE if_expr T_EOL { menu_add_visibility($2); }; @@ -470,23 +421,14 @@ visible: T_VISIBLE if_expr
prompt_stmt_opt: /* empty */ - | prompt if_expr + | T_WORD_QUOTE if_expr { menu_add_prompt(P_PROMPT, $1, $2); };
-prompt: T_WORD - | T_WORD_QUOTE -; - -end: T_ENDMENU T_EOL { $$ = $1; } - | T_ENDCHOICE T_EOL { $$ = $1; } - | T_ENDIF T_EOL { $$ = $1; } -; - -nl: - T_EOL - | nl T_EOL +end: T_ENDMENU T_EOL { $$ = "menu"; } + | T_ENDCHOICE T_EOL { $$ = "choice"; } + | T_ENDIF T_EOL { $$ = "if"; } ;
if_expr: /* empty */ { $$ = NULL; } @@ -518,7 +460,13 @@ word_opt: /* empty */ { $$ = NULL; }
/* assignment statement */
-assignment_stmt: T_VARIABLE T_ASSIGN assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } +assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } + +assign_op: + T_EQUAL { $$ = VAR_RECURSIVE; } + | T_COLON_EQUAL { $$ = VAR_SIMPLE; } + | T_PLUS_EQUAL { $$ = VAR_APPEND; } +;
assign_val: /* empty */ { $$ = xstrdup(""); }; @@ -560,38 +508,24 @@ void conf_parse(const char *name) } if (yynerrs) exit(1); - sym_set_change_count(1); -} - -static const char *zconf_tokenname(int token) -{ - switch (token) { - case T_MENU: return "menu"; - case T_ENDMENU: return "endmenu"; - case T_CHOICE: return "choice"; - case T_ENDCHOICE: return "endchoice"; - case T_IF: return "if"; - case T_ENDIF: return "endif"; - case T_DEPENDS: return "depends"; - case T_VISIBLE: return "visible"; - } - return "<token>"; + conf_set_changed(true); }
-static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken) +static bool zconf_endtoken(const char *tokenname, + const char *expected_tokenname) { - if (id->token != endtoken) { + if (strcmp(tokenname, expected_tokenname)) { zconf_error("unexpected '%s' within %s block", - id->name, zconf_tokenname(starttoken)); + tokenname, expected_tokenname); yynerrs++; return false; } if (current_menu->file != current_file) { zconf_error("'%s' in different file than '%s'", - id->name, zconf_tokenname(starttoken)); + tokenname, expected_tokenname); fprintf(stderr, "%s:%d: location of the '%s'\n", current_menu->file->name, current_menu->lineno, - zconf_tokenname(starttoken)); + expected_tokenname); yynerrs++; return false; } @@ -719,7 +653,7 @@ static void print_symbol(FILE *out, struct menu *menu) break; case P_SYMBOL: fputs( " symbol ", out); - fprintf(out, "%s\n", prop->sym->name); + fprintf(out, "%s\n", prop->menu->sym->name); break; default: fprintf(out, " unknown prop %d!\n", prop->type); @@ -780,11 +714,3 @@ void zconfdump(FILE *out) } } } - -#include "zconf.lex.c" -#include "util.c" -#include "confdata.c" -#include "expr.c" -#include "symbol.c" -#include "menu.c" -#include "preprocess.c" diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c index 5ca2df790d3c..748da578b418 100644 --- a/scripts/kconfig/preprocess.c +++ b/scripts/kconfig/preprocess.c @@ -2,6 +2,7 @@ // // Copyright (C) 2018 Masahiro Yamada yamada.masahiro@socionext.com
+#include <ctype.h> #include <stdarg.h> #include <stdbool.h> #include <stdio.h> @@ -9,10 +10,12 @@ #include <string.h>
#include "list.h" +#include "lkc.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
static char *expand_string_with_args(const char *in, int argc, char *argv[]); +static char *expand_string(const char *in);
static void __attribute__((noreturn)) pperror(const char *format, ...) { @@ -111,7 +114,7 @@ static char *do_error_if(int argc, char *argv[]) if (!strcmp(argv[0], "y")) pperror("%s", argv[1]);
- return NULL; + return xstrdup(""); }
static char *do_filename(int argc, char *argv[]) @@ -138,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; @@ -548,15 +551,14 @@ static char *expand_string_with_args(const char *in, int argc, char *argv[]) return __expand_string(&in, is_end_of_str, argc, argv); }
-char *expand_string(const char *in) +static char *expand_string(const char *in) { return expand_string_with_args(in, 0, NULL); }
static bool is_end_of_token(char c) { - /* Why are '.' and '/' valid characters for symbols? */ - return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/'); + return !(isalnum(c) || c == '_' || c == '-'); }
/* diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh index 02ccc0ae1031..117f36e568fc 100755 --- a/scripts/kconfig/qconf-cfg.sh +++ b/scripts/kconfig/qconf-cfg.sh @@ -1,32 +1,29 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0
+cflags=$1 +libs=$2 +bin=$3 + PKG="Qt5Core Qt5Gui Qt5Widgets" -PKG2="QtCore QtGui"
-if [ -z "$(command -v pkg-config)" ]; then +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 Qt5Core Qt5Gui Qt5Widgets)" - echo libs="$(pkg-config --libs $PKG)" - echo moc="$(pkg-config --variable=host_bins Qt5Core)/moc" - exit 0 -fi - -if pkg-config --exists $PKG2; then - echo cflags="$(pkg-config --cflags $PKG2)" - echo libs="$(pkg-config --libs $PKG2)" - echo moc="$(pkg-config --variable=moc_location QtCore)" +if ${HOSTPKG_CONFIG} --exists $PKG; then + ${HOSTPKG_CONFIG} --cflags ${PKG} > ${cflags} + ${HOSTPKG_CONFIG} --libs ${PKG} > ${libs} + ${HOSTPKG_CONFIG} --variable=host_bins Qt5Core > ${bin} exit 0 fi
echo >&2 "*" -echo >&2 "* Could not find Qt via pkg-config." -echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH" +echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}." +echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH" +echo >&2 "* You need $PKG" echo >&2 "*" exit 1 diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 0c3fa9405684..78087b2d9ac6 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1,38 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org * Copyright (C) 2015 Boris Barbulovski bbarbulovski@gmail.com - * Released under the terms of the GNU GPL v2.0. */
-#include <qglobal.h> - -#include <QMainWindow> -#include <QList> -#include <qtextbrowser.h> #include <QAction> +#include <QApplication> +#include <QCloseEvent> +#include <QDebug> +#include <QDesktopWidget> #include <QFileDialog> +#include <QLabel> +#include <QLayout> +#include <QList> #include <QMenu> - -#include <qapplication.h> -#include <qdesktopwidget.h> -#include <qtoolbar.h> -#include <qlayout.h> -#include <qsplitter.h> -#include <qlineedit.h> -#include <qlabel.h> -#include <qpushbutton.h> -#include <qmenubar.h> -#include <qmessagebox.h> -#include <qregexp.h> -#include <qevent.h> +#include <QMenuBar> +#include <QMessageBox> +#include <QToolBar>
#include <stdlib.h>
#include "lkc.h" #include "qconf.h"
-#include "qconf.moc" -#include "images.c" +#include "images.h"
static QApplication *configApp; @@ -40,11 +31,6 @@ static ConfigSettings *configSettings;
QAction *ConfigMainWindow::saveAction;
-static inline QString qgettext(const char* str) -{ - return QString::fromLocal8Bit(str); -} - ConfigSettings::ConfigSettings() : QSettings("kernel.org", "qconf") { @@ -88,14 +74,13 @@ bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value) return true; }
- -/* - * set the new data - * TODO check the value - */ -void ConfigItem::okRename(int col) -{ -} +QIcon ConfigItem::symbolYesIcon; +QIcon ConfigItem::symbolModIcon; +QIcon ConfigItem::symbolNoIcon; +QIcon ConfigItem::choiceYesIcon; +QIcon ConfigItem::choiceNoIcon; +QIcon ConfigItem::menuIcon; +QIcon ConfigItem::menubackIcon;
/* * update the displayed of a menu entry @@ -111,14 +96,14 @@ void ConfigItem::updateMenu(void)
list = listView(); if (goParent) { - setPixmap(promptColIdx, list->menuBackPix); + setIcon(promptColIdx, menubackIcon); prompt = ".."; goto set_prompt; }
sym = menu->sym; prop = menu->prompt; - prompt = qgettext(menu_get_prompt(menu)); + prompt = menu_get_prompt(menu);
if (prop) switch (prop->type) { case P_MENU: @@ -128,15 +113,16 @@ void ConfigItem::updateMenu(void) */ if (sym && list->rootEntry == menu) break; - setPixmap(promptColIdx, list->menuPix); + setIcon(promptColIdx, menuIcon); } else { if (sym) break; - setPixmap(promptColIdx, QIcon()); + setIcon(promptColIdx, QIcon()); } goto set_prompt; case P_COMMENT: - setPixmap(promptColIdx, QIcon()); + setIcon(promptColIdx, QIcon()); + prompt = "*** " + prompt + " ***"; goto set_prompt; default: ; @@ -144,7 +130,7 @@ void ConfigItem::updateMenu(void) if (!sym) goto set_prompt;
- setText(nameColIdx, QString::fromLocal8Bit(sym->name)); + setText(nameColIdx, sym->name);
type = sym_get_type(sym); switch (type) { @@ -152,58 +138,38 @@ void ConfigItem::updateMenu(void) case S_TRISTATE: char ch;
- if (!sym_is_changable(sym) && list->optMode == normalOpt) { - setPixmap(promptColIdx, QIcon()); - setText(noColIdx, QString::null); - setText(modColIdx, QString::null); - setText(yesColIdx, QString::null); + if (!sym_is_changeable(sym) && list->optMode == normalOpt) { + setIcon(promptColIdx, QIcon()); break; } expr = sym_get_tristate_value(sym); switch (expr) { case yes: if (sym_is_choice_value(sym) && type == S_BOOLEAN) - setPixmap(promptColIdx, list->choiceYesPix); + setIcon(promptColIdx, choiceYesIcon); else - setPixmap(promptColIdx, list->symbolYesPix); - setText(yesColIdx, "Y"); + setIcon(promptColIdx, symbolYesIcon); ch = 'Y'; break; case mod: - setPixmap(promptColIdx, list->symbolModPix); - setText(modColIdx, "M"); + setIcon(promptColIdx, symbolModIcon); ch = 'M'; break; default: if (sym_is_choice_value(sym) && type == S_BOOLEAN) - setPixmap(promptColIdx, list->choiceNoPix); + setIcon(promptColIdx, choiceNoIcon); else - setPixmap(promptColIdx, list->symbolNoPix); - setText(noColIdx, "N"); + setIcon(promptColIdx, symbolNoIcon); ch = 'N'; break; } - if (expr != no) - setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0); - if (expr != mod) - setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0); - if (expr != yes) - setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
setText(dataColIdx, QChar(ch)); break; case S_INT: case S_HEX: case S_STRING: - const char* data; - - data = sym_get_string_value(sym); - - setText(dataColIdx, data); - if (type == S_STRING) - prompt = QString("%1: %2").arg(prompt).arg(data); - else - prompt = QString("(%2) %1").arg(prompt).arg(data); + setText(dataColIdx, sym_get_string_value(sym)); break; } if (!sym_has_value(sym) && visible) @@ -244,6 +210,17 @@ void ConfigItem::init(void) if (list->mode != fullMode) setExpanded(true); sym_calc_value(menu->sym); + + if (menu->sym) { + enum symbol_type type = menu->sym->type; + + // Allow to edit "int", "hex", and "string" in-place in + // the data column. Unfortunately, you cannot specify + // the flags per column. Set ItemIsEditable for all + // columns here, and check the column in createEditor(). + if (type == S_INT || type == S_HEX || type == S_STRING) + setFlags(flags() | Qt::ItemIsEditable); + } } updateMenu(); } @@ -264,53 +241,67 @@ ConfigItem::~ConfigItem(void) } }
-ConfigLineEdit::ConfigLineEdit(ConfigView* parent) - : Parent(parent) +QWidget *ConfigItemDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const { - connect(this, SIGNAL(editingFinished()), SLOT(hide())); -} + ConfigItem *item;
-void ConfigLineEdit::show(ConfigItem* i) -{ - item = i; - if (sym_get_string_value(item->menu->sym)) - setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym))); - else - setText(QString::null); - Parent::show(); - setFocus(); + // Only the data column is editable + if (index.column() != dataColIdx) + return nullptr; + + // You cannot edit invisible menus + item = static_cast<ConfigItem *>(index.internalPointer()); + if (!item || !item->menu || !menu_is_visible(item->menu)) + return nullptr; + + return QStyledItemDelegate::createEditor(parent, option, index); }
-void ConfigLineEdit::keyPressEvent(QKeyEvent* e) +void ConfigItemDelegate::setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const { - switch (e->key()) { - case Qt::Key_Escape: - break; - case Qt::Key_Return: - case Qt::Key_Enter: - sym_set_string_value(item->menu->sym, text().toLatin1()); - parent()->updateList(item); - break; - default: - Parent::keyPressEvent(e); - return; + QLineEdit *lineEdit; + ConfigItem *item; + struct symbol *sym; + bool success; + + lineEdit = qobject_cast<QLineEdit *>(editor); + // If this is not a QLineEdit, use the parent's default. + // (does this happen?) + if (!lineEdit) + goto parent; + + item = static_cast<ConfigItem *>(index.internalPointer()); + if (!item || !item->menu) + goto parent; + + sym = item->menu->sym; + if (!sym) + goto parent; + + success = sym_set_string_value(sym, lineEdit->text().toUtf8().data()); + if (success) { + ConfigList::updateListForAll(); + } else { + QMessageBox::information(editor, "qconf", + "Cannot set the data (maybe due to out of range).\n" + "Setting the old value."); + lineEdit->setText(sym_get_string_value(sym)); } - e->accept(); - parent()->list->setFocus(); - hide(); + +parent: + QStyledItemDelegate::setModelData(editor, model, index); }
-ConfigList::ConfigList(ConfigView* p, const char *name) - : Parent(p), +ConfigList::ConfigList(QWidget *parent, const char *name) + : QTreeWidget(parent), updateAll(false), - symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), - choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), - menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), - showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt), + showName(false), mode(singleMode), optMode(normalOpt), rootEntry(0), headerPopup(0) { - int i; - setObjectName(name); setSortingEnabled(false); setRootIsDecorated(true); @@ -318,26 +309,34 @@ ConfigList::ConfigList(ConfigView* p, const char *name) setVerticalScrollMode(ScrollPerPixel); setHorizontalScrollMode(ScrollPerPixel);
- setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); + setHeaderLabels(QStringList() << "Option" << "Name" << "Value");
- connect(this, SIGNAL(itemSelectionChanged(void)), - SLOT(updateSelection(void))); + connect(this, &ConfigList::itemSelectionChanged, + this, &ConfigList::updateSelection);
if (name) { configSettings->beginGroup(name); showName = configSettings->value("/showName", false).toBool(); - showRange = configSettings->value("/showRange", false).toBool(); - showData = configSettings->value("/showData", false).toBool(); optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt(); configSettings->endGroup(); - connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigList::saveSettings); }
- addColumn(promptColIdx); + showColumn(promptColIdx); + + setItemDelegate(new ConfigItemDelegate(this)); + + allLists.append(this);
reinit(); }
+ConfigList::~ConfigList() +{ + allLists.removeOne(this); +} + bool ConfigList::menuSkip(struct menu *menu) { if (optMode == normalOpt && menu_is_visible(menu)) @@ -351,21 +350,22 @@ bool ConfigList::menuSkip(struct menu *menu)
void ConfigList::reinit(void) { - removeColumn(dataColIdx); - removeColumn(yesColIdx); - removeColumn(modColIdx); - removeColumn(noColIdx); - removeColumn(nameColIdx); + hideColumn(nameColIdx);
if (showName) - addColumn(nameColIdx); - if (showRange) { - addColumn(noColIdx); - addColumn(modColIdx); - addColumn(yesColIdx); - } - if (showData) - addColumn(dataColIdx); + showColumn(nameColIdx); + + updateListAll(); +} + +void ConfigList::setOptionMode(QAction *action) +{ + if (action == showNormalAction) + optMode = normalOpt; + else if (action == showAllAction) + optMode = allOpt; + else + optMode = promptOpt;
updateListAll(); } @@ -375,8 +375,6 @@ void ConfigList::saveSettings(void) if (!objectName().isEmpty()) { configSettings->beginGroup(objectName()); configSettings->setValue("/showName", showName); - configSettings->setValue("/showRange", showRange); - configSettings->setValue("/showData", showData); configSettings->setValue("/optionMode", (int)optMode); configSettings->endGroup(); } @@ -415,15 +413,15 @@ void ConfigList::updateSelection(void) emit menuSelected(menu); }
-void ConfigList::updateList(ConfigItem* item) +void ConfigList::updateList() { ConfigItem* last = 0; + ConfigItem *item;
if (!rootEntry) { if (mode != listMode) goto update; QTreeWidgetItemIterator it(this); - ConfigItem* item;
while (*it) { item = (ConfigItem*)(*it); @@ -445,7 +443,7 @@ void ConfigList::updateList(ConfigItem* item) } if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && rootEntry->sym && rootEntry->prompt) { - item = last ? last->nextSibling() : firstChild(); + item = last ? last->nextSibling() : nullptr; if (!item) item = new ConfigItem(this, last, rootEntry, true); else @@ -457,11 +455,33 @@ void ConfigList::updateList(ConfigItem* item) return; } update: - updateMenuList(this, rootEntry); + updateMenuList(rootEntry); update(); resizeColumnToContents(0); }
+void ConfigList::updateListForAll() +{ + QListIterator<ConfigList *> it(allLists); + + while (it.hasNext()) { + ConfigList *list = it.next(); + + list->updateList(); + } +} + +void ConfigList::updateListAllForAll() +{ + QListIterator<ConfigList *> it(allLists); + + while (it.hasNext()) { + ConfigList *list = it.next(); + + list->updateList(); + } +} + void ConfigList::setValue(ConfigItem* item, tristate val) { struct symbol* sym; @@ -482,7 +502,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val) return; if (oldval == no && item->menu->list) item->setExpanded(true); - parent()->updateList(item); + ConfigList::updateListForAll(); break; } } @@ -516,12 +536,9 @@ void ConfigList::changeValue(ConfigItem* item) item->setExpanded(true); } if (oldexpr != newexpr) - parent()->updateList(item); + ConfigList::updateListForAll(); break; - case S_INT: - case S_HEX: - case S_STRING: - parent()->lineEdit->show(item); + default: break; } } @@ -535,11 +552,11 @@ void ConfigList::setRootMenu(struct menu *menu) type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; if (type != P_MENU) return; - updateMenuList(this, 0); + updateMenuList(0); rootEntry = menu; updateListAll(); if (currentItem()) { - currentItem()->setSelected(hasFocus()); + setSelected(currentItem(), hasFocus()); scrollToItem(currentItem()); } } @@ -627,7 +644,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) last = item; continue; } - hide: +hide: if (item && item->menu == child) { last = parent->firstChild(); if (last == item) @@ -639,7 +656,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) } }
-void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu) +void ConfigList::updateMenuList(struct menu *menu) { struct menu* child; ConfigItem* item; @@ -648,19 +665,19 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu) enum prop_type type;
if (!menu) { - while (parent->topLevelItemCount() > 0) + while (topLevelItemCount() > 0) { - delete parent->takeTopLevelItem(0); + delete takeTopLevelItem(0); }
return; }
- last = (ConfigItem*)parent->topLevelItem(0); + last = (ConfigItem *)topLevelItem(0); if (last && !last->goParent) last = 0; for (child = menu->list; child; child = child->next) { - item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0); + item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0); type = child->prompt ? child->prompt->type : P_UNKNOWN;
switch (mode) { @@ -681,7 +698,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu) if (!child->sym && !child->list && !child->prompt) continue; if (!item || item->menu != child) - item = new ConfigItem(parent, last, child, visible); + item = new ConfigItem(this, last, child, visible); else item->testUpdateMenu(visible);
@@ -692,9 +709,9 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu) last = item; continue; } - hide: +hide: if (item && item->menu == child) { - last = (ConfigItem*)parent->topLevelItem(0); + last = (ConfigItem *)topLevelItem(0); if (last == item) last = 0; else while (last->nextSibling() != item) @@ -736,7 +753,10 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) type = menu->prompt ? menu->prompt->type : P_UNKNOWN; if (type == P_MENU && rootEntry != menu && mode != fullMode && mode != menuMode) { - emit menuSelected(menu); + if (mode == menuMode) + emit menuSelected(menu); + else + emit itemSelected(menu); break; } case Qt::Key_Space: @@ -782,7 +802,7 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e) idx = header()->logicalIndexAt(x); switch (idx) { case promptColIdx: - icon = item->pixmap(promptColIdx); + icon = item->icon(promptColIdx); if (!icon.isNull()) { int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly. if (x >= off && x < off + icon.availableSizes().first().width()) { @@ -793,22 +813,14 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e) break; ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; if (ptype == P_MENU && rootEntry != menu && - mode != fullMode && mode != menuMode) + mode != fullMode && mode != menuMode && + mode != listMode) emit menuSelected(menu); else changeValue(item); } } break; - case noColIdx: - setValue(item, no); - break; - case modColIdx: - setValue(item, mod); - break; - case yesColIdx: - setValue(item, yes); - break; case dataColIdx: changeValue(item); break; @@ -828,7 +840,7 @@ void ConfigList::mouseMoveEvent(QMouseEvent* e)
void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) { - QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport). + QPoint p = e->pos(); ConfigItem* item = (ConfigItem*)itemAt(p); struct menu *menu; enum prop_type ptype; @@ -843,9 +855,12 @@ void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) if (!menu) goto skip; ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - if (ptype == P_MENU && (mode == singleMode || mode == symbolMode)) - emit menuSelected(menu); - else if (menu->sym) + if (ptype == P_MENU && mode != listMode) { + if (mode == singleMode) + emit itemSelected(menu); + else if (mode == symbolMode) + emit menuSelected(menu); + } else if (menu->sym) changeValue(item);
skip: @@ -861,7 +876,7 @@ void ConfigList::focusInEvent(QFocusEvent *e)
ConfigItem* item = (ConfigItem *)currentItem(); if (item) { - item->setSelected(true); + setSelected(item, true); menu = item->menu; } emit gotFocus(menu); @@ -869,114 +884,38 @@ void ConfigList::focusInEvent(QFocusEvent *e)
void ConfigList::contextMenuEvent(QContextMenuEvent *e) { - if (e->y() <= header()->geometry().bottom()) { - if (!headerPopup) { - QAction *action; - - headerPopup = new QMenu(this); - action = new QAction("Show Name", this); - action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), - parent(), SLOT(setShowName(bool))); - connect(parent(), SIGNAL(showNameChanged(bool)), - action, SLOT(setOn(bool))); - action->setChecked(showName); - headerPopup->addAction(action); - action = new QAction("Show Range", this); - action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), - parent(), SLOT(setShowRange(bool))); - connect(parent(), SIGNAL(showRangeChanged(bool)), - action, SLOT(setOn(bool))); - action->setChecked(showRange); - headerPopup->addAction(action); - action = new QAction("Show Data", this); - action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), - parent(), SLOT(setShowData(bool))); - connect(parent(), SIGNAL(showDataChanged(bool)), - action, SLOT(setOn(bool))); - action->setChecked(showData); - headerPopup->addAction(action); - } - headerPopup->exec(e->globalPos()); - e->accept(); - } else - e->ignore(); -} - -ConfigView*ConfigView::viewList; -QAction *ConfigView::showNormalAction; -QAction *ConfigView::showAllAction; -QAction *ConfigView::showPromptAction; - -ConfigView::ConfigView(QWidget* parent, const char *name) - : Parent(parent) -{ - setObjectName(name); - QVBoxLayout *verticalLayout = new QVBoxLayout(this); - verticalLayout->setContentsMargins(0, 0, 0, 0); - - list = new ConfigList(this); - verticalLayout->addWidget(list); - lineEdit = new ConfigLineEdit(this); - lineEdit->hide(); - verticalLayout->addWidget(lineEdit); - - this->nextView = viewList; - viewList = this; -} - -ConfigView::~ConfigView(void) -{ - ConfigView** vp; - - for (vp = &viewList; *vp; vp = &(*vp)->nextView) { - if (*vp == this) { - *vp = nextView; - break; - } + if (!headerPopup) { + QAction *action; + + headerPopup = new QMenu(this); + action = new QAction("Show Name", this); + action->setCheckable(true); + connect(action, &QAction::toggled, + this, &ConfigList::setShowName); + connect(this, &ConfigList::showNameChanged, + action, &QAction::setChecked); + action->setChecked(showName); + headerPopup->addAction(action); } -}
-void ConfigView::setOptionMode(QAction *act) -{ - if (act == showNormalAction) - list->optMode = normalOpt; - else if (act == showAllAction) - list->optMode = allOpt; - else - list->optMode = promptOpt; - - list->updateListAll(); + headerPopup->exec(e->globalPos()); + e->accept(); }
-void ConfigView::setShowName(bool b) +void ConfigList::setShowName(bool on) { - if (list->showName != b) { - list->showName = b; - list->reinit(); - emit showNameChanged(b); - } -} + if (showName == on) + return;
-void ConfigView::setShowRange(bool b) -{ - if (list->showRange != b) { - list->showRange = b; - list->reinit(); - emit showRangeChanged(b); - } + showName = on; + reinit(); + emit showNameChanged(on); }
-void ConfigView::setShowData(bool b) -{ - if (list->showData != b) { - list->showData = b; - list->reinit(); - emit showDataChanged(b); - } -} +QList<ConfigList *> ConfigList::allLists; +QAction *ConfigList::showNormalAction; +QAction *ConfigList::showAllAction; +QAction *ConfigList::showPromptAction;
void ConfigList::setAllOpen(bool open) { @@ -989,34 +928,31 @@ void ConfigList::setAllOpen(bool open) } }
-void ConfigView::updateList(ConfigItem* item) -{ - ConfigView* v; - - for (v = viewList; v; v = v->nextView) - v->list->updateList(item); -} - -void ConfigView::updateListAll(void) -{ - ConfigView* v; - - for (v = viewList; v; v = v->nextView) - v->list->updateListAll(); -} - ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) : Parent(parent), sym(0), _menu(0) { setObjectName(name); - + setOpenLinks(false);
if (!objectName().isEmpty()) { configSettings->beginGroup(objectName()); setShowDebug(configSettings->value("/showDebug", false).toBool()); configSettings->endGroup(); - connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigInfoView::saveSettings); } + + contextMenu = createStandardContextMenu(); + QAction *action = new QAction("Show Debug Info", contextMenu); + + action->setCheckable(true); + connect(action, &QAction::toggled, + this, &ConfigInfoView::setShowDebug); + connect(this, &ConfigInfoView::showDebugChanged, + action, &QAction::setChecked); + action->setChecked(showDebug()); + contextMenu->addSeparator(); + contextMenu->addAction(action); }
void ConfigInfoView::saveSettings(void) @@ -1071,108 +1007,119 @@ void ConfigInfoView::symbolInfo(void) void ConfigInfoView::menuInfo(void) { struct symbol* sym; - QString head, debug, help; + QString info; + QTextStream stream(&info);
sym = _menu->sym; if (sym) { if (_menu->prompt) { - head += "<big><b>"; - head += print_filter(_menu->prompt->text); - head += "</b></big>"; + stream << "<big><b>"; + stream << print_filter(_menu->prompt->text); + stream << "</b></big>"; if (sym->name) { - head += " ("; + stream << " ("; if (showDebug()) - head += QString().sprintf("<a href="s%p">", sym); - head += print_filter(sym->name); + stream << "<a href="s" << sym->name << "">"; + stream << print_filter(sym->name); if (showDebug()) - head += "</a>"; - head += ")"; + stream << "</a>"; + stream << ")"; } } else if (sym->name) { - head += "<big><b>"; + stream << "<big><b>"; if (showDebug()) - head += QString().sprintf("<a href="s%p">", sym); - head += print_filter(sym->name); + stream << "<a href="s" << sym->name << "">"; + stream << print_filter(sym->name); if (showDebug()) - head += "</a>"; - head += "</b></big>"; + stream << "</a>"; + stream << "</b></big>"; } - head += "<br><br>"; + stream << "<br><br>";
if (showDebug()) - debug = debug_info(sym); + stream << debug_info(sym);
struct gstr help_gstr = str_new(); + menu_get_ext_help(_menu, &help_gstr); - help = print_filter(str_get(&help_gstr)); + stream << print_filter(str_get(&help_gstr)); str_free(&help_gstr); } else if (_menu->prompt) { - head += "<big><b>"; - head += print_filter(_menu->prompt->text); - head += "</b></big><br><br>"; + stream << "<big><b>"; + stream << print_filter(_menu->prompt->text); + stream << "</b></big><br><br>"; if (showDebug()) { if (_menu->prompt->visible.expr) { - debug += " dep: "; - expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); - debug += "<br><br>"; + stream << " dep: "; + expr_print(_menu->prompt->visible.expr, + expr_print_help, &stream, E_NONE); + stream << "<br><br>"; } + + stream << "defined at " << _menu->file->name << ":" + << _menu->lineno << "<br><br>"; } } - if (showDebug()) - debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
- setText(head + debug + help); + setText(info); }
QString ConfigInfoView::debug_info(struct symbol *sym) { QString debug; + QTextStream stream(&debug);
- debug += "type: "; - debug += print_filter(sym_type_name(sym->type)); + stream << "type: "; + stream << print_filter(sym_type_name(sym->type)); if (sym_is_choice(sym)) - debug += " (choice)"; + stream << " (choice)"; debug += "<br>"; if (sym->rev_dep.expr) { - debug += "reverse dep: "; - expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE); - debug += "<br>"; + stream << "reverse dep: "; + expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE); + stream << "<br>"; } for (struct property *prop = sym->prop; prop; prop = prop->next) { switch (prop->type) { case P_PROMPT: case P_MENU: - debug += QString().sprintf("prompt: <a href="m%p">", prop->menu); - debug += print_filter(prop->text); - debug += "</a><br>"; + stream << "prompt: <a href="m" << sym->name << "">"; + stream << print_filter(prop->text); + stream << "</a><br>"; break; case P_DEFAULT: case P_SELECT: case P_RANGE: - debug += prop_get_type_name(prop->type); - debug += ": "; - expr_print(prop->expr, expr_print_help, &debug, E_NONE); - debug += "<br>"; + case P_COMMENT: + case P_IMPLY: + case P_SYMBOL: + stream << prop_get_type_name(prop->type); + stream << ": "; + expr_print(prop->expr, expr_print_help, + &stream, E_NONE); + stream << "<br>"; break; case P_CHOICE: if (sym_is_choice(sym)) { - debug += "choice: "; - expr_print(prop->expr, expr_print_help, &debug, E_NONE); - debug += "<br>"; + stream << "choice: "; + expr_print(prop->expr, expr_print_help, + &stream, E_NONE); + stream << "<br>"; } break; default: - debug += "unknown property: "; - debug += prop_get_type_name(prop->type); - debug += "<br>"; + stream << "unknown property: "; + stream << prop_get_type_name(prop->type); + stream << "<br>"; } if (prop->visible.expr) { - debug += " dep: "; - expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); - debug += "<br>"; + stream << " dep: "; + expr_print(prop->visible.expr, expr_print_help, + &stream, E_NONE); + stream << "<br>"; } } - debug += "<br>"; + stream << "<br>";
return debug; } @@ -1210,88 +1157,125 @@ QString ConfigInfoView::print_filter(const QString &str)
void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str) { - QString* text = reinterpret_cast<QString*>(data); - QString str2 = print_filter(str); + QTextStream *stream = reinterpret_cast<QTextStream *>(data);
if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { - *text += QString().sprintf("<a href="s%p">", sym); - *text += str2; - *text += "</a>"; - } else - *text += str2; + *stream << "<a href="s" << sym->name << "">"; + *stream << print_filter(str); + *stream << "</a>"; + } else { + *stream << print_filter(str); + } }
-QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) +void ConfigInfoView::clicked(const QUrl &url) { - QMenu* popup = Parent::createStandardContextMenu(pos); - QAction* action = new QAction("Show Debug Info", popup); - action->setCheckable(true); - connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); - connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); - action->setChecked(showDebug()); - popup->addSeparator(); - popup->addAction(action); - return popup; + QByteArray str = url.toEncoded(); + const std::size_t count = str.size(); + char *data = new char[count + 1]; + struct symbol **result; + struct menu *m = NULL; + + if (count < 1) { + delete[] data; + return; + } + + memcpy(data, str.constData(), count); + data[count] = '\0'; + + /* Seek for exact match */ + data[0] = '^'; + strcat(data, "$"); + result = sym_re_search(data); + if (!result) { + delete[] data; + return; + } + + sym = *result; + + /* Seek for the menu which holds the symbol */ + for (struct property *prop = sym->prop; prop; prop = prop->next) { + if (prop->type != P_PROMPT && prop->type != P_MENU) + continue; + m = prop->menu; + break; + } + + if (!m) { + /* Symbol is not visible as a menu */ + symbolInfo(); + emit showDebugChanged(true); + } else { + emit menuSelected(m); + } + + free(result); + delete[] data; }
-void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e) +void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event) { - Parent::contextMenuEvent(e); + contextMenu->popup(event->globalPos()); + event->accept(); }
-ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name) +ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) : Parent(parent), result(NULL) { - setObjectName(name); + setObjectName("search"); setWindowTitle("Search Config");
QVBoxLayout* layout1 = new QVBoxLayout(this); layout1->setContentsMargins(11, 11, 11, 11); layout1->setSpacing(6); - QHBoxLayout* layout2 = new QHBoxLayout(0); + + QHBoxLayout* layout2 = new QHBoxLayout(); layout2->setContentsMargins(0, 0, 0, 0); layout2->setSpacing(6); layout2->addWidget(new QLabel("Find:", this)); editField = new QLineEdit(this); - connect(editField, SIGNAL(returnPressed()), SLOT(search())); + connect(editField, &QLineEdit::returnPressed, + this, &ConfigSearchWindow::search); layout2->addWidget(editField); searchButton = new QPushButton("Search", this); searchButton->setAutoDefault(false); - connect(searchButton, SIGNAL(clicked()), SLOT(search())); + connect(searchButton, &QPushButton::clicked, + this, &ConfigSearchWindow::search); layout2->addWidget(searchButton); layout1->addLayout(layout2);
split = new QSplitter(this); split->setOrientation(Qt::Vertical); - list = new ConfigView(split, name); - list->list->mode = listMode; - info = new ConfigInfoView(split, name); - connect(list->list, SIGNAL(menuChanged(struct menu *)), - info, SLOT(setInfo(struct menu *))); - connect(list->list, SIGNAL(menuChanged(struct menu *)), - parent, SLOT(setMenuLink(struct menu *))); + list = new ConfigList(split, "search"); + list->mode = listMode; + info = new ConfigInfoView(split, "search"); + connect(list, &ConfigList::menuChanged, + info, &ConfigInfoView::setInfo); + connect(list, &ConfigList::menuChanged, + parent, &ConfigMainWindow::setMenuLink);
layout1->addWidget(split);
- if (name) { - QVariant x, y; - int width, height; - bool ok; + QVariant x, y; + int width, height; + bool ok;
- configSettings->beginGroup(name); - width = configSettings->value("/window width", parent->width() / 2).toInt(); - height = configSettings->value("/window height", parent->height() / 2).toInt(); - resize(width, height); - x = configSettings->value("/window x"); - y = configSettings->value("/window y"); - if ((x.isValid())&&(y.isValid())) - move(x.toInt(), y.toInt()); - QList<int> sizes = configSettings->readSizes("/split", &ok); - if (ok) - split->setSizes(sizes); - configSettings->endGroup(); - connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); - } + configSettings->beginGroup("search"); + width = configSettings->value("/window width", parent->width() / 2).toInt(); + height = configSettings->value("/window height", parent->height() / 2).toInt(); + resize(width, height); + x = configSettings->value("/window x"); + y = configSettings->value("/window y"); + if (x.isValid() && y.isValid()) + move(x.toInt(), y.toInt()); + QList<int> sizes = configSettings->readSizes("/split", &ok); + if (ok) + split->setSizes(sizes); + configSettings->endGroup(); + connect(configApp, &QApplication::aboutToQuit, + this, &ConfigSearchWindow::saveSettings); }
void ConfigSearchWindow::saveSettings(void) @@ -1314,7 +1298,7 @@ void ConfigSearchWindow::search(void) ConfigItem *lastItem = NULL;
free(result); - list->list->clear(); + list->clear(); info->clear();
result = sym_re_search(editField->text().toLatin1()); @@ -1322,7 +1306,7 @@ void ConfigSearchWindow::search(void) return; for (p = result; *p; p++) { for_all_prompts((*p), prop) - lastItem = new ConfigItem(list->list, lastItem, prop->menu, + lastItem = new ConfigItem(list, lastItem, prop->menu, menu_is_visible(prop->menu)); } } @@ -1333,7 +1317,6 @@ void ConfigSearchWindow::search(void) ConfigMainWindow::ConfigMainWindow(void) : searchWindow(0) { - QMenuBar* menu; bool ok = true; QVariant x, y; int width, height; @@ -1354,95 +1337,123 @@ ConfigMainWindow::ConfigMainWindow(void) if ((x.isValid())&&(y.isValid())) move(x.toInt(), y.toInt());
- split1 = new QSplitter(this); + // set up icons + ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); + ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); + ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); + ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); + ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); + ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); + ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); + + QWidget *widget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(widget); + setCentralWidget(widget); + + split1 = new QSplitter(widget); split1->setOrientation(Qt::Horizontal); - setCentralWidget(split1); + split1->setChildrenCollapsible(false);
- menuView = new ConfigView(split1, "menu"); - menuList = menuView->list; + menuList = new ConfigList(widget, "menu");
- split2 = new QSplitter(split1); + split2 = new QSplitter(widget); + split2->setChildrenCollapsible(false); split2->setOrientation(Qt::Vertical);
// create config tree - configView = new ConfigView(split2, "config"); - configList = configView->list; + configList = new ConfigList(widget, "config"); + + helpText = new ConfigInfoView(widget, "help");
- helpText = new ConfigInfoView(split2, "help"); + layout->addWidget(split2); + split2->addWidget(split1); + split1->addWidget(configList); + split1->addWidget(menuList); + split2->addWidget(helpText);
setTabOrder(configList, helpText); configList->setFocus();
- menu = menuBar(); - toolBar = new QToolBar("Tools", this); - addToolBar(toolBar); - backAction = new QAction(QPixmap(xpm_back), "Back", this); - connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); - backAction->setEnabled(false); + connect(backAction, &QAction::triggered, + this, &ConfigMainWindow::goBack); + QAction *quitAction = new QAction("&Quit", this); quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); - connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); + connect(quitAction, &QAction::triggered, + this, &ConfigMainWindow::close); + QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); loadAction->setShortcut(Qt::CTRL + Qt::Key_L); - connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); + connect(loadAction, &QAction::triggered, + this, &ConfigMainWindow::loadConfig); + saveAction = new QAction(QPixmap(xpm_save), "&Save", this); saveAction->setShortcut(Qt::CTRL + Qt::Key_S); - connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); + connect(saveAction, &QAction::triggered, + this, &ConfigMainWindow::saveConfig); + conf_set_changed_callback(conf_changed); + // Set saveAction's initial state conf_changed(); + configname = xstrdup(conf_get_configname()); + QAction *saveAsAction = new QAction("Save &As...", this); - connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs())); + connect(saveAsAction, &QAction::triggered, + this, &ConfigMainWindow::saveConfigAs); QAction *searchAction = new QAction("&Find", this); searchAction->setShortcut(Qt::CTRL + Qt::Key_F); - connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig())); + connect(searchAction, &QAction::triggered, + this, &ConfigMainWindow::searchConfig); singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); singleViewAction->setCheckable(true); - connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView())); + connect(singleViewAction, &QAction::triggered, + this, &ConfigMainWindow::showSingleView); splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); splitViewAction->setCheckable(true); - connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView())); + connect(splitViewAction, &QAction::triggered, + this, &ConfigMainWindow::showSplitView); fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); fullViewAction->setCheckable(true); - connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView())); + connect(fullViewAction, &QAction::triggered, + this, &ConfigMainWindow::showFullView);
QAction *showNameAction = new QAction("Show Name", this); showNameAction->setCheckable(true); - connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); - showNameAction->setChecked(configView->showName()); - QAction *showRangeAction = new QAction("Show Range", this); - showRangeAction->setCheckable(true); - connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); - QAction *showDataAction = new QAction("Show Data", this); - showDataAction->setCheckable(true); - connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); + connect(showNameAction, &QAction::toggled, + configList, &ConfigList::setShowName); + showNameAction->setChecked(configList->showName);
QActionGroup *optGroup = new QActionGroup(this); optGroup->setExclusive(true); - connect(optGroup, SIGNAL(triggered(QAction*)), configView, - SLOT(setOptionMode(QAction *))); - connect(optGroup, SIGNAL(triggered(QAction *)), menuView, - SLOT(setOptionMode(QAction *))); - - configView->showNormalAction = new QAction("Show Normal Options", optGroup); - configView->showAllAction = new QAction("Show All Options", optGroup); - configView->showPromptAction = new QAction("Show Prompt Options", optGroup); - configView->showNormalAction->setCheckable(true); - configView->showAllAction->setCheckable(true); - configView->showPromptAction->setCheckable(true); + connect(optGroup, &QActionGroup::triggered, + configList, &ConfigList::setOptionMode); + connect(optGroup, &QActionGroup::triggered, + menuList, &ConfigList::setOptionMode); + + ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup); + ConfigList::showNormalAction->setCheckable(true); + ConfigList::showAllAction = new QAction("Show All Options", optGroup); + ConfigList::showAllAction->setCheckable(true); + ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup); + ConfigList::showPromptAction->setCheckable(true);
QAction *showDebugAction = new QAction("Show Debug Info", this); showDebugAction->setCheckable(true); - connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); + connect(showDebugAction, &QAction::toggled, + helpText, &ConfigInfoView::setShowDebug); showDebugAction->setChecked(helpText->showDebug());
QAction *showIntroAction = new QAction("Introduction", this); - connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro())); + connect(showIntroAction, &QAction::triggered, + this, &ConfigMainWindow::showIntro); QAction *showAboutAction = new QAction("About", this); - connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout())); + connect(showAboutAction, &QAction::triggered, + this, &ConfigMainWindow::showAbout);
// init tool bar + QToolBar *toolBar = addToolBar("Tools"); toolBar->addAction(backAction); toolBar->addSeparator(); toolBar->addAction(loadAction); @@ -1452,53 +1463,55 @@ ConfigMainWindow::ConfigMainWindow(void) toolBar->addAction(splitViewAction); toolBar->addAction(fullViewAction);
- // create config menu - QMenu* config = menu->addMenu("&File"); - config->addAction(loadAction); - config->addAction(saveAction); - config->addAction(saveAsAction); - config->addSeparator(); - config->addAction(quitAction); + // create file menu + QMenu *menu = menuBar()->addMenu("&File"); + menu->addAction(loadAction); + menu->addAction(saveAction); + menu->addAction(saveAsAction); + menu->addSeparator(); + menu->addAction(quitAction);
// create edit menu - QMenu* editMenu = menu->addMenu("&Edit"); - editMenu->addAction(searchAction); + menu = menuBar()->addMenu("&Edit"); + menu->addAction(searchAction);
// create options menu - QMenu* optionMenu = menu->addMenu("&Option"); - optionMenu->addAction(showNameAction); - optionMenu->addAction(showRangeAction); - optionMenu->addAction(showDataAction); - optionMenu->addSeparator(); - optionMenu->addActions(optGroup->actions()); - optionMenu->addSeparator(); - optionMenu->addAction(showDebugAction); + menu = menuBar()->addMenu("&Option"); + menu->addAction(showNameAction); + menu->addSeparator(); + menu->addActions(optGroup->actions()); + menu->addSeparator(); + menu->addAction(showDebugAction);
// create help menu - menu->addSeparator(); - QMenu* helpMenu = menu->addMenu("&Help"); - helpMenu->addAction(showIntroAction); - helpMenu->addAction(showAboutAction); - - connect(configList, SIGNAL(menuChanged(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(configList, SIGNAL(menuSelected(struct menu *)), - SLOT(changeMenu(struct menu *))); - connect(configList, SIGNAL(parentSelected()), - SLOT(goBack())); - connect(menuList, SIGNAL(menuChanged(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(menuList, SIGNAL(menuSelected(struct menu *)), - SLOT(changeMenu(struct menu *))); - - connect(configList, SIGNAL(gotFocus(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(menuList, SIGNAL(gotFocus(struct menu *)), - helpText, SLOT(setInfo(struct menu *))); - connect(menuList, SIGNAL(gotFocus(struct menu *)), - SLOT(listFocusChanged(void))); - connect(helpText, SIGNAL(menuSelected(struct menu *)), - SLOT(setMenuLink(struct menu *))); + menu = menuBar()->addMenu("&Help"); + menu->addAction(showIntroAction); + menu->addAction(showAboutAction); + + connect(helpText, &ConfigInfoView::anchorClicked, + helpText, &ConfigInfoView::clicked); + + connect(configList, &ConfigList::menuChanged, + helpText, &ConfigInfoView::setInfo); + connect(configList, &ConfigList::menuSelected, + this, &ConfigMainWindow::changeMenu); + connect(configList, &ConfigList::itemSelected, + this, &ConfigMainWindow::changeItens); + connect(configList, &ConfigList::parentSelected, + this, &ConfigMainWindow::goBack); + connect(menuList, &ConfigList::menuChanged, + helpText, &ConfigInfoView::setInfo); + connect(menuList, &ConfigList::menuSelected, + this, &ConfigMainWindow::changeMenu); + + connect(configList, &ConfigList::gotFocus, + helpText, &ConfigInfoView::setInfo); + connect(menuList, &ConfigList::gotFocus, + helpText, &ConfigInfoView::setInfo); + connect(menuList, &ConfigList::gotFocus, + this, &ConfigMainWindow::listFocusChanged); + connect(helpText, &ConfigInfoView::menuSelected, + this, &ConfigMainWindow::setMenuLink);
QString listMode = configSettings->value("/listMode", "symbol").toString(); if (listMode == "single") @@ -1520,45 +1533,74 @@ ConfigMainWindow::ConfigMainWindow(void)
void ConfigMainWindow::loadConfig(void) { - QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname()); - if (s.isNull()) + QString str; + QByteArray ba; + const char *name; + + str = QFileDialog::getOpenFileName(this, "", configname); + if (str.isNull()) return; - if (conf_read(QFile::encodeName(s))) + + ba = str.toLocal8Bit(); + name = ba.data(); + + if (conf_read(name)) QMessageBox::information(this, "qconf", "Unable to load configuration!"); - ConfigView::updateListAll(); + + free(configname); + configname = xstrdup(name); + + ConfigList::updateListAllForAll(); }
bool ConfigMainWindow::saveConfig(void) { - if (conf_write(NULL)) { + if (conf_write(configname)) { QMessageBox::information(this, "qconf", "Unable to save configuration!"); return false; } + conf_write_autoconf(0); + return true; }
void ConfigMainWindow::saveConfigAs(void) { - QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname()); - if (s.isNull()) + QString str; + QByteArray ba; + const char *name; + + str = QFileDialog::getSaveFileName(this, "", configname); + if (str.isNull()) return; - saveConfig(); + + ba = str.toLocal8Bit(); + name = ba.data(); + + if (conf_write(name)) { + QMessageBox::information(this, "qconf", "Unable to save configuration!"); + } + conf_write_autoconf(0); + + free(configname); + configname = xstrdup(name); }
void ConfigMainWindow::searchConfig(void) { if (!searchWindow) - searchWindow = new ConfigSearchWindow(this, "search"); + searchWindow = new ConfigSearchWindow(this); searchWindow->show(); }
-void ConfigMainWindow::changeMenu(struct menu *menu) +void ConfigMainWindow::changeItens(struct menu *menu) { configList->setRootMenu(menu); - if (configList->rootEntry->parent == &rootmenu) - backAction->setEnabled(false); - else - backAction->setEnabled(true); +} + +void ConfigMainWindow::changeMenu(struct menu *menu) +{ + menuList->setRootMenu(menu); }
void ConfigMainWindow::setMenuLink(struct menu *menu) @@ -1578,22 +1620,26 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) return; list->setRootMenu(parent); break; - case symbolMode: + case menuMode: if (menu->flags & MENU_ROOT) { - configList->setRootMenu(menu); + menuList->setRootMenu(menu); configList->clearSelection(); - list = menuList; - } else { list = configList; + } else { parent = menu_get_parent_menu(menu->parent); if (!parent) return; - item = menuList->findConfigItem(parent); + + /* Select the config view */ + item = configList->findConfigItem(parent); if (item) { - item->setSelected(true); - menuList->scrollToItem(item); + configList->setSelected(item, true); + configList->scrollToItem(item); } - list->setRootMenu(parent); + + menuList->setRootMenu(parent); + menuList->clearSelection(); + list = menuList; } break; case fullMode: @@ -1606,9 +1652,10 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) if (list) { item = list->findConfigItem(menu); if (item) { - item->setSelected(true); + list->setSelected(item, true); list->scrollToItem(item); list->setFocus(); + helpText->setInfo(menu); } } } @@ -1621,25 +1668,10 @@ void ConfigMainWindow::listFocusChanged(void)
void ConfigMainWindow::goBack(void) { - ConfigItem* item, *oldSelection; - - configList->setParentMenu(); if (configList->rootEntry == &rootmenu) - backAction->setEnabled(false); - - if (menuList->selectedItems().count() == 0) return;
- item = (ConfigItem*)menuList->selectedItems().first(); - oldSelection = item; - while (item) { - if (item->menu == configList->rootEntry) { - oldSelection->setSelected(false); - item->setSelected(true); - break; - } - item = (ConfigItem*)item->parent(); - } + configList->setParentMenu(); }
void ConfigMainWindow::showSingleView(void) @@ -1651,7 +1683,9 @@ void ConfigMainWindow::showSingleView(void) fullViewAction->setEnabled(true); fullViewAction->setChecked(false);
- menuView->hide(); + backAction->setEnabled(true); + + menuList->hide(); menuList->setRootMenu(0); configList->mode = singleMode; if (configList->rootEntry == &rootmenu) @@ -1670,17 +1704,19 @@ void ConfigMainWindow::showSplitView(void) fullViewAction->setEnabled(true); fullViewAction->setChecked(false);
- configList->mode = symbolMode; + backAction->setEnabled(false); + + configList->mode = menuMode; if (configList->rootEntry == &rootmenu) configList->updateListAll(); else configList->setRootMenu(&rootmenu); configList->setAllOpen(true); configApp->processEvents(); - menuList->mode = menuMode; + menuList->mode = symbolMode; menuList->setRootMenu(&rootmenu); menuList->setAllOpen(true); - menuView->show(); + menuList->show(); menuList->setFocus(); }
@@ -1693,7 +1729,9 @@ void ConfigMainWindow::showFullView(void) fullViewAction->setEnabled(false); fullViewAction->setChecked(true);
- menuView->hide(); + backAction->setEnabled(false); + + menuList->hide(); menuList->setRootMenu(0); configList->mode = fullMode; if (configList->rootEntry == &rootmenu) @@ -1705,7 +1743,6 @@ void ConfigMainWindow::showFullView(void)
/* * ask for saving configuration before quitting - * TODO ask only when something changed */ void ConfigMainWindow::closeEvent(QCloseEvent* e) { @@ -1736,17 +1773,26 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
void ConfigMainWindow::showIntro(void) { - static const QString str = "Welcome to the qconf graphical configuration tool.\n\n" - "For each option, a blank box indicates the feature is disabled, a check\n" - "indicates it is enabled, and a dot indicates that it is to be compiled\n" - "as a module. Clicking on the box will cycle through the three states.\n\n" - "If you do not see an option (e.g., a device driver) that you believe\n" - "should be present, try turning on Show All Options under the Options menu.\n" - "Although there is no cross reference yet to help you figure out what other\n" - "options must be enabled to support the option you are interested in, you can\n" - "still view the help of a grayed-out option.\n\n" - "Toggling Show Debug Info under the Options menu will show the dependencies,\n" - "which you can then match by examining other options.\n\n"; + static const QString str = + "Welcome to the qconf graphical configuration tool.\n" + "\n" + "For bool and tristate options, a blank box indicates the " + "feature is disabled, a check indicates it is enabled, and a " + "dot indicates that it is to be compiled as a module. Clicking " + "on the box will cycle through the three states. For int, hex, " + "and string options, double-clicking or pressing F2 on the " + "Value cell will allow you to edit the value.\n" + "\n" + "If you do not see an option (e.g., a device driver) that you " + "believe should be present, try turning on Show All Options " + "under the Options menu. Enabling Show Debug Info will help you" + "figure out what other options must be enabled to support the " + "option you are interested in, and hyperlinks will navigate to " + "them.\n" + "\n" + "Toggling Show Debug Info under the Options menu will show the " + "dependencies, which you can then match by examining other " + "options.\n";
QMessageBox::information(this, "qconf", str); } @@ -1754,10 +1800,13 @@ void ConfigMainWindow::showIntro(void) void ConfigMainWindow::showAbout(void) { static const QString str = "qconf is Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org.\n" - "Copyright (C) 2015 Boris Barbulovski bbarbulovski@gmail.com.\n\n" - "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/%5Cn"; + "Copyright (C) 2015 Boris Barbulovski bbarbulovski@gmail.com.\n" + "\n" + "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/%5Cn" + "\n" + "Qt Version: ";
- QMessageBox::information(this, "qconf", str); + QMessageBox::information(this, "qconf", str + qVersion()); }
void ConfigMainWindow::saveSettings(void) @@ -1826,7 +1875,6 @@ int main(int ac, char** av) const char *name;
progname = av[0]; - configApp = new QApplication(ac, av); if (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { case 's': @@ -1847,6 +1895,8 @@ int main(int ac, char** av) conf_read(NULL); //zconfdump(stdout);
+ configApp = new QApplication(ac, av); + configSettings = new ConfigSettings(); configSettings->beginGroup("/kconfig/qconf"); v = new ConfigMainWindow(); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index a40036d1b059..78b0a1dfcd53 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -1,25 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
-#include <QTextBrowser> -#include <QTreeWidget> -#include <QMainWindow> +#include <QCheckBox> +#include <QDialog> #include <QHeaderView> -#include <qsettings.h> +#include <QLineEdit> +#include <QMainWindow> #include <QPushButton> #include <QSettings> -#include <QLineEdit> #include <QSplitter> -#include <QCheckBox> -#include <QDialog> +#include <QStyledItemDelegate> +#include <QTextBrowser> +#include <QTreeWidget> + #include "expr.h"
-class ConfigView; class ConfigList; class ConfigItem; -class ConfigLineEdit; class ConfigMainWindow;
class ConfigSettings : public QSettings { @@ -30,7 +29,7 @@ public: };
enum colIdx { - promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr + promptColIdx, nameColIdx, dataColIdx }; enum listMode { singleMode, menuMode, symbolMode, fullMode, listMode @@ -43,13 +42,16 @@ class ConfigList : public QTreeWidget { Q_OBJECT typedef class QTreeWidget Parent; public: - ConfigList(ConfigView* p, const char *name = 0); + ConfigList(QWidget *parent, const char *name = 0); + ~ConfigList(); void reinit(void); - ConfigView* parent(void) const - { - return (ConfigView*)Parent::parent(); - } ConfigItem* findConfigItem(struct menu *); + void setSelected(QTreeWidgetItem *item, bool enable) { + for (int i = 0; i < selectedItems().size(); i++) + selectedItems().at(i)->setSelected(false); + + item->setSelected(enable); + }
protected: void keyPressEvent(QKeyEvent *e); @@ -63,61 +65,52 @@ protected: public slots: void setRootMenu(struct menu *menu);
- void updateList(ConfigItem *item); + void updateList(); void setValue(ConfigItem* item, tristate val); void changeValue(ConfigItem* item); void updateSelection(void); void saveSettings(void); + void setOptionMode(QAction *action); + void setShowName(bool on); + signals: void menuChanged(struct menu *menu); void menuSelected(struct menu *menu); + void itemSelected(struct menu *menu); void parentSelected(void); void gotFocus(struct menu *); + void showNameChanged(bool on);
public: void updateListAll(void) { updateAll = true; - updateList(NULL); + updateList(); updateAll = false; } - ConfigList* listView() - { - return this; - } - ConfigItem* firstChild() const - { - return (ConfigItem *)children().first(); - } - void addColumn(colIdx idx) - { - showColumn(idx); - } - void removeColumn(colIdx idx) - { - hideColumn(idx); - } void setAllOpen(bool open); void setParentMenu(void);
bool menuSkip(struct menu *);
void updateMenuList(ConfigItem *parent, struct menu*); - void updateMenuList(ConfigList *parent, struct menu*); + void updateMenuList(struct menu *menu);
bool updateAll;
- QPixmap symbolYesPix, symbolModPix, symbolNoPix; - QPixmap choiceYesPix, choiceNoPix; - QPixmap menuPix, menuInvPix, menuBackPix, voidPix; - - bool showName, showRange, showData; + bool showName; enum listMode mode; enum optionMode optMode; struct menu *rootEntry; QPalette disabledColorGroup; QPalette inactivedColorGroup; QMenu* headerPopup; + + static QList<ConfigList *> allLists; + static void updateListForAll(); + static void updateListAllForAll(); + + static QAction *showNormalAction, *showAllAction, *showPromptAction; };
class ConfigItem : public QTreeWidgetItem { @@ -140,7 +133,6 @@ public: } ~ConfigItem(void); void init(void); - void okRename(int col); void updateMenu(void); void testUpdateMenu(bool v); ConfigList* listView() const @@ -165,82 +157,36 @@ public:
return ret; } - void setText(colIdx idx, const QString& text) - { - Parent::setText(idx, text); - } - QString text(colIdx idx) const - { - return Parent::text(idx); - } - void setPixmap(colIdx idx, const QIcon &icon) - { - Parent::setIcon(idx, icon); - } - const QIcon pixmap(colIdx idx) const - { - return icon(idx); - } // TODO: Implement paintCell
ConfigItem* nextItem; struct menu *menu; bool visible; bool goParent; -};
-class ConfigLineEdit : public QLineEdit { - Q_OBJECT - typedef class QLineEdit Parent; -public: - ConfigLineEdit(ConfigView* parent); - ConfigView* parent(void) const - { - return (ConfigView*)Parent::parent(); - } - void show(ConfigItem *i); - void keyPressEvent(QKeyEvent *e); - -public: - ConfigItem *item; + static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon; + static QIcon choiceYesIcon, choiceNoIcon; + static QIcon menuIcon, menubackIcon; };
-class ConfigView : public QWidget { - Q_OBJECT - typedef class QWidget Parent; -public: - ConfigView(QWidget* parent, const char *name = 0); - ~ConfigView(void); - static void updateList(ConfigItem* item); - static void updateListAll(void); - - bool showName(void) const { return list->showName; } - bool showRange(void) const { return list->showRange; } - bool showData(void) const { return list->showData; } -public slots: - void setShowName(bool); - void setShowRange(bool); - void setShowData(bool); - void setOptionMode(QAction *); -signals: - void showNameChanged(bool); - void showRangeChanged(bool); - void showDataChanged(bool); +class ConfigItemDelegate : public QStyledItemDelegate +{ +private: + struct menu *menu; public: - ConfigList* list; - ConfigLineEdit* lineEdit; - - static ConfigView* viewList; - ConfigView* nextView; - - static QAction *showNormalAction; - static QAction *showAllAction; - static QAction *showPromptAction; + ConfigItemDelegate(QObject *parent = nullptr) + : QStyledItemDelegate(parent) {} + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; };
class ConfigInfoView : public QTextBrowser { Q_OBJECT typedef class QTextBrowser Parent; + QMenu *contextMenu; public: ConfigInfoView(QWidget* parent, const char *name = 0); bool showDebug(void) const { return _showDebug; } @@ -249,6 +195,7 @@ public slots: void setInfo(struct menu *menu); void saveSettings(void); void setShowDebug(bool); + void clicked (const QUrl &url);
signals: void showDebugChanged(bool); @@ -260,8 +207,7 @@ protected: QString debug_info(struct symbol *sym); static QString print_filter(const QString &str); static void expr_print_help(void *data, struct symbol *sym, const char *str); - QMenu *createStandardContextMenu(const QPoint & pos); - void contextMenuEvent(QContextMenuEvent *e); + void contextMenuEvent(QContextMenuEvent *event);
struct symbol *sym; struct menu *_menu; @@ -272,7 +218,7 @@ class ConfigSearchWindow : public QDialog { Q_OBJECT typedef class QDialog Parent; public: - ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0); + ConfigSearchWindow(ConfigMainWindow *parent);
public slots: void saveSettings(void); @@ -282,7 +228,7 @@ protected: QLineEdit* editField; QPushButton* searchButton; QSplitter* split; - ConfigView* list; + ConfigList *list; ConfigInfoView* info;
struct symbol **result; @@ -291,12 +237,14 @@ protected: class ConfigMainWindow : public QMainWindow { Q_OBJECT
+ char *configname; static QAction *saveAction; static void conf_changed(void); public: ConfigMainWindow(void); public slots: void changeMenu(struct menu *); + void changeItens(struct menu *); void setMenuLink(struct menu *); void listFocusChanged(void); void goBack(void); @@ -315,12 +263,9 @@ protected: void closeEvent(QCloseEvent *e);
ConfigSearchWindow *searchWindow; - ConfigView *menuView; ConfigList *menuList; - ConfigView *configView; ConfigList *configList; ConfigInfoView *helpText; - QToolBar *toolBar; QAction *backAction; QAction *singleViewAction; QAction *splitViewAction; diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 4686531e2f8c..3387ad7508f7 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 # # Copyright 2005-2009 - Steven Rostedt -# Licensed under the terms of the GNU GPL License version 2 # # It's simple enough to figure out how this works. # If not, then you can ask me at stripconfig@goodmis.org @@ -21,7 +21,7 @@ # 1. Boot up the kernel that you want to stream line the config on. # 2. Change directory to the directory holding the source of the # kernel that you just booted. -# 3. Copy the configuraton file to this directory as .config +# 3. Copy the configuration file to this directory as .config # 4. Have all your devices that you need modules for connected and # operational (make sure that their corresponding modules are loaded) # 5. Run this script redirecting the output to some other file @@ -56,8 +56,6 @@ sub dprint { print STDERR @_; }
-my $config = ".config"; - my $uname = `uname -r`; chomp $uname;
@@ -145,6 +143,7 @@ my %depends; my %selects; my %prompts; my %objects; +my %config2kfile; my $var; my $iflevel = 0; my @ifdeps; @@ -171,7 +170,7 @@ sub read_kconfig { $source =~ s/$($env)/$ENV{$env}/; }
- open(my $kinfile, '<', $source) || die "Can't open $kconfig"; + open(my $kinfile, '<', $source) || die "Can't open $source"; while (<$kinfile>) { chomp;
@@ -203,6 +202,7 @@ sub read_kconfig { if (/^\s*(menu)?config\s+(\S+)\s*$/) { $state = "NEW"; $config = $2; + $config2kfile{"CONFIG_$config"} = $kconfig;
# Add depends for 'if' nesting for (my $i = 0; $i < $iflevel; $i++) { @@ -374,7 +374,7 @@ if (defined($lsmod_file)) { $lsmod = "$dir/lsmod"; last; } -} + } if (!defined($lsmod)) { # try just the path $lsmod = "lsmod"; @@ -481,7 +481,7 @@ sub parse_config_depends # The idea is we look at all the configs that select it. If one # is already in our list of configs to enable, then there's nothing # else to do. If there isn't, we pick the first config that was -# enabled in the orignal config and use that. +# enabled in the original config and use that. sub parse_config_selects { my ($config, $p) = @_; @@ -593,6 +593,23 @@ while ($repeat) { }
my %setconfigs; +my @preserved_kconfigs; +if (defined($ENV{'LMC_KEEP'})) { + @preserved_kconfigs = split(/:/,$ENV{LMC_KEEP}); +} + +sub in_preserved_kconfigs { + my $kconfig = $config2kfile{$_[0]}; + if (!defined($kconfig)) { + return 0; + } + foreach my $excl (@preserved_kconfigs) { + if($kconfig =~ /^$excl/) { + return 1; + } + } + return 0; +}
# Finally, read the .config file and turn off any module enabled that # we could not find a reason to keep enabled. @@ -612,47 +629,52 @@ foreach my $line (@config_file) { }
if (/CONFIG_MODULE_SIG_KEY="(.+)"/) { - my $orig_cert = $1; - my $default_cert = "certs/signing_key.pem"; - - # Check that the logic in this script still matches the one in Kconfig - if (!defined($depends{"MODULE_SIG_KEY"}) || - $depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) { - print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ", - "update needed to ", __FILE__, " line ", __LINE__, "\n"; - print; - } elsif ($orig_cert ne $default_cert && ! -f $orig_cert) { - print STDERR "Module signature verification enabled but ", - "module signing key "$orig_cert" not found. Resetting ", - "signing key to default value.\n"; - print "CONFIG_MODULE_SIG_KEY="$default_cert"\n"; - } else { - print; - } - next; + my $orig_cert = $1; + my $default_cert = "certs/signing_key.pem"; + + # Check that the logic in this script still matches the one in Kconfig + if (!defined($depends{"MODULE_SIG_KEY"}) || + $depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) { + print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ", + "update needed to ", __FILE__, " line ", __LINE__, "\n"; + print; + } elsif ($orig_cert ne $default_cert && ! -f $orig_cert) { + print STDERR "Module signature verification enabled but ", + "module signing key "$orig_cert" not found. Resetting ", + "signing key to default value.\n"; + print "CONFIG_MODULE_SIG_KEY="$default_cert"\n"; + } else { + print; + } + next; }
if (/CONFIG_SYSTEM_TRUSTED_KEYS="(.+)"/) { - my $orig_keys = $1; - - if (! -f $orig_keys) { - print STDERR "System keyring enabled but keys "$orig_keys" ", - "not found. Resetting keys to default value.\n"; - print "CONFIG_SYSTEM_TRUSTED_KEYS=""\n"; - } else { - print; - } - next; + my $orig_keys = $1; + + if (! -f $orig_keys) { + print STDERR "System keyring enabled but keys "$orig_keys" ", + "not found. Resetting keys to default value.\n"; + print "CONFIG_SYSTEM_TRUSTED_KEYS=""\n"; + } else { + print; + } + next; }
if (/^(CONFIG.*)=(m|y)/) { + if (in_preserved_kconfigs($1)) { + dprint "Preserve config $1"; + print; + next; + } if (defined($configs{$1})) { if ($localyesconfig) { - $setconfigs{$1} = 'y'; + $setconfigs{$1} = 'y'; print "$1=y\n"; next; } else { - $setconfigs{$1} = $2; + $setconfigs{$1} = $2; } } elsif ($2 eq "m") { print "# $1 is not set\n"; @@ -680,3 +702,5 @@ foreach my $module (keys(%modules)) { print STDERR "\n"; } } + +# vim: softtabstop=4 diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 703b9b899ee9..0572330bf8a7 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -1,13 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 Roman Zippel zippel@linux-m68k.org - * Released under the terms of the GNU GPL v2.0. */
+#include <sys/types.h> #include <ctype.h> #include <stdlib.h> #include <string.h> #include <regex.h> -#include <sys/utsname.h>
#include "lkc.h"
@@ -15,23 +15,28 @@ struct symbol symbol_yes = { .name = "y", .curr = { "y", yes }, .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_mod = { +}; + +struct symbol symbol_mod = { .name = "m", .curr = { "m", mod }, .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_no = { +}; + +struct symbol symbol_no = { .name = "n", .curr = { "n", no }, .flags = SYMBOL_CONST|SYMBOL_VALID, -}, symbol_empty = { +}; + +static struct symbol symbol_empty = { .name = "", .curr = { "", no }, .flags = SYMBOL_VALID, };
-struct symbol *sym_defconfig_list; struct symbol *modules_sym; -tristate modules_val; +static tristate modules_val;
enum symbol_type sym_get_type(struct symbol *sym) { @@ -61,8 +66,6 @@ const char *sym_type_name(enum symbol_type type) return "string"; case S_UNKNOWN: return "unknown"; - case S_OTHER: - break; } return "???"; } @@ -88,7 +91,7 @@ static struct property *sym_get_default_prop(struct symbol *sym) return NULL; }
-static struct property *sym_get_range_prop(struct symbol *sym) +struct property *sym_get_range_prop(struct symbol *sym) { struct property *prop;
@@ -223,7 +226,7 @@ static void sym_calc_visibility(struct symbol *sym) sym_set_changed(sym); } tri = no; - if (sym->implied.expr && sym->dir_dep.tri != no) + if (sym->implied.expr) tri = expr_calc_value(sym->implied.expr); if (tri == mod && sym_get_type(sym) == S_BOOLEAN) tri = yes; @@ -396,6 +399,8 @@ void sym_calc_value(struct symbol *sym) if (sym->implied.tri != no) { sym->flags |= SYMBOL_WRITE; newval.tri = EXPR_OR(newval.tri, sym->implied.tri); + newval.tri = EXPR_AND(newval.tri, + sym->dir_dep.tri); } } calc_newval: @@ -403,8 +408,7 @@ void sym_calc_value(struct symbol *sym) sym_warn_unmet_dep(sym); newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } - if (newval.tri == mod && - (sym_get_type(sym) == S_BOOLEAN || sym->implied.tri == yes)) + if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) newval.tri = yes; break; case S_STRING: @@ -468,7 +472,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym) sym->flags &= ~SYMBOL_VALID; - sym_add_change_count(1); + conf_set_changed(true); sym_calc_value(modules_sym); }
@@ -486,8 +490,6 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) return false; if (sym->visible <= sym->rev_dep.tri) return false; - if (sym->implied.tri == yes && val == mod) - return false; if (sym_is_choice_value(sym) && sym->visible == yes) return val == yes; return val >= sym->rev_dep.tri && val <= sym->visible; @@ -757,7 +759,6 @@ const char *sym_get_string_default(struct symbol *sym) return str; case S_STRING: return str; - case S_OTHER: case S_UNKNOWN: break; } @@ -788,7 +789,7 @@ const char *sym_get_string_value(struct symbol *sym) return (const char *)sym->curr.val; }
-bool sym_is_changable(struct symbol *sym) +bool sym_is_changeable(struct symbol *sym) { return sym->visible > sym->rev_dep.tri; } @@ -835,7 +836,7 @@ struct symbol *sym_lookup(const char *name, int flags) memset(symbol, 0, sizeof(*symbol)); symbol->name = new_name; symbol->type = S_UNKNOWN; - symbol->flags |= flags; + symbol->flags = flags;
symbol->next = symbol_hash[hash]; symbol_hash[hash] = symbol; @@ -870,49 +871,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; @@ -1117,7 +1075,7 @@ static void sym_check_print_recursive(struct symbol *last_sym) }
fprintf(stderr, - "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n" + "For a resolution refer to Documentation/kbuild/kconfig-language.rst\n" "subsection "Kconfig recursive dependency limitations"\n" "\n");
@@ -1276,28 +1234,6 @@ struct symbol *sym_check_deps(struct symbol *sym) return sym2; }
-struct property *prop_alloc(enum prop_type type, struct symbol *sym) -{ - struct property *prop; - struct property **propp; - - prop = xmalloc(sizeof(*prop)); - memset(prop, 0, sizeof(*prop)); - prop->type = type; - prop->sym = sym; - prop->file = current_file; - prop->lineno = zconf_lineno(); - - /* append property to the prop list of symbol */ - if (sym) { - for (propp = &sym->prop; *propp; propp = &(*propp)->next) - ; - *propp = prop; - } - - return prop; -} - struct symbol *prop_get_symbol(struct property *prop) { if (prop->expr && (prop->expr->type == E_SYMBOL || diff --git a/scripts/kconfig/tests/auto_submenu/Kconfig b/scripts/kconfig/tests/auto_submenu/Kconfig index c17bf2caa7e6..b20761edc2f4 100644 --- a/scripts/kconfig/tests/auto_submenu/Kconfig +++ b/scripts/kconfig/tests/auto_submenu/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config A bool "A" default y diff --git a/scripts/kconfig/tests/auto_submenu/__init__.py b/scripts/kconfig/tests/auto_submenu/__init__.py index 32e79b85faeb..25abd927fd0a 100644 --- a/scripts/kconfig/tests/auto_submenu/__init__.py +++ b/scripts/kconfig/tests/auto_submenu/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Create submenu for symbols that depend on the preceding one.
diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig index cc60e9ce2c03..0930eb65e932 100644 --- a/scripts/kconfig/tests/choice/Kconfig +++ b/scripts/kconfig/tests/choice/Kconfig @@ -1,6 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + config MODULES bool "Enable loadable module support" - option modules + modules default y
choice diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py index 9edcc5262134..4318fce05912 100644 --- a/scripts/kconfig/tests/choice/__init__.py +++ b/scripts/kconfig/tests/choice/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Basic choice tests.
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig index 11ac25c26040..bd970cec07d6 100644 --- a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig +++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig @@ -1,6 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + config MODULES def_bool y - option modules + modules
config DEP tristate diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py index f8d728c7b101..075b4e08696e 100644 --- a/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py +++ b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Hide tristate choice values with mod dependency in y choice.
diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py index 0345ef6e3273..af8774a5697c 100644 --- a/scripts/kconfig/tests/conftest.py +++ b/scripts/kconfig/tests/conftest.py @@ -53,6 +53,10 @@ class Conf: # Override 'srctree' environment to make the test as the top directory extra_env['srctree'] = self._test_dir
+ # Clear KCONFIG_DEFCONFIG_LIST to keep unit tests from being affected + # by the user's environment. + extra_env['KCONFIG_DEFCONFIG_LIST'] = '' + # Run Kconfig in a temporary directory. # This directory is automatically removed when done. with tempfile.TemporaryDirectory() as temp_dir: diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr index 84679b104655..c9f4abf9a791 100644 --- a/scripts/kconfig/tests/err_recursive_dep/expected_stderr +++ b/scripts/kconfig/tests/err_recursive_dep/expected_stderr @@ -1,38 +1,38 @@ Kconfig:11:error: recursive dependency detected! Kconfig:11: symbol B is selected by B -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations"
Kconfig:5:error: recursive dependency detected! Kconfig:5: symbol A depends on A -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations"
Kconfig:17:error: recursive dependency detected! Kconfig:17: symbol C1 depends on C2 Kconfig:21: symbol C2 depends on C1 -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations"
Kconfig:32:error: recursive dependency detected! Kconfig:32: symbol D2 is selected by D1 Kconfig:27: symbol D1 depends on D2 -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations"
Kconfig:37:error: recursive dependency detected! Kconfig:37: symbol E1 depends on E2 Kconfig:42: symbol E2 is implied by E1 -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations"
Kconfig:60:error: recursive dependency detected! Kconfig:60: symbol G depends on G -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations"
Kconfig:51:error: recursive dependency detected! Kconfig:51: symbol F2 depends on F1 Kconfig:49: symbol F1 default value contains F2 -For a resolution refer to Documentation/kbuild/kconfig-language.txt +For a resolution refer to Documentation/kbuild/kconfig-language.rst subsection "Kconfig recursive dependency limitations" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig index 0e4c8750ab65..c6f4adec76d1 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only source "Kconfig.inc1" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 index 00e408d653fc..01cbf0d69cce 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 index 349ea2db15dc..82351075ab1b 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only
source "Kconfig.inc3" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 index 0e4c8750ab65..c6f4adec76d1 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only source "Kconfig.inc1" diff --git a/scripts/kconfig/tests/err_recursive_inc/__init__.py b/scripts/kconfig/tests/err_recursive_inc/__init__.py index 0e4c839c54aa..27aa1895a0b2 100644 --- a/scripts/kconfig/tests/err_recursive_inc/__init__.py +++ b/scripts/kconfig/tests/err_recursive_inc/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Detect recursive inclusion error.
diff --git a/scripts/kconfig/tests/err_recursive_inc/expected_stderr b/scripts/kconfig/tests/err_recursive_inc/expected_stderr index 6b582eee2176..b070a31fdfeb 100644 --- a/scripts/kconfig/tests/err_recursive_inc/expected_stderr +++ b/scripts/kconfig/tests/err_recursive_inc/expected_stderr @@ -1,6 +1,6 @@ Recursive inclusion detected. Inclusion path: current file : Kconfig.inc1 - included from: Kconfig.inc3:1 - included from: Kconfig.inc2:3 - included from: Kconfig.inc1:4 + included from: Kconfig.inc3:2 + included from: Kconfig.inc2:4 + included from: Kconfig.inc1:5 diff --git a/scripts/kconfig/tests/inter_choice/Kconfig b/scripts/kconfig/tests/inter_choice/Kconfig index e44449f075df..26c25f68695b 100644 --- a/scripts/kconfig/tests/inter_choice/Kconfig +++ b/scripts/kconfig/tests/inter_choice/Kconfig @@ -1,6 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + config MODULES def_bool y - option modules + modules
choice prompt "Choice" diff --git a/scripts/kconfig/tests/inter_choice/__init__.py b/scripts/kconfig/tests/inter_choice/__init__.py index 5c7fc365ed40..ffea6b1148a6 100644 --- a/scripts/kconfig/tests/inter_choice/__init__.py +++ b/scripts/kconfig/tests/inter_choice/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Do not affect user-assigned choice value by another choice.
diff --git a/scripts/kconfig/tests/new_choice_with_dep/Kconfig b/scripts/kconfig/tests/new_choice_with_dep/Kconfig index 53ef1b86e7bf..127731c046b5 100644 --- a/scripts/kconfig/tests/new_choice_with_dep/Kconfig +++ b/scripts/kconfig/tests/new_choice_with_dep/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config A bool "A" help diff --git a/scripts/kconfig/tests/new_choice_with_dep/__init__.py b/scripts/kconfig/tests/new_choice_with_dep/__init__.py index f0e0ead0f32f..fe9d322539c9 100644 --- a/scripts/kconfig/tests/new_choice_with_dep/__init__.py +++ b/scripts/kconfig/tests/new_choice_with_dep/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Ask new choice values when they become visible.
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig index c00b8fe54f45..4767aab6d8e3 100644 --- a/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config A bool "A"
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py index 207261b0fe00..ffd469d1f226 100644 --- a/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 """ Do not write choice values to .config if the dependency is unmet.
diff --git a/scripts/kconfig/tests/preprocess/builtin_func/Kconfig b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig new file mode 100644 index 000000000000..baa328827911 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 + +# 'info' prints the argument to stdout. +$(info,hello world 0) + +# 'warning-if', if the first argument is y, sends the second argument to stderr, +# and the message is prefixed with the current file name and line number. +$(warning-if,y,hello world 1) + +# 'error-if' is similar, but it terminates the parsing immediately. +# The following is just no-op since the first argument is not y. +$(error-if,n,this should not be printed) + +# Shorthand +warning = $(warning-if,y,$(1)) + +# 'shell' executes a command, and returns its stdout. +$(warning,$(shell,echo hello world 3)) + +# Every newline in the output is replaced with a space, +# but any trailing newlines are deleted. +$(warning,$(shell,printf 'hello\nworld\n\n4\n\n\n')) + +# 'filename' is expanded to the currently parsed file name, +# 'lineno' to the line number. +$(warning,filename=$(filename)) +$(warning,lineno=$(lineno)) diff --git a/scripts/kconfig/tests/preprocess/builtin_func/__init__.py b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py new file mode 100644 index 000000000000..2e53ba08fca1 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Built-in function tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stdout_contains('expected_stdout') + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr new file mode 100644 index 000000000000..33ea9ca38400 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr @@ -0,0 +1,5 @@ +Kconfig:8: hello world 1 +Kconfig:18: hello world 3 +Kconfig:22: hello world 4 +Kconfig:26: filename=Kconfig +Kconfig:27: lineno=27 diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout new file mode 100644 index 000000000000..82de3a7e97de --- /dev/null +++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout @@ -0,0 +1 @@ +hello world 0 diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig new file mode 100644 index 000000000000..6838997c23ba --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +X = $(Y) +Y = $(X) +$(info $(X)) diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py new file mode 100644 index 000000000000..419bda3e075c --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Detect circular variable expansion. + +If a recursively expanded variable references itself (eventually), +it should fail with an error message. +""" + +def test(conf): + assert conf.oldaskconfig() != 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr new file mode 100644 index 000000000000..cde68fa989d0 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr @@ -0,0 +1 @@ +Kconfig:5: Recursive variable 'X' references itself (eventually) diff --git a/scripts/kconfig/tests/preprocess/escape/Kconfig b/scripts/kconfig/tests/preprocess/escape/Kconfig new file mode 100644 index 000000000000..4e3f44445544 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/Kconfig @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# You can not pass commas directly to a function since they are treated as +# delimiters. You can use the following trick to do so. +comma := , +$(warning,hello$(comma) world) + +# Like Make, single quotes, double quotes, spaces are treated verbatim. +# The following prints the text as-is. +$(warning, ' " '" ' ''' "'") + +# Unlike Make, '$' has special meaning only when it is followed by '('. +# No need to escape '$' itself. +$(warning,$) +$(warning,$$) +$ := 1 +$(warning,$($)) + +# You need a trick to escape '$' followed by '(' +# The following should print "$(X)". It should not be expanded further. +dollar := $ +$(warning,$(dollar)(X)) + +# You need a trick to treat unbalanced parentheses. +# The following should print "(". +left_paren := ( +$(warning,$(left_paren)) + +# A simple expanded should not be expanded multiple times. +# The following should print "$(X)". It should not be expanded further. +Y := $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(X)" as well. +Y = $(dollar)(X) +$(warning,$(Y)) + +# The following should print "$(". +# It should not be emit "unterminated reference" error. +unterminated := $(dollar)( +$(warning,$(unterminated)) diff --git a/scripts/kconfig/tests/preprocess/escape/__init__.py b/scripts/kconfig/tests/preprocess/escape/__init__.py new file mode 100644 index 000000000000..7ee8e747f546 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Escape sequence tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/escape/expected_stderr b/scripts/kconfig/tests/preprocess/escape/expected_stderr new file mode 100644 index 000000000000..1c00957ddaa9 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/escape/expected_stderr @@ -0,0 +1,10 @@ +Kconfig:9: hello, world +Kconfig:13: ' " '" ' ''' "'" +Kconfig:17: $ +Kconfig:18: $$ +Kconfig:20: 1 +Kconfig:25: $(X) +Kconfig:30: ( +Kconfig:35: $(X) +Kconfig:39: $(X) +Kconfig:44: $( diff --git a/scripts/kconfig/tests/preprocess/variable/Kconfig b/scripts/kconfig/tests/preprocess/variable/Kconfig new file mode 100644 index 000000000000..9ce2f95cbd24 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/Kconfig @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Shorthand +warning = $(warning-if,y,$(1)) + +# Simply expanded variable. +X := 1 +SIMPLE := $(X) +X := 2 +$(warning,SIMPLE = $(SIMPLE)) + +# Recursively expanded variable. +X := 1 +RECURSIVE = $(X) +X := 2 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Append something to a simply expanded variable. +Y := 3 +SIMPLE += $(Y) +Y := 4 +$(warning,SIMPLE = $(SIMPLE)) + +# Append something to a recursively expanded variable. +Y := 3 +RECURSIVE += $(Y) +Y := 4 +$(warning,RECURSIVE = $(RECURSIVE)) + +# Use += operator to an undefined variable. +# This works as a recursively expanded variable. +Y := 3 +UNDEFINED_VARIABLE += $(Y) +Y := 4 +$(warning,UNDEFINED_VARIABLE = $(UNDEFINED_VARIABLE)) + +# You can use variable references for the lefthand side of assignment statement. +X := A +Y := B +$(X)$(Y) := 5 +$(warning,AB = $(AB)) + +# User-defined function. +greeting = $(1), my name is $(2). +$(warning,$(greeting,Hello,John)) + +# The number of arguments is not checked for user-defined functions. +# If some arguments are optional, it is useful to pass fewer parameters. +# $(2) will be blank in this case. +$(warning,$(greeting,Hello)) + +# Unreferenced parameters are just ignored. +$(warning,$(greeting,Hello,John,ignored,ignored)) diff --git a/scripts/kconfig/tests/preprocess/variable/__init__.py b/scripts/kconfig/tests/preprocess/variable/__init__.py new file mode 100644 index 000000000000..e88b1708d6d4 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/__init__.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Variable and user-defined function tests. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_matches('expected_stderr') diff --git a/scripts/kconfig/tests/preprocess/variable/expected_stderr b/scripts/kconfig/tests/preprocess/variable/expected_stderr new file mode 100644 index 000000000000..a4841c3fdff5 --- /dev/null +++ b/scripts/kconfig/tests/preprocess/variable/expected_stderr @@ -0,0 +1,9 @@ +Kconfig:10: SIMPLE = 1 +Kconfig:16: RECURSIVE = 2 +Kconfig:22: SIMPLE = 1 3 +Kconfig:28: RECURSIVE = 2 4 +Kconfig:35: UNDEFINED_VARIABLE = 4 +Kconfig:41: AB = 5 +Kconfig:45: Hello, my name is John. +Kconfig:50: Hello, my name is . +Kconfig:53: Hello, my name is John. diff --git a/scripts/kconfig/tests/rand_nested_choice/Kconfig b/scripts/kconfig/tests/rand_nested_choice/Kconfig deleted file mode 100644 index c591d512929f..000000000000 --- a/scripts/kconfig/tests/rand_nested_choice/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -choice - prompt "choice" - -config A - bool "A" - -config B - bool "B" - -if B -choice - prompt "sub choice" - -config C - bool "C" - -config D - bool "D" - -if D -choice - prompt "subsub choice" - -config E - bool "E" - -endchoice -endif # D - -endchoice -endif # B - -endchoice diff --git a/scripts/kconfig/tests/rand_nested_choice/__init__.py b/scripts/kconfig/tests/rand_nested_choice/__init__.py deleted file mode 100644 index e729a4e85218..000000000000 --- a/scripts/kconfig/tests/rand_nested_choice/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -Set random values recursively in nested choices. - -Kconfig can create a choice-in-choice structure by using 'if' statement. -randconfig should correctly set random choice values. - -Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29 -""" - - -def test(conf): - for i in range(20): - assert conf.randconfig() == 0 - assert (conf.config_contains('expected_stdout0') or - conf.config_contains('expected_stdout1') or - conf.config_contains('expected_stdout2')) diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 deleted file mode 100644 index 05450f3d4eb5..000000000000 --- a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_A=y -# CONFIG_B is not set diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 deleted file mode 100644 index 37ab29584157..000000000000 --- a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 +++ /dev/null @@ -1,4 +0,0 @@ -# CONFIG_A is not set -CONFIG_B=y -CONFIG_C=y -# CONFIG_D is not set diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 deleted file mode 100644 index 849ff47e9848..000000000000 --- a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 +++ /dev/null @@ -1,5 +0,0 @@ -# CONFIG_A is not set -CONFIG_B=y -# CONFIG_C is not set -CONFIG_D=y -CONFIG_E=y diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index d999683bb2a7..b78f114ad48c 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002-2005 Roman Zippel zippel@linux-m68k.org * Copyright (C) 2002-2005 Sam Ravnborg sam@ravnborg.org - * - * Released under the terms of the GNU GPL v2.0. */
#include <stdarg.h> @@ -75,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; }