From 9870a93d3118239fd7732a0f908e05f67b39a294 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 1 Jun 2006 21:28:50 -0400 Subject: kbuild: obj-dirs is calculated incorrectly if hostprogs-y is defined When Makefile.host is included, $(obj-dirs) is subjected to the addprefix operation for the second time. Prefix only needs to be added to the newly added directories, but not to those that came from Makefile.lib. This causes the build system to create unneeded empty directories in the build tree when building in a separate directory. For instance, lib/lib/zlib_inflate is created in the build tree. Signed-off-by: Pavel Roskin Signed-off-by: Sam Ravnborg --- scripts/Makefile.host | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 2d519704b8fd..2b066d12af2c 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -33,8 +33,8 @@ __hostprogs := $(sort $(hostprogs-y)$(hostprogs-m)) # hostprogs-y := tools/build may have been specified. Retreive directory -obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f)))) -obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs)))) +host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f)))) +host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs)))) # C code @@ -73,7 +73,9 @@ host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) host-cshlib := $(addprefix $(obj)/,$(host-cshlib)) host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs)) -obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) +host-objdirs := $(addprefix $(obj)/,$(host-objdirs)) + +obj-dirs += $(host-objdirs) ##### # Handle options to gcc. Support building with separate output directory -- cgit v1.2.3 From 1a0f3d422bb9ac959383a5ed1a4127f5900f56a8 Mon Sep 17 00:00:00 2001 From: Mike Wolf Date: Fri, 2 Jun 2006 09:53:42 -0500 Subject: kbuild: fix make rpm for powerpc The default target for most powerpc platforms is zImage. The zImage however is in arch/powerpc/boot and the mkspec script was set up to get the kernel from the top level of the kernel tree. This patch copies vmlinux to arch/powerpc/boot and then copies the kernel to the tmp directory so the rpm can be made. Signed-off-by: Mike Wolf Signed-off-by: Sam Ravnborg --- scripts/package/mkspec | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 0b1038737548..df892841b118 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -73,8 +73,13 @@ echo "%ifarch ia64" echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" echo "%else" +echo "%ifarch ppc64" +echo "cp vmlinux arch/powerpc/boot" +echo "cp arch/powerpc/boot/"'$KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE" +echo "%else" echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE" echo "%endif" +echo "%endif" echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" -- cgit v1.2.3 From 35899c57516be6eaa42cc27151767c52d75b2979 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 7 Jun 2006 16:23:26 -0700 Subject: kbuild: ignore smp_locks section warnings from init/exit code Add ".smp_locks" section to whitelist as being safe from init and exit sections. Signed-off-by: Randy Dunlap Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d0f86ed43f7a..94047bc99961 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -821,6 +821,7 @@ static int init_section_ref_ok(const char *name) ".pci_fixup_final", ".pdr", "__param", + ".smp_locks", NULL }; /* Start of section names */ @@ -892,6 +893,7 @@ static int exit_section_ref_ok(const char *name) ".exitcall.exit", ".eh_frame", ".stab", + ".smp_locks", NULL }; /* Start of section names */ -- cgit v1.2.3 From 909252d279dd5d47e44c125558e87bb44097289f Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 8 Jun 2006 20:37:30 +0200 Subject: kbuild: fix false section mismatch with ARCH=um build Ignoring references to .init.text, .exit.text from the .plt section brought the false positives down to two warnings for a defconfig build of ARCH=um on x86_64. Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 94047bc99961..a70f5ddb705c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -822,6 +822,7 @@ static int init_section_ref_ok(const char *name) ".pdr", "__param", ".smp_locks", + ".plt", /* seen on ARCH=um build on x86_64. Harmless */ NULL }; /* Start of section names */ @@ -894,6 +895,7 @@ static int exit_section_ref_ok(const char *name) ".eh_frame", ".stab", ".smp_locks", + ".plt", /* seen on ARCH=um build on x86_64. Harmless */ NULL }; /* Start of section names */ -- cgit v1.2.3 From ddc97cacb310ad68483952e67764c4153c138ed2 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:38 -0700 Subject: kconfig: improve config load/save output During loading special case the first common case (.config), be silent about it and otherwise mark it as a change that requires saving. Instead output that the file has been changed. IOW if conf does nothing (special), it's silent. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/confdata.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 1b5df589f3ae..a9e3b6abf661 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -98,20 +98,28 @@ int conf_read_simple(const char *name) in = zconf_fopen(name); } else { const char **names = conf_confnames; + name = *names++; + if (!name) + return 1; + in = zconf_fopen(name); + if (in) + goto load; + sym_change_count++; while ((name = *names++)) { name = conf_expand_value(name); in = zconf_fopen(name); if (in) { printf(_("#\n" - "# using defaults found in %s\n" - "#\n"), name); - break; + "# using defaults found in %s\n" + "#\n"), name); + goto load; } } } if (!in) return 1; +load: conf_filename = name; conf_lineno = 0; conf_warnings = 0; @@ -275,6 +283,8 @@ int conf_read(const char *name) struct expr *e; int i; + sym_change_count = 0; + if (conf_read_simple(name)) return 1; @@ -325,7 +335,7 @@ int conf_read(const char *name) sym->flags |= e->right.sym->flags & SYMBOL_NEW; } - sym_change_count = conf_warnings || conf_unsaved; + sym_change_count += conf_warnings || conf_unsaved; return 0; } @@ -524,6 +534,10 @@ int conf_write(const char *name) if (rename(newname, tmpname)) return 1; + printf(_("#\n" + "# configuration written to %s\n" + "#\n"), tmpname); + sym_change_count = 0; return 0; -- cgit v1.2.3 From c955ccafc38e77312b4c65e5a70960080fb8a3f2 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:39 -0700 Subject: kconfig: fix .config dependencies This fixes one of the worst kbuild warts left - the broken dependencies used to check and regenerate the .config file. This was done via an indirect dependency and the .config itself had an empty command, which can cause make not to reread the changed .config file. Instead of this we generate now a new file include/config/auto.conf from .config, which is used for kbuild and has the proper dependencies. It's also the main make target now for all files generated during this step (and thus replaces include/linux/autoconf.h). This also means we can now relax the syntax requirements for the .config file and we don't have to rewrite it all the time, i.e. silentoldconfig only writes .config now when it's necessary to keep it in sync with the Kconfig files and even this can be suppressed by setting the environment variable KCONFIG_NOSILENTUPDATE, so the update can (and must) be done manually. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- Makefile | 27 +++---- scripts/Makefile.build | 2 +- scripts/Makefile.modpost | 2 +- scripts/kconfig/conf.c | 16 +++- scripts/kconfig/confdata.c | 177 +++++++++++++++++++++++++++++++------------- scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/util.c | 4 +- 7 files changed, 156 insertions(+), 73 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index a3a7baad8555..b1610562a65f 100644 --- a/Makefile +++ b/Makefile @@ -404,7 +404,7 @@ include $(srctree)/arch/$(ARCH)/Makefile export KBUILD_DEFCONFIG config %config: scripts_basic outputmakefile FORCE - $(Q)mkdir -p include/linux + $(Q)mkdir -p include/linux include/config $(Q)$(MAKE) $(build)=scripts/kconfig $@ $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease @@ -421,8 +421,6 @@ PHONY += scripts scripts: scripts_basic include/config/MARKER $(Q)$(MAKE) $(build)=$(@) -scripts_basic: include/linux/autoconf.h - # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ drivers-y := drivers/ sound/ @@ -436,25 +434,22 @@ ifeq ($(dot-config),1) # Read in dependencies to all Kconfig* files, make sure to run # oldconfig if changes are detected. --include .kconfig.d - -include .config +-include include/config/auto.conf.cmd +-include include/config/auto.conf -# If .config needs to be updated, it will be done via the dependency -# that autoconf has on .config. # To avoid any implicit rule to kick in, define an empty command -.config .kconfig.d: ; +.config include/config/auto.conf.cmd: ; -# If .config is newer than include/linux/autoconf.h, someone tinkered +# If .config is newer than include/config/auto.conf, someone tinkered # with it and forgot to run make oldconfig. -# If kconfig.d is missing then we are probarly in a cleaned tree so +# if auto.conf.cmd is missing then we are probarly in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/linux/autoconf.h: .kconfig.d .config - $(Q)mkdir -p include/linux +include/config/auto.conf: .config include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig + else # Dummy target needed, because used as prerequisite -include/linux/autoconf.h: ; +include/config/auto.conf: ; endif # The all: target is the default when no target is given on the @@ -779,7 +774,7 @@ PHONY += prepare-all prepare3: .kernelrelease ifneq ($(KBUILD_SRC),) @echo ' Using $(srctree) as source for kernel' - $(Q)if [ -f $(srctree)/.config ]; then \ + $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \ echo " $(srctree) is not clean, please run 'make mrproper'";\ echo " in the '$(srctree)' directory.";\ /bin/false; \ @@ -822,7 +817,7 @@ include/asm: # Split autoconf.h into include/linux/config/* -include/config/MARKER: scripts/basic/split-include include/linux/autoconf.h +include/config/MARKER: scripts/basic/split-include include/config/auto.conf @echo ' SPLIT include/linux/autoconf.h -> include/config/*' @scripts/basic/split-include include/linux/autoconf.h include/config @touch $@ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e48e60da3040..53e53a2e80ae 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -8,7 +8,7 @@ PHONY := __build __build: # Read .config if it exist, otherwise ignore --include .config +-include include/config/auto.conf include scripts/Kbuild.include diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 0e056cffffdb..576cce5e387f 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -35,7 +35,7 @@ PHONY := _modpost _modpost: __modpost -include .config +include include/config/auto.conf include scripts/Kbuild.include include scripts/Makefile.lib diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 8012d1076876..9334da65f364 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -599,7 +599,15 @@ int main(int ac, char **av) input_mode = ask_silent; valid_stdin = 1; } - } + } else if (sym_change_count) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n")); + return 1; + } + } else + goto skip_check; + do { conf_cnt = 0; check_conf(&rootmenu); @@ -608,5 +616,11 @@ int main(int ac, char **av) fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); return 1; } +skip_check: + if (input_mode == ask_silent && conf_write_autoconf()) { + fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + return 1; + } + return 0; } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index a9e3b6abf661..2da4a8d775a5 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -342,7 +342,7 @@ int conf_read(const char *name) int conf_write(const char *name) { - FILE *out, *out_h; + FILE *out; struct symbol *sym; struct menu *menu; const char *basename; @@ -379,13 +379,6 @@ int conf_write(const char *name) out = fopen(newname, "w"); if (!out) return 1; - out_h = NULL; - if (!name) { - out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) - return 1; - file_write_dep(NULL); - } sym = sym_lookup("KERNELVERSION", 0); sym_calc_value(sym); time(&now); @@ -401,16 +394,6 @@ int conf_write(const char *name) sym_get_string_value(sym), use_timestamp ? "# " : "", use_timestamp ? ctime(&now) : ""); - if (out_h) - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - " * Linux kernel version: %s\n" - "%s%s" - " */\n" - "#define AUTOCONF_INCLUDED\n", - sym_get_string_value(sym), - use_timestamp ? " * " : "", - use_timestamp ? ctime(&now) : ""); if (!sym_change_count) sym_clear_all_valid(); @@ -426,11 +409,6 @@ int conf_write(const char *name) "#\n" "# %s\n" "#\n", str); - if (out_h) - fprintf(out_h, "\n" - "/*\n" - " * %s\n" - " */\n", str); } else if (!(sym->flags & SYMBOL_CHOICE)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) @@ -448,59 +426,39 @@ int conf_write(const char *name) switch (sym_get_tristate_value(sym)) { case no: fprintf(out, "# CONFIG_%s is not set\n", sym->name); - if (out_h) - fprintf(out_h, "#undef CONFIG_%s\n", sym->name); break; case mod: fprintf(out, "CONFIG_%s=m\n", sym->name); - if (out_h) - fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; case yes: fprintf(out, "CONFIG_%s=y\n", sym->name); - if (out_h) - fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); break; } break; case S_STRING: - // fix me str = sym_get_string_value(sym); fprintf(out, "CONFIG_%s=\"", sym->name); - if (out_h) - fprintf(out_h, "#define CONFIG_%s \"", sym->name); - do { + while (1) { l = strcspn(str, "\"\\"); if (l) { fwrite(str, l, 1, out); - if (out_h) - fwrite(str, l, 1, out_h); - } - str += l; - while (*str == '\\' || *str == '"') { - fprintf(out, "\\%c", *str); - if (out_h) - fprintf(out_h, "\\%c", *str); - str++; + str += l; } - } while (*str); + if (!*str) + break; + fprintf(out, "\\%c", *str++); + } fputs("\"\n", out); - if (out_h) - fputs("\"\n", out_h); break; case S_HEX: str = sym_get_string_value(sym); if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - if (out_h) - fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); break; } case S_INT: str = sym_get_string_value(sym); fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - if (out_h) - fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); break; } } @@ -520,10 +478,6 @@ int conf_write(const char *name) } } fclose(out); - if (out_h) { - fclose(out_h); - rename(".tmpconfig.h", "include/linux/autoconf.h"); - } if (!name || basename != conf_def_filename) { if (!name) name = conf_def_filename; @@ -542,3 +496,120 @@ int conf_write(const char *name) return 0; } + +int conf_write_autoconf(void) +{ + struct symbol *sym; + const char *str; + char *name; + FILE *out, *out_h; + time_t now; + int i, l; + + file_write_dep("include/config/auto.conf.cmd"); + + out = fopen(".tmpconfig", "w"); + if (!out) + return 1; + + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) { + fclose(out); + return 1; + } + + sym = sym_lookup("KERNELVERSION", 0); + sym_calc_value(sym); + time(&now); + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" + "# Linux kernel version: %s\n" + "# %s" + "#\n", + sym_get_string_value(sym), ctime(&now)); + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " * Linux kernel version: %s\n" + " * %s" + " */\n" + "#define AUTOCONF_INCLUDED\n", + sym_get_string_value(sym), ctime(&now)); + + sym_clear_all_valid(); + + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE) || !sym->name) + continue; + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + break; + case mod: + fprintf(out, "CONFIG_%s=m\n", sym->name); + fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); + break; + case yes: + fprintf(out, "CONFIG_%s=y\n", sym->name); + fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); + break; + } + break; + case S_STRING: + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=\"", sym->name); + fprintf(out_h, "#define CONFIG_%s \"", sym->name); + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + fwrite(str, l, 1, out_h); + str += l; + } + if (!*str) + break; + fprintf(out, "\\%c", *str); + fprintf(out_h, "\\%c", *str); + str++; + } + fputs("\"\n", out); + fputs("\"\n", out_h); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); + break; + default: + break; + } + } + fclose(out); + fclose(out_h); + + name = getenv("KCONFIG_AUTOHEADER"); + if (!name) + name = "include/linux/autoconf.h"; + if (rename(".tmpconfig.h", name)) + return 1; + name = getenv("KCONFIG_AUTOCONFIG"); + if (!name) + name = "include/config/auto.conf"; + /* + * This must be the last step, kbuild has a dependency on auto.conf + * and this marks the successful completion of the previous steps. + */ + if (rename(".tmpconfig", name)) + return 1; + + return 0; +} diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index b6a389c5fcbd..bd0fb1dc1322 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -4,6 +4,7 @@ P(conf_parse,void,(const char *name)); P(conf_read,int,(const char *name)); P(conf_read_simple,int,(const char *name)); P(conf_write,int,(const char *name)); +P(conf_write_autoconf,int,(void)); /* menu.c */ P(rootmenu,struct menu,); diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c index 656d2c87d661..e3f28b9d59f4 100644 --- a/scripts/kconfig/util.c +++ b/scripts/kconfig/util.c @@ -44,7 +44,9 @@ int file_write_dep(const char *name) else fprintf(out, "\t%s\n", file->name); } - fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n"); + fprintf(out, "\ninclude/config/auto.conf: \\\n" + "\t$(deps_config)\n\n" + "$(deps_config): ;\n"); fclose(out); rename("..config.tmp", name); return 0; -- cgit v1.2.3 From c0e150acde52e4661675539bf5323309270f2e83 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:40 -0700 Subject: kconfig: remove SYMBOL_{YES,MOD,NO} The SYMBOL_{YES,MOD,NO} are not really used anymore (they were more used be the cml1 converter), so just remove them. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/expr.c | 3 ++- scripts/kconfig/expr.h | 5 +---- scripts/kconfig/gconf.c | 6 ------ scripts/kconfig/symbol.c | 6 +++--- 4 files changed, 6 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 30e4f9d69c2f..87238afb21b7 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -145,7 +145,8 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e return; } if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && - e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) + e1->left.sym == e2->left.sym && + (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) return; if (!expr_eq(e1, e2)) return; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 1b36ef18c48d..52ea4df8e349 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -78,10 +78,7 @@ struct symbol { #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) -#define SYMBOL_YES 0x0001 -#define SYMBOL_MOD 0x0002 -#define SYMBOL_NO 0x0004 -#define SYMBOL_CONST 0x0007 +#define SYMBOL_CONST 0x0001 #define SYMBOL_CHECK 0x0008 #define SYMBOL_CHOICE 0x0010 #define SYMBOL_CHOICEVAL 0x0020 diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 665bd5300a19..9cb3e6a47555 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -114,12 +114,6 @@ const char *dbg_print_flags(int val) 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) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 3d7877afccd5..a0a467a4387b 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -15,15 +15,15 @@ struct symbol symbol_yes = { .name = "y", .curr = { "y", yes }, - .flags = SYMBOL_YES|SYMBOL_VALID, + .flags = SYMBOL_CONST|SYMBOL_VALID, }, symbol_mod = { .name = "m", .curr = { "m", mod }, - .flags = SYMBOL_MOD|SYMBOL_VALID, + .flags = SYMBOL_CONST|SYMBOL_VALID, }, symbol_no = { .name = "n", .curr = { "n", no }, - .flags = SYMBOL_NO|SYMBOL_VALID, + .flags = SYMBOL_CONST|SYMBOL_VALID, }, symbol_empty = { .name = "", .curr = { "", no }, -- cgit v1.2.3 From 0c1822e6991a10da6dc391f0a2e2cf5fb2e31238 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:41 -0700 Subject: kconfig: allow multiple default values per symbol Extend struct symbol to allow storing multiple default values, which can be used to hold multiple configurations. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/confdata.c | 34 +++++++++++++++++----------------- scripts/kconfig/expr.h | 7 ++++++- scripts/kconfig/symbol.c | 16 ++++++++-------- 3 files changed, 31 insertions(+), 26 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 2da4a8d775a5..54ca1a786d25 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -134,11 +134,11 @@ load: case S_INT: case S_HEX: case S_STRING: - if (sym->user.val) - free(sym->user.val); + if (sym->def[S_DEF_USER].val) + free(sym->def[S_DEF_USER].val); default: - sym->user.val = NULL; - sym->user.tri = no; + sym->def[S_DEF_USER].val = NULL; + sym->def[S_DEF_USER].tri = no; } } @@ -166,7 +166,7 @@ load: switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - sym->user.tri = no; + sym->def[S_DEF_USER].tri = no; sym->flags &= ~SYMBOL_NEW; break; default: @@ -196,18 +196,18 @@ load: switch (sym->type) { case S_TRISTATE: if (p[0] == 'm') { - sym->user.tri = mod; + sym->def[S_DEF_USER].tri = mod; sym->flags &= ~SYMBOL_NEW; break; } case S_BOOLEAN: if (p[0] == 'y') { - sym->user.tri = yes; + sym->def[S_DEF_USER].tri = yes; sym->flags &= ~SYMBOL_NEW; break; } if (p[0] == 'n') { - sym->user.tri = no; + sym->def[S_DEF_USER].tri = no; sym->flags &= ~SYMBOL_NEW; break; } @@ -230,7 +230,7 @@ load: case S_INT: case S_HEX: if (sym_string_valid(sym, p)) { - sym->user.val = strdup(p); + sym->def[S_DEF_USER].val = strdup(p); sym->flags &= ~SYMBOL_NEW; } else { conf_warning("symbol value '%s' invalid for %s", p, sym->name); @@ -249,24 +249,24 @@ load: } if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - switch (sym->user.tri) { + switch (sym->def[S_DEF_USER].tri) { case no: break; case mod: - if (cs->user.tri == yes) { + if (cs->def[S_DEF_USER].tri == yes) { conf_warning("%s creates inconsistent choice state", sym->name); cs->flags |= SYMBOL_NEW; } break; case yes: - if (cs->user.tri != no) { + if (cs->def[S_DEF_USER].tri != no) { conf_warning("%s creates inconsistent choice state", sym->name); cs->flags |= SYMBOL_NEW; } else - cs->user.val = sym; + cs->def[S_DEF_USER].val = sym; break; } - cs->user.tri = E_OR(cs->user.tri, sym->user.tri); + cs->def[S_DEF_USER].tri = E_OR(cs->def[S_DEF_USER].tri, sym->def[S_DEF_USER].tri); } } fclose(in); @@ -297,12 +297,12 @@ int conf_read(const char *name) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - if (sym->user.tri != sym_get_tristate_value(sym)) + if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) break; if (!sym_is_choice(sym)) goto sym_ok; default: - if (!strcmp(sym->curr.val, sym->user.val)) + if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) goto sym_ok; break; } @@ -319,7 +319,7 @@ int conf_read(const char *name) case S_STRING: case S_INT: case S_HEX: - if (!sym_string_within_range(sym, sym->user.val)) { + if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val)) { sym->flags |= SYMBOL_NEW; sym->flags &= ~SYMBOL_VALID; } diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 52ea4df8e349..043859d426d7 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -63,12 +63,17 @@ enum symbol_type { S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER }; +enum { + S_DEF_USER, /* main user value */ +}; + struct symbol { struct symbol *next; char *name; char *help; enum symbol_type type; - struct symbol_value curr, user; + struct symbol_value curr; + struct symbol_value def[4]; tristate visible; int flags; struct property *prop; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index a0a467a4387b..4ea0050dcb16 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -227,7 +227,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym) struct expr *e; /* is the user choice visible? */ - def_sym = sym->user.val; + def_sym = sym->def[S_DEF_USER].val; if (def_sym) { sym_calc_visibility(def_sym); if (def_sym->visible != no) @@ -306,7 +306,7 @@ void sym_calc_value(struct symbol *sym) } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { sym->flags |= SYMBOL_WRITE; if (sym_has_value(sym)) - newval.tri = sym->user.tri; + newval.tri = sym->def[S_DEF_USER].tri; else if (!sym_is_choice(sym)) { prop = sym_get_default_prop(sym); if (prop) @@ -329,7 +329,7 @@ void sym_calc_value(struct symbol *sym) if (sym->visible != no) { sym->flags |= SYMBOL_WRITE; if (sym_has_value(sym)) { - newval.val = sym->user.val; + newval.val = sym->def[S_DEF_USER].val; break; } } @@ -439,7 +439,7 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) struct property *prop; struct expr *e; - cs->user.val = sym; + cs->def[S_DEF_USER].val = sym; cs->flags &= ~SYMBOL_NEW; prop = sym_get_choice_prop(cs); for (e = prop->expr; e; e = e->left.expr) { @@ -448,7 +448,7 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) } } - sym->user.tri = val; + sym->def[S_DEF_USER].tri = val; if (oldval != val) { sym_clear_all_valid(); if (sym == modules_sym) @@ -596,15 +596,15 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) sym_set_changed(sym); } - oldval = sym->user.val; + oldval = sym->def[S_DEF_USER].val; size = strlen(newval) + 1; if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { size += 2; - sym->user.val = val = malloc(size); + sym->def[S_DEF_USER].val = val = malloc(size); *val++ = '0'; *val++ = 'x'; } else if (!oldval || strcmp(oldval, newval)) - sym->user.val = val = malloc(size); + sym->def[S_DEF_USER].val = val = malloc(size); else return true; -- cgit v1.2.3 From 669bfad906522e74ee8d962801552a8c224c0d63 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:42 -0700 Subject: kconfig: allow loading multiple configurations Extend conf_read_simple() so it can load multiple configurations. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/conf.c | 6 +-- scripts/kconfig/confdata.c | 111 ++++++++++++++++++++++++++------------------ scripts/kconfig/expr.h | 6 ++- scripts/kconfig/gconf.c | 6 +-- scripts/kconfig/lkc.h | 2 +- scripts/kconfig/lkc_proto.h | 2 +- scripts/kconfig/symbol.c | 13 +++--- 7 files changed, 84 insertions(+), 62 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 9334da65f364..ded5ffe184b8 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -573,7 +573,7 @@ int main(int ac, char **av) case set_random: name = getenv("KCONFIG_ALLCONFIG"); if (name && !stat(name, &tmpstat)) { - conf_read_simple(name); + conf_read_simple(name, S_DEF_USER); break; } switch (input_mode) { @@ -584,9 +584,9 @@ int main(int ac, char **av) default: break; } if (!stat(name, &tmpstat)) - conf_read_simple(name); + conf_read_simple(name, S_DEF_USER); else if (!stat("all.config", &tmpstat)) - conf_read_simple("all.config"); + conf_read_simple("all.config", S_DEF_USER); break; default: break; diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 54ca1a786d25..ca693fcd023f 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -86,13 +86,13 @@ char *conf_get_default_confname(void) return name; } -int conf_read_simple(const char *name) +int conf_read_simple(const char *name, int def) { FILE *in = NULL; char line[1024]; char *p, *p2; struct symbol *sym; - int i; + int i, def_flags; if (name) { in = zconf_fopen(name); @@ -125,20 +125,21 @@ load: conf_warnings = 0; conf_unsaved = 0; + def_flags = SYMBOL_DEF << def; for_all_symbols(i, sym) { - sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; + sym->flags |= SYMBOL_CHANGED; + sym->flags &= ~(def_flags|SYMBOL_VALID); if (sym_is_choice(sym)) - sym->flags &= ~SYMBOL_NEW; - sym->flags &= ~SYMBOL_VALID; + sym->flags |= def_flags; switch (sym->type) { case S_INT: case S_HEX: case S_STRING: - if (sym->def[S_DEF_USER].val) - free(sym->def[S_DEF_USER].val); + if (sym->def[def].val) + free(sym->def[def].val); default: - sym->def[S_DEF_USER].val = NULL; - sym->def[S_DEF_USER].tri = no; + sym->def[def].val = NULL; + sym->def[def].tri = no; } } @@ -155,19 +156,26 @@ load: *p++ = 0; if (strncmp(p, "is not set", 10)) continue; - sym = sym_find(line + 9); - if (!sym) { - conf_warning("trying to assign nonexistent symbol %s", line + 9); - break; - } else if (!(sym->flags & SYMBOL_NEW)) { + if (def == S_DEF_USER) { + sym = sym_find(line + 9); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 9); + break; + } + } else { + sym = sym_lookup(line + 9, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_BOOLEAN; + } + if (sym->flags & def_flags) { conf_warning("trying to reassign symbol %s", sym->name); break; } switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - sym->def[S_DEF_USER].tri = no; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = no; + sym->flags |= def_flags; break; default: ; @@ -185,34 +193,48 @@ load: p2 = strchr(p, '\n'); if (p2) *p2 = 0; - sym = sym_find(line + 7); - if (!sym) { - conf_warning("trying to assign nonexistent symbol %s", line + 7); - break; - } else if (!(sym->flags & SYMBOL_NEW)) { + if (def == S_DEF_USER) { + sym = sym_find(line + 7); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 7); + break; + } + } else { + sym = sym_lookup(line + 7, 0); + if (sym->type == S_UNKNOWN) + sym->type = S_OTHER; + } + if (sym->flags & def_flags) { conf_warning("trying to reassign symbol %s", sym->name); break; } switch (sym->type) { case S_TRISTATE: if (p[0] == 'm') { - sym->def[S_DEF_USER].tri = mod; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = mod; + sym->flags |= def_flags; break; } case S_BOOLEAN: if (p[0] == 'y') { - sym->def[S_DEF_USER].tri = yes; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = yes; + sym->flags |= def_flags; break; } if (p[0] == 'n') { - sym->def[S_DEF_USER].tri = no; - sym->flags &= ~SYMBOL_NEW; + sym->def[def].tri = no; + sym->flags |= def_flags; break; } conf_warning("symbol value '%s' invalid for %s", p, sym->name); break; + case S_OTHER: + if (*p != '"') { + for (p2 = p; *p2 && !isspace(*p2); p2++) + ; + sym->type = S_STRING; + goto done; + } case S_STRING: if (*p++ != '"') break; @@ -229,9 +251,10 @@ load: } case S_INT: case S_HEX: + done: if (sym_string_valid(sym, p)) { - sym->def[S_DEF_USER].val = strdup(p); - sym->flags &= ~SYMBOL_NEW; + sym->def[def].val = strdup(p); + sym->flags |= def_flags; } else { conf_warning("symbol value '%s' invalid for %s", p, sym->name); continue; @@ -249,24 +272,24 @@ load: } if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - switch (sym->def[S_DEF_USER].tri) { + switch (sym->def[def].tri) { case no: break; case mod: - if (cs->def[S_DEF_USER].tri == yes) { + if (cs->def[def].tri == yes) { conf_warning("%s creates inconsistent choice state", sym->name); - cs->flags |= SYMBOL_NEW; + cs->flags &= ~def_flags; } break; case yes: - if (cs->def[S_DEF_USER].tri != no) { + if (cs->def[def].tri != no) { conf_warning("%s creates inconsistent choice state", sym->name); - cs->flags |= SYMBOL_NEW; + cs->flags &= ~def_flags; } else - cs->def[S_DEF_USER].val = sym; + cs->def[def].val = sym; break; } - cs->def[S_DEF_USER].tri = E_OR(cs->def[S_DEF_USER].tri, sym->def[S_DEF_USER].tri); + cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri); } } fclose(in); @@ -281,11 +304,11 @@ int conf_read(const char *name) struct symbol *sym; struct property *prop; struct expr *e; - int i; + int i, flags; sym_change_count = 0; - if (conf_read_simple(name)) + if (conf_read_simple(name, S_DEF_USER)) return 1; for_all_symbols(i, sym) { @@ -314,15 +337,13 @@ int conf_read(const char *name) sym_ok: if (sym_has_value(sym) && !sym_is_choice_value(sym)) { if (sym->visible == no) - sym->flags |= SYMBOL_NEW; + sym->flags &= ~SYMBOL_DEF_USER; switch (sym->type) { case S_STRING: case S_INT: case S_HEX: - if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val)) { - sym->flags |= SYMBOL_NEW; - sym->flags &= ~SYMBOL_VALID; - } + if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val)) + sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); default: break; } @@ -330,9 +351,11 @@ int conf_read(const char *name) if (!sym_is_choice(sym)) continue; prop = sym_get_choice_prop(sym); + flags = sym->flags; for (e = prop->expr; e; e = e->left.expr) if (e->right.sym->visible != no) - sym->flags |= e->right.sym->flags & SYMBOL_NEW; + flags &= e->right.sym->flags; + sym->flags |= flags & SYMBOL_DEF_USER; } sym_change_count += conf_warnings || conf_unsaved; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 043859d426d7..998cf4f656b8 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -92,10 +92,14 @@ struct symbol { #define SYMBOL_OPTIONAL 0x0100 #define SYMBOL_WRITE 0x0200 #define SYMBOL_CHANGED 0x0400 -#define SYMBOL_NEW 0x0800 #define SYMBOL_AUTO 0x1000 #define SYMBOL_CHECKED 0x2000 #define SYMBOL_WARNED 0x8000 +#define SYMBOL_DEF 0x10000 +#define SYMBOL_DEF_USER 0x10000 +#define SYMBOL_DEF2 0x20000 +#define SYMBOL_DEF3 0x40000 +#define SYMBOL_DEF4 0x80000 #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 257 diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 9cb3e6a47555..7b0d3a93d5c0 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -132,8 +132,6 @@ const char *dbg_print_flags(int val) strcat(buf, "write/"); if (val & SYMBOL_CHANGED) strcat(buf, "changed/"); - if (val & SYMBOL_NEW) - strcat(buf, "new/"); if (val & SYMBOL_AUTO) strcat(buf, "auto/"); @@ -1186,9 +1184,7 @@ static gchar **fill_row(struct menu *menu) row[COL_OPTION] = g_strdup_printf("%s %s", menu_get_prompt(menu), - sym ? (sym-> - flags & SYMBOL_NEW ? "(NEW)" : "") : - ""); + sym && sym_has_value(sym) ? "(NEW)" : ""); if (show_all && !menu_is_visible(menu)) row[COL_COLOR] = g_strdup("DarkGray"); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 527f60c99c50..52c296e0440e 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -137,7 +137,7 @@ static inline bool sym_is_optional(struct symbol *sym) static inline bool sym_has_value(struct symbol *sym) { - return sym->flags & SYMBOL_NEW ? false : true; + return sym->flags & SYMBOL_DEF_USER ? true : false; } #ifdef __cplusplus diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index bd0fb1dc1322..e195c455bfef 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -2,7 +2,7 @@ /* confdata.c */ P(conf_parse,void,(const char *name)); P(conf_read,int,(const char *name)); -P(conf_read_simple,int,(const char *name)); +P(conf_read_simple,int,(const char *name, int)); P(conf_write,int,(const char *name)); P(conf_write_autoconf,int,(void)); diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 4ea0050dcb16..78a60ba39e54 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -426,8 +426,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) if (oldval != val && !sym_tristate_within_range(sym, val)) return false; - if (sym->flags & SYMBOL_NEW) { - sym->flags &= ~SYMBOL_NEW; + if (!(sym->flags & SYMBOL_DEF_USER)) { + sym->flags |= SYMBOL_DEF_USER; sym_set_changed(sym); } /* @@ -440,11 +440,11 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) struct expr *e; cs->def[S_DEF_USER].val = sym; - cs->flags &= ~SYMBOL_NEW; + cs->flags |= SYMBOL_DEF_USER; prop = sym_get_choice_prop(cs); for (e = prop->expr; e; e = e->left.expr) { if (e->right.sym->visible != no) - e->right.sym->flags &= ~SYMBOL_NEW; + e->right.sym->flags |= SYMBOL_DEF_USER; } } @@ -591,8 +591,8 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) if (!sym_string_within_range(sym, newval)) return false; - if (sym->flags & SYMBOL_NEW) { - sym->flags &= ~SYMBOL_NEW; + if (!(sym->flags & SYMBOL_DEF_USER)) { + sym->flags |= SYMBOL_DEF_USER; sym_set_changed(sym); } @@ -679,7 +679,6 @@ struct symbol *sym_lookup(const char *name, int isconst) memset(symbol, 0, sizeof(*symbol)); symbol->name = new_name; symbol->type = S_UNKNOWN; - symbol->flags = SYMBOL_NEW; if (isconst) symbol->flags |= SYMBOL_CONST; -- cgit v1.2.3 From 2e3646e51b2d6415549b310655df63e7e0d7a080 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:42 -0700 Subject: kconfig: integrate split config into silentoldconfig Now that kconfig can load multiple configurations, it becomes simple to integrate the split config step, by simply comparing the new .config file with the old auto.conf (and then saving the new auto.conf). A nice side effect is that this saves a bit of disk space and cache, as no data needs to be read from or saved into the splitted config files anymore (e.g. include/config is now 648KB instead of 5.2MB). Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- Makefile | 11 +- arch/arm/Makefile | 2 +- arch/sh/Makefile | 4 +- arch/xtensa/Makefile | 2 +- scripts/basic/Makefile | 6 +- scripts/basic/split-include.c | 226 ------------------------------------------ scripts/kconfig/confdata.c | 121 +++++++++++++++++++++- scripts/kconfig/expr.h | 3 +- 8 files changed, 129 insertions(+), 246 deletions(-) delete mode 100644 scripts/basic/split-include.c (limited to 'scripts') diff --git a/Makefile b/Makefile index b1610562a65f..4b996c8fb70a 100644 --- a/Makefile +++ b/Makefile @@ -418,7 +418,7 @@ ifeq ($(KBUILD_EXTMOD),) # Carefully list dependencies so we do not try to build scripts twice # in parrallel PHONY += scripts -scripts: scripts_basic include/config/MARKER +scripts: scripts_basic include/config/auto.conf $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -787,7 +787,7 @@ endif prepare2: prepare3 outputmakefile prepare1: prepare2 include/linux/version.h include/asm \ - include/config/MARKER + include/config/auto.conf ifneq ($(KBUILD_MODULES),) $(Q)mkdir -p $(MODVERDIR) $(Q)rm -f $(MODVERDIR)/* @@ -815,13 +815,6 @@ include/asm: $(Q)if [ ! -d include ]; then mkdir -p include; fi; @ln -fsn asm-$(ARCH) $@ -# Split autoconf.h into include/linux/config/* - -include/config/MARKER: scripts/basic/split-include include/config/auto.conf - @echo ' SPLIT include/linux/autoconf.h -> include/config/*' - @scripts/basic/split-include include/linux/autoconf.h include/config - @touch $@ - # Generate some files # --------------------------------------------------------------------------- diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6f8e84c1c1f2..9791d870ae71 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -175,7 +175,7 @@ boot := arch/arm/boot # them changed. We use .arch to indicate when they were updated # last, otherwise make uses the target directory mtime. -include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/MARKER +include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf @echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)' ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm-arm diff --git a/arch/sh/Makefile b/arch/sh/Makefile index c72e17a96eed..e467a450662b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -147,7 +147,7 @@ endif # them changed. We use .arch and .mach to indicate when they were # updated last, otherwise make uses the target directory mtime. -include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER +include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu @@ -157,7 +157,7 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER # don't, just reference the parent directory so the semantics are # kept roughly the same. -include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER +include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf @echo -n ' SYMLINK include/asm-sh/mach -> ' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 98fac8489aed..3a3a4c66ef87 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -71,7 +71,7 @@ archprepare: $(archinc)/.platform # Update machine cpu and platform symlinks if something which affects # them changed. -$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER +$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/auto.conf @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' $(Q)mkdir -p $(archinc) $(Q)mkdir -p $(archinc)/xtensa diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index f22e94c3a2d1..2f60070f9733 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -1,17 +1,15 @@ ### # Makefile.basic list the most basic programs used during the build process. # The programs listed herein is what is needed to do the basic stuff, -# such as splitting .config and fix dependency file. +# such as fix dependency file. # This initial step is needed to avoid files to be recompiled # when kernel configuration changes (which is what happens when # .config is included by main Makefile. # --------------------------------------------------------------------------- # fixdep: Used to generate dependency information during build process -# split-include: Divide all config symbols up in a number of files in -# include/config/... # docproc: Used in Documentation/docbook -hostprogs-y := fixdep split-include docproc +hostprogs-y := fixdep docproc always := $(hostprogs-y) # fixdep is needed to compile other host programs diff --git a/scripts/basic/split-include.c b/scripts/basic/split-include.c deleted file mode 100644 index 459c45276cb1..000000000000 --- a/scripts/basic/split-include.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * split-include.c - * - * Copyright abandoned, Michael Chastain, . - * This is a C version of syncdep.pl by Werner Almesberger. - * - * This program takes autoconf.h as input and outputs a directory full - * of one-line include files, merging onto the old values. - * - * Think of the configuration options as key-value pairs. Then there - * are five cases: - * - * key old value new value action - * - * KEY-1 VALUE-1 VALUE-1 leave file alone - * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file - * KEY-3 - VALUE-3 write VALUE-3 into file - * KEY-4 VALUE-4 - write an empty file - * KEY-5 (empty) - leave old empty file alone - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define ERROR_EXIT(strExit) \ - { \ - const int errnoSave = errno; \ - fprintf(stderr, "%s: ", str_my_name); \ - errno = errnoSave; \ - perror((strExit)); \ - exit(1); \ - } - - - -int main(int argc, const char * argv []) -{ - const char * str_my_name; - const char * str_file_autoconf; - const char * str_dir_config; - - FILE * fp_config; - FILE * fp_target; - FILE * fp_find; - - int buffer_size; - - char * line; - char * old_line; - char * list_target; - char * ptarget; - - struct stat stat_buf; - - /* Check arg count. */ - if (argc != 3) - { - fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]); - exit(1); - } - - str_my_name = argv[0]; - str_file_autoconf = argv[1]; - str_dir_config = argv[2]; - - /* Find a buffer size. */ - if (stat(str_file_autoconf, &stat_buf) != 0) - ERROR_EXIT(str_file_autoconf); - buffer_size = 2 * stat_buf.st_size + 4096; - - /* Allocate buffers. */ - if ( (line = malloc(buffer_size)) == NULL - || (old_line = malloc(buffer_size)) == NULL - || (list_target = malloc(buffer_size)) == NULL ) - ERROR_EXIT(str_file_autoconf); - - /* Open autoconfig file. */ - if ((fp_config = fopen(str_file_autoconf, "r")) == NULL) - ERROR_EXIT(str_file_autoconf); - - /* Make output directory if needed. */ - if (stat(str_dir_config, &stat_buf) != 0) - { - if (mkdir(str_dir_config, 0755) != 0) - ERROR_EXIT(str_dir_config); - } - - /* Change to output directory. */ - if (chdir(str_dir_config) != 0) - ERROR_EXIT(str_dir_config); - - /* Put initial separator into target list. */ - ptarget = list_target; - *ptarget++ = '\n'; - - /* Read config lines. */ - while (fgets(line, buffer_size, fp_config)) - { - const char * str_config; - int is_same; - int itarget; - - if (line[0] != '#') - continue; - if ((str_config = strstr(line, "CONFIG_")) == NULL) - continue; - - /* Make the output file name. */ - str_config += sizeof("CONFIG_") - 1; - for (itarget = 0; !isspace(str_config[itarget]); itarget++) - { - int c = (unsigned char) str_config[itarget]; - if (isupper(c)) c = tolower(c); - if (c == '_') c = '/'; - ptarget[itarget] = c; - } - ptarget[itarget++] = '.'; - ptarget[itarget++] = 'h'; - ptarget[itarget++] = '\0'; - - /* Check for existing file. */ - is_same = 0; - if ((fp_target = fopen(ptarget, "r")) != NULL) - { - fgets(old_line, buffer_size, fp_target); - if (fclose(fp_target) != 0) - ERROR_EXIT(ptarget); - if (!strcmp(line, old_line)) - is_same = 1; - } - - if (!is_same) - { - /* Auto-create directories. */ - int islash; - for (islash = 0; islash < itarget; islash++) - { - if (ptarget[islash] == '/') - { - ptarget[islash] = '\0'; - if (stat(ptarget, &stat_buf) != 0 - && mkdir(ptarget, 0755) != 0) - ERROR_EXIT( ptarget ); - ptarget[islash] = '/'; - } - } - - /* Write the file. */ - if ((fp_target = fopen(ptarget, "w" )) == NULL) - ERROR_EXIT(ptarget); - fputs(line, fp_target); - if (ferror(fp_target) || fclose(fp_target) != 0) - ERROR_EXIT(ptarget); - } - - /* Update target list */ - ptarget += itarget; - *(ptarget-1) = '\n'; - } - - /* - * Close autoconfig file. - * Terminate the target list. - */ - if (fclose(fp_config) != 0) - ERROR_EXIT(str_file_autoconf); - *ptarget = '\0'; - - /* - * Fix up existing files which have no new value. - * This is Case 4 and Case 5. - * - * I re-read the tree and filter it against list_target. - * This is crude. But it avoids data copies. Also, list_target - * is compact and contiguous, so it easily fits into cache. - * - * Notice that list_target contains strings separated by \n, - * with a \n before the first string and after the last. - * fgets gives the incoming names a terminating \n. - * So by having an initial \n, strstr will find exact matches. - */ - - fp_find = popen("find * -type f -name \"*.h\" -print", "r"); - if (fp_find == 0) - ERROR_EXIT( "find" ); - - line[0] = '\n'; - while (fgets(line+1, buffer_size, fp_find)) - { - if (strstr(list_target, line) == NULL) - { - /* - * This is an old file with no CONFIG_* flag in autoconf.h. - */ - - /* First strip the \n. */ - line[strlen(line)-1] = '\0'; - - /* Grab size. */ - if (stat(line+1, &stat_buf) != 0) - ERROR_EXIT(line); - - /* If file is not empty, make it empty and give it a fresh date. */ - if (stat_buf.st_size != 0) - { - if ((fp_target = fopen(line+1, "w")) == NULL) - ERROR_EXIT(line); - if (fclose(fp_target) != 0) - ERROR_EXIT(line); - } - } - } - - if (pclose(fp_find) != 0) - ERROR_EXIT("find"); - - return 0; -} diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index ca693fcd023f..e28cd0c2ca08 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -520,6 +521,119 @@ int conf_write(const char *name) return 0; } +int conf_split_config(void) +{ + char *name, path[128]; + char *s, *d, c; + struct symbol *sym; + struct stat sb; + int res, i, fd; + + name = getenv("KCONFIG_AUTOCONFIG"); + if (!name) + name = "include/config/auto.conf"; + conf_read_simple(name, S_DEF_AUTO); + + if (chdir("include/config")) + return 1; + + res = 0; + for_all_symbols(i, sym) { + sym_calc_value(sym); + if ((sym->flags & SYMBOL_AUTO) || !sym->name) + continue; + if (sym->flags & SYMBOL_WRITE) { + if (sym->flags & SYMBOL_DEF_AUTO) { + /* + * symbol has old and new value, + * so compare them... + */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_get_tristate_value(sym) == + sym->def[S_DEF_AUTO].tri) + continue; + break; + case S_STRING: + case S_HEX: + case S_INT: + if (!strcmp(sym_get_string_value(sym), + sym->def[S_DEF_AUTO].val)) + continue; + break; + default: + break; + } + } else { + /* + * If there is no old value, only 'no' (unset) + * is allowed as new value. + */ + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + if (sym_get_tristate_value(sym) == no) + continue; + break; + default: + break; + } + } + } else if (!(sym->flags & SYMBOL_DEF_AUTO)) + /* There is neither an old nor a new value. */ + continue; + /* else + * There is an old value, but no new value ('no' (unset) + * isn't saved in auto.conf, so the old value is always + * different from 'no'). + */ + + /* Replace all '_' and append ".h" */ + s = sym->name; + d = path; + while ((c = *s++)) { + c = tolower(c); + *d++ = (c == '_') ? '/' : c; + } + strcpy(d, ".h"); + + /* Assume directory path already exists. */ + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + if (errno != ENOENT) { + res = 1; + break; + } + /* + * Create directory components, + * unless they exist already. + */ + d = path; + while ((d = strchr(d, '/'))) { + *d = 0; + if (stat(path, &sb) && mkdir(path, 0755)) { + res = 1; + goto out; + } + *d++ = '/'; + } + /* Try it again. */ + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + res = 1; + break; + } + } + close(fd); + } +out: + if (chdir("../..")) + return 1; + + return res; +} + int conf_write_autoconf(void) { struct symbol *sym; @@ -529,8 +643,13 @@ int conf_write_autoconf(void) time_t now; int i, l; + sym_clear_all_valid(); + file_write_dep("include/config/auto.conf.cmd"); + if (conf_split_config()) + return 1; + out = fopen(".tmpconfig", "w"); if (!out) return 1; @@ -558,8 +677,6 @@ int conf_write_autoconf(void) "#define AUTOCONF_INCLUDED\n", sym_get_string_value(sym), ctime(&now)); - sym_clear_all_valid(); - for_all_symbols(i, sym) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE) || !sym->name) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 998cf4f656b8..ffd42c7007ee 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -65,6 +65,7 @@ enum symbol_type { enum { S_DEF_USER, /* main user value */ + S_DEF_AUTO, }; struct symbol { @@ -97,7 +98,7 @@ struct symbol { #define SYMBOL_WARNED 0x8000 #define SYMBOL_DEF 0x10000 #define SYMBOL_DEF_USER 0x10000 -#define SYMBOL_DEF2 0x20000 +#define SYMBOL_DEF_AUTO 0x20000 #define SYMBOL_DEF3 0x40000 #define SYMBOL_DEF4 0x80000 -- cgit v1.2.3 From f6a88aa86027bdecfc74ef7c6bf6c68233e86bb3 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:44 -0700 Subject: kconfig: add symbol option config syntax This adds the general framework to the parser to define options for config symbols with a syntax like: config FOO option bar[="arg"] Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/lex.zconf.c_shipped | 91 ++-- scripts/kconfig/lkc.h | 5 + scripts/kconfig/menu.c | 4 + scripts/kconfig/zconf.gperf | 3 + scripts/kconfig/zconf.hash.c_shipped | 181 +++---- scripts/kconfig/zconf.tab.c_shipped | 920 +++++++++++++++++++++-------------- scripts/kconfig/zconf.y | 23 + 7 files changed, 735 insertions(+), 492 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped index 24e3c8cbb7ac..800f8c71c407 100644 --- a/scripts/kconfig/lex.zconf.c_shipped +++ b/scripts/kconfig/lex.zconf.c_shipped @@ -8,7 +8,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 31 +#define YY_FLEX_SUBMINOR_VERSION 33 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -30,7 +30,15 @@ /* C99 systems have . Non-C99 systems may or may not. */ -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; @@ -134,6 +142,10 @@ typedef unsigned int flex_uint32_t; #define YY_BUF_SIZE 16384 #endif +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; @@ -267,7 +279,7 @@ int zconfleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ +static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow zconfwrap()'s to do buffer switches @@ -820,6 +832,8 @@ void alloc_string(const char *str, int size) #define YY_EXTRA_TYPE void * #endif +static int yy_init_globals (void ); + /* Macros after this point can all be overridden by user definitions in * section 1. */ @@ -942,9 +956,9 @@ YY_DECL int str = 0; int ts, i; - if ( (yy_init) ) + if ( !(yy_init) ) { - (yy_init) = 0; + (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; @@ -1452,7 +1466,7 @@ static int yy_get_next_buffer (void) else { - size_t num_to_read = + int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) @@ -1969,16 +1983,16 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to zconflex() will * scan from a @e copy of @a str. - * @param yy_str a NUL-terminated string to scan + * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * zconf_scan_bytes() instead. */ -YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str ) +YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr ) { - return zconf_scan_bytes(yy_str,strlen(yy_str) ); + return zconf_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to zconflex() will @@ -1988,7 +2002,7 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str ) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len ) +YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; @@ -1996,15 +2010,15 @@ YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len ) int i; /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; + n = _yybytes_len + 2; buf = (char *) zconfalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = zconf_scan_buffer(buf,n ); if ( ! b ) @@ -2125,6 +2139,34 @@ void zconfset_debug (int bdebug ) zconf_flex_debug = bdebug ; } +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from zconflex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + zconfin = stdin; + zconfout = stdout; +#else + zconfin = (FILE *) 0; + zconfout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * zconflex_init() + */ + return 0; +} + /* zconflex_destroy is for both reentrant and non-reentrant scanners. */ int zconflex_destroy (void) { @@ -2140,6 +2182,10 @@ int zconflex_destroy (void) zconffree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * zconflex() is called, initialization will occur. */ + yy_init_globals( ); + return 0; } @@ -2151,7 +2197,7 @@ int zconflex_destroy (void) static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; - for ( i = 0; i < n; ++i ) + for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif @@ -2160,7 +2206,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) static int yy_flex_strlen (yyconst char * s ) { register int n; - for ( n = 0; s[n]; ++n ) + for ( n = 0; s[n]; ++n ) ; return n; @@ -2191,19 +2237,6 @@ void zconffree (void * ptr ) #define YYTABLES_NAME "yytables" -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef yytext_ptr -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - void zconf_starthelp(void) { new_string(); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 52c296e0440e..8e89d342889e 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -40,6 +40,10 @@ extern "C" { #define TF_COMMAND 0x0001 #define TF_PARAM 0x0002 +#define TF_OPTION 0x0004 + +#define T_OPT_MODULES 1 +#define T_OPT_DEFCONFIG_LIST 2 struct kconf_id { int name; @@ -78,6 +82,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); +void menu_add_option(int token, char *arg); void menu_finalize(struct menu *parent); void menu_set_type(int type); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 0fce20cb7f3c..151ef2168a2c 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -152,6 +152,10 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); } +void menu_add_option(int token, char *arg) +{ +} + static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf index b03220600b3a..9b44c80dd899 100644 --- a/scripts/kconfig/zconf.gperf +++ b/scripts/kconfig/zconf.gperf @@ -39,5 +39,8 @@ string, T_TYPE, TF_COMMAND, S_STRING select, T_SELECT, TF_COMMAND enable, T_SELECT, TF_COMMAND range, T_RANGE, TF_COMMAND +option, T_OPTION, TF_COMMAND on, T_ON, TF_PARAM +modules, T_OPT_MODULES, TF_OPTION +defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION %% diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped index 345f0fc07ca3..47c8b5babf34 100644 --- a/scripts/kconfig/zconf.hash.c_shipped +++ b/scripts/kconfig/zconf.hash.c_shipped @@ -53,10 +53,10 @@ kconf_id_hash (register const char *str, register unsigned int len) 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 25, 10, 15, - 0, 0, 5, 47, 0, 0, 47, 47, 0, 10, - 0, 20, 20, 20, 5, 0, 0, 20, 47, 47, - 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 25, 30, 15, + 0, 15, 0, 47, 5, 15, 47, 47, 30, 20, + 5, 0, 25, 15, 0, 0, 10, 35, 47, 47, + 5, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, @@ -88,69 +88,75 @@ kconf_id_hash (register const char *str, register unsigned int len) struct kconf_id_strings_t { - char kconf_id_strings_str2[sizeof("if")]; - char kconf_id_strings_str3[sizeof("int")]; - char kconf_id_strings_str4[sizeof("help")]; - char kconf_id_strings_str5[sizeof("endif")]; - char kconf_id_strings_str6[sizeof("select")]; - char kconf_id_strings_str7[sizeof("endmenu")]; - char kconf_id_strings_str8[sizeof("tristate")]; - char kconf_id_strings_str9[sizeof("endchoice")]; + char kconf_id_strings_str2[sizeof("on")]; + char kconf_id_strings_str6[sizeof("string")]; + char kconf_id_strings_str7[sizeof("default")]; + char kconf_id_strings_str8[sizeof("def_bool")]; char kconf_id_strings_str10[sizeof("range")]; - char kconf_id_strings_str11[sizeof("string")]; - char kconf_id_strings_str12[sizeof("default")]; - char kconf_id_strings_str13[sizeof("def_bool")]; - char kconf_id_strings_str14[sizeof("menu")]; - char kconf_id_strings_str16[sizeof("def_boolean")]; - char kconf_id_strings_str17[sizeof("def_tristate")]; - char kconf_id_strings_str18[sizeof("mainmenu")]; - char kconf_id_strings_str20[sizeof("menuconfig")]; - char kconf_id_strings_str21[sizeof("config")]; - char kconf_id_strings_str22[sizeof("on")]; - char kconf_id_strings_str23[sizeof("hex")]; - char kconf_id_strings_str26[sizeof("source")]; - char kconf_id_strings_str27[sizeof("depends")]; - char kconf_id_strings_str28[sizeof("optional")]; - char kconf_id_strings_str31[sizeof("enable")]; - char kconf_id_strings_str32[sizeof("comment")]; - char kconf_id_strings_str33[sizeof("requires")]; + char kconf_id_strings_str11[sizeof("def_boolean")]; + char kconf_id_strings_str12[sizeof("def_tristate")]; + char kconf_id_strings_str13[sizeof("hex")]; + char kconf_id_strings_str14[sizeof("defconfig_list")]; + char kconf_id_strings_str16[sizeof("option")]; + char kconf_id_strings_str17[sizeof("if")]; + char kconf_id_strings_str18[sizeof("optional")]; + char kconf_id_strings_str20[sizeof("endif")]; + char kconf_id_strings_str21[sizeof("choice")]; + char kconf_id_strings_str22[sizeof("endmenu")]; + char kconf_id_strings_str23[sizeof("requires")]; + char kconf_id_strings_str24[sizeof("endchoice")]; + char kconf_id_strings_str26[sizeof("config")]; + char kconf_id_strings_str27[sizeof("modules")]; + char kconf_id_strings_str28[sizeof("int")]; + char kconf_id_strings_str29[sizeof("menu")]; + char kconf_id_strings_str31[sizeof("prompt")]; + char kconf_id_strings_str32[sizeof("depends")]; + char kconf_id_strings_str33[sizeof("tristate")]; char kconf_id_strings_str34[sizeof("bool")]; + char kconf_id_strings_str35[sizeof("menuconfig")]; + char kconf_id_strings_str36[sizeof("select")]; char kconf_id_strings_str37[sizeof("boolean")]; - char kconf_id_strings_str41[sizeof("choice")]; - char kconf_id_strings_str46[sizeof("prompt")]; + char kconf_id_strings_str39[sizeof("help")]; + char kconf_id_strings_str41[sizeof("source")]; + char kconf_id_strings_str42[sizeof("comment")]; + char kconf_id_strings_str43[sizeof("mainmenu")]; + char kconf_id_strings_str46[sizeof("enable")]; }; static struct kconf_id_strings_t kconf_id_strings_contents = { - "if", - "int", - "help", - "endif", - "select", - "endmenu", - "tristate", - "endchoice", - "range", + "on", "string", "default", "def_bool", - "menu", + "range", "def_boolean", "def_tristate", - "mainmenu", - "menuconfig", - "config", - "on", "hex", - "source", - "depends", + "defconfig_list", + "option", + "if", "optional", - "enable", - "comment", + "endif", + "choice", + "endmenu", "requires", + "endchoice", + "config", + "modules", + "int", + "menu", + "prompt", + "depends", + "tristate", "bool", + "menuconfig", + "select", "boolean", - "choice", - "prompt" + "help", + "source", + "comment", + "mainmenu", + "enable" }; #define kconf_id_strings ((const char *) &kconf_id_strings_contents) #ifdef __GNUC__ @@ -161,9 +167,9 @@ kconf_id_lookup (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 30, + TOTAL_KEYWORDS = 33, MIN_WORD_LENGTH = 2, - MAX_WORD_LENGTH = 12, + MAX_WORD_LENGTH = 14, MIN_HASH_VALUE = 2, MAX_HASH_VALUE = 46 }; @@ -171,43 +177,48 @@ kconf_id_lookup (register const char *str, register unsigned int len) static struct kconf_id wordlist[] = { {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM}, + {-1}, {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_TYPE, TF_COMMAND, S_STRING}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, + {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_TYPE, TF_COMMAND, S_HEX}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_OPTION, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_IF, TF_COMMAND|TF_PARAM}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX}, - {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND}, - {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_ENDIF, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CHOICE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_REQUIRES, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24, T_ENDCHOICE, TF_COMMAND}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_CONFIG, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_INT}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_PROMPT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_DEPENDS, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_TRISTATE}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_SELECT, TF_COMMAND}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN}, - {-1}, {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND}, - {-1}, {-1}, {-1}, {-1}, - {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, TF_COMMAND} + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_HELP, TF_COMMAND}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_COMMENT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_MAINMENU, TF_COMMAND}, + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index ea7755da82f5..137426e507ec 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -1,7 +1,7 @@ -/* A Bison parser, made by GNU Bison 2.0. */ +/* A Bison parser, made by GNU Bison 2.1. */ /* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. @@ -36,6 +36,9 @@ /* Identify Bison output. */ #define YYBISON 1 +/* Bison version. */ +#define YYBISON_VERSION "2.1" + /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -82,19 +85,21 @@ T_DEFAULT = 276, T_SELECT = 277, T_RANGE = 278, - T_ON = 279, - T_WORD = 280, - T_WORD_QUOTE = 281, - T_UNEQUAL = 282, - T_CLOSE_PAREN = 283, - T_OPEN_PAREN = 284, - T_EOL = 285, - T_OR = 286, - T_AND = 287, - T_EQUAL = 288, - T_NOT = 289 + T_OPTION = 279, + T_ON = 280, + T_WORD = 281, + T_WORD_QUOTE = 282, + T_UNEQUAL = 283, + T_CLOSE_PAREN = 284, + T_OPEN_PAREN = 285, + T_EOL = 286, + T_OR = 287, + T_AND = 288, + T_EQUAL = 289, + T_NOT = 290 }; #endif +/* Tokens. */ #define T_MAINMENU 258 #define T_MENU 259 #define T_ENDMENU 260 @@ -116,17 +121,18 @@ #define T_DEFAULT 276 #define T_SELECT 277 #define T_RANGE 278 -#define T_ON 279 -#define T_WORD 280 -#define T_WORD_QUOTE 281 -#define T_UNEQUAL 282 -#define T_CLOSE_PAREN 283 -#define T_OPEN_PAREN 284 -#define T_EOL 285 -#define T_OR 286 -#define T_AND 287 -#define T_EQUAL 288 -#define T_NOT 289 +#define T_OPTION 279 +#define T_ON 280 +#define T_WORD 281 +#define T_WORD_QUOTE 282 +#define T_UNEQUAL 283 +#define T_CLOSE_PAREN 284 +#define T_OPEN_PAREN 285 +#define T_EOL 286 +#define T_OR 287 +#define T_AND 288 +#define T_EQUAL 289 +#define T_NOT 290 @@ -187,6 +193,11 @@ static struct menu *current_menu, *current_entry; # define YYERROR_VERBOSE 0 #endif +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) typedef union YYSTYPE { @@ -197,7 +208,7 @@ typedef union YYSTYPE { struct menu *menu; struct kconf_id *id; } YYSTYPE; -/* Line 190 of yacc.c. */ +/* Line 196 of yacc.c. */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -209,17 +220,36 @@ typedef union YYSTYPE { /* Copy the second part of user declarations. */ -/* Line 213 of yacc.c. */ +/* Line 219 of yacc.c. */ -#if ! defined (yyoverflow) || YYERROR_VERBOSE +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif -# ifndef YYFREE -# define YYFREE free +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif # endif -# ifndef YYMALLOC -# define YYMALLOC malloc +# ifndef YY_ +# define YY_(msgid) msgid # endif +#endif + +#if ! defined (yyoverflow) || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -229,6 +259,10 @@ typedef union YYSTYPE { # define YYSTACK_ALLOC __builtin_alloca # else # define YYSTACK_ALLOC alloca +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYINCLUDED_STDLIB_H +# endif # endif # endif # endif @@ -236,13 +270,39 @@ typedef union YYSTYPE { # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ # endif +# else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) +# endif +# ifdef __cplusplus +extern "C" { +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ + && (defined (__STDC__) || defined (__cplusplus))) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ + && (defined (__STDC__) || defined (__cplusplus))) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifdef __cplusplus +} +# endif # endif #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ @@ -277,7 +337,7 @@ union yyalloc # define YYCOPY(To, From, Count) \ do \ { \ - register YYSIZE_T yyi; \ + YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ @@ -312,22 +372,22 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 264 +#define YYLAST 275 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 35 +#define YYNTOKENS 36 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 42 +#define YYNNTS 45 /* YYNRULES -- Number of rules. */ -#define YYNRULES 104 +#define YYNRULES 110 /* YYNRULES -- Number of states. */ -#define YYNSTATES 175 +#define YYNSTATES 183 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 289 +#define YYMAXUTOK 290 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ @@ -361,7 +421,8 @@ static const unsigned char yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -372,72 +433,75 @@ static const unsigned short int yyprhs[] = 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, - 81, 84, 85, 88, 91, 94, 97, 100, 104, 109, - 114, 119, 125, 128, 131, 133, 137, 138, 141, 144, - 147, 150, 153, 158, 162, 165, 170, 171, 174, 178, - 180, 184, 185, 188, 191, 194, 198, 201, 203, 207, - 208, 211, 214, 217, 221, 225, 228, 231, 234, 235, - 238, 241, 244, 249, 253, 257, 258, 261, 263, 265, - 268, 271, 274, 276, 279, 280, 283, 285, 289, 293, - 297, 300, 304, 308, 310 + 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, + 112, 117, 122, 128, 132, 133, 137, 138, 141, 144, + 147, 149, 153, 154, 157, 160, 163, 166, 169, 174, + 178, 181, 186, 187, 190, 194, 196, 200, 201, 204, + 207, 210, 214, 217, 219, 223, 224, 227, 230, 233, + 237, 241, 244, 247, 250, 251, 254, 257, 260, 265, + 269, 273, 274, 277, 279, 281, 284, 287, 290, 292, + 295, 296, 299, 301, 305, 309, 313, 316, 320, 324, + 326 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yysigned_char yyrhs[] = { - 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, - 50, -1, 37, 61, -1, 37, 3, 71, 73, -1, - 37, 72, -1, 37, 25, 1, 30, -1, 37, 38, - 1, 30, -1, 37, 1, 30, -1, 16, -1, 19, + 37, 0, -1, 38, -1, -1, 38, 40, -1, 38, + 54, -1, 38, 65, -1, 38, 3, 75, 77, -1, + 38, 76, -1, 38, 26, 1, 31, -1, 38, 39, + 1, 31, -1, 38, 1, 31, -1, 16, -1, 19, -1, 20, -1, 22, -1, 18, -1, 23, -1, 21, - -1, 30, -1, 56, -1, 65, -1, 42, -1, 44, - -1, 63, -1, 25, 1, 30, -1, 1, 30, -1, - 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, - -1, 43, 45, -1, -1, 45, 46, -1, 45, 69, - -1, 45, 67, -1, 45, 40, -1, 45, 30, -1, - 20, 70, 30, -1, 19, 71, 74, 30, -1, 21, - 75, 74, 30, -1, 22, 25, 74, 30, -1, 23, - 76, 76, 74, 30, -1, 7, 30, -1, 47, 51, - -1, 72, -1, 48, 53, 49, -1, -1, 51, 52, - -1, 51, 69, -1, 51, 67, -1, 51, 30, -1, - 51, 40, -1, 19, 71, 74, 30, -1, 20, 70, - 30, -1, 18, 30, -1, 21, 25, 74, 30, -1, - -1, 53, 39, -1, 14, 75, 73, -1, 72, -1, - 54, 57, 55, -1, -1, 57, 39, -1, 57, 61, - -1, 57, 50, -1, 4, 71, 30, -1, 58, 68, - -1, 72, -1, 59, 62, 60, -1, -1, 62, 39, - -1, 62, 61, -1, 62, 50, -1, 6, 71, 30, - -1, 9, 71, 30, -1, 64, 68, -1, 12, 30, - -1, 66, 13, -1, -1, 68, 69, -1, 68, 30, - -1, 68, 40, -1, 16, 24, 75, 30, -1, 16, - 75, 30, -1, 17, 75, 30, -1, -1, 71, 74, - -1, 25, -1, 26, -1, 5, 30, -1, 8, 30, - -1, 15, 30, -1, 30, -1, 73, 30, -1, -1, - 14, 75, -1, 76, -1, 76, 33, 76, -1, 76, - 27, 76, -1, 29, 75, 28, -1, 34, 75, -1, - 75, 31, 75, -1, 75, 32, 75, -1, 25, -1, - 26, -1 + -1, 31, -1, 60, -1, 69, -1, 43, -1, 45, + -1, 67, -1, 26, 1, 31, -1, 1, 31, -1, + 10, 26, 31, -1, 42, 46, -1, 11, 26, 31, + -1, 44, 46, -1, -1, 46, 47, -1, 46, 48, + -1, 46, 73, -1, 46, 71, -1, 46, 41, -1, + 46, 31, -1, 20, 74, 31, -1, 19, 75, 78, + 31, -1, 21, 79, 78, 31, -1, 22, 26, 78, + 31, -1, 23, 80, 80, 78, 31, -1, 24, 49, + 31, -1, -1, 49, 26, 50, -1, -1, 34, 75, + -1, 7, 31, -1, 51, 55, -1, 76, -1, 52, + 57, 53, -1, -1, 55, 56, -1, 55, 73, -1, + 55, 71, -1, 55, 31, -1, 55, 41, -1, 19, + 75, 78, 31, -1, 20, 74, 31, -1, 18, 31, + -1, 21, 26, 78, 31, -1, -1, 57, 40, -1, + 14, 79, 77, -1, 76, -1, 58, 61, 59, -1, + -1, 61, 40, -1, 61, 65, -1, 61, 54, -1, + 4, 75, 31, -1, 62, 72, -1, 76, -1, 63, + 66, 64, -1, -1, 66, 40, -1, 66, 65, -1, + 66, 54, -1, 6, 75, 31, -1, 9, 75, 31, + -1, 68, 72, -1, 12, 31, -1, 70, 13, -1, + -1, 72, 73, -1, 72, 31, -1, 72, 41, -1, + 16, 25, 79, 31, -1, 16, 79, 31, -1, 17, + 79, 31, -1, -1, 75, 78, -1, 26, -1, 27, + -1, 5, 31, -1, 8, 31, -1, 15, 31, -1, + 31, -1, 77, 31, -1, -1, 14, 79, -1, 80, + -1, 80, 34, 80, -1, 80, 28, 80, -1, 30, + 79, 29, -1, 35, 79, -1, 79, 32, 79, -1, + 79, 33, 79, -1, 26, -1, 27, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short int yyrline[] = { - 0, 103, 103, 105, 107, 108, 109, 110, 111, 112, - 113, 117, 121, 121, 121, 121, 121, 121, 121, 125, - 126, 127, 128, 129, 130, 134, 135, 141, 149, 155, - 163, 173, 175, 176, 177, 178, 179, 182, 190, 196, - 206, 212, 220, 229, 234, 242, 245, 247, 248, 249, - 250, 251, 254, 260, 271, 277, 287, 289, 294, 302, - 310, 313, 315, 316, 317, 322, 329, 334, 342, 345, - 347, 348, 349, 352, 360, 367, 374, 380, 387, 389, - 390, 391, 394, 399, 404, 412, 414, 419, 420, 423, - 424, 425, 429, 430, 433, 434, 437, 438, 439, 440, - 441, 442, 443, 446, 447 + 0, 105, 105, 107, 109, 110, 111, 112, 113, 114, + 115, 119, 123, 123, 123, 123, 123, 123, 123, 127, + 128, 129, 130, 131, 132, 136, 137, 143, 151, 157, + 165, 175, 177, 178, 179, 180, 181, 182, 185, 193, + 199, 209, 215, 221, 224, 226, 237, 238, 243, 252, + 257, 265, 268, 270, 271, 272, 273, 274, 277, 283, + 294, 300, 310, 312, 317, 325, 333, 336, 338, 339, + 340, 345, 352, 357, 365, 368, 370, 371, 372, 375, + 383, 390, 397, 403, 410, 412, 413, 414, 417, 422, + 427, 435, 437, 442, 443, 446, 447, 448, 452, 453, + 456, 457, 460, 461, 462, 463, 464, 465, 466, 469, + 470 }; #endif -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { @@ -445,17 +509,18 @@ static const char *const yytname[] = "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", - "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", - "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", - "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", - "option_error", "config_entry_start", "config_stmt", + "T_SELECT", "T_RANGE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", + "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", + "T_EQUAL", "T_NOT", "$accept", "input", "stmt_list", "option_name", + "common_stmt", "option_error", "config_entry_start", "config_stmt", "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", - "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", - "choice_option_list", "choice_option", "choice_block", "if_entry", - "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end", - "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt", - "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", - "prompt", "end", "nl", "if_expr", "expr", "symbol", 0 + "config_option", "symbol_option", "symbol_option_list", + "symbol_option_arg", "choice", "choice_entry", "choice_end", + "choice_stmt", "choice_option_list", "choice_option", "choice_block", + "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", + "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", + "comment_stmt", "help_start", "help", "depends_list", "depends", + "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 0 }; #endif @@ -467,24 +532,25 @@ static const unsigned short int yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289 + 285, 286, 287, 288, 289, 290 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { - 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, - 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, - 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, - 46, 46, 47, 48, 49, 50, 51, 51, 51, 51, - 51, 51, 52, 52, 52, 52, 53, 53, 54, 55, - 56, 57, 57, 57, 57, 58, 59, 60, 61, 62, - 62, 62, 62, 63, 64, 65, 66, 67, 68, 68, - 68, 68, 69, 69, 69, 70, 70, 71, 71, 72, - 72, 72, 73, 73, 74, 74, 75, 75, 75, 75, - 75, 75, 75, 76, 76 + 0, 36, 37, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 39, 39, 39, 39, 39, 39, 39, 40, + 40, 40, 40, 40, 40, 41, 41, 42, 43, 44, + 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, + 47, 47, 47, 48, 49, 49, 50, 50, 51, 52, + 53, 54, 55, 55, 55, 55, 55, 55, 56, 56, + 56, 56, 57, 57, 58, 59, 60, 61, 61, 61, + 61, 62, 63, 64, 65, 66, 66, 66, 66, 67, + 68, 69, 70, 71, 72, 72, 72, 72, 73, 73, + 73, 74, 74, 75, 75, 76, 76, 76, 77, 77, + 78, 78, 79, 79, 79, 79, 79, 79, 79, 80, + 80 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -493,14 +559,15 @@ static const unsigned char yyr2[] = 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, - 2, 0, 2, 2, 2, 2, 2, 3, 4, 4, - 4, 5, 2, 2, 1, 3, 0, 2, 2, 2, - 2, 2, 4, 3, 2, 4, 0, 2, 3, 1, - 3, 0, 2, 2, 2, 3, 2, 1, 3, 0, - 2, 2, 2, 3, 3, 2, 2, 2, 0, 2, - 2, 2, 4, 3, 3, 0, 2, 1, 1, 2, - 2, 2, 1, 2, 0, 2, 1, 3, 3, 3, - 2, 3, 3, 1, 1 + 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, + 4, 4, 5, 3, 0, 3, 0, 2, 2, 2, + 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, + 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, + 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, + 3, 2, 2, 2, 0, 2, 2, 2, 4, 3, + 3, 0, 2, 1, 1, 2, 2, 2, 1, 2, + 0, 2, 1, 3, 3, 3, 2, 3, 3, 1, + 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -511,175 +578,164 @@ static const unsigned char yydefact[] = 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, - 23, 46, 56, 5, 61, 20, 78, 69, 6, 24, - 78, 21, 8, 11, 87, 88, 0, 0, 89, 0, - 42, 90, 0, 0, 0, 103, 104, 0, 0, 0, - 96, 91, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 92, 7, 65, 73, 74, 27, 29, 0, - 100, 0, 0, 58, 0, 0, 9, 10, 0, 0, - 0, 0, 0, 85, 0, 0, 0, 0, 36, 35, - 32, 0, 34, 33, 0, 0, 85, 0, 50, 51, - 47, 49, 48, 57, 45, 44, 62, 64, 60, 63, - 59, 80, 81, 79, 70, 72, 68, 71, 67, 93, - 99, 101, 102, 98, 97, 26, 76, 0, 0, 0, - 94, 0, 94, 94, 94, 0, 0, 77, 54, 94, - 0, 94, 0, 83, 84, 0, 0, 37, 86, 0, - 0, 94, 25, 0, 53, 0, 82, 95, 38, 39, - 40, 0, 52, 55, 41 + 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, + 84, 21, 8, 11, 93, 94, 0, 0, 95, 0, + 48, 96, 0, 0, 0, 109, 110, 0, 0, 0, + 102, 97, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 98, 7, 71, 79, 80, 27, 29, 0, + 106, 0, 0, 64, 0, 0, 9, 10, 0, 0, + 0, 0, 0, 91, 0, 0, 0, 44, 0, 37, + 36, 32, 33, 0, 35, 34, 0, 0, 91, 0, + 56, 57, 53, 55, 54, 63, 51, 50, 68, 70, + 66, 69, 65, 86, 87, 85, 76, 78, 74, 77, + 73, 99, 105, 107, 108, 104, 103, 26, 82, 0, + 0, 0, 100, 0, 100, 100, 100, 0, 0, 0, + 83, 60, 100, 0, 100, 0, 89, 90, 0, 0, + 38, 92, 0, 0, 100, 46, 43, 25, 0, 59, + 0, 88, 101, 39, 40, 41, 0, 0, 45, 58, + 61, 42, 47 }; /* YYDEFGOTO[NTERM-NUM]. */ static const short int yydefgoto[] = { - -1, 1, 2, 25, 26, 99, 27, 28, 29, 30, - 64, 100, 31, 32, 114, 33, 66, 110, 67, 34, - 118, 35, 68, 36, 37, 126, 38, 70, 39, 40, - 41, 101, 102, 69, 103, 141, 142, 42, 73, 156, - 59, 60 + -1, 1, 2, 25, 26, 100, 27, 28, 29, 30, + 64, 101, 102, 148, 178, 31, 32, 116, 33, 66, + 112, 67, 34, 120, 35, 68, 36, 37, 128, 38, + 70, 39, 40, 41, 103, 104, 69, 105, 143, 144, + 42, 73, 159, 59, 60 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -78 +#define YYPACT_NINF -135 static const short int yypact[] = { - -78, 2, 159, -78, -21, 0, 0, -12, 0, 1, - 4, 0, 27, 38, 60, 58, -78, -78, -78, -78, - -78, -78, -78, 100, -78, 104, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, 86, 113, -78, 114, - -78, -78, 125, 127, 128, -78, -78, 60, 60, 210, - 65, -78, 141, 142, 39, 103, 182, 200, 6, 66, - 6, 131, -78, 146, -78, -78, -78, -78, -78, 196, - -78, 60, 60, 146, 40, 40, -78, -78, 155, 156, - -2, 60, 0, 0, 60, 105, 40, 194, -78, -78, - -78, 206, -78, -78, 183, 0, 0, 195, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, 197, -78, -78, -78, -78, -78, 60, 213, 216, - 212, 203, 212, 190, 212, 40, 208, -78, -78, 212, - 222, 212, 219, -78, -78, 60, 223, -78, -78, 224, - 225, 212, -78, 226, -78, 227, -78, 47, -78, -78, - -78, 228, -78, -78, -78 + -135, 2, 170, -135, -14, 56, 56, -8, 56, 24, + 67, 56, 7, 14, 62, 97, -135, -135, -135, -135, + -135, -135, -135, 156, -135, 166, -135, -135, -135, -135, + -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, + -135, -135, -135, -135, -135, -135, 138, 151, -135, 152, + -135, -135, 163, 167, 176, -135, -135, 62, 62, 185, + -19, -135, 188, 190, 42, 103, 194, 85, 70, 222, + 70, 132, -135, 191, -135, -135, -135, -135, -135, 127, + -135, 62, 62, 191, 104, 104, -135, -135, 193, 203, + 9, 62, 56, 56, 62, 161, 104, -135, 196, -135, + -135, -135, -135, 233, -135, -135, 204, 56, 56, 221, + -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, + -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, + -135, -135, -135, 219, -135, -135, -135, -135, -135, 62, + 209, 212, 240, 224, 240, -1, 240, 104, 41, 225, + -135, -135, 240, 226, 240, 218, -135, -135, 62, 227, + -135, -135, 228, 229, 240, 230, -135, -135, 231, -135, + 232, -135, 112, -135, -135, -135, 234, 56, -135, -135, + -135, -135, -135 }; /* YYPGOTO[NTERM-NUM]. */ static const short int yypgoto[] = { - -78, -78, -78, -78, 164, -36, -78, -78, -78, -78, - 230, -78, -78, -78, -78, 29, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, 59, -78, -78, -78, - -78, -78, 198, 220, 24, 157, -5, 169, 202, 74, - -53, -77 + -135, -135, -135, -135, 94, -45, -135, -135, -135, -135, + 237, -135, -135, -135, -135, -135, -135, -135, -54, -135, + -135, -135, -135, -135, -135, -135, -135, -135, -135, 1, + -135, -135, -135, -135, -135, 195, 235, -44, 159, -5, + 98, 210, -134, -53, -77 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -76 +#define YYTABLE_NINF -82 static const short int yytable[] = { - 46, 47, 3, 49, 79, 80, 52, 133, 134, 43, - 6, 7, 8, 9, 10, 11, 12, 13, 48, 145, - 14, 15, 137, 55, 56, 44, 45, 57, 131, 132, - 109, 50, 58, 122, 51, 122, 24, 138, 139, -28, - 88, 143, -28, -28, -28, -28, -28, -28, -28, -28, - -28, 89, 53, -28, -28, 90, 91, -28, 92, 93, - 94, 95, 96, 54, 97, 55, 56, 88, 161, 98, - -66, -66, -66, -66, -66, -66, -66, -66, 81, 82, - -66, -66, 90, 91, 152, 55, 56, 140, 61, 57, - 112, 97, 84, 123, 58, 123, 121, 117, 85, 125, - 149, 62, 167, -30, 88, 63, -30, -30, -30, -30, - -30, -30, -30, -30, -30, 89, 72, -30, -30, 90, - 91, -30, 92, 93, 94, 95, 96, 119, 97, 127, - 144, -75, 88, 98, -75, -75, -75, -75, -75, -75, - -75, -75, -75, 74, 75, -75, -75, 90, 91, -75, - -75, -75, -75, -75, -75, 76, 97, 77, 78, -2, - 4, 121, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 86, 87, 14, 15, 16, 129, 17, 18, 19, - 20, 21, 22, 88, 23, 135, 136, -43, -43, 24, - -43, -43, -43, -43, 89, 146, -43, -43, 90, 91, - 104, 105, 106, 107, 155, 7, 8, 97, 10, 11, - 12, 13, 108, 148, 14, 15, 158, 159, 160, 147, - 151, 81, 82, 163, 130, 165, 155, 81, 82, 82, - 24, 113, 116, 157, 124, 171, 115, 120, 162, 128, - 72, 81, 82, 153, 81, 82, 154, 81, 82, 166, - 81, 82, 164, 168, 169, 170, 172, 173, 174, 65, - 71, 83, 0, 150, 111 + 46, 47, 3, 49, 79, 80, 52, 135, 136, 84, + 161, 162, 163, 158, 119, 85, 127, 43, 168, 147, + 170, 111, 114, 48, 124, 125, 124, 125, 133, 134, + 176, 81, 82, 53, 139, 55, 56, 140, 141, 57, + 54, 145, -28, 88, 58, -28, -28, -28, -28, -28, + -28, -28, -28, -28, 89, 50, -28, -28, 90, 91, + -28, 92, 93, 94, 95, 96, 97, 165, 98, 121, + 164, 129, 166, 99, 6, 7, 8, 9, 10, 11, + 12, 13, 44, 45, 14, 15, 155, 142, 55, 56, + 7, 8, 57, 10, 11, 12, 13, 58, 51, 14, + 15, 24, 152, -30, 88, 172, -30, -30, -30, -30, + -30, -30, -30, -30, -30, 89, 24, -30, -30, 90, + 91, -30, 92, 93, 94, 95, 96, 97, 61, 98, + 55, 56, -81, 88, 99, -81, -81, -81, -81, -81, + -81, -81, -81, -81, 81, 82, -81, -81, 90, 91, + -81, -81, -81, -81, -81, -81, 132, 62, 98, 81, + 82, 115, 118, 123, 126, 117, 122, 63, 130, 72, + -2, 4, 182, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 74, 75, 14, 15, 16, 146, 17, 18, + 19, 20, 21, 22, 76, 88, 23, 149, 77, -49, + -49, 24, -49, -49, -49, -49, 89, 78, -49, -49, + 90, 91, 106, 107, 108, 109, 72, 81, 82, 86, + 98, 87, 131, 88, 137, 110, -72, -72, -72, -72, + -72, -72, -72, -72, 138, 151, -72, -72, 90, 91, + 156, 81, 82, 157, 81, 82, 150, 154, 98, 171, + 81, 82, 82, 123, 158, 160, 167, 169, 173, 174, + 175, 113, 179, 180, 177, 181, 65, 153, 0, 83, + 0, 0, 0, 0, 0, 71 }; static const short int yycheck[] = { - 5, 6, 0, 8, 57, 58, 11, 84, 85, 30, - 4, 5, 6, 7, 8, 9, 10, 11, 30, 96, - 14, 15, 24, 25, 26, 25, 26, 29, 81, 82, - 66, 30, 34, 69, 30, 71, 30, 90, 91, 0, - 1, 94, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 25, 25, 25, 26, 1, 145, 30, - 4, 5, 6, 7, 8, 9, 10, 11, 31, 32, - 14, 15, 16, 17, 137, 25, 26, 92, 30, 29, - 66, 25, 27, 69, 34, 71, 30, 68, 33, 70, - 105, 1, 155, 0, 1, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 30, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 68, 25, 70, - 25, 0, 1, 30, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 30, 30, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 30, 25, 30, 30, 0, - 1, 30, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 30, 30, 14, 15, 16, 30, 18, 19, 20, - 21, 22, 23, 1, 25, 30, 30, 5, 6, 30, - 8, 9, 10, 11, 12, 1, 14, 15, 16, 17, - 18, 19, 20, 21, 14, 5, 6, 25, 8, 9, - 10, 11, 30, 30, 14, 15, 142, 143, 144, 13, - 25, 31, 32, 149, 28, 151, 14, 31, 32, 32, - 30, 67, 68, 30, 70, 161, 67, 68, 30, 70, - 30, 31, 32, 30, 31, 32, 30, 31, 32, 30, - 31, 32, 30, 30, 30, 30, 30, 30, 30, 29, - 40, 59, -1, 106, 66 + 5, 6, 0, 8, 57, 58, 11, 84, 85, 28, + 144, 145, 146, 14, 68, 34, 70, 31, 152, 96, + 154, 66, 66, 31, 69, 69, 71, 71, 81, 82, + 164, 32, 33, 26, 25, 26, 27, 90, 91, 30, + 26, 94, 0, 1, 35, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 31, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 26, 26, 68, + 147, 70, 31, 31, 4, 5, 6, 7, 8, 9, + 10, 11, 26, 27, 14, 15, 139, 92, 26, 27, + 5, 6, 30, 8, 9, 10, 11, 35, 31, 14, + 15, 31, 107, 0, 1, 158, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 31, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 31, 26, + 26, 27, 0, 1, 31, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 32, 33, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 29, 1, 26, 32, + 33, 67, 68, 31, 70, 67, 68, 1, 70, 31, + 0, 1, 177, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 31, 31, 14, 15, 16, 26, 18, 19, + 20, 21, 22, 23, 31, 1, 26, 1, 31, 5, + 6, 31, 8, 9, 10, 11, 12, 31, 14, 15, + 16, 17, 18, 19, 20, 21, 31, 32, 33, 31, + 26, 31, 31, 1, 31, 31, 4, 5, 6, 7, + 8, 9, 10, 11, 31, 31, 14, 15, 16, 17, + 31, 32, 33, 31, 32, 33, 13, 26, 26, 31, + 32, 33, 33, 31, 14, 31, 31, 31, 31, 31, + 31, 66, 31, 31, 34, 31, 29, 108, -1, 59, + -1, -1, -1, -1, -1, 40 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { - 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, + 0, 37, 38, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16, 18, 19, 20, - 21, 22, 23, 25, 30, 38, 39, 41, 42, 43, - 44, 47, 48, 50, 54, 56, 58, 59, 61, 63, - 64, 65, 72, 30, 25, 26, 71, 71, 30, 71, - 30, 30, 71, 25, 25, 25, 26, 29, 34, 75, - 76, 30, 1, 1, 45, 45, 51, 53, 57, 68, - 62, 68, 30, 73, 30, 30, 30, 30, 30, 75, - 75, 31, 32, 73, 27, 33, 30, 30, 1, 12, - 16, 17, 19, 20, 21, 22, 23, 25, 30, 40, - 46, 66, 67, 69, 18, 19, 20, 21, 30, 40, - 52, 67, 69, 39, 49, 72, 39, 50, 55, 61, - 72, 30, 40, 69, 39, 50, 60, 61, 72, 30, - 28, 75, 75, 76, 76, 30, 30, 24, 75, 75, - 71, 70, 71, 75, 25, 76, 1, 13, 30, 71, - 70, 25, 75, 30, 30, 14, 74, 30, 74, 74, - 74, 76, 30, 74, 30, 74, 30, 75, 30, 30, - 30, 74, 30, 30, 30 + 21, 22, 23, 26, 31, 39, 40, 42, 43, 44, + 45, 51, 52, 54, 58, 60, 62, 63, 65, 67, + 68, 69, 76, 31, 26, 27, 75, 75, 31, 75, + 31, 31, 75, 26, 26, 26, 27, 30, 35, 79, + 80, 31, 1, 1, 46, 46, 55, 57, 61, 72, + 66, 72, 31, 77, 31, 31, 31, 31, 31, 79, + 79, 32, 33, 77, 28, 34, 31, 31, 1, 12, + 16, 17, 19, 20, 21, 22, 23, 24, 26, 31, + 41, 47, 48, 70, 71, 73, 18, 19, 20, 21, + 31, 41, 56, 71, 73, 40, 53, 76, 40, 54, + 59, 65, 76, 31, 41, 73, 40, 54, 64, 65, + 76, 31, 29, 79, 79, 80, 80, 31, 31, 25, + 79, 79, 75, 74, 75, 79, 26, 80, 49, 1, + 13, 31, 75, 74, 26, 79, 31, 31, 14, 78, + 31, 78, 78, 78, 80, 26, 31, 31, 78, 31, + 78, 31, 79, 31, 31, 31, 78, 34, 50, 31, + 31, 31, 75 }; -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) @@ -709,8 +765,8 @@ do \ goto yybackup; \ } \ else \ - { \ - yyerror ("syntax error: cannot back up");\ + { \ + yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) @@ -789,7 +845,7 @@ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ + yysymprint (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ @@ -837,13 +893,13 @@ yy_reduce_print (yyrule) #endif { int yyi; - unsigned int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", yyrule - 1, yylno); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); + YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); } # define YY_REDUCE_PRINT(Rule) \ @@ -872,7 +928,7 @@ int yydebug; if the built-in stack extension method is used). Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH @@ -896,7 +952,7 @@ yystrlen (yystr) const char *yystr; # endif { - register const char *yys = yystr; + const char *yys = yystr; while (*yys++ != '\0') continue; @@ -921,8 +977,8 @@ yystpcpy (yydest, yysrc) const char *yysrc; # endif { - register char *yyd = yydest; - register const char *yys = yysrc; + char *yyd = yydest; + const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; @@ -932,7 +988,55 @@ yystpcpy (yydest, yysrc) # endif # endif -#endif /* !YYERROR_VERBOSE */ +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + size_t yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +#endif /* YYERROR_VERBOSE */ @@ -998,7 +1102,7 @@ yydestruct (yymsg, yytype, yyvaluep) switch (yytype) { - case 48: /* choice_entry */ + case 52: /* "choice_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1008,7 +1112,7 @@ yydestruct (yymsg, yytype, yyvaluep) }; break; - case 54: /* if_entry */ + case 58: /* "if_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1018,7 +1122,7 @@ yydestruct (yymsg, yytype, yyvaluep) }; break; - case 59: /* menu_entry */ + case 63: /* "menu_entry" */ { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -1082,13 +1186,13 @@ yyparse (void) #else int yyparse () - + ; #endif #endif { - register int yystate; - register int yyn; + int yystate; + int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; @@ -1106,12 +1210,12 @@ yyparse () /* The state stack. */ short int yyssa[YYINITDEPTH]; short int *yyss = yyssa; - register short int *yyssp; + short int *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; + YYSTYPE *yyvsp; @@ -1143,9 +1247,6 @@ yyparse () yyssp = yyss; yyvsp = yyvs; - - yyvsp[0] = yylval; - goto yysetstate; /*------------------------------------------------------------. @@ -1178,7 +1279,7 @@ yyparse () data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", + yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), @@ -1189,11 +1290,11 @@ yyparse () } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE - goto yyoverflowlab; + goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; @@ -1203,7 +1304,7 @@ yyparse () union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) - goto yyoverflowlab; + goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); @@ -1403,7 +1504,7 @@ yyreduce: ;} break; - case 37: + case 38: { menu_set_type((yyvsp[-2].id)->stype); @@ -1413,7 +1514,7 @@ yyreduce: ;} break; - case 38: + case 39: { menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); @@ -1421,7 +1522,7 @@ yyreduce: ;} break; - case 39: + case 40: { menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr)); @@ -1433,7 +1534,7 @@ yyreduce: ;} break; - case 40: + case 41: { menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); @@ -1441,7 +1542,7 @@ yyreduce: ;} break; - case 41: + case 42: { menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr)); @@ -1449,7 +1550,29 @@ yyreduce: ;} break; - case 42: + case 45: + + { + struct kconf_id *id = kconf_id_lookup((yyvsp[-1].string), strlen((yyvsp[-1].string))); + if (id && id->flags & TF_OPTION) + menu_add_option(id->token, (yyvsp[0].string)); + else + zconfprint("warning: ignoring unknown option %s", (yyvsp[-1].string)); + free((yyvsp[-1].string)); +;} + break; + + case 46: + + { (yyval.string) = NULL; ;} + break; + + case 47: + + { (yyval.string) = (yyvsp[0].string); ;} + break; + + case 48: { struct symbol *sym = sym_lookup(NULL, 0); @@ -1460,14 +1583,14 @@ yyreduce: ;} break; - case 43: + case 49: { (yyval.menu) = menu_add_menu(); ;} break; - case 44: + case 50: { if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) { @@ -1477,7 +1600,7 @@ yyreduce: ;} break; - case 52: + case 58: { menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); @@ -1485,7 +1608,7 @@ yyreduce: ;} break; - case 53: + case 59: { if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) { @@ -1498,7 +1621,7 @@ yyreduce: ;} break; - case 54: + case 60: { current_entry->sym->flags |= SYMBOL_OPTIONAL; @@ -1506,7 +1629,7 @@ yyreduce: ;} break; - case 55: + case 61: { if ((yyvsp[-3].id)->stype == S_UNKNOWN) { @@ -1518,7 +1641,7 @@ yyreduce: ;} break; - case 58: + case 64: { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); @@ -1528,7 +1651,7 @@ yyreduce: ;} break; - case 59: + case 65: { if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) { @@ -1538,7 +1661,7 @@ yyreduce: ;} break; - case 65: + case 71: { menu_add_entry(NULL); @@ -1547,14 +1670,14 @@ yyreduce: ;} break; - case 66: + case 72: { (yyval.menu) = menu_add_menu(); ;} break; - case 67: + case 73: { if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) { @@ -1564,7 +1687,7 @@ yyreduce: ;} break; - case 73: + case 79: { printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); @@ -1572,7 +1695,7 @@ yyreduce: ;} break; - case 74: + case 80: { menu_add_entry(NULL); @@ -1581,14 +1704,14 @@ yyreduce: ;} break; - case 75: + case 81: { menu_end_entry(); ;} break; - case 76: + case 82: { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); @@ -1596,14 +1719,14 @@ yyreduce: ;} break; - case 77: + case 83: { current_entry->sym->help = (yyvsp[0].string); ;} break; - case 82: + case 88: { menu_add_dep((yyvsp[-1].expr)); @@ -1611,7 +1734,7 @@ yyreduce: ;} break; - case 83: + case 89: { menu_add_dep((yyvsp[-1].expr)); @@ -1619,7 +1742,7 @@ yyreduce: ;} break; - case 84: + case 90: { menu_add_dep((yyvsp[-1].expr)); @@ -1627,87 +1750,88 @@ yyreduce: ;} break; - case 86: + case 92: { menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr)); ;} break; - case 89: + case 95: { (yyval.id) = (yyvsp[-1].id); ;} break; - case 90: + case 96: { (yyval.id) = (yyvsp[-1].id); ;} break; - case 91: + case 97: { (yyval.id) = (yyvsp[-1].id); ;} break; - case 94: + case 100: { (yyval.expr) = NULL; ;} break; - case 95: + case 101: { (yyval.expr) = (yyvsp[0].expr); ;} break; - case 96: + case 102: { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;} break; - case 97: + case 103: { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} break; - case 98: + case 104: { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} break; - case 99: + case 105: { (yyval.expr) = (yyvsp[-1].expr); ;} break; - case 100: + case 106: { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;} break; - case 101: + case 107: { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} break; - case 102: + case 108: { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} break; - case 103: + case 109: { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;} break; - case 104: + case 110: { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;} break; + default: break; } -/* Line 1037 of yacc.c. */ +/* Line 1126 of yacc.c. */ yyvsp -= yylen; @@ -1747,12 +1871,36 @@ yyerrlab: if (YYPACT_NINF < yyn && yyn < YYLAST) { - YYSIZE_T yysize = 0; int yytype = YYTRANSLATE (yychar); - const char* yyprefix; - char *yymsg; + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + char *yymsg = 0; +# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; +#if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +#endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; @@ -1760,48 +1908,68 @@ yyerrlab: /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 0; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); - yyprefix = ", expecting "; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { - yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); - yycount += 1; - if (yycount == 5) + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { - yysize = 0; + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; break; } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= yysize1 < yysize; + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; } - yysize += (sizeof ("syntax error, unexpected ") - + yystrlen (yytname[yytype])); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - if (yycount < 5) + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= yysize1 < yysize; + yysize = yysize1; + + if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yymsg; + int yyi = 0; + while ((*yyp = *yyf)) { - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - yyp = yystpcpy (yyp, yyprefix); - yyp = yystpcpy (yyp, yytname[yyx]); - yyprefix = " or "; - } + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } } yyerror (yymsg); YYSTACK_FREE (yymsg); } else - yyerror ("syntax error; also virtual memory exhausted"); + { + yyerror (YY_("syntax error")); + goto yyexhaustedlab; + } } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror (YY_("syntax error")); } @@ -1813,18 +1981,9 @@ yyerrlab: if (yychar <= YYEOF) { - /* If at end of input, pop the error token, - then the rest of the stack, then return failure. */ + /* Return failure if at end of input. */ if (yychar == YYEOF) - for (;;) - { - - YYPOPSTACK; - if (yyssp == yyss) - YYABORT; - yydestruct ("Error: popping", - yystos[*yyssp], yyvsp); - } + YYABORT; } else { @@ -1843,12 +2002,11 @@ yyerrlab: `---------------------------------------------------*/ yyerrorlab: -#ifdef __GNUC__ - /* Pacify GCC when the user code never invokes YYERROR and the label - yyerrorlab therefore never appears in user code. */ + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ if (0) goto yyerrorlab; -#endif yyvsp -= yylen; yyssp -= yylen; @@ -1911,23 +2069,29 @@ yyacceptlab: | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: - yydestruct ("Error: discarding lookahead", - yytoken, &yylval); - yychar = YYEMPTY; yyresult = 1; goto yyreturn; #ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK; + } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 1f61fba6aa28..9d08582f2aa6 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -71,6 +71,7 @@ static struct menu *current_menu, *current_entry; %token T_DEFAULT %token T_SELECT %token T_RANGE +%token T_OPTION %token T_ON %token T_WORD %token T_WORD_QUOTE @@ -91,6 +92,7 @@ static struct menu *current_menu, *current_entry; %type end %type option_name %type if_entry menu_entry choice_entry +%type symbol_option_arg %destructor { fprintf(stderr, "%s:%d: missing end statement for this entry\n", @@ -173,6 +175,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list config_option_list: /* empty */ | config_option_list config_option + | config_option_list symbol_option | config_option_list depends | config_option_list help | config_option_list option_error @@ -215,6 +218,26 @@ config_option: T_RANGE symbol symbol if_expr T_EOL printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); }; +symbol_option: T_OPTION symbol_option_list T_EOL +; + +symbol_option_list: + /* empty */ + | symbol_option_list T_WORD symbol_option_arg +{ + struct kconf_id *id = kconf_id_lookup($2, strlen($2)); + if (id && id->flags & TF_OPTION) + menu_add_option(id->token, $3); + else + zconfprint("warning: ignoring unknown option %s", $2); + free($2); +}; + +symbol_option_arg: + /* empty */ { $$ = NULL; } + | T_EQUAL prompt { $$ = $2; } +; + /* choice entry */ choice: T_CHOICE T_EOL -- cgit v1.2.3 From face4374e288372fba67c865eb0c92337f50d5a4 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:45 -0700 Subject: kconfig: add defconfig_list/module option This makes it possible to change two options which were hardcoded sofar. 1. Any symbol can now take the role of CONFIG_MODULES 2. The more useful option is to change the list of default file names, which kconfig uses to load the base configuration if .config isn't available. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- init/Kconfig | 8 ++++++++ scripts/kconfig/confdata.c | 26 +++++++++++--------------- scripts/kconfig/expr.h | 1 + scripts/kconfig/lkc.h | 1 + scripts/kconfig/menu.c | 14 ++++++++++++++ scripts/kconfig/symbol.c | 15 ++++++++------- scripts/kconfig/zconf.tab.c_shipped | 10 +++++++++- scripts/kconfig/zconf.y | 10 +++++++++- 8 files changed, 61 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/init/Kconfig b/init/Kconfig index 3b36a1d53656..9fb403af1085 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1,3 +1,11 @@ +config DEFCONFIG_LIST + string + option defconfig_list + default "/lib/modules/$UNAME_RELEASE/.config" + default "/etc/kernel-config" + default "/boot/config-$UNAME_RELEASE" + default "arch/$ARCH/defconfig" + menu "Code maturity level options" config EXPERIMENTAL diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index e28cd0c2ca08..5bd66f451189 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -25,15 +25,6 @@ const char conf_def_filename[] = ".config"; const char conf_defname[] = "arch/$ARCH/defconfig"; -const char *conf_confnames[] = { - ".config", - "/lib/modules/$UNAME_RELEASE/.config", - "/etc/kernel-config", - "/boot/config-$UNAME_RELEASE", - conf_defname, - NULL, -}; - static void conf_warning(const char *fmt, ...) { va_list ap; @@ -98,16 +89,21 @@ int conf_read_simple(const char *name, int def) if (name) { in = zconf_fopen(name); } else { - const char **names = conf_confnames; - name = *names++; - if (!name) - return 1; + struct property *prop; + + name = conf_def_filename; in = zconf_fopen(name); if (in) goto load; sym_change_count++; - while ((name = *names++)) { - name = conf_expand_value(name); + if (!sym_defconfig_list) + return 1; + + for_all_defaults(sym_defconfig_list, prop) { + if (expr_calc_value(prop->visible.expr) == no || + prop->expr->type != E_SYMBOL) + continue; + name = conf_expand_value(prop->expr->left.sym->name); in = zconf_fopen(name); if (in) { printf(_("#\n" diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index ffd42c7007ee..6084525f604b 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -156,6 +156,7 @@ struct file *lookup_file(const char *name); extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol *modules_sym; +extern struct symbol *sym_defconfig_list; extern int cdebug; struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 8e89d342889e..2d3d4ed3c9f2 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -104,6 +104,7 @@ const char *str_get(struct gstr *gs); /* symbol.c */ void sym_init(void); void sym_clear_all_valid(void); +void sym_set_all_changed(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); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 151ef2168a2c..a8afce24fb1b 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -154,6 +154,20 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) void menu_add_option(int token, char *arg) { + struct property *prop; + + switch (token) { + case T_OPT_MODULES: + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(current_entry->sym); + break; + case T_OPT_DEFCONFIG_LIST: + if (!sym_defconfig_list) + sym_defconfig_list = current_entry->sym; + else if (sym_defconfig_list != current_entry->sym) + zconf_error("trying to redefine defconfig symbol"); + break; + } } static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 78a60ba39e54..ee225ced2ce4 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -31,6 +31,7 @@ struct symbol symbol_yes = { }; int sym_change_count; +struct symbol *sym_defconfig_list; struct symbol *modules_sym; tristate modules_val; @@ -352,10 +353,13 @@ void sym_calc_value(struct symbol *sym) sym->curr.val = sym_calc_choice(sym); sym_validate_range(sym); - if (memcmp(&oldval, &sym->curr, sizeof(oldval))) + if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { sym_set_changed(sym); - if (modules_sym == sym) - modules_val = modules_sym->curr.tri; + if (modules_sym == sym) { + sym_set_all_changed(); + modules_val = modules_sym->curr.tri; + } + } if (sym_is_choice(sym)) { int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); @@ -449,11 +453,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) } sym->def[S_DEF_USER].tri = val; - if (oldval != val) { + if (oldval != val) sym_clear_all_valid(); - if (sym == modules_sym) - sym_set_all_changed(); - } return true; } diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 137426e507ec..2fb0a4fc61d0 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -2112,7 +2112,9 @@ void conf_parse(const char *name) sym_init(); menu_init(); - modules_sym = sym_lookup("MODULES", 0); + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); #if YYDEBUG @@ -2122,6 +2124,12 @@ void conf_parse(const char *name) zconfparse(); if (zconfnerrs) exit(1); + if (!modules_sym->prop) { + struct property *prop; + + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); + } menu_finalize(&rootmenu); for_all_symbols(i, sym) { sym_check_deps(sym); diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 9d08582f2aa6..ab44feb3c600 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -481,7 +481,9 @@ void conf_parse(const char *name) sym_init(); menu_init(); - modules_sym = sym_lookup("MODULES", 0); + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); #if YYDEBUG @@ -491,6 +493,12 @@ void conf_parse(const char *name) zconfparse(); if (zconfnerrs) exit(1); + if (!modules_sym->prop) { + struct property *prop; + + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); + } menu_finalize(&rootmenu); for_all_symbols(i, sym) { sym_check_deps(sym); -- cgit v1.2.3 From 43bf612af2d4f2615dcbf86af8206e2f40231237 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:45 -0700 Subject: kconfig: Add search option for xconfig Implement a simple search request for xconfig. Currently the capabilities are rather simple (the same as menuconfig). Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/qconf.cc | 444 ++++++++++++++++++++++++++++++----------------- scripts/kconfig/qconf.h | 61 +++++-- 2 files changed, 333 insertions(+), 172 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 4590cd31623f..2befaeac6e64 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -6,16 +6,20 @@ #include #include #include +#include #include #include #include -#include +#include #include +#include +#include #include #include #include #include #include +#include #include #include @@ -35,12 +39,12 @@ static QApplication *configApp; static inline QString qgettext(const char* str) { - return QString::fromLocal8Bit(gettext(str)); + return QString::fromLocal8Bit(gettext(str)); } static inline QString qgettext(const QString& str) { - return QString::fromLocal8Bit(gettext(str.latin1())); + return QString::fromLocal8Bit(gettext(str.latin1())); } ConfigSettings::ConfigSettings() @@ -355,6 +359,12 @@ ConfigItem::~ConfigItem(void) } } +ConfigLineEdit::ConfigLineEdit(ConfigView* parent) + : Parent(parent) +{ + connect(this, SIGNAL(lostFocus()), SLOT(hide())); +} + void ConfigLineEdit::show(ConfigItem* i) { item = i; @@ -385,8 +395,8 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e) hide(); } -ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv, ConfigSettings* configSettings) - : Parent(p), cview(cv), +ConfigList::ConfigList(ConfigView* p, ConfigSettings* configSettings) + : Parent(p), updateAll(false), symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), @@ -450,9 +460,8 @@ void ConfigList::updateSelection(void) if (!item) return; - cview->setHelp(item); - menu = item->menu; + emit menuChanged(menu); if (!menu) return; type = menu->prompt ? menu->prompt->type : P_UNKNOWN; @@ -464,8 +473,20 @@ void ConfigList::updateList(ConfigItem* item) { ConfigItem* last = 0; - if (!rootEntry) - goto update; + if (!rootEntry) { + if (mode != listMode) + goto update; + QListViewItemIterator it(this); + ConfigItem* item; + + for (; it.current(); ++it) { + item = (ConfigItem*)it.current(); + if (!item->menu) + continue; + item->testUpdateMenu(menu_is_visible(item->menu)); + } + return; + } if (rootEntry != &rootmenu && (mode == singleMode || (mode == symbolMode && rootEntry->parent != &rootmenu))) { @@ -610,7 +631,7 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) struct menu *menu; enum prop_type type; - if (ev->key() == Key_Escape && mode != fullMode) { + if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) { emit parentSelected(); ev->accept(); return; @@ -767,11 +788,10 @@ void ConfigList::focusInEvent(QFocusEvent *e) ConfigView* ConfigView::viewList; -ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview, - ConfigSettings *configSettings) +ConfigView::ConfigView(QWidget* parent, ConfigSettings *configSettings) : Parent(parent) { - list = new ConfigList(this, cview, configSettings); + list = new ConfigList(this, configSettings); lineEdit = new ConfigLineEdit(this); lineEdit->hide(); @@ -807,13 +827,238 @@ void ConfigView::updateListAll(void) v->list->updateListAll(); } +ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) + : Parent(parent, name), menu(0) +{ +} + +void ConfigInfoView::setShowDebug(bool b) +{ + if (_showDebug != b) { + _showDebug = b; + if (menu) + menuInfo(); + emit showDebugChanged(b); + } +} + +void ConfigInfoView::setInfo(struct menu *m) +{ + menu = m; + if (!menu) + clear(); + else + menuInfo(); +} + +void ConfigInfoView::setSource(const QString& name) +{ + const char *p = name.latin1(); + + menu = NULL; + + switch (p[0]) { + case 'm': + if (sscanf(p, "m%p", &menu) == 1) + menuInfo(); + break; + } +} + +void ConfigInfoView::menuInfo(void) +{ + struct symbol* sym; + QString head, debug, help; + + sym = menu->sym; + if (sym) { + if (menu->prompt) { + head += ""; + head += print_filter(_(menu->prompt->text)); + head += ""; + if (sym->name) { + head += " ("; + head += print_filter(sym->name); + head += ")"; + } + } else if (sym->name) { + head += ""; + head += print_filter(sym->name); + head += ""; + } + head += "

