author | kergoth <kergoth> | 2003-06-17 17:03:49 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2003-06-17 17:03:49 (UTC) |
commit | 16e53b2a2e94742f3b55ee73700bb264e36638d4 (patch) (side-by-side diff) | |
tree | 4f2b65a635d25c1ce0cfeea7953623c2bf7d9534 /scripts | |
parent | 384b7f1a42f9f2f101dc8fe11c3625055d96f672 (diff) | |
download | opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.zip opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.tar.gz opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.tar.bz2 |
Update LinuxKernelConf version to 1.4.
-rw-r--r-- | scripts/kconfig/Makefile | 51 | ||||
-rw-r--r-- | scripts/kconfig/Makefile.kernel | 52 | ||||
-rw-r--r-- | scripts/kconfig/conf.c | 222 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 152 | ||||
-rw-r--r-- | scripts/kconfig/expr.c | 37 | ||||
-rw-r--r-- | scripts/kconfig/expr.h | 79 | ||||
-rw-r--r-- | scripts/kconfig/gconf.c | 1618 | ||||
-rw-r--r-- | scripts/kconfig/gconf.glade | 543 | ||||
-rw-r--r-- | scripts/kconfig/images.c | 34 | ||||
-rw-r--r-- | scripts/kconfig/lkc-language.txt | 52 | ||||
-rw-r--r-- | scripts/kconfig/lkc.h | 14 | ||||
-rw-r--r-- | scripts/kconfig/lkc_proto.h | 5 | ||||
-rw-r--r-- | scripts/kconfig/mconf.c | 66 | ||||
-rw-r--r-- | scripts/kconfig/menu.c | 194 | ||||
-rw-r--r-- | scripts/kconfig/qconf.cc | 405 | ||||
-rw-r--r-- | scripts/kconfig/qconf.h | 20 | ||||
-rw-r--r-- | scripts/kconfig/symbol.c | 465 | ||||
-rw-r--r-- | scripts/kconfig/zconf.l | 23 | ||||
-rw-r--r-- | scripts/kconfig/zconf.y | 230 |
19 files changed, 3489 insertions, 773 deletions
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 5a0d7e5..b918300 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -1,2 +1,2 @@ -VERSION=1.3 +VERSION=1.4 CC=gcc @@ -4,5 +4,5 @@ CXX=g++ CFLAGS=-O0 -Wall -g -fPIC -CXXFLAGS=$(CFLAGS) -I$(HOSTQTDIR)/include +CXXFLAGS=$(CFLAGS) -I$(QTDIR)/include LDFLAGS= -LXXFLAGS=$(LDFLAGS) -L$(HOSTQTDIR)/lib -Wl,-rpath,$(HOSTQTDIR)/lib +LXXFLAGS=$(LDFLAGS) -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib LEX=flex @@ -11,7 +11,9 @@ YACC=bison YFLAGS=-l -#YFLAGS=-d -t -v -l -ifndef HOSTQTDIR -HOSTQTDIR=/usr/share/qt +#YFLAGS=-t -v -l +ifndef QTDIR +QTDIR=/usr/share/qt3 endif -MOC=$(wildcard $(HOSTQTDIR)/bin/moc) +MOC=$(wildcard $(QTDIR)/bin/moc) +GTKCFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` +GTKLDFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs` @@ -21,2 +23,3 @@ mconf_SRC=mconf.c $(parse_SRC) qconf_SRC=qconf.cc +gconf_SRC=gconf.c kconfig_load.c HDR=expr.h lkc.h lkc_proto.h qconf.h @@ -25,3 +28,3 @@ OTHER=README lkc-language.txt Makefile.kernel \ INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \ - conf.c mconf.c qconf.cc kconfig_load.c images.c $(HDR) + conf.c mconf.c qconf.cc gconf.c gconf.glade kconfig_load.c images.c $(HDR) INSTGEN=lex.zconf.c zconf.tab.c @@ -62,2 +65,7 @@ qconf_OBJ=$(filter %.o, \ $(qconf_SRC)))))) +gconf_OBJ=$(filter %.o, \ + $(patsubst %.c,%.o, \ + $(patsubst %.y,%.tab.o, \ + $(patsubst %.l,lex.%.o, \ + $(gconf_SRC))))) OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ) @@ -86,2 +94,3 @@ qconf.moc: qconf.h qconf.o: qconf.cc qconf.moc images.c $(lkc_deps) +gconf.o: gconf.c $(lkc_deps) @@ -96,3 +105,3 @@ qconf: @echo Unable to find the QT installation. Please make sure that the - @echo QT development package is correctly installed and the HOSTQTDIR + @echo QT development package is correctly installed and the QTDIR @echo environment variable is set to the correct location. @@ -101,5 +110,11 @@ else qconf: $(qconf_OBJ) - $(CXX) $(LXXFLAGS) $^ -lqt -o $@ + $(CXX) $(LXXFLAGS) $^ -lqt-mt -o $@ endif +gconf.o: gconf.c + $(CC) $(CFLAGS) $(GTKCFLAGS) -c $< -o $@ + +gconf: $(gconf_OBJ) + $(CC) $(LDFLAGS) $(GTKLDFLAGS) $^ -o $@ + libkconfig.so: $(parse_OBJ) @@ -128,3 +143,3 @@ lex.%.c: %.l %.moc: %.h - $(HOSTQTDIR)/bin/moc -i $< -o $@ + $(QTDIR)/bin/moc -i $< -o $@ @@ -138,10 +153,12 @@ ifdef KERNELSRC install: $(INSTGEN) - set -x; cp $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \ - for f in $(INSTGEN); do cp $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \ - cp Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile + set -x; cp --remove-destination $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \ + for f in $(INSTGEN); do cp --remove-destination $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \ + cp --remove-destination Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile; \ + cp --remove-destination lkc-language.txt $(KERNELSRC)/Documentation/kbuild/kconfig-language.txt diff: $(INSTGEN) - for f in $(sort $(INST)); do diff -u $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \ - for f in $(INSTGEN); do diff -u $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \ - diff -u $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel + for f in $(sort $(INST)); do diff -Nu $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \ + for f in $(INSTGEN); do diff -Nu $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \ + diff -Nu $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel; \ + diff -Nu lkc-language.txt $(KERNELSRC)/Documentation/kbuild/kconfig-language.txt else diff --git a/scripts/kconfig/Makefile.kernel b/scripts/kconfig/Makefile.kernel index 22724a7..bae5e29 100644 --- a/scripts/kconfig/Makefile.kernel +++ b/scripts/kconfig/Makefile.kernel @@ -8,3 +8,6 @@ # Based on QT which needs to be installed to compile it +# gconf: Used for the gconfig target +# Based on GTK which needs to be installed to compile it # +################# @@ -13,3 +16,3 @@ libkconfig-objs := zconf.tab.o -host-progs := conf mconf qconf +host-progs := conf mconf qconf gconf conf-objs := conf.o libkconfig.so @@ -17,9 +20,13 @@ mconf-objs := mconf.o libkconfig.so -qconf-objs := kconfig_load.o +ifeq ($(MAKECMDGOALS),$(obj)/qconf) qconf-cxxobjs := qconf.o +qconf-objs := kconfig_load.o +endif -clean-files := libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \ - zconf.tab.c zconf.tab.h lex.zconf.c +ifeq ($(MAKECMDGOALS),$(obj)/gconf) +gconf-objs := gconf.o kconfig_load.o +endif -include $(TOPDIR)/Rules.make +clean-files := libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \ + .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c @@ -32,3 +39,6 @@ HOSTCXXFLAGS_qconf.o = -I$(QTDIR)/include -$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o: $(obj)/zconf.tab.h +HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs` +HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` + +$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h @@ -42,3 +52,3 @@ MOC = $(QTDIR)/bin/moc $(obj)/.tmp_qtcheck: - @set -e; for d in $$QTDIR /usr/share/qt /usr/lib/qt3; do \ + @set -e; for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \ @@ -64,2 +74,28 @@ endif +$(obj)/gconf.o: $(obj)/.tmp_gtkcheck + +ifeq ($(MAKECMDGOALS),$(obj)/gconf) +-include $(obj)/.tmp_gtkcheck + +# GTK needs some extra effort, too... +$(obj)/.tmp_gtkcheck: + @if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then \ + if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then \ + touch $@; \ + else \ + echo "*"; \ + echo "* GTK+ is present but version >= 2.0.0 is required."; \ + echo "*"; \ + false; \ + fi \ + else \ + echo "*"; \ + echo "* Unable to find the GTK+ installation. Please make sure that"; \ + echo "* the GTK+ 2.0 development package is correctly installed..."; \ + echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ + echo "*"; \ + false; \ + fi +endif + $(obj)/zconf.tab.o: $(obj)/lex.zconf.c @@ -70,2 +106,4 @@ $(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h +$(obj)/gconf.o: $(obj)/lkc_defs.h + $(obj)/%.moc: $(src)/%.h diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 1602d5f..3c27a78 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -37,40 +37,2 @@ static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; -#if 0 -static void printc(int ch) -{ - static int sep = 0; - - if (!sep) { - putchar('['); - sep = 1; - } else if (ch) - putchar('/'); - if (!ch) { - putchar(']'); - putchar(' '); - sep = 0; - } else - putchar(ch); -} -#endif - -static void printo(const char *o) -{ - static int sep = 0; - - if (!sep) { - putchar('('); - sep = 1; - } else if (o) { - putchar(','); - putchar(' '); - } - if (!o) { - putchar(')'); - putchar(' '); - sep = 0; - } else - printf("%s", o); -} - static void strip(char *str) @@ -92,2 +54,12 @@ static void strip(char *str) +static void check_stdin(void) +{ + if (!valid_stdin && input_mode == ask_silent) { + printf("aborted!\n\n"); + printf("Console input/output is redirected. "); + printf("Run 'make oldconfig' to update configuration.\n\n"); + exit(1); + } +} + static void conf_askvalue(struct symbol *sym, const char *def) @@ -103,2 +75,9 @@ static void conf_askvalue(struct symbol *sym, const char *def) + if (!sym_is_changable(sym)) { + printf("%s\n", def); + line[0] = '\n'; + line[1] = 0; + return; + } + switch (input_mode) { @@ -110,8 +89,3 @@ static void conf_askvalue(struct symbol *sym, const char *def) } - if (!valid_stdin && input_mode == ask_silent) { - printf("aborted!\n\n"); - printf("Console input/output is redirected. "); - printf("Run 'make oldconfig' to update configuration.\n\n"); - exit(1); - } + check_stdin(); case ask_all: @@ -296,5 +270,4 @@ static int conf_choice(struct menu *menu) struct symbol *sym, *def_sym; - struct menu *cmenu, *def_menu; - const char *help; - int type, len; + struct menu *child; + int type; bool is_new; @@ -316,6 +289,10 @@ static int conf_choice(struct menu *menu) } else { - sym->def = sym->curr; - if (S_TRI(sym->curr) == mod) { + switch (sym_get_tristate_value(sym)) { + case no: + return 1; + case mod: printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); return 0; + case yes: + break; } @@ -324,19 +301,38 @@ static int conf_choice(struct menu *menu) while (1) { - printf("%*s%s ", indent - 1, "", menu_get_prompt(menu)); + int cnt, def; + + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); def_sym = sym_get_choice_value(sym); - def_menu = NULL; - for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { - if (!menu_is_visible(cmenu)) + cnt = def = 0; + line[0] = '0'; + line[1] = 0; + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) continue; - printo(menu_get_prompt(cmenu)); - if (cmenu->sym == def_sym) - def_menu = cmenu; - } - printo(NULL); - if (def_menu) - printf("[%s] ", menu_get_prompt(def_menu)); - else { + if (!child->sym) { + printf("%*c %s\n", indent, '*', menu_get_prompt(child)); + continue; + } + cnt++; + if (child->sym == def_sym) { + def = cnt; + printf("%*c", indent, '>'); + } else + printf("%*c", indent, ' '); + printf(" %d. %s", cnt, menu_get_prompt(child)); + if (child->sym->name) + printf(" (%s)", child->sym->name); + if (!sym_has_value(child->sym)) + printf(" (NEW)"); printf("\n"); - return 1; } + printf("%*schoice", indent - 1, ""); + if (cnt == 1) { + printf("[1]: 1\n"); + goto conf_childs; + } + printf("[1-%d", cnt); + if (sym->help) + printf("?"); + printf("]: "); switch (input_mode) { @@ -344,42 +340,56 @@ static int conf_choice(struct menu *menu) case ask_silent: + if (!is_new) { + cnt = def; + printf("%d\n", cnt); + break; + } + check_stdin(); case ask_all: - if (is_new) - sym->flags |= SYMBOL_NEW; - conf_askvalue(sym, menu_get_prompt(def_menu)); + fflush(stdout); + fgets(line, 128, stdin); strip(line); + if (line[0] == '?') { + printf("\n%s\n", menu->sym->help ? + menu->sym->help : nohelp_text); + continue; + } + if (!line[0]) + cnt = def; + else if (isdigit(line[0])) + cnt = atoi(line); + else + continue; + break; + case set_random: + def = (random() % cnt) + 1; + case set_default: + case set_yes: + case set_mod: + case set_no: + cnt = def; + printf("%d\n", cnt); break; - default: - line[0] = 0; - printf("\n"); } - if (line[0] == '?' && !line[1]) { - help = nohelp_text; - if (menu->sym->help) - help = menu->sym->help; - printf("\n%s\n", help); - continue; + + conf_childs: + for (child = menu->list; child; child = child->next) { + if (!child->sym || !menu_is_visible(child)) + continue; + if (!--cnt) + break; } - if (line[0]) { - len = strlen(line); - line[len] = 0; - - def_menu = NULL; - for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { - if (!cmenu->sym || !menu_is_visible(cmenu)) - continue; - if (!strncasecmp(line, menu_get_prompt(cmenu), len)) { - def_menu = cmenu; - break; - } - } + if (!child) + continue; + if (line[strlen(line) - 1] == '?') { + printf("\n%s\n", child->sym->help ? + child->sym->help : nohelp_text); + continue; } - if (def_menu) { - sym_set_choice_value(sym, def_menu->sym); - if (def_menu->list) { - indent += 2; - conf(def_menu->list); - indent -= 2; - } - return 1; + sym_set_choice_value(sym, child->sym); + if (child->list) { + indent += 2; + conf(child->list); + indent -= 2; } + return 1; } @@ -424,3 +434,3 @@ static void conf(struct menu *menu) conf_choice(menu); - if (S_TRI(sym->curr) != mod) + if (sym->curr.tri != mod) return; @@ -458,7 +468,4 @@ static void check_conf(struct menu *menu) sym = menu->sym; - if (!sym) - goto conf_childs; - - if (sym_is_choice(sym)) { - if (!sym_has_value(sym)) { + if (sym) { + if (sym_is_changable(sym) && !sym_has_value(sym)) { if (!conf_cnt++) @@ -468,15 +475,6 @@ static void check_conf(struct menu *menu) } - if (sym_get_tristate_value(sym) != mod) + if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod) return; - goto conf_childs; } - if (!sym_has_value(sym)) { - if (!conf_cnt++) - printf("*\n* Restart config...\n*\n"); - rootEntry = menu_get_parent_menu(menu); - conf(rootEntry); - } - -conf_childs: for (child = menu->list; child; child = child->next) @@ -538,3 +536,3 @@ int main(int ac, char **av) printf("***\n" - "*** You have not yet configured your kernel!\n" + "*** You have not yet configured!\n" "***\n" diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9bf7af9..f3796ce 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -21,5 +21,2 @@ const char *conf_confnames[] = { ".config", - "/lib/modules/$UNAME_RELEASE/.config", - "/etc/kernel-config", - "/boot/config-$UNAME_RELEASE", conf_defname, @@ -107,7 +104,7 @@ int conf_read(const char *name) case S_STRING: - if (S_VAL(sym->def)) - free(S_VAL(sym->def)); + if (sym->user.val) + free(sym->user.val); default: - S_VAL(sym->def) = NULL; - S_TRI(sym->def) = no; + sym->user.val = NULL; + sym->user.tri = no; } @@ -131,3 +128,3 @@ int conf_read(const char *name) case S_TRISTATE: - sym->def = symbol_no.curr; + sym->user = symbol_no.curr; sym->flags &= ~SYMBOL_NEW; @@ -156,3 +153,3 @@ int conf_read(const char *name) if (p[0] == 'm') { - S_TRI(sym->def) = mod; + sym->user.tri = mod; sym->flags &= ~SYMBOL_NEW; @@ -162,3 +159,3 @@ int conf_read(const char *name) if (p[0] == 'y') { - S_TRI(sym->def) = yes; + sym->user.tri = yes; sym->flags &= ~SYMBOL_NEW; @@ -167,3 +164,3 @@ int conf_read(const char *name) if (p[0] == 'n') { - S_TRI(sym->def) = no; + sym->user.tri = no; sym->flags &= ~SYMBOL_NEW; @@ -189,3 +186,3 @@ int conf_read(const char *name) if (sym_string_valid(sym, p)) { - S_VAL(sym->def) = strdup(p); + sym->user.val = strdup(p); sym->flags &= ~SYMBOL_NEW; @@ -200,6 +197,6 @@ int conf_read(const char *name) if (sym_is_choice_value(sym)) { - prop = sym_get_choice_prop(sym); - switch (S_TRI(sym->def)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->user.tri) { case mod: - if (S_TRI(prop->def->def) == yes) + if (cs->user.tri == yes) /* warn? */; @@ -207,5 +204,5 @@ int conf_read(const char *name) case yes: - if (S_TRI(prop->def->def) != no) + if (cs->user.tri != no) /* warn? */; - S_VAL(prop->def->def) = sym; + cs->user.val = sym; break; @@ -214,3 +211,3 @@ int conf_read(const char *name) } - S_TRI(prop->def->def) = S_TRI(sym->def); + cs->user.tri = sym->user.tri; } @@ -226,2 +223,16 @@ int conf_read(const char *name) for_all_symbols(i, sym) { + sym_calc_value(sym); + if (sym_has_value(sym)) { + if (sym->visible == no) + sym->flags |= SYMBOL_NEW; + switch (sym->type) { + case S_STRING: + case S_INT: + case S_HEX: + if (!sym_string_within_range(sym, sym->user.val)) + sym->flags |= SYMBOL_NEW; + default: + break; + } + } if (!sym_is_choice(sym)) @@ -230,4 +241,5 @@ int conf_read(const char *name) sym->flags &= ~SYMBOL_NEW; - for (e = prop->dep; e; e = e->left.expr) - sym->flags |= e->right.sym->flags & SYMBOL_NEW; + for (e = prop->expr; e; e = e->left.expr) + if (e->right.sym->visible != no) + sym->flags |= e->right.sym->flags & SYMBOL_NEW; } @@ -244,3 +256,4 @@ int conf_write(const char *name) struct menu *menu; - char oldname[128]; + const char *basename; + char dirname[128], tmpname[128], newname[128]; int type, l; @@ -248,8 +261,28 @@ int conf_write(const char *name) - out = fopen(".tmpconfig", "w"); + dirname[0] = 0; + if (name && name[0]) { + char *slash = strrchr(name, '/'); + if (slash) { + int size = slash - name + 1; + memcpy(dirname, name, size); + dirname[size] = 0; + if (slash[1]) + basename = slash + 1; + else + basename = conf_def_filename; + } else + basename = name; + } else + basename = conf_def_filename; + + sprintf(newname, "%s.tmpconfig.%d", dirname, getpid()); + out = fopen(newname, "w"); if (!out) return 1; - out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) - return 1; + out_h = NULL; + if (!name) { + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) + return 1; + } fprintf(out, "#\n" @@ -257,6 +290,7 @@ int conf_write(const char *name) "#\n"); - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - " */\n" - "#define AUTOCONF_INCLUDED\n"); + if (out_h) + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " */\n" + "#define AUTOCONF_INCLUDED\n"); @@ -276,6 +310,7 @@ int conf_write(const char *name) "#\n", str); - fprintf(out_h, "\n" - "/*\n" - " * %s\n" - " */\n", str); + if (out_h) + fprintf(out_h, "\n" + "/*\n" + " * %s\n" + " */\n", str); } else if (!(sym->flags & SYMBOL_CHOICE)) { @@ -288,3 +323,3 @@ int conf_write(const char *name) sym_calc_value(modules_sym); - if (S_TRI(modules_sym->curr) == no) + if (modules_sym->curr.tri == no) type = S_BOOLEAN; @@ -297,3 +332,4 @@ int conf_write(const char *name) fprintf(out, "# CONFIG_%s is not set\n", sym->name); - fprintf(out_h, "#undef CONFIG_%s\n", sym->name); + if (out_h) + fprintf(out_h, "#undef CONFIG_%s\n", sym->name); break; @@ -301,3 +337,4 @@ int conf_write(const char *name) fprintf(out, "CONFIG_%s=m\n", sym->name); - fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; @@ -305,3 +342,4 @@ int conf_write(const char *name) fprintf(out, "CONFIG_%s=y\n", sym->name); - fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); break; @@ -313,3 +351,4 @@ int conf_write(const char *name) fprintf(out, "CONFIG_%s=\"", sym->name); - fprintf(out_h, "#define CONFIG_%s \"", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s \"", sym->name); do { @@ -318,3 +357,4 @@ int conf_write(const char *name) fwrite(str, l, 1, out); - fwrite(str, l, 1, out_h); + if (out_h) + fwrite(str, l, 1, out_h); } @@ -323,3 +363,4 @@ int conf_write(const char *name) fprintf(out, "\\%c", *str); - fprintf(out_h, "\\%c", *str); + if (out_h) + fprintf(out_h, "\\%c", *str); str++; @@ -328,3 +369,4 @@ int conf_write(const char *name) fputs("\"\n", out); - fputs("\"\n", out_h); + if (out_h) + fputs("\"\n", out_h); break; @@ -334,3 +376,4 @@ int conf_write(const char *name) fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); break; @@ -340,3 +383,4 @@ int conf_write(const char *name) fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); break; @@ -360,14 +404,14 @@ int conf_write(const char *name) fclose(out); - fclose(out_h); - - if (!name) { + if (out_h) { + fclose(out_h); rename(".tmpconfig.h", "include/linux/autoconf.h"); - name = conf_def_filename; - file_write_dep(NULL); - } else - unlink(".tmpconfig.h"); - - sprintf(oldname, "%s.old", name); - rename(name, oldname); - if (rename(".tmpconfig", name)) + } + if (!name || basename != conf_def_filename) { + if (!name) + name = conf_def_filename; + sprintf(tmpname, "%s.old", name); + rename(name, tmpname); + } + sprintf(tmpname, "%s%s", dirname, basename); + if (rename(newname, tmpname)) return 1; diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d1af2a5..3f15ae8 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -57,2 +57,9 @@ struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; +} + struct expr *expr_copy(struct expr *org) @@ -160,5 +167,18 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) { - if (!e1 || !e2 || e1->type != e2->type) + if (!e1 || !e2) return; - __expr_eliminate_eq(e1->type, ep1, ep2); + switch (e1->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e1->type, ep1, ep2); + default: + ; + } + if (e1->type != e2->type) switch (e2->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e2->type, ep1, ep2); + default: + ; + } e1 = expr_eliminate_yn(e1); @@ -197,2 +217,3 @@ int expr_eq(struct expr *e1, struct expr *e2) case E_CHOICE: + case E_RANGE: case E_NONE: @@ -899,2 +920,3 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb case E_CHOICE: + case E_RANGE: case E_NONE: @@ -916,3 +938,3 @@ tristate expr_calc_value(struct expr *e) sym_calc_value(e->left.sym); - return S_TRI(e->left.sym->curr); + return e->left.sym->curr.tri; case E_AND: @@ -1019,7 +1041,14 @@ void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, in case E_CHOICE: + fn(data, e->right.sym->name); if (e->left.expr) { - expr_print(e->left.expr, fn, data, E_CHOICE); fn(data, " ^ "); + expr_print(e->left.expr, fn, data, E_CHOICE); } + break; + case E_RANGE: + fn(data, "["); + fn(data, e->left.sym->name); + fn(data, " "); fn(data, e->right.sym->name); + fn(data, "]"); break; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 896a296..cc616f1 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -20,6 +20,2 @@ struct file { struct file *parent; -#ifdef CML1 - struct statement *stmt; - struct statement *last_stmt; -#endif char *name; @@ -38,3 +34,3 @@ typedef enum tristate { enum expr_type { - E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL + E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE }; @@ -47,7 +43,3 @@ union expr_data { struct expr { -#ifdef CML1 - int token; -#else enum expr_type type; -#endif union expr_data left, right; @@ -55,6 +47,2 @@ struct expr { -#define E_TRI(ev) ((ev).tri) -#define E_EXPR(ev) ((ev).expr) -#define E_CALC(ev) (E_TRI(ev) = expr_calc_value(E_EXPR(ev))) - #define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) @@ -68,8 +56,4 @@ struct expr_value { -#define S_VAL(sv) ((sv).value) -#define S_TRI(sv) ((sv).tri) -#define S_EQ(sv1, sv2) (S_VAL(sv1) == S_VAL(sv2) || !strcmp(S_VAL(sv1), S_VAL(sv2))) - struct symbol_value { - void *value; + void *val; tristate tri; @@ -85,8 +69,4 @@ struct symbol { char *help; -#ifdef CML1 - int type; -#else enum symbol_type type; -#endif - struct symbol_value curr, def; + struct symbol_value curr, user; tristate visible; @@ -95,3 +75,3 @@ struct symbol { struct expr *dep, *dep2; - struct menu *menu; + struct expr_value rev_dep; }; @@ -100,12 +80,2 @@ struct symbol { -#ifdef CML1 -#define SYMBOL_UNKNOWN S_UNKNOWN -#define SYMBOL_BOOLEAN S_BOOLEAN -#define SYMBOL_TRISTATE S_TRISTATE -#define SYMBOL_INT S_INT -#define SYMBOL_HEX S_HEX -#define SYMBOL_STRING S_STRING -#define SYMBOL_OTHER S_OTHER -#endif - #define SYMBOL_YES 0x0001 @@ -124,2 +94,5 @@ struct symbol { #define SYMBOL_AUTO 0x1000 +#define SYMBOL_CHECKED 0x2000 +#define SYMBOL_CHECK_DONE 0x4000 +#define SYMBOL_WARNED 0x8000 @@ -130,3 +103,3 @@ struct symbol { enum prop_type { - P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE + P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE }; @@ -136,12 +109,6 @@ struct property { struct symbol *sym; -#ifdef CML1 - int token; -#else enum prop_type type; -#endif const char *text; - struct symbol *def; struct expr_value visible; - struct expr *dep; - struct expr *dep2; + struct expr *expr; struct menu *menu; @@ -149,5 +116,2 @@ struct property { int lineno; -#ifdef CML1 - struct property *next_pos; -#endif }; @@ -157,5 +121,7 @@ struct property { if (st->type == (tok)) -#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT) #define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) #define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) +#define for_all_prompts(sym, st) \ + for (st = sym->prop; st; st = st->next) \ + if (st->text) @@ -176,2 +142,3 @@ struct menu { #define MENU_CHANGED 0x0001 +#define MENU_ROOT 0x0002 @@ -186,9 +153,3 @@ extern struct symbol *modules_sym; extern int cdebug; -extern int print_type; struct expr *expr_alloc_symbol(struct symbol *sym); -#ifdef CML1 -struct expr *expr_alloc_one(int token, struct expr *ce); -struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2); -struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2); -#else struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); @@ -196,4 +157,4 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); -#endif struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); struct expr *expr_copy(struct expr *org); @@ -217,13 +178,2 @@ void print_expr(int mask, struct expr *e, int prevtoken); -#ifdef CML1 -static inline int expr_is_yes(struct expr *e) -{ - return !e || (e->token == WORD && e->left.sym == &symbol_yes); -} - -static inline int expr_is_no(struct expr *e) -{ - return e && (e->token == WORD && e->left.sym == &symbol_no); -} -#else static inline int expr_is_yes(struct expr *e) @@ -238,3 +188,2 @@ static inline int expr_is_no(struct expr *e) #endif -#endif diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c new file mode 100644 index 0000000..3227180 --- a/dev/null +++ b/scripts/kconfig/gconf.c @@ -0,0 +1,1618 @@ +/* Hey EMACS -*- linux-c -*- */ +/* + * + * Copyright (C) 2002-2003 Romain Lievin <roms@lpg.ticalc.org> + * Released under the terms of the GNU GPL v2.0. + * + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "lkc.h" +#include "images.c" + +#include <glade/glade.h> +#include <gtk/gtk.h> +#include <glib.h> +#include <gdk/gdkkeysyms.h> + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <stdlib.h> + +//#define DEBUG + +enum { + SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW +}; + +static gint view_mode = SPLIT_VIEW; +static gboolean show_name = TRUE; +static gboolean show_range = TRUE; +static gboolean show_value = TRUE; +static gboolean show_all = FALSE; +static gboolean show_debug = FALSE; +static gboolean resizeable = FALSE; + +static gboolean config_changed = FALSE; + +static char nohelp_text[] = + "Sorry, no help available for this option yet.\n"; + +GtkWidget *main_wnd = NULL; +GtkWidget *tree1_w = NULL; // left frame +GtkWidget *tree2_w = NULL; // right frame +GtkWidget *text_w = NULL; +GtkWidget *hpaned = NULL; +GtkWidget *vpaned = NULL; +GtkWidget *back_btn = NULL; + +GtkTextTag *tag1, *tag2; +GdkColor color; + +GtkTreeStore *tree1, *tree2, *tree; +GtkTreeModel *model1, *model2; +static GtkTreeIter *parents[256] = { 0 }; +static gint indent; + +static struct menu *current; + +enum { + COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE, + COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF, + COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD, + COL_NUMBER +}; + +static void display_list(void); +static void display_tree(struct menu *menu); +static void display_tree_part(void); +static void update_tree(struct menu *src, GtkTreeIter * dst); +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); +static gchar **fill_row(struct menu *menu); + + +/* Helping/Debugging Functions */ + + +const char *dbg_print_stype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == S_UNKNOWN) + strcpy(buf, "unknown"); + if (val == S_BOOLEAN) + strcpy(buf, "boolean"); + if (val == S_TRISTATE) + strcpy(buf, "tristate"); + if (val == S_INT) + strcpy(buf, "int"); + if (val == S_HEX) + strcpy(buf, "hex"); + if (val == S_STRING) + strcpy(buf, "string"); + if (val == S_OTHER) + strcpy(buf, "other"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_flags(int val) +{ + static char buf[256] = { 0 }; + + bzero(buf, 256); + + if (val & SYMBOL_YES) + strcat(buf, "yes/"); + if (val & SYMBOL_MOD) + strcat(buf, "mod/"); + if (val & SYMBOL_NO) + strcat(buf, "no/"); + if (val & SYMBOL_CONST) + strcat(buf, "const/"); + if (val & SYMBOL_CHECK) + strcat(buf, "check/"); + if (val & SYMBOL_CHOICE) + strcat(buf, "choice/"); + if (val & SYMBOL_CHOICEVAL) + strcat(buf, "choiceval/"); + if (val & SYMBOL_PRINTED) + strcat(buf, "printed/"); + if (val & SYMBOL_VALID) + strcat(buf, "valid/"); + if (val & SYMBOL_OPTIONAL) + strcat(buf, "optional/"); + if (val & SYMBOL_WRITE) + strcat(buf, "write/"); + if (val & SYMBOL_CHANGED) + strcat(buf, "changed/"); + if (val & SYMBOL_NEW) + strcat(buf, "new/"); + if (val & SYMBOL_AUTO) + strcat(buf, "auto/"); + + buf[strlen(buf) - 1] = '\0'; +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_ptype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == P_UNKNOWN) + strcpy(buf, "unknown"); + if (val == P_PROMPT) + strcpy(buf, "prompt"); + if (val == P_COMMENT) + strcpy(buf, "comment"); + if (val == P_MENU) + strcpy(buf, "menu"); + if (val == P_DEFAULT) + strcpy(buf, "default"); + if (val == P_CHOICE) + strcpy(buf, "choice"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + + +/* Main Window Initialization */ + + +void init_main_window(const gchar * glade_file) +{ + GladeXML *xml; + GtkWidget *widget; + GtkTextBuffer *txtbuf; + char title[256]; + GdkPixmap *pixmap; + GdkBitmap *mask; + GtkStyle *style; + + xml = glade_xml_new(glade_file, "window1", NULL); + if (!xml) + g_error("GUI loading failed !\n"); + glade_xml_signal_autoconnect(xml); + + main_wnd = glade_xml_get_widget(xml, "window1"); + hpaned = glade_xml_get_widget(xml, "hpaned1"); + vpaned = glade_xml_get_widget(xml, "vpaned1"); + tree1_w = glade_xml_get_widget(xml, "treeview1"); + tree2_w = glade_xml_get_widget(xml, "treeview2"); + text_w = glade_xml_get_widget(xml, "textview3"); + + back_btn = glade_xml_get_widget(xml, "button1"); + gtk_widget_set_sensitive(back_btn, FALSE); + + widget = glade_xml_get_widget(xml, "show_name1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_name); + + widget = glade_xml_get_widget(xml, "show_range1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_range); + + widget = glade_xml_get_widget(xml, "show_data1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_value); + + style = gtk_widget_get_style(main_wnd); + widget = glade_xml_get_widget(xml, "toolbar1"); + + pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (gchar **) xpm_single_view); + gtk_image_set_from_pixmap(GTK_IMAGE + (((GtkToolbarChild + *) (g_list_nth(GTK_TOOLBAR(widget)-> + children, + 5)->data))->icon), + pixmap, mask); + pixmap = + gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (gchar **) xpm_split_view); + gtk_image_set_from_pixmap(GTK_IMAGE + (((GtkToolbarChild + *) (g_list_nth(GTK_TOOLBAR(widget)-> + children, + 6)->data))->icon), + pixmap, mask); + pixmap = + gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, + &style->bg[GTK_STATE_NORMAL], + (gchar **) xpm_tree_view); + gtk_image_set_from_pixmap(GTK_IMAGE + (((GtkToolbarChild + *) (g_list_nth(GTK_TOOLBAR(widget)-> + children, + 7)->data))->icon), + pixmap, mask); + + switch (view_mode) { + case SINGLE_VIEW: + widget = glade_xml_get_widget(xml, "button4"); + gtk_button_clicked(GTK_BUTTON(widget)); + break; + case SPLIT_VIEW: + widget = glade_xml_get_widget(xml, "button5"); + gtk_button_clicked(GTK_BUTTON(widget)); + break; + case FULL_VIEW: + widget = glade_xml_get_widget(xml, "button6"); + gtk_button_clicked(GTK_BUTTON(widget)); + break; + } + + txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", + "foreground", "red", + "weight", PANGO_WEIGHT_BOLD, + NULL); + tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2", + /*"style", PANGO_STYLE_OBLIQUE, */ + NULL); + + sprintf(title, "Build Configuration") + gtk_window_set_title(GTK_WINDOW(main_wnd), title); + + gtk_widget_show(main_wnd); +} + +void init_tree_model(void) +{ + gint i; + + tree = tree2 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, + G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + model2 = GTK_TREE_MODEL(tree2); + + for (parents[0] = NULL, i = 1; i < 256; i++) + parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter)); + + tree1 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, + G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + model1 = GTK_TREE_MODEL(tree1); +} + +void init_left_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(tree1_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + + gtk_tree_view_set_model(view, model1); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, FALSE); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Options", renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); + gtk_widget_realize(tree1_w); +} + +static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data); +static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle, + gchar * arg1, gpointer user_data); + +void init_right_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(tree2_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + gint i; + + gtk_tree_view_set_model(view, model2); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, FALSE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, "Options"); + + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "pixbuf", COL_PIXBUF, + "visible", COL_PIXVIS, NULL); + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVIS, + "radio", COL_BTNRAD, NULL); + /*g_signal_connect(G_OBJECT(renderer), "toggled", + G_CALLBACK(renderer_toggled), NULL); */ + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Name", renderer, + "text", COL_NAME, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "N", renderer, + "text", COL_NO, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "M", renderer, + "text", COL_MOD, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Y", renderer, + "text", COL_YES, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Value", renderer, + "text", COL_VALUE, + "editable", + COL_EDIT, + "foreground-gdk", + COL_COLOR, NULL); + g_signal_connect(G_OBJECT(renderer), "edited", + G_CALLBACK(renderer_edited), NULL); + + column = gtk_tree_view_get_column(view, COL_NAME); + gtk_tree_view_column_set_visible(column, show_name); + column = gtk_tree_view_get_column(view, COL_NO); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_MOD); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_YES); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_VALUE); + gtk_tree_view_column_set_visible(column, show_value); + + if (resizeable) { + for (i = 0; i < COL_VALUE; i++) { + column = gtk_tree_view_get_column(view, i); + gtk_tree_view_column_set_resizable(column, TRUE); + } + } + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); +} + + +/* Utility Functions */ + + +static void text_insert_help(struct menu *menu) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *prompt = menu_get_prompt(menu); + gchar *name; + const char *help = nohelp_text; + + if (!menu->sym) + help = ""; + else if (menu->sym->help) + help = menu->sym->help; + + if (menu->sym && menu->sym->name) + name = g_strdup_printf(menu->sym->name); + else + name = g_strdup(""); + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, " ", 1); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2, + NULL); +} + + +static void text_insert_msg(const char *title, const char *message) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *msg = message; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2, + NULL); +} + + +/* Main Windows Callbacks */ + +void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data); +gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, + gpointer user_data) +{ + GtkWidget *dialog, *label; + gint result; + + if (config_changed == FALSE) + return FALSE; + + dialog = gtk_dialog_new_with_buttons("Warning !", + GTK_WINDOW(main_wnd), + (GtkDialogFlags) + (GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_STOCK_OK, + GTK_RESPONSE_YES, + GTK_STOCK_NO, + GTK_RESPONSE_NO, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), + GTK_RESPONSE_CANCEL); + + label = gtk_label_new("\nSave configuration ?\n"); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); + gtk_widget_show(label); + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + switch (result) { + case GTK_RESPONSE_YES: + on_save1_activate(NULL, NULL); + return FALSE; + case GTK_RESPONSE_NO: + return FALSE; + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: + default: + gtk_widget_destroy(dialog); + return TRUE; + } + + return FALSE; +} + + +void on_window1_destroy(GtkObject * object, gpointer user_data) +{ + gtk_main_quit(); +} + + +void +on_window1_size_request(GtkWidget * widget, + GtkRequisition * requisition, gpointer user_data) +{ + static gint old_h = 0; + gint w, h; + + if (widget->window == NULL) + gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); + else + gdk_window_get_size(widget->window, &w, &h); + + if (h == old_h) + return; + old_h = h; + + gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3); +} + + +/* Menu & Toolbar Callbacks */ + + +static void +load_filename(GtkFileSelection * file_selector, gpointer user_data) +{ + const gchar *fn; + + fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION + (user_data)); + + if (conf_read(fn)) + text_insert_msg("Error", "Unable to load configuration !"); + else + display_tree(&rootmenu); +} + +void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *fs; + + fs = gtk_file_selection_new("Load file..."); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), + "clicked", + G_CALLBACK(load_filename), (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->ok_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + gtk_widget_show(fs); +} + + +void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + if (conf_write(NULL)) + text_insert_msg("Error", "Unable to save configuration !"); + + config_changed = FALSE; +} + + +static void +store_filename(GtkFileSelection * file_selector, gpointer user_data) +{ + const gchar *fn; + + fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION + (user_data)); + + if (conf_write(fn)) + text_insert_msg("Error", "Unable to save configuration !"); + + gtk_widget_destroy(GTK_WIDGET(user_data)); +} + +void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *fs; + + fs = gtk_file_selection_new("Save file as..."); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), + "clicked", + G_CALLBACK(store_filename), (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->ok_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + gtk_widget_show(fs); +} + + +void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + if (!on_window1_delete_event(NULL, NULL, NULL)) + gtk_widget_destroy(GTK_WIDGET(main_wnd)); +} + + +void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_name = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME); + if (col) + gtk_tree_view_column_set_visible(col, show_name); +} + + +void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_range = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + +} + + +void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_value = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE); + if (col) + gtk_tree_view_column_set_visible(col, show_value); +} + + +void +on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; + + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); // instead of update_tree for speed reasons +} + + +void +on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; + update_tree(&rootmenu, NULL); +} + + +void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *intro_text = + "Welcome to gkc, the GTK+ graphical configuration tool\n" + "for Linux.\n" + "For each option, a blank box indicates the feature is disabled, a\n" + "check indicates it is enabled, and a dot indicates that it is to\n" + "be compiled as a module. Clicking on the box will cycle through the three states.\n" + "\n" + "If you do not see an option (e.g., a device driver) that you\n" + "believe should be present, try turning on Show All Options\n" + "under the Options menu.\n" + "Although there is no cross reference yet to help you figure out\n" + "what other options must be enabled to support the option you\n" + "are interested in, you can still view the help of a grayed-out\n" + "option.\n" + "\n" + "Toggling Show Debug Info under the Options menu will show \n" + "the dependencies, which you can then match by examining other options."; + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, intro_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *about_text = + "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" + "Based on the source code from Roman Zippel.\n"; + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, about_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *license_text = + "gkc is released under the terms of the GNU GPL v2.\n" + "For more information, please see the source code or\n" + "visit http://www.fsf.org/licenses/licenses.html\n"; + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, license_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_back_pressed(GtkButton * button, gpointer user_data) +{ + enum prop_type ptype; + + current = current->parent; + ptype = current->prompt ? current->prompt->type : P_UNKNOWN; + if (ptype != P_MENU) + current = current->parent; + display_tree_part(); + + if (current == &rootmenu) + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_load_pressed(GtkButton * button, gpointer user_data) +{ + on_load1_activate(NULL, user_data); +} + + +void on_save_pressed(GtkButton * button, gpointer user_data) +{ + on_save1_activate(NULL, user_data); +} + + +void on_single_clicked(GtkButton * button, gpointer user_data) +{ + view_mode = SINGLE_VIEW; + gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + current = &rootmenu; + display_tree_part(); +} + + +void on_split_clicked(GtkButton * button, gpointer user_data) +{ + gint w, h; + view_mode = SPLIT_VIEW; + gtk_widget_show(tree1_w); + gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); + gtk_paned_set_position(GTK_PANED(hpaned), w / 2); + if (tree2) + gtk_tree_store_clear(tree2); + display_list(); +} + + +void on_full_clicked(GtkButton * button, gpointer user_data) +{ + view_mode = FULL_VIEW; + gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + if (tree2) + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_collapse_pressed(GtkButton * button, gpointer user_data) +{ + gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); +} + + +void on_expand_pressed(GtkButton * button, gpointer user_data) +{ + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); +} + + +/* CTree Callbacks */ + +/* Change hex/int/string value in the cell */ +static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data) +{ + GtkTreePath *path = gtk_tree_path_new_from_string(path_string); + GtkTreeIter iter; + const char *old_def, *new_def; + struct menu *menu; + struct symbol *sym; + + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + sym = menu->sym; + + gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1); + new_def = new_text; + + sym_set_string_value(sym, new_def); + + config_changed = TRUE; + update_tree(&rootmenu, NULL); + + gtk_tree_path_free(path); +} + +/* Change the value of a symbol and update the tree */ +static void change_sym_value(struct menu *menu, gint col) +{ + struct symbol *sym = menu->sym; + tristate oldval, newval; + + if (!sym) + return; + + if (col == COL_NO) + newval = no; + else if (col == COL_MOD) + newval = mod; + else if (col == COL_YES) + newval = yes; + else + return; + + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + oldval = sym_get_tristate_value(sym); + if (!sym_tristate_within_range(sym, newval)) + newval = yes; + sym_set_tristate_value(sym, newval); + config_changed = TRUE; + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL); + else if (view_mode == SPLIT_VIEW) { + update_tree(current, NULL); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(); //fixme: keep exp/coll + break; + case S_INT: + case S_HEX: + case S_STRING: + default: + break; + } +} + +static void toggle_sym_value(struct menu *menu) +{ + const tristate next_val[3] = { no, mod, yes }; + tristate newval; + + if (!menu->sym) + return; + + newval = next_val[(sym_get_tristate_value(menu->sym) + 1) % 3]; + if (!sym_tristate_within_range(menu->sym, newval)) + newval = yes; + sym_set_tristate_value(menu->sym, newval); + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL); + else if (view_mode == SPLIT_VIEW) { + update_tree(current, NULL); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(); //fixme: keep exp/coll +} + +static void renderer_toggled(GtkCellRendererToggle * cell, + gchar * path_string, gpointer user_data) +{ + GtkTreePath *path, *sel_path = NULL; + GtkTreeIter iter, sel_iter; + GtkTreeSelection *sel; + struct menu *menu; + + path = gtk_tree_path_new_from_string(path_string); + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w)); + if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter)) + sel_path = gtk_tree_model_get_path(model2, &sel_iter); + if (!sel_path) + goto out1; + if (gtk_tree_path_compare(path, sel_path)) + goto out2; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + toggle_sym_value(menu); + + out2: + gtk_tree_path_free(sel_path); + out1: + gtk_tree_path_free(path); +} + +static gint column2index(GtkTreeViewColumn * column) +{ + gint i; + + for (i = 0; i < COL_NUMBER; i++) { + GtkTreeViewColumn *col; + + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i); + if (col == column) + return i; + } + + return -1; +} + + +//#define GTK_BUG_FIXED // uncomment it for GTK+ >= 2.1.4 (2.2) + +/* User click: update choice (full) or goes down (single) */ +gboolean +on_treeview2_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + gint col; + +#ifdef GTK_BUG_FIXED + gint tx = (gint) event->x; + gint ty = (gint) event->y; + gint cx, cy; + + gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, + &cy); +#else + gtk_tree_view_get_cursor(view, &path, &column); +#endif + if (path == NULL) + return FALSE; + + gtk_tree_model_get_iter(model2, &iter, path); + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + + col = column2index(column); + if (event->type == GDK_2BUTTON_PRESS) { + enum prop_type ptype; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + + if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) { + // goes down into menu + current = menu; + display_tree_part(); + gtk_widget_set_sensitive(back_btn, TRUE); + } else if ((col == COL_OPTION)) { + toggle_sym_value(menu); + gtk_tree_view_expand_row(view, path, TRUE); + } + } else { + if (col == COL_VALUE) { + toggle_sym_value(menu); + gtk_tree_view_expand_row(view, path, TRUE); + } else if (col == COL_NO || col == COL_MOD + || col == COL_YES) { + change_sym_value(menu, col); + gtk_tree_view_expand_row(view, path, TRUE); + } + } + + return FALSE; +} + +/* Key pressed: update choice */ +gboolean +on_treeview2_key_press_event(GtkWidget * widget, + GdkEventKey * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + gint col; + + gtk_tree_view_get_cursor(view, &path, &column); + if (path == NULL) + return FALSE; + + if (event->keyval == GDK_space) { + if (gtk_tree_view_row_expanded(view, path)) + gtk_tree_view_collapse_row(view, path); + else + gtk_tree_view_expand_row(view, path, FALSE); + return TRUE; + } + if (event->keyval == GDK_KP_Enter) { + } + if (widget == tree1_w) + return FALSE; + + gtk_tree_model_get_iter(model2, &iter, path); + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + + if (!strcasecmp(event->string, "n")) + col = COL_NO; + else if (!strcasecmp(event->string, "m")) + col = COL_MOD; + else if (!strcasecmp(event->string, "y")) + col = COL_YES; + else + col = -1; + change_sym_value(menu, col); + + return FALSE; +} + + +/* Row selection changed: update help */ +void +on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) +{ + GtkTreeSelection *selection; + GtkTreeIter iter; + struct menu *menu; + + selection = gtk_tree_view_get_selection(treeview); + if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + text_insert_help(menu); + } +} + + +/* User click: display sub-tree in the right frame. */ +gboolean +on_treeview1_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + + gint tx = (gint) event->x; + gint ty = (gint) event->y; + gint cx, cy; + + gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, + &cy); + if (path == NULL) + return FALSE; + + gtk_tree_model_get_iter(model1, &iter, path); + gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); + + if (event->type == GDK_2BUTTON_PRESS) { + toggle_sym_value(menu); + current = menu; + display_tree_part(); + } else { + current = menu; + display_tree_part(); + } + + gtk_widget_realize(tree2_w); + gtk_tree_view_set_cursor(view, path, NULL, FALSE); + gtk_widget_grab_focus(GTK_TREE_VIEW(tree2_w)); + + return FALSE; +} + + +/* Conf management */ + + +/* Fill a row of strings */ +static gchar **fill_row(struct menu *menu) +{ + static gchar *row[COL_NUMBER] = { 0 }; + struct symbol *sym = menu->sym; + const char *def; + int stype; + tristate val; + enum prop_type ptype; + int i; + + for (i = COL_OPTION; i <= COL_COLOR; i++) + g_free(row[i]); + bzero(row, sizeof(row)); + + row[COL_OPTION] = + g_strdup_printf("%s %s", menu_get_prompt(menu), + sym ? (sym-> + flags & SYMBOL_NEW ? "(NEW)" : "") : + ""); + + if (show_all && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else + row[COL_COLOR] = g_strdup("Black"); + + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + switch (ptype) { + case P_MENU: + row[COL_PIXBUF] = (gchar *) xpm_menu; + if (view_mode != FULL_VIEW) + row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + case P_COMMENT: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + default: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); + break; + } + + if (!sym) + return row; + row[COL_NAME] = g_strdup(sym->name); + + sym_calc_value(sym); + sym->flags &= ~SYMBOL_CHANGED; + + if (sym_is_choice(sym)) { // parse childs for getting final value + struct menu *child; + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) + && child->sym == def_sym) + def_menu = child; + } + + if (def_menu) + row[COL_VALUE] = + g_strdup(menu_get_prompt(def_menu)); + } + if(sym->flags & SYMBOL_CHOICEVAL) + row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); + + stype = sym_get_type(sym); + switch (stype) { + case S_BOOLEAN: + if (sym_is_choice(sym)) + break; + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { + case no: + row[COL_NO] = g_strdup("N"); + row[COL_VALUE] = g_strdup("N"); + row[COL_BTNACT] = GINT_TO_POINTER(FALSE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + case mod: + row[COL_MOD] = g_strdup("M"); + row[COL_VALUE] = g_strdup("M"); + row[COL_BTNINC] = GINT_TO_POINTER(TRUE); + break; + case yes: + row[COL_YES] = g_strdup("Y"); + row[COL_VALUE] = g_strdup("Y"); + row[COL_BTNACT] = GINT_TO_POINTER(TRUE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + } + + if (val != no && sym_tristate_within_range(sym, no)) + row[COL_NO] = g_strdup("_"); + if (val != mod && sym_tristate_within_range(sym, mod)) + row[COL_MOD] = g_strdup("_"); + if (val != yes && sym_tristate_within_range(sym, yes)) + row[COL_YES] = g_strdup("_"); + break; + case S_INT: + case S_HEX: + case S_STRING: + def = sym_get_string_value(sym); + row[COL_VALUE] = g_strdup(def); + row[COL_EDIT] = GINT_TO_POINTER(TRUE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + } + + return row; +} + + +/* Set the node content with a row of strings */ +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row) +{ + GdkColor color; + gboolean success; + GdkPixbuf *pix; + + pix = gdk_pixbuf_new_from_xpm_data((const char **) + row[COL_PIXBUF]); + + gdk_color_parse(row[COL_COLOR], &color); + gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, + FALSE, FALSE, &success); + + gtk_tree_store_set(tree, node, + COL_OPTION, row[COL_OPTION], + COL_NAME, row[COL_NAME], + COL_NO, row[COL_NO], + COL_MOD, row[COL_MOD], + COL_YES, row[COL_YES], + COL_VALUE, row[COL_VALUE], + COL_MENU, (gpointer) menu, + COL_COLOR, &color, + COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), + COL_PIXBUF, pix, + COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), + COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]), + COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), + COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), + COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), + -1); + + g_object_unref(pix); +} + + +/* Add a node to the tree */ +static void place_node(struct menu *menu, char **row) +{ + GtkTreeIter *parent = parents[indent - 1]; + GtkTreeIter *node = parents[indent]; + + gtk_tree_store_append(tree, node, parent); + set_node(node, menu, row); +} + + +/* Find a node in the GTK+ tree */ +static GtkTreeIter found; + +/* + * Find a menu in the GtkTree starting at parent. + */ +GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, + struct menu *tofind) +{ + GtkTreeIter iter; + GtkTreeIter *child = &iter; + gboolean valid; + GtkTreeIter *ret; + + valid = gtk_tree_model_iter_children(model2, child, parent); + while (valid) { + struct menu *menu; + + gtk_tree_model_get(model2, child, 6, &menu, -1); + + if (menu == tofind) { + memcpy(&found, child, sizeof(GtkTreeIter)); + return &found; + } + + ret = gtktree_iter_find_node(child, tofind); + if (ret) + return ret; + + valid = gtk_tree_model_iter_next(model2, child); + } + + return NULL; +} + + +/* + * Update the tree by adding/removing entries + * Does not change other nodes + */ +static void update_tree(struct menu *src, GtkTreeIter * dst) +{ + struct menu *child1; + GtkTreeIter iter, tmp; + GtkTreeIter *child2 = &iter; + gboolean valid; + GtkTreeIter *sibling; + struct symbol *sym; + struct property *prop; + struct menu *menu1, *menu2; + static GtkTreePath *path = NULL; + + if (src == &rootmenu) + indent = 1; + + valid = gtk_tree_model_iter_children(model2, child2, dst); + for (child1 = src->list; child1; child1 = child1->next) { + + prop = child1->prompt; + sym = child1->sym; + + reparse: + menu1 = child1; + if (valid) + gtk_tree_model_get(model2, child2, COL_MENU, + &menu2, -1); + else + menu2 = NULL; // force adding of a first child + +#ifdef DEBUG + printf("%*c%s | %s\n", indent, ' ', + menu1 ? menu_get_prompt(menu1) : "nil", + menu2 ? menu_get_prompt(menu2) : "nil"); +#endif + + if (!menu_is_visible(child1) && !show_all) { // remove node + if (gtktree_iter_find_node(dst, menu1) != NULL) { + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } else + continue; + } + + if (menu1 != menu2) { + if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node + if (!valid && !menu2) + sibling = NULL; + else + sibling = child2; + gtk_tree_store_insert_before(tree2, + child2, + dst, sibling); + set_node(child2, menu1, fill_row(menu1)); + if (menu2 == NULL) + valid = TRUE; + } else { // remove node + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } + } else if (sym && (sym->flags & SYMBOL_CHANGED)) { + set_node(child2, menu1, fill_row(menu1)); + } + + indent++; + update_tree(child1, child2); + indent--; + + valid = gtk_tree_model_iter_next(model2, child2); + } +} + + +/* Display the whole tree (single/split/full view) */ +static void display_tree(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + enum prop_type ptype; + + if (menu == &rootmenu) { + indent = 1; + current = &rootmenu; + } + + for (child = menu->list; child; child = child->next) { + prop = child->prompt; + sym = child->sym; + ptype = prop ? prop->type : P_UNKNOWN; + + if (sym) + sym->flags &= ~SYMBOL_CHANGED; + + if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) && + (tree == tree1)) + continue; + + if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) && + (tree == tree2)) + continue; + + if (menu_is_visible(child) || show_all) + place_node(child, fill_row(child)); +#ifdef DEBUG + printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); + dbg_print_ptype(ptype); + printf(" | "); + if (sym) { + dbg_print_stype(sym->type); + printf(" | "); + dbg_print_flags(sym->flags); + printf("\n"); + } else + printf("\n"); +#endif + if ((view_mode != FULL_VIEW) && (ptype == P_MENU) + && (tree == tree2)) + continue; + + if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) || + (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW)) { + indent++; + display_tree(child); + indent--; + } + } +} + +/* Display a part of the tree starting at current node (single/split view) */ +static void display_tree_part(void) +{ + if (tree2) + gtk_tree_store_clear(tree2); + display_tree(current); + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); +} + +/* Display the list in the left frame (split view) */ +static void display_list(void) +{ + if (tree1) + gtk_tree_store_clear(tree1); + + tree = tree1; + display_tree(current = &rootmenu); + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w)); + tree = tree2; +} + +static void fixup_rootmenu(struct menu *menu) +{ + struct menu *child; + + if (!menu->prompt || menu->prompt->type != P_MENU) + return; + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) + fixup_rootmenu(child); +} + + +/* Main */ + + +int main(int ac, char *av[]) +{ + const char *name; + gchar *cur_dir, *exe_path; + gchar *glade_file; + +#ifndef LKC_DIRECT_LINK + kconfig_load(); +#endif + + /* GTK stuffs */ + gtk_set_locale(); + gtk_init(&ac, &av); + glade_init(); + + //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); + //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); + + /* Determine GUI path */ + cur_dir = g_get_current_dir(); + exe_path = g_strdup(av[0]); + exe_path[0] = '/'; + glade_file = g_strconcat(cur_dir, exe_path, ".glade", NULL); + g_free(cur_dir); + g_free(exe_path); + + /* Load the interface and connect signals */ + init_main_window(glade_file); + init_tree_model(); + init_left_tree(); + init_right_tree(); + + /* Conf stuffs */ + if (ac > 1 && av[1][0] == '-') { + switch (av[1][1]) { + case 'a': + //showAll = 1; + break; + case 'h': + case '?': + printf("%s <config>\n", av[0]); + exit(0); + } + name = av[2]; + } else + name = av[1]; + + conf_parse(name); + fixup_rootmenu(&rootmenu); + conf_read(NULL); + + switch (view_mode) { + case SINGLE_VIEW: + display_tree_part(); + break; + case SPLIT_VIEW: + display_list(); + break; + case FULL_VIEW: + display_tree(&rootmenu); + break; + } + + gtk_main(); + + return 0; +} diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade new file mode 100644 index 0000000..1e1736d --- a/dev/null +++ b/scripts/kconfig/gconf.glade @@ -0,0 +1,543 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkWindow" id="window1"> + <property name="visible">True</property> + <property name="title" translatable="yes">Gtk Kernel Configurator</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="default_width">640</property> + <property name="default_height">480</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <signal name="destroy" handler="on_window1_destroy" object="window1"/> + <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/> + <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/> + + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkMenuBar" id="menubar1"> + <property name="visible">True</property> + + <child> + <widget class="GtkMenuItem" id="file1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_File</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="file1_menu"> + + <child> + <widget class="GtkImageMenuItem" id="load1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Load a config file</property> + <property name="label" translatable="yes">_Load</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_load1_activate"/> + <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image27"> + <property name="visible">True</property> + <property name="stock">gtk-open</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="save1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Save the config in .config</property> + <property name="label" translatable="yes">_Save</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_save1_activate"/> + <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image28"> + <property name="visible">True</property> + <property name="stock">gtk-save</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="save_as1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Save the config in a file</property> + <property name="label" translatable="yes">Save _as</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_save_as1_activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image29"> + <property name="visible">True</property> + <property name="stock">gtk-save-as</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator1"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="quit1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Quit</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_quit1_activate"/> + <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image30"> + <property name="visible">True</property> + <property name="stock">gtk-quit</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="options1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Options</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="options1_menu"> + + <child> + <widget class="GtkCheckMenuItem" id="show_name1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Show name</property> + <property name="label" translatable="yes">Show _name</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_show_name1_activate"/> + </widget> + </child> + + <child> + <widget class="GtkCheckMenuItem" id="show_range1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Show range (Y/M/N)</property> + <property name="label" translatable="yes">Show _range</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_show_range1_activate"/> + </widget> + </child> + + <child> + <widget class="GtkCheckMenuItem" id="show_data1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Show value of the option</property> + <property name="label" translatable="yes">Show _data</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_show_data1_activate"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator2"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkCheckMenuItem" id="show_all_options1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Show all options</property> + <property name="label" translatable="yes">Show all _options</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_show_all_options1_activate"/> + </widget> + </child> + + <child> + <widget class="GtkCheckMenuItem" id="show_debug_info1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Show masked options</property> + <property name="label" translatable="yes">Show _debug info</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_show_debug_info1_activate"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="help1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Help</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="help1_menu"> + + <child> + <widget class="GtkImageMenuItem" id="introduction1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Introduction</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_introduction1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/> + <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image31"> + <property name="visible">True</property> + <property name="stock">gtk-dialog-question</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="about1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_About</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_about1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/> + <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image32"> + <property name="visible">True</property> + <property name="stock">gtk-properties</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="license1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_License</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image33"> + <property name="visible">True</property> + <property name="stock">gtk-justify-fill</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHandleBox" id="handlebox1"> + <property name="visible">True</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> + <property name="handle_position">GTK_POS_LEFT</property> + <property name="snap_edge">GTK_POS_TOP</property> + + <child> + <widget class="GtkToolbar" id="toolbar1"> + <property name="visible">True</property> + <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> + <property name="toolbar_style">GTK_TOOLBAR_BOTH</property> + <property name="tooltips">True</property> + + <child> + <widget class="button" id="button1"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Goes up of one level (single view)</property> + <property name="label" translatable="yes">Back</property> + <property name="use_underline">True</property> + <property name="stock_pixmap">gtk-undo</property> + <signal name="pressed" handler="on_back_pressed"/> + </widget> + </child> + + <child> + <widget class="GtkVSeparator" id="vseparator1"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="button" id="button2"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Load a config file</property> + <property name="label" translatable="yes">Load</property> + <property name="use_underline">True</property> + <property name="stock_pixmap">gtk-open</property> + <signal name="pressed" handler="on_load_pressed"/> + </widget> + </child> + + <child> + <widget class="button" id="button3"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Save a config file</property> + <property name="label" translatable="yes">Save</property> + <property name="use_underline">True</property> + <property name="stock_pixmap">gtk-save</property> + <signal name="pressed" handler="on_save_pressed"/> + </widget> + </child> + + <child> + <widget class="GtkVSeparator" id="vseparator2"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="button" id="button4"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Single view</property> + <property name="label" translatable="yes">Single</property> + <property name="use_underline">True</property> + <property name="stock_pixmap">gtk-missing-image</property> + <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/> + </widget> + </child> + + <child> + <widget class="button" id="button5"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Split view</property> + <property name="label" translatable="yes">Split</property> + <property name="use_underline">True</property> + <property name="stock_pixmap">gtk-missing-image</property> + <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/> + </widget> + </child> + + <child> + <widget class="button" id="button6"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Full view</property> + <property name="label" translatable="yes">Full</property> + <property name="use_underline">True</property> + <property name="stock_pixmap">gtk-missing-image</property> + <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkVSeparator" id="vseparator3"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="button" id="button7"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property> + <property name="label" translatable="yes">Collapse</property> + <property name="use_underline">True</property> + <signal name="pressed" handler="on_collapse_pressed"/> + </widget> + </child> + + <child> + <widget class="button" id="button8"> + <property name="visible">True</property> + <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property> + <property name="label" translatable="yes">Expand</property> + <property name="use_underline">True</property> + <signal name="pressed" handler="on_expand_pressed"/> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHPaned" id="hpaned1"> + <property name="width_request">1</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="position">0</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/> + <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/> + <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/> + </widget> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">False</property> + </packing> + </child> + + <child> + <widget class="GtkVPaned" id="vpaned1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="position">0</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/> + <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/> + <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/> + </widget> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow3"> + <property name="visible">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_WORD</property> + <property name="cursor_visible">True</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes">Sorry, no help available for this option yet.</property> + </widget> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">True</property> + </packing> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c index 65a5d67..d4f84bd 100644 --- a/scripts/kconfig/images.c +++ b/scripts/kconfig/images.c @@ -292 +292,35 @@ static const char *xpm_menu_inv[] = { " "}; + +static const char *xpm_menuback[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_void[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/scripts/kconfig/lkc-language.txt b/scripts/kconfig/lkc-language.txt index a3037ff..40f8583 100644 --- a/scripts/kconfig/lkc-language.txt +++ b/scripts/kconfig/lkc-language.txt @@ -20,3 +20,3 @@ organized in a tree structure: Every entry has its own dependencies. These dependencies are used -to determine the visible of an entry. Any child entry is only +to determine the visibility of an entry. Any child entry is only visible if its parent entry is also visible. @@ -52,3 +52,3 @@ applicable everywhere (see syntax). Every config option must have a type. There are only two basic types: - tristate and string, the other types base on these two. The type + tristate and string, the other types are based on these two. The type definition optionally accepts an input prompt, so these two examples @@ -66,3 +66,3 @@ applicable everywhere (see syntax). -- default value: "default" <symbol> ["if" <expr>] +- default value: "default" <expr> ["if" <expr>] A config option can have any number of default values. If multiple @@ -71,3 +71,3 @@ applicable everywhere (see syntax). defined, this means the default can be defined somewhere else or be - overriden by an earlier definition. + overridden by an earlier definition. The default value is only assigned to the config symbol if no other @@ -83,3 +83,3 @@ applicable everywhere (see syntax). are applied to all other options within this menu entry (which also - accept "if" expression), so these two examples are equivalent: + accept an "if" expression), so these two examples are equivalent: @@ -92,5 +92,20 @@ applicable everywhere (see syntax). +- reverse dependencies: "select" <symbol> ["if" <expr>] + While normal dependencies reduce the upper limit of a symbol (see + below), reverse dependencies can be used to force a lower limit of + another symbol. The value of the current menu symbol is used as the + minimal value <symbol> can be set to. If <symbol> is selected multiple + times, the limit is set to the largest selection. + Reverse dependencies can only be used with boolean or tristate + symbols. + +- numerical ranges: "range" <symbol> <symbol> ["if" <expr>] + This allows to limit the range of possible input values for integer + and hex symbols. The user can only input a value which is larger than + or equal to the first symbol and smaller than or equal to the second + symbol. + - help text: "help" This defines a help text. The end of the help text is determined by - the level indentation, this means it ends at the first line which has + the indentation level, this means it ends at the first line which has a smaller indentation than the first line of the help text. @@ -125,4 +140,4 @@ Expressions are listed in decreasing order of precedence. (5) Returns the result of (2-/expr/). -(6) Returns the result of min(/expr/, /expr/). -(7) Returns the result of max(/expr/, /expr/). +(6) Returns the result of max(/expr/, /expr/). +(7) Returns the result of min(/expr/, /expr/). @@ -132,3 +147,3 @@ expression evaluates to 'm' or 'y'. -There are two type of symbols: constant and nonconstant symbols. +There are two types of symbols: constant and nonconstant symbols. Nonconstant symbols are the most common ones and are defined with the @@ -144,3 +159,3 @@ Menu structure The position of a menu entry in the tree is determined in two ways. First -it can be specified explicitely: +it can be specified explicitly: @@ -161,4 +176,4 @@ The other way to generate the menu structure is done by analyzing the dependencies. If a menu entry somehow depends on the previous entry, it -can be made a submenu of it. First the the previous (parent) symbol must -be part of the dependency list and then one of these two condititions +can be made a submenu of it. First, the previous (parent) symbol must +be part of the dependency list and then one of these two conditions must be true: @@ -179,3 +194,3 @@ MODVERSIONS directly depends on MODULES, this means it's only visible if MODULES is different from 'n'. The comment on the other hand is always -visible when MODULES it's visible (the (empty) dependency of MODULES is +visible when MODULES is visible (the (empty) dependency of MODULES is also part of the comment dependencies). @@ -190,2 +205,3 @@ end a menu entry: - config +- menuconfig - choice/endchoice @@ -195,3 +211,3 @@ end a menu entry: - source -The first four also start the definition of a menu entry. +The first five also start the definition of a menu entry. @@ -205,2 +221,10 @@ attributes as options. +menuconfig: + "menuconfig" <symbol> + <config options> + +This is similiar to the simple config entry above, but it also gives a +hint to front ends, that all suboptions should be displayed as a +separate list of options. + choices: diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index cdd04a9..dd040f7 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -51,5 +51,7 @@ void menu_add_entry(struct symbol *sym); void menu_end_entry(void); -struct property *create_prop(enum prop_type type); void menu_add_dep(struct expr *dep); -struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep); +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); +void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); void menu_finalize(struct menu *parent); @@ -66,2 +68,5 @@ void sym_clear_all_valid(void); void sym_set_changed(struct symbol *sym); +struct symbol *sym_check_deps(struct symbol *sym); +struct property *prop_alloc(enum prop_type type, struct symbol *sym); +struct symbol *prop_get_symbol(struct property *prop); @@ -69,3 +74,3 @@ static inline tristate sym_get_tristate_value(struct symbol *sym) { - return S_TRI(sym->curr); + return sym->curr.tri; } @@ -75,3 +80,3 @@ static inline struct symbol *sym_get_choice_value(struct symbol *sym) { - return (struct symbol *)S_VAL(sym->curr); + return (struct symbol *)sym->curr.val; } @@ -100,3 +105,2 @@ static inline bool sym_has_value(struct symbol *sym) { - //return S_VAL(sym->def) != NULL; return sym->flags & SYMBOL_NEW ? false : true; diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 116d759..97c7917 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -20,5 +20,5 @@ P(sym_lookup,struct symbol *,(const char *name, int isconst)); P(sym_find,struct symbol *,(const char *name)); -P(sym_type_name,const char *,(int type)); +P(sym_type_name,const char *,(enum symbol_type type)); P(sym_calc_value,void,(struct symbol *sym)); -P(sym_get_type,int,(struct symbol *sym)); +P(sym_get_type,enum symbol_type,(struct symbol *sym)); P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); @@ -27,2 +27,3 @@ P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); +P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 6d82718..b9cf25f 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -51,3 +51,3 @@ setmod_text[] = nohelp_text[] = - "There is no help available for this kernel option.\n", + "There is no help available for this option.\n", load_config_text[] = @@ -58,3 +58,3 @@ load_config_help[] = "\n" - "For various reasons, one may wish to keep several different kernel\n" + "For various reasons, one may wish to keep several different \n" "configurations available on a single machine.\n" @@ -62,3 +62,3 @@ load_config_help[] = "If you have saved a previous configuration in a file other than the\n" - "kernel's default, entering the name of the file here will allow you\n" + "default, entering the name of the file here will allow you\n" "to modify that configuration.\n" @@ -72,3 +72,3 @@ save_config_help[] = "\n" - "For various reasons, one may wish to keep different kernel\n" + "For various reasons, one may wish to keep different\n" "configurations available on a single machine.\n" @@ -149,2 +149,3 @@ static void cprint_init(void) { + char *env = getenv("LXDIALOG"); bufptr = buf; @@ -154,3 +155,7 @@ static void cprint_init(void) child_count = 0; - cprint("./scripts/lxdialog/lxdialog"); + if(env != NULL) { + cprint(env); + } else { + cprint("./scripts/lxdialog/lxdialog"); + } cprint("--backtitle"); @@ -304,7 +309,4 @@ static void build_conf(struct menu *menu) indent + 1, ' ', prompt); - } else { - if (menu->parent != &rootmenu) - cprint1(" %*c", indent + 1, ' '); - cprint1("%s --->", prompt); - } + } else + cprint1(" %*c%s --->", indent + 1, ' ', prompt); @@ -375,2 +377,7 @@ static void build_conf(struct menu *menu) } else { + if (menu == current_menu) { + cprint(":%p", menu); + cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + goto conf_childs; + } child_count++; @@ -384,3 +391,6 @@ static void build_conf(struct menu *menu) cprint("t%p", menu); - cprint1("[%c]", val == no ? ' ' : '*'); + if (sym_is_changable(sym)) + cprint1("[%c]", val == no ? ' ' : '*'); + else + cprint1("---"); break; @@ -393,3 +403,6 @@ static void build_conf(struct menu *menu) } - cprint1("<%c>", ch); + if (sym_is_changable(sym)) + cprint1("<%c>", ch); + else + cprint1("---"); break; @@ -402,3 +415,4 @@ static void build_conf(struct menu *menu) cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), - sym_has_value(sym) ? "" : " (NEW)"); + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); cprint_done(); @@ -408,3 +422,9 @@ static void build_conf(struct menu *menu) cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), - sym_has_value(sym) ? "" : " (NEW)"); + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + if (menu->prompt->type == P_MENU) { + cprint1(" --->"); + cprint_done(); + return; + } cprint_done(); @@ -447,5 +467,5 @@ static void conf(struct menu *menu) cprint("L"); - cprint("Load an Alternate Configuration File"); + cprint(" Load an Alternate Configuration File"); cprint("S"); - cprint("Save Configuration to an Alternate File"); + cprint(" Save Configuration to an Alternate File"); } @@ -486,2 +506,4 @@ static void conf(struct menu *menu) conf_choice(submenu); + else if (submenu->prompt->type == P_MENU) + conf(submenu); break; @@ -746,4 +768,3 @@ int main(int ac, char **av) sym_calc_value(sym); - sprintf(menu_backtitle, "Opie %s Configuration", - sym_get_string_value(sym)); + sprintf(menu_backtitle, "Build Configuration"); @@ -772,7 +793,8 @@ int main(int ac, char **av) printf("\n\n" - "*** End of Opie configuration.\n" - "*** Check the top-level Makefile for additional configuration.\n" - "*** Next, you may run 'make'.\n\n"); + "*** End of configuration.\n" + "\n\n"); } else - printf("\n\nYour Opie configuration changes were NOT saved.\n\n"); + printf("\n\n" + "Your configuration changes were NOT saved." + "\n\n"); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 24be0ec..1631767 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -56,5 +56,30 @@ void menu_end_menu(void) +struct expr *menu_check_dep(struct expr *e) +{ + if (!e) + return e; + + switch (e->type) { + case E_NOT: + e->left.expr = menu_check_dep(e->left.expr); + break; + case E_OR: + case E_AND: + e->left.expr = menu_check_dep(e->left.expr); + e->right.expr = menu_check_dep(e->right.expr); + break; + case E_SYMBOL: + /* change 'm' into 'm' && MODULES */ + if (e->left.sym == &symbol_mod) + return expr_alloc_and(e, expr_alloc_symbol(modules_sym)); + break; + default: + break; + } + return e; +} + void menu_add_dep(struct expr *dep) { - current_entry->dep = expr_alloc_and(current_entry->dep, dep); + current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); } @@ -71,3 +96,3 @@ void menu_set_type(int type) } - fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n", + fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n", current_entry->file->name, current_entry->lineno, @@ -76,34 +101,16 @@ void menu_set_type(int type) -struct property *create_prop(enum prop_type type) -{ - struct property *prop; - - prop = malloc(sizeof(*prop)); - memset(prop, 0, sizeof(*prop)); - prop->type = type; - prop->file = current_file; - prop->lineno = zconf_lineno(); - - return prop; -} - -struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep) +struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) { - struct property *prop = create_prop(token); - struct property **propp; + struct property *prop = prop_alloc(type, current_entry->sym); - prop->sym = current_entry->sym; prop->menu = current_entry; prop->text = prompt; - prop->def = def; - E_EXPR(prop->visible) = dep; + prop->expr = expr; + prop->visible.expr = menu_check_dep(dep); - if (prompt) + if (prompt) { + if (current_entry->prompt) + fprintf(stderr, "%s:%d: prompt redefined\n", + current_entry->file->name, current_entry->lineno); current_entry->prompt = prop; - - /* append property to the prop list of symbol */ - if (prop->sym) { - for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next) - ; - *propp = prop; } @@ -113,10 +120,15 @@ struct property *menu_add_prop(int token, char *prompt, struct symbol *def, stru -void menu_add_prompt(int token, char *prompt, struct expr *dep) +void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) { - current_entry->prompt = menu_add_prop(token, prompt, NULL, dep); + menu_add_prop(type, prompt, NULL, dep); } -void menu_add_default(int token, struct symbol *def, struct expr *dep) +void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) { - current_entry->prompt = menu_add_prop(token, NULL, def, dep); + menu_add_prop(type, NULL, expr, dep); +} + +void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) +{ + menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); } @@ -128,3 +140,3 @@ void menu_finalize(struct menu *parent) struct property *prop; - struct expr *parentdep, *basedep, *dep, *dep2; + struct expr *parentdep, *basedep, *dep, *dep2, **ep; @@ -145,3 +157,3 @@ void menu_finalize(struct menu *parent) } else if (parent->prompt) - parentdep = E_EXPR(parent->prompt->visible); + parentdep = parent->prompt->visible.expr; else @@ -161,3 +173,3 @@ void menu_finalize(struct menu *parent) continue; - dep = expr_transform(E_EXPR(prop->visible)); + dep = expr_transform(prop->visible.expr); dep = expr_alloc_and(expr_copy(basedep), dep); @@ -166,3 +178,8 @@ void menu_finalize(struct menu *parent) dep = expr_trans_bool(dep); - E_EXPR(prop->visible) = dep; + prop->visible.expr = dep; + if (prop->type == P_SELECT) { + struct symbol *es = prop_get_symbol(prop); + es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, + expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); + } } @@ -171,4 +188,4 @@ void menu_finalize(struct menu *parent) menu_finalize(menu); - } else if (sym && parent->prompt) { - basedep = E_EXPR(parent->prompt->visible); + } else if (sym) { + basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); @@ -177,3 +194,3 @@ void menu_finalize(struct menu *parent) for (menu = parent->next; menu; menu = menu->next) { - dep = menu->prompt ? E_EXPR(menu->prompt->visible) : menu->dep; + dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; if (!expr_contains_symbol(dep, sym)) @@ -206,10 +223,23 @@ void menu_finalize(struct menu *parent) menu->sym->flags |= SYMBOL_CHOICEVAL; + if (!menu->prompt) + fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n", + menu->file->name, menu->lineno); + for (prop = menu->sym->prop; prop; prop = prop->next) { + if (prop->type == P_PROMPT && prop->menu != menu) { + fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n", + prop->file->name, prop->lineno); + + } + if (prop->type == P_DEFAULT) + fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n", + prop->file->name, prop->lineno); + } current_entry = menu; menu_set_type(sym->type); - menu_add_prop(P_CHOICE, NULL, parent->sym, NULL); - prop = sym_get_choice_prop(parent->sym); - //dep = expr_alloc_one(E_CHOICE, dep); - //dep->right.sym = menu->sym; - prop->dep = expr_alloc_one(E_CHOICE, prop->dep); - prop->dep->right.sym = menu->sym; + menu_add_symbol(P_CHOICE, sym, NULL); + prop = sym_get_choice_prop(sym); + for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) + ; + *ep = expr_alloc_one(E_CHOICE, NULL); + (*ep)->right.sym = menu->sym; } @@ -226,2 +256,49 @@ void menu_finalize(struct menu *parent) } + + if (sym && !(sym->flags & SYMBOL_WARNED)) { + struct symbol *sym2; + if (sym->type == S_UNKNOWN) + fprintf(stderr, "%s:%d:warning: config symbol defined without type\n", + parent->file->name, parent->lineno); + + if (sym_is_choice(sym) && !parent->prompt) + fprintf(stderr, "%s:%d:warning: choice must have a prompt\n", + parent->file->name, parent->lineno); + + for (prop = sym->prop; prop; prop = prop->next) { + switch (prop->type) { + case P_DEFAULT: + if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && + prop->expr->type != E_SYMBOL) + fprintf(stderr, "%s:%d:warning: default must be a single symbol\n", + prop->file->name, prop->lineno); + break; + case P_SELECT: + sym2 = prop_get_symbol(prop); + if ((sym->type != S_BOOLEAN && sym->type != S_TRISTATE) || + (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)) + fprintf(stderr, "%s:%d:warning: enable is only allowed with boolean and tristate symbols\n", + prop->file->name, prop->lineno); + break; + case P_RANGE: + if (sym->type != S_INT && sym->type != S_HEX) + fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n", + prop->file->name, prop->lineno); + if (!sym_string_valid(sym, prop->expr->left.sym->name) || + !sym_string_valid(sym, prop->expr->right.sym->name)) + fprintf(stderr, "%s:%d:warning: range is invalid\n", + prop->file->name, prop->lineno); + break; + default: + ; + } + } + sym->flags |= SYMBOL_WARNED; + } + + if (sym && !sym_is_optional(sym) && parent->prompt) { + sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, + expr_alloc_and(parent->prompt->visible.expr, + expr_alloc_symbol(&symbol_mod))); + } } @@ -230,2 +307,4 @@ bool menu_is_visible(struct menu *menu) { + struct menu *child; + struct symbol *sym; tristate visible; @@ -234,8 +313,18 @@ bool menu_is_visible(struct menu *menu) return false; - if (menu->sym) { - sym_calc_value(menu->sym); - visible = E_TRI(menu->prompt->visible); + sym = menu->sym; + if (sym) { + sym_calc_value(sym); + visible = menu->prompt->visible.tri; } else - visible = E_CALC(menu->prompt->visible); - return visible != no; + visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); + + if (visible != no) + return true; + if (!sym || sym_get_tristate_value(menu->sym) == no) + return false; + + for (child = menu->list; child; child = child->next) + if (menu_is_visible(child)) + return true; + return false; } @@ -260,6 +349,5 @@ struct menu *menu_get_parent_menu(struct menu *menu) - while (menu != &rootmenu) { - menu = menu->parent; + for (; menu != &rootmenu; menu = menu->parent) { type = menu->prompt ? menu->prompt->type : 0; - if (type == P_MENU || type == P_ROOTMENU) + if (type == P_MENU) break; diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index bed541d..52419ad 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -44,6 +44,5 @@ static QSettings *configSettings; template <class P> -static void updateMenuList(P* parent, struct menu* menu) +void ConfigList::updateMenuList(P* parent, struct menu* menu) { struct menu* child; - ConfigList* list = parent->listView(); ConfigItem* item; @@ -51,4 +50,2 @@ static void updateMenuList(P* parent, struct menu* menu) bool visible; - bool showAll = list->showAll; - enum listMode mode = list->mode; enum prop_type type; @@ -61,3 +58,5 @@ static void updateMenuList(P* parent, struct menu* menu) - last = 0; + last = parent->firstChild(); + if (last && !last->goParent) + last = 0; for (child = menu->list; child; child = child->next) { @@ -68,3 +67,3 @@ static void updateMenuList(P* parent, struct menu* menu) case menuMode: - if (type != P_ROOTMENU) + if (!(child->flags & MENU_ROOT)) goto hide; @@ -72,3 +71,3 @@ static void updateMenuList(P* parent, struct menu* menu) case symbolMode: - if (type == P_ROOTMENU) + if (child->flags & MENU_ROOT) goto hide; @@ -83,15 +82,6 @@ static void updateMenuList(P* parent, struct menu* menu) item = new ConfigItem(parent, last, child, visible); - else { - item->visible = visible; - if (item->updateNeeded()) { - ConfigItem* i = (ConfigItem*)child->data; - for (; i; i = i->nextItem) { - i->updateMenu(); - } - } else if (list->updateAll) - item->updateMenu(); - } + else + item->testUpdateMenu(visible); - if (mode == fullMode || mode == menuMode || - (type != P_MENU && type != P_ROOTMENU)) + if (mode == fullMode || mode == menuMode || type != P_MENU) updateMenuList(item, child); @@ -102,3 +92,3 @@ static void updateMenuList(P* parent, struct menu* menu) } - hide: + hide: if (item && item->menu == child) { @@ -133,5 +123,5 @@ void ConfigItem::updateMenu(void) struct symbol* sym; + struct property *prop; QString prompt; int type; - enum prop_type ptype; tristate expr; @@ -139,14 +129,35 @@ void ConfigItem::updateMenu(void) list = listView(); + if (goParent) { + setPixmap(promptColIdx, list->menuBackPix); + prompt = ".."; + goto set_prompt; + } sym = menu->sym; - if (!sym) { - setText(promptColIdx, menu_get_prompt(menu)); - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - if ((ptype == P_ROOTMENU || ptype == P_MENU) && - (list->mode == singleMode || list->mode == symbolMode)) + prop = menu->prompt; + prompt = menu_get_prompt(menu); + + if (prop) switch (prop->type) { + case P_MENU: + if (list->mode == singleMode || list->mode == symbolMode) { + /* a menuconfig entry is displayed differently + * depending whether it's at the view root or a child. + */ + if (sym && list->rootEntry == menu) + break; setPixmap(promptColIdx, list->menuPix); - else + } else { + if (sym) + break; setPixmap(promptColIdx, 0); - return; + } + goto set_prompt; + case P_COMMENT: + setPixmap(promptColIdx, 0); + goto set_prompt; + default: + ; } + if (!sym) + goto set_prompt; @@ -160,4 +171,4 @@ void ConfigItem::updateMenu(void) - prompt = menu_get_prompt(menu); if (!sym_is_changable(sym) && !list->showAll) { + setPixmap(promptColIdx, 0); setText(noColIdx, 0); @@ -213,5 +224,5 @@ void ConfigItem::updateMenu(void) if (type == S_STRING) - prompt.sprintf("%s: %s", menu_get_prompt(menu), data); + prompt.sprintf("%s: %s", prompt.latin1(), data); else - prompt.sprintf("(%s) %s", data, menu_get_prompt(menu)); + prompt.sprintf("(%s) %s", data, prompt.latin1()); break; @@ -220,2 +231,3 @@ void ConfigItem::updateMenu(void) prompt += " (NEW)"; +set_prompt: setText(promptColIdx, prompt); @@ -223,12 +235,18 @@ void ConfigItem::updateMenu(void) -bool ConfigItem::updateNeeded(void) +void ConfigItem::testUpdateMenu(bool v) { - struct symbol* sym = menu->sym; - if (sym) - sym_calc_value(sym); + ConfigItem* i; + + visible = v; + if (!menu) + return; + + sym_calc_value(menu->sym); if (menu->flags & MENU_CHANGED) { + /* the menu entry changed, so update all list items */ menu->flags &= ~MENU_CHANGED; - return true; - } - return false; + for (i = (ConfigItem*)menu->data; i; i = i->nextItem) + i->updateMenu(); + } else if (listView()->updateAll) + updateMenu(); } @@ -253,10 +271,11 @@ void ConfigItem::init(void) { - ConfigList* list = listView(); - nextItem = (ConfigItem*)menu->data; - menu->data = this; + if (menu) { + ConfigList* list = listView(); + nextItem = (ConfigItem*)menu->data; + menu->data = this; - if (list->mode != fullMode) - setOpen(TRUE); - if (menu->sym) + if (list->mode != fullMode) + setOpen(TRUE); sym_calc_value(menu->sym); + } updateMenu(); @@ -269,7 +288,9 @@ ConfigItem::~ConfigItem(void) { - ConfigItem** ip = &(ConfigItem*)menu->data; - for (; *ip; ip = &(*ip)->nextItem) { - if (*ip == this) { - *ip = nextItem; - break; + if (menu) { + ConfigItem** ip = (ConfigItem**)&menu->data; + for (; *ip; ip = &(*ip)->nextItem) { + if (*ip == this) { + *ip = nextItem; + break; + } } @@ -312,3 +333,4 @@ ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv) symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), - choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), + choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), + menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), showAll(false), showName(false), showRange(false), showData(false), @@ -368,4 +390,6 @@ void ConfigList::updateSelection(void) menu = item->menu; + if (!menu) + return; type = menu->prompt ? menu->prompt->type : P_UNKNOWN; - if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU)) + if (mode == menuMode && type == P_MENU) emit menuSelected(menu); @@ -375,3 +399,24 @@ void ConfigList::updateList(ConfigItem* item) { - (void)item; // unused so far + ConfigItem* last = 0; + + if (!rootEntry) + goto update; + + if (rootEntry != &rootmenu && (mode == singleMode || + (mode == symbolMode && rootEntry->parent != &rootmenu))) { + item = firstChild(); + if (!item) + item = new ConfigItem(this, 0, true); + last = item; + } + if (mode == singleMode && rootEntry->sym && rootEntry->prompt) { + item = last ? last->nextSibling() : firstChild(); + if (!item) + item = new ConfigItem(this, last, rootEntry, true); + + updateMenuList(item, rootEntry); + triggerUpdate(); + return; + } +update: updateMenuList(this, rootEntry); @@ -394,3 +439,3 @@ void ConfigList::setValue(ConfigItem* item, tristate val) - sym = item->menu->sym; + sym = item->menu ? item->menu->sym : 0; if (!sym) @@ -420,2 +465,4 @@ void ConfigList::changeValue(ConfigItem* item) menu = item->menu; + if (!menu) + return; sym = menu->sym; @@ -462,3 +509,3 @@ void ConfigList::setRootMenu(struct menu *menu) type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; - if (type != P_MENU && type != P_ROOTMENU) + if (type != P_MENU) return; @@ -473,9 +520,8 @@ void ConfigList::setParentMenu(void) ConfigItem* item; - struct menu *oldroot, *newroot; + struct menu *oldroot; oldroot = rootEntry; - newroot = menu_get_parent_menu(oldroot); - if (newroot == oldroot) + if (rootEntry == &rootmenu) return; - setRootMenu(newroot); + setRootMenu(menu_get_parent_menu(rootEntry->parent)); @@ -513,5 +559,12 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) case Key_Enter: + if (item->goParent) { + emit parentSelected(); + break; + } menu = item->menu; + if (!menu) + break; type = menu->prompt ? menu->prompt->type : P_UNKNOWN; - if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) { + if (type == P_MENU && rootEntry != menu && + mode != fullMode && mode != menuMode) { emit menuSelected(menu); @@ -550,2 +603,3 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) struct menu *menu; + enum prop_type ptype; const QPixmap* pm; @@ -566,6 +620,13 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) if (x >= off && x < off + pm->width()) { - if (menu->sym) - changeValue(item); - else + if (item->goParent) { + emit parentSelected(); + break; + } else if (!menu) + break; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + if (ptype == P_MENU && rootEntry != menu && + mode != fullMode && mode != menuMode) emit menuSelected(menu); + else + changeValue(item); } @@ -608,6 +669,11 @@ void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) goto skip; + if (item->goParent) { + emit parentSelected(); + goto skip; + } menu = item->menu; + if (!menu) + goto skip; ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - if ((ptype == P_ROOTMENU || ptype == P_MENU) && - (mode == singleMode || mode == symbolMode)) + if (ptype == P_MENU && (mode == singleMode || mode == symbolMode)) emit menuSelected(menu); @@ -679,3 +745,2 @@ ConfigMainWindow::ConfigMainWindow(void) { - ConfigView* view; QMenuBar* menu; @@ -709,4 +774,4 @@ ConfigMainWindow::ConfigMainWindow(void) - view = new ConfigView(split1, this); - menuList = view->list; + menuView = new ConfigView(split1, this); + menuList = menuView->list; @@ -716,4 +781,4 @@ ConfigMainWindow::ConfigMainWindow(void) // create config tree - view = new ConfigView(split2, this); - configList = view->list; + configView = new ConfigView(split2, this); + configList = configView->list; @@ -820,3 +885,2 @@ ConfigMainWindow::ConfigMainWindow(void) - //showFullView(); showSplitView(); @@ -866,77 +930,81 @@ void ConfigMainWindow::setHelp(QListViewItem* item) struct symbol* sym; - struct menu* menu; + struct menu* menu = 0; configList->parent()->lineEdit->hide(); - if (item) { - QString head, debug, help; + if (item) menu = ((ConfigItem*)item)->menu; - sym = menu->sym; - if (sym) { - if (menu->prompt) { - head += "<big><b>"; - head += print_filter(menu->prompt->text); - head += "</b></big>"; - if (sym->name) { - head += " ("; - head += print_filter(sym->name); - head += ")"; - } - } else if (sym->name) { - head += "<big><b>"; + if (!menu) { + helpText->setText(NULL); + return; + } + + QString head, debug, help; + menu = ((ConfigItem*)item)->menu; + sym = menu->sym; + if (sym) { + if (menu->prompt) { + head += "<big><b>"; + head += print_filter(menu->prompt->text); + head += "</b></big>"; + if (sym->name) { + head += " ("; head += print_filter(sym->name); - head += "</b></big>"; + head += ")"; } - head += "<br><br>"; - - if (showDebug) { - debug += "type: "; - debug += print_filter(sym_type_name(sym->type)); + } else if (sym->name) { + head += "<big><b>"; + head += print_filter(sym->name); + head += "</b></big>"; + } + head += "<br><br>"; + + if (showDebug) { + debug += "type: "; + debug += print_filter(sym_type_name(sym->type)); + if (sym_is_choice(sym)) + debug += " (choice)"; + debug += "<br>"; + if (sym->rev_dep.expr) { + debug += "reverse dep: "; + expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE); debug += "<br>"; - for (struct property *prop = sym->prop; prop; prop = prop->next) { - switch (prop->type) { - case P_PROMPT: - debug += "prompt: "; - debug += print_filter(prop->text); - debug += "<br>"; - if (prop->visible.expr) { - debug += " dep: "; - expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); - debug += "<br>"; - } - break; - case P_DEFAULT: - debug += "default: "; - if (sym_is_choice(sym)) - debug += print_filter(prop->def->name); - else { - sym_calc_value(prop->def); - debug += print_filter(sym_get_string_value(prop->def)); - } - debug += "<br>"; - if (prop->visible.expr) { - debug += " dep: "; - expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); - debug += "<br>"; - } - break; - case P_CHOICE: - break; - default: - debug += "unknown property: "; - debug += prop_get_type_name(prop->type); + } + for (struct property *prop = sym->prop; prop; prop = prop->next) { + switch (prop->type) { + case P_PROMPT: + case P_MENU: + debug += "prompt: "; + debug += print_filter(prop->text); + debug += "<br>"; + break; + case P_DEFAULT: + debug += "default: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + break; + case P_CHOICE: + if (sym_is_choice(sym)) { + debug += "choice: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); debug += "<br>"; } + break; + case P_SELECT: + debug += "select: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + break; + case P_RANGE: + debug += "range: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + break; + default: + debug += "unknown property: "; + debug += prop_get_type_name(prop->type); + debug += "<br>"; } - debug += "<br>"; - } - - help = print_filter(sym->help); - } else if (menu->prompt) { - head += "<big><b>"; - head += print_filter(menu->prompt->text); - head += "</b></big><br><br>"; - if (showDebug) { - if (menu->prompt->visible.expr) { - debug += " dep: "; - expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); + if (prop->visible.expr) { + debug += " dep: "; + expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); debug += "<br>"; @@ -944,7 +1012,21 @@ void ConfigMainWindow::setHelp(QListViewItem* item) } + debug += "<br>"; + } + + help = print_filter(sym->help); + } else if (menu->prompt) { + head += "<big><b>"; + head += print_filter(menu->prompt->text); + head += "</b></big><br><br>"; + if (showDebug) { + if (menu->prompt->visible.expr) { + debug += " dep: "; + expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); + debug += "<br><br>"; + } } - helpText->setText(head + debug + help); - return; } - helpText->setText(NULL); + if (showDebug) + debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno); + helpText->setText(head + debug + help); } @@ -1012,3 +1094,3 @@ void ConfigMainWindow::showSingleView(void) { - menuList->hide(); + menuView->hide(); menuList->setRootMenu(0); @@ -1034,4 +1116,4 @@ void ConfigMainWindow::showSplitView(void) menuList->setRootMenu(&rootmenu); - menuList->show(); menuList->setAllOpen(TRUE); + menuView->show(); menuList->setFocus(); @@ -1041,3 +1123,3 @@ void ConfigMainWindow::showFullView(void) { - menuList->hide(); + menuView->hide(); menuList->setRootMenu(0); @@ -1075,2 +1157,4 @@ void ConfigMainWindow::setShowName(bool b) configList->reinit(); + menuList->showName = b; + menuList->reinit(); } @@ -1083,2 +1167,4 @@ void ConfigMainWindow::setShowRange(bool b) configList->reinit(); + menuList->showRange = b; + menuList->reinit(); } @@ -1091,2 +1177,4 @@ void ConfigMainWindow::setShowData(bool b) configList->reinit(); + menuList->showData = b; + menuList->reinit(); } @@ -1148,8 +1236,21 @@ void fixup_rootmenu(struct menu *menu) struct menu *child; + static int menu_cnt = 0; - if (!menu->prompt || menu->prompt->type != P_MENU) - return; - menu->prompt->type = P_ROOTMENU; - for (child = menu->list; child; child = child->next) - fixup_rootmenu(child); + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) { + if (child->prompt && child->prompt->type == P_MENU) { + menu_cnt++; + fixup_rootmenu(child); + menu_cnt--; + } else if (!menu_cnt) + fixup_rootmenu(child); + } +} + +static const char *progname; + +static void usage(void) +{ + printf("%s <config>\n", progname); + exit(0); } @@ -1165,2 +1266,3 @@ int main(int ac, char** av) + progname = av[0]; configApp = new QApplication(ac, av); @@ -1171,9 +1273,5 @@ int main(int ac, char** av) switch (av[1][1]) { - case 'a': - //showAll = 1; - break; case 'h': case '?': - printf("%s <config>\n", av[0]); - exit(0); + usage(); } @@ -1182,2 +1280,5 @@ int main(int ac, char** av) name = av[1]; + if (!name) + usage(); + conf_parse(name); diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index 6f096b4..c548884 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -103,2 +103,5 @@ public: + template <class P> + void ConfigList::updateMenuList(P*, struct menu*); + bool updateAll; @@ -106,3 +109,4 @@ public: QPixmap symbolYesPix, symbolModPix, symbolNoPix; - QPixmap choiceYesPix, choiceNoPix, menuPix, menuInvPix; + QPixmap choiceYesPix, choiceNoPix; + QPixmap menuPix, menuInvPix, menuBackPix, voidPix; @@ -123,3 +127,3 @@ public: ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), menu(m), visible(v) + : Parent(parent, after), menu(m), visible(v), goParent(false) { @@ -128,3 +132,8 @@ public: ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) - : Parent(parent, after), menu(m), visible(v) + : Parent(parent, after), menu(m), visible(v), goParent(false) + { + init(); + } + ConfigItem(QListView *parent, ConfigItem *after, bool v) + : Parent(parent, after), menu(0), visible(v), goParent(true) { @@ -138,3 +147,3 @@ public: void updateMenu(void); - bool updateNeeded(void); + void testUpdateMenu(bool v); ConfigList* listView() const @@ -172,2 +181,3 @@ public: bool visible; + bool goParent; }; @@ -218,3 +228,5 @@ protected: + ConfigView *menuView; ConfigList *menuList; + ConfigView *configView; ConfigList *configList; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 845d8a3..11318d9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -36,14 +36,5 @@ void sym_add_default(struct symbol *sym, const char *def) { - struct property *prop = create_prop(P_DEFAULT); - struct property **propp; - - prop->sym = sym; - prop->def = sym_lookup(def, 1); + struct property *prop = prop_alloc(P_DEFAULT, sym); - /* append property to the prop list of symbol */ - if (prop->sym) { - for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next) - ; - *propp = prop; - } + prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); } @@ -83,5 +74,6 @@ void sym_init(void) -int sym_get_type(struct symbol *sym) +enum symbol_type sym_get_type(struct symbol *sym) { - int type = sym->type; + enum symbol_type type = sym->type; + if (type == S_TRISTATE) { @@ -91,3 +83,3 @@ int sym_get_type(struct symbol *sym) sym_calc_value(modules_sym); - if (S_TRI(modules_sym->curr) == no) + if (modules_sym->curr.tri == no) type = S_BOOLEAN; @@ -98,3 +90,3 @@ int sym_get_type(struct symbol *sym) -const char *sym_type_name(int type) +const char *sym_type_name(enum symbol_type type) { @@ -113,2 +105,4 @@ const char *sym_type_name(int type) return "unknown"; + case S_OTHER: + break; } @@ -129,7 +123,6 @@ struct property *sym_get_default_prop(struct symbol *sym) struct property *prop; - tristate visible; for_all_defaults(sym, prop) { - visible = E_CALC(prop->visible); - if (visible != no) + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri != no) return prop; @@ -139,14 +132,36 @@ struct property *sym_get_default_prop(struct symbol *sym) -void sym_calc_visibility(struct symbol *sym) +struct property *sym_get_range_prop(struct symbol *sym) { struct property *prop; - tristate visible, oldvisible; + + for_all_properties(sym, prop, P_RANGE) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri != no) + return prop; + } + return NULL; +} + +static void sym_calc_visibility(struct symbol *sym) +{ + struct property *prop; + tristate tri; /* any prompt visible? */ - oldvisible = sym->visible; - visible = no; - for_all_prompts(sym, prop) - visible = E_OR(visible, E_CALC(prop->visible)); - if (oldvisible != visible) { - sym->visible = visible; + tri = no; + for_all_prompts(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + tri = E_OR(tri, prop->visible.tri); + } + if (sym->visible != tri) { + sym->visible = tri; + sym_set_changed(sym); + } + if (sym_is_choice_value(sym)) + return; + tri = no; + if (sym->rev_dep.expr) + tri = expr_calc_value(sym->rev_dep.expr); + if (sym->rev_dep.tri != tri) { + sym->rev_dep.tri = tri; sym_set_changed(sym); @@ -155,2 +170,41 @@ void sym_calc_visibility(struct symbol *sym) +static struct symbol *sym_calc_choice(struct symbol *sym) +{ + struct symbol *def_sym; + struct property *prop; + struct expr *e; + + /* is the user choice visible? */ + def_sym = sym->user.val; + if (def_sym) { + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* any of the defaults visible? */ + for_all_defaults(sym, prop) { + prop->visible.tri = expr_calc_value(prop->visible.expr); + if (prop->visible.tri == no) + continue; + def_sym = prop_get_symbol(prop); + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* just get the first visible value */ + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) { + def_sym = e->right.sym; + sym_calc_visibility(def_sym); + if (def_sym->visible != no) + return def_sym; + } + + /* no choice? reset tristate value */ + sym->curr.tri = no; + return NULL; +} + void sym_calc_value(struct symbol *sym) @@ -158,8 +212,11 @@ void sym_calc_value(struct symbol *sym) struct symbol_value newval, oldval; - struct property *prop, *def_prop; - struct symbol *def_sym; + struct property *prop; struct expr *e; + if (!sym) + return; + if (sym->flags & SYMBOL_VALID) return; + sym->flags |= SYMBOL_VALID; @@ -178,13 +235,6 @@ void sym_calc_value(struct symbol *sym) default: - S_VAL(newval) = sym->name; - S_TRI(newval) = no; - if (sym->flags & SYMBOL_CONST) { - goto out; - } - //newval = symbol_empty.curr; - // generate warning somewhere here later - //S_TRI(newval) = yes; - goto out; + sym->curr.val = sym->name; + sym->curr.tri = no; + return; } - sym->flags |= SYMBOL_VALID; if (!sym_is_choice_value(sym)) @@ -197,86 +247,64 @@ void sym_calc_value(struct symbol *sym) - if (sym->visible != no) { - sym->flags |= SYMBOL_WRITE; - if (!sym_has_value(sym)) { - if (!sym_is_choice(sym)) { - prop = sym_get_default_prop(sym); - if (prop) { - sym_calc_value(prop->def); - newval = prop->def->curr; - } - } else - S_TRI(newval) = S_TRI(sym->def); - } else - newval = sym->def; - - S_TRI(newval) = E_AND(S_TRI(newval), sym->visible); - /* if the symbol is visible and not optionial, - * possibly ignore old user choice. */ - if (!sym_is_optional(sym) && S_TRI(newval) == no) - S_TRI(newval) = sym->visible; + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: if (sym_is_choice_value(sym) && sym->visible == yes) { prop = sym_get_choice_prop(sym); - S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; - } - } else { - prop = sym_get_default_prop(sym); - if (prop) { + newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; + } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { sym->flags |= SYMBOL_WRITE; - sym_calc_value(prop->def); - newval = prop->def->curr; + if (sym_has_value(sym)) + newval.tri = sym->user.tri; + else if (!sym_is_choice(sym)) { + prop = sym_get_default_prop(sym); + if (prop) + newval.tri = expr_calc_value(prop->expr); + } + newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri); + } else if (!sym_is_choice(sym)) { + prop = sym_get_default_prop(sym); + if (prop) { + sym->flags |= SYMBOL_WRITE; + newval.tri = expr_calc_value(prop->expr); + } } - } - - switch (sym_get_type(sym)) { - case S_TRISTATE: - if (S_TRI(newval) != mod) - break; - sym_calc_value(modules_sym); - if (S_TRI(modules_sym->curr) == no) - S_TRI(newval) = yes; - break; - case S_BOOLEAN: - if (S_TRI(newval) == mod) - S_TRI(newval) = yes; - } - -out: - sym->curr = newval; - - if (sym_is_choice(sym) && S_TRI(newval) == yes) { - def_sym = S_VAL(sym->def); - if (def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible == no) - def_sym = NULL; + if (sym_get_type(sym) == S_BOOLEAN) { + if (newval.tri == mod) + newval.tri = yes; + if (sym->visible == mod) + sym->visible = yes; + if (sym->rev_dep.tri == mod) + sym->rev_dep.tri = yes; } - if (!def_sym) { - for_all_defaults(sym, def_prop) { - if (E_CALC(def_prop->visible) == no) - continue; - sym_calc_visibility(def_prop->def); - if (def_prop->def->visible != no) { - def_sym = def_prop->def; - break; - } + break; + case S_STRING: + case S_HEX: + case S_INT: + if (sym->visible != no) { + sym->flags |= SYMBOL_WRITE; + if (sym_has_value(sym)) { + newval.val = sym->user.val; + break; } } - - if (!def_sym) { - prop = sym_get_choice_prop(sym); - for (e = prop->dep; e; e = e->left.expr) { - sym_calc_visibility(e->right.sym); - if (e->right.sym->visible != no) { - def_sym = e->right.sym; - break; - } + prop = sym_get_default_prop(sym); + if (prop) { + struct symbol *ds = prop_get_symbol(prop); + if (ds) { + sym->flags |= SYMBOL_WRITE; + sym_calc_value(ds); + newval.val = ds->curr.val; } } - - S_VAL(newval) = def_sym; + break; + default: + ; } - if (memcmp(&oldval, &newval, sizeof(newval))) - sym_set_changed(sym); sym->curr = newval; + if (sym_is_choice(sym) && newval.tri == yes) + sym->curr.val = sym_calc_choice(sym); + + if (memcmp(&oldval, &sym->curr, sizeof(oldval))) + sym_set_changed(sym); @@ -285,3 +313,3 @@ out: prop = sym_get_choice_prop(sym); - for (e = prop->dep; e; e = e->left.expr) { + for (e = prop->expr; e; e = e->left.expr) { e->right.sym->flags |= flags; @@ -333,15 +361,9 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) - switch (val) { - case no: - if (sym_is_choice_value(sym) && sym->visible == yes) - return false; - return sym_is_optional(sym); - case mod: - if (sym_is_choice_value(sym) && sym->visible == yes) - return false; - return type == S_TRISTATE; - case yes: - return type == S_BOOLEAN || sym->visible == yes; - } - return false; + if (type == S_BOOLEAN && val == mod) + return false; + if (sym->visible <= sym->rev_dep.tri) + return false; + if (sym_is_choice_value(sym) && sym->visible == yes) + return val == yes; + return val >= sym->rev_dep.tri && val <= sym->visible; } @@ -360,9 +382,9 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) if (sym_is_choice_value(sym) && val == yes) { - struct property *prop = sym_get_choice_prop(sym); + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - S_VAL(prop->def->def) = sym; - prop->def->flags &= ~SYMBOL_NEW; + cs->user.val = sym; + cs->flags &= ~SYMBOL_NEW; } - S_TRI(sym->def) = val; + sym->user.tri = val; if (oldval != val) { @@ -431,10 +453,47 @@ bool sym_string_valid(struct symbol *sym, const char *str) switch (str[0]) { - case 'y': - case 'Y': + case 'y': case 'Y': + case 'm': case 'M': + case 'n': case 'N': + return true; + } + return false; + default: + return false; + } +} + +bool sym_string_within_range(struct symbol *sym, const char *str) +{ + struct property *prop; + int val; + + switch (sym->type) { + case S_STRING: + return sym_string_valid(sym, str); + case S_INT: + if (!sym_string_valid(sym, str)) + return false; + prop = sym_get_range_prop(sym); + if (!prop) + return true; + val = strtol(str, NULL, 10); + return val >= strtol(prop->expr->left.sym->name, NULL, 10) && + val <= strtol(prop->expr->right.sym->name, NULL, 10); + case S_HEX: + if (!sym_string_valid(sym, str)) + return false; + prop = sym_get_range_prop(sym); + if (!prop) + return true; + val = strtol(str, NULL, 16); + return val >= strtol(prop->expr->left.sym->name, NULL, 16) && + val <= strtol(prop->expr->right.sym->name, NULL, 16); + case S_BOOLEAN: + case S_TRISTATE: + switch (str[0]) { + case 'y': case 'Y': return sym_tristate_within_range(sym, yes); - case 'm': - case 'M': + case 'm': case 'M': return sym_tristate_within_range(sym, mod); - case 'n': - case 'N': + case 'n': case 'N': return sym_tristate_within_range(sym, no); @@ -457,10 +516,7 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) switch (newval[0]) { - case 'y': - case 'Y': + case 'y': case 'Y': return sym_set_tristate_value(sym, yes); - case 'm': - case 'M': + case 'm': case 'M': return sym_set_tristate_value(sym, mod); - case 'n': - case 'N': + case 'n': case 'N': return sym_set_tristate_value(sym, no); @@ -472,3 +528,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) - if (!sym_string_valid(sym, newval)) + if (!sym_string_within_range(sym, newval)) return false; @@ -480,3 +536,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) - oldval = S_VAL(sym->def); + oldval = sym->user.val; size = strlen(newval) + 1; @@ -484,3 +540,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) size += 2; - S_VAL(sym->def) = val = malloc(size); + sym->user.val = val = malloc(size); *val++ = '0'; @@ -488,3 +544,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) } else if (!oldval || strcmp(oldval, newval)) - S_VAL(sym->def) = val = malloc(size); + sym->user.val = val = malloc(size); else @@ -519,3 +575,3 @@ const char *sym_get_string_value(struct symbol *sym) } - return (const char *)S_VAL(sym->curr); + return (const char *)sym->curr.val; } @@ -524,11 +580,3 @@ bool sym_is_changable(struct symbol *sym) { - if (sym->visible == no) - return false; - /* at least 'n' and 'y'/'m' is selectable */ - if (sym_is_optional(sym)) - return true; - /* no 'n', so 'y' and 'm' must be selectable */ - if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) - return true; - return false; + return sym->visible > sym->rev_dep.tri; } @@ -610,2 +658,100 @@ struct symbol *sym_find(const char *name) +struct symbol *sym_check_deps(struct symbol *sym); + +static struct symbol *sym_check_expr_deps(struct expr *e) +{ + struct symbol *sym; + + if (!e) + return NULL; + switch (e->type) { + case E_OR: + case E_AND: + sym = sym_check_expr_deps(e->left.expr); + if (sym) + return sym; + return sym_check_expr_deps(e->right.expr); + case E_NOT: + return sym_check_expr_deps(e->left.expr); + case E_EQUAL: + case E_UNEQUAL: + sym = sym_check_deps(e->left.sym); + if (sym) + return sym; + return sym_check_deps(e->right.sym); + case E_SYMBOL: + return sym_check_deps(e->left.sym); + default: + break; + } + printf("Oops! How to check %d?\n", e->type); + return NULL; +} + +struct symbol *sym_check_deps(struct symbol *sym) +{ + struct symbol *sym2; + struct property *prop; + + if (sym->flags & SYMBOL_CHECK_DONE) + return NULL; + if (sym->flags & SYMBOL_CHECK) { + printf("Warning! Found recursive dependency: %s", sym->name); + return sym; + } + + sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + sym2 = sym_check_expr_deps(sym->rev_dep.expr); + if (sym2) + goto out; + + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->type == P_CHOICE) + continue; + sym2 = sym_check_expr_deps(prop->visible.expr); + if (sym2) + goto out; + if (prop->type != P_DEFAULT || sym_is_choice(sym)) + continue; + sym2 = sym_check_expr_deps(prop->expr); + if (sym2) + goto out; + } +out: + if (sym2) + printf(" %s", sym->name); + sym->flags &= ~SYMBOL_CHECK; + return sym2; +} + +struct property *prop_alloc(enum prop_type type, struct symbol *sym) +{ + struct property *prop; + struct property **propp; + + prop = malloc(sizeof(*prop)); + memset(prop, 0, sizeof(*prop)); + prop->type = type; + prop->sym = sym; + prop->file = current_file; + prop->lineno = zconf_lineno(); + + /* append property to the prop list of symbol */ + if (sym) { + for (propp = &sym->prop; *propp; propp = &(*propp)->next) + ; + *propp = prop; + } + + return prop; +} + +struct symbol *prop_get_symbol(struct property *prop) +{ + if (prop->expr && (prop->expr->type == E_SYMBOL || + prop->expr->type == E_CHOICE)) + return prop->expr->left.sym; + return NULL; +} + const char *prop_get_type_name(enum prop_type type) @@ -619,4 +765,2 @@ const char *prop_get_type_name(enum prop_type type) return "menu"; - case P_ROOTMENU: - return "rootmenu"; case P_DEFAULT: @@ -625,5 +769,10 @@ const char *prop_get_type_name(enum prop_type type) return "choice"; - default: - return "unknown"; + case P_SELECT: + return "select"; + case P_RANGE: + return "range"; + case P_UNKNOWN: + break; } + return "unknown"; } diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 1471630..55517b2 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -98,2 +98,3 @@ n [A-Za-z0-9_] "config" BEGIN(PARAM); return T_CONFIG; + "menuconfig" BEGIN(PARAM); return T_MENUCONFIG; "help" BEGIN(PARAM); return T_HELP; @@ -107,4 +108,7 @@ n [A-Za-z0-9_] "tristate" BEGIN(PARAM); return T_TRISTATE; + "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE; "bool" BEGIN(PARAM); return T_BOOLEAN; "boolean" BEGIN(PARAM); return T_BOOLEAN; + "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN; + "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN; "int" BEGIN(PARAM); return T_INT; @@ -112,2 +116,5 @@ n [A-Za-z0-9_] "string" BEGIN(PARAM); return T_STRING; + "select" BEGIN(PARAM); return T_SELECT; + "enable" BEGIN(PARAM); return T_SELECT; + "range" BEGIN(PARAM); return T_RANGE; {n}+ { @@ -143,2 +150,3 @@ n [A-Za-z0-9_] } + #.* /* comment */ \\\n current_file->lineno++; @@ -154,3 +162,3 @@ n [A-Za-z0-9_] zconflval.string = text; - return T_STRING; + return T_WORD_QUOTE; } @@ -162,3 +170,3 @@ n [A-Za-z0-9_] zconflval.string = text; - return T_STRING; + return T_WORD_QUOTE; } @@ -171,3 +179,3 @@ n [A-Za-z0-9_] zconflval.string = text; - return T_STRING; + return T_WORD_QUOTE; } else @@ -208,5 +216,4 @@ n [A-Za-z0-9_] } - } - \n/[^ \t\n] { + [ \t]*\n/[^ \t\n] { current_file->lineno++; @@ -250,3 +257,3 @@ static void zconf_endhelp(void) zconflval.string = text; - BEGIN(INITIAL); + BEGIN(INITIAL); } @@ -254,3 +261,3 @@ static void zconf_endhelp(void) -/* +/* * Try to open specified file with following names: @@ -347,3 +354,3 @@ int zconf_lineno(void) if (current_buf) - return current_file->lineno; + return current_file->lineno - 1; else diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 996b10a..2468068 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -29,3 +29,3 @@ struct symbol *symbol_hash[257]; %} -%expect 36 +%expect 40 @@ -48,2 +48,3 @@ struct symbol *symbol_hash[257]; %token T_CONFIG +%token T_MENUCONFIG %token T_HELP @@ -58,3 +59,6 @@ struct symbol *symbol_hash[257]; %token T_TRISTATE +%token T_DEF_TRISTATE %token T_BOOLEAN +%token T_DEF_BOOLEAN +%token T_STRING %token T_INT @@ -62,3 +66,3 @@ struct symbol *symbol_hash[257]; %token <string> T_WORD -%token <string> T_STRING +%token <string> T_WORD_QUOTE %token T_UNEQUAL @@ -69,2 +73,4 @@ struct symbol *symbol_hash[257]; %token T_ON +%token T_SELECT +%token T_RANGE @@ -105,2 +111,3 @@ common_block: | config_stmt + | menuconfig_stmt | source_stmt @@ -110,5 +117,5 @@ common_block: -/* config entry */ +/* config/menuconfig entry */ -config_entry_start: T_CONFIG T_WORD +config_entry_start: T_CONFIG T_WORD T_EOL { @@ -120,3 +127,3 @@ config_entry_start: T_CONFIG T_WORD -config_stmt: config_entry_start T_EOL config_option_list +config_stmt: config_entry_start config_option_list { @@ -126,11 +133,29 @@ config_stmt: config_entry_start T_EOL config_option_list +menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +menuconfig_stmt: menuconfig_entry_start config_option_list +{ + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + config_option_list: /* empty */ - | config_option_list config_option T_EOL - | config_option_list depends T_EOL + | config_option_list config_option + | config_option_list depends | config_option_list help | config_option_list T_EOL -{ }; +; -config_option: T_TRISTATE prompt_stmt_opt +config_option: T_TRISTATE prompt_stmt_opt T_EOL { @@ -140,3 +165,10 @@ config_option: T_TRISTATE prompt_stmt_opt -config_option: T_BOOLEAN prompt_stmt_opt +config_option: T_DEF_TRISTATE expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_BOOLEAN prompt_stmt_opt T_EOL { @@ -146,3 +178,10 @@ config_option: T_BOOLEAN prompt_stmt_opt -config_option: T_INT prompt_stmt_opt +config_option: T_DEF_BOOLEAN expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_INT prompt_stmt_opt T_EOL { @@ -152,3 +191,3 @@ config_option: T_INT prompt_stmt_opt -config_option: T_HEX prompt_stmt_opt +config_option: T_HEX prompt_stmt_opt T_EOL { @@ -158,3 +197,3 @@ config_option: T_HEX prompt_stmt_opt -config_option: T_STRING prompt_stmt_opt +config_option: T_STRING prompt_stmt_opt T_EOL { @@ -164,5 +203,5 @@ config_option: T_STRING prompt_stmt_opt -config_option: T_PROMPT prompt if_expr +config_option: T_PROMPT prompt if_expr T_EOL { - menu_add_prop(P_PROMPT, $2, NULL, $3); + menu_add_prompt(P_PROMPT, $2, $3); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); @@ -170,5 +209,5 @@ config_option: T_PROMPT prompt if_expr -config_option: T_DEFAULT symbol if_expr +config_option: T_DEFAULT expr if_expr T_EOL { - menu_add_prop(P_DEFAULT, NULL, $2, $3); + menu_add_expr(P_DEFAULT, $2, $3); printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); @@ -176,5 +215,17 @@ config_option: T_DEFAULT symbol if_expr +config_option: T_SELECT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_RANGE symbol symbol if_expr T_EOL +{ + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +}; + /* choice entry */ -choice: T_CHOICE +choice: T_CHOICE T_EOL { @@ -183,3 +234,3 @@ choice: T_CHOICE menu_add_entry(sym); - menu_add_prop(P_CHOICE, NULL, NULL, NULL); + menu_add_expr(P_CHOICE, NULL, NULL); printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); @@ -187,3 +238,3 @@ choice: T_CHOICE -choice_entry: choice T_EOL choice_option_list +choice_entry: choice choice_option_list { @@ -202,3 +253,3 @@ choice_end: end choice_stmt: - choice_entry choice_block choice_end T_EOL + choice_entry choice_block choice_end | choice_entry choice_block @@ -211,4 +262,4 @@ choice_option_list: /* empty */ - | choice_option_list choice_option T_EOL - | choice_option_list depends T_EOL + | choice_option_list choice_option + | choice_option_list depends | choice_option_list help @@ -217,5 +268,5 @@ choice_option_list: -choice_option: T_PROMPT prompt if_expr +choice_option: T_PROMPT prompt if_expr T_EOL { - menu_add_prop(P_PROMPT, $2, NULL, $3); + menu_add_prompt(P_PROMPT, $2, $3); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); @@ -223,3 +274,15 @@ choice_option: T_PROMPT prompt if_expr -choice_option: T_OPTIONAL +choice_option: T_TRISTATE prompt_stmt_opt T_EOL +{ + menu_set_type(S_TRISTATE); + printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_BOOLEAN prompt_stmt_opt T_EOL +{ + menu_set_type(S_BOOLEAN); + printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_OPTIONAL T_EOL { @@ -229,5 +292,5 @@ choice_option: T_OPTIONAL -choice_option: T_DEFAULT symbol if_expr +choice_option: T_DEFAULT T_WORD if_expr T_EOL { - menu_add_prop(P_DEFAULT, NULL, $2, $3); + menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); @@ -242,3 +305,3 @@ choice_block: -if: T_IF expr +if: T_IF expr T_EOL { @@ -260,4 +323,4 @@ if_end: end if_stmt: - if T_EOL if_block if_end T_EOL - | if T_EOL if_block + if if_block if_end + | if if_block { @@ -276,3 +339,3 @@ if_block: -menu: T_MENU prompt +menu: T_MENU prompt T_EOL { @@ -283,3 +346,3 @@ menu: T_MENU prompt -menu_entry: menu T_EOL depends_list +menu_entry: menu depends_list { @@ -298,3 +361,3 @@ menu_end: end menu_stmt: - menu_entry menu_block menu_end T_EOL + menu_entry menu_block menu_end | menu_entry menu_block @@ -313,3 +376,3 @@ menu_block: -source: T_SOURCE prompt +source: T_SOURCE prompt T_EOL { @@ -319,3 +382,3 @@ source: T_SOURCE prompt -source_stmt: source T_EOL +source_stmt: source { @@ -326,3 +389,3 @@ source_stmt: source T_EOL -comment: T_COMMENT prompt +comment: T_COMMENT prompt T_EOL { @@ -333,3 +396,3 @@ comment: T_COMMENT prompt -comment_stmt: comment T_EOL depends_list +comment_stmt: comment depends_list { @@ -354,7 +417,7 @@ help: help_start T_HELPTEXT depends_list: /* empty */ - | depends_list depends T_EOL + | depends_list depends | depends_list T_EOL -{ }; +; -depends: T_DEPENDS T_ON expr +depends: T_DEPENDS T_ON expr T_EOL { @@ -363,3 +426,3 @@ depends: T_DEPENDS T_ON expr } - | T_DEPENDS expr + | T_DEPENDS expr T_EOL { @@ -368,3 +431,3 @@ depends: T_DEPENDS T_ON expr } - | T_REQUIRES expr + | T_REQUIRES expr T_EOL { @@ -378,9 +441,5 @@ prompt_stmt_opt: /* empty */ - | prompt -{ - menu_add_prop(P_PROMPT, $1, NULL, NULL); -} - | prompt T_IF expr + | prompt if_expr { - menu_add_prop(P_PROMPT, $1, NULL, $3); + menu_add_prop(P_PROMPT, $1, NULL, $2); }; @@ -388,8 +447,8 @@ prompt_stmt_opt: prompt: T_WORD - | T_STRING + | T_WORD_QUOTE ; -end: T_ENDMENU { $$ = T_ENDMENU; } - | T_ENDCHOICE { $$ = T_ENDCHOICE; } - | T_ENDIF { $$ = T_ENDIF; } +end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } + | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } + | T_ENDIF nl_or_eof { $$ = T_ENDIF; } ; @@ -413,3 +472,3 @@ expr: symbol { $$ = expr_alloc_symbol($1); } symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } - | T_STRING { $$ = sym_lookup($1, 1); free($1); } + | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); } ; @@ -420,2 +479,5 @@ void conf_parse(const char *name) { + struct symbol *sym; + int i; + zconf_initscan(name); @@ -424,3 +486,4 @@ void conf_parse(const char *name) menu_init(); - rootmenu.prompt = menu_add_prop(P_MENU, "Configuration", NULL, NULL); + modules_sym = sym_lookup("MODULES", 0); + rootmenu.prompt = menu_add_prop(P_MENU, "Build Configuration", NULL, NULL); @@ -431,4 +494,8 @@ void conf_parse(const char *name) menu_finalize(&rootmenu); - - modules_sym = sym_lookup("MODULES", 0); + for_all_symbols(i, sym) { + if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) + printf("\n"); + else + sym->flags |= SYMBOL_CHECK_DONE; + } @@ -448,3 +515,3 @@ const char *zconf_tokenname(int token) return "<token>"; -} +} @@ -470,3 +537,3 @@ static void zconfprint(const char *err, ...) - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); va_start(ap, err); @@ -479,3 +546,3 @@ static void zconferror(const char *err) { - fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err); + fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); } @@ -504,4 +571,2 @@ void print_symbol(FILE *out, struct menu *menu) - //sym->flags |= SYMBOL_PRINTED; - if (sym_is_choice(sym)) @@ -530,9 +595,2 @@ void print_symbol(FILE *out, struct menu *menu) } -#if 0 - if (!expr_is_yes(sym->dep)) { - fputs(" depends ", out); - expr_fprint(sym->dep, out); - fputc('\n', out); - } -#endif for (prop = sym->prop; prop; prop = prop->next) { @@ -544,12 +602,5 @@ void print_symbol(FILE *out, struct menu *menu) print_quoted_string(out, prop->text); - if (prop->def) { - fputc(' ', out); - if (prop->def->flags & SYMBOL_CONST) - print_quoted_string(out, prop->def->name); - else - fputs(prop->def->name, out); - } - if (!expr_is_yes(E_EXPR(prop->visible))) { + if (!expr_is_yes(prop->visible.expr)) { fputs(" if ", out); - expr_fprint(E_EXPR(prop->visible), out); + expr_fprint(prop->visible.expr, out); } @@ -559,6 +610,6 @@ void print_symbol(FILE *out, struct menu *menu) fputs( " default ", out); - print_quoted_string(out, prop->def->name); - if (!expr_is_yes(E_EXPR(prop->visible))) { + expr_fprint(prop->expr, out); + if (!expr_is_yes(prop->visible.expr)) { fputs(" if ", out); - expr_fprint(E_EXPR(prop->visible), out); + expr_fprint(prop->visible.expr, out); } @@ -585,3 +636,2 @@ void zconfdump(FILE *out) { - //struct file *file; struct property *prop; @@ -596,7 +646,2 @@ void zconfdump(FILE *out) switch (prop->type) { - //case T_MAINMENU: - // fputs("\nmainmenu ", out); - // print_quoted_string(out, prop->text); - // fputs("\n", out); - // break; case P_COMMENT: @@ -611,9 +656,2 @@ void zconfdump(FILE *out) break; - //case T_SOURCE: - // fputs("\nsource ", out); - // print_quoted_string(out, prop->text); - // fputs("\n", out); - // break; - //case T_IF: - // fputs("\nif\n", out); default: @@ -621,5 +659,5 @@ void zconfdump(FILE *out) } - if (!expr_is_yes(E_EXPR(prop->visible))) { + if (!expr_is_yes(prop->visible.expr)) { fputs(" depends ", out); - expr_fprint(E_EXPR(prop->visible), out); + expr_fprint(prop->visible.expr, out); fputc('\n', out); |