diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2009-12-24 15:16:02 +0900 | 
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2009-12-24 15:16:02 +0900 | 
| commit | f34548cb735b7a80bbbb0bdd09ad4c2173ba92d5 (patch) | |
| tree | e53c9e39b3149221779c10595bc59fa02de4f45f /scripts | |
| parent | 76382b5bdb77c29ab430e1b82ef1c604c8dd113b (diff) | |
| parent | 32b53076c31ce9159740b744d5eb5d9505312add (diff) | |
Merge branch 'sh/g3-prep' into sh/for-2.6.33
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Kbuild.include | 6 | ||||
| -rw-r--r-- | scripts/Makefile.build | 1 | ||||
| -rw-r--r-- | scripts/Makefile.lib | 2 | ||||
| -rw-r--r-- | scripts/Makefile.modbuiltin | 55 | ||||
| -rw-r--r-- | scripts/basic/fixdep.c | 10 | ||||
| -rw-r--r-- | scripts/genksyms/keywords.c_shipped | 191 | ||||
| -rw-r--r-- | scripts/genksyms/keywords.gperf | 2 | ||||
| -rwxr-xr-x | scripts/headers.sh | 2 | ||||
| -rw-r--r-- | scripts/kconfig/Makefile | 1 | ||||
| -rw-r--r-- | scripts/kconfig/confdata.c | 24 | ||||
| -rwxr-xr-x | scripts/mkcompile_h | 2 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 2 | ||||
| -rw-r--r-- | scripts/package/Makefile | 20 | ||||
| -rw-r--r-- | scripts/package/buildtar | 6 | ||||
| -rwxr-xr-x | scripts/recordmcount.pl | 58 | ||||
| -rwxr-xr-x | scripts/tags.sh | 8 | ||||
| -rw-r--r-- | scripts/unifdef.c | 341 | 
17 files changed, 485 insertions, 246 deletions
| diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index c67e73ecd5be..ed2773edfe71 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -149,6 +149,12 @@ ld-option = $(call try-run,\  # $(Q)$(MAKE) $(build)=dir  build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj +### +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj= +# Usage: +# $(Q)$(MAKE) $(modbuiltin)=dir +modbuiltin := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.modbuiltin obj +  # Prefix -I with $(srctree) if it is not an absolute path.  # skip if -I has no parameter  addtree = $(if $(patsubst -I%,%,$(1)), \ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 341b58902ffc..0b94d2fa3a88 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -207,6 +207,7 @@ endif  ifdef CONFIG_FTRACE_MCOUNT_RECORD  cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ +	"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \  	"$(if $(CONFIG_64BIT),64,32)" \  	"$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \  	"$(if $(part-of-module),1,0)" "$(@)"; diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 224d85e72ef1..cd815ac2a50b 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -213,7 +213,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \  # Bzip2 and LZMA do not include size in file... so we have to fake that;  # append the size as a 32-bit littleendian number as gzip does. -size_append = /bin/echo -ne $(shell					\ +size_append = printf $(shell						\  dec_size=0;								\  for F in $1; do								\  	fsize=$$(stat -c "%s" $$F);					\ diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin new file mode 100644 index 000000000000..102a276f6eea --- /dev/null +++ b/scripts/Makefile.modbuiltin @@ -0,0 +1,55 @@ +# ========================================================================== +# Generating modules.builtin +# ========================================================================== + +src := $(obj) + +PHONY := __modbuiltin +__modbuiltin: + +-include include/config/auto.conf +# tristate.conf sets tristate variables to uppercase 'Y' or 'M' +# That way, we get the list of built-in modules in obj-Y +-include include/config/tristate.conf + +include scripts/Kbuild.include + +# The filename Kbuild has precedence over Makefile +kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) +include $(kbuild-file) + +include scripts/Makefile.lib +__subdir-Y     := $(patsubst %/,%,$(filter %/, $(obj-Y))) +subdir-Y       += $(__subdir-Y) +subdir-ym      := $(sort $(subdir-y) $(subdir-Y) $(subdir-m)) +subdir-ym      := $(addprefix $(obj)/,$(subdir-ym)) +obj-Y          := $(addprefix $(obj)/,$(obj-Y)) + +modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym)) +modbuiltin-mods    := $(filter %.ko, $(obj-Y:.o=.ko)) +modbuiltin-target  := $(obj)/modules.builtin + +__modbuiltin: $(modbuiltin-target) $(subdir-ym) +	@: + +$(modbuiltin-target): $(subdir-ym) FORCE +	$(Q)(for m in $(modbuiltin-mods); do echo kernel/$$m; done;	\ +	cat /dev/null $(modbuiltin-subdirs)) > $@ + +PHONY += FORCE + +FORCE: + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ym) +$(subdir-ym): +	$(Q)$(MAKE) $(modbuiltin)=$@ + + +# Declare the contents of the .PHONY variable as phony.  We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 6bf21f83837d..ea26b23de082 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -16,15 +16,15 @@   * tells make when to remake a file.   *   * To use this list as-is however has the drawback that virtually - * every file in the kernel includes <linux/autoconf.h>. + * every file in the kernel includes autoconf.h.   * - * If the user re-runs make *config, linux/autoconf.h will be + * If the user re-runs make *config, autoconf.h will be   * regenerated.  make notices that and will rebuild every file which   * includes autoconf.h, i.e. basically all files. This is extremely   * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.   *   * So we play the same trick that "mkdep" played before. We replace - * the dependency on linux/autoconf.h by a dependency on every config + * the dependency on autoconf.h by a dependency on every config   * option which is mentioned in any of the listed prequisites.   *   * kconfig populates a tree in include/config/ with an empty file @@ -73,7 +73,7 @@   *   cmd_<target> = <cmdline>   *   * and then basically copies the .<target>.d file to stdout, in the - * process filtering out the dependency on linux/autoconf.h and adding + * process filtering out the dependency on autoconf.h and adding   * dependencies on include/config/my/option.h for every   * CONFIG_MY_OPTION encountered in any of the prequisites.   * @@ -324,7 +324,7 @@ static void parse_dep_file(void *map, size_t len)  			p++;  		}  		memcpy(s, m, p-m); s[p-m] = 0; -		if (strrcmp(s, "include/linux/autoconf.h") && +		if (strrcmp(s, "include/generated/autoconf.h") &&  		    strrcmp(s, "arch/um/include/uml-config.h") &&  		    strrcmp(s, ".ver")) {  			printf("  %s \\\n", s); diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index 287467a2e8c7..8060e06798b3 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.4 */  /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf  */  #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -34,7 +34,7 @@ struct resword;  static const struct resword *is_reserved_word(register const char *str, register unsigned int len);  #line 5 "scripts/genksyms/keywords.gperf"  struct resword { const char *name; int token; }; -/* maximum key range = 62, duplicates = 0 */ +/* maximum key range = 64, duplicates = 0 */  #ifdef __GNUC__  __inline @@ -48,39 +48,39 @@ is_reserved_hash (register const char *str, register unsigned int len)  {    static const unsigned char asso_values[] =      { -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65,  5, -      65, 65, 65, 65, 65, 65, 35, 65, 65, 65, -       0, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65,  0, 65,  0, 65,  5, -      20, 15, 10, 30, 65, 15, 65, 65, 20,  0, -      10, 35, 20, 65, 10,  5,  0, 10,  5, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65, 65, 65, 65, 65, -      65, 65, 65, 65, 65, 65 +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67,  0, +      67, 67, 67, 67, 67, 67, 15, 67, 67, 67, +       0, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67,  0, 67,  0, 67,  5, +      25, 20, 15, 30, 67, 15, 67, 67, 10,  0, +      10, 40, 20, 67, 10,  5,  0, 10, 15, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67, 67, 67, 67, 67, +      67, 67, 67, 67, 67, 67      };    return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];  }  #ifdef __GNUC__  __inline -#ifdef __GNUC_STDC_INLINE__ +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__  __attribute__ ((__gnu_inline__))  #endif  #endif @@ -89,116 +89,119 @@ is_reserved_word (register const char *str, register unsigned int len)  {    enum      { -      TOTAL_KEYWORDS = 43, +      TOTAL_KEYWORDS = 45,        MIN_WORD_LENGTH = 3,        MAX_WORD_LENGTH = 24,        MIN_HASH_VALUE = 3, -      MAX_HASH_VALUE = 64 +      MAX_HASH_VALUE = 66      };    static const struct resword wordlist[] =      {        {""}, {""}, {""}, -#line 28 "scripts/genksyms/keywords.gperf" +#line 30 "scripts/genksyms/keywords.gperf"        {"asm", ASM_KEYW},        {""}, -#line 10 "scripts/genksyms/keywords.gperf" +#line 12 "scripts/genksyms/keywords.gperf"        {"__asm", ASM_KEYW},        {""}, -#line 11 "scripts/genksyms/keywords.gperf" +#line 13 "scripts/genksyms/keywords.gperf"        {"__asm__", ASM_KEYW},        {""}, {""}, -#line 54 "scripts/genksyms/keywords.gperf" +#line 56 "scripts/genksyms/keywords.gperf"        {"__typeof__", TYPEOF_KEYW},        {""}, -#line 14 "scripts/genksyms/keywords.gperf" +#line 16 "scripts/genksyms/keywords.gperf"        {"__const", CONST_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" -      {"__attribute__", ATTRIBUTE_KEYW},  #line 15 "scripts/genksyms/keywords.gperf" +      {"__attribute__", ATTRIBUTE_KEYW}, +#line 17 "scripts/genksyms/keywords.gperf"        {"__const__", CONST_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" +#line 22 "scripts/genksyms/keywords.gperf"        {"__signed__", SIGNED_KEYW}, -#line 46 "scripts/genksyms/keywords.gperf" +#line 48 "scripts/genksyms/keywords.gperf"        {"static", STATIC_KEYW}, -#line 22 "scripts/genksyms/keywords.gperf" -      {"__volatile__", VOLATILE_KEYW}, -#line 41 "scripts/genksyms/keywords.gperf" +      {""}, +#line 43 "scripts/genksyms/keywords.gperf"        {"int", INT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" +#line 36 "scripts/genksyms/keywords.gperf"        {"char", CHAR_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" +#line 37 "scripts/genksyms/keywords.gperf"        {"const", CONST_KEYW}, -#line 47 "scripts/genksyms/keywords.gperf" +#line 49 "scripts/genksyms/keywords.gperf"        {"struct", STRUCT_KEYW}, -#line 26 "scripts/genksyms/keywords.gperf" +#line 28 "scripts/genksyms/keywords.gperf"        {"__restrict__", RESTRICT_KEYW}, -#line 27 "scripts/genksyms/keywords.gperf" +#line 29 "scripts/genksyms/keywords.gperf"        {"restrict", RESTRICT_KEYW}, -#line 25 "scripts/genksyms/keywords.gperf" -      {"_restrict", RESTRICT_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" +#line 9 "scripts/genksyms/keywords.gperf" +      {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, +#line 20 "scripts/genksyms/keywords.gperf"        {"__inline__", INLINE_KEYW}, -#line 12 "scripts/genksyms/keywords.gperf" -      {"__attribute", ATTRIBUTE_KEYW},        {""}, -#line 16 "scripts/genksyms/keywords.gperf" +#line 24 "scripts/genksyms/keywords.gperf" +      {"__volatile__", VOLATILE_KEYW}, +#line 7 "scripts/genksyms/keywords.gperf" +      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 27 "scripts/genksyms/keywords.gperf" +      {"_restrict", RESTRICT_KEYW}, +      {""}, +#line 14 "scripts/genksyms/keywords.gperf" +      {"__attribute", ATTRIBUTE_KEYW}, +#line 8 "scripts/genksyms/keywords.gperf" +      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 18 "scripts/genksyms/keywords.gperf"        {"__extension__", EXTENSION_KEYW}, -#line 37 "scripts/genksyms/keywords.gperf" +#line 39 "scripts/genksyms/keywords.gperf"        {"enum", ENUM_KEYW}, -#line 21 "scripts/genksyms/keywords.gperf" -      {"__volatile", VOLATILE_KEYW}, -#line 38 "scripts/genksyms/keywords.gperf" +#line 10 "scripts/genksyms/keywords.gperf" +      {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 40 "scripts/genksyms/keywords.gperf"        {"extern", EXTERN_KEYW},        {""}, -#line 19 "scripts/genksyms/keywords.gperf" +#line 21 "scripts/genksyms/keywords.gperf"        {"__signed", SIGNED_KEYW}, -#line 9 "scripts/genksyms/keywords.gperf" -      {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, -      {""}, -#line 53 "scripts/genksyms/keywords.gperf" +#line 11 "scripts/genksyms/keywords.gperf" +      {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 51 "scripts/genksyms/keywords.gperf" +      {"union", UNION_KEYW}, +#line 55 "scripts/genksyms/keywords.gperf"        {"typeof", TYPEOF_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" +#line 50 "scripts/genksyms/keywords.gperf"        {"typedef", TYPEDEF_KEYW}, -#line 17 "scripts/genksyms/keywords.gperf" +#line 19 "scripts/genksyms/keywords.gperf"        {"__inline", INLINE_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" +#line 35 "scripts/genksyms/keywords.gperf"        {"auto", AUTO_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" -      {"union", UNION_KEYW}, -      {""}, {""}, -#line 50 "scripts/genksyms/keywords.gperf" -      {"unsigned", UNSIGNED_KEYW}, -#line 51 "scripts/genksyms/keywords.gperf" -      {"void", VOID_KEYW}, -#line 44 "scripts/genksyms/keywords.gperf" -      {"short", SHORT_KEYW}, +#line 23 "scripts/genksyms/keywords.gperf" +      {"__volatile", VOLATILE_KEYW},        {""}, {""},  #line 52 "scripts/genksyms/keywords.gperf" -      {"volatile", VOLATILE_KEYW}, -      {""}, -#line 39 "scripts/genksyms/keywords.gperf" -      {"float", FLOAT_KEYW}, -#line 36 "scripts/genksyms/keywords.gperf" -      {"double", DOUBLE_KEYW}, +      {"unsigned", UNSIGNED_KEYW},        {""}, -#line 7 "scripts/genksyms/keywords.gperf" -      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, -      {""}, {""}, -#line 40 "scripts/genksyms/keywords.gperf" +#line 46 "scripts/genksyms/keywords.gperf" +      {"short", SHORT_KEYW}, +#line 42 "scripts/genksyms/keywords.gperf"        {"inline", INLINE_KEYW}, -#line 8 "scripts/genksyms/keywords.gperf" -      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 43 "scripts/genksyms/keywords.gperf" -      {"register", REGISTER_KEYW},        {""}, -#line 24 "scripts/genksyms/keywords.gperf" +#line 54 "scripts/genksyms/keywords.gperf" +      {"volatile", VOLATILE_KEYW}, +#line 44 "scripts/genksyms/keywords.gperf" +      {"long", LONG_KEYW}, +#line 26 "scripts/genksyms/keywords.gperf"        {"_Bool", BOOL_KEYW}, -#line 45 "scripts/genksyms/keywords.gperf" -      {"signed", SIGNED_KEYW},        {""}, {""}, -#line 42 "scripts/genksyms/keywords.gperf" -      {"long", LONG_KEYW} +#line 45 "scripts/genksyms/keywords.gperf" +      {"register", REGISTER_KEYW}, +#line 53 "scripts/genksyms/keywords.gperf" +      {"void", VOID_KEYW}, +#line 41 "scripts/genksyms/keywords.gperf" +      {"float", FLOAT_KEYW}, +#line 38 "scripts/genksyms/keywords.gperf" +      {"double", DOUBLE_KEYW}, +      {""}, {""}, {""}, {""}, +#line 47 "scripts/genksyms/keywords.gperf" +      {"signed", SIGNED_KEYW}      };    if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index 8fe977a4d57b..e6349acb6f2f 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf @@ -7,6 +7,8 @@ struct resword { const char *name; int token; }  EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW  EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW  EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW  __asm, ASM_KEYW  __asm__, ASM_KEYW  __attribute, ATTRIBUTE_KEYW diff --git a/scripts/headers.sh b/scripts/headers.sh index 0308ecc10d5b..1ddcdd38d97f 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -8,8 +8,6 @@ do_command()  {  	if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then  		make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 -	elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then -		make ARCH=$2 KBUILD_HEADERS=$1 headers_$1  	else  		printf "Ignoring arch: %s\n" ${arch}  	fi diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 80599e3a7994..999e8a7d5bf7 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -27,6 +27,7 @@ oldconfig: $(obj)/conf  	$< -o $(Kconfig)  silentoldconfig: $(obj)/conf +	$(Q)mkdir -p include/generated  	$< -s $(Kconfig)  localmodconfig: $(obj)/streamline_config.pl $(obj)/conf diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index b55e72ff2fc6..c4dec80cfd8e 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -677,7 +677,7 @@ int conf_write_autoconf(void)  	struct symbol *sym;  	const char *str;  	const char *name; -	FILE *out, *out_h; +	FILE *out, *tristate, *out_h;  	time_t now;  	int i, l; @@ -692,9 +692,16 @@ int conf_write_autoconf(void)  	if (!out)  		return 1; +	tristate = fopen(".tmpconfig_tristate", "w"); +	if (!tristate) { +		fclose(out); +		return 1; +	} +  	out_h = fopen(".tmpconfig.h", "w");  	if (!out_h) {  		fclose(out); +		fclose(tristate);  		return 1;  	} @@ -707,6 +714,9 @@ int conf_write_autoconf(void)  		     "# %s"  		     "#\n",  		     sym_get_string_value(sym), ctime(&now)); +	fprintf(tristate, "#\n" +			  "# Automatically generated - do not edit\n" +			  "\n");  	fprintf(out_h, "/*\n"  		       " * Automatically generated C config: don't edit\n"  		       " * Linux kernel version: %s\n" @@ -727,10 +737,14 @@ int conf_write_autoconf(void)  				break;  			case mod:  				fprintf(out, "CONFIG_%s=m\n", sym->name); +				fprintf(tristate, "CONFIG_%s=M\n", sym->name);  				fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);  				break;  			case yes:  				fprintf(out, "CONFIG_%s=y\n", sym->name); +				if (sym->type == S_TRISTATE) +					fprintf(tristate, "CONFIG_%s=Y\n", +							sym->name);  				fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);  				break;  			} @@ -772,13 +786,19 @@ int conf_write_autoconf(void)  		}  	}  	fclose(out); +	fclose(tristate);  	fclose(out_h);  	name = getenv("KCONFIG_AUTOHEADER");  	if (!name) -		name = "include/linux/autoconf.h"; +		name = "include/generated/autoconf.h";  	if (rename(".tmpconfig.h", name))  		return 1; +	name = getenv("KCONFIG_TRISTATE"); +	if (!name) +		name = "include/config/tristate.conf"; +	if (rename(".tmpconfig_tristate", name)) +		return 1;  	name = conf_get_autoconfig_name();  	/*  	 * This must be the last step, kbuild has a dependency on auto.conf diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index bce3d0fe6fbd..23dbad80cce9 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -14,7 +14,7 @@ vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }  # So "sudo make install" won't change the "compiled by <user>"  # do "compiled by root" -if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then +if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then    vecho "  SKIPPED $TARGET"    exit 0  fi diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6c4ffc767b91..20923613467c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -15,7 +15,7 @@  #include <stdio.h>  #include <ctype.h>  #include "modpost.h" -#include "../../include/linux/autoconf.h" +#include "../../include/generated/autoconf.h"  #include "../../include/linux/license.h"  /* Some toolchains use a `_' prefix for all user symbols. */ diff --git a/scripts/package/Makefile b/scripts/package/Makefile index f67cc885c807..62fcc3a7f4d3 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -77,9 +77,27 @@ clean-files += $(objtree)/binkernel.spec  # Deb target  # --------------------------------------------------------------------------- +quiet_cmd_builddeb = BUILDDEB +      cmd_builddeb = set -e; \ +	test `id -u` = 0 || \ +	test -n "$(KBUILD_PKG_ROOTCMD)" || { \ +		which fakeroot >/dev/null 2>&1 && \ +		KBUILD_PKG_ROOTCMD="fakeroot -u"; \ +	} || { \ +		echo; \ +		echo "builddeb must be run as root (or using fakeroot)."; \ +		echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \ +		echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \ +		echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \ +		false; \ +	} && \ +	\ +	$$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \ +		$(srctree)/scripts/package/builddeb +  deb-pkg: FORCE  	$(MAKE) KBUILD_SRC= -	$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb +	$(call cmd,builddeb)  clean-dirs += $(objtree)/debian/ diff --git a/scripts/package/buildtar b/scripts/package/buildtar index b1fd48db1640..51b2aa0acb82 100644 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -101,7 +101,11 @@ esac  #  (  	cd "${tmpdir}" -	tar cf - . | ${compress} > "${tarball}${file_ext}" +	opts= +	if tar --owner=root --group=root --help >/dev/null 2>&1; then +		opts="--owner=root --group=root" +	fi +	tar cf - . $opts | ${compress} > "${tarball}${file_ext}"  )  echo "Tarball successfully created in ${tarball}${file_ext}" diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 9cf0a6fad6ba..92f09fe9639e 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -113,13 +113,13 @@ $P =~ s@.*/@@g;  my $V = '0.1'; -if ($#ARGV != 10) { -	print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; +if ($#ARGV != 11) { +	print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n";  	print "version: $V\n";  	exit(1);  } -my ($arch, $bits, $objdump, $objcopy, $cc, +my ($arch, $endian, $bits, $objdump, $objcopy, $cc,      $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;  # This file refers to mcount and shouldn't be ftraced, so lets' ignore it @@ -295,6 +295,58 @@ if ($arch eq "x86_64") {      $ld .= " -m elf64_sparc";      $cc .= " -m64";      $objcopy .= " -O elf64-sparc"; +} elsif ($arch eq "mips") { +    # To enable module support, we need to enable the -mlong-calls option +    # of gcc for module, after using this option, we can not get the real +    # offset of the calling to _mcount, but the offset of the lui +    # instruction or the addiu one. herein, we record the address of the +    # first one, and then we can replace this instruction by a branch +    # instruction to jump over the profiling function to filter the +    # indicated functions, or swith back to the lui instruction to trace +    # them, which means dynamic tracing. +    # +    #       c:	3c030000 	lui	v1,0x0 +    #			c: R_MIPS_HI16	_mcount +    #			c: R_MIPS_NONE	*ABS* +    #			c: R_MIPS_NONE	*ABS* +    #      10:	64630000 	daddiu	v1,v1,0 +    #			10: R_MIPS_LO16	_mcount +    #			10: R_MIPS_NONE	*ABS* +    #			10: R_MIPS_NONE	*ABS* +    #      14:	03e0082d 	move	at,ra +    #      18:	0060f809 	jalr	v1 +    # +    # for the kernel: +    # +    #     10:   03e0082d        move    at,ra +    #	  14:   0c000000        jal     0 <loongson_halt> +    #                    14: R_MIPS_26   _mcount +    #                    14: R_MIPS_NONE *ABS* +    #                    14: R_MIPS_NONE *ABS* +    #	 18:   00020021        nop +    if ($is_module eq "0") { +	    $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; +    } else { +	    $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$"; +    } +    $objdump .= " -Melf-trad".$endian."mips "; + +    if ($endian eq "big") { +	    $endian = " -EB "; +	    $ld .= " -melf".$bits."btsmip"; +    } else { +	    $endian = " -EL "; +	    $ld .= " -melf".$bits."ltsmip"; +    } + +    $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian; +    $ld .= $endian; + +    if ($bits == 64) { +	    $function_regex = +		"^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:"; +	    $type = ".dword"; +    }  } elsif ($arch eq "microblaze") {      # Microblaze calls '_mcount' instead of plain 'mcount'.      $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; diff --git a/scripts/tags.sh b/scripts/tags.sh index d52f7a01557c..1a0c44d7c4a7 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -89,7 +89,13 @@ all_defconfigs()  docscope()  { -	(echo \-k; echo \-q; all_sources) > cscope.files +	# always use absolute paths for cscope, as recommended by cscope +	# upstream +	case "$tree" in +		/*) ;; +		*) tree=$PWD/$tree ;; +	esac +	(cd /; echo \-k; echo \-q; all_sources) > cscope.files  	cscope -b -f cscope.out  } diff --git a/scripts/unifdef.c b/scripts/unifdef.c index 30d459fb0709..44d39785e50d 100644 --- a/scripts/unifdef.c +++ b/scripts/unifdef.c @@ -1,13 +1,5 @@  /* - * Copyright (c) 2002 - 2005 Tony Finch <dot@dotat.at>.  All rights reserved. - * - * This code is derived from software contributed to Berkeley by Dave Yost. - * It was rewritten to support ANSI C by Tony Finch. The original version of - * unifdef carried the following copyright notice. None of its code remains - * in this version (though some of the names remain). - * - * Copyright (c) 1985, 1993 - *	The Regents of the University of California.  All rights reserved. + * Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>   *   * Redistribution and use in source and binary forms, with or without   * modification, are permitted provided that the following conditions @@ -31,23 +23,20 @@   * SUCH DAMAGE.   */ -#include <sys/cdefs.h> +/* + * This code was derived from software contributed to Berkeley by Dave Yost. + * It was rewritten to support ANSI C by Tony Finch. The original version + * of unifdef carried the 4-clause BSD copyright licence. None of its code + * remains in this version (though some of the names remain) so it now + * carries a more liberal licence. + * + * The latest version is available from http://dotat.at/prog/unifdef + */ -#ifndef lint -#if 0 -static const char copyright[] = -"@(#) Copyright (c) 1985, 1993\n\ -	The Regents of the University of California.  All rights reserved.\n"; -#endif -#ifdef __IDSTRING -__IDSTRING(Berkeley, "@(#)unifdef.c	8.1 (Berkeley) 6/6/93"); -__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $"); -__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $"); -#endif -#endif /* not lint */ -#ifdef __FBSDID -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $"); -#endif +static const char * const copyright[] = { +    "@(#) Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>\n", +    "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $", +};  /*   * unifdef - remove ifdef'ed lines @@ -72,8 +61,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05  #include <string.h>  #include <unistd.h> -size_t strlcpy(char *dst, const char *src, size_t siz); -  /* types of input lines: */  typedef enum {  	LT_TRUEI,		/* a true #if with ignore flag */ @@ -90,6 +77,7 @@ typedef enum {  	LT_DODGY_LAST = LT_DODGY + LT_ENDIF,  	LT_PLAIN,		/* ordinary line */  	LT_EOF,			/* end of file */ +	LT_ERROR,		/* unevaluable #if */  	LT_COUNT  } Linetype; @@ -100,7 +88,7 @@ static char const * const linetype_name[] = {  	"DODGY IF", "DODGY TRUE", "DODGY FALSE",  	"DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",  	"DODGY ELSE", "DODGY ENDIF", -	"PLAIN", "EOF" +	"PLAIN", "EOF", "ERROR"  };  /* state of #if processing */ @@ -168,11 +156,13 @@ static char const * const linestate_name[] = {   * Globals.   */ +static bool             compblank;		/* -B: compress blank lines */ +static bool             lnblank;		/* -b: blank deleted lines */  static bool             complement;		/* -c: do the complement */  static bool             debugging;		/* -d: debugging reports */  static bool             iocccok;		/* -e: fewer IOCCC errors */ +static bool             strictlogic;		/* -K: keep ambiguous #ifs */  static bool             killconsts;		/* -k: eval constant #ifs */ -static bool             lnblank;		/* -l: blank deleted lines */  static bool             lnnum;			/* -n: add #line directives */  static bool             symlist;		/* -s: output symbol list */  static bool             text;			/* -t: this is a text file */ @@ -196,7 +186,9 @@ static bool             ignoring[MAXDEPTH];	/* ignore comments state */  static int              stifline[MAXDEPTH];	/* start of current #if */  static int              depth;			/* current #if nesting */  static int              delcount;		/* count of deleted lines */ -static bool             keepthis;		/* don't delete constant #if */ +static unsigned         blankcount;		/* count of blank lines */ +static unsigned         blankmax;		/* maximum recent blankcount */ +static bool             constexpr;		/* constant #if expression */  static int              exitstat;		/* program exit status */ @@ -206,13 +198,14 @@ static void             done(void);  static void             error(const char *);  static int              findsym(const char *);  static void             flushline(bool); -static Linetype         get_line(void); +static Linetype         parseline(void);  static Linetype         ifeval(const char **);  static void             ignoreoff(void);  static void             ignoreon(void);  static void             keywordedit(const char *);  static void             nest(void);  static void             process(void); +static const char      *skipargs(const char *);  static const char      *skipcomment(const char *);  static const char      *skipsym(const char *);  static void             state(Ifstate); @@ -220,7 +213,7 @@ static int              strlcmp(const char *, const char *, size_t);  static void             unnest(void);  static void             usage(void); -#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') +#define endsym(c) (!isalnum((unsigned char)c) && c != '_')  /*   * The main program. @@ -230,7 +223,7 @@ main(int argc, char *argv[])  {  	int opt; -	while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) +	while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1)  		switch (opt) {  		case 'i': /* treat stuff controlled by these symbols as text */  			/* @@ -255,6 +248,13 @@ main(int argc, char *argv[])  		case 'I':  			/* no-op for compatibility with cpp */  			break; +		case 'B': /* compress blank lines around removed section */ +			compblank = true; +			break; +		case 'b': /* blank deleted lines instead of omitting them */ +		case 'l': /* backwards compatibility */ +			lnblank = true; +			break;  		case 'c': /* treat -D as -U and vice versa */  			complement = true;  			break; @@ -264,12 +264,12 @@ main(int argc, char *argv[])  		case 'e': /* fewer errors from dodgy lines */  			iocccok = true;  			break; +		case 'K': /* keep ambiguous #ifs */ +			strictlogic = true; +			break;  		case 'k': /* process constant #ifs */  			killconsts = true;  			break; -		case 'l': /* blank deleted lines instead of omitting them */ -			lnblank = true; -			break;  		case 'n': /* add #line directive after deleted lines */  			lnnum = true;  			break; @@ -284,6 +284,8 @@ main(int argc, char *argv[])  		}  	argc -= optind;  	argv += optind; +	if (compblank && lnblank) +		errx(2, "-B and -b are mutually exclusive");  	if (argc > 1) {  		errx(2, "can only do one file");  	} else if (argc == 1 && strcmp(*argv, "-") != 0) { @@ -302,7 +304,7 @@ main(int argc, char *argv[])  static void  usage(void)  { -	fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" +	fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]"  	    " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");  	exit(2);  } @@ -383,46 +385,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {  /* IS_OUTSIDE */  { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,    Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eendif, -  print, done }, +  print, done,  abort },  /* IS_FALSE_PREFIX */  { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,    Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, -  drop,  Eeof }, +  drop,  Eeof,  abort },  /* IS_TRUE_PREFIX */  { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,    Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, -  print, Eeof }, +  print, Eeof,  abort },  /* IS_PASS_MIDDLE */  { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,    Oiffy, Oiffy, Fpass, Oif,   Oif,   Pelif, Oelif, Oelif, Pelse, Pendif, -  print, Eeof }, +  print, Eeof,  abort },  /* IS_FALSE_MIDDLE */  { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,    Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, -  drop,  Eeof }, +  drop,  Eeof,  abort },  /* IS_TRUE_MIDDLE */  { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,    Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Pendif, -  print, Eeof }, +  print, Eeof,  abort },  /* IS_PASS_ELSE */  { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,    Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Pendif, -  print, Eeof }, +  print, Eeof,  abort },  /* IS_FALSE_ELSE */  { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,    Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, -  drop,  Eeof }, +  drop,  Eeof,  abort },  /* IS_TRUE_ELSE */  { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,    Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eioccc, -  print, Eeof }, +  print, Eeof,  abort },  /* IS_FALSE_TRAILER */  { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,    Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, -  drop,  Eeof } +  drop,  Eeof,  abort }  /*TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF    TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF (DODGY) -  PLAIN  EOF */ +  PLAIN  EOF    ERROR */  };  /* @@ -463,9 +465,11 @@ keywordedit(const char *replacement)  static void  nest(void)  { -	depth += 1; -	if (depth >= MAXDEPTH) +	if (depth > MAXDEPTH-1) +		abort(); /* bug */ +	if (depth == MAXDEPTH-1)  		error("Too many levels of nesting"); +	depth += 1;  	stifline[depth] = linenum;  }  static void @@ -490,15 +494,23 @@ flushline(bool keep)  	if (symlist)  		return;  	if (keep ^ complement) { -		if (lnnum && delcount > 0) -			printf("#line %d\n", linenum); -		fputs(tline, stdout); -		delcount = 0; +		bool blankline = tline[strspn(tline, " \t\n")] == '\0'; +		if (blankline && compblank && blankcount != blankmax) { +			delcount += 1; +			blankcount += 1; +		} else { +			if (lnnum && delcount > 0) +				printf("#line %d\n", linenum); +			fputs(tline, stdout); +			delcount = 0; +			blankmax = blankcount = blankline ? blankcount + 1 : 0; +		}  	} else {  		if (lnblank)  			putc('\n', stdout);  		exitstat = 1;  		delcount += 1; +		blankcount = 0;  	}  } @@ -510,9 +522,12 @@ process(void)  {  	Linetype lineval; +	/* When compressing blank lines, act as if the file +	   is preceded by a large number of blank lines. */ +	blankmax = blankcount = 1000;  	for (;;) {  		linenum++; -		lineval = get_line(); +		lineval = parseline();  		trans_table[ifstate[depth]][lineval]();  		debug("process %s -> %s depth %d",  		    linetype_name[lineval], @@ -526,7 +541,7 @@ process(void)   * help from skipcomment().   */  static Linetype -get_line(void) +parseline(void)  {  	const char *cp;  	int cursym; @@ -595,9 +610,21 @@ get_line(void)  			if (incomment)  				linestate = LS_DIRTY;  		} -		/* skipcomment should have changed the state */ -		if (linestate == LS_HASH) -			abort(); /* bug */ +		/* skipcomment normally changes the state, except +		   if the last line of the file lacks a newline, or +		   if there is too much whitespace in a directive */ +		if (linestate == LS_HASH) { +			size_t len = cp - tline; +			if (fgets(tline + len, MAXLINE - len, input) == NULL) { +				/* append the missing newline */ +				tline[len+0] = '\n'; +				tline[len+1] = '\0'; +				cp++; +				linestate = LS_START; +			} else { +				linestate = LS_DIRTY; +			} +		}  	}  	if (linestate == LS_DIRTY) {  		while (*cp != '\0') @@ -610,17 +637,40 @@ get_line(void)  /*   * These are the binary operators that are supported by the expression - * evaluator. Note that if support for division is added then we also - * need short-circuiting booleans because of divide-by-zero. + * evaluator.   */ -static int op_lt(int a, int b) { return (a < b); } -static int op_gt(int a, int b) { return (a > b); } -static int op_le(int a, int b) { return (a <= b); } -static int op_ge(int a, int b) { return (a >= b); } -static int op_eq(int a, int b) { return (a == b); } -static int op_ne(int a, int b) { return (a != b); } -static int op_or(int a, int b) { return (a || b); } -static int op_and(int a, int b) { return (a && b); } +static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) { +	if(at == LT_IF || bt == LT_IF) return (LT_IF); +	return (*p = v, v ? LT_TRUE : LT_FALSE); +} +static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) { +	return op_strict(p, a < b, at, bt); +} +static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) { +	return op_strict(p, a > b, at, bt); +} +static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) { +	return op_strict(p, a <= b, at, bt); +} +static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) { +	return op_strict(p, a >= b, at, bt); +} +static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) { +	return op_strict(p, a == b, at, bt); +} +static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) { +	return op_strict(p, a != b, at, bt); +} +static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) { +	if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE)) +		return (*p = 1, LT_TRUE); +	return op_strict(p, a || b, at, bt); +} +static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) { +	if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE)) +		return (*p = 0, LT_FALSE); +	return op_strict(p, a && b, at, bt); +}  /*   * An evaluation function takes three arguments, as follows: (1) a pointer to @@ -629,8 +679,8 @@ static int op_and(int a, int b) { return (a && b); }   * value of the expression; and (3) a pointer to a char* that points to the   * expression to be evaluated and that is updated to the end of the expression   * when evaluation is complete. The function returns LT_FALSE if the value of - * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the - * expression could not be evaluated. + * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression + * depends on an unknown symbol, or LT_ERROR if there is a parse failure.   */  struct ops; @@ -649,7 +699,7 @@ static const struct ops {  	eval_fn *inner;  	struct op {  		const char *str; -		int (*fn)(int, int); +		Linetype (*fn)(int *, Linetype, int, Linetype, int);  	} op[5];  } eval_ops[] = {  	{ eval_table, { { "||", op_or } } }, @@ -664,8 +714,8 @@ static const struct ops {  /*   * Function for evaluating the innermost parts of expressions, - * viz. !expr (expr) defined(symbol) symbol number - * We reset the keepthis flag when we find a non-constant subexpression. + * viz. !expr (expr) number defined(symbol) symbol + * We reset the constexpr flag in the last two cases.   */  static Linetype  eval_unary(const struct ops *ops, int *valp, const char **cpp) @@ -673,68 +723,83 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)  	const char *cp;  	char *ep;  	int sym; +	bool defparen; +	Linetype lt;  	cp = skipcomment(*cpp);  	if (*cp == '!') {  		debug("eval%d !", ops - eval_ops);  		cp++; -		if (eval_unary(ops, valp, &cp) == LT_IF) { -			*cpp = cp; -			return (LT_IF); +		lt = eval_unary(ops, valp, &cp); +		if (lt == LT_ERROR) +			return (LT_ERROR); +		if (lt != LT_IF) { +			*valp = !*valp; +			lt = *valp ? LT_TRUE : LT_FALSE;  		} -		*valp = !*valp;  	} else if (*cp == '(') {  		cp++;  		debug("eval%d (", ops - eval_ops); -		if (eval_table(eval_ops, valp, &cp) == LT_IF) -			return (LT_IF); +		lt = eval_table(eval_ops, valp, &cp); +		if (lt == LT_ERROR) +			return (LT_ERROR);  		cp = skipcomment(cp);  		if (*cp++ != ')') -			return (LT_IF); +			return (LT_ERROR);  	} else if (isdigit((unsigned char)*cp)) {  		debug("eval%d number", ops - eval_ops);  		*valp = strtol(cp, &ep, 0); +		if (ep == cp) +			return (LT_ERROR); +		lt = *valp ? LT_TRUE : LT_FALSE;  		cp = skipsym(cp);  	} else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) {  		cp = skipcomment(cp+7);  		debug("eval%d defined", ops - eval_ops); -		if (*cp++ != '(') -			return (LT_IF); -		cp = skipcomment(cp); +		if (*cp == '(') { +			cp = skipcomment(cp+1); +			defparen = true; +		} else { +			defparen = false; +		}  		sym = findsym(cp); -		cp = skipsym(cp); -		cp = skipcomment(cp); -		if (*cp++ != ')') -			return (LT_IF); -		if (sym >= 0) +		if (sym < 0) { +			lt = LT_IF; +		} else {  			*valp = (value[sym] != NULL); -		else { -			*cpp = cp; -			return (LT_IF); +			lt = *valp ? LT_TRUE : LT_FALSE;  		} -		keepthis = false; +		cp = skipsym(cp); +		cp = skipcomment(cp); +		if (defparen && *cp++ != ')') +			return (LT_ERROR); +		constexpr = false;  	} else if (!endsym(*cp)) {  		debug("eval%d symbol", ops - eval_ops);  		sym = findsym(cp); -		if (sym < 0) -			return (LT_IF); -		if (value[sym] == NULL) +		cp = skipsym(cp); +		if (sym < 0) { +			lt = LT_IF; +			cp = skipargs(cp); +		} else if (value[sym] == NULL) {  			*valp = 0; -		else { +			lt = LT_FALSE; +		} else {  			*valp = strtol(value[sym], &ep, 0);  			if (*ep != '\0' || ep == value[sym]) -				return (LT_IF); +				return (LT_ERROR); +			lt = *valp ? LT_TRUE : LT_FALSE; +			cp = skipargs(cp);  		} -		cp = skipsym(cp); -		keepthis = false; +		constexpr = false;  	} else {  		debug("eval%d bad expr", ops - eval_ops); -		return (LT_IF); +		return (LT_ERROR);  	}  	*cpp = cp;  	debug("eval%d = %d", ops - eval_ops, *valp); -	return (*valp ? LT_TRUE : LT_FALSE); +	return (lt);  }  /* @@ -746,11 +811,13 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)  	const struct op *op;  	const char *cp;  	int val; -	Linetype lhs, rhs; +	Linetype lt, rt;  	debug("eval%d", ops - eval_ops);  	cp = *cpp; -	lhs = ops->inner(ops+1, valp, &cp); +	lt = ops->inner(ops+1, valp, &cp); +	if (lt == LT_ERROR) +		return (LT_ERROR);  	for (;;) {  		cp = skipcomment(cp);  		for (op = ops->op; op->str != NULL; op++) @@ -760,32 +827,16 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)  			break;  		cp += strlen(op->str);  		debug("eval%d %s", ops - eval_ops, op->str); -		rhs = ops->inner(ops+1, &val, &cp); -		if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) { -			debug("eval%d: and always false", ops - eval_ops); -			if (lhs == LT_IF) -				*valp = val; -			lhs = LT_FALSE; -			continue; -		} -		if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) { -			debug("eval%d: or always true", ops - eval_ops); -			if (lhs == LT_IF) -				*valp = val; -			lhs = LT_TRUE; -			continue; -		} -		if (rhs == LT_IF) -			lhs = LT_IF; -		if (lhs != LT_IF) -			*valp = op->fn(*valp, val); +		rt = ops->inner(ops+1, &val, &cp); +		if (rt == LT_ERROR) +			return (LT_ERROR); +		lt = op->fn(valp, lt, *valp, rt, val);  	}  	*cpp = cp;  	debug("eval%d = %d", ops - eval_ops, *valp); -	if (lhs != LT_IF) -		lhs = (*valp ? LT_TRUE : LT_FALSE); -	return lhs; +	debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]); +	return (lt);  }  /* @@ -796,17 +847,14 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)  static Linetype  ifeval(const char **cpp)  { -	const char *cp = *cpp;  	int ret; -	int val; +	int val = 0;  	debug("eval %s", *cpp); -	keepthis = killconsts ? false : true; -	ret = eval_table(eval_ops, &val, &cp); -	if (ret != LT_IF) -		*cpp = cp; +	constexpr = killconsts ? false : true; +	ret = eval_table(eval_ops, &val, cpp);  	debug("eval = %d", val); -	return (keepthis ? LT_IF : ret); +	return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);  }  /* @@ -918,6 +966,31 @@ skipcomment(const char *cp)  }  /* + * Skip macro arguments. + */ +static const char * +skipargs(const char *cp) +{ +	const char *ocp = cp; +	int level = 0; +	cp = skipcomment(cp); +	if (*cp != '(') +		return (cp); +	do { +		if (*cp == '(') +			level++; +		if (*cp == ')') +			level--; +		cp = skipcomment(cp+1); +	} while (level != 0 && *cp != '\0'); +	if (level == 0) +		return (cp); +	else +	/* Rewind and re-detect the syntax error later. */ +		return (ocp); +} + +/*   * Skip over an identifier.   */  static const char * @@ -929,7 +1002,7 @@ skipsym(const char *cp)  }  /* - * Look for the symbol in the symbol table. If is is found, we return + * Look for the symbol in the symbol table. If it is found, we return   * the symbol table index, else we return -1.   */  static int | 