"; + + if (showDebug()) + debug = debug_info(sym); + + help = print_filter(_(sym->help)); + } else if (menu->prompt) { + head += ""; + head += print_filter(_(menu->prompt->text)); + head += "

"; + if (showDebug()) { + if (menu->prompt->visible.expr) { + debug += "  dep: "; + expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); + debug += "

"; + } + } + } + if (showDebug()) + debug += QString().sprintf("defined at %s:%d

", menu->file->name, menu->lineno); + + setText(head + debug + help); +} + +QString ConfigInfoView::debug_info(struct symbol *sym) +{ + QString debug; + + debug += "type: "; + debug += print_filter(sym_type_name(sym->type)); + if (sym_is_choice(sym)) + debug += " (choice)"; + debug += "
"; + if (sym->rev_dep.expr) { + debug += "reverse dep: "; + expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE); + debug += "
"; + } + 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 += "
"; + break; + case P_DEFAULT: + debug += "default: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "
"; + break; + case P_CHOICE: + if (sym_is_choice(sym)) { + debug += "choice: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "
"; + } + break; + case P_SELECT: + debug += "select: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "
"; + break; + case P_RANGE: + debug += "range: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "
"; + break; + default: + debug += "unknown property: "; + debug += prop_get_type_name(prop->type); + debug += "
"; + } + if (prop->visible.expr) { + debug += "    dep: "; + expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); + debug += "
"; + } + } + debug += "
"; + + return debug; +} + +QString ConfigInfoView::print_filter(const QString &str) +{ + QRegExp re("[<>&\"\\n]"); + QString res = str; + for (int i = 0; (i = res.find(re, i)) >= 0;) { + switch (res[i].latin1()) { + case '<': + res.replace(i, 1, "<"); + i += 4; + break; + case '>': + res.replace(i, 1, ">"); + i += 4; + break; + case '&': + res.replace(i, 1, "&"); + i += 5; + break; + case '"': + res.replace(i, 1, """); + i += 6; + break; + case '\n': + res.replace(i, 1, "
"); + i += 4; + break; + } + } + return res; +} + +void ConfigInfoView::expr_print_help(void *data, const char *str) +{ + reinterpret_cast(data)->append(print_filter(str)); +} + +ConfigSearchWindow::ConfigSearchWindow(QWidget* parent) + : Parent(parent), result(NULL) +{ + setCaption("Search Config"); + + QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6); + QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6); + layout2->addWidget(new QLabel("Find:", this)); + editField = new QLineEdit(this); + connect(editField, SIGNAL(returnPressed()), SLOT(search())); + layout2->addWidget(editField); + searchButton = new QPushButton("Search", this); + searchButton->setAutoDefault(FALSE); + connect(searchButton, SIGNAL(clicked()), SLOT(search())); + layout2->addWidget(searchButton); + layout1->addLayout(layout2); + + QSplitter* split = new QSplitter(this); + split->setOrientation(QSplitter::Vertical); + list = new ConfigView(split, NULL); + list->list->mode = listMode; + info = new ConfigInfoView(split); + connect(list->list, SIGNAL(menuChanged(struct menu *)), + info, SLOT(setInfo(struct menu *))); + layout1->addWidget(split); +} + +void ConfigSearchWindow::search(void) +{ + struct symbol **p; + struct property *prop; + ConfigItem *lastItem = NULL; + + free(result); + list->list->clear(); + + result = sym_re_search(editField->text().latin1()); + if (!result) + return; + for (p = result; *p; p++) { + for_all_prompts((*p), prop) + lastItem = new ConfigItem(list->list, lastItem, prop->menu, + menu_is_visible(prop->menu)); + } +} + /* * Construct the complete config widget */ ConfigMainWindow::ConfigMainWindow(void) { QMenuBar* menu; - bool ok; + bool ok, showDebug; int x, y, width, height; QWidget *d = configApp->desktop(); @@ -843,18 +1088,19 @@ ConfigMainWindow::ConfigMainWindow(void) split1->setOrientation(QSplitter::Horizontal); setCentralWidget(split1); - menuView = new ConfigView(split1, this, configSettings); + menuView = new ConfigView(split1, configSettings); menuList = menuView->list; split2 = new QSplitter(split1); split2->setOrientation(QSplitter::Vertical); // create config tree - configView = new ConfigView(split2, this, configSettings); + configView = new ConfigView(split2, configSettings); configList = configView->list; - helpText = new QTextView(split2); + helpText = new ConfigInfoView(split2); helpText->setTextFormat(Qt::RichText); + helpText->setShowDebug(showDebug); setTabOrder(configList, helpText); configList->setFocus(); @@ -873,6 +1119,8 @@ ConfigMainWindow::ConfigMainWindow(void) connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this); connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); + QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this); + connect(searchAction, SIGNAL(activated()), SLOT(searchConfig())); QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this); connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this); @@ -899,7 +1147,8 @@ ConfigMainWindow::ConfigMainWindow(void) QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); showDebugAction->setToggleAction(TRUE); showDebugAction->setOn(showDebug); - connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); + connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); + connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this); connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); @@ -923,6 +1172,8 @@ ConfigMainWindow::ConfigMainWindow(void) saveAction->addTo(config); saveAsAction->addTo(config); config->insertSeparator(); + searchAction->addTo(config); + config->insertSeparator(); quitAction->addTo(config); // create options menu @@ -942,10 +1193,14 @@ ConfigMainWindow::ConfigMainWindow(void) showIntroAction->addTo(helpMenu); showAboutAction->addTo(helpMenu); + connect(configList, SIGNAL(menuChanged(struct menu *)), + helpText, SLOT(setInfo(struct menu *))); connect(configList, SIGNAL(menuSelected(struct menu *)), SLOT(changeMenu(struct menu *))); connect(configList, SIGNAL(parentSelected()), SLOT(goBack())); + connect(menuList, SIGNAL(menuChanged(struct menu *)), + helpText, SLOT(setInfo(struct menu *))); connect(menuList, SIGNAL(menuSelected(struct menu *)), SLOT(changeMenu(struct menu *))); @@ -977,42 +1232,6 @@ ConfigMainWindow::ConfigMainWindow(void) delete configSettings; } -static QString print_filter(const QString &str) -{ - QRegExp re("[<>&\"\\n]"); - QString res = str; - for (int i = 0; (i = res.find(re, i)) >= 0;) { - switch (res[i].latin1()) { - case '<': - res.replace(i, 1, "<"); - i += 4; - break; - case '>': - res.replace(i, 1, ">"); - i += 4; - break; - case '&': - res.replace(i, 1, "&"); - i += 5; - break; - case '"': - res.replace(i, 1, """); - i += 6; - break; - case '\n': - res.replace(i, 1, "
"); - i += 4; - break; - } - } - return res; -} - -static void expr_print_help(void *data, const char *str) -{ - reinterpret_cast(data)->append(print_filter(str)); -} - /* * display a new help entry as soon as a new menu entry is selected */ @@ -1021,105 +1240,9 @@ void ConfigMainWindow::setHelp(QListViewItem* item) struct symbol* sym; struct menu* menu = 0; - configList->parent()->lineEdit->hide(); if (item) menu = ((ConfigItem*)item)->menu; - if (!menu) { - helpText->setText(QString::null); - return; - } - - QString head, debug, help; - menu = ((ConfigItem*)item)->menu; - sym = menu->sym; - if (sym) { - if (menu->prompt) { - head += ""; - head += print_filter(_(menu->prompt->text)); - head += ""; - if (sym->name) { - head += " ("; - head += print_filter(_(sym->name)); - head += ")"; - } - } else if (sym->name) { - head += ""; - head += print_filter(_(sym->name)); - head += ""; - } - head += "

"; - - if (showDebug) { - debug += "type: "; - debug += print_filter(sym_type_name(sym->type)); - if (sym_is_choice(sym)) - debug += " (choice)"; - debug += "
"; - if (sym->rev_dep.expr) { - debug += "reverse dep: "; - expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE); - debug += "
"; - } - 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 += "
"; - break; - case P_DEFAULT: - debug += "default: "; - expr_print(prop->expr, expr_print_help, &debug, E_NONE); - debug += "
"; - break; - case P_CHOICE: - if (sym_is_choice(sym)) { - debug += "choice: "; - expr_print(prop->expr, expr_print_help, &debug, E_NONE); - debug += "
"; - } - break; - case P_SELECT: - debug += "select: "; - expr_print(prop->expr, expr_print_help, &debug, E_NONE); - debug += "
"; - break; - case P_RANGE: - debug += "range: "; - expr_print(prop->expr, expr_print_help, &debug, E_NONE); - debug += "
"; - break; - default: - debug += "unknown property: "; - debug += prop_get_type_name(prop->type); - debug += "
"; - } - if (prop->visible.expr) { - debug += "    dep: "; - expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); - debug += "
"; - } - } - debug += "
"; - } - - help = print_filter(_(sym->help)); - } else if (menu->prompt) { - head += ""; - head += print_filter(_(menu->prompt->text)); - head += "

"; - if (showDebug) { - if (menu->prompt->visible.expr) { - debug += "  dep: "; - expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); - debug += "

"; - } - } - } - if (showDebug) - debug += QString().sprintf("defined at %s:%d

", menu->file->name, menu->lineno); - helpText->setText(head + debug + help); + helpText->setInfo(menu); } void ConfigMainWindow::loadConfig(void) @@ -1147,6 +1270,13 @@ void ConfigMainWindow::saveConfigAs(void) QMessageBox::information(this, "qconf", "Unable to save configuration!"); } +void ConfigMainWindow::searchConfig(void) +{ + if (!searchWindow) + searchWindow = new ConfigSearchWindow(this); + searchWindow->show(); +} + void ConfigMainWindow::changeMenu(struct menu *menu) { configList->setRootMenu(menu); @@ -1233,13 +1363,6 @@ void ConfigMainWindow::setShowAll(bool b) menuList->updateListAll(); } -void ConfigMainWindow::setShowDebug(bool b) -{ - if (showDebug == b) - return; - showDebug = b; -} - void ConfigMainWindow::setShowName(bool b) { if (configList->showName == b) @@ -1334,7 +1457,7 @@ void ConfigMainWindow::saveSettings(void) configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange); configSettings->writeEntry("/kconfig/qconf/showData", configList->showData); configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll); - configSettings->writeEntry("/kconfig/qconf/showDebug", showDebug); + configSettings->writeEntry("/kconfig/qconf/showDebug", helpText->showDebug()); QString entry; switch(configList->mode) { @@ -1417,9 +1540,10 @@ int main(int ac, char** av) v = new ConfigMainWindow(); //zconfdump(stdout); - v->show(); + configApp->setMainWidget(v); configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); + v->show(); configApp->exec(); return 0; diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index e52f3e90bf0c..a548d13149b3 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -36,7 +36,7 @@ class ConfigView : public QVBox { Q_OBJECT typedef class QVBox Parent; public: - ConfigView(QWidget* parent, ConfigMainWindow* cview, ConfigSettings* configSettings); + ConfigView(QWidget* parent, ConfigSettings* configSettings); ~ConfigView(void); static void updateList(ConfigItem* item); static void updateListAll(void); @@ -53,14 +53,14 @@ enum colIdx { promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr }; enum listMode { - singleMode, menuMode, symbolMode, fullMode + singleMode, menuMode, symbolMode, fullMode, listMode }; class ConfigList : public QListView { Q_OBJECT typedef class QListView Parent; public: - ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings); + ConfigList(ConfigView* p, ConfigSettings *configSettings); void reinit(void); ConfigView* parent(void) const { @@ -68,8 +68,6 @@ public: } protected: - ConfigMainWindow* cview; - void keyPressEvent(QKeyEvent *e); void contentsMousePressEvent(QMouseEvent *e); void contentsMouseReleaseEvent(QMouseEvent *e); @@ -84,6 +82,7 @@ public slots: void changeValue(ConfigItem* item); void updateSelection(void); signals: + void menuChanged(struct menu *menu); void menuSelected(struct menu *menu); void parentSelected(void); void gotFocus(void); @@ -208,9 +207,7 @@ class ConfigLineEdit : public QLineEdit { Q_OBJECT typedef class QLineEdit Parent; public: - ConfigLineEdit(ConfigView* parent) - : Parent(parent) - { } + ConfigLineEdit(ConfigView* parent); ConfigView* parent(void) const { return (ConfigView*)Parent::parent(); @@ -222,6 +219,47 @@ public: ConfigItem *item; }; +class ConfigInfoView : public QTextBrowser { + Q_OBJECT + typedef class QTextBrowser Parent; +public: + ConfigInfoView(QWidget* parent, const char *name = 0); + bool showDebug(void) const { return _showDebug; } + +public slots: + void setInfo(struct menu *menu); + void setSource(const QString& name); + void setShowDebug(bool); + +signals: + void showDebugChanged(bool); + +protected: + void menuInfo(void); + QString debug_info(struct symbol *sym); + static QString print_filter(const QString &str); + static void expr_print_help(void *data, const char *str); + + struct menu *menu; + bool _showDebug; +}; + +class ConfigSearchWindow : public QDialog { + Q_OBJECT + typedef class QDialog Parent; +public: + ConfigSearchWindow(QWidget* parent); +public slots: + void search(void); +protected: + QLineEdit* editField; + QPushButton* searchButton; + ConfigView* list; + ConfigInfoView* info; + + struct symbol **result; +}; + class ConfigMainWindow : public QMainWindow { Q_OBJECT public: @@ -234,11 +272,11 @@ public slots: void loadConfig(void); void saveConfig(void); void saveConfigAs(void); + void searchConfig(void); void showSingleView(void); void showSplitView(void); void showFullView(void); void setShowAll(bool); - void setShowDebug(bool); void setShowRange(bool); void setShowName(bool); void setShowData(bool); @@ -249,15 +287,14 @@ public slots: protected: void closeEvent(QCloseEvent *e); + ConfigSearchWindow *searchWindow; ConfigView *menuView; ConfigList *menuList; ConfigView *configView; ConfigList *configList; - QTextView *helpText; + ConfigInfoView *helpText; QToolBar *toolBar; QAction *backAction; QSplitter* split1; QSplitter* split2; - - bool showDebug; }; -- cgit v1.2.3 From 7fc925fd6a4c24e1db879d227fc0a0f65a335aa1 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:46 -0700 Subject: kconfig: finer customization via popup menus This allows to configure every symbol list and info window separately via a popup menu, these settings are also separately saved and restored. Cleanup the ConfigSettings class a bit to reduce the number of #ifdef. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/qconf.cc | 486 +++++++++++++++++++++++++++-------------------- scripts/kconfig/qconf.h | 95 +++++---- 2 files changed, 343 insertions(+), 238 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 2befaeac6e64..f3f86e735a87 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -36,6 +36,7 @@ #endif static QApplication *configApp; +static ConfigSettings *configSettings; static inline QString qgettext(const char* str) { @@ -47,23 +48,6 @@ static inline QString qgettext(const QString& str) return QString::fromLocal8Bit(gettext(str.latin1())); } -ConfigSettings::ConfigSettings() - : showAll(false), showName(false), showRange(false), showData(false) -{ -} - -#if QT_VERSION >= 300 -/** - * Reads the list column settings from the application settings. - */ -void ConfigSettings::readListSettings() -{ - showAll = readBoolEntry("/kconfig/qconf/showAll", false); - showName = readBoolEntry("/kconfig/qconf/showName", false); - showRange = readBoolEntry("/kconfig/qconf/showRange", false); - showData = readBoolEntry("/kconfig/qconf/showData", false); -} - /** * Reads a list of integer values from the application settings. */ @@ -92,76 +76,7 @@ bool ConfigSettings::writeSizes(const QString& key, const QValueList& value stringList.push_back(QString::number(*it)); return writeEntry(key, stringList); } -#endif - - -/* - * update all the children of a menu entry - * removes/adds the entries from the parent widget as necessary - * - * parent: either the menu list widget or a menu entry widget - * menu: entry to be updated - */ -template -void ConfigList::updateMenuList(P* parent, struct menu* menu) -{ - struct menu* child; - ConfigItem* item; - ConfigItem* last; - bool visible; - enum prop_type type; - - if (!menu) { - while ((item = parent->firstChild())) - delete item; - return; - } - - last = parent->firstChild(); - if (last && !last->goParent) - last = 0; - for (child = menu->list; child; child = child->next) { - item = last ? last->nextSibling() : parent->firstChild(); - type = child->prompt ? child->prompt->type : P_UNKNOWN; - - switch (mode) { - case menuMode: - if (!(child->flags & MENU_ROOT)) - goto hide; - break; - case symbolMode: - if (child->flags & MENU_ROOT) - goto hide; - break; - default: - break; - } - - visible = menu_is_visible(child); - if (showAll || visible) { - if (!item || item->menu != child) - item = new ConfigItem(parent, last, child, visible); - else - item->testUpdateMenu(visible); - if (mode == fullMode || mode == menuMode || type != P_MENU) - updateMenuList(item, child); - else - updateMenuList(item, 0); - last = item; - continue; - } - hide: - if (item && item->menu == child) { - last = parent->firstChild(); - if (last == item) - last = 0; - else while (last->nextSibling() != item) - last = last->nextSibling(); - delete item; - } - } -} #if QT_VERSION >= 300 /* @@ -395,14 +310,14 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e) hide(); } -ConfigList::ConfigList(ConfigView* p, ConfigSettings* configSettings) - : Parent(p), +ConfigList::ConfigList(ConfigView* p, const char *name) + : Parent(p, name), updateAll(false), symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), showAll(false), showName(false), showRange(false), showData(false), - rootEntry(0) + rootEntry(0), headerPopup(0) { int i; @@ -416,11 +331,14 @@ ConfigList::ConfigList(ConfigView* p, ConfigSettings* configSettings) connect(this, SIGNAL(selectionChanged(void)), SLOT(updateSelection(void))); - if (configSettings) { - showAll = configSettings->showAll; - showName = configSettings->showName; - showRange = configSettings->showRange; - showData = configSettings->showData; + if (name) { + configSettings->beginGroup(name); + showAll = configSettings->readBoolEntry("/showAll", false); + showName = configSettings->readBoolEntry("/showName", false); + showRange = configSettings->readBoolEntry("/showRange", false); + showData = configSettings->readBoolEntry("/showData", false); + configSettings->endGroup(); + connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); } for (i = 0; i < colNr; i++) @@ -451,6 +369,18 @@ void ConfigList::reinit(void) updateListAll(); } +void ConfigList::saveSettings(void) +{ + if (name()) { + configSettings->beginGroup(name()); + configSettings->writeEntry("/showName", showName); + configSettings->writeEntry("/showRange", showRange); + configSettings->writeEntry("/showData", showData); + configSettings->writeEntry("/showAll", showAll); + configSettings->endGroup(); + } +} + void ConfigList::updateSelection(void) { struct menu *menu; @@ -512,14 +442,6 @@ update: triggerUpdate(); } -void ConfigList::setAllOpen(bool open) -{ - QListViewItemIterator it(this); - - for (; it.current(); it++) - it.current()->setOpen(open); -} - void ConfigList::setValue(ConfigItem* item, tristate val) { struct symbol* sym; @@ -624,6 +546,74 @@ void ConfigList::setParentMenu(void) } } +/* + * update all the children of a menu entry + * removes/adds the entries from the parent widget as necessary + * + * parent: either the menu list widget or a menu entry widget + * menu: entry to be updated + */ +template +void ConfigList::updateMenuList(P* parent, struct menu* menu) +{ + struct menu* child; + ConfigItem* item; + ConfigItem* last; + bool visible; + enum prop_type type; + + if (!menu) { + while ((item = parent->firstChild())) + delete item; + return; + } + + last = parent->firstChild(); + if (last && !last->goParent) + last = 0; + for (child = menu->list; child; child = child->next) { + item = last ? last->nextSibling() : parent->firstChild(); + type = child->prompt ? child->prompt->type : P_UNKNOWN; + + switch (mode) { + case menuMode: + if (!(child->flags & MENU_ROOT)) + goto hide; + break; + case symbolMode: + if (child->flags & MENU_ROOT) + goto hide; + break; + default: + break; + } + + visible = menu_is_visible(child); + if (showAll || visible) { + if (!item || item->menu != child) + item = new ConfigItem(parent, last, child, visible); + else + item->testUpdateMenu(visible); + + if (mode == fullMode || mode == menuMode || type != P_MENU) + updateMenuList(item, child); + else + updateMenuList(item, 0); + last = item; + continue; + } + hide: + if (item && item->menu == child) { + last = parent->firstChild(); + if (last == item) + last = 0; + else while (last->nextSibling() != item) + last = last->nextSibling(); + delete item; + } + } +} + void ConfigList::keyPressEvent(QKeyEvent* ev) { QListViewItem* i = currentItem(); @@ -786,12 +776,50 @@ void ConfigList::focusInEvent(QFocusEvent *e) emit gotFocus(); } +void ConfigList::contextMenuEvent(QContextMenuEvent *e) +{ + if (e->y() <= header()->geometry().bottom()) { + if (!headerPopup) { + QAction *action; + + headerPopup = new QPopupMenu(this); + action = new QAction("Show Name", 0, this); + action->setToggleAction(TRUE); + connect(action, SIGNAL(toggled(bool)), + parent(), SLOT(setShowName(bool))); + connect(parent(), SIGNAL(showNameChanged(bool)), + action, SLOT(setOn(bool))); + action->setOn(showName); + action->addTo(headerPopup); + action = new QAction("Show Range", 0, this); + action->setToggleAction(TRUE); + connect(action, SIGNAL(toggled(bool)), + parent(), SLOT(setShowRange(bool))); + connect(parent(), SIGNAL(showRangeChanged(bool)), + action, SLOT(setOn(bool))); + action->setOn(showRange); + action->addTo(headerPopup); + action = new QAction("Show Data", 0, this); + action->setToggleAction(TRUE); + connect(action, SIGNAL(toggled(bool)), + parent(), SLOT(setShowData(bool))); + connect(parent(), SIGNAL(showDataChanged(bool)), + action, SLOT(setOn(bool))); + action->setOn(showData); + action->addTo(headerPopup); + } + headerPopup->exec(e->globalPos()); + e->accept(); + } else + e->ignore(); +} + ConfigView* ConfigView::viewList; -ConfigView::ConfigView(QWidget* parent, ConfigSettings *configSettings) - : Parent(parent) +ConfigView::ConfigView(QWidget* parent, const char *name) + : Parent(parent, name) { - list = new ConfigList(this, configSettings); + list = new ConfigList(this, name); lineEdit = new ConfigLineEdit(this); lineEdit->hide(); @@ -811,6 +839,50 @@ ConfigView::~ConfigView(void) } } +void ConfigView::setShowAll(bool b) +{ + if (list->showAll != b) { + list->showAll = b; + list->updateListAll(); + emit showAllChanged(b); + } +} + +void ConfigView::setShowName(bool b) +{ + if (list->showName != b) { + list->showName = b; + list->reinit(); + emit showNameChanged(b); + } +} + +void ConfigView::setShowRange(bool b) +{ + if (list->showRange != b) { + list->showRange = b; + list->reinit(); + emit showRangeChanged(b); + } +} + +void ConfigView::setShowData(bool b) +{ + if (list->showData != b) { + list->showData = b; + list->reinit(); + emit showDataChanged(b); + } +} + +void ConfigList::setAllOpen(bool open) +{ + QListViewItemIterator it(this); + + for (; it.current(); it++) + it.current()->setOpen(open); +} + void ConfigView::updateList(ConfigItem* item) { ConfigView* v; @@ -830,6 +902,21 @@ void ConfigView::updateListAll(void) ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) : Parent(parent, name), menu(0) { + if (name) { + configSettings->beginGroup(name); + _showDebug = configSettings->readBoolEntry("/showDebug", false); + configSettings->endGroup(); + connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + } +} + +void ConfigInfoView::saveSettings(void) +{ + if (name()) { + configSettings->beginGroup(name()); + configSettings->writeEntry("/showDebug", showDebug()); + configSettings->endGroup(); + } } void ConfigInfoView::setShowDebug(bool b) @@ -1006,8 +1093,26 @@ void ConfigInfoView::expr_print_help(void *data, const char *str) reinterpret_cast(data)->append(print_filter(str)); } -ConfigSearchWindow::ConfigSearchWindow(QWidget* parent) - : Parent(parent), result(NULL) +QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) +{ + QPopupMenu* popup = Parent::createPopupMenu(pos); + QAction* action = new QAction("Show Debug Info", 0, popup); + action->setToggleAction(TRUE); + connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); + connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); + action->setOn(showDebug()); + popup->insertSeparator(); + action->addTo(popup); + return popup; +} + +void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e) +{ + Parent::contentsContextMenuEvent(e); +} + +ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name) + : Parent(parent, name), result(NULL) { setCaption("Search Config"); @@ -1023,14 +1128,47 @@ ConfigSearchWindow::ConfigSearchWindow(QWidget* parent) layout2->addWidget(searchButton); layout1->addLayout(layout2); - QSplitter* split = new QSplitter(this); + split = new QSplitter(this); split->setOrientation(QSplitter::Vertical); - list = new ConfigView(split, NULL); + list = new ConfigView(split, name); list->list->mode = listMode; - info = new ConfigInfoView(split); + info = new ConfigInfoView(split, name); connect(list->list, SIGNAL(menuChanged(struct menu *)), info, SLOT(setInfo(struct menu *))); layout1->addWidget(split); + + if (name) { + int x, y, width, height; + bool ok; + + configSettings->beginGroup(name); + width = configSettings->readNumEntry("/window width", parent->width() / 2); + height = configSettings->readNumEntry("/window height", parent->height() / 2); + resize(width, height); + x = configSettings->readNumEntry("/window x", 0, &ok); + if (ok) + y = configSettings->readNumEntry("/window y", 0, &ok); + if (ok) + move(x, y); + QValueList sizes = configSettings->readSizes("/split", &ok); + if (ok) + split->setSizes(sizes); + configSettings->endGroup(); + connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); + } +} + +void ConfigSearchWindow::saveSettings(void) +{ + if (name()) { + configSettings->beginGroup(name()); + configSettings->writeEntry("/window x", pos().x()); + configSettings->writeEntry("/window y", pos().y()); + configSettings->writeEntry("/window width", size().width()); + configSettings->writeEntry("/window height", size().height()); + configSettings->writeSizes("/split", split->sizes()); + configSettings->endGroup(); + } } void ConfigSearchWindow::search(void) @@ -1058,49 +1196,36 @@ void ConfigSearchWindow::search(void) ConfigMainWindow::ConfigMainWindow(void) { QMenuBar* menu; - bool ok, showDebug; + bool ok; int x, y, width, height; QWidget *d = configApp->desktop(); - ConfigSettings* configSettings = new ConfigSettings(); -#if QT_VERSION >= 300 - width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64); - height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64); + width = configSettings->readNumEntry("/window width", d->width() - 64); + height = configSettings->readNumEntry("/window height", d->height() - 64); resize(width, height); - x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok); + x = configSettings->readNumEntry("/window x", 0, &ok); if (ok) - y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok); + y = configSettings->readNumEntry("/window y", 0, &ok); if (ok) move(x, y); - showDebug = configSettings->readBoolEntry("/kconfig/qconf/showDebug", false); - - // read list settings into configSettings, will be used later for ConfigList setup - configSettings->readListSettings(); -#else - width = d->width() - 64; - height = d->height() - 64; - resize(width, height); - showDebug = false; -#endif split1 = new QSplitter(this); split1->setOrientation(QSplitter::Horizontal); setCentralWidget(split1); - menuView = new ConfigView(split1, configSettings); + menuView = new ConfigView(split1, "menu"); menuList = menuView->list; split2 = new QSplitter(split1); split2->setOrientation(QSplitter::Vertical); // create config tree - configView = new ConfigView(split2, configSettings); + configView = new ConfigView(split2, "config"); configList = configView->list; - helpText = new ConfigInfoView(split2); + helpText = new ConfigInfoView(split2, "help"); helpText->setTextFormat(Qt::RichText); - helpText->setShowDebug(showDebug); setTabOrder(configList, helpText); configList->setFocus(); @@ -1130,25 +1255,29 @@ ConfigMainWindow::ConfigMainWindow(void) QAction *showNameAction = new QAction(NULL, "Show Name", 0, this); showNameAction->setToggleAction(TRUE); - showNameAction->setOn(configList->showName); - connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool))); + connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); + connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool))); + showNameAction->setOn(configView->showName()); QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this); showRangeAction->setToggleAction(TRUE); + connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); + connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool))); showRangeAction->setOn(configList->showRange); - connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool))); QAction *showDataAction = new QAction(NULL, "Show Data", 0, this); showDataAction->setToggleAction(TRUE); + connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); + connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); showDataAction->setOn(configList->showData); - connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool))); QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this); showAllAction->setToggleAction(TRUE); + connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); + connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); showAllAction->setOn(configList->showAll); - connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool))); QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); showDebugAction->setToggleAction(TRUE); - showDebugAction->setOn(showDebug); connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); + showDebugAction->setOn(helpText->showDebug()); QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this); connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); @@ -1209,8 +1338,7 @@ ConfigMainWindow::ConfigMainWindow(void) connect(menuList, SIGNAL(gotFocus(void)), SLOT(listFocusChanged(void))); -#if QT_VERSION >= 300 - QString listMode = configSettings->readEntry("/kconfig/qconf/listMode", "symbol"); + QString listMode = configSettings->readEntry("/listMode", "symbol"); if (listMode == "single") showSingleView(); else if (listMode == "full") @@ -1219,17 +1347,13 @@ ConfigMainWindow::ConfigMainWindow(void) showSplitView(); // UI setup done, restore splitter positions - QValueList sizes = configSettings->readSizes("/kconfig/qconf/split1", &ok); + QValueList sizes = configSettings->readSizes("/split1", &ok); if (ok) split1->setSizes(sizes); - sizes = configSettings->readSizes("/kconfig/qconf/split2", &ok); + sizes = configSettings->readSizes("/split2", &ok); if (ok) split2->setSizes(sizes); -#else - showSplitView(); -#endif - delete configSettings; } /* @@ -1237,7 +1361,6 @@ ConfigMainWindow::ConfigMainWindow(void) */ void ConfigMainWindow::setHelp(QListViewItem* item) { - struct symbol* sym; struct menu* menu = 0; if (item) @@ -1273,7 +1396,7 @@ void ConfigMainWindow::saveConfigAs(void) void ConfigMainWindow::searchConfig(void) { if (!searchWindow) - searchWindow = new ConfigSearchWindow(this); + searchWindow = new ConfigSearchWindow(this, "search"); searchWindow->show(); } @@ -1353,46 +1476,6 @@ void ConfigMainWindow::showFullView(void) configList->setFocus(); } -void ConfigMainWindow::setShowAll(bool b) -{ - if (configList->showAll == b) - return; - configList->showAll = b; - configList->updateListAll(); - menuList->showAll = b; - menuList->updateListAll(); -} - -void ConfigMainWindow::setShowName(bool b) -{ - if (configList->showName == b) - return; - configList->showName = b; - configList->reinit(); - menuList->showName = b; - menuList->reinit(); -} - -void ConfigMainWindow::setShowRange(bool b) -{ - if (configList->showRange == b) - return; - configList->showRange = b; - configList->reinit(); - menuList->showRange = b; - menuList->reinit(); -} - -void ConfigMainWindow::setShowData(bool b) -{ - if (configList->showData == b) - return; - configList->showData = b; - configList->reinit(); - menuList->showData = b; - menuList->reinit(); -} - /* * ask for saving configuration before quitting * TODO ask only when something changed @@ -1447,17 +1530,10 @@ void ConfigMainWindow::showAbout(void) void ConfigMainWindow::saveSettings(void) { -#if QT_VERSION >= 300 - ConfigSettings *configSettings = new ConfigSettings; - configSettings->writeEntry("/kconfig/qconf/window x", pos().x()); - configSettings->writeEntry("/kconfig/qconf/window y", pos().y()); - configSettings->writeEntry("/kconfig/qconf/window width", size().width()); - configSettings->writeEntry("/kconfig/qconf/window height", size().height()); - configSettings->writeEntry("/kconfig/qconf/showName", configList->showName); - configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange); - configSettings->writeEntry("/kconfig/qconf/showData", configList->showData); - configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll); - configSettings->writeEntry("/kconfig/qconf/showDebug", helpText->showDebug()); + configSettings->writeEntry("/window x", pos().x()); + configSettings->writeEntry("/window y", pos().y()); + configSettings->writeEntry("/window width", size().width()); + configSettings->writeEntry("/window height", size().height()); QString entry; switch(configList->mode) { @@ -1473,13 +1549,10 @@ void ConfigMainWindow::saveSettings(void) entry = "full"; break; } - configSettings->writeEntry("/kconfig/qconf/listMode", entry); + configSettings->writeEntry("/listMode", entry); - configSettings->writeSizes("/kconfig/qconf/split1", split1->sizes()); - configSettings->writeSizes("/kconfig/qconf/split2", split2->sizes()); - - delete configSettings; -#endif + configSettings->writeSizes("/split1", split1->sizes()); + configSettings->writeSizes("/split2", split2->sizes()); } void fixup_rootmenu(struct menu *menu) @@ -1537,6 +1610,8 @@ int main(int ac, char** av) conf_read(NULL); //zconfdump(stdout); + configSettings = new ConfigSettings(); + configSettings->beginGroup("/kconfig/qconf"); v = new ConfigMainWindow(); //zconfdump(stdout); @@ -1546,5 +1621,8 @@ int main(int ac, char** av) v->show(); configApp->exec(); + configSettings->endGroup(); + delete configSettings; + return 0; } diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index a548d13149b3..fb50e1c6029f 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -7,9 +7,25 @@ #if QT_VERSION >= 300 #include #else -class QSettings { }; +class QSettings { +public: + void beginGroup(const QString& group) { } + void endGroup(void) { } + bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const + { if (ok) *ok = FALSE; return def; } + int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const + { if (ok) *ok = FALSE; return def; } + QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const + { if (ok) *ok = FALSE; return def; } + QStringList readListEntry(const QString& key, bool* ok = 0) const + { if (ok) *ok = FALSE; return QStringList(); } + template + bool writeEntry(const QString& key, t value) + { return TRUE; } +}; #endif +class ConfigView; class ConfigList; class ConfigItem; class ConfigLineEdit; @@ -18,35 +34,8 @@ class ConfigMainWindow; class ConfigSettings : public QSettings { public: - ConfigSettings(); - -#if QT_VERSION >= 300 - void readListSettings(); QValueList readSizes(const QString& key, bool *ok); bool writeSizes(const QString& key, const QValueList& value); -#endif - - bool showAll; - bool showName; - bool showRange; - bool showData; -}; - -class ConfigView : public QVBox { - Q_OBJECT - typedef class QVBox Parent; -public: - ConfigView(QWidget* parent, ConfigSettings* configSettings); - ~ConfigView(void); - static void updateList(ConfigItem* item); - static void updateListAll(void); - -public: - ConfigList* list; - ConfigLineEdit* lineEdit; - - static ConfigView* viewList; - ConfigView* nextView; }; enum colIdx { @@ -60,7 +49,7 @@ class ConfigList : public QListView { Q_OBJECT typedef class QListView Parent; public: - ConfigList(ConfigView* p, ConfigSettings *configSettings); + ConfigList(ConfigView* p, const char *name = 0); void reinit(void); ConfigView* parent(void) const { @@ -74,6 +63,8 @@ protected: void contentsMouseMoveEvent(QMouseEvent *e); void contentsMouseDoubleClickEvent(QMouseEvent *e); void focusInEvent(QFocusEvent *e); + void contextMenuEvent(QContextMenuEvent *e); + public slots: void setRootMenu(struct menu *menu); @@ -81,6 +72,7 @@ public slots: void setValue(ConfigItem* item, tristate val); void changeValue(ConfigItem* item); void updateSelection(void); + void saveSettings(void); signals: void menuChanged(struct menu *menu); void menuSelected(struct menu *menu); @@ -136,6 +128,7 @@ public: struct menu *rootEntry; QColorGroup disabledColorGroup; QColorGroup inactivedColorGroup; + QPopupMenu* headerPopup; private: int colMap[colNr]; @@ -219,6 +212,37 @@ public: ConfigItem *item; }; +class ConfigView : public QVBox { + Q_OBJECT + typedef class QVBox Parent; +public: + ConfigView(QWidget* parent, const char *name = 0); + ~ConfigView(void); + static void updateList(ConfigItem* item); + static void updateListAll(void); + + bool showAll(void) const { return list->showAll; } + bool showName(void) const { return list->showName; } + bool showRange(void) const { return list->showRange; } + bool showData(void) const { return list->showData; } +public slots: + void setShowAll(bool); + void setShowName(bool); + void setShowRange(bool); + void setShowData(bool); +signals: + void showAllChanged(bool); + void showNameChanged(bool); + void showRangeChanged(bool); + void showDataChanged(bool); +public: + ConfigList* list; + ConfigLineEdit* lineEdit; + + static ConfigView* viewList; + ConfigView* nextView; +}; + class ConfigInfoView : public QTextBrowser { Q_OBJECT typedef class QTextBrowser Parent; @@ -228,6 +252,7 @@ public: public slots: void setInfo(struct menu *menu); + void saveSettings(void); void setSource(const QString& name); void setShowDebug(bool); @@ -239,6 +264,8 @@ protected: QString debug_info(struct symbol *sym); static QString print_filter(const QString &str); static void expr_print_help(void *data, const char *str); + QPopupMenu* createPopupMenu(const QPoint& pos); + void contentsContextMenuEvent(QContextMenuEvent *e); struct menu *menu; bool _showDebug; @@ -248,12 +275,16 @@ class ConfigSearchWindow : public QDialog { Q_OBJECT typedef class QDialog Parent; public: - ConfigSearchWindow(QWidget* parent); + ConfigSearchWindow(QWidget* parent, const char *name = 0); + public slots: + void saveSettings(void); void search(void); + protected: QLineEdit* editField; QPushButton* searchButton; + QSplitter* split; ConfigView* list; ConfigInfoView* info; @@ -276,10 +307,6 @@ public slots: void showSingleView(void); void showSplitView(void); void showFullView(void); - void setShowAll(bool); - void setShowRange(bool); - void setShowName(bool); - void setShowData(bool); void showIntro(void); void showAbout(void); void saveSettings(void); -- cgit v1.2.3 From ab45d190fd4acf0b0e5d307294ce24a90a69cc23 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:47 -0700 Subject: kconfig: create links in info window Extend the expression print helper function to allow customization of the symbol output and use it to add links to the info window. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/expr.c | 50 +++++++++++++++++++-------------------- scripts/kconfig/lkc_proto.h | 2 +- scripts/kconfig/qconf.cc | 57 +++++++++++++++++++++++++++++++++++++++++---- scripts/kconfig/qconf.h | 4 +++- 4 files changed, 81 insertions(+), 32 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 87238afb21b7..6f98dbfe70cf 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1013,73 +1013,73 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) #endif } -void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) +void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) { if (!e) { - fn(data, "y"); + fn(data, NULL, "y"); return; } if (expr_compare_type(prevtoken, e->type) > 0) - fn(data, "("); + fn(data, NULL, "("); switch (e->type) { case E_SYMBOL: if (e->left.sym->name) - fn(data, e->left.sym->name); + fn(data, e->left.sym, e->left.sym->name); else - fn(data, ""); + fn(data, NULL, ""); break; case E_NOT: - fn(data, "!"); + fn(data, NULL, "!"); expr_print(e->left.expr, fn, data, E_NOT); break; case E_EQUAL: - fn(data, e->left.sym->name); - fn(data, "="); - fn(data, e->right.sym->name); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, "="); + fn(data, e->right.sym, e->right.sym->name); break; case E_UNEQUAL: - fn(data, e->left.sym->name); - fn(data, "!="); - fn(data, e->right.sym->name); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, "!="); + fn(data, e->right.sym, e->right.sym->name); break; case E_OR: expr_print(e->left.expr, fn, data, E_OR); - fn(data, " || "); + fn(data, NULL, " || "); expr_print(e->right.expr, fn, data, E_OR); break; case E_AND: expr_print(e->left.expr, fn, data, E_AND); - fn(data, " && "); + fn(data, NULL, " && "); expr_print(e->right.expr, fn, data, E_AND); break; case E_CHOICE: - fn(data, e->right.sym->name); + fn(data, e->right.sym, e->right.sym->name); if (e->left.expr) { - fn(data, " ^ "); + fn(data, NULL, " ^ "); 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, "]"); + fn(data, NULL, "["); + fn(data, e->left.sym, e->left.sym->name); + fn(data, NULL, " "); + fn(data, e->right.sym, e->right.sym->name); + fn(data, NULL, "]"); break; default: { char buf[32]; sprintf(buf, "", e->type); - fn(data, buf); + fn(data, NULL, buf); break; } } if (expr_compare_type(prevtoken, e->type) > 0) - fn(data, ")"); + fn(data, NULL, ")"); } -static void expr_print_file_helper(void *data, const char *str) +static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) { fwrite(str, strlen(str), 1, data); } @@ -1089,7 +1089,7 @@ void expr_fprint(struct expr *e, FILE *out) expr_print(e, expr_print_file_helper, out, E_NONE); } -static void expr_print_gstr_helper(void *data, const char *str) +static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) { str_append((struct gstr*)data, str); } diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index e195c455bfef..a263746cfa7d 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -39,4 +39,4 @@ P(prop_get_type_name,const char *,(enum prop_type type)); /* expr.c */ P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); -P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); +P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)); diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index f3f86e735a87..425ce5ce2d12 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -925,6 +925,8 @@ void ConfigInfoView::setShowDebug(bool b) _showDebug = b; if (menu) menuInfo(); + else if (sym) + symbolInfo(); emit showDebugChanged(b); } } @@ -943,15 +945,44 @@ void ConfigInfoView::setSource(const QString& name) const char *p = name.latin1(); menu = NULL; + sym = NULL; switch (p[0]) { case 'm': - if (sscanf(p, "m%p", &menu) == 1) + struct menu *m; + + if (sscanf(p, "m%p", &m) == 1 && menu != m) { + menu = m; menuInfo(); + } + break; + case 's': + struct symbol *s; + + if (sscanf(p, "s%p", &s) == 1 && sym != s) { + sym = s; + symbolInfo(); + } break; } } +void ConfigInfoView::symbolInfo(void) +{ + QString str; + + str += "Symbol: "; + str += print_filter(sym->name); + str += "

value: "; + str += print_filter(sym_get_string_value(sym)); + str += "
visibility: "; + str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n"; + str += "
"; + str += debug_info(sym); + + setText(str); +} + void ConfigInfoView::menuInfo(void) { struct symbol* sym; @@ -965,12 +996,20 @@ void ConfigInfoView::menuInfo(void) head += ""; if (sym->name) { head += " ("; + if (showDebug()) + head += QString().sprintf("", sym); head += print_filter(sym->name); + if (showDebug()) + head += ""; head += ")"; } } else if (sym->name) { head += ""; + if (showDebug()) + head += QString().sprintf("", sym); head += print_filter(sym->name); + if (showDebug()) + head += ""; head += ""; } head += "

"; @@ -1015,9 +1054,9 @@ QString ConfigInfoView::debug_info(struct symbol *sym) switch (prop->type) { case P_PROMPT: case P_MENU: - debug += "prompt: "; + debug += QString().sprintf("prompt: ", prop->menu); debug += print_filter(_(prop->text)); - debug += "
"; + debug += "

"; break; case P_DEFAULT: debug += "default: "; @@ -1088,9 +1127,17 @@ QString ConfigInfoView::print_filter(const QString &str) return res; } -void ConfigInfoView::expr_print_help(void *data, const char *str) +void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str) { - reinterpret_cast(data)->append(print_filter(str)); + QString* text = reinterpret_cast(data); + QString str2 = print_filter(str); + + if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { + *text += QString().sprintf("", sym); + *text += str2; + *text += ""; + } else + *text += str2; } QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index fb50e1c6029f..b824f78cc06d 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -260,13 +260,15 @@ signals: void showDebugChanged(bool); protected: + void symbolInfo(void); void menuInfo(void); QString debug_info(struct symbol *sym); static QString print_filter(const QString &str); - static void expr_print_help(void *data, const char *str); + static void expr_print_help(void *data, struct symbol *sym, const char *str); QPopupMenu* createPopupMenu(const QPoint& pos); void contentsContextMenuEvent(QContextMenuEvent *e); + struct symbol *sym; struct menu *menu; bool _showDebug; }; -- cgit v1.2.3 From b65a47e1ac494777d853d7952cef611eedc22037 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:47 -0700 Subject: kconfig: jump to linked menu prompt If clicking on of the links, which leads to a visible prompt, jump to it in the symbol list. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/qconf.cc | 109 +++++++++++++++++++++++++++++++++++------------ scripts/kconfig/qconf.h | 6 ++- 2 files changed, 86 insertions(+), 29 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 425ce5ce2d12..393f3749f330 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -381,6 +381,18 @@ void ConfigList::saveSettings(void) } } +ConfigItem* ConfigList::findConfigItem(struct menu *menu) +{ + ConfigItem* item = (ConfigItem*)menu->data; + + for (; item; item = item->nextItem) { + if (this == item->listView()) + break; + } + + return item; +} + void ConfigList::updateSelection(void) { struct menu *menu; @@ -524,6 +536,7 @@ void ConfigList::setRootMenu(struct menu *menu) rootEntry = menu; updateListAll(); setSelected(currentItem(), hasFocus()); + ensureItemVisible(currentItem()); } void ConfigList::setParentMenu(void) @@ -766,14 +779,16 @@ skip: void ConfigList::focusInEvent(QFocusEvent *e) { - Parent::focusInEvent(e); + struct menu *menu = NULL; - QListViewItem* item = currentItem(); - if (!item) - return; + Parent::focusInEvent(e); - setSelected(item, TRUE); - emit gotFocus(); + ConfigItem* item = (ConfigItem *)currentItem(); + if (item) { + setSelected(item, TRUE); + menu = item->menu; + } + emit gotFocus(menu); } void ConfigList::contextMenuEvent(QContextMenuEvent *e) @@ -933,6 +948,8 @@ void ConfigInfoView::setShowDebug(bool b) void ConfigInfoView::setInfo(struct menu *m) { + if (menu == m) + return; menu = m; if (!menu) clear(); @@ -954,6 +971,7 @@ void ConfigInfoView::setSource(const QString& name) if (sscanf(p, "m%p", &m) == 1 && menu != m) { menu = m; menuInfo(); + emit menuSelected(menu); } break; case 's': @@ -1380,10 +1398,14 @@ ConfigMainWindow::ConfigMainWindow(void) connect(menuList, SIGNAL(menuSelected(struct menu *)), SLOT(changeMenu(struct menu *))); - connect(configList, SIGNAL(gotFocus(void)), - SLOT(listFocusChanged(void))); - connect(menuList, SIGNAL(gotFocus(void)), + connect(configList, SIGNAL(gotFocus(struct menu *)), + helpText, SLOT(setInfo(struct menu *))); + connect(menuList, SIGNAL(gotFocus(struct menu *)), + helpText, SLOT(setInfo(struct menu *))); + connect(menuList, SIGNAL(gotFocus(struct menu *)), SLOT(listFocusChanged(void))); + connect(helpText, SIGNAL(menuSelected(struct menu *)), + SLOT(setMenuLink(struct menu *))); QString listMode = configSettings->readEntry("/listMode", "symbol"); if (listMode == "single") @@ -1403,18 +1425,6 @@ ConfigMainWindow::ConfigMainWindow(void) split2->setSizes(sizes); } -/* - * display a new help entry as soon as a new menu entry is selected - */ -void ConfigMainWindow::setHelp(QListViewItem* item) -{ - struct menu* menu = 0; - - if (item) - menu = ((ConfigItem*)item)->menu; - helpText->setInfo(menu); -} - void ConfigMainWindow::loadConfig(void) { QString s = QFileDialog::getOpenFileName(".config", NULL, this); @@ -1453,17 +1463,62 @@ void ConfigMainWindow::changeMenu(struct menu *menu) backAction->setEnabled(TRUE); } -void ConfigMainWindow::listFocusChanged(void) +void ConfigMainWindow::setMenuLink(struct menu *menu) { - if (menuList->hasFocus()) { - if (menuList->mode == menuMode) + struct menu *parent; + ConfigList* list = NULL; + ConfigItem* item; + + if (!menu_is_visible(menu) && !configView->showAll()) + return; + + switch (configList->mode) { + case singleMode: + list = configList; + parent = menu_get_parent_menu(menu); + if (!parent) + return; + list->setRootMenu(parent); + break; + case symbolMode: + if (menu->flags & MENU_ROOT) { + configList->setRootMenu(menu); configList->clearSelection(); - setHelp(menuList->selectedItem()); - } else if (configList->hasFocus()) { - setHelp(configList->selectedItem()); + list = menuList; + } else { + list = configList; + parent = menu_get_parent_menu(menu->parent); + if (!parent) + return; + item = menuList->findConfigItem(parent); + if (item) { + menuList->setSelected(item, TRUE); + menuList->ensureItemVisible(item); + } + list->setRootMenu(parent); + } + break; + case fullMode: + list = configList; + break; + } + + if (list) { + item = list->findConfigItem(menu); + if (item) { + list->setSelected(item, TRUE); + list->ensureItemVisible(item); + list->setFocus(); + } } } +void ConfigMainWindow::listFocusChanged(void) +{ + if (menuList->mode == menuMode) + configList->clearSelection(); +} + void ConfigMainWindow::goBack(void) { ConfigItem* item; diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index b824f78cc06d..6a9e3b14c227 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -55,6 +55,7 @@ public: { return (ConfigView*)Parent::parent(); } + ConfigItem* findConfigItem(struct menu *); protected: void keyPressEvent(QKeyEvent *e); @@ -77,7 +78,7 @@ signals: void menuChanged(struct menu *menu); void menuSelected(struct menu *menu); void parentSelected(void); - void gotFocus(void); + void gotFocus(struct menu *); public: void updateListAll(void) @@ -258,6 +259,7 @@ public slots: signals: void showDebugChanged(bool); + void menuSelected(struct menu *); protected: void symbolInfo(void); @@ -298,8 +300,8 @@ class ConfigMainWindow : public QMainWindow { public: ConfigMainWindow(void); public slots: - void setHelp(QListViewItem* item); void changeMenu(struct menu *); + void setMenuLink(struct menu *); void listFocusChanged(void); void goBack(void); void loadConfig(void); -- cgit v1.2.3 From f001f7f89689d3226678ab3986f3a486f54aa069 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:48 -0700 Subject: kconfig: warn about leading whitespace for menu prompts Kconfig does its own indentation of menu prompts, so warn about and ignore leading whitespace. Remove also a few unnecessary newlines after other warning prints. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/menu.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index a8afce24fb1b..c86c27f2c761 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -114,7 +114,7 @@ void menu_set_type(int type) sym->type = type; return; } - menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n", + menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", sym->name ? sym->name : "", sym_type_name(sym->type), sym_type_name(type)); } @@ -124,15 +124,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e struct property *prop = prop_alloc(type, current_entry->sym); prop->menu = current_entry; - prop->text = prompt; prop->expr = expr; prop->visible.expr = menu_check_dep(dep); if (prompt) { + if (isspace(*prompt)) { + prop_warn(prop, "leading whitespace ignored"); + while (isspace(*prompt)) + prompt++; + } if (current_entry->prompt) - menu_warn(current_entry, "prompt redefined\n"); + prop_warn(prop, "prompt redefined"); current_entry->prompt = prop; } + prop->text = prompt; return prop; } @@ -343,11 +348,10 @@ void menu_finalize(struct menu *parent) if (sym && !(sym->flags & SYMBOL_WARNED)) { if (sym->type == S_UNKNOWN) - menu_warn(parent, "config symbol defined " - "without type\n"); + menu_warn(parent, "config symbol defined without type"); if (sym_is_choice(sym) && !parent->prompt) - menu_warn(parent, "choice must have a prompt\n"); + menu_warn(parent, "choice must have a prompt"); /* Check properties connected to this symbol */ sym_check_prop(sym); -- cgit v1.2.3 From 250725aa13f5c9595e5bc265ebed8471e816d8b4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 8 Jun 2006 22:12:50 -0700 Subject: kconfig: exit if no beginning filename If the beginning Kconfig file is missing, config segfaults so it might as well exit after the error message. Signed-off-by: Randy Dunlap Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/kconfig/conf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index ded5ffe184b8..4dcb8867b5f4 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -539,6 +539,7 @@ int main(int ac, char **av) name = av[i]; if (!name) { printf(_("%s: Kconfig file missing\n"), av[0]); + exit(1); } conf_parse(name); //zconfdump(stdout); -- cgit v1.2.3 From 14cdd3c402bf7c66f0bcd76e290f0770a54a4b21 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Thu, 8 Jun 2006 22:12:51 -0700 Subject: kconfig: KCONFIG_OVERWRITECONFIG If you set KCONFIG_OVERWRITECONFIG in environment, Kconfig will not break symlinks when .config is a symlink to somewhere else. Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- Makefile | 6 ++++-- scripts/kconfig/confdata.c | 46 +++++++++++++++++++++++++++++----------------- scripts/kconfig/lkc.h | 2 -- 3 files changed, 33 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 3c55de99ed31..3cb9270c584d 100644 --- a/Makefile +++ b/Makefile @@ -178,6 +178,8 @@ CROSS_COMPILE ?= # Architecture as present in compile.h UTS_MACHINE := $(ARCH) +KCONFIG_CONFIG ?= .config + # SHELL used by kbuild CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; then echo /bin/bash; \ @@ -437,13 +439,13 @@ ifeq ($(dot-config),1) -include include/config/auto.conf # To avoid any implicit rule to kick in, define an empty command -.config include/config/auto.conf.cmd: ; +$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # If .config is newer than include/config/auto.conf, someone tinkered # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probarly in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/config/auto.conf: .config include/config/auto.conf.cmd +include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 5bd66f451189..2ee48c377b66 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -21,8 +21,6 @@ static void conf_warning(const char *fmt, ...) static const char *conf_filename; static int conf_lineno, conf_warnings, conf_unsaved; -const char conf_def_filename[] = ".config"; - const char conf_defname[] = "arch/$ARCH/defconfig"; static void conf_warning(const char *fmt, ...) @@ -36,6 +34,13 @@ static void conf_warning(const char *fmt, ...) conf_warnings++; } +const char *conf_get_configname(void) +{ + char *name = getenv("KCONFIG_CONFIG"); + + return name ? name : ".config"; +} + static char *conf_expand_value(const char *in) { struct symbol *sym; @@ -91,7 +96,7 @@ int conf_read_simple(const char *name, int def) } else { struct property *prop; - name = conf_def_filename; + name = conf_get_configname(); in = zconf_fopen(name); if (in) goto load; @@ -381,7 +386,7 @@ int conf_write(const char *name) if (!stat(name, &st) && S_ISDIR(st.st_mode)) { strcpy(dirname, name); strcat(dirname, "/"); - basename = conf_def_filename; + basename = conf_get_configname(); } else if ((slash = strrchr(name, '/'))) { int size = slash - name + 1; memcpy(dirname, name, size); @@ -389,16 +394,24 @@ int conf_write(const char *name) if (slash[1]) basename = slash + 1; else - basename = conf_def_filename; + basename = conf_get_configname(); } else basename = name; } else - basename = conf_def_filename; + basename = conf_get_configname(); - sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(newname, "w"); + sprintf(newname, "%s%s", dirname, basename); + env = getenv("KCONFIG_OVERWRITECONFIG"); + if (!env || !*env) { + sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); + out = fopen(tmpname, "w"); + } else { + *tmpname = 0; + out = fopen(newname, "w"); + } if (!out) return 1; + sym = sym_lookup("KERNELVERSION", 0); sym_calc_value(sym); time(&now); @@ -498,19 +511,18 @@ int conf_write(const char *name) } } fclose(out); - if (!name || basename != conf_def_filename) { - if (!name) - name = conf_def_filename; - sprintf(tmpname, "%s.old", name); - rename(name, tmpname); + + if (*tmpname) { + strcat(dirname, name ? name : conf_get_configname()); + strcat(dirname, ".old"); + rename(newname, dirname); + if (rename(tmpname, newname)) + return 1; } - sprintf(tmpname, "%s%s", dirname, basename); - if (rename(newname, tmpname)) - return 1; printf(_("#\n" "# configuration written to %s\n" - "#\n"), tmpname); + "#\n"), newname); sym_change_count = 0; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 2d3d4ed3c9f2..2628023a1fe1 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -64,8 +64,6 @@ int zconf_lineno(void); char *zconf_curname(void); /* confdata.c */ -extern const char conf_def_filename[]; - char *conf_get_default_confname(void); /* kconfig_load.c */ -- cgit v1.2.3 From bd5cbcedf446e2f37cf2a37f533a7e1d7dff9312 Mon Sep 17 00:00:00 2001 From: Ram Pai Date: Thu, 8 Jun 2006 22:12:53 -0700 Subject: kbuild: export-type enhancement to modpost.c This patch provides the ability to identify the export-type of each exported symbols in Module.symvers. NOTE: It updates the Module.symvers file with the additional information as shown below. 0x0f8b92af platform_device_add_resources vmlinux EXPORT_SYMBOL_GPL 0xcf7efb2a ethtool_op_set_tx_csum vmlinux EXPORT_SYMBOL Signed-off-by: Andreas Gruenbacher Signed-off-by: Ram Pai Signed-off-by: Avantika Mathur Signed-off-by: Valdis Kletnieks Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 93 ++++++++++++++++++++++++++++++++++++++++++--------- scripts/mod/modpost.h | 3 ++ 2 files changed, 80 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a70f5ddb705c..ba2e4fc2af20 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -22,6 +22,8 @@ int have_vmlinux = 0; static int all_versions = 0; /* If we are modposting external module set to 1 */ static int external_module = 0; +/* How a symbol is exported */ +enum export {export_plain, export_gpl, export_gpl_future, export_unknown}; void fatal(const char *fmt, ...) { @@ -118,6 +120,7 @@ struct symbol { unsigned int kernel:1; /* 1 if symbol is from kernel * (only for external modules) **/ unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ + enum export export; /* Type of export */ char name[0]; }; @@ -153,7 +156,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, } /* For the hash of exported symbols */ -static struct symbol *new_symbol(const char *name, struct module *module) +static struct symbol *new_symbol(const char *name, struct module *module, + enum export export) { unsigned int hash; struct symbol *new; @@ -161,6 +165,7 @@ static struct symbol *new_symbol(const char *name, struct module *module) hash = tdb_hash(name) % SYMBOL_HASH_SIZE; new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); new->module = module; + new->export = export; return new; } @@ -179,16 +184,55 @@ static struct symbol *find_symbol(const char *name) return NULL; } +static struct { + const char *str; + enum export export; +} export_list[] = { + { .str = "EXPORT_SYMBOL", .export = export_plain }, + { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, + { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future }, + { .str = "(unknown)", .export = export_unknown }, +}; + + +static const char *export_str(enum export ex) +{ + return export_list[ex].str; +} + +static enum export export_no(const char * s) +{ + int i; + for (i = 0; export_list[i].export != export_unknown; i++) { + if (strcmp(export_list[i].str, s) == 0) + return export_list[i].export; + } + return export_unknown; +} + +static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) +{ + if (sec == elf->export_sec) + return export_plain; + else if (sec == elf->export_gpl_sec) + return export_gpl; + else if (sec == elf->export_gpl_future_sec) + return export_gpl_future; + else + return export_unknown; +} + /** * Add an exported symbol - it may have already been added without a * CRC, in this case just update the CRC **/ -static struct symbol *sym_add_exported(const char *name, struct module *mod) +static struct symbol *sym_add_exported(const char *name, struct module *mod, + enum export export) { struct symbol *s = find_symbol(name); if (!s) { - s = new_symbol(name, mod); + s = new_symbol(name, mod, export); } else { if (!s->preloaded) { warn("%s: '%s' exported twice. Previous export " @@ -200,16 +244,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod) s->preloaded = 0; s->vmlinux = is_vmlinux(mod->name); s->kernel = 0; + s->export = export; return s; } static void sym_update_crc(const char *name, struct module *mod, - unsigned int crc) + unsigned int crc, enum export export) { struct symbol *s = find_symbol(name); if (!s) - s = new_symbol(name, mod); + s = new_symbol(name, mod, export); s->crc = crc; s->crc_valid = 1; } @@ -309,13 +354,21 @@ static void parse_elf(struct elf_info *info, const char *filename) for (i = 1; i < hdr->e_shnum; i++) { const char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + const char *secname; if (sechdrs[i].sh_offset > info->size) goto truncated; - if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) { + secname = secstrings + sechdrs[i].sh_name; + if (strcmp(secname, ".modinfo") == 0) { info->modinfo = (void *)hdr + sechdrs[i].sh_offset; info->modinfo_len = sechdrs[i].sh_size; - } + } else if (strcmp(secname, "__ksymtab") == 0) + info->export_sec = i; + else if (strcmp(secname, "__ksymtab_gpl") == 0) + info->export_gpl_sec = i; + else if (strcmp(secname, "__ksymtab_gpl_future") == 0) + info->export_gpl_future_sec = i; + if (sechdrs[i].sh_type != SHT_SYMTAB) continue; @@ -353,6 +406,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname) { unsigned int crc; + enum export export = export_from_sec(info, sym->st_shndx); switch (sym->st_shndx) { case SHN_COMMON: @@ -362,7 +416,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, /* CRC'd symbol */ if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { crc = (unsigned int) sym->st_value; - sym_update_crc(symname + strlen(CRC_PFX), mod, crc); + sym_update_crc(symname + strlen(CRC_PFX), mod, crc, + export); } break; case SHN_UNDEF: @@ -406,7 +461,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, default: /* All exported symbols */ if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { - sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); + sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, + export); } if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) mod->has_init = 1; @@ -1146,6 +1202,9 @@ static void write_if_changed(struct buffer *b, const char *fname) fclose(file); } +/* parse Module.symvers file. line format: + * 0x12345678symbolmodule[export] + **/ static void read_dump(const char *fname, unsigned int kernel) { unsigned long size, pos = 0; @@ -1157,7 +1216,7 @@ static void read_dump(const char *fname, unsigned int kernel) return; while ((line = get_next_line(&pos, file, size))) { - char *symname, *modname, *d; + char *symname, *modname, *d, *export; unsigned int crc; struct module *mod; struct symbol *s; @@ -1168,8 +1227,9 @@ static void read_dump(const char *fname, unsigned int kernel) if (!(modname = strchr(symname, '\t'))) goto fail; *modname++ = '\0'; - if (strchr(modname, '\t')) - goto fail; + if (!(export = strchr(modname, '\t'))) + *export++ = '\0'; + crc = strtoul(line, &d, 16); if (*symname == '\0' || *modname == '\0' || *d != '\0') goto fail; @@ -1181,10 +1241,10 @@ static void read_dump(const char *fname, unsigned int kernel) mod = new_module(NOFAIL(strdup(modname))); mod->skip = 1; } - s = sym_add_exported(symname, mod); + s = sym_add_exported(symname, mod, export_no(export)); s->kernel = kernel; s->preloaded = 1; - sym_update_crc(symname, mod, crc); + sym_update_crc(symname, mod, crc, export_no(export)); } return; fail: @@ -1214,9 +1274,10 @@ static void write_dump(const char *fname) symbol = symbolhash[n]; while (symbol) { if (dump_sym(symbol)) - buf_printf(&buf, "0x%08x\t%s\t%s\n", + buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n", symbol->crc, symbol->name, - symbol->module->name); + symbol->module->name, + export_str(symbol->export)); symbol = symbol->next; } } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 861d866fcd83..f7ee3a3fde14 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -115,6 +115,9 @@ struct elf_info { Elf_Shdr *sechdrs; Elf_Sym *symtab_start; Elf_Sym *symtab_stop; + Elf_Section export_sec; + Elf_Section export_gpl_sec; + Elf_Section export_gpl_future_sec; const char *strtab; char *modinfo; unsigned int modinfo_len; -- cgit v1.2.3 From b817f6feff4a565b08f0e699a5790b4008b8f494 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 9 Jun 2006 21:53:55 +0200 Subject: kbuild: check license compatibility when building modules Modules that uses GPL symbols can no longer be build with kbuild, the build will fail during the modpost step. When a GPL-incompatible module uses a EXPORT_SYMBOL_GPL_FUTURE symbol then warn during modpost so author are actually notified. The actual license compatibility check is shared with the kernel to make sure it is in sync. Patch originally from: Andreas Gruenbacher and Ram Pai Signed-off-by: Sam Ravnborg --- include/linux/license.h | 14 ++++++++++ kernel/module.c | 11 +------- scripts/mod/modpost.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++-- scripts/mod/modpost.h | 1 + 4 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 include/linux/license.h (limited to 'scripts') diff --git a/include/linux/license.h b/include/linux/license.h new file mode 100644 index 000000000000..decdbf43cb5c --- /dev/null +++ b/include/linux/license.h @@ -0,0 +1,14 @@ +#ifndef __LICENSE_H +#define __LICENSE_H + +static inline int license_is_gpl_compatible(const char *license) +{ + return (strcmp(license, "GPL") == 0 + || strcmp(license, "GPL v2") == 0 + || strcmp(license, "GPL and additional rights") == 0 + || strcmp(license, "Dual BSD/GPL") == 0 + || strcmp(license, "Dual MIT/GPL") == 0 + || strcmp(license, "Dual MPL/GPL") == 0); +} + +#endif diff --git a/kernel/module.c b/kernel/module.c index bbe04862e1b0..690381508d09 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -43,6 +43,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk @@ -1248,16 +1249,6 @@ static void layout_sections(struct module *mod, } } -static inline int license_is_gpl_compatible(const char *license) -{ - return (strcmp(license, "GPL") == 0 - || strcmp(license, "GPL v2") == 0 - || strcmp(license, "GPL and additional rights") == 0 - || strcmp(license, "Dual BSD/GPL") == 0 - || strcmp(license, "Dual MIT/GPL") == 0 - || strcmp(license, "Dual MPL/GPL") == 0); -} - static void set_license(struct module *mod, const char *license) { if (!license) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index ba2e4fc2af20..baa4d83d29a8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -13,6 +13,7 @@ #include #include "modpost.h" +#include "../../include/linux/license.h" /* Are we using CONFIG_MODVERSIONS? */ int modversions = 0; @@ -99,6 +100,7 @@ static struct module *new_module(char *modname) /* add to list */ mod->name = p; + mod->gpl_compatible = -1; mod->next = modules; modules = mod; @@ -493,13 +495,18 @@ static char *next_string(char *string, unsigned long *secsize) return string; } -static char *get_modinfo(void *modinfo, unsigned long modinfo_len, - const char *tag) +static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len, + const char *tag, char *info) { char *p; unsigned int taglen = strlen(tag); unsigned long size = modinfo_len; + if (info) { + size -= info - (char *)modinfo; + modinfo = next_string(info, &size); + } + for (p = modinfo; p; p = next_string(p, &size)) { if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') return p + taglen + 1; @@ -507,6 +514,13 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, return NULL; } +static char *get_modinfo(void *modinfo, unsigned long modinfo_len, + const char *tag) + +{ + return get_next_modinfo(modinfo, modinfo_len, tag, NULL); +} + /** * Test if string s ends in string sub * return 0 if match @@ -981,6 +995,7 @@ static void read_symbols(char *modname) { const char *symname; char *version; + char *license; struct module *mod; struct elf_info info = { }; Elf_Sym *sym; @@ -996,6 +1011,18 @@ static void read_symbols(char *modname) mod->skip = 1; } + license = get_modinfo(info.modinfo, info.modinfo_len, "license"); + while (license) { + if (license_is_gpl_compatible(license)) + mod->gpl_compatible = 1; + else { + mod->gpl_compatible = 0; + break; + } + license = get_next_modinfo(info.modinfo, info.modinfo_len, + "license", license); + } + for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { symname = info.strtab + sym->st_name; @@ -1052,6 +1079,40 @@ void buf_write(struct buffer *buf, const char *s, int len) buf->pos += len; } +void check_license(struct module *mod) +{ + struct symbol *s, *exp; + + for (s = mod->unres; s; s = s->next) { + if (mod->gpl_compatible == 1) { + /* GPL-compatible modules may use all symbols */ + continue; + } + exp = find_symbol(s->name); + if (!exp || exp->module == mod) + continue; + const char *basename = strrchr(mod->name, '/'); + if (basename) + basename++; + switch (exp->export) { + case export_gpl: + fatal("modpost: GPL-incompatible module %s " + "uses GPL-only symbol '%s'\n", + basename ? basename : mod->name, + exp->name); + break; + case export_gpl_future: + warn("modpost: GPL-incompatible module %s " + "uses future GPL-only symbol '%s'\n", + basename ? basename : mod->name, + exp->name); + break; + case export_plain: /* ignore */ break; + case export_unknown: /* ignore */ break; + } + } +} + /** * Header for the generated file **/ @@ -1325,6 +1386,12 @@ int main(int argc, char **argv) read_symbols(argv[optind++]); } + for (mod = modules; mod; mod = mod->next) { + if (mod->skip) + continue; + check_license(mod); + } + for (mod = modules; mod; mod = mod->next) { if (mod->skip) continue; diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index f7ee3a3fde14..2b00c6062844 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -100,6 +100,7 @@ buf_write(struct buffer *buf, const char *s, int len); struct module { struct module *next; const char *name; + int gpl_compatible; struct symbol *unres; int seen; int skip; -- cgit v1.2.3 From 6449bd621ba51ef652ac5bda632eeabbc18dd296 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 9 Jun 2006 20:45:06 -0700 Subject: kbuild: modpost build fix scripts/mod/modpost.c: In function `check_license': scripts/mod/modpost.c:1094: parse error before `const' scripts/mod/modpost.c:1095: `basename' undeclared (first use in this function) scripts/mod/modpost.c:1095: (Each undeclared identifier is reported only once scripts/mod/modpost.c:1095: for each function it appears in.) Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index baa4d83d29a8..f27ddb841df8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1084,6 +1084,7 @@ void check_license(struct module *mod) struct symbol *s, *exp; for (s = mod->unres; s; s = s->next) { + const char *basename; if (mod->gpl_compatible == 1) { /* GPL-compatible modules may use all symbols */ continue; @@ -1091,7 +1092,7 @@ void check_license(struct module *mod) exp = find_symbol(s->name); if (!exp || exp->module == mod) continue; - const char *basename = strrchr(mod->name, '/'); + basename = strrchr(mod->name, '/'); if (basename) basename++; switch (exp->export) { -- cgit v1.2.3 From 9ac545b0f7161eaf2e180acc406c1dd6fdd77686 Mon Sep 17 00:00:00 2001 From: Laurent Riffard Date: Sun, 11 Jun 2006 08:02:06 +0200 Subject: kbuild: fix module.symvers parsing in modpost read_dump didn't split lines between module name and export type. Signed-off-by: Laurent Riffard Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f27ddb841df8..d03c9fff5b2a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1289,7 +1289,7 @@ static void read_dump(const char *fname, unsigned int kernel) if (!(modname = strchr(symname, '\t'))) goto fail; *modname++ = '\0'; - if (!(export = strchr(modname, '\t'))) + if ((export = strchr(modname, '\t')) != NULL) *export++ = '\0'; crc = strtoul(line, &d, 16); -- cgit v1.2.3 From 29b0c89953fee8597b4a9cbdd763c294ae0eb4c7 Mon Sep 17 00:00:00 2001 From: Uwe Zeisberger Date: Fri, 16 Jun 2006 08:47:57 +0200 Subject: kbuild: append git revision for all untagged commits adds revision suffix for untagged commits that are reachable from a tag I'm bisecting and don't get the -g...... suffix. The reason is, that git name-rev --tags HEAD returns e.g. HEAD tags/v2.6.17-rc1^0~1067 which is currently good enough for setlocalversion to skip the suffix. This introduces a dependecy to grep -E, which should be fine. Signed-off-by: Uwe Zeisberger Acked-By: Ryan Anderson Signed-off-by: Sam Ravnborg --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 9a23825218f2..b7bc0f5b64f6 100644 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -11,7 +11,7 @@ cd "${1:-.}" || usage # Check for git and a git repo. if head=`git rev-parse --verify HEAD 2>/dev/null`; then # Do we have an untagged version? - if [ "`git name-rev --tags HEAD`" = "HEAD undefined" ]; then + if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then printf '%s%s' -g `echo "$head" | cut -c1-8` fi -- cgit v1.2.3 From 216b2f1f718d653795024a085636d063693dd9a9 Mon Sep 17 00:00:00 2001 From: Uwe Zeisberger Date: Fri, 16 Jun 2006 08:48:48 +0200 Subject: kbuild: append -dirty for updated but uncommited changes Compare the working copy with the last commit, instead of the index. Signed-off-by: Uwe Zeisberger Acked-by: Ryan Anderson Signed-off-by: Sam Ravnborg --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index b7bc0f5b64f6..82e4993f0a73 100644 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -16,7 +16,7 @@ if head=`git rev-parse --verify HEAD 2>/dev/null`; then fi # Are there uncommitted changes? - if git diff-files | read dummy; then + if git diff-index HEAD | read dummy; then printf '%s' -dirty fi fi -- cgit v1.2.3 From e5c44fd88c146755da6941d047de4d97651404a9 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 24 Jun 2006 22:50:18 +0200 Subject: kbuild: fix make -rR breakage make failed to supply the filename when using make -rR and using $(*F) to get target filename without extension. This bug was not reproduceable in small scale but using: $(basename $(notdir $@)) fixes it with same functionality. Signed-off-by: Sam Ravnborg --- scripts/Kbuild.include | 5 +++++ scripts/Makefile.build | 2 +- scripts/Makefile.host | 6 ++++-- scripts/Makefile.lib | 6 +++--- scripts/Makefile.modpost | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index b0d067be7390..ac5f275b0283 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -12,6 +12,11 @@ space := $(empty) $(empty) # contain a comma depfile = $(subst $(comma),_,$(@D)/.$(@F).d) +### +# basetarget equals the filename of the target with no extension. +# So 'foo/bar.o' becomes 'bar' +basetarget = $(basename $(notdir $@)) + ### # Escape single quote for use in echo statements escsq = $(subst $(squote),'\$(squote)',$1) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 53e53a2e80ae..e8e7d27cfc9a 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -117,7 +117,7 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M] $(obj-m) : quiet_modtag := [M] # Default for not multi-part modules -modname = $(*F) +modname = $(basetarget) $(multi-objs-m) : modname = $(modname-multi) $(multi-objs-m:.o=.i) : modname = $(modname-multi) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 2b066d12af2c..18ecd4d5df7f 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -80,8 +80,10 @@ obj-dirs += $(host-objdirs) ##### # Handle options to gcc. Support building with separate output directory -_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o) -_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o) +_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ + $(HOSTCFLAGS_$(basetarget).o) +_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ + $(HOSTCXXFLAGS_$(basetarget).o) ifeq ($(KBUILD_SRC),) __hostc_flags = $(_hostc_flags) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2cb4935e85d1..fc498fee68ed 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -82,12 +82,12 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) # than one module. In that case KBUILD_MODNAME will be set to foo_bar, # where foo and bar are the name of the modules. name-fix = $(subst $(comma),_,$(subst -,_,$1)) -basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))" +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) -_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) +_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(basetarget).o) +_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o) _cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F)) # If building the kernel in a separate objtree expand all occurrences diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 576cce5e387f..e83613e0e827 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -72,7 +72,7 @@ $(modules:.ko=.mod.c): __modpost ; # Step 5), compile all *.mod.c files # modname is set to make c_flags define KBUILD_MODNAME -modname = $(*F) +modname = $(basetarget) quiet_cmd_cc_o_c = CC $@ cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ -- cgit v1.2.3 From c5e3003381f4e39773a1758a9eb68dff9740a56c Mon Sep 17 00:00:00 2001 From: Ram Pai Date: Fri, 23 Jun 2006 16:44:38 -0700 Subject: kbuild: export-symbol usage report generator The following patch provides the ability to generate a report of (1) All the exported symbols and their in-kernel-module usage count (2) For each module, lists the modules and their exported symbols, on which it depends. the report can be generated by executing: perl scripts/export_report The tool warns if the modules are not build using MODVERSIONING. Signed-off-by: Ram Pai Signed-off-by: Sam Ravnborg --- scripts/export_report.pl | 169 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 scripts/export_report.pl (limited to 'scripts') diff --git a/scripts/export_report.pl b/scripts/export_report.pl new file mode 100644 index 000000000000..9ed00d9bb0a7 --- /dev/null +++ b/scripts/export_report.pl @@ -0,0 +1,169 @@ +#!/usr/bin/perl -w +# +# (C) Copyright IBM Corporation 2006. +# Released under GPL v2. +# Author : Ram Pai (linuxram@us.ibm.com) +# +# Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c +# + +use Getopt::Std; +use strict; + +sub numerically { + my $no1 = (split /\s+/, $a)[1]; + my $no2 = (split /\s+/, $b)[1]; + return $no1 <=> $no2; +} + +sub alphabetically { + my ($module1, $value1) = @{$a}; + my ($module2, $value2) = @{$b}; + return $value1 <=> $value2 || $module2 cmp $module1; +} + +sub print_depends_on { + my ($href) = @_; + print "\n"; + while (my ($mod, $list) = each %$href) { + print "\t$mod:\n"; + foreach my $sym (sort numerically @{$list}) { + my ($symbol, $no) = split /\s+/, $sym; + printf("\t\t%-25s\t%-25d\n", $symbol, $no); + } + print "\n"; + } + print "\n"; + print "~"x80 , "\n"; +} + +sub usage { + print "Usage: @_ -h -k Module.symvers [ -o outputfile ] \n", + "\t-f: treat all the non-option argument as .mod.c files. ", + "Recommend using this as the last option\n", + "\t-h: print detailed help\n", + "\t-k: the path to Module.symvers file. By default uses ", + "the file from the current directory\n", + "\t-o outputfile: output the report to outputfile\n"; + exit 0; +} + +sub collectcfiles { + my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`; + @file = grep {s/\.ko/.mod.c/} @file; + chomp @file; + return @file; +} + +my (%SYMBOL, %MODULE, %opt, @allcfiles); + +if (not getopts('hk:o:f',\%opt) or defined $opt{'h'}) { + usage($0); +} + +if (defined $opt{'f'}) { + @allcfiles = @ARGV; +} else { + @allcfiles = collectcfiles(); +} + +if (not defined $opt{'k'}) { + $opt{'k'} = "Module.symvers"; +} + +unless (open(MODULE_SYMVERS, $opt{'k'})) { + die "Sorry, cannot open $opt{'k'}: $!\n"; +} + +if (defined $opt{'o'}) { + unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) { + die "Sorry, cannot open $opt{'o'} $!\n"; + } + select OUTPUT_HANDLE; +} +# +# collect all the symbols and their attributes from the +# Module.symvers file +# +while ( ) { + chomp; + my (undef, $symbol, $module, $gpl) = split; + $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; +} +close(MODULE_SYMVERS); + +# +# collect the usage count of each symbol. +# +foreach my $thismod (@allcfiles) { + unless (open(MODULE_MODULE, $thismod)) { + print "Sorry, cannot open $thismod: $!\n"; + next; + } + my $state=0; + while ( ) { + chomp; + if ($state eq 0) { + $state = 1 if ($_ =~ /static const struct modversion_info/); + next; + } + if ($state eq 1) { + $state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/); + next; + } + if ($state eq 2) { + if ( $_ !~ /0x[0-9a-f]{7,8},/ ) { + next; + } + my $sym = (split /([,"])/,)[4]; + my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}}; + $SYMBOL{ $sym } = [ $module, $value+1, $symbol, $gpl]; + push(@{$MODULE{$thismod}} , $sym); + } + } + if ($state ne 2) { + print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n"; + } + close(MODULE_MODULE); +} + +print "\tThis file reports the exported symbols usage patterns by in-tree\n", + "\t\t\t\tmodules\n"; +printf("%s\n\n\n","x"x80); +printf("\t\t\t\tINDEX\n\n\n"); +printf("SECTION 1: Usage counts of all exported symbols\n"); +printf("SECTION 2: List of modules and the exported symbols they use\n"); +printf("%s\n\n\n","x"x80); +printf("SECTION 1:\tThe exported symbols and their usage count\n\n"); +printf("%-25s\t%-25s\t%-5s\t%-25s\n", "Symbol", "Module", "Usage count", + "export type"); + +# +# print the list of unused exported symbols +# +foreach my $list (sort alphabetically values(%SYMBOL)) { + my ($module, $value, $symbol, $gpl) = @{$list}; + printf("%-25s\t%-25s\t%-10s\t", $symbol, $module, $value); + if (defined $gpl) { + printf("%-25s\n",$gpl); + } else { + printf("\n"); + } +} +printf("%s\n\n\n","x"x80); + +printf("SECTION 2:\n\tThis section reports export-symbol-usage of in-kernel +modules. Each module lists the modules, and the symbols from that module that +it uses. Each listed symbol reports the number of modules using it\n"); + +print "~"x80 , "\n"; +while (my ($thismod, $list) = each %MODULE) { + my %depends; + $thismod =~ s/\.mod\.c/.ko/; + print "\t\t\t$thismod\n"; + foreach my $symbol (@{$list}) { + my ($module, $value, undef, $gpl) = @{$SYMBOL{$symbol}}; + push (@{$depends{"$module"}}, "$symbol $value"); + } + print_depends_on(\%depends); +} -- cgit v1.2.3 From 468d949401d729b28eed6ea5be25695c5731d3f1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 23 Jun 2006 23:22:43 +0100 Subject: kbuild: kill some false positives from modpost Signed-off-by: Al Viro Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d03c9fff5b2a..7e226896579c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -891,6 +891,8 @@ static int init_section_ref_ok(const char *name) ".pci_fixup_final", ".pdr", "__param", + "__ex_table", + ".fixup", ".smp_locks", ".plt", /* seen on ARCH=um build on x86_64. Harmless */ NULL @@ -918,6 +920,8 @@ static int init_section_ref_ok(const char *name) for (s = namelist3; *s; s++) if (strstr(name, *s) != NULL) return 1; + if (strrcmp(name, ".init") == 0) + return 1; return 0; } @@ -964,6 +968,8 @@ static int exit_section_ref_ok(const char *name) ".exitcall.exit", ".eh_frame", ".stab", + "__ex_table", + ".fixup", ".smp_locks", ".plt", /* seen on ARCH=um build on x86_64. Harmless */ NULL -- cgit v1.2.3 From ac031f26e89cc04fc7504f31ae137857eb83a051 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 21 Jun 2006 20:53:09 -0400 Subject: kbuild: add option for stripping modules while installing them Add option for stripping modules while installing them. This function adds support for stripping modules while they are being installed. CONFIG_DEBUG_KERNEL (which will probably become more popular as developers use kdump) causes the size of the installed modules to grow by a factor of 9 or so. Some kernel package systems solve this problem by stripping the debug information from /lib/modules after running "make modules_install", but that may not work for people who are installing directly into /lib/modules --- root partitions that were sized to handle 16 megs worth of modules may not be quite so happy with 145 megs of modules, so the "make modules_install" never succeeds. This patch allows such users to request modules_install to strip the modules as they are installed. Signed-off-by: "Theodore Ts'o" Signed-off-by: Sam Ravnborg --- Documentation/kbuild/makefiles.txt | 8 ++++++++ Makefile | 17 +++++++++++++++++ scripts/Makefile.modinst | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index a9c00facdf40..14ef3868a328 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -1123,6 +1123,14 @@ The top Makefile exports the following variables: $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may override this value on the command line if desired. + INSTALL_MOD_STRIP + + If this variable is specified, will cause modules to be stripped + after they are installed. If INSTALL_MOD_STRIP is '1', then the + default option --strip-debug will be used. Otherwise, + INSTALL_MOD_STRIP will used as the option(s) to the strip command. + + === 8 Makefile language The kernel Makefiles are designed to run with GNU Make. The Makefiles diff --git a/Makefile b/Makefile index 1b2fd97f503a..d810d6cb4d08 100644 --- a/Makefile +++ b/Makefile @@ -512,6 +512,23 @@ export INSTALL_PATH ?= /boot MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB +# +# INSTALL_MOD_STRIP, if defined, will cause modules to be +# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then +# the default option --strip-debug will be used. Otherwise, +# INSTALL_MOD_STRIP will used as the options to the strip command. + +ifdef INSTALL_MOD_STRIP +ifeq ($(INSTALL_MOD_STRIP),1) +mod_strip_cmd = $STRIP) --strip-debug +else +mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) +endif # INSTALL_MOD_STRIP=1 +else +mod_strip_cmd = true +endif # INSTALL_MOD_STRIP +export mod_strip_cmd + ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 2686dd5dce8c..f0ff248f5e6f 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -17,7 +17,7 @@ __modinst: $(modules) @: quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra -- cgit v1.2.3 From 15fde6751886fd972a64ed65ba49db309919c504 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 9 May 2006 20:37:30 +0200 Subject: kbuild: support for %.symtypes files Here is a patch that adds a new -T option to genksyms for generating dumps of the type definition that makes up the symbol version hashes. This allows to trace modversion changes back to what caused them. The dump format is the name of the type defined, followed by its definition (which is almost C): s#list_head struct list_head { s#list_head * next , * prev ; } The s#, u#, e#, and t# prefixes stand for struct, union, enum, and typedef. The exported symbols do not define types, and thus do not have an x# prefix: nfs4_acl_get_whotype int nfs4_acl_get_whotype ( char * , t#u32 ) The symbol type defintion of a single file can be generated with: make fs/jbd/journal.symtypes If KBUILD_SYMTYPES is defined, all the *.symtypes of all object files that export symbols are generated. The single *.symtypes files can be combined into a single file after a kernel build with a script like the following: for f in $(find -name '*.symtypes' | sort); do f=${f#./} echo "/* ${f%.symtypes}.o */" cat $f echo done \ | sed -e '\:UNKNOWN:d' \ -e 's:[,;] }:}:g' \ -e 's:\([[({]\) :\1:g' \ -e 's: \([])},;]\):\1:g' \ -e 's: $::' \ $f \ | awk ' /^.#/ { if (defined[$1] == $0) { print $1 next } defined[$1] = $0 } { print } ' When the kernel ABI changes, diffing individual *.symtype files, or the combined files, against each other will show which symbol changes caused the ABI changes. This can save a tremendous amount of time. Dump the types that make up modversions Signed-off-by: Andreas Gruenbacher Signed-off-by: Sam Ravnborg --- Makefile | 5 ++- scripts/Makefile.build | 12 ++++++- scripts/genksyms/genksyms.c | 77 ++++++++++++++++++++++++++++++--------------- scripts/genksyms/genksyms.h | 1 + 4 files changed, 67 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 1888fabe4032..e8906694dcc5 100644 --- a/Makefile +++ b/Makefile @@ -969,7 +969,8 @@ clean: archclean $(clean-dirs) $(call cmd,rmfiles) @find . $(RCS_FIND_IGNORE) \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ - -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ + -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ + -o -name '*.symtypes' \) \ -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1311,6 +1312,8 @@ endif $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) %.o: %.S prepare scripts FORCE $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.symtypes: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) # Modules / %/: prepare scripts FORCE diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e8e7d27cfc9a..3cb445cc7432 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -140,6 +140,15 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< %.i: %.c FORCE $(call if_changed_dep,cc_i_c) +quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ +cmd_cc_symtypes_c = \ + $(CPP) -D__GENKSYMS__ $(c_flags) $< \ + | $(GENKSYMS) -T $@ >/dev/null; \ + test -s $@ || rm -f $@ + +%.symtypes : %.c FORCE + $(call if_changed_dep,cc_symtypes_c) + # C (.c) files # The C file is compiled and updated dependency information is generated. # (See cmd_cc_o_c + relevant part of rule_cc_o_c) @@ -166,7 +175,8 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< cmd_modversions = \ if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ $(CPP) -D__GENKSYMS__ $(c_flags) $< \ - | $(GENKSYMS) -a $(ARCH) \ + | $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \ + -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \ > $(@D)/.tmp_$(@F:.o=.ver); \ \ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 5b0344e20d61..b0381823e404 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -42,7 +42,7 @@ static FILE *debugfile; int cur_line = 1; char *cur_filename; -static int flag_debug, flag_dump_defs, flag_warnings; +static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings; static const char *arch = ""; static const char *mod_prefix = ""; @@ -50,6 +50,7 @@ static int errors; static int nsyms; static struct symbol *expansion_trail; +static struct symbol *visited_symbols; static const char *const symbol_type_name[] = { "normal", "typedef", "enum", "struct", "union" @@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, sym->type = type; sym->defn = defn; sym->expansion_trail = NULL; + sym->visited = NULL; sym->is_extern = is_extern; sym->hash_next = symtab[h]; @@ -236,26 +238,11 @@ static int equal_list(struct string_list *a, struct string_list *b) static void print_node(FILE * f, struct string_list *list) { - switch (list->tag) { - case SYM_STRUCT: - putc('s', f); - goto printit; - case SYM_UNION: - putc('u', f); - goto printit; - case SYM_ENUM: - putc('e', f); - goto printit; - case SYM_TYPEDEF: - putc('t', f); - goto printit; - - printit: + if (list->tag != SYM_NORMAL) { + putc(symbol_type_name[list->tag][0], f); putc('#', f); - case SYM_NORMAL: - fputs(list->string, f); - break; } + fputs(list->string, f); } static void print_list(FILE * f, struct string_list *list) @@ -287,9 +274,9 @@ static void print_list(FILE * f, struct string_list *list) } } -static unsigned long expand_and_crc_list(struct string_list *list, - unsigned long crc) +static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) { + struct string_list *list = sym->defn; struct string_list **e, **b; struct string_list *tmp, **tmp2; int elem = 1; @@ -332,7 +319,7 @@ static unsigned long expand_and_crc_list(struct string_list *list, } else { subsym->expansion_trail = expansion_trail; expansion_trail = subsym; - crc = expand_and_crc_list(subsym->defn, crc); + crc = expand_and_crc_sym(subsym, crc); } break; @@ -382,12 +369,22 @@ static unsigned long expand_and_crc_list(struct string_list *list, } else { subsym->expansion_trail = expansion_trail; expansion_trail = subsym; - crc = expand_and_crc_list(subsym->defn, crc); + crc = expand_and_crc_sym(subsym, crc); } break; } } + { + static struct symbol **end = &visited_symbols; + + if (!sym->visited) { + *end = sym; + end = &sym->visited; + sym->visited = (struct symbol *)-1L; + } + } + return crc; } @@ -406,7 +403,7 @@ void export_symbol(const char *name) expansion_trail = (struct symbol *)-1L; - crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; + crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; sym = expansion_trail; while (sym != (struct symbol *)-1L) { @@ -464,6 +461,7 @@ static void genksyms_usage(void) int main(int argc, char **argv) { + FILE *dumpfile = NULL; int o; #ifdef __GNU_LIBRARY__ @@ -473,15 +471,16 @@ int main(int argc, char **argv) {"warnings", 0, 0, 'w'}, {"quiet", 0, 0, 'q'}, {"dump", 0, 0, 'D'}, + {"dump-types", 1, 0, 'T'}, {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; - while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", + while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:", &long_opts[0], NULL)) != EOF) #else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) + while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF) #endif /* __GNU_LIBRARY__ */ switch (o) { case 'a': @@ -502,6 +501,14 @@ int main(int argc, char **argv) case 'D': flag_dump_defs = 1; break; + case 'T': + flag_dump_types = 1; + dumpfile = fopen(optarg, "w"); + if (!dumpfile) { + perror(optarg); + return 1; + } + break; case 'h': genksyms_usage(); return 0; @@ -524,6 +531,24 @@ int main(int argc, char **argv) yyparse(); + if (flag_dump_types && visited_symbols) { + while (visited_symbols != (struct symbol *)-1L) { + struct symbol *sym = visited_symbols; + + if (sym->type != SYM_NORMAL) { + putc(symbol_type_name[sym->type][0], dumpfile); + putc('#', dumpfile); + } + fputs(sym->name, dumpfile); + putc(' ', dumpfile); + print_list(dumpfile, sym->defn); + putc('\n', dumpfile); + + visited_symbols = sym->visited; + sym->visited = NULL; + } + } + if (flag_debug) { fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", nsyms, HASH_BUCKETS, diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index ab6f34f38735..2668287aa498 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h @@ -41,6 +41,7 @@ struct symbol { enum symbol_type type; struct string_list *defn; struct symbol *expansion_trail; + struct symbol *visited; int is_extern; }; -- cgit v1.2.3 From 6803dc0ea85ad21b2cb3ec88decff5e27d7a390b Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 24 Jun 2006 23:46:54 +0200 Subject: kbuild: replace abort() with exit(1) We have had no use of the coredump file for a long time. So just exit(1) and avoid coredumping. Signed-off-by: Sam Ravnborg --- scripts/genksyms/lex.c_shipped | 2 +- scripts/genksyms/lex.l | 2 +- scripts/mod/mk_elfconfig.c | 6 +++--- scripts/mod/modpost.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/genksyms/lex.c_shipped b/scripts/genksyms/lex.c_shipped index 1218053ee960..37ba98241b96 100644 --- a/scripts/genksyms/lex.c_shipped +++ b/scripts/genksyms/lex.c_shipped @@ -2023,7 +2023,7 @@ repeat: break; default: - abort(); + exit(1); } fini: diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index fe0dfeedf0ff..5e544a06678b 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -392,7 +392,7 @@ repeat: break; default: - abort(); + exit(1); } fini: diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 3c92c83733f4..725d61c0fb43 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -28,7 +28,7 @@ main(int argc, char **argv) printf("#define KERNEL_ELFCLASS ELFCLASS64\n"); break; default: - abort(); + exit(1); } switch (ei[EI_DATA]) { case ELFDATA2LSB: @@ -38,7 +38,7 @@ main(int argc, char **argv) printf("#define KERNEL_ELFDATA ELFDATA2MSB\n"); break; default: - abort(); + exit(1); } if (sizeof(unsigned long) == 4) { @@ -53,7 +53,7 @@ main(int argc, char **argv) else if (memcmp(endian_test.c, "\x02\x01", 2) == 0) printf("#define HOST_ELFDATA ELFDATA2LSB\n"); else - abort(); + exit(1); if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7e226896579c..0dd16177642d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -330,7 +330,7 @@ static void parse_elf(struct elf_info *info, const char *filename) hdr = grab_file(filename, &info->size); if (!hdr) { perror(filename); - abort(); + exit(1); } info->hdr = hdr; if (info->size < sizeof(*hdr)) -- cgit v1.2.3