build: scripts/config - update to kconfig-v5.14

Functional Changes
---------- -------
- make 'imply' not impose any restrictions: allow symbols implied by y
  to become m
- change "modules" from sub-option to first-level attribute

Bugfixes
--------
- nconf: fix core dump when searching in empty menu
- nconf: stop endless search loops
- xconfig: fix content of the main widget
- xconfig: fix support for the split view mode

Other Changes
----- -------
- highlight xconfig 'comment' lines with '***'
- xconfig: navigate menus on hyperlinks
- xconfig: drop support for Qt4
- improve host ncurses detection

Update the 'option modules' usage to just 'modules' in Config.in.

Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
This commit is contained in:
Eneas U de Queiroz 2021-11-24 18:25:43 -03:00 committed by Petr Štetiar
parent 73ea763c0d
commit 009293c52e
30 changed files with 3218 additions and 3931 deletions

View File

@ -5,7 +5,7 @@
mainmenu "OpenWrt Configuration"
config MODULES
option modules
modules
bool
default y

View File

@ -1,22 +1,16 @@
#
# Generated files
#
*.moc
*conf-cfg
# SPDX-License-Identifier: GPL-2.0-only
/conf
/[gmnq]conf
/[gmnq]conf-cfg
/qconf-moc.cc
# From linux kconfig parent directories
.*
# OpenWrt-generated files
mconf_check
#
# configuration programs
#
conf
mconf
nconf
qconf
gconf
#
# temporary files from older version. Should be removed
#
# Temporary files from older versions. They should be removed after the
# end of support for OpenWrt 19.07.
zconf.???.c
zconf.hash.c
.tmp_qtcheck

View File

