提交 e4d6152b 编写于 作者: L Linus Torvalds

Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6: (26 commits)
  kconfig: add savedefconfig
  kconfig: code refactoring in confdata.c
  kconfig: refactor code in symbol.c
  kconfig: add alldefconfig
  kconfig: print more info when we see a recursive dependency
  kconfig: save location of config symbols
  kconfig: change nonint_oldconfig to listnewconfig
  kconfig: rename loose_nonint_oldconfig => oldnoconfig
  kconfig: use long options in conf
  kconfig: fix MODULES-related bug in case of no .config
  kconfig: make randconfig fair for booleans
  kconfig: Don't write invisible choice values
  kbuild: Warn on selecting symbols with unmet direct dependencies
  scripts:conf.c Fix warning: variable 'type' set but not used
  menuconfig: truncate list items
  menuconfig: fix to center checklist correctly in a corner case
  xconfig: add support to show hidden options which have prompts
  xconfig: remove unused function
  xconfig: clean up
  gconfig: fix null pointer warning
  ...
...@@ -65,7 +65,7 @@ also use the environment variable KCONFIG_ALLCONFIG as a flag or a ...@@ -65,7 +65,7 @@ also use the environment variable KCONFIG_ALLCONFIG as a flag or a
filename that contains config symbols that the user requires to be filename that contains config symbols that the user requires to be
set to a specific value. If KCONFIG_ALLCONFIG is used without a set to a specific value. If KCONFIG_ALLCONFIG is used without a
filename, "make *config" checks for a file named filename, "make *config" checks for a file named
"all{yes/mod/no/random}.config" (corresponding to the *config command "all{yes/mod/no/def/random}.config" (corresponding to the *config command
that was used) for symbol values that are to be forced. If this file that was used) for symbol values that are to be forced. If this file
is not found, it checks for a file named "all.config" to contain forced is not found, it checks for a file named "all.config" to contain forced
values. values.
......
...@@ -21,17 +21,17 @@ menuconfig: $(obj)/mconf ...@@ -21,17 +21,17 @@ menuconfig: $(obj)/mconf
$< $(Kconfig) $< $(Kconfig)
config: $(obj)/conf config: $(obj)/conf
$< $(Kconfig) $< --oldaskconfig $(Kconfig)
nconfig: $(obj)/nconf nconfig: $(obj)/nconf
$< $(Kconfig) $< $(Kconfig)
oldconfig: $(obj)/conf oldconfig: $(obj)/conf
$< -o $(Kconfig) $< --$@ $(Kconfig)
silentoldconfig: $(obj)/conf silentoldconfig: $(obj)/conf
$(Q)mkdir -p include/generated $(Q)mkdir -p include/generated
$< -s $(Kconfig) $< --$@ $(Kconfig)
# if no path is given, then use src directory to find file # if no path is given, then use src directory to find file
ifdef LSMOD ifdef LSMOD
...@@ -44,15 +44,15 @@ endif ...@@ -44,15 +44,15 @@ endif
localmodconfig: $(obj)/streamline_config.pl $(obj)/conf localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
$(Q)mkdir -p include/generated $(Q)mkdir -p include/generated
$(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
$(Q)if [ -f .config ]; then \ $(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \ cmp -s .tmp.config .config || \
(mv -f .config .config.old.1; \ (mv -f .config .config.old.1; \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
$(obj)/conf -s $(Kconfig); \ $(obj)/conf --silentoldconfig $(Kconfig); \
mv -f .config.old.1 .config.old) \ mv -f .config.old.1 .config.old) \
else \ else \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
$(obj)/conf -s $(Kconfig); \ $(obj)/conf --silentoldconfig $(Kconfig); \
fi fi
$(Q)rm -f .tmp.config $(Q)rm -f .tmp.config
...@@ -60,15 +60,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf ...@@ -60,15 +60,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
$(Q)mkdir -p include/generated $(Q)mkdir -p include/generated
$(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
$(Q)sed -i s/=m/=y/ .tmp.config $(Q)sed -i s/=m/=y/ .tmp.config
$(Q)if [ -f .config ]; then \ $(Q)if [ -f .config ]; then \
cmp -s .tmp.config .config || \ cmp -s .tmp.config .config || \
(mv -f .config .config.old.1; \ (mv -f .config .config.old.1; \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
$(obj)/conf -s $(Kconfig); \ $(obj)/conf --silentoldconfig $(Kconfig); \
mv -f .config.old.1 .config.old) \ mv -f .config.old.1 .config.old) \
else \ else \
mv -f .tmp.config .config; \ mv -f .tmp.config .config; \
$(obj)/conf -s $(Kconfig); \ $(obj)/conf --silentoldconfig $(Kconfig); \
fi fi
$(Q)rm -f .tmp.config $(Q)rm -f .tmp.config
...@@ -95,30 +95,29 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h ...@@ -95,30 +95,29 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
$(Q)rm -f arch/um/Kconfig.arch $(Q)rm -f arch/um/Kconfig.arch
$(Q)rm -f $(obj)/config.pot $(Q)rm -f $(obj)/config.pot
PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
randconfig: $(obj)/conf allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
$< -r $(Kconfig) $< --$@ $(Kconfig)
allyesconfig: $(obj)/conf PHONY += listnewconfig oldnoconfig savedefconfig defconfig
$< -y $(Kconfig)
allnoconfig: $(obj)/conf listnewconfig oldnoconfig: $(obj)/conf
$< -n $(Kconfig) $< --$@ $(Kconfig)
allmodconfig: $(obj)/conf savedefconfig: $(obj)/conf
$< -m $(Kconfig) $< --$@=defconfig $(Kconfig)
defconfig: $(obj)/conf defconfig: $(obj)/conf
ifeq ($(KBUILD_DEFCONFIG),) ifeq ($(KBUILD_DEFCONFIG),)
$< -d $(Kconfig) $< --defconfig $(Kconfig)
else else
@echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
$(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
endif endif
%_defconfig: $(obj)/conf %_defconfig: $(obj)/conf
$(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
# Help text used by make help # Help text used by make help
help: help:
...@@ -131,11 +130,15 @@ help: ...@@ -131,11 +130,15 @@ help:
@echo ' localmodconfig - Update current config disabling modules not loaded' @echo ' localmodconfig - Update current config disabling modules not loaded'
@echo ' localyesconfig - Update current config converting local mods to core' @echo ' localyesconfig - Update current config converting local mods to core'
@echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
@echo ' randconfig - New config with random answer to all options' @echo ' defconfig - New config with default from ARCH supplied defconfig'
@echo ' defconfig - New config with default answer to all options' @echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
@echo ' allmodconfig - New config selecting modules when possible'
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New config where all options are answered with no' @echo ' allnoconfig - New config where all options are answered with no'
@echo ' allyesconfig - New config where all options are accepted with yes'
@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 ' listnewconfig - List new options'
@echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)'
# lxdialog stuff # lxdialog stuff
check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
...@@ -19,16 +20,21 @@ ...@@ -19,16 +20,21 @@
static void conf(struct menu *menu); static void conf(struct menu *menu);
static void check_conf(struct menu *menu); static void check_conf(struct menu *menu);
enum { enum input_mode {
ask_all, oldaskconfig,
ask_new, silentoldconfig,
ask_silent, oldconfig,
set_default, allnoconfig,
set_yes, allyesconfig,
set_mod, allmodconfig,
set_no, alldefconfig,
set_random randconfig,
} input_mode = ask_all; defconfig,
savedefconfig,
listnewconfig,
oldnoconfig,
} input_mode = oldaskconfig;
char *defconfig_file; char *defconfig_file;
static int indent = 1; static int indent = 1;
...@@ -93,14 +99,14 @@ static int conf_askvalue(struct symbol *sym, const char *def) ...@@ -93,14 +99,14 @@ static int conf_askvalue(struct symbol *sym, const char *def)
} }
switch (input_mode) { switch (input_mode) {
case ask_new: case oldconfig:
case ask_silent: case silentoldconfig:
if (sym_has_value(sym)) { if (sym_has_value(sym)) {
printf("%s\n", def); printf("%s\n", def);
return 0; return 0;
} }
check_stdin(); check_stdin();
case ask_all: case oldaskconfig:
fflush(stdout); fflush(stdout);
fgets(line, 128, stdin); fgets(line, 128, stdin);
return 1; return 1;
...@@ -156,14 +162,12 @@ static int conf_string(struct menu *menu) ...@@ -156,14 +162,12 @@ static int conf_string(struct menu *menu)
static int conf_sym(struct menu *menu) static int conf_sym(struct menu *menu)
{ {
struct symbol *sym = menu->sym; struct symbol *sym = menu->sym;
int type;
tristate oldval, newval; tristate oldval, newval;
while (1) { while (1) {
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
if (sym->name) if (sym->name)
printf("(%s) ", sym->name); printf("(%s) ", sym->name);
type = sym_get_type(sym);
putchar('['); putchar('[');
oldval = sym_get_tristate_value(sym); oldval = sym_get_tristate_value(sym);
switch (oldval) { switch (oldval) {
...@@ -228,11 +232,9 @@ static int conf_choice(struct menu *menu) ...@@ -228,11 +232,9 @@ static int conf_choice(struct menu *menu)
{ {
struct symbol *sym, *def_sym; struct symbol *sym, *def_sym;
struct menu *child; struct menu *child;
int type;
bool is_new; bool is_new;
sym = menu->sym; sym = menu->sym;
type = sym_get_type(sym);
is_new = !sym_has_value(sym); is_new = !sym_has_value(sym);
if (sym_is_changable(sym)) { if (sym_is_changable(sym)) {
conf_sym(menu); conf_sym(menu);
...@@ -294,15 +296,15 @@ static int conf_choice(struct menu *menu) ...@@ -294,15 +296,15 @@ static int conf_choice(struct menu *menu)
printf("?"); printf("?");
printf("]: "); printf("]: ");
switch (input_mode) { switch (input_mode) {
case ask_new: case oldconfig:
case ask_silent: case silentoldconfig:
if (!is_new) { if (!is_new) {
cnt = def; cnt = def;
printf("%d\n", cnt); printf("%d\n", cnt);
break; break;
} }
check_stdin(); check_stdin();
case ask_all: case oldaskconfig:
fflush(stdout); fflush(stdout);
fgets(line, 128, stdin); fgets(line, 128, stdin);
strip(line); strip(line);
...@@ -360,7 +362,10 @@ static void conf(struct menu *menu) ...@@ -360,7 +362,10 @@ static void conf(struct menu *menu)
switch (prop->type) { switch (prop->type) {
case P_MENU: case P_MENU:
if (input_mode == ask_silent && rootEntry != menu) { if ((input_mode == silentoldconfig ||
input_mode == listnewconfig ||
input_mode == oldnoconfig) &&
rootEntry != menu) {
check_conf(menu); check_conf(menu);
return; return;
} }
...@@ -418,10 +423,16 @@ static void check_conf(struct menu *menu) ...@@ -418,10 +423,16 @@ static void check_conf(struct menu *menu)
if (sym && !sym_has_value(sym)) { if (sym && !sym_has_value(sym)) {
if (sym_is_changable(sym) || if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
if (!conf_cnt++) if (input_mode == listnewconfig) {
printf(_("*\n* Restart config...\n*\n")); if (sym->name && !sym_is_choice_value(sym)) {
rootEntry = menu_get_parent_menu(menu); printf("CONFIG_%s\n", sym->name);
conf(rootEntry); }
} else {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
conf(rootEntry);
}
} }
} }
...@@ -429,6 +440,22 @@ static void check_conf(struct menu *menu) ...@@ -429,6 +440,22 @@ static void check_conf(struct menu *menu)
check_conf(child); check_conf(child);
} }
static struct option long_opts[] = {
{"oldaskconfig", no_argument, NULL, oldaskconfig},
{"oldconfig", no_argument, NULL, oldconfig},
{"silentoldconfig", no_argument, NULL, silentoldconfig},
{"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},
{"oldnoconfig", no_argument, NULL, oldnoconfig},
{NULL, 0, NULL, 0}
};
int main(int ac, char **av) int main(int ac, char **av)
{ {
int opt; int opt;
...@@ -439,32 +466,17 @@ int main(int ac, char **av) ...@@ -439,32 +466,17 @@ int main(int ac, char **av)
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE); textdomain(PACKAGE);
while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) {
input_mode = (enum input_mode)opt;
switch (opt) { switch (opt) {
case 'o': case silentoldconfig:
input_mode = ask_silent;
break;
case 's':
input_mode = ask_silent;
sync_kconfig = 1; sync_kconfig = 1;
break; break;
case 'd': case defconfig:
input_mode = set_default; case savedefconfig:
break;
case 'D':
input_mode = set_default;
defconfig_file = optarg; defconfig_file = optarg;
break; break;
case 'n': case randconfig:
input_mode = set_no;
break;
case 'm':
input_mode = set_mod;
break;
case 'y':
input_mode = set_yes;
break;
case 'r':
{ {
struct timeval now; struct timeval now;
unsigned int seed; unsigned int seed;
...@@ -477,17 +489,12 @@ int main(int ac, char **av) ...@@ -477,17 +489,12 @@ int main(int ac, char **av)
seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
srand(seed); srand(seed);
input_mode = set_random;
break; break;
} }
case 'h': case '?':
printf(_("See README for usage info\n"));
exit(0);
break;
default:
fprintf(stderr, _("See README for usage info\n")); fprintf(stderr, _("See README for usage info\n"));
exit(1); exit(1);
break;
} }
} }
if (ac == optind) { if (ac == optind) {
...@@ -512,7 +519,7 @@ int main(int ac, char **av) ...@@ -512,7 +519,7 @@ int main(int ac, char **av)
} }
switch (input_mode) { switch (input_mode) {
case set_default: case defconfig:
if (!defconfig_file) if (!defconfig_file)
defconfig_file = conf_get_default_confname(); defconfig_file = conf_get_default_confname();
if (conf_read(defconfig_file)) { if (conf_read(defconfig_file)) {
...@@ -522,25 +529,32 @@ int main(int ac, char **av) ...@@ -522,25 +529,32 @@ int main(int ac, char **av)
exit(1); exit(1);
} }
break; break;
case ask_silent: case savedefconfig:
case ask_all: conf_read(NULL);
case ask_new: break;
case silentoldconfig:
case oldaskconfig:
case oldconfig:
case listnewconfig:
case oldnoconfig:
conf_read(NULL); conf_read(NULL);
break; break;
case set_no: case allnoconfig:
case set_mod: case allyesconfig:
case set_yes: case allmodconfig:
case set_random: case alldefconfig:
case randconfig:
name = getenv("KCONFIG_ALLCONFIG"); name = getenv("KCONFIG_ALLCONFIG");
if (name && !stat(name, &tmpstat)) { if (name && !stat(name, &tmpstat)) {
conf_read_simple(name, S_DEF_USER); conf_read_simple(name, S_DEF_USER);
break; break;
} }
switch (input_mode) { switch (input_mode) {
case set_no: name = "allno.config"; break; case allnoconfig: name = "allno.config"; break;
case set_mod: name = "allmod.config"; break; case allyesconfig: name = "allyes.config"; break;
case set_yes: name = "allyes.config"; break; case allmodconfig: name = "allmod.config"; break;
case set_random: name = "allrandom.config"; break; case alldefconfig: name = "alldef.config"; break;
case randconfig: name = "allrandom.config"; break;
default: break; default: break;
} }
if (!stat(name, &tmpstat)) if (!stat(name, &tmpstat))
...@@ -565,33 +579,42 @@ int main(int ac, char **av) ...@@ -565,33 +579,42 @@ int main(int ac, char **av)
} }
switch (input_mode) { switch (input_mode) {
case set_no: case allnoconfig:
conf_set_all_new_symbols(def_no); conf_set_all_new_symbols(def_no);
break; break;
case set_yes: case allyesconfig:
conf_set_all_new_symbols(def_yes); conf_set_all_new_symbols(def_yes);
break; break;
case set_mod: case allmodconfig:
conf_set_all_new_symbols(def_mod); conf_set_all_new_symbols(def_mod);
break; break;
case set_random: case alldefconfig:
conf_set_all_new_symbols(def_default);
break;
case randconfig:
conf_set_all_new_symbols(def_random); conf_set_all_new_symbols(def_random);
break; break;
case set_default: case defconfig:
conf_set_all_new_symbols(def_default); conf_set_all_new_symbols(def_default);
break; break;
case ask_new: case savedefconfig:
case ask_all: break;
case oldconfig:
case oldaskconfig:
rootEntry = &rootmenu; rootEntry = &rootmenu;
conf(&rootmenu); conf(&rootmenu);
input_mode = ask_silent; input_mode = silentoldconfig;
/* fall through */ /* fall through */
case ask_silent: case listnewconfig:
case oldnoconfig:
case silentoldconfig:
/* Update until a loop caused no more changes */ /* Update until a loop caused no more changes */
do { do {
conf_cnt = 0; conf_cnt = 0;
check_conf(&rootmenu); check_conf(&rootmenu);
} while (conf_cnt); } while (conf_cnt &&
(input_mode != listnewconfig &&
input_mode != oldnoconfig));
break; break;
} }
...@@ -607,7 +630,13 @@ int main(int ac, char **av) ...@@ -607,7 +630,13 @@ int main(int ac, char **av)
fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
return 1; return 1;
} }
} else { } else 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)) { if (conf_write(NULL)) {
fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
exit(1); exit(1);
......
...@@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def) ...@@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def)
if (in) if (in)
goto load; goto load;
sym_add_change_count(1); sym_add_change_count(1);
if (!sym_defconfig_list) if (!sym_defconfig_list) {
if (modules_sym)
sym_calc_value(modules_sym);
return 1; return 1;
}
for_all_defaults(sym_defconfig_list, prop) { for_all_defaults(sym_defconfig_list, prop) {
if (expr_calc_value(prop->visible.expr) == no || if (expr_calc_value(prop->visible.expr) == no ||
...@@ -396,15 +399,149 @@ int conf_read(const char *name) ...@@ -396,15 +399,149 @@ int conf_read(const char *name)
return 0; return 0;
} }
/* Write a S_STRING */
static void conf_write_string(bool headerfile, const char *name,
const char *str, FILE *out)
{
int l;
if (headerfile)
fprintf(out, "#define CONFIG_%s \"", name);
else
fprintf(out, "CONFIG_%s=\"", name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
str += l;
}
if (!*str)
break;
fprintf(out, "\\%c", *str++);
}
fputs("\"\n", out);
}
static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
FILE *out, bool write_no)
{
const char *str;
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
if (write_no)
fprintf(out, "# CONFIG_%s is not set\n", sym->name);
break;
case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name);
break;
case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name);
break;
}
break;
case S_STRING:
conf_write_string(false, sym->name, sym_get_string_value(sym), out);
break;
case S_HEX:
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
break;
case S_OTHER:
case S_UNKNOWN:
break;
}
}
/*
* Write out a minimal config.
* All values that has default values are skipped as this is redundant.
*/
int conf_write_defconfig(const char *filename)
{
struct symbol *sym;
struct menu *menu;
FILE *out;
out = fopen(filename, "w");
if (!out)
return 1;
sym_clear_all_valid();
/* Traverse all menus to find all relevant symbols */
menu = rootmenu.list;
while (menu != NULL)
{
sym = menu->sym;
if (sym == NULL) {
if (!menu_is_visible(menu))
goto next_menu;
} else if (!sym_is_choice(sym)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
goto next_menu;
sym->flags &= ~SYMBOL_WRITE;
/* If we cannot change the symbol - skip */
if (!sym_is_changable(sym))
goto next_menu;
/* If symbol equals to default value - skip */
if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
goto next_menu;
/*
* If symbol is a choice value and equals to the
* default for a choice - skip.
* But only if value equal to "y".
*/
if (sym_is_choice_value(sym)) {
struct symbol *cs;
struct symbol *ds;
cs = prop_get_symbol(sym_get_choice_prop(sym));
ds = sym_choice_default(cs);
if (sym == ds) {
if ((sym->type == S_BOOLEAN ||
sym->type == S_TRISTATE) &&
sym_get_tristate_value(sym) == yes)
goto next_menu;
}
}
conf_write_symbol(sym, sym->type, out, true);
}
next_menu:
if (menu->list != NULL) {
menu = menu->list;
}
else if (menu->next != NULL) {
menu = menu->next;
} else {
while ((menu = menu->parent)) {
if (menu->next != NULL) {
menu = menu->next;
break;
}
}
}
}
fclose(out);
return 0;
}
int conf_write(const char *name) int conf_write(const char *name)
{ {
FILE *out; FILE *out;
struct symbol *sym; struct symbol *sym;
struct menu *menu; struct menu *menu;
const char *basename; const char *basename;
char dirname[128], tmpname[128], newname[128];
int type, l;
const char *str; const char *str;
char dirname[128], tmpname[128], newname[128];
enum symbol_type type;
time_t now; time_t now;
int use_timestamp = 1; int use_timestamp = 1;
char *env; char *env;
...@@ -484,50 +621,11 @@ int conf_write(const char *name) ...@@ -484,50 +621,11 @@ int conf_write(const char *name)
if (modules_sym->curr.tri == no) if (modules_sym->curr.tri == no)
type = S_BOOLEAN; type = S_BOOLEAN;
} }
switch (type) { /* Write config symbol to file */
case S_BOOLEAN: conf_write_symbol(sym, type, out, true);
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
fprintf(out, "# CONFIG_%s is not set\n", sym->name);
break;
case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name);
break;
case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name);
break;
}
break;
case S_STRING:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=\"", sym->name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
str += l;
}
if (!*str)
break;
fprintf(out, "\\%c", *str++);
}
fputs("\"\n", out);
break;
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
break;
}
} }
next: next:
if (menu->list) { if (menu->list) {
menu = menu->list; menu = menu->list;
continue; continue;
...@@ -679,7 +777,7 @@ int conf_write_autoconf(void) ...@@ -679,7 +777,7 @@ int conf_write_autoconf(void)
const char *name; const char *name;
FILE *out, *tristate, *out_h; FILE *out, *tristate, *out_h;
time_t now; time_t now;
int i, l; int i;
sym_clear_all_valid(); sym_clear_all_valid();
...@@ -729,6 +827,11 @@ int conf_write_autoconf(void) ...@@ -729,6 +827,11 @@ int conf_write_autoconf(void)
sym_calc_value(sym); sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE) || !sym->name) if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
continue; continue;
/* write symbol to config file */
conf_write_symbol(sym, sym->type, out, false);
/* update autoconf and tristate files */
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
...@@ -736,12 +839,10 @@ int conf_write_autoconf(void) ...@@ -736,12 +839,10 @@ int conf_write_autoconf(void)
case no: case no:
break; break;
case mod: case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name);
fprintf(tristate, "CONFIG_%s=M\n", sym->name); fprintf(tristate, "CONFIG_%s=M\n", sym->name);
fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
break; break;
case yes: case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name);
if (sym->type == S_TRISTATE) if (sym->type == S_TRISTATE)
fprintf(tristate, "CONFIG_%s=Y\n", fprintf(tristate, "CONFIG_%s=Y\n",
sym->name); sym->name);
...@@ -750,35 +851,16 @@ int conf_write_autoconf(void) ...@@ -750,35 +851,16 @@ int conf_write_autoconf(void)
} }
break; break;
case S_STRING: case S_STRING:
str = sym_get_string_value(sym); conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
fprintf(out, "CONFIG_%s=\"", sym->name);
fprintf(out_h, "#define CONFIG_%s \"", sym->name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
fwrite(str, l, 1, out_h);
str += l;
}
if (!*str)
break;
fprintf(out, "\\%c", *str);
fprintf(out_h, "\\%c", *str);
str++;
}
fputs("\"\n", out);
fputs("\"\n", out_h);
break; break;
case S_HEX: case S_HEX:
str = sym_get_string_value(sym); str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
break; break;
} }
case S_INT: case S_INT:
str = sym_get_string_value(sym); str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
break; break;
default: default:
...@@ -862,7 +944,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) ...@@ -862,7 +944,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
sym->def[S_DEF_USER].tri = no; sym->def[S_DEF_USER].tri = no;
break; break;
case def_random: case def_random:
sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
break; break;
default: default:
continue; continue;
......
...@@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s ...@@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s
} }
str_append(gs, str); str_append(gs, str);
if (sym) if (sym && sym->type != S_UNKNOWN)
str_printf(gs, " [=%s]", sym_str); str_printf(gs, " [=%s]", sym_str);
} }
......
...@@ -83,6 +83,7 @@ struct symbol { ...@@ -83,6 +83,7 @@ struct symbol {
tristate visible; tristate visible;
int flags; int flags;
struct property *prop; struct property *prop;
struct expr_value dir_dep;
struct expr_value rev_dep; struct expr_value rev_dep;
}; };
...@@ -131,6 +132,7 @@ enum prop_type { ...@@ -131,6 +132,7 @@ enum prop_type {
P_SELECT, /* select BAR */ P_SELECT, /* select BAR */
P_RANGE, /* range 7..100 (for a symbol) */ P_RANGE, /* range 7..100 (for a symbol) */
P_ENV, /* value from environment variable */ P_ENV, /* value from environment variable */
P_SYMBOL, /* where a symbol is defined */
}; };
struct property { struct property {
...@@ -163,6 +165,7 @@ struct menu { ...@@ -163,6 +165,7 @@ struct menu {
struct symbol *sym; struct symbol *sym;
struct property *prompt; struct property *prompt;
struct expr *dep; struct expr *dep;
struct expr *dir_dep;
unsigned int flags; unsigned int flags;
char *help; char *help;
struct file *file; struct file *file;
......
...@@ -1114,7 +1114,7 @@ static gchar **fill_row(struct menu *menu) ...@@ -1114,7 +1114,7 @@ static gchar **fill_row(struct menu *menu)
row[COL_OPTION] = row[COL_OPTION] =
g_strdup_printf("%s %s", _(menu_get_prompt(menu)), g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
sym && sym_has_value(sym) ? "(NEW)" : ""); sym && !sym_has_value(sym) ? "(NEW)" : "");
if (opt_mode == OPT_ALL && !menu_is_visible(menu)) if (opt_mode == OPT_ALL && !menu_is_visible(menu))
row[COL_COLOR] = g_strdup("DarkGray"); row[COL_COLOR] = g_strdup("DarkGray");
...@@ -1343,7 +1343,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) ...@@ -1343,7 +1343,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
#endif #endif
if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
(opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) { (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
(opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
/* remove node */ /* remove node */
if (gtktree_iter_find_node(dst, menu1) != NULL) { if (gtktree_iter_find_node(dst, menu1) != NULL) {
...@@ -1425,7 +1426,7 @@ static void display_tree(struct menu *menu) ...@@ -1425,7 +1426,7 @@ static void display_tree(struct menu *menu)
if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
(opt_mode == OPT_PROMPT && menu_has_prompt(child)) || (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
(opt_mode == OPT_ALL)) (opt_mode == OPT_ALL && menu_get_prompt(child)))
place_node(child, fill_row(child)); place_node(child, fill_row(child));
#ifdef DEBUG #ifdef DEBUG
printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
......
...@@ -126,6 +126,8 @@ void sym_init(void); ...@@ -126,6 +126,8 @@ void sym_init(void);
void sym_clear_all_valid(void); void sym_clear_all_valid(void);
void sym_set_all_changed(void); void sym_set_all_changed(void);
void sym_set_changed(struct symbol *sym); void sym_set_changed(struct symbol *sym);
struct symbol *sym_choice_default(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym);
struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym);
struct symbol *prop_get_symbol(struct property *prop); struct symbol *prop_get_symbol(struct property *prop);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
P(conf_parse,void,(const char *name)); P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name)); P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name, int)); P(conf_read_simple,int,(const char *name, int));
P(conf_write_defconfig,int,(const char *name));
P(conf_write,int,(const char *name)); P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void)); P(conf_write_autoconf,int,(void));
P(conf_get_changed,bool,(void)); P(conf_get_changed,bool,(void));
......
...@@ -31,6 +31,10 @@ static int list_width, check_x, item_x; ...@@ -31,6 +31,10 @@ static int list_width, check_x, item_x;
static void print_item(WINDOW * win, int choice, int selected) static void print_item(WINDOW * win, int choice, int selected)
{ {
int i; int i;
char *list_item = malloc(list_width + 1);
strncpy(list_item, item_str(), list_width - item_x);
list_item[list_width - item_x] = '\0';
/* Clear 'residue' of last item */ /* Clear 'residue' of last item */
wattrset(win, dlg.menubox.atr); wattrset(win, dlg.menubox.atr);
...@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected) ...@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected)
wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
mvwaddch(win, choice, item_x, item_str()[0]); mvwaddch(win, choice, item_x, list_item[0]);
wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
waddstr(win, (char *)item_str() + 1); waddstr(win, list_item + 1);
if (selected) { if (selected) {
wmove(win, choice, check_x + 1); wmove(win, choice, check_x + 1);
wrefresh(win); wrefresh(win);
} }
free(list_item);
} }
/* /*
...@@ -175,6 +180,7 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -175,6 +180,7 @@ int dialog_checklist(const char *title, const char *prompt, int height,
check_x = 0; check_x = 0;
item_foreach() item_foreach()
check_x = MAX(check_x, strlen(item_str()) + 4); check_x = MAX(check_x, strlen(item_str()) + 4);
check_x = MIN(check_x, list_width);
check_x = (list_width - check_x) / 2; check_x = (list_width - check_x) / 2;
item_x = check_x + 4; item_x = check_x + 4;
......
...@@ -74,7 +74,7 @@ static const char mconf_readme[] = N_( ...@@ -74,7 +74,7 @@ static const char mconf_readme[] = N_(
"\n" "\n"
" Shortcut: Press <H> or <?>.\n" " Shortcut: Press <H> or <?>.\n"
"\n" "\n"
"o To show hidden options, press <Z>.\n" "o To toggle the display of hidden options, press <Z>.\n"
"\n" "\n"
"\n" "\n"
"Radiolists (Choice lists)\n" "Radiolists (Choice lists)\n"
......
...@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym) ...@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
*last_entry_ptr = menu; *last_entry_ptr = menu;
last_entry_ptr = &menu->next; last_entry_ptr = &menu->next;
current_entry = menu; current_entry = menu;
if (sym)
menu_add_symbol(P_SYMBOL, sym, NULL);
} }
void menu_end_entry(void) void menu_end_entry(void)
...@@ -105,6 +107,7 @@ static struct expr *menu_check_dep(struct expr *e) ...@@ -105,6 +107,7 @@ static struct expr *menu_check_dep(struct expr *e)
void menu_add_dep(struct expr *dep) void menu_add_dep(struct expr *dep)
{ {
current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
current_entry->dir_dep = current_entry->dep;
} }
void menu_set_type(int type) void menu_set_type(int type)
...@@ -288,6 +291,10 @@ void menu_finalize(struct menu *parent) ...@@ -288,6 +291,10 @@ void menu_finalize(struct menu *parent)
for (menu = parent->list; menu; menu = menu->next) for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu); menu_finalize(menu);
} else if (sym) { } else if (sym) {
/* ignore inherited dependencies for dir_dep */
sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep)); basedep = expr_eliminate_dups(expr_transform(basedep));
...@@ -419,9 +426,13 @@ bool menu_is_visible(struct menu *menu) ...@@ -419,9 +426,13 @@ bool menu_is_visible(struct menu *menu)
if (!sym || sym_get_tristate_value(menu->sym) == no) if (!sym || sym_get_tristate_value(menu->sym) == no)
return false; return false;
for (child = menu->list; child; child = child->next) for (child = menu->list; child; child = child->next) {
if (menu_is_visible(child)) if (menu_is_visible(child)) {
if (sym)
sym->flags |= SYMBOL_DEF_USER;
return true; return true;
}
}
return false; return false;
} }
...@@ -501,9 +512,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) ...@@ -501,9 +512,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
bool hit; bool hit;
struct property *prop; struct property *prop;
if (sym && sym->name) if (sym && sym->name) {
str_printf(r, "Symbol: %s [=%s]\n", sym->name, str_printf(r, "Symbol: %s [=%s]\n", sym->name,
sym_get_string_value(sym)); sym_get_string_value(sym));
str_printf(r, "Type : %s\n", sym_type_name(sym->type));
if (sym->type == S_INT || sym->type == S_HEX) {
prop = sym_get_range_prop(sym);
if (prop) {
str_printf(r, "Range : ");
expr_gstr_print(prop->expr, r);
str_append(r, "\n");
}
}
}
for_all_prompts(sym, prop) for_all_prompts(sym, prop)
get_prompt_str(r, prop); get_prompt_str(r, prop);
hit = false; hit = false;
......
...@@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok) ...@@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
{ {
QValueList<int> result; QValueList<int> result;
QStringList entryList = readListEntry(key, ok); QStringList entryList = readListEntry(key, ok);
if (ok) { QStringList::Iterator it;
QStringList::Iterator it;
for (it = entryList.begin(); it != entryList.end(); ++it) for (it = entryList.begin(); it != entryList.end(); ++it)
result.push_back((*it).toInt()); result.push_back((*it).toInt());
}
return result; return result;
} }
...@@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void) ...@@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void)
case S_TRISTATE: case S_TRISTATE:
char ch; char ch;
if (!sym_is_changable(sym) && !list->showAll) { if (!sym_is_changable(sym) && list->optMode == normalOpt) {
setPixmap(promptColIdx, 0); setPixmap(promptColIdx, 0);
setText(noColIdx, QString::null); setText(noColIdx, QString::null);
setText(modColIdx, QString::null); setText(modColIdx, QString::null);
...@@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name) ...@@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
showAll(false), showName(false), showRange(false), showData(false), showName(false), showRange(false), showData(false), optMode(normalOpt),
rootEntry(0), headerPopup(0) rootEntry(0), headerPopup(0)
{ {
int i; int i;
...@@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name) ...@@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
if (name) { if (name) {
configSettings->beginGroup(name); configSettings->beginGroup(name);
showAll = configSettings->readBoolEntry("/showAll", false);
showName = configSettings->readBoolEntry("/showName", false); showName = configSettings->readBoolEntry("/showName", false);
showRange = configSettings->readBoolEntry("/showRange", false); showRange = configSettings->readBoolEntry("/showRange", false);
showData = configSettings->readBoolEntry("/showData", false); showData = configSettings->readBoolEntry("/showData", false);
optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
configSettings->endGroup(); configSettings->endGroup();
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
} }
...@@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name) ...@@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
reinit(); reinit();
} }
bool ConfigList::menuSkip(struct menu *menu)
{
if (optMode == normalOpt && menu_is_visible(menu))
return false;
if (optMode == promptOpt && menu_has_prompt(menu))
return false;
if (optMode == allOpt)
return false;
return true;
}
void ConfigList::reinit(void) void ConfigList::reinit(void)
{ {
removeColumn(dataColIdx); removeColumn(dataColIdx);
...@@ -380,7 +390,7 @@ void ConfigList::saveSettings(void) ...@@ -380,7 +390,7 @@ void ConfigList::saveSettings(void)
configSettings->writeEntry("/showName", showName); configSettings->writeEntry("/showName", showName);
configSettings->writeEntry("/showRange", showRange); configSettings->writeEntry("/showRange", showRange);
configSettings->writeEntry("/showData", showData); configSettings->writeEntry("/showData", showData);
configSettings->writeEntry("/showAll", showAll); configSettings->writeEntry("/optionMode", (int)optMode);
configSettings->endGroup(); configSettings->endGroup();
} }
} }
...@@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) ...@@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
} }
visible = menu_is_visible(child); visible = menu_is_visible(child);
if (showAll || visible) { if (!menuSkip(child)) {
if (!child->sym && !child->list && !child->prompt) if (!child->sym && !child->list && !child->prompt)
continue; continue;
if (!item || item->menu != child) if (!item || item->menu != child)
...@@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) ...@@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
e->ignore(); e->ignore();
} }
ConfigView* ConfigView::viewList; ConfigView*ConfigView::viewList;
QAction *ConfigView::showNormalAction;
QAction *ConfigView::showAllAction;
QAction *ConfigView::showPromptAction;
ConfigView::ConfigView(QWidget* parent, const char *name) ConfigView::ConfigView(QWidget* parent, const char *name)
: Parent(parent, name) : Parent(parent, name)
...@@ -860,13 +873,16 @@ ConfigView::~ConfigView(void) ...@@ -860,13 +873,16 @@ ConfigView::~ConfigView(void)
} }
} }
void ConfigView::setShowAll(bool b) void ConfigView::setOptionMode(QAction *act)
{ {
if (list->showAll != b) { if (act == showNormalAction)
list->showAll = b; list->optMode = normalOpt;
list->updateListAll(); else if (act == showAllAction)
emit showAllChanged(b); list->optMode = allOpt;
} else
list->optMode = promptOpt;
list->updateListAll();
} }
void ConfigView::setShowName(bool b) void ConfigView::setShowName(bool b)
...@@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m) ...@@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m)
menuInfo(); menuInfo();
} }
void ConfigInfoView::setSource(const QString& name)
{
const char *p = name.latin1();
menu = NULL;
sym = NULL;
switch (p[0]) {
case 'm':
struct menu *m;
if (sscanf(p, "m%p", &m) == 1 && menu != m) {
menu = m;
menuInfo();
emit menuSelected(menu);
}
break;
case 's':
struct symbol *s;
if (sscanf(p, "s%p", &s) == 1 && sym != s) {
sym = s;
symbolInfo();
}
break;
}
}
void ConfigInfoView::symbolInfo(void) void ConfigInfoView::symbolInfo(void)
{ {
QString str; QString str;
...@@ -1349,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void) ...@@ -1349,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void)
connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
showDataAction->setOn(configList->showData); showDataAction->setOn(configList->showData);
QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
showAllAction->setToggleAction(TRUE); QActionGroup *optGroup = new QActionGroup(this);
connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); optGroup->setExclusive(TRUE);
connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); connect(optGroup, SIGNAL(selected(QAction *)), configView,
showAllAction->setOn(configList->showAll); SLOT(setOptionMode(QAction *)));
connect(optGroup, SIGNAL(selected(QAction *)), menuView,
SLOT(setOptionMode(QAction *)));
configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup);
configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup);
configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup);
configView->showNormalAction->setToggleAction(TRUE);
configView->showNormalAction->setOn(configList->optMode == normalOpt);
configView->showAllAction->setToggleAction(TRUE);
configView->showAllAction->setOn(configList->optMode == allOpt);
configView->showPromptAction->setToggleAction(TRUE);
configView->showPromptAction->setOn(configList->optMode == promptOpt);
QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
showDebugAction->setToggleAction(TRUE); showDebugAction->setToggleAction(TRUE);
connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
...@@ -1396,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void) ...@@ -1396,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void)
showRangeAction->addTo(optionMenu); showRangeAction->addTo(optionMenu);
showDataAction->addTo(optionMenu); showDataAction->addTo(optionMenu);
optionMenu->insertSeparator(); optionMenu->insertSeparator();
showAllAction->addTo(optionMenu); optGroup->addTo(optionMenu);
optionMenu->insertSeparator();
showDebugAction->addTo(optionMenu); showDebugAction->addTo(optionMenu);
// create help menu // create help menu
...@@ -1491,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) ...@@ -1491,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
ConfigList* list = NULL; ConfigList* list = NULL;
ConfigItem* item; ConfigItem* item;
if (!menu_is_visible(menu) && !configView->showAll()) if (configList->menuSkip(menu))
return; return;
switch (configList->mode) { switch (configList->mode) {
......
...@@ -44,6 +44,9 @@ enum colIdx { ...@@ -44,6 +44,9 @@ enum colIdx {
enum listMode { enum listMode {
singleMode, menuMode, symbolMode, fullMode, listMode singleMode, menuMode, symbolMode, fullMode, listMode
}; };
enum optionMode {
normalOpt = 0, allOpt, promptOpt
};
class ConfigList : public QListView { class ConfigList : public QListView {
Q_OBJECT Q_OBJECT
...@@ -115,6 +118,8 @@ public slots: ...@@ -115,6 +118,8 @@ public slots:
void setAllOpen(bool open); void setAllOpen(bool open);
void setParentMenu(void); void setParentMenu(void);
bool menuSkip(struct menu *);
template <class P> template <class P>
void updateMenuList(P*, struct menu*); void updateMenuList(P*, struct menu*);
...@@ -124,8 +129,9 @@ public slots: ...@@ -124,8 +129,9 @@ public slots:
QPixmap choiceYesPix, choiceNoPix; QPixmap choiceYesPix, choiceNoPix;
QPixmap menuPix, menuInvPix, menuBackPix, voidPix; QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
bool showAll, showName, showRange, showData; bool showName, showRange, showData;
enum listMode mode; enum listMode mode;
enum optionMode optMode;
struct menu *rootEntry; struct menu *rootEntry;
QColorGroup disabledColorGroup; QColorGroup disabledColorGroup;
QColorGroup inactivedColorGroup; QColorGroup inactivedColorGroup;
...@@ -222,17 +228,15 @@ class ConfigView : public QVBox { ...@@ -222,17 +228,15 @@ class ConfigView : public QVBox {
static void updateList(ConfigItem* item); static void updateList(ConfigItem* item);
static void updateListAll(void); static void updateListAll(void);
bool showAll(void) const { return list->showAll; }
bool showName(void) const { return list->showName; } bool showName(void) const { return list->showName; }
bool showRange(void) const { return list->showRange; } bool showRange(void) const { return list->showRange; }
bool showData(void) const { return list->showData; } bool showData(void) const { return list->showData; }
public slots: public slots:
void setShowAll(bool);
void setShowName(bool); void setShowName(bool);
void setShowRange(bool); void setShowRange(bool);
void setShowData(bool); void setShowData(bool);
void setOptionMode(QAction *);
signals: signals:
void showAllChanged(bool);
void showNameChanged(bool); void showNameChanged(bool);
void showRangeChanged(bool); void showRangeChanged(bool);
void showDataChanged(bool); void showDataChanged(bool);
...@@ -242,6 +246,10 @@ public slots: ...@@ -242,6 +246,10 @@ public slots:
static ConfigView* viewList; static ConfigView* viewList;
ConfigView* nextView; ConfigView* nextView;
static QAction *showNormalAction;
static QAction *showAllAction;
static QAction *showPromptAction;
}; };
class ConfigInfoView : public QTextBrowser { class ConfigInfoView : public QTextBrowser {
...@@ -254,7 +262,6 @@ class ConfigInfoView : public QTextBrowser { ...@@ -254,7 +262,6 @@ class ConfigInfoView : public QTextBrowser {
public slots: public slots:
void setInfo(struct menu *menu); void setInfo(struct menu *menu);
void saveSettings(void); void saveSettings(void);
void setSource(const QString& name);
void setShowDebug(bool); void setShowDebug(bool);
signals: signals:
......
...@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym) ...@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym)
} }
if (sym_is_choice_value(sym)) if (sym_is_choice_value(sym))
return; return;
/* defaulting to "yes" if no explicit "depends on" are given */
tri = yes;
if (sym->dir_dep.expr)
tri = expr_calc_value(sym->dir_dep.expr);
if (tri == mod)
tri = yes;
if (sym->dir_dep.tri != tri) {
sym->dir_dep.tri = tri;
sym_set_changed(sym);
}
tri = no; tri = no;
if (sym->rev_dep.expr) if (sym->rev_dep.expr)
tri = expr_calc_value(sym->rev_dep.expr); tri = expr_calc_value(sym->rev_dep.expr);
...@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym) ...@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym)
} }
} }
static struct symbol *sym_calc_choice(struct symbol *sym) /*
* Find the default symbol for a choice.
* First try the default values for the choice symbol
* Next locate the first visible choice value
* Return NULL if none was found
*/
struct symbol *sym_choice_default(struct symbol *sym)
{ {
struct symbol *def_sym; struct symbol *def_sym;
struct property *prop; struct property *prop;
struct expr *e; struct expr *e;
/* is the user choice visible? */
def_sym = sym->def[S_DEF_USER].val;
if (def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
return def_sym;
}
/* any of the defaults visible? */ /* any of the defaults visible? */
for_all_defaults(sym, prop) { for_all_defaults(sym, prop) {
prop->visible.tri = expr_calc_value(prop->visible.expr); prop->visible.tri = expr_calc_value(prop->visible.expr);
if (prop->visible.tri == no) if (prop->visible.tri == no)
continue; continue;
def_sym = prop_get_symbol(prop); def_sym = prop_get_symbol(prop);
sym_calc_visibility(def_sym);
if (def_sym->visible != no) if (def_sym->visible != no)
return def_sym; return def_sym;
} }
/* just get the first visible value */ /* just get the first visible value */
prop = sym_get_choice_prop(sym); prop = sym_get_choice_prop(sym);
expr_list_for_each_sym(prop->expr, e, def_sym) { expr_list_for_each_sym(prop->expr, e, def_sym)
sym_calc_visibility(def_sym);
if (def_sym->visible != no) if (def_sym->visible != no)
return def_sym; return def_sym;
}
/* no choice? reset tristate value */ /* failed to locate any defaults */
sym->curr.tri = no;
return NULL; return NULL;
} }
static struct symbol *sym_calc_choice(struct symbol *sym)
{
struct symbol *def_sym;
struct property *prop;
struct expr *e;
/* first calculate all choice values' visibilities */
prop = sym_get_choice_prop(sym);
expr_list_for_each_sym(prop->expr, e, def_sym)
sym_calc_visibility(def_sym);
/* is the user choice visible? */
def_sym = sym->def[S_DEF_USER].val;
if (def_sym && def_sym->visible != no)
return def_sym;
def_sym = sym_choice_default(sym);
if (def_sym == NULL)
/* no choice? reset tristate value */
sym->curr.tri = no;
return def_sym;
}
void sym_calc_value(struct symbol *sym) void sym_calc_value(struct symbol *sym)
{ {
struct symbol_value newval, oldval; struct symbol_value newval, oldval;
...@@ -321,6 +350,14 @@ void sym_calc_value(struct symbol *sym) ...@@ -321,6 +350,14 @@ void sym_calc_value(struct symbol *sym)
} }
} }
calc_newval: calc_newval:
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
fprintf(stderr, "warning: (");
expr_fprint(sym->rev_dep.expr, stderr);
fprintf(stderr, ") selects %s which has unmet direct dependencies (",
sym->name);
expr_fprint(sym->dir_dep.expr, stderr);
fprintf(stderr, ")\n");
}
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
} }
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
...@@ -365,12 +402,13 @@ void sym_calc_value(struct symbol *sym) ...@@ -365,12 +402,13 @@ void sym_calc_value(struct symbol *sym)
if (sym_is_choice(sym)) { if (sym_is_choice(sym)) {
struct symbol *choice_sym; struct symbol *choice_sym;
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
prop = sym_get_choice_prop(sym); prop = sym_get_choice_prop(sym);
expr_list_for_each_sym(prop->expr, e, choice_sym) { expr_list_for_each_sym(prop->expr, e, choice_sym) {
choice_sym->flags |= flags; if ((sym->flags & SYMBOL_WRITE) &&
if (flags & SYMBOL_CHANGED) choice_sym->visible != no)
choice_sym->flags |= SYMBOL_WRITE;
if (sym->flags & SYMBOL_CHANGED)
sym_set_changed(choice_sym); sym_set_changed(choice_sym);
} }
} }
...@@ -623,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) ...@@ -623,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
return true; return true;
} }
/*
* Find the default value associated to a symbol.
* For tristate symbol handle the modules=n case
* in which case "m" becomes "y".
* If the symbol does not have any default then fallback
* to the fixed default values.
*/
const char *sym_get_string_default(struct symbol *sym)
{
struct property *prop;
struct symbol *ds;
const char *str;
tristate val;
sym_calc_visibility(sym);
sym_calc_value(modules_sym);
val = symbol_no.curr.tri;
str = symbol_empty.curr.val;
/* If symbol has a default value look it up */
prop = sym_get_default_prop(sym);
if (prop != NULL) {
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
/* The visibility imay limit the value from yes => mod */
val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
break;
default:
/*
* The following fails to handle the situation
* where a default value is further limited by
* the valid range.
*/
ds = prop_get_symbol(prop);
if (ds != NULL) {
sym_calc_value(ds);
str = (const char *)ds->curr.val;
}
}
}
/* Handle select statements */
val = EXPR_OR(val, sym->rev_dep.tri);
/* transpose mod to yes if modules are not enabled */
if (val == mod)
if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
val = yes;
/* transpose mod to yes if type is bool */
if (sym->type == S_BOOLEAN && val == mod)
val = yes;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (val) {
case no: return "n";
case mod: return "m";
case yes: return "y";
}
case S_INT:
case S_HEX:
return str;
case S_STRING:
return str;
case S_OTHER:
case S_UNKNOWN:
break;
}
return "";
}
const char *sym_get_string_value(struct symbol *sym) const char *sym_get_string_value(struct symbol *sym)
{ {
tristate val; tristate val;
...@@ -765,6 +877,110 @@ struct symbol **sym_re_search(const char *pattern) ...@@ -765,6 +877,110 @@ struct symbol **sym_re_search(const char *pattern)
return sym_arr; return sym_arr;
} }
/*
* When we check for recursive dependencies we use a stack to save
* current state so we can print out relevant info to user.
* The entries are located on the call stack so no need to free memory.
* Note inser() remove() must always match to properly clear the stack.
*/
static struct dep_stack {
struct dep_stack *prev, *next;
struct symbol *sym;
struct property *prop;
struct expr *expr;
} *check_top;
static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
{
memset(stack, 0, sizeof(*stack));
if (check_top)
check_top->next = stack;
stack->prev = check_top;
stack->sym = sym;
check_top = stack;
}
static void dep_stack_remove(void)
{
check_top = check_top->prev;
if (check_top)
check_top->next = NULL;
}
/*
* Called when we have detected a recursive dependency.
* check_top point to the top of the stact so we use
* the ->prev pointer to locate the bottom of the stack.
*/
static void sym_check_print_recursive(struct symbol *last_sym)
{
struct dep_stack *stack;
struct symbol *sym, *next_sym;
struct menu *menu = NULL;
struct property *prop;
struct dep_stack cv_stack;
if (sym_is_choice_value(last_sym)) {
dep_stack_insert(&cv_stack, last_sym);
last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
}
for (stack = check_top; stack != NULL; stack = stack->prev)
if (stack->sym == last_sym)
break;
if (!stack) {
fprintf(stderr, "unexpected recursive dependency error\n");
return;
}
for (; stack; stack = stack->next) {
sym = stack->sym;
next_sym = stack->next ? stack->next->sym : last_sym;
prop = stack->prop;
/* for choice values find the menu entry (used below) */
if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
for (prop = sym->prop; prop; prop = prop->next) {
menu = prop->menu;
if (prop->menu)
break;
}
}
if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno);
if (stack->expr) {
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>",
prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>");
} else if (stack->prop) {
fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
} else if (sym_is_choice(sym)) {
fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
menu->file->name, menu->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
} else if (sym_is_choice_value(sym)) {
fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
menu->file->name, menu->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
} else {
fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
}
}
if (check_top == &cv_stack)
dep_stack_remove();
}
static struct symbol *sym_check_expr_deps(struct expr *e) static struct symbol *sym_check_expr_deps(struct expr *e)
{ {
...@@ -801,24 +1017,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) ...@@ -801,24 +1017,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
{ {
struct symbol *sym2; struct symbol *sym2;
struct property *prop; struct property *prop;
struct dep_stack stack;
dep_stack_insert(&stack, sym);
sym2 = sym_check_expr_deps(sym->rev_dep.expr); sym2 = sym_check_expr_deps(sym->rev_dep.expr);
if (sym2) if (sym2)
return sym2; goto out;
for (prop = sym->prop; prop; prop = prop->next) { for (prop = sym->prop; prop; prop = prop->next) {
if (prop->type == P_CHOICE || prop->type == P_SELECT) if (prop->type == P_CHOICE || prop->type == P_SELECT)
continue; continue;
stack.prop = prop;
sym2 = sym_check_expr_deps(prop->visible.expr); sym2 = sym_check_expr_deps(prop->visible.expr);
if (sym2) if (sym2)
break; break;
if (prop->type != P_DEFAULT || sym_is_choice(sym)) if (prop->type != P_DEFAULT || sym_is_choice(sym))
continue; continue;
stack.expr = prop->expr;
sym2 = sym_check_expr_deps(prop->expr); sym2 = sym_check_expr_deps(prop->expr);
if (sym2) if (sym2)
break; break;
stack.expr = NULL;
} }
out:
dep_stack_remove();
return sym2; return sym2;
} }
...@@ -827,6 +1052,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) ...@@ -827,6 +1052,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
struct symbol *sym, *sym2; struct symbol *sym, *sym2;
struct property *prop; struct property *prop;
struct expr *e; struct expr *e;
struct dep_stack stack;
dep_stack_insert(&stack, choice);
prop = sym_get_choice_prop(choice); prop = sym_get_choice_prop(choice);
expr_list_for_each_sym(prop->expr, e, sym) expr_list_for_each_sym(prop->expr, e, sym)
...@@ -840,10 +1068,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) ...@@ -840,10 +1068,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
expr_list_for_each_sym(prop->expr, e, sym) { expr_list_for_each_sym(prop->expr, e, sym) {
sym2 = sym_check_sym_deps(sym); sym2 = sym_check_sym_deps(sym);
if (sym2) { if (sym2)
fprintf(stderr, " -> %s", sym->name);
break; break;
}
} }
out: out:
expr_list_for_each_sym(prop->expr, e, sym) expr_list_for_each_sym(prop->expr, e, sym)
...@@ -853,6 +1079,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) ...@@ -853,6 +1079,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
prop_get_symbol(sym_get_choice_prop(sym2)) == choice) prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
sym2 = choice; sym2 = choice;
dep_stack_remove();
return sym2; return sym2;
} }
...@@ -862,18 +1090,20 @@ struct symbol *sym_check_deps(struct symbol *sym) ...@@ -862,18 +1090,20 @@ struct symbol *sym_check_deps(struct symbol *sym)
struct property *prop; struct property *prop;
if (sym->flags & SYMBOL_CHECK) { if (sym->flags & SYMBOL_CHECK) {
fprintf(stderr, "%s:%d:error: found recursive dependency: %s", sym_check_print_recursive(sym);
sym->prop->file->name, sym->prop->lineno,
sym->name ? sym->name : "<choice>");
return sym; return sym;
} }
if (sym->flags & SYMBOL_CHECKED) if (sym->flags & SYMBOL_CHECKED)
return NULL; return NULL;
if (sym_is_choice_value(sym)) { if (sym_is_choice_value(sym)) {
struct dep_stack stack;
/* for choice groups start the check with main choice symbol */ /* for choice groups start the check with main choice symbol */
dep_stack_insert(&stack, sym);
prop = sym_get_choice_prop(sym); prop = sym_get_choice_prop(sym);
sym2 = sym_check_deps(prop_get_symbol(prop)); sym2 = sym_check_deps(prop_get_symbol(prop));
dep_stack_remove();
} else if (sym_is_choice(sym)) { } else if (sym_is_choice(sym)) {
sym2 = sym_check_choice_deps(sym); sym2 = sym_check_choice_deps(sym);
} else { } else {
...@@ -882,14 +1112,8 @@ struct symbol *sym_check_deps(struct symbol *sym) ...@@ -882,14 +1112,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
sym->flags &= ~SYMBOL_CHECK; sym->flags &= ~SYMBOL_CHECK;
} }
if (sym2) { if (sym2 && sym2 == sym)
fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); sym2 = NULL;
if (sym2 == sym) {
fprintf(stderr, "\n");
zconfnerrs++;
sym2 = NULL;
}
}
return sym2; return sym2;
} }
...@@ -943,6 +1167,8 @@ const char *prop_get_type_name(enum prop_type type) ...@@ -943,6 +1167,8 @@ const char *prop_get_type_name(enum prop_type type)
return "select"; return "select";
case P_RANGE: case P_RANGE:
return "range"; return "range";
case P_SYMBOL:
return "symbol";
case P_UNKNOWN: case P_UNKNOWN:
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册