@ -5,11 +5,11 @@
.PHONY: clean all
all: conf mconf
clean:
rm -f *.o lxdialog/*.o *.moc $(clean-files) conf mconf qconf nconf
rm -f *.o lxdialog/*.o *.moc .*.cmd $(clean-files)
# This clean-files definition is here to ensure that temporary files from the
# previous version are removed by make config-clean.
# It should be removed or emptied when this Makefile get updated again.
# It should be emptied after the end of support for OpenWrt 19.07.
clean-files := zconf.tab.c zconf.lex.c zconf.hash.c .tmp_qtcheck
# ===========================================================================
@ -24,9 +24,11 @@ src:=.
obj:=.
Q:=$(if $V,,@)
cmd = $(cmd_$(1))
dot-target = $(dir $@).$(notdir $@)
# taken from ../Kbuild.include
# some definitions taken from ../Kbuild.include
dot-target = $(dir $@).$(notdir $@)
squote := '
escsq = $(subst $(squote),'\$(squote)',$1)
define filechk
$(Q)set -e; \
mkdir -p $(dir $@); \
@ -37,23 +39,29 @@ define filechk
mv -f $(dot-target).tmp $@; \
fi
endef
cmd-check = $(if $(strip $(cmd_$@)),,1)
make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
newer-prereqs = $(filter-out $(PHONY),$?)
if_changed = $(if $(newer-prereqs)$(cmd-check), \
$(cmd); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
### Stripped down upstream Makefile follows:
# ===========================================================================
# object files used by all kconfig flavours
common-objs := confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \
symbol.o util.o
common-objs := confdata.o expr.o lexer.lex.o menu.o parser.tab.o \
preprocess.o symbol.o util.o
$(obj)/lexer.lex.o: $(obj)/parser.tab.h
HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src)
HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src)
# conf: Used for defconfig, oldconfig and related targets
hostprogs-y += conf
hostprogs += conf
conf-objs := conf.o $(common-objs)
# nconf: Used for the nconfig target based on ncurses
hostprogs-y += nconf
hostprogs += nconf
nconf-objs := nconf.o nconf.gui.o $(common-objs)
HOSTLDLIBS_nconf = $(shell . $(obj)/nconf-cfg && echo $$libs)
@ -63,7 +71,7 @@ HOSTCFLAGS_nconf.gui.o = $(shell . $(obj)/nconf-cfg && echo $$cflags)
$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/nconf-cfg
# mconf: Used for the menuconfig target based on lxdialog
hostprogs-y += mconf
hostprogs += mconf
lxdialog := $(addprefix lxdialog/, \
checklist.o inputbox.o menubox.o textbox.o util.o yesno.o)
mconf-objs := mconf.o $(lxdialog) $(common-objs)
@ -75,20 +83,23 @@ $(foreach f, mconf.o $(lxdialog), \
$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg
# qconf: Used for the xconfig target based on Qt
hostprogs-y += qconf
qconf-cxxobjs := qconf.o
hostprogs += qconf
qconf-cxxobjs := qconf.o qconf-moc.o
qconf-objs := images.o $(common-objs)
HOSTLDLIBS_qconf = $(shell . $(obj)/qconf-cfg && echo $$libs)
HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
$(obj)/qconf.o: $(obj)/qconf-cfg $(obj)/qconf.moc
$(obj)/qconf.o: $(obj)/qconf-cfg
quiet_cmd_moc = MOC $@
cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) -i $< -o $@
cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@
$(obj)/%.moc: $(src)/%.h $(obj)/qconf-cfg
$(call cmd,moc)
$(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE
$(call if_changed,moc)
targets += qconf-moc.cc
# check if necessary packages are available, and configure build flags
filechk_conf_cfg = $(CONFIG_SHELL) $<
@ -102,6 +113,8 @@ clean-files += *conf-cfg
# OpenWrt rules and final adjustments that need to be made after reading the
# full upstream Makefile
clean-files += $(targets) $(hostprogs)
FORCE:
ifdef BUILD_SHIPPED_FILES
@ -117,24 +130,25 @@ clean-files += $(shipped-files)
flex -L -o$@ $<
endif
$(foreach f, mconf.o $(lxdialog), \
$(eval $f: CFLAGS+=$$(HOSTCFLAGS_$f)))
$(foreach f,$(conf-objs) $(filter-out $(common-objs),$(mconf-objs) \
$(qconf-objs) \
$(nconf-objs)), \
$(eval $(obj)/$f: CFLAGS+=$$(HOSTCFLAGS_$f)))
$(obj)/lexer.lex.o: CFLAGS += $(HOSTCFLAGS_lexer.lex.o)
$(obj)/parser.tab.o: CFLAGS += $(HOSTCFLAGS_parser.tab.o)
$(obj)/qconf.o: CXXFLAGS+=$(HOSTCXXFLAGS_qconf.o)
$(foreach f,$(qconf-cxxobjs), \
$(eval $(obj)/$f: CXXFLAGS+=$$(HOSTCXXFLAGS_$f)))
conf: $(conf-objs)
$(obj)/conf: $(addprefix $(obj)/,$(conf-objs))
# The *conf-cfg file is used (then filtered out) as the first prerequisite to
# avoid sourcing it before the script is built, when trying to compute CFLAGS
# for the actual first prerequisite. This avoids errors like:
# '/bin/sh: ./mconf-cfg: No such file or directory'
mconf: mconf-cfg $(mconf-objs)
$(obj)/mconf: mconf-cfg $(addprefix $(obj)/,$(mconf-objs))
$(CC) -o $@ $(filter-out mconf-cfg,$^) $(HOSTLDLIBS_mconf)
nconf: nconf-cfg $(nconf-objs)
$(obj)/nconf: nconf-cfg $(addprefix $(obj)/,$(nconf-objs))
$(CC) -o $@ $(filter-out nconf-cfg,$^) $(HOSTLDLIBS_nconf)
qconf: qconf-cfg $(qconf-cxxobjs) $(qconf-objs)
$(obj)/qconf: qconf-cfg $(addprefix $(obj)/,$(qconf-cxxobjs) $(qconf-objs))
$(CXX) -o $@ $(filter-out qconf-cfg,$^) $(HOSTLDLIBS_qconf)

View File

@ -1,7 +1,6 @@
These files were taken from the Linux Kernel Configuration System at commit
089b7d890f972f6b649fedc9259f6b93a18fb970 (Feb 4, 2020) and modified for the
OpenWrt Buildroot:
- Removed gconf, tests and kernel configuration targets.
These files were taken from the Linux 5.14 Kernel Configuration System and
modified for the OpenWrt Buildroot:
- Removed nconf, gconf, tests and kernel configuration targets.
- Adjusted the Makefile to compile outside the kernel.
- Always use default file when running make all{no,mod,yes}config.
- Added a 'reset' command to reset config when the target changes.
@ -24,4 +23,4 @@ OpenWrt Buildroot:
BUILD_SHIPPED_FILES defined
For a full list of changes, see the repository at:
https://github.com/cotequeiroz/linux/commits/openwrt/scripts/kconfig
https://github.com/cotequeiroz/linux/commits/openwrt-5.14/scripts/kconfig

View File

@ -11,7 +11,6 @@
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <errno.h>
@ -39,7 +38,7 @@ enum input_mode {
fatalrecursive,
};
static enum input_mode input_mode = oldaskconfig;
static int input_mode_opt;
static int indent = 1;
static int tty_stdio;
static int sync_kconfig;
@ -84,10 +83,243 @@ static void xfgets(char *str, int size, FILE *in)
printf("%s", str);
}
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_y2m,
def_m2y,
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);
}
}
sym_clear_all_valid();
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;
}
}
/*
* 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_mod_or_yes(enum conf_def_mode mode)
{
struct symbol *sym;
int i;
tristate old_val = (mode == def_y2m) ? yes : mod;
tristate new_val = (mode == def_y2m) ? mod : yes;
for_all_symbols(i, sym) {
if (sym_get_type(sym) == S_TRISTATE &&
sym->def[S_DEF_USER].tri == old_val)
sym->def[S_DEF_USER].tri = new_val;
}
sym_clear_all_valid();
}
static int conf_askvalue(struct symbol *sym, const char *def)
{
enum symbol_type type = sym_get_type(sym);
if (!sym_has_value(sym))
printf("(NEW) ");
@ -109,24 +341,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;
}
@ -139,7 +359,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;
@ -421,34 +641,37 @@ static void check_conf(struct menu *menu)
return;
sym = menu->sym;
if (sym && !sym_has_value(sym)) {
if (sym_is_changeable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (input_mode == listnewconfig) {
if (sym->name) {
const char *str;
if (sym && !sym_has_value(sym) &&
(sym_is_changeable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
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);
}
switch (input_mode) {
case listnewconfig:
if (sym->name) {
const char *str;
if (sym->type == S_STRING) {
str = sym_get_string_value(sym);
str = sym_escape_string_value(str);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
free((void *)str);
} else {
str = sym_get_string_value(sym);
printf("%s%s=%s\n", CONFIG_, sym->name, str);
}
} else if (input_mode == helpnewconfig) {
printf("-----\n");
print_help(menu);
printf("-----\n");
} else {
if (!conf_cnt++)
printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
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;
}
}
@ -456,31 +679,38 @@ 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", required_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},
{"helpnewconfig", no_argument, NULL, helpnewconfig},
{"olddefconfig", no_argument, NULL, olddefconfig},
{"yes2modconfig", no_argument, NULL, yes2modconfig},
{"mod2yesconfig", no_argument, NULL, mod2yesconfig},
{"fatalrecursive", no_argument, NULL, fatalrecursive},
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},
{"fatalrecursive",no_argument, NULL, fatalrecursive},
{NULL, 0, NULL, 0}
};
static void conf_usage(const char *progname)
{
printf("Usage: %s [-s] [--fatalrecursive] [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(" --fatalrecursive Treat recursive depenendencies as a fatal error\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");
@ -497,6 +727,7 @@ static void conf_usage(const char *progname)
printf(" --randconfig New config with random answer to all options\n");
printf(" --yes2modconfig Change answers from yes to mod if possible\n");
printf(" --mod2yesconfig Change answers from mod to yes if possible\n");
printf(" (If none of the above is given, --oldaskconfig is the default)\n");
}
int main(int ac, char **av)
@ -509,84 +740,56 @@ int main(int ac, char **av)
tty_stdio = isatty(0) && isatty(1);
while ((opt = getopt_long(ac, av, "r:w:s", long_opts, NULL)) != -1) {
if (opt == 's') {
conf_set_message_callback(NULL);
continue;
}
while ((opt = getopt_long(ac, av, "hr:sw:", long_opts, NULL)) != -1) {
switch (opt) {
case syncconfig:
/*
* syncconfig is invoked during the build stage.
* Suppress distracting "configuration written to ..."
*/
case 'h':
conf_usage(progname);
exit(1);
break;
case 's':
conf_set_message_callback(NULL);
sync_kconfig = 1;
break;
case defconfig:
case savedefconfig:
defconfig_file = optarg;
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;
}
}
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 helpnewconfig:
case olddefconfig:
case yes2modconfig:
case mod2yesconfig:
break;
case fatalrecursive:
recursive_is_error = 1;
continue;
case 'r':
input_file = optarg;
continue;
break;
case 'w':
output_file = optarg;
continue;
case '?':
conf_usage(progname);
exit(1);
break;
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;
}
default:
break;
}
input_mode = (enum input_mode)opt;
}
if (ac == optind) {
fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
conf_usage(progname);
exit(1);
}
name = av[optind];
conf_parse(name);
conf_parse(av[optind]);
//zconfdump(stdout);
switch (input_mode) {

View File

@ -5,6 +5,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@ -32,7 +33,7 @@ static bool is_dir(const char *path)
struct stat st;
if (stat(path, &st))
return 0;
return false;
return S_ISDIR(st.st_mode);
}
@ -129,19 +130,14 @@ static size_t depfile_prefix_len;
static int conf_touch_dep(const char *name)
{
int fd, ret;
const char *s;
char *d, c;
char *d;
/* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */
if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path))
/* check overflow: prefix + name + '\0' must fit in buffer. */
if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
return -1;
d = depfile_path + depfile_prefix_len;
s = name;
while ((c = *s++))
*d++ = (c == '_') ? '/' : tolower(c);
strcpy(d, ".h");
strcpy(d, name);
/* Assume directory path already exists. */
fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
@ -384,28 +380,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)
@ -434,7 +448,7 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 2 + strlen(CONFIG_));
if (!sym) {
sym_add_change_count(1);
conf_set_changed(true);
continue;
}
} else {
@ -470,11 +484,11 @@ load:
* Reading from include/config/auto.conf
* If CONFIG_FOO previously existed in
* auto.conf but it is missing now,
* include/config/foo.h must be touched.
* include/config/FOO must be touched.
*/
conf_touch_dep(line + strlen(CONFIG_));
else
sym_add_change_count(1);
conf_set_changed(true);
continue;
}
@ -519,7 +533,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);
@ -577,7 +591,8 @@ 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;
}
@ -922,7 +937,7 @@ next:
if (is_same(name, tmpname)) {
conf_message("No change to %s", name);
unlink(tmpname);
sym_set_change_count(0);
conf_set_changed(false);
return 0;
}
@ -934,7 +949,7 @@ next:
conf_message("configuration written to %s", name);
sym_set_change_count(0);
conf_set_changed(false);
return 0;
}
@ -1105,26 +1120,20 @@ int conf_write_autoconf(int overwrite)
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))
@ -1132,54 +1141,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;
@ -1199,147 +1160,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;
sym_clear_all_valid();
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;
}
}
/*
* 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;
}
void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
{
struct symbol *sym;
int i;
tristate old_val = (mode == def_y2m) ? yes : mod;
tristate new_val = (mode == def_y2m) ? mod : yes;
for_all_symbols(i, sym) {
if (sym_get_type(sym) == S_TRISTATE &&
sym->def[S_DEF_USER].tri == old_val) {
sym->def[S_DEF_USER].tri = new_val;
sym_add_change_count(1);
}
}
}

View File

@ -156,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
@ -282,15 +279,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);

View File

@ -5,7 +5,7 @@
#include "images.h"
const char *xpm_load[] = {
const char * const xpm_load[] = {
"22 22 5 1",
". c None",
"# c #000000",
@ -35,7 +35,7 @@ const char *xpm_load[] = {
"###############.......",
"......................"};
const char *xpm_save[] = {
const char * const xpm_save[] = {
"22 22 5 1",
". c None",
"# c #000000",
@ -65,7 +65,7 @@ const char *xpm_save[] = {
"..##################..",
"......................"};
const char *xpm_back[] = {
const char * const xpm_back[] = {
"22 22 3 1",
". c None",
"# c #000083",
@ -93,7 +93,7 @@ const char *xpm_back[] = {
"......................",
"......................"};
const char *xpm_tree_view[] = {
const char * const xpm_tree_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@ -120,7 +120,7 @@ const char *xpm_tree_view[] = {
"......................",
"......................"};
const char *xpm_single_view[] = {
const char * const xpm_single_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@ -147,7 +147,7 @@ const char *xpm_single_view[] = {
"......................",
"......................"};
const char *xpm_split_view[] = {
const char * const xpm_split_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@ -174,7 +174,7 @@ const char *xpm_split_view[] = {
"......................",
"......................"};
const char *xpm_symbol_no[] = {
const char * const xpm_symbol_no[] = {
"12 12 2 1",
" c white",
". c black",
@ -191,7 +191,7 @@ const char *xpm_symbol_no[] = {
" .......... ",
" "};
const char *xpm_symbol_mod[] = {
const char * const xpm_symbol_mod[] = {
"12 12 2 1",
" c white",
". c black",
@ -208,7 +208,7 @@ const char *xpm_symbol_mod[] = {
" .......... ",
" "};
const char *xpm_symbol_yes[] = {
const char * const xpm_symbol_yes[] = {
"12 12 2 1",
" c white",
". c black",
@ -225,7 +225,7 @@ const char *xpm_symbol_yes[] = {
" .......... ",
" "};
const char *xpm_choice_no[] = {
const char * const xpm_choice_no[] = {
"12 12 2 1",
" c white",
". c black",
@ -242,7 +242,7 @@ const char *xpm_choice_no[] = {
" .... ",
" "};
const char *xpm_choice_yes[] = {
const char * const xpm_choice_yes[] = {
"12 12 2 1",
" c white",
". c black",
@ -259,7 +259,7 @@ const char *xpm_choice_yes[] = {
" .... ",
" "};
const char *xpm_menu[] = {
const char * const xpm_menu[] = {
"12 12 2 1",
" c white",
". c black",
@ -276,7 +276,7 @@ const char *xpm_menu[] = {
" .......... ",
" "};
const char *xpm_menu_inv[] = {
const char * const xpm_menu_inv[] = {
"12 12 2 1",
" c white",
". c black",
@ -293,7 +293,7 @@ const char *xpm_menu_inv[] = {
" .......... ",
" "};
const char *xpm_menuback[] = {
const char * const xpm_menuback[] = {
"12 12 2 1",
" c white",
". c black",
@ -310,7 +310,7 @@ const char *xpm_menuback[] = {
" .......... ",
" "};
const char *xpm_void[] = {
const char * const xpm_void[] = {
"12 12 2 1",
" c white",
". c black",

View File

@ -10,21 +10,21 @@
extern "C" {
#endif
extern const char *xpm_load[];
extern const char *xpm_save[];
extern const char *xpm_back[];
extern const char *xpm_tree_view[];
extern const char *xpm_single_view[];
extern const char *xpm_split_view[];
extern const char *xpm_symbol_no[];
extern const char *xpm_symbol_mod[];
extern const char *xpm_symbol_yes[];
extern const char *xpm_choice_no[];
extern const char *xpm_choice_yes[];
extern const char *xpm_menu[];
extern const char *xpm_menu_inv[];
extern const char *xpm_menuback[];
extern const char *xpm_void[];
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
}

View File

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef INTERNAL_H
#define INTERNAL_H