aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-03-01 02:55:20 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-03-01 02:55:20 -0500
commit35858adbfca13678af99fb31618ef4428d6dedb0 (patch)
tree3336feaa61324486945816cb52c347733e7c0821 /scripts
parent197d4db752e67160d79fed09968c2140376a80a3 (diff)
parent4b70858ba8d4537daf782defebe5f2ff80ccef2b (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include6
-rw-r--r--scripts/Makefile.build1
-rw-r--r--scripts/Makefile.lib21
-rw-r--r--scripts/Makefile.modbuiltin55
-rw-r--r--scripts/basic/fixdep.c10
-rwxr-xr-xscripts/checkpatch.pl2
-rw-r--r--scripts/genksyms/keywords.c_shipped191
-rw-r--r--scripts/genksyms/keywords.gperf2
-rwxr-xr-xscripts/get_maintainer.pl583
-rwxr-xr-xscripts/headers.sh2
-rw-r--r--scripts/kconfig/Makefile1
-rw-r--r--scripts/kconfig/confdata.c24
-rw-r--r--scripts/markup_oops.pl2
-rwxr-xr-xscripts/mkcompile_h2
-rw-r--r--scripts/mod/Makefile2
-rw-r--r--scripts/mod/file2alias.c2
-rw-r--r--scripts/mod/mk_elfconfig.c9
-rw-r--r--scripts/mod/modpost.c177
-rw-r--r--scripts/mod/modpost.h3
-rw-r--r--scripts/package/Makefile20
-rw-r--r--scripts/package/buildtar6
-rwxr-xr-xscripts/recordmcount.pl60
-rwxr-xr-xscripts/tags.sh8
-rw-r--r--scripts/unifdef.c341
24 files changed, 942 insertions, 588 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,\
149# $(Q)$(MAKE) $(build)=dir 149# $(Q)$(MAKE) $(build)=dir
150build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj 150build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
151 151
152###
153# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj=
154# Usage:
155# $(Q)$(MAKE) $(modbuiltin)=dir
156modbuiltin := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.modbuiltin obj
157
152# Prefix -I with $(srctree) if it is not an absolute path. 158# Prefix -I with $(srctree) if it is not an absolute path.
153# skip if -I has no parameter 159# skip if -I has no parameter
154addtree = $(if $(patsubst -I%,%,$(1)), \ 160addtree = $(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
207 207
208ifdef CONFIG_FTRACE_MCOUNT_RECORD 208ifdef CONFIG_FTRACE_MCOUNT_RECORD
209cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ 209cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
210 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
210 "$(if $(CONFIG_64BIT),64,32)" \ 211 "$(if $(CONFIG_64BIT),64,32)" \
211 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ 212 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
212 "$(if $(part-of-module),1,0)" "$(@)"; 213 "$(if $(part-of-module),1,0)" "$(@)";
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index ffdafb26f539..f9bdf264473d 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -127,6 +127,11 @@ _c_flags += $(if $(patsubst n%,, \
127 $(CFLAGS_GCOV)) 127 $(CFLAGS_GCOV))
128endif 128endif
129 129
130ifdef CONFIG_SYMBOL_PREFIX
131_cpp_flags += -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))
132endif
133
134
130# If building the kernel in a separate objtree expand all occurrences 135# If building the kernel in a separate objtree expand all occurrences
131# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). 136# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
132 137
@@ -208,14 +213,19 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \
208 213
209# Bzip2 and LZMA do not include size in file... so we have to fake that; 214# Bzip2 and LZMA do not include size in file... so we have to fake that;
210# append the size as a 32-bit littleendian number as gzip does. 215# append the size as a 32-bit littleendian number as gzip does.
211size_append = /bin/echo -ne $(shell \ 216size_append = printf $(shell \
212dec_size=0; \ 217dec_size=0; \
213for F in $1; do \ 218for F in $1; do \
214 fsize=$$(stat -c "%s" $$F); \ 219 fsize=$$(stat -c "%s" $$F); \
215 dec_size=$$(expr $$dec_size + $$fsize); \ 220 dec_size=$$(expr $$dec_size + $$fsize); \
216done; \ 221done; \
217printf "%08x" $$dec_size | \ 222printf "%08x\n" $$dec_size | \
218 sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g' \ 223 sed 's/\(..\)/\1 /g' | { \
224 read ch0 ch1 ch2 ch3; \
225 for ch in $$ch3 $$ch2 $$ch1 $$ch0; do \
226 printf '%s%03o' '\\' $$((0x$$ch)); \
227 done; \
228 } \
219) 229)
220 230
221quiet_cmd_bzip2 = BZIP2 $@ 231quiet_cmd_bzip2 = BZIP2 $@
@@ -230,3 +240,8 @@ quiet_cmd_lzma = LZMA $@
230cmd_lzma = (cat $(filter-out FORCE,$^) | \ 240cmd_lzma = (cat $(filter-out FORCE,$^) | \
231 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 241 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
232 (rm -f $@ ; false) 242 (rm -f $@ ; false)
243
244quiet_cmd_lzo = LZO $@
245cmd_lzo = (cat $(filter-out FORCE,$^) | \
246 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
247 (rm -f $@ ; false)
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 @@
1# ==========================================================================
2# Generating modules.builtin
3# ==========================================================================
4
5src := $(obj)
6
7PHONY := __modbuiltin
8__modbuiltin:
9
10-include include/config/auto.conf
11# tristate.conf sets tristate variables to uppercase 'Y' or 'M'
12# That way, we get the list of built-in modules in obj-Y
13-include include/config/tristate.conf
14
15include scripts/Kbuild.include
16
17# The filename Kbuild has precedence over Makefile
18kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
19kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
20include $(kbuild-file)
21
22include scripts/Makefile.lib
23__subdir-Y := $(patsubst %/,%,$(filter %/, $(obj-Y)))
24subdir-Y += $(__subdir-Y)
25subdir-ym := $(sort $(subdir-y) $(subdir-Y) $(subdir-m))
26subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
27obj-Y := $(addprefix $(obj)/,$(obj-Y))
28
29modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym))
30modbuiltin-mods := $(filter %.ko, $(obj-Y:.o=.ko))
31modbuiltin-target := $(obj)/modules.builtin
32
33__modbuiltin: $(modbuiltin-target) $(subdir-ym)
34 @:
35
36$(modbuiltin-target): $(subdir-ym) FORCE
37 $(Q)(for m in $(modbuiltin-mods); do echo kernel/$$m; done; \
38 cat /dev/null $(modbuiltin-subdirs)) > $@
39
40PHONY += FORCE
41
42FORCE:
43
44# Descending
45# ---------------------------------------------------------------------------
46
47PHONY += $(subdir-ym)
48$(subdir-ym):
49 $(Q)$(MAKE) $(modbuiltin)=$@
50
51
52# Declare the contents of the .PHONY variable as phony. We keep that
53# information in a variable se we can use it in if_changed and friends.
54
55.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 @@
16 * tells make when to remake a file. 16 * tells make when to remake a file.
17 * 17 *
18 * To use this list as-is however has the drawback that virtually 18 * To use this list as-is however has the drawback that virtually
19 * every file in the kernel includes <linux/autoconf.h>. 19 * every file in the kernel includes autoconf.h.
20 * 20 *
21 * If the user re-runs make *config, linux/autoconf.h will be 21 * If the user re-runs make *config, autoconf.h will be
22 * regenerated. make notices that and will rebuild every file which 22 * regenerated. make notices that and will rebuild every file which
23 * includes autoconf.h, i.e. basically all files. This is extremely 23 * includes autoconf.h, i.e. basically all files. This is extremely
24 * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. 24 * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
25 * 25 *
26 * So we play the same trick that "mkdep" played before. We replace 26 * So we play the same trick that "mkdep" played before. We replace
27 * the dependency on linux/autoconf.h by a dependency on every config 27 * the dependency on autoconf.h by a dependency on every config
28 * option which is mentioned in any of the listed prequisites. 28 * option which is mentioned in any of the listed prequisites.
29 * 29 *
30 * kconfig populates a tree in include/config/ with an empty file 30 * kconfig populates a tree in include/config/ with an empty file
@@ -73,7 +73,7 @@
73 * cmd_<target> = <cmdline> 73 * cmd_<target> = <cmdline>
74 * 74 *
75 * and then basically copies the .<target>.d file to stdout, in the 75 * and then basically copies the .<target>.d file to stdout, in the
76 * process filtering out the dependency on linux/autoconf.h and adding 76 * process filtering out the dependency on autoconf.h and adding
77 * dependencies on include/config/my/option.h for every 77 * dependencies on include/config/my/option.h for every
78 * CONFIG_MY_OPTION encountered in any of the prequisites. 78 * CONFIG_MY_OPTION encountered in any of the prequisites.
79 * 79 *
@@ -324,7 +324,7 @@ static void parse_dep_file(void *map, size_t len)
324 p++; 324 p++;
325 } 325 }
326 memcpy(s, m, p-m); s[p-m] = 0; 326 memcpy(s, m, p-m); s[p-m] = 0;
327 if (strrcmp(s, "include/linux/autoconf.h") && 327 if (strrcmp(s, "include/generated/autoconf.h") &&
328 strrcmp(s, "arch/um/include/uml-config.h") && 328 strrcmp(s, "arch/um/include/uml-config.h") &&
329 strrcmp(s, ".ver")) { 329 strrcmp(s, ".ver")) {
330 printf(" %s \\\n", s); 330 printf(" %s \\\n", s);
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index bc4114f1ab30..3257d3d96767 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,5 +1,5 @@
1#!/usr/bin/perl -w 1#!/usr/bin/perl -w
2# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit) 2# (c) 2001, Dave Jones. (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5# (c) 2008,2009, Andy Whitcroft <apw@canonical.com> 5# (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
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 @@
1/* ANSI-C code produced by gperf version 3.0.3 */ 1/* ANSI-C code produced by gperf version 3.0.4 */
2/* 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 */ 2/* 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 */
3 3
4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -34,7 +34,7 @@ struct resword;
34static const struct resword *is_reserved_word(register const char *str, register unsigned int len); 34static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
35#line 5 "scripts/genksyms/keywords.gperf" 35#line 5 "scripts/genksyms/keywords.gperf"
36struct resword { const char *name; int token; }; 36struct resword { const char *name; int token; };
37/* maximum key range = 62, duplicates = 0 */ 37/* maximum key range = 64, duplicates = 0 */
38 38
39#ifdef __GNUC__ 39#ifdef __GNUC__
40__inline 40__inline
@@ -48,39 +48,39 @@ is_reserved_hash (register const char *str, register unsigned int len)
48{ 48{
49 static const unsigned char asso_values[] = 49 static const unsigned char asso_values[] =
50 { 50 {
51 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 51 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
52 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 52 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
53 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 53 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
54 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 54 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
55 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
56 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 56 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
57 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, 57 67, 67, 67, 67, 67, 67, 67, 67, 67, 0,
58 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, 58 67, 67, 67, 67, 67, 67, 15, 67, 67, 67,
59 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, 59 0, 67, 67, 67, 67, 67, 67, 67, 67, 67,
60 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, 60 67, 67, 67, 67, 67, 0, 67, 0, 67, 5,
61 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, 61 25, 20, 15, 30, 67, 15, 67, 67, 10, 0,
62 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, 62 10, 40, 20, 67, 10, 5, 0, 10, 15, 67,
63 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 63 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
64 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 64 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
66 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
67 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
68 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 68 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
69 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 69 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
70 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
71 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 71 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
72 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 72 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
73 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 73 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
74 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 74 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
75 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 75 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
76 65, 65, 65, 65, 65, 65 76 67, 67, 67, 67, 67, 67
77 }; 77 };
78 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; 78 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
79} 79}
80 80
81#ifdef __GNUC__ 81#ifdef __GNUC__
82__inline 82__inline
83#ifdef __GNUC_STDC_INLINE__ 83#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
84__attribute__ ((__gnu_inline__)) 84__attribute__ ((__gnu_inline__))
85#endif 85#endif
86#endif 86#endif
@@ -89,116 +89,119 @@ is_reserved_word (register const char *str, register unsigned int len)
89{ 89{
90 enum 90 enum
91 { 91 {
92 TOTAL_KEYWORDS = 43, 92 TOTAL_KEYWORDS = 45,
93 MIN_WORD_LENGTH = 3, 93 MIN_WORD_LENGTH = 3,
94 MAX_WORD_LENGTH = 24, 94 MAX_WORD_LENGTH = 24,
95 MIN_HASH_VALUE = 3, 95 MIN_HASH_VALUE = 3,
96 MAX_HASH_VALUE = 64 96 MAX_HASH_VALUE = 66
97 }; 97 };
98 98
99 static const struct resword wordlist[] = 99 static const struct resword wordlist[] =
100 { 100 {
101 {""}, {""}, {""}, 101 {""}, {""}, {""},
102#line 28 "scripts/genksyms/keywords.gperf" 102#line 30 "scripts/genksyms/keywords.gperf"
103 {"asm", ASM_KEYW}, 103 {"asm", ASM_KEYW},
104 {""}, 104 {""},
105#line 10 "scripts/genksyms/keywords.gperf" 105#line 12 "scripts/genksyms/keywords.gperf"
106 {"__asm", ASM_KEYW}, 106 {"__asm", ASM_KEYW},
107 {""}, 107 {""},
108#line 11 "scripts/genksyms/keywords.gperf" 108#line 13 "scripts/genksyms/keywords.gperf"
109 {"__asm__", ASM_KEYW}, 109 {"__asm__", ASM_KEYW},
110 {""}, {""}, 110 {""}, {""},
111#line 54 "scripts/genksyms/keywords.gperf" 111#line 56 "scripts/genksyms/keywords.gperf"
112 {"__typeof__", TYPEOF_KEYW}, 112 {"__typeof__", TYPEOF_KEYW},
113 {""}, 113 {""},
114#line 14 "scripts/genksyms/keywords.gperf" 114#line 16 "scripts/genksyms/keywords.gperf"
115 {"__const", CONST_KEYW}, 115 {"__const", CONST_KEYW},
116#line 13 "scripts/genksyms/keywords.gperf"
117 {"__attribute__", ATTRIBUTE_KEYW},
118#line 15 "scripts/genksyms/keywords.gperf" 116#line 15 "scripts/genksyms/keywords.gperf"
117 {"__attribute__", ATTRIBUTE_KEYW},
118#line 17 "scripts/genksyms/keywords.gperf"
119 {"__const__", CONST_KEYW}, 119 {"__const__", CONST_KEYW},
120#line 20 "scripts/genksyms/keywords.gperf" 120#line 22 "scripts/genksyms/keywords.gperf"
121 {"__signed__", SIGNED_KEYW}, 121 {"__signed__", SIGNED_KEYW},
122#line 46 "scripts/genksyms/keywords.gperf" 122#line 48 "scripts/genksyms/keywords.gperf"
123 {"static", STATIC_KEYW}, 123 {"static", STATIC_KEYW},
124#line 22 "scripts/genksyms/keywords.gperf" 124 {""},
125 {"__volatile__", VOLATILE_KEYW}, 125#line 43 "scripts/genksyms/keywords.gperf"
126#line 41 "scripts/genksyms/keywords.gperf"
127 {"int", INT_KEYW}, 126 {"int", INT_KEYW},
128#line 34 "scripts/genksyms/keywords.gperf" 127#line 36 "scripts/genksyms/keywords.gperf"
129 {"char", CHAR_KEYW}, 128 {"char", CHAR_KEYW},
130#line 35 "scripts/genksyms/keywords.gperf" 129#line 37 "scripts/genksyms/keywords.gperf"
131 {"const", CONST_KEYW}, 130 {"const", CONST_KEYW},
132#line 47 "scripts/genksyms/keywords.gperf" 131#line 49 "scripts/genksyms/keywords.gperf"
133 {"struct", STRUCT_KEYW}, 132 {"struct", STRUCT_KEYW},
134#line 26 "scripts/genksyms/keywords.gperf" 133#line 28 "scripts/genksyms/keywords.gperf"
135 {"__restrict__", RESTRICT_KEYW}, 134 {"__restrict__", RESTRICT_KEYW},
136#line 27 "scripts/genksyms/keywords.gperf" 135#line 29 "scripts/genksyms/keywords.gperf"
137 {"restrict", RESTRICT_KEYW}, 136 {"restrict", RESTRICT_KEYW},
138#line 25 "scripts/genksyms/keywords.gperf" 137#line 9 "scripts/genksyms/keywords.gperf"
139 {"_restrict", RESTRICT_KEYW}, 138 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
140#line 18 "scripts/genksyms/keywords.gperf" 139#line 20 "scripts/genksyms/keywords.gperf"
141 {"__inline__", INLINE_KEYW}, 140 {"__inline__", INLINE_KEYW},
142#line 12 "scripts/genksyms/keywords.gperf"
143 {"__attribute", ATTRIBUTE_KEYW},
144 {""}, 141 {""},
145#line 16 "scripts/genksyms/keywords.gperf" 142#line 24 "scripts/genksyms/keywords.gperf"
143 {"__volatile__", VOLATILE_KEYW},
144#line 7 "scripts/genksyms/keywords.gperf"
145 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
146#line 27 "scripts/genksyms/keywords.gperf"
147 {"_restrict", RESTRICT_KEYW},
148 {""},
149#line 14 "scripts/genksyms/keywords.gperf"
150 {"__attribute", ATTRIBUTE_KEYW},
151#line 8 "scripts/genksyms/keywords.gperf"
152 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
153#line 18 "scripts/genksyms/keywords.gperf"
146 {"__extension__", EXTENSION_KEYW}, 154 {"__extension__", EXTENSION_KEYW},
147#line 37 "scripts/genksyms/keywords.gperf" 155#line 39 "scripts/genksyms/keywords.gperf"
148 {"enum", ENUM_KEYW}, 156 {"enum", ENUM_KEYW},
149#line 21 "scripts/genksyms/keywords.gperf" 157#line 10 "scripts/genksyms/keywords.gperf"
150 {"__volatile", VOLATILE_KEYW}, 158 {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
151#line 38 "scripts/genksyms/keywords.gperf" 159#line 40 "scripts/genksyms/keywords.gperf"
152 {"extern", EXTERN_KEYW}, 160 {"extern", EXTERN_KEYW},
153 {""}, 161 {""},
154#line 19 "scripts/genksyms/keywords.gperf" 162#line 21 "scripts/genksyms/keywords.gperf"
155 {"__signed", SIGNED_KEYW}, 163 {"__signed", SIGNED_KEYW},
156#line 9 "scripts/genksyms/keywords.gperf" 164#line 11 "scripts/genksyms/keywords.gperf"
157 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, 165 {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
158 {""}, 166#line 51 "scripts/genksyms/keywords.gperf"
159#line 53 "scripts/genksyms/keywords.gperf" 167 {"union", UNION_KEYW},
168#line 55 "scripts/genksyms/keywords.gperf"
160 {"typeof", TYPEOF_KEYW}, 169 {"typeof", TYPEOF_KEYW},
161#line 48 "scripts/genksyms/keywords.gperf" 170#line 50 "scripts/genksyms/keywords.gperf"
162 {"typedef", TYPEDEF_KEYW}, 171 {"typedef", TYPEDEF_KEYW},
163#line 17 "scripts/genksyms/keywords.gperf" 172#line 19 "scripts/genksyms/keywords.gperf"
164 {"__inline", INLINE_KEYW}, 173 {"__inline", INLINE_KEYW},
165#line 33 "scripts/genksyms/keywords.gperf" 174#line 35 "scripts/genksyms/keywords.gperf"
166 {"auto", AUTO_KEYW}, 175 {"auto", AUTO_KEYW},
167#line 49 "scripts/genksyms/keywords.gperf" 176#line 23 "scripts/genksyms/keywords.gperf"
168 {"union", UNION_KEYW}, 177 {"__volatile", VOLATILE_KEYW},
169 {""}, {""},
170#line 50 "scripts/genksyms/keywords.gperf"
171 {"unsigned", UNSIGNED_KEYW},
172#line 51 "scripts/genksyms/keywords.gperf"
173 {"void", VOID_KEYW},
174#line 44 "scripts/genksyms/keywords.gperf"
175 {"short", SHORT_KEYW},
176 {""}, {""}, 178 {""}, {""},
177#line 52 "scripts/genksyms/keywords.gperf" 179#line 52 "scripts/genksyms/keywords.gperf"
178 {"volatile", VOLATILE_KEYW}, 180 {"unsigned", UNSIGNED_KEYW},
179 {""},
180#line 39 "scripts/genksyms/keywords.gperf"
181 {"float", FLOAT_KEYW},
182#line 36 "scripts/genksyms/keywords.gperf"
183 {"double", DOUBLE_KEYW},
184 {""}, 181 {""},
185#line 7 "scripts/genksyms/keywords.gperf" 182#line 46 "scripts/genksyms/keywords.gperf"
186 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, 183 {"short", SHORT_KEYW},
187 {""}, {""}, 184#line 42 "scripts/genksyms/keywords.gperf"
188#line 40 "scripts/genksyms/keywords.gperf"
189 {"inline", INLINE_KEYW}, 185 {"inline", INLINE_KEYW},
190#line 8 "scripts/genksyms/keywords.gperf"
191 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
192#line 43 "scripts/genksyms/keywords.gperf"
193 {"register", REGISTER_KEYW},
194 {""}, 186 {""},
195#line 24 "scripts/genksyms/keywords.gperf" 187#line 54 "scripts/genksyms/keywords.gperf"
188 {"volatile", VOLATILE_KEYW},
189#line 44 "scripts/genksyms/keywords.gperf"
190 {"long", LONG_KEYW},
191#line 26 "scripts/genksyms/keywords.gperf"
196 {"_Bool", BOOL_KEYW}, 192 {"_Bool", BOOL_KEYW},
197#line 45 "scripts/genksyms/keywords.gperf"
198 {"signed", SIGNED_KEYW},
199 {""}, {""}, 193 {""}, {""},
200#line 42 "scripts/genksyms/keywords.gperf" 194#line 45 "scripts/genksyms/keywords.gperf"
201 {"long", LONG_KEYW} 195 {"register", REGISTER_KEYW},
196#line 53 "scripts/genksyms/keywords.gperf"
197 {"void", VOID_KEYW},
198#line 41 "scripts/genksyms/keywords.gperf"
199 {"float", FLOAT_KEYW},
200#line 38 "scripts/genksyms/keywords.gperf"
201 {"double", DOUBLE_KEYW},
202 {""}, {""}, {""}, {""},
203#line 47 "scripts/genksyms/keywords.gperf"
204 {"signed", SIGNED_KEYW}
202 }; 205 };
203 206
204 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 207 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; }
7EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW 7EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
8EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW 8EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
9EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW 9EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
10EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW
11EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
10__asm, ASM_KEYW 12__asm, ASM_KEYW
11__asm__, ASM_KEYW 13__asm__, ASM_KEYW
12__attribute, ATTRIBUTE_KEYW 14__attribute, ATTRIBUTE_KEYW
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 81a67a458e78..090f24839700 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -13,7 +13,7 @@
13use strict; 13use strict;
14 14
15my $P = $0; 15my $P = $0;
16my $V = '0.21'; 16my $V = '0.23';
17 17
18use Getopt::Long qw(:config no_auto_abbrev); 18use Getopt::Long qw(:config no_auto_abbrev);
19 19
@@ -23,16 +23,19 @@ my $email_usename = 1;
23my $email_maintainer = 1; 23my $email_maintainer = 1;
24my $email_list = 1; 24my $email_list = 1;
25my $email_subscriber_list = 0; 25my $email_subscriber_list = 0;
26my $email_git = 1;
27my $email_git_penguin_chiefs = 0; 26my $email_git_penguin_chiefs = 0;
27my $email_git = 1;
28my $email_git_blame = 0;
28my $email_git_min_signatures = 1; 29my $email_git_min_signatures = 1;
29my $email_git_max_maintainers = 5; 30my $email_git_max_maintainers = 5;
30my $email_git_min_percent = 5; 31my $email_git_min_percent = 5;
31my $email_git_since = "1-year-ago"; 32my $email_git_since = "1-year-ago";
32my $email_git_blame = 0; 33my $email_hg_since = "-365";
33my $email_remove_duplicates = 1; 34my $email_remove_duplicates = 1;
34my $output_multiline = 1; 35my $output_multiline = 1;
35my $output_separator = ", "; 36my $output_separator = ", ";
37my $output_roles = 0;
38my $output_rolestats = 0;
36my $scm = 0; 39my $scm = 0;
37my $web = 0; 40my $web = 0;
38my $subsystem = 0; 41my $subsystem = 0;
@@ -64,21 +67,52 @@ my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)";
64my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; 67my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
65my $rfc822_char = '[\\000-\\377]'; 68my $rfc822_char = '[\\000-\\377]';
66 69
70# VCS command support: class-like functions and strings
71
72my %VCS_cmds;
73
74my %VCS_cmds_git = (
75 "execute_cmd" => \&git_execute_cmd,
76 "available" => '(which("git") ne "") && (-d ".git")',
77 "find_signers_cmd" => "git log --since=\$email_git_since -- \$file",
78 "find_commit_signers_cmd" => "git log -1 \$commit",
79 "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file",
80 "blame_file_cmd" => "git blame -l \$file",
81 "commit_pattern" => "^commit [0-9a-f]{40,40}",
82 "blame_commit_pattern" => "^([0-9a-f]+) "
83);
84
85my %VCS_cmds_hg = (
86 "execute_cmd" => \&hg_execute_cmd,
87 "available" => '(which("hg") ne "") && (-d ".hg")',
88 "find_signers_cmd" =>
89 "hg log --date=\$email_hg_since" .
90 " --template='commit {node}\\n{desc}\\n' -- \$file",
91 "find_commit_signers_cmd" => "hg log --template='{desc}\\n' -r \$commit",
92 "blame_range_cmd" => "", # not supported
93 "blame_file_cmd" => "hg blame -c \$file",
94 "commit_pattern" => "^commit [0-9a-f]{40,40}",
95 "blame_commit_pattern" => "^([0-9a-f]+):"
96);
97
67if (!GetOptions( 98if (!GetOptions(
68 'email!' => \$email, 99 'email!' => \$email,
69 'git!' => \$email_git, 100 'git!' => \$email_git,
101 'git-blame!' => \$email_git_blame,
70 'git-chief-penguins!' => \$email_git_penguin_chiefs, 102 'git-chief-penguins!' => \$email_git_penguin_chiefs,
71 'git-min-signatures=i' => \$email_git_min_signatures, 103 'git-min-signatures=i' => \$email_git_min_signatures,
72 'git-max-maintainers=i' => \$email_git_max_maintainers, 104 'git-max-maintainers=i' => \$email_git_max_maintainers,
73 'git-min-percent=i' => \$email_git_min_percent, 105 'git-min-percent=i' => \$email_git_min_percent,
74 'git-since=s' => \$email_git_since, 106 'git-since=s' => \$email_git_since,
75 'git-blame!' => \$email_git_blame, 107 'hg-since=s' => \$email_hg_since,
76 'remove-duplicates!' => \$email_remove_duplicates, 108 'remove-duplicates!' => \$email_remove_duplicates,
77 'm!' => \$email_maintainer, 109 'm!' => \$email_maintainer,
78 'n!' => \$email_usename, 110 'n!' => \$email_usename,
79 'l!' => \$email_list, 111 'l!' => \$email_list,
80 's!' => \$email_subscriber_list, 112 's!' => \$email_subscriber_list,
81 'multiline!' => \$output_multiline, 113 'multiline!' => \$output_multiline,
114 'roles!' => \$output_roles,
115 'rolestats!' => \$output_rolestats,
82 'separator=s' => \$output_separator, 116 'separator=s' => \$output_separator,
83 'subsystem!' => \$subsystem, 117 'subsystem!' => \$subsystem,
84 'status!' => \$status, 118 'status!' => \$status,
@@ -90,8 +124,7 @@ if (!GetOptions(
90 'v|version' => \$version, 124 'v|version' => \$version,
91 'h|help' => \$help, 125 'h|help' => \$help,
92 )) { 126 )) {
93 usage(); 127 die "$P: invalid argument - use --help if necessary\n";
94 die "$P: invalid argument\n";
95} 128}
96 129
97if ($help != 0) { 130if ($help != 0) {
@@ -113,6 +146,10 @@ if ($output_separator ne ", ") {
113 $output_multiline = 0; 146 $output_multiline = 0;
114} 147}
115 148
149if ($output_rolestats) {
150 $output_roles = 1;
151}
152
116my $selections = $email + $scm + $status + $subsystem + $web; 153my $selections = $email + $scm + $status + $subsystem + $web;
117if ($selections == 0) { 154if ($selections == 0) {
118 usage(); 155 usage();
@@ -175,7 +212,7 @@ if ($email_remove_duplicates) {
175 next if ($line =~ m/^\s*$/); 212 next if ($line =~ m/^\s*$/);
176 213
177 my ($name, $address) = parse_email($line); 214 my ($name, $address) = parse_email($line);
178 $line = format_email($name, $address); 215 $line = format_email($name, $address, $email_usename);
179 216
180 next if ($line =~ m/^\s*$/); 217 next if ($line =~ m/^\s*$/);
181 218
@@ -207,12 +244,10 @@ foreach my $file (@ARGV) {
207 push(@files, $file); 244 push(@files, $file);
208 if (-f $file && $keywords) { 245 if (-f $file && $keywords) {
209 open(FILE, "<$file") or die "$P: Can't open ${file}\n"; 246 open(FILE, "<$file") or die "$P: Can't open ${file}\n";
210 while (<FILE>) { 247 my $text = do { local($/) ; <FILE> };
211 my $patch_line = $_; 248 foreach my $line (keys %keyword_hash) {
212 foreach my $line (keys %keyword_hash) { 249 if ($text =~ m/$keyword_hash{$line}/x) {
213 if ($patch_line =~ m/^.*$keyword_hash{$line}/x) { 250 push(@keyword_tvi, $line);
214 push(@keyword_tvi, $line);
215 }
216 } 251 }
217 } 252 }
218 close(FILE); 253 close(FILE);
@@ -261,54 +296,64 @@ my @status = ();
261 296
262foreach my $file (@files) { 297foreach my $file (@files) {
263 298
264#Do not match excluded file patterns 299 my %hash;
265 300 my $tvi = find_first_section();
266 my $exclude = 0; 301 while ($tvi < @typevalue) {
267 foreach my $line (@typevalue) { 302 my $start = find_starting_index($tvi);
268 if ($line =~ m/^(\C):\s*(.*)/) { 303 my $end = find_ending_index($tvi);
269 my $type = $1; 304 my $exclude = 0;
270 my $value = $2; 305 my $i;
271 if ($type eq 'X') {
272 if (file_match_pattern($file, $value)) {
273 $exclude = 1;
274 last;
275 }
276 }
277 }
278 }
279 306
280 if (!$exclude) { 307 #Do not match excluded file patterns
281 my $tvi = 0; 308
282 my %hash; 309 for ($i = $start; $i < $end; $i++) {
283 foreach my $line (@typevalue) { 310 my $line = $typevalue[$i];
284 if ($line =~ m/^(\C):\s*(.*)/) { 311 if ($line =~ m/^(\C):\s*(.*)/) {
285 my $type = $1; 312 my $type = $1;
286 my $value = $2; 313 my $value = $2;
287 if ($type eq 'F') { 314 if ($type eq 'X') {
288 if (file_match_pattern($file, $value)) { 315 if (file_match_pattern($file, $value)) {
289 my $value_pd = ($value =~ tr@/@@); 316 $exclude = 1;
290 my $file_pd = ($file =~ tr@/@@);
291 $value_pd++ if (substr($value,-1,1) ne "/");
292 if ($pattern_depth == 0 ||
293 (($file_pd - $value_pd) < $pattern_depth)) {
294 $hash{$tvi} = $value_pd;
295 }
296 } 317 }
297 } 318 }
298 } 319 }
299 $tvi++;
300 } 320 }
301 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { 321
302 add_categories($line); 322 if (!$exclude) {
323 for ($i = $start; $i < $end; $i++) {
324 my $line = $typevalue[$i];
325 if ($line =~ m/^(\C):\s*(.*)/) {
326 my $type = $1;
327 my $value = $2;
328 if ($type eq 'F') {
329 if (file_match_pattern($file, $value)) {
330 my $value_pd = ($value =~ tr@/@@);
331 my $file_pd = ($file =~ tr@/@@);
332 $value_pd++ if (substr($value,-1,1) ne "/");
333 if ($pattern_depth == 0 ||
334 (($file_pd - $value_pd) < $pattern_depth)) {
335 $hash{$tvi} = $value_pd;
336 }
337 }
338 }
339 }
340 }
303 } 341 }
342
343 $tvi += ($end - $start);
344
345 }
346
347 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
348 add_categories($line);
304 } 349 }
305 350
306 if ($email && $email_git) { 351 if ($email && $email_git) {
307 recent_git_signoffs($file); 352 vcs_file_signoffs($file);
308 } 353 }
309 354
310 if ($email && $email_git_blame) { 355 if ($email && $email_git_blame) {
311 git_assign_blame($file); 356 vcs_file_blame($file);
312 } 357 }
313} 358}
314 359
@@ -324,11 +369,11 @@ if ($email) {
324 if ($chief =~ m/^(.*):(.*)/) { 369 if ($chief =~ m/^(.*):(.*)/) {
325 my $email_address; 370 my $email_address;
326 371
327 $email_address = format_email($1, $2); 372 $email_address = format_email($1, $2, $email_usename);
328 if ($email_git_penguin_chiefs) { 373 if ($email_git_penguin_chiefs) {
329 push(@email_to, $email_address); 374 push(@email_to, [$email_address, 'chief penguin']);
330 } else { 375 } else {
331 @email_to = grep(!/${email_address}/, @email_to); 376 @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
332 } 377 }
333 } 378 }
334 } 379 }
@@ -342,7 +387,7 @@ if ($email || $email_list) {
342 if ($email_list) { 387 if ($email_list) {
343 @to = (@to, @list_to); 388 @to = (@to, @list_to);
344 } 389 }
345 output(uniq(@to)); 390 output(merge_email(@to));
346} 391}
347 392
348if ($scm) { 393if ($scm) {
@@ -398,13 +443,16 @@ MAINTAINER field selection options:
398 --git-min-signatures => number of signatures required (default: 1) 443 --git-min-signatures => number of signatures required (default: 1)
399 --git-max-maintainers => maximum maintainers to add (default: 5) 444 --git-max-maintainers => maximum maintainers to add (default: 5)
400 --git-min-percent => minimum percentage of commits required (default: 5) 445 --git-min-percent => minimum percentage of commits required (default: 5)
401 --git-since => git history to use (default: 1-year-ago)
402 --git-blame => use git blame to find modified commits for patch or file 446 --git-blame => use git blame to find modified commits for patch or file
447 --git-since => git history to use (default: 1-year-ago)
448 --hg-since => hg history to use (default: -365)
403 --m => include maintainer(s) if any 449 --m => include maintainer(s) if any
404 --n => include name 'Full Name <addr\@domain.tld>' 450 --n => include name 'Full Name <addr\@domain.tld>'
405 --l => include list(s) if any 451 --l => include list(s) if any
406 --s => include subscriber only list(s) if any 452 --s => include subscriber only list(s) if any
407 --remove-duplicates => minimize duplicate email names/addresses 453 --remove-duplicates => minimize duplicate email names/addresses
454 --roles => show roles (status:subsystem, git-signer, list, etc...)
455 --rolestats => show roles and statistics (commits/total_commits, %)
408 --scm => print SCM tree(s) if any 456 --scm => print SCM tree(s) if any
409 --status => print status if any 457 --status => print status if any
410 --subsystem => print subsystem name if any 458 --subsystem => print subsystem name if any
@@ -430,11 +478,24 @@ Notes:
430 directory are examined as git recurses directories. 478 directory are examined as git recurses directories.
431 Any specified X: (exclude) pattern matches are _not_ ignored. 479 Any specified X: (exclude) pattern matches are _not_ ignored.
432 Used with "--nogit", directory is used as a pattern match, 480 Used with "--nogit", directory is used as a pattern match,
433 no individual file within the directory or subdirectory 481 no individual file within the directory or subdirectory
434 is matched. 482 is matched.
435 Used with "--git-blame", does not iterate all files in directory 483 Used with "--git-blame", does not iterate all files in directory
436 Using "--git-blame" is slow and may add old committers and authors 484 Using "--git-blame" is slow and may add old committers and authors
437 that are no longer active maintainers to the output. 485 that are no longer active maintainers to the output.
486 Using "--roles" or "--rolestats" with git send-email --cc-cmd or any
487 other automated tools that expect only ["name"] <email address>
488 may not work because of additional output after <email address>.
489 Using "--rolestats" and "--git-blame" shows the #/total=% commits,
490 not the percentage of the entire file authored. # of commits is
491 not a good measure of amount of code authored. 1 major commit may
492 contain a thousand lines, 5 trivial commits may modify a single line.
493 If git is not installed, but mercurial (hg) is installed and an .hg
494 repository exists, the following options apply to mercurial:
495 --git,
496 --git-min-signatures, --git-max-maintainers, --git-min-percent, and
497 --git-blame
498 Use --hg-since not --git-since to control date selection
438EOT 499EOT
439} 500}
440 501
@@ -493,7 +554,7 @@ sub parse_email {
493} 554}
494 555
495sub format_email { 556sub format_email {
496 my ($name, $address) = @_; 557 my ($name, $address, $usename) = @_;
497 558
498 my $formatted_email; 559 my $formatted_email;
499 560
@@ -506,11 +567,11 @@ sub format_email {
506 $name = "\"$name\""; 567 $name = "\"$name\"";
507 } 568 }
508 569
509 if ($email_usename) { 570 if ($usename) {
510 if ("$name" eq "") { 571 if ("$name" eq "") {
511 $formatted_email = "$address"; 572 $formatted_email = "$address";
512 } else { 573 } else {
513 $formatted_email = "$name <${address}>"; 574 $formatted_email = "$name <$address>";
514 } 575 }
515 } else { 576 } else {
516 $formatted_email = $address; 577 $formatted_email = $address;
@@ -519,6 +580,20 @@ sub format_email {
519 return $formatted_email; 580 return $formatted_email;
520} 581}
521 582
583sub find_first_section {
584 my $index = 0;
585
586 while ($index < @typevalue) {
587 my $tv = $typevalue[$index];
588 if (($tv =~ m/^(\C):\s*(.*)/)) {
589 last;
590 }
591 $index++;
592 }
593
594 return $index;
595}
596
522sub find_starting_index { 597sub find_starting_index {
523 my ($index) = @_; 598 my ($index) = @_;
524 599
@@ -547,6 +622,71 @@ sub find_ending_index {
547 return $index; 622 return $index;
548} 623}
549 624
625sub get_maintainer_role {
626 my ($index) = @_;
627
628 my $i;
629 my $start = find_starting_index($index);
630 my $end = find_ending_index($index);
631
632 my $role;
633 my $subsystem = $typevalue[$start];
634 if (length($subsystem) > 20) {
635 $subsystem = substr($subsystem, 0, 17);
636 $subsystem =~ s/\s*$//;
637 $subsystem = $subsystem . "...";
638 }
639
640 for ($i = $start + 1; $i < $end; $i++) {
641 my $tv = $typevalue[$i];
642 if ($tv =~ m/^(\C):\s*(.*)/) {
643 my $ptype = $1;
644 my $pvalue = $2;
645 if ($ptype eq "S") {
646 $role = $pvalue;
647 }
648 }
649 }
650
651 $role = lc($role);
652 if ($role eq "supported") {
653 $role = "supporter";
654 } elsif ($role eq "maintained") {
655 $role = "maintainer";
656 } elsif ($role eq "odd fixes") {
657 $role = "odd fixer";
658 } elsif ($role eq "orphan") {
659 $role = "orphan minder";
660 } elsif ($role eq "obsolete") {
661 $role = "obsolete minder";
662 } elsif ($role eq "buried alive in reporters") {
663 $role = "chief penguin";
664 }
665
666 return $role . ":" . $subsystem;
667}
668
669sub get_list_role {
670 my ($index) = @_;
671
672 my $i;
673 my $start = find_starting_index($index);
674 my $end = find_ending_index($index);
675
676 my $subsystem = $typevalue[$start];
677 if (length($subsystem) > 20) {
678 $subsystem = substr($subsystem, 0, 17);
679 $subsystem =~ s/\s*$//;
680 $subsystem = $subsystem . "...";
681 }
682
683 if ($subsystem eq "THE REST") {
684 $subsystem = "";
685 }
686
687 return $subsystem;
688}
689
550sub add_categories { 690sub add_categories {
551 my ($index) = @_; 691 my ($index) = @_;
552 692
@@ -564,17 +704,22 @@ sub add_categories {
564 if ($ptype eq "L") { 704 if ($ptype eq "L") {
565 my $list_address = $pvalue; 705 my $list_address = $pvalue;
566 my $list_additional = ""; 706 my $list_additional = "";
707 my $list_role = get_list_role($i);
708
709 if ($list_role ne "") {
710 $list_role = ":" . $list_role;
711 }
567 if ($list_address =~ m/([^\s]+)\s+(.*)$/) { 712 if ($list_address =~ m/([^\s]+)\s+(.*)$/) {
568 $list_address = $1; 713 $list_address = $1;
569 $list_additional = $2; 714 $list_additional = $2;
570 } 715 }
571 if ($list_additional =~ m/subscribers-only/) { 716 if ($list_additional =~ m/subscribers-only/) {
572 if ($email_subscriber_list) { 717 if ($email_subscriber_list) {
573 push(@list_to, $list_address); 718 push(@list_to, [$list_address, "subscriber list${list_role}"]);
574 } 719 }
575 } else { 720 } else {
576 if ($email_list) { 721 if ($email_list) {
577 push(@list_to, $list_address); 722 push(@list_to, [$list_address, "open list${list_role}"]);
578 } 723 }
579 } 724 }
580 } elsif ($ptype eq "M") { 725 } elsif ($ptype eq "M") {
@@ -585,13 +730,14 @@ sub add_categories {
585 if ($tv =~ m/^(\C):\s*(.*)/) { 730 if ($tv =~ m/^(\C):\s*(.*)/) {
586 if ($1 eq "P") { 731 if ($1 eq "P") {
587 $name = $2; 732 $name = $2;
588 $pvalue = format_email($name, $address); 733 $pvalue = format_email($name, $address, $email_usename);
589 } 734 }
590 } 735 }
591 } 736 }
592 } 737 }
593 if ($email_maintainer) { 738 if ($email_maintainer) {
594 push_email_addresses($pvalue); 739 my $role = get_maintainer_role($i);
740 push_email_addresses($pvalue, $role);
595 } 741 }
596 } elsif ($ptype eq "T") { 742 } elsif ($ptype eq "T") {
597 push(@scm, $pvalue); 743 push(@scm, $pvalue);
@@ -618,7 +764,7 @@ sub email_inuse {
618} 764}
619 765
620sub push_email_address { 766sub push_email_address {
621 my ($line) = @_; 767 my ($line, $role) = @_;
622 768
623 my ($name, $address) = parse_email($line); 769 my ($name, $address) = parse_email($line);
624 770
@@ -627,9 +773,9 @@ sub push_email_address {
627 } 773 }
628 774
629 if (!$email_remove_duplicates) { 775 if (!$email_remove_duplicates) {
630 push(@email_to, format_email($name, $address)); 776 push(@email_to, [format_email($name, $address, $email_usename), $role]);
631 } elsif (!email_inuse($name, $address)) { 777 } elsif (!email_inuse($name, $address)) {
632 push(@email_to, format_email($name, $address)); 778 push(@email_to, [format_email($name, $address, $email_usename), $role]);
633 $email_hash_name{$name}++; 779 $email_hash_name{$name}++;
634 $email_hash_address{$address}++; 780 $email_hash_address{$address}++;
635 } 781 }
@@ -638,24 +784,52 @@ sub push_email_address {
638} 784}
639 785
640sub push_email_addresses { 786sub push_email_addresses {
641 my ($address) = @_; 787 my ($address, $role) = @_;
642 788
643 my @address_list = (); 789 my @address_list = ();
644 790
645 if (rfc822_valid($address)) { 791 if (rfc822_valid($address)) {
646 push_email_address($address); 792 push_email_address($address, $role);
647 } elsif (@address_list = rfc822_validlist($address)) { 793 } elsif (@address_list = rfc822_validlist($address)) {
648 my $array_count = shift(@address_list); 794 my $array_count = shift(@address_list);
649 while (my $entry = shift(@address_list)) { 795 while (my $entry = shift(@address_list)) {
650 push_email_address($entry); 796 push_email_address($entry, $role);
651 } 797 }
652 } else { 798 } else {
653 if (!push_email_address($address)) { 799 if (!push_email_address($address, $role)) {
654 warn("Invalid MAINTAINERS address: '" . $address . "'\n"); 800 warn("Invalid MAINTAINERS address: '" . $address . "'\n");
655 } 801 }
656 } 802 }
657} 803}
658 804
805sub add_role {
806 my ($line, $role) = @_;
807
808 my ($name, $address) = parse_email($line);
809 my $email = format_email($name, $address, $email_usename);
810
811 foreach my $entry (@email_to) {
812 if ($email_remove_duplicates) {
813 my ($entry_name, $entry_address) = parse_email($entry->[0]);
814 if ($name eq $entry_name || $address eq $entry_address) {
815 if ($entry->[1] eq "") {
816 $entry->[1] = "$role";
817 } else {
818 $entry->[1] = "$entry->[1],$role";
819 }
820 }
821 } else {
822 if ($email eq $entry->[0]) {
823 if ($entry->[1] eq "") {
824 $entry->[1] = "$role";
825 } else {
826 $entry->[1] = "$entry->[1],$role";
827 }
828 }
829 }
830 }
831}
832
659sub which { 833sub which {
660 my ($bin) = @_; 834 my ($bin) = @_;
661 835
@@ -669,7 +843,7 @@ sub which {
669} 843}
670 844
671sub mailmap { 845sub mailmap {
672 my @lines = @_; 846 my (@lines) = @_;
673 my %hash; 847 my %hash;
674 848
675 foreach my $line (@lines) { 849 foreach my $line (@lines) {
@@ -678,14 +852,14 @@ sub mailmap {
678 $hash{$name} = $address; 852 $hash{$name} = $address;
679 } elsif ($address ne $hash{$name}) { 853 } elsif ($address ne $hash{$name}) {
680 $address = $hash{$name}; 854 $address = $hash{$name};
681 $line = format_email($name, $address); 855 $line = format_email($name, $address, $email_usename);
682 } 856 }
683 if (exists($mailmap{$name})) { 857 if (exists($mailmap{$name})) {
684 my $obj = $mailmap{$name}; 858 my $obj = $mailmap{$name};
685 foreach my $map_address (@$obj) { 859 foreach my $map_address (@$obj) {
686 if (($map_address eq $address) && 860 if (($map_address eq $address) &&
687 ($map_address ne $hash{$name})) { 861 ($map_address ne $hash{$name})) {
688 $line = format_email($name, $hash{$name}); 862 $line = format_email($name, $hash{$name}, $email_usename);
689 } 863 }
690 } 864 }
691 } 865 }
@@ -694,34 +868,38 @@ sub mailmap {
694 return @lines; 868 return @lines;
695} 869}
696 870
697sub recent_git_signoffs { 871sub git_execute_cmd {
698 my ($file) = @_; 872 my ($cmd) = @_;
699
700 my $sign_offs = "";
701 my $cmd = "";
702 my $output = "";
703 my $count = 0;
704 my @lines = (); 873 my @lines = ();
705 my %hash;
706 my $total_sign_offs;
707 874
708 if (which("git") eq "") { 875 my $output = `$cmd`;
709 warn("$P: git not found. Add --nogit to options?\n"); 876 $output =~ s/^\s*//gm;
710 return; 877 @lines = split("\n", $output);
711 }
712 if (!(-d ".git")) {
713 warn("$P: .git directory not found. Use a git repository for better results.\n");
714 warn("$P: perhaps 'git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git'\n");
715 return;
716 }
717 878
718 $cmd = "git log --since=${email_git_since} -- ${file}"; 879 return @lines;
880}
719 881
720 $output = `${cmd}`; 882sub hg_execute_cmd {
721 $output =~ s/^\s*//gm; 883 my ($cmd) = @_;
884 my @lines = ();
722 885
886 my $output = `$cmd`;
723 @lines = split("\n", $output); 887 @lines = split("\n", $output);
724 888
889 return @lines;
890}
891
892sub vcs_find_signers {
893 my ($cmd) = @_;
894 my @lines = ();
895 my $commits;
896
897 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
898
899 my $pattern = $VCS_cmds{"commit_pattern"};
900
901 $commits = grep(/$pattern/, @lines); # of commits
902
725 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); 903 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines);
726 if (!$email_git_penguin_chiefs) { 904 if (!$email_git_penguin_chiefs) {
727 @lines = grep(!/${penguin_chiefs}/i, @lines); 905 @lines = grep(!/${penguin_chiefs}/i, @lines);
@@ -729,111 +907,183 @@ sub recent_git_signoffs {
729 # cut -f2- -d":" 907 # cut -f2- -d":"
730 s/.*:\s*(.+)\s*/$1/ for (@lines); 908 s/.*:\s*(.+)\s*/$1/ for (@lines);
731 909
732 $total_sign_offs = @lines; 910## Reformat email addresses (with names) to avoid badly written signatures
733 911
734 if ($email_remove_duplicates) { 912 foreach my $line (@lines) {
735 @lines = mailmap(@lines); 913 my ($name, $address) = parse_email($line);
914 $line = format_email($name, $address, 1);
736 } 915 }
737 916
738 @lines = sort(@lines); 917 return ($commits, @lines);
739
740 # uniq -c
741 $hash{$_}++ for @lines;
742
743 # sort -rn
744 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
745 my $sign_offs = $hash{$line};
746 $count++;
747 last if ($sign_offs < $email_git_min_signatures ||
748 $count > $email_git_max_maintainers ||
749 $sign_offs * 100 / $total_sign_offs < $email_git_min_percent);
750 push_email_address($line);
751 }
752} 918}
753 919
754sub save_commits { 920sub vcs_save_commits {
755 my ($cmd, @commits) = @_; 921 my ($cmd) = @_;
756 my $output;
757 my @lines = (); 922 my @lines = ();
923 my @commits = ();
758 924
759 $output = `${cmd}`; 925 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
760 926
761 @lines = split("\n", $output);
762 foreach my $line (@lines) { 927 foreach my $line (@lines) {
763 if ($line =~ m/^(\w+) /) { 928 if ($line =~ m/$VCS_cmds{"blame_commit_pattern"}/) {
764 push (@commits, $1); 929 push(@commits, $1);
765 } 930 }
766 } 931 }
932
767 return @commits; 933 return @commits;
768} 934}
769 935
770sub git_assign_blame { 936sub vcs_blame {
771 my ($file) = @_; 937 my ($file) = @_;
772
773 my @lines = ();
774 my @commits = ();
775 my $cmd; 938 my $cmd;
776 my $output; 939 my @commits = ();
777 my %hash; 940
778 my $total_sign_offs; 941 return @commits if (!(-f $file));
779 my $count; 942
943 if (@range && $VCS_cmds{"blame_range_cmd"} eq "") {
944 my @all_commits = ();
945
946 $cmd = $VCS_cmds{"blame_file_cmd"};
947 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
948 @all_commits = vcs_save_commits($cmd);
780 949
781 if (@range) {
782 foreach my $file_range_diff (@range) { 950 foreach my $file_range_diff (@range) {
783 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/)); 951 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
784 my $diff_file = $1; 952 my $diff_file = $1;
785 my $diff_start = $2; 953 my $diff_start = $2;
786 my $diff_length = $3; 954 my $diff_length = $3;
787 next if (!("$file" eq "$diff_file")); 955 next if ("$file" ne "$diff_file");
788 $cmd = "git blame -l -L $diff_start,+$diff_length $file"; 956 for (my $i = $diff_start; $i < $diff_start + $diff_length; $i++) {
789 @commits = save_commits($cmd, @commits); 957 push(@commits, $all_commits[$i]);
958 }
790 } 959 }
791 } else { 960 } elsif (@range) {
792 if (-f $file) { 961 foreach my $file_range_diff (@range) {
793 $cmd = "git blame -l $file"; 962 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
794 @commits = save_commits($cmd, @commits); 963 my $diff_file = $1;
964 my $diff_start = $2;
965 my $diff_length = $3;
966 next if ("$file" ne "$diff_file");
967 $cmd = $VCS_cmds{"blame_range_cmd"};
968 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
969 push(@commits, vcs_save_commits($cmd));
795 } 970 }
971 } else {
972 $cmd = $VCS_cmds{"blame_file_cmd"};
973 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
974 @commits = vcs_save_commits($cmd);
796 } 975 }
797 976
798 $total_sign_offs = 0; 977 return @commits;
799 @commits = uniq(@commits); 978}
800 foreach my $commit (@commits) {
801 $cmd = "git log -1 ${commit}";
802 979
803 $output = `${cmd}`; 980my $printed_novcs = 0;
804 $output =~ s/^\s*//gm; 981sub vcs_exists {
805 @lines = split("\n", $output); 982 %VCS_cmds = %VCS_cmds_git;
983 return 1 if eval $VCS_cmds{"available"};
984 %VCS_cmds = %VCS_cmds_hg;
985 return 1 if eval $VCS_cmds{"available"};
986 %VCS_cmds = ();
987 if (!$printed_novcs) {
988 warn("$P: No supported VCS found. Add --nogit to options?\n");
989 warn("Using a git repository produces better results.\n");
990 warn("Try Linus Torvalds' latest git repository using:\n");
991 warn("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git\n");
992 $printed_novcs = 1;
993 }
994 return 0;
995}
806 996
807 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); 997sub vcs_assign {
808 if (!$email_git_penguin_chiefs) { 998 my ($role, $divisor, @lines) = @_;
809 @lines = grep(!/${penguin_chiefs}/i, @lines);
810 }
811 999
812 # cut -f2- -d":" 1000 my %hash;
813 s/.*:\s*(.+)\s*/$1/ for (@lines); 1001 my $count = 0;
814 1002
815 $total_sign_offs += @lines; 1003 return if (@lines <= 0);
816 1004
817 if ($email_remove_duplicates) { 1005 if ($divisor <= 0) {
818 @lines = mailmap(@lines); 1006 warn("Bad divisor in " . (caller(0))[3] . ": $divisor\n");
819 } 1007 $divisor = 1;
1008 }
820 1009
821 $hash{$_}++ for @lines; 1010 if ($email_remove_duplicates) {
1011 @lines = mailmap(@lines);
822 } 1012 }
823 1013
824 $count = 0; 1014 @lines = sort(@lines);
1015
1016 # uniq -c
1017 $hash{$_}++ for @lines;
1018
1019 # sort -rn
825 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { 1020 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
826 my $sign_offs = $hash{$line}; 1021 my $sign_offs = $hash{$line};
1022 my $percent = $sign_offs * 100 / $divisor;
1023
1024 $percent = 100 if ($percent > 100);
827 $count++; 1025 $count++;
828 last if ($sign_offs < $email_git_min_signatures || 1026 last if ($sign_offs < $email_git_min_signatures ||
829 $count > $email_git_max_maintainers || 1027 $count > $email_git_max_maintainers ||
830 $sign_offs * 100 / $total_sign_offs < $email_git_min_percent); 1028 $percent < $email_git_min_percent);
831 push_email_address($line); 1029 push_email_address($line, '');
1030 if ($output_rolestats) {
1031 my $fmt_percent = sprintf("%.0f", $percent);
1032 add_role($line, "$role:$sign_offs/$divisor=$fmt_percent%");
1033 } else {
1034 add_role($line, $role);
1035 }
1036 }
1037}
1038
1039sub vcs_file_signoffs {
1040 my ($file) = @_;
1041
1042 my @signers = ();
1043 my $commits;
1044
1045 return if (!vcs_exists());
1046
1047 my $cmd = $VCS_cmds{"find_signers_cmd"};
1048 $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
1049
1050 ($commits, @signers) = vcs_find_signers($cmd);
1051 vcs_assign("commit_signer", $commits, @signers);
1052}
1053
1054sub vcs_file_blame {
1055 my ($file) = @_;
1056
1057 my @signers = ();
1058 my @commits = ();
1059 my $total_commits;
1060
1061 return if (!vcs_exists());
1062
1063 @commits = vcs_blame($file);
1064 @commits = uniq(@commits);
1065 $total_commits = @commits;
1066
1067 foreach my $commit (@commits) {
1068 my $commit_count;
1069 my @commit_signers = ();
1070
1071 my $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1072 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1073
1074 ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1075 push(@signers, @commit_signers);
1076 }
1077
1078 if ($from_filename) {
1079 vcs_assign("commits", $total_commits, @signers);
1080 } else {
1081 vcs_assign("modified commits", $total_commits, @signers);
832 } 1082 }
833} 1083}
834 1084
835sub uniq { 1085sub uniq {
836 my @parms = @_; 1086 my (@parms) = @_;
837 1087
838 my %saw; 1088 my %saw;
839 @parms = grep(!$saw{$_}++, @parms); 1089 @parms = grep(!$saw{$_}++, @parms);
@@ -841,7 +1091,7 @@ sub uniq {
841} 1091}
842 1092
843sub sort_and_uniq { 1093sub sort_and_uniq {
844 my @parms = @_; 1094 my (@parms) = @_;
845 1095
846 my %saw; 1096 my %saw;
847 @parms = sort @parms; 1097 @parms = sort @parms;
@@ -849,8 +1099,27 @@ sub sort_and_uniq {
849 return @parms; 1099 return @parms;
850} 1100}
851 1101
1102sub merge_email {
1103 my @lines;
1104 my %saw;
1105
1106 for (@_) {
1107 my ($address, $role) = @$_;
1108 if (!$saw{$address}) {
1109 if ($output_roles) {
1110 push(@lines, "$address ($role)");
1111 } else {
1112 push(@lines, $address);
1113 }
1114 $saw{$address} = 1;
1115 }
1116 }
1117
1118 return @lines;
1119}
1120
852sub output { 1121sub output {
853 my @parms = @_; 1122 my (@parms) = @_;
854 1123
855 if ($output_multiline) { 1124 if ($output_multiline) {
856 foreach my $line (@parms) { 1125 foreach my $line (@parms) {
@@ -947,11 +1216,9 @@ sub rfc822_validlist ($) {
947 if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so && 1216 if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so &&
948 $s =~ m/^$rfc822_char*$/) { 1217 $s =~ m/^$rfc822_char*$/) {
949 while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) { 1218 while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) {
950 push @r, $1; 1219 push(@r, $1);
951 } 1220 }
952 return wantarray ? (scalar(@r), @r) : 1; 1221 return wantarray ? (scalar(@r), @r) : 1;
953 } 1222 }
954 else { 1223 return wantarray ? () : 0;
955 return wantarray ? () : 0;
956 }
957} 1224}
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()
8{ 8{
9 if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then 9 if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then
10 make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 10 make ARCH=$2 KBUILD_HEADERS=$1 headers_$1
11 elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then
12 make ARCH=$2 KBUILD_HEADERS=$1 headers_$1
13 else 11 else
14 printf "Ignoring arch: %s\n" ${arch} 12 printf "Ignoring arch: %s\n" ${arch}
15 fi 13 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
27 $< -o $(Kconfig) 27 $< -o $(Kconfig)
28 28
29silentoldconfig: $(obj)/conf 29silentoldconfig: $(obj)/conf
30 $(Q)mkdir -p include/generated
30 $< -s $(Kconfig) 31 $< -s $(Kconfig)
31 32
32localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 33localmodconfig: $(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)
677 struct symbol *sym; 677 struct symbol *sym;
678 const char *str; 678 const char *str;
679 const char *name; 679 const char *name;
680 FILE *out, *out_h; 680 FILE *out, *tristate, *out_h;
681 time_t now; 681 time_t now;
682 int i, l; 682 int i, l;
683 683
@@ -692,9 +692,16 @@ int conf_write_autoconf(void)
692 if (!out) 692 if (!out)
693 return 1; 693 return 1;
694 694
695 tristate = fopen(".tmpconfig_tristate", "w");
696 if (!tristate) {
697 fclose(out);
698 return 1;
699 }
700
695 out_h = fopen(".tmpconfig.h", "w"); 701 out_h = fopen(".tmpconfig.h", "w");
696 if (!out_h) { 702 if (!out_h) {
697 fclose(out); 703 fclose(out);
704 fclose(tristate);
698 return 1; 705 return 1;
699 } 706 }
700 707
@@ -707,6 +714,9 @@ int conf_write_autoconf(void)
707 "# %s" 714 "# %s"
708 "#\n", 715 "#\n",
709 sym_get_string_value(sym), ctime(&now)); 716 sym_get_string_value(sym), ctime(&now));
717 fprintf(tristate, "#\n"
718 "# Automatically generated - do not edit\n"
719 "\n");
710 fprintf(out_h, "/*\n" 720 fprintf(out_h, "/*\n"
711 " * Automatically generated C config: don't edit\n" 721 " * Automatically generated C config: don't edit\n"
712 " * Linux kernel version: %s\n" 722 " * Linux kernel version: %s\n"
@@ -727,10 +737,14 @@ int conf_write_autoconf(void)
727 break; 737 break;
728 case mod: 738 case mod:
729 fprintf(out, "CONFIG_%s=m\n", sym->name); 739 fprintf(out, "CONFIG_%s=m\n", sym->name);
740 fprintf(tristate, "CONFIG_%s=M\n", sym->name);
730 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 741 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
731 break; 742 break;
732 case yes: 743 case yes:
733 fprintf(out, "CONFIG_%s=y\n", sym->name); 744 fprintf(out, "CONFIG_%s=y\n", sym->name);
745 if (sym->type == S_TRISTATE)
746 fprintf(tristate, "CONFIG_%s=Y\n",
747 sym->name);
734 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 748 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
735 break; 749 break;
736 } 750 }
@@ -772,13 +786,19 @@ int conf_write_autoconf(void)
772 } 786 }
773 } 787 }
774 fclose(out); 788 fclose(out);
789 fclose(tristate);
775 fclose(out_h); 790 fclose(out_h);
776 791
777 name = getenv("KCONFIG_AUTOHEADER"); 792 name = getenv("KCONFIG_AUTOHEADER");
778 if (!name) 793 if (!name)
779 name = "include/linux/autoconf.h"; 794 name = "include/generated/autoconf.h";
780 if (rename(".tmpconfig.h", name)) 795 if (rename(".tmpconfig.h", name))
781 return 1; 796 return 1;
797 name = getenv("KCONFIG_TRISTATE");
798 if (!name)
799 name = "include/config/tristate.conf";
800 if (rename(".tmpconfig_tristate", name))
801 return 1;
782 name = conf_get_autoconfig_name(); 802 name = conf_get_autoconfig_name();
783 /* 803 /*
784 * This must be the last step, kbuild has a dependency on auto.conf 804 * This must be the last step, kbuild has a dependency on auto.conf
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index 5f0fcb712e29..ce3e40b01e48 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -154,7 +154,7 @@ while (<STDIN>) {
154 if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) { 154 if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) {
155 $target = $1; 155 $target = $1;
156 } 156 }
157 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { 157 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+0x([0-9a-f]+)\/0x[a-f0-9]/) {
158 $function = $1; 158 $function = $1;
159 $func_offset = $2; 159 $func_offset = $2;
160 } 160 }
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 "$@" ; }
14# So "sudo make install" won't change the "compiled by <user>" 14# So "sudo make install" won't change the "compiled by <user>"
15# do "compiled by root" 15# do "compiled by root"
16 16
17if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then 17if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then
18 vecho " SKIPPED $TARGET" 18 vecho " SKIPPED $TARGET"
19 exit 0 19 exit 0
20fi 20fi
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
index 11d69c35e5b4..ff954f8168c1 100644
--- a/scripts/mod/Makefile
+++ b/scripts/mod/Makefile
@@ -8,7 +8,7 @@ modpost-objs := modpost.o file2alias.o sumversion.o
8$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h 8$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h
9 9
10quiet_cmd_elfconfig = MKELF $@ 10quiet_cmd_elfconfig = MKELF $@
11 cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ 11 cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
12 12
13$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE 13$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
14 $(call if_changed,elfconfig) 14 $(call if_changed,elfconfig)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 6f426afbc522..220213e603db 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -804,7 +804,7 @@ static inline int sym_is(const char *symbol, const char *name)
804 match = strstr(symbol, name); 804 match = strstr(symbol, name);
805 if (!match) 805 if (!match)
806 return 0; 806 return 0;
807 return match[strlen(symbol)] == '\0'; 807 return match[strlen(name)] == '\0';
808} 808}
809 809
810static void do_table(void *symval, unsigned long size, 810static void do_table(void *symval, unsigned long size,
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
index 6a96d47bd1e6..639bca7ba559 100644
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -9,9 +9,6 @@ main(int argc, char **argv)
9 unsigned char ei[EI_NIDENT]; 9 unsigned char ei[EI_NIDENT];
10 union { short s; char c[2]; } endian_test; 10 union { short s; char c[2]; } endian_test;
11 11
12 if (argc != 2) {
13 fprintf(stderr, "Error: no arch\n");
14 }
15 if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) { 12 if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
16 fprintf(stderr, "Error: input truncated\n"); 13 fprintf(stderr, "Error: input truncated\n");
17 return 1; 14 return 1;
@@ -55,12 +52,6 @@ main(int argc, char **argv)
55 else 52 else
56 exit(1); 53 exit(1);
57 54
58 if ((strcmp(argv[1], "h8300") == 0)
59 || (strcmp(argv[1], "blackfin") == 0))
60 printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
61 else
62 printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
63
64 return 0; 55 return 0;
65} 56}
66 57
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 801a16a17545..20923613467c 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -15,8 +15,17 @@
15#include <stdio.h> 15#include <stdio.h>
16#include <ctype.h> 16#include <ctype.h>
17#include "modpost.h" 17#include "modpost.h"
18#include "../../include/generated/autoconf.h"
18#include "../../include/linux/license.h" 19#include "../../include/linux/license.h"
19 20
21/* Some toolchains use a `_' prefix for all user symbols. */
22#ifdef CONFIG_SYMBOL_PREFIX
23#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
24#else
25#define MODULE_SYMBOL_PREFIX ""
26#endif
27
28
20/* Are we using CONFIG_MODVERSIONS? */ 29/* Are we using CONFIG_MODVERSIONS? */
21int modversions = 0; 30int modversions = 0;
22/* Warn about undefined symbols? (do so if we have vmlinux) */ 31/* Warn about undefined symbols? (do so if we have vmlinux) */
@@ -451,8 +460,6 @@ static int parse_elf(struct elf_info *info, const char *filename)
451 info->export_unused_gpl_sec = i; 460 info->export_unused_gpl_sec = i;
452 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 461 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
453 info->export_gpl_future_sec = i; 462 info->export_gpl_future_sec = i;
454 else if (strcmp(secname, "__markers_strings") == 0)
455 info->markers_strings_sec = i;
456 463
457 if (sechdrs[i].sh_type != SHT_SYMTAB) 464 if (sechdrs[i].sh_type != SHT_SYMTAB)
458 continue; 465 continue;
@@ -515,7 +522,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
515 break; 522 break;
516 case SHN_ABS: 523 case SHN_ABS:
517 /* CRC'd symbol */ 524 /* CRC'd symbol */
518 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 525 if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
519 crc = (unsigned int) sym->st_value; 526 crc = (unsigned int) sym->st_value;
520 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 527 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
521 export); 528 export);
@@ -559,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
559 break; 566 break;
560 default: 567 default:
561 /* All exported symbols */ 568 /* All exported symbols */
562 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 569 if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
563 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, 570 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
564 export); 571 export);
565 } 572 }
@@ -1509,62 +1516,6 @@ static void check_sec_ref(struct module *mod, const char *modname,
1509 } 1516 }
1510} 1517}
1511 1518
1512static void get_markers(struct elf_info *info, struct module *mod)
1513{
1514 const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec];
1515 const char *strings = (const char *) info->hdr + sh->sh_offset;
1516 const Elf_Sym *sym, *first_sym, *last_sym;
1517 size_t n;
1518
1519 if (!info->markers_strings_sec)
1520 return;
1521
1522 /*
1523 * First count the strings. We look for all the symbols defined
1524 * in the __markers_strings section named __mstrtab_*. For
1525 * these local names, the compiler puts a random .NNN suffix on,
1526 * so the names don't correspond exactly.
1527 */
1528 first_sym = last_sym = NULL;
1529 n = 0;
1530 for (sym = info->symtab_start; sym < info->symtab_stop; sym++)
1531 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1532 sym->st_shndx == info->markers_strings_sec &&
1533 !strncmp(info->strtab + sym->st_name,
1534 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1535 if (first_sym == NULL)
1536 first_sym = sym;
1537 last_sym = sym;
1538 ++n;
1539 }
1540
1541 if (n == 0)
1542 return;
1543
1544 /*
1545 * Now collect each name and format into a line for the output.
1546 * Lines look like:
1547 * marker_name vmlinux marker %s format %d
1548 * The format string after the second \t can use whitespace.
1549 */
1550 mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n));
1551 mod->nmarkers = n;
1552
1553 n = 0;
1554 for (sym = first_sym; sym <= last_sym; sym++)
1555 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1556 sym->st_shndx == info->markers_strings_sec &&
1557 !strncmp(info->strtab + sym->st_name,
1558 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1559 const char *name = strings + sym->st_value;
1560 const char *fmt = strchr(name, '\0') + 1;
1561 char *line = NULL;
1562 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1563 NOFAIL(line);
1564 mod->markers[n++] = line;
1565 }
1566}
1567
1568static void read_symbols(char *modname) 1519static void read_symbols(char *modname)
1569{ 1520{
1570 const char *symname; 1521 const char *symname;
@@ -1620,8 +1571,6 @@ static void read_symbols(char *modname)
1620 get_src_version(modname, mod->srcversion, 1571 get_src_version(modname, mod->srcversion,
1621 sizeof(mod->srcversion)-1); 1572 sizeof(mod->srcversion)-1);
1622 1573
1623 get_markers(&info, mod);
1624
1625 parse_elf_finish(&info); 1574 parse_elf_finish(&info);
1626 1575
1627 /* Our trick to get versioning for module struct etc. - it's 1576 /* Our trick to get versioning for module struct etc. - it's
@@ -1976,96 +1925,6 @@ static void write_dump(const char *fname)
1976 write_if_changed(&buf, fname); 1925 write_if_changed(&buf, fname);
1977} 1926}
1978 1927
1979static void add_marker(struct module *mod, const char *name, const char *fmt)
1980{
1981 char *line = NULL;
1982 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1983 NOFAIL(line);
1984
1985 mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) *
1986 sizeof mod->markers[0])));
1987 mod->markers[mod->nmarkers++] = line;
1988}
1989
1990static void read_markers(const char *fname)
1991{
1992 unsigned long size, pos = 0;
1993 void *file = grab_file(fname, &size);
1994 char *line;
1995
1996 if (!file) /* No old markers, silently ignore */
1997 return;
1998
1999 while ((line = get_next_line(&pos, file, size))) {
2000 char *marker, *modname, *fmt;
2001 struct module *mod;
2002
2003 marker = line;
2004 modname = strchr(marker, '\t');
2005 if (!modname)
2006 goto fail;
2007 *modname++ = '\0';
2008 fmt = strchr(modname, '\t');
2009 if (!fmt)
2010 goto fail;
2011 *fmt++ = '\0';
2012 if (*marker == '\0' || *modname == '\0')
2013 goto fail;
2014
2015 mod = find_module(modname);
2016 if (!mod) {
2017 mod = new_module(modname);
2018 mod->skip = 1;
2019 }
2020 if (is_vmlinux(modname)) {
2021 have_vmlinux = 1;
2022 mod->skip = 0;
2023 }
2024
2025 if (!mod->skip)
2026 add_marker(mod, marker, fmt);
2027 }
2028 release_file(file, size);
2029 return;
2030fail:
2031 fatal("parse error in markers list file\n");
2032}
2033
2034static int compare_strings(const void *a, const void *b)
2035{
2036 return strcmp(*(const char **) a, *(const char **) b);
2037}
2038
2039static void write_markers(const char *fname)
2040{
2041 struct buffer buf = { };
2042 struct module *mod;
2043 size_t i;
2044
2045 for (mod = modules; mod; mod = mod->next)
2046 if ((!external_module || !mod->skip) && mod->markers != NULL) {
2047 /*
2048 * Sort the strings so we can skip duplicates when
2049 * we write them out.
2050 */
2051 qsort(mod->markers, mod->nmarkers,
2052 sizeof mod->markers[0], &compare_strings);
2053 for (i = 0; i < mod->nmarkers; ++i) {
2054 char *line = mod->markers[i];
2055 buf_write(&buf, line, strlen(line));
2056 while (i + 1 < mod->nmarkers &&
2057 !strcmp(mod->markers[i],
2058 mod->markers[i + 1]))
2059 free(mod->markers[i++]);
2060 free(mod->markers[i]);
2061 }
2062 free(mod->markers);
2063 mod->markers = NULL;
2064 }
2065
2066 write_if_changed(&buf, fname);
2067}
2068
2069struct ext_sym_list { 1928struct ext_sym_list {
2070 struct ext_sym_list *next; 1929 struct ext_sym_list *next;
2071 const char *file; 1930 const char *file;
@@ -2077,8 +1936,6 @@ int main(int argc, char **argv)
2077 struct buffer buf = { }; 1936 struct buffer buf = { };
2078 char *kernel_read = NULL, *module_read = NULL; 1937 char *kernel_read = NULL, *module_read = NULL;
2079 char *dump_write = NULL; 1938 char *dump_write = NULL;
2080 char *markers_read = NULL;
2081 char *markers_write = NULL;
2082 int opt; 1939 int opt;
2083 int err; 1940 int err;
2084 struct ext_sym_list *extsym_iter; 1941 struct ext_sym_list *extsym_iter;
@@ -2122,12 +1979,6 @@ int main(int argc, char **argv)
2122 case 'w': 1979 case 'w':
2123 warn_unresolved = 1; 1980 warn_unresolved = 1;
2124 break; 1981 break;
2125 case 'M':
2126 markers_write = optarg;
2127 break;
2128 case 'K':
2129 markers_read = optarg;
2130 break;
2131 default: 1982 default:
2132 exit(1); 1983 exit(1);
2133 } 1984 }
@@ -2182,11 +2033,5 @@ int main(int argc, char **argv)
2182 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", 2033 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
2183 sec_mismatch_count); 2034 sec_mismatch_count);
2184 2035
2185 if (markers_read)
2186 read_markers(markers_read);
2187
2188 if (markers_write)
2189 write_markers(markers_write);
2190
2191 return err; 2036 return err;
2192} 2037}
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 09f58e33d227..be987a44f250 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -112,8 +112,6 @@ struct module {
112 int has_init; 112 int has_init;
113 int has_cleanup; 113 int has_cleanup;
114 struct buffer dev_table_buf; 114 struct buffer dev_table_buf;
115 char **markers;
116 size_t nmarkers;
117 char srcversion[25]; 115 char srcversion[25];
118}; 116};
119 117
@@ -128,7 +126,6 @@ struct elf_info {
128 Elf_Section export_gpl_sec; 126 Elf_Section export_gpl_sec;
129 Elf_Section export_unused_gpl_sec; 127 Elf_Section export_unused_gpl_sec;
130 Elf_Section export_gpl_future_sec; 128 Elf_Section export_gpl_future_sec;
131 Elf_Section markers_strings_sec;
132 const char *strtab; 129 const char *strtab;
133 char *modinfo; 130 char *modinfo;
134 unsigned int modinfo_len; 131 unsigned int modinfo_len;
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
77 77
78# Deb target 78# Deb target
79# --------------------------------------------------------------------------- 79# ---------------------------------------------------------------------------
80quiet_cmd_builddeb = BUILDDEB
81 cmd_builddeb = set -e; \
82 test `id -u` = 0 || \
83 test -n "$(KBUILD_PKG_ROOTCMD)" || { \
84 which fakeroot >/dev/null 2>&1 && \
85 KBUILD_PKG_ROOTCMD="fakeroot -u"; \
86 } || { \
87 echo; \
88 echo "builddeb must be run as root (or using fakeroot)."; \
89 echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \
90 echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \
91 echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \
92 false; \
93 } && \
94 \
95 $$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \
96 $(srctree)/scripts/package/builddeb
97
80deb-pkg: FORCE 98deb-pkg: FORCE
81 $(MAKE) KBUILD_SRC= 99 $(MAKE) KBUILD_SRC=
82 $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb 100 $(call cmd,builddeb)
83 101
84clean-dirs += $(objtree)/debian/ 102clean-dirs += $(objtree)/debian/
85 103
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
101# 101#
102( 102(
103 cd "${tmpdir}" 103 cd "${tmpdir}"
104 tar cf - . | ${compress} > "${tarball}${file_ext}" 104 opts=
105 if tar --owner=root --group=root --help >/dev/null 2>&1; then
106 opts="--owner=root --group=root"
107 fi
108 tar cf - . $opts | ${compress} > "${tarball}${file_ext}"
105) 109)
106 110
107echo "Tarball successfully created in ${tarball}${file_ext}" 111echo "Tarball successfully created in ${tarball}${file_ext}"
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 9cf0a6fad6ba..ea6f6e3adaea 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -113,13 +113,13 @@ $P =~ s@.*/@@g;
113 113
114my $V = '0.1'; 114my $V = '0.1';
115 115
116if ($#ARGV != 10) { 116if ($#ARGV != 11) {
117 print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; 117 print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
118 print "version: $V\n"; 118 print "version: $V\n";
119 exit(1); 119 exit(1);
120} 120}
121 121
122my ($arch, $bits, $objdump, $objcopy, $cc, 122my ($arch, $endian, $bits, $objdump, $objcopy, $cc,
123 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; 123 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
124 124
125# This file refers to mcount and shouldn't be ftraced, so lets' ignore it 125# This file refers to mcount and shouldn't be ftraced, so lets' ignore it
@@ -194,7 +194,7 @@ sub check_objcopy
194 } 194 }
195} 195}
196 196
197if ($arch eq "x86") { 197if ($arch =~ /(x86(_64)?)|(i386)/) {
198 if ($bits == 64) { 198 if ($bits == 64) {
199 $arch = "x86_64"; 199 $arch = "x86_64";
200 } else { 200 } else {
@@ -295,6 +295,58 @@ if ($arch eq "x86_64") {
295 $ld .= " -m elf64_sparc"; 295 $ld .= " -m elf64_sparc";
296 $cc .= " -m64"; 296 $cc .= " -m64";
297 $objcopy .= " -O elf64-sparc"; 297 $objcopy .= " -O elf64-sparc";
298} elsif ($arch eq "mips") {
299 # To enable module support, we need to enable the -mlong-calls option
300 # of gcc for module, after using this option, we can not get the real
301 # offset of the calling to _mcount, but the offset of the lui
302 # instruction or the addiu one. herein, we record the address of the
303 # first one, and then we can replace this instruction by a branch
304 # instruction to jump over the profiling function to filter the
305 # indicated functions, or swith back to the lui instruction to trace
306 # them, which means dynamic tracing.
307 #
308 # c: 3c030000 lui v1,0x0
309 # c: R_MIPS_HI16 _mcount
310 # c: R_MIPS_NONE *ABS*
311 # c: R_MIPS_NONE *ABS*
312 # 10: 64630000 daddiu v1,v1,0
313 # 10: R_MIPS_LO16 _mcount
314 # 10: R_MIPS_NONE *ABS*
315 # 10: R_MIPS_NONE *ABS*
316 # 14: 03e0082d move at,ra
317 # 18: 0060f809 jalr v1
318 #
319 # for the kernel:
320 #
321 # 10: 03e0082d move at,ra
322 # 14: 0c000000 jal 0 <loongson_halt>
323 # 14: R_MIPS_26 _mcount
324 # 14: R_MIPS_NONE *ABS*
325 # 14: R_MIPS_NONE *ABS*
326 # 18: 00020021 nop
327 if ($is_module eq "0") {
328 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
329 } else {
330 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$";
331 }
332 $objdump .= " -Melf-trad".$endian."mips ";
333
334 if ($endian eq "big") {
335 $endian = " -EB ";
336 $ld .= " -melf".$bits."btsmip";
337 } else {
338 $endian = " -EL ";
339 $ld .= " -melf".$bits."ltsmip";
340 }
341
342 $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian;
343 $ld .= $endian;
344
345 if ($bits == 64) {
346 $function_regex =
347 "^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:";
348 $type = ".dword";
349 }
298} elsif ($arch eq "microblaze") { 350} elsif ($arch eq "microblaze") {
299 # Microblaze calls '_mcount' instead of plain 'mcount'. 351 # Microblaze calls '_mcount' instead of plain 'mcount'.
300 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; 352 $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()
89 89
90docscope() 90docscope()
91{ 91{
92 (echo \-k; echo \-q; all_sources) > cscope.files 92 # always use absolute paths for cscope, as recommended by cscope
93 # upstream
94 case "$tree" in
95 /*) ;;
96 *) tree=$PWD/$tree ;;
97 esac
98 (cd /; echo \-k; echo \-q; all_sources) > cscope.files
93 cscope -b -f cscope.out 99 cscope -b -f cscope.out
94} 100}
95 101
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 @@
1/* 1/*
2 * Copyright (c) 2002 - 2005 Tony Finch <dot@dotat.at>. All rights reserved. 2 * Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>
3 *
4 * This code is derived from software contributed to Berkeley by Dave Yost.
5 * It was rewritten to support ANSI C by Tony Finch. The original version of
6 * unifdef carried the following copyright notice. None of its code remains
7 * in this version (though some of the names remain).
8 *
9 * Copyright (c) 1985, 1993
10 * The Regents of the University of California. All rights reserved.
11 * 3 *
12 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -31,23 +23,20 @@
31 * SUCH DAMAGE. 23 * SUCH DAMAGE.
32 */ 24 */
33 25
34#include <sys/cdefs.h> 26/*
27 * This code was derived from software contributed to Berkeley by Dave Yost.
28 * It was rewritten to support ANSI C by Tony Finch. The original version
29 * of unifdef carried the 4-clause BSD copyright licence. None of its code
30 * remains in this version (though some of the names remain) so it now
31 * carries a more liberal licence.
32 *
33 * The latest version is available from http://dotat.at/prog/unifdef
34 */
35 35
36#ifndef lint 36static const char * const copyright[] = {
37#if 0 37 "@(#) Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>\n",
38static const char copyright[] = 38 "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $",
39"@(#) Copyright (c) 1985, 1993\n\ 39};
40 The Regents of the University of California. All rights reserved.\n";
41#endif
42#ifdef __IDSTRING
43__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93");
44__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $");
45__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $");
46#endif
47#endif /* not lint */
48#ifdef __FBSDID
49__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $");
50#endif
51 40
52/* 41/*
53 * unifdef - remove ifdef'ed lines 42 * 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
72#include <string.h> 61#include <string.h>
73#include <unistd.h> 62#include <unistd.h>
74 63
75size_t strlcpy(char *dst, const char *src, size_t siz);
76
77/* types of input lines: */ 64/* types of input lines: */
78typedef enum { 65typedef enum {
79 LT_TRUEI, /* a true #if with ignore flag */ 66 LT_TRUEI, /* a true #if with ignore flag */
@@ -90,6 +77,7 @@ typedef enum {
90 LT_DODGY_LAST = LT_DODGY + LT_ENDIF, 77 LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
91 LT_PLAIN, /* ordinary line */ 78 LT_PLAIN, /* ordinary line */
92 LT_EOF, /* end of file */ 79 LT_EOF, /* end of file */
80 LT_ERROR, /* unevaluable #if */
93 LT_COUNT 81 LT_COUNT
94} Linetype; 82} Linetype;
95 83
@@ -100,7 +88,7 @@ static char const * const linetype_name[] = {
100 "DODGY IF", "DODGY TRUE", "DODGY FALSE", 88 "DODGY IF", "DODGY TRUE", "DODGY FALSE",
101 "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE", 89 "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
102 "DODGY ELSE", "DODGY ENDIF", 90 "DODGY ELSE", "DODGY ENDIF",
103 "PLAIN", "EOF" 91 "PLAIN", "EOF", "ERROR"
104}; 92};
105 93
106/* state of #if processing */ 94/* state of #if processing */
@@ -168,11 +156,13 @@ static char const * const linestate_name[] = {
168 * Globals. 156 * Globals.
169 */ 157 */
170 158
159static bool compblank; /* -B: compress blank lines */
160static bool lnblank; /* -b: blank deleted lines */
171static bool complement; /* -c: do the complement */ 161static bool complement; /* -c: do the complement */
172static bool debugging; /* -d: debugging reports */ 162static bool debugging; /* -d: debugging reports */
173static bool iocccok; /* -e: fewer IOCCC errors */ 163static bool iocccok; /* -e: fewer IOCCC errors */
164static bool strictlogic; /* -K: keep ambiguous #ifs */
174static bool killconsts; /* -k: eval constant #ifs */ 165static bool killconsts; /* -k: eval constant #ifs */
175static bool lnblank; /* -l: blank deleted lines */
176static bool lnnum; /* -n: add #line directives */ 166static bool lnnum; /* -n: add #line directives */
177static bool symlist; /* -s: output symbol list */ 167static bool symlist; /* -s: output symbol list */
178static bool text; /* -t: this is a text file */ 168static bool text; /* -t: this is a text file */
@@ -196,7 +186,9 @@ static bool ignoring[MAXDEPTH]; /* ignore comments state */
196static int stifline[MAXDEPTH]; /* start of current #if */ 186static int stifline[MAXDEPTH]; /* start of current #if */
197static int depth; /* current #if nesting */ 187static int depth; /* current #if nesting */
198static int delcount; /* count of deleted lines */ 188static int delcount; /* count of deleted lines */
199static bool keepthis; /* don't delete constant #if */ 189static unsigned blankcount; /* count of blank lines */
190static unsigned blankmax; /* maximum recent blankcount */
191static bool constexpr; /* constant #if expression */
200 192
201static int exitstat; /* program exit status */ 193static int exitstat; /* program exit status */
202 194
@@ -206,13 +198,14 @@ static void done(void);
206static void error(const char *); 198static void error(const char *);
207static int findsym(const char *); 199static int findsym(const char *);
208static void flushline(bool); 200static void flushline(bool);
209static Linetype get_line(void); 201static Linetype parseline(void);
210static Linetype ifeval(const char **); 202static Linetype ifeval(const char **);
211static void ignoreoff(void); 203static void ignoreoff(void);
212static void ignoreon(void); 204static void ignoreon(void);
213static void keywordedit(const char *); 205static void keywordedit(const char *);
214static void nest(void); 206static void nest(void);
215static void process(void); 207static void process(void);
208static const char *skipargs(const char *);
216static const char *skipcomment(const char *); 209static const char *skipcomment(const char *);
217static const char *skipsym(const char *); 210static const char *skipsym(const char *);
218static void state(Ifstate); 211static void state(Ifstate);
@@ -220,7 +213,7 @@ static int strlcmp(const char *, const char *, size_t);
220static void unnest(void); 213static void unnest(void);
221static void usage(void); 214static void usage(void);
222 215
223#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') 216#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
224 217
225/* 218/*
226 * The main program. 219 * The main program.
@@ -230,7 +223,7 @@ main(int argc, char *argv[])
230{ 223{
231 int opt; 224 int opt;
232 225
233 while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) 226 while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1)
234 switch (opt) { 227 switch (opt) {
235 case 'i': /* treat stuff controlled by these symbols as text */ 228 case 'i': /* treat stuff controlled by these symbols as text */
236 /* 229 /*
@@ -255,6 +248,13 @@ main(int argc, char *argv[])
255 case 'I': 248 case 'I':
256 /* no-op for compatibility with cpp */ 249 /* no-op for compatibility with cpp */
257 break; 250 break;
251 case 'B': /* compress blank lines around removed section */
252 compblank = true;
253 break;
254 case 'b': /* blank deleted lines instead of omitting them */
255 case 'l': /* backwards compatibility */
256 lnblank = true;
257 break;
258 case 'c': /* treat -D as -U and vice versa */ 258 case 'c': /* treat -D as -U and vice versa */
259 complement = true; 259 complement = true;
260 break; 260 break;
@@ -264,12 +264,12 @@ main(int argc, char *argv[])
264 case 'e': /* fewer errors from dodgy lines */ 264 case 'e': /* fewer errors from dodgy lines */
265 iocccok = true; 265 iocccok = true;
266 break; 266 break;
267 case 'K': /* keep ambiguous #ifs */
268 strictlogic = true;
269 break;
267 case 'k': /* process constant #ifs */ 270 case 'k': /* process constant #ifs */
268 killconsts = true; 271 killconsts = true;
269 break; 272 break;
270 case 'l': /* blank deleted lines instead of omitting them */
271 lnblank = true;
272 break;
273 case 'n': /* add #line directive after deleted lines */ 273 case 'n': /* add #line directive after deleted lines */
274 lnnum = true; 274 lnnum = true;
275 break; 275 break;
@@ -284,6 +284,8 @@ main(int argc, char *argv[])
284 } 284 }
285 argc -= optind; 285 argc -= optind;
286 argv += optind; 286 argv += optind;
287 if (compblank && lnblank)
288 errx(2, "-B and -b are mutually exclusive");
287 if (argc > 1) { 289 if (argc > 1) {
288 errx(2, "can only do one file"); 290 errx(2, "can only do one file");
289 } else if (argc == 1 && strcmp(*argv, "-") != 0) { 291 } else if (argc == 1 && strcmp(*argv, "-") != 0) {
@@ -302,7 +304,7 @@ main(int argc, char *argv[])
302static void 304static void
303usage(void) 305usage(void)
304{ 306{
305 fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" 307 fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]"
306 " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); 308 " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
307 exit(2); 309 exit(2);
308} 310}
@@ -383,46 +385,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
383/* IS_OUTSIDE */ 385/* IS_OUTSIDE */
384{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif, 386{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
385 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif, 387 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif,
386 print, done }, 388 print, done, abort },
387/* IS_FALSE_PREFIX */ 389/* IS_FALSE_PREFIX */
388{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif, 390{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
389 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, 391 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
390 drop, Eeof }, 392 drop, Eeof, abort },
391/* IS_TRUE_PREFIX */ 393/* IS_TRUE_PREFIX */
392{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif, 394{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
393 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, 395 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
394 print, Eeof }, 396 print, Eeof, abort },
395/* IS_PASS_MIDDLE */ 397/* IS_PASS_MIDDLE */
396{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif, 398{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
397 Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif, 399 Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif,
398 print, Eeof }, 400 print, Eeof, abort },
399/* IS_FALSE_MIDDLE */ 401/* IS_FALSE_MIDDLE */
400{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif, 402{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
401 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, 403 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
402 drop, Eeof }, 404 drop, Eeof, abort },
403/* IS_TRUE_MIDDLE */ 405/* IS_TRUE_MIDDLE */
404{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif, 406{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
405 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif, 407 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
406 print, Eeof }, 408 print, Eeof, abort },
407/* IS_PASS_ELSE */ 409/* IS_PASS_ELSE */
408{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif, 410{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
409 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif, 411 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif,
410 print, Eeof }, 412 print, Eeof, abort },
411/* IS_FALSE_ELSE */ 413/* IS_FALSE_ELSE */
412{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif, 414{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
413 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, 415 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
414 drop, Eeof }, 416 drop, Eeof, abort },
415/* IS_TRUE_ELSE */ 417/* IS_TRUE_ELSE */
416{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif, 418{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
417 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc, 419 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc,
418 print, Eeof }, 420 print, Eeof, abort },
419/* IS_FALSE_TRAILER */ 421/* IS_FALSE_TRAILER */
420{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif, 422{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
421 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, 423 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
422 drop, Eeof } 424 drop, Eeof, abort }
423/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF 425/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF
424 TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY) 426 TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY)
425 PLAIN EOF */ 427 PLAIN EOF ERROR */
426}; 428};
427 429
428/* 430/*
@@ -463,9 +465,11 @@ keywordedit(const char *replacement)
463static void 465static void
464nest(void) 466nest(void)
465{ 467{
466 depth += 1; 468 if (depth > MAXDEPTH-1)
467 if (depth >= MAXDEPTH) 469 abort(); /* bug */
470 if (depth == MAXDEPTH-1)
468 error("Too many levels of nesting"); 471 error("Too many levels of nesting");
472 depth += 1;
469 stifline[depth] = linenum; 473 stifline[depth] = linenum;
470} 474}
471static void 475static void
@@ -490,15 +494,23 @@ flushline(bool keep)
490 if (symlist) 494 if (symlist)
491 return; 495 return;
492 if (keep ^ complement) { 496 if (keep ^ complement) {
493 if (lnnum && delcount > 0) 497 bool blankline = tline[strspn(tline, " \t\n")] == '\0';
494 printf("#line %d\n", linenum); 498 if (blankline && compblank && blankcount != blankmax) {
495 fputs(tline, stdout); 499 delcount += 1;
496 delcount = 0; 500 blankcount += 1;
501 } else {
502 if (lnnum && delcount > 0)
503 printf("#line %d\n", linenum);
504 fputs(tline, stdout);
505 delcount = 0;
506 blankmax = blankcount = blankline ? blankcount + 1 : 0;
507 }
497 } else { 508 } else {
498 if (lnblank) 509 if (lnblank)
499 putc('\n', stdout); 510 putc('\n', stdout);
500 exitstat = 1; 511 exitstat = 1;
501 delcount += 1; 512 delcount += 1;
513 blankcount = 0;
502 } 514 }
503} 515}
504 516
@@ -510,9 +522,12 @@ process(void)
510{ 522{
511 Linetype lineval; 523 Linetype lineval;
512 524
525 /* When compressing blank lines, act as if the file
526 is preceded by a large number of blank lines. */
527 blankmax = blankcount = 1000;
513 for (;;) { 528 for (;;) {
514 linenum++; 529 linenum++;
515 lineval = get_line(); 530 lineval = parseline();
516 trans_table[ifstate[depth]][lineval](); 531 trans_table[ifstate[depth]][lineval]();
517 debug("process %s -> %s depth %d", 532 debug("process %s -> %s depth %d",
518 linetype_name[lineval], 533 linetype_name[lineval],
@@ -526,7 +541,7 @@ process(void)
526 * help from skipcomment(). 541 * help from skipcomment().
527 */ 542 */
528static Linetype 543static Linetype
529get_line(void) 544parseline(void)
530{ 545{
531 const char *cp; 546 const char *cp;
532 int cursym; 547 int cursym;
@@ -595,9 +610,21 @@ get_line(void)
595 if (incomment) 610 if (incomment)
596 linestate = LS_DIRTY; 611 linestate = LS_DIRTY;
597 } 612 }
598 /* skipcomment should have changed the state */ 613 /* skipcomment normally changes the state, except
599 if (linestate == LS_HASH) 614 if the last line of the file lacks a newline, or
600 abort(); /* bug */ 615 if there is too much whitespace in a directive */
616 if (linestate == LS_HASH) {
617 size_t len = cp - tline;
618 if (fgets(tline + len, MAXLINE - len, input) == NULL) {
619 /* append the missing newline */
620 tline[len+0] = '\n';
621 tline[len+1] = '\0';
622 cp++;
623 linestate = LS_START;
624 } else {
625 linestate = LS_DIRTY;
626 }
627 }
601 } 628 }
602 if (linestate == LS_DIRTY) { 629 if (linestate == LS_DIRTY) {
603 while (*cp != '\0') 630 while (*cp != '\0')
@@ -610,17 +637,40 @@ get_line(void)
610 637
611/* 638/*
612 * These are the binary operators that are supported by the expression 639 * These are the binary operators that are supported by the expression
613 * evaluator. Note that if support for division is added then we also 640 * evaluator.
614 * need short-circuiting booleans because of divide-by-zero.
615 */ 641 */
616static int op_lt(int a, int b) { return (a < b); } 642static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) {
617static int op_gt(int a, int b) { return (a > b); } 643 if(at == LT_IF || bt == LT_IF) return (LT_IF);
618static int op_le(int a, int b) { return (a <= b); } 644 return (*p = v, v ? LT_TRUE : LT_FALSE);
619static int op_ge(int a, int b) { return (a >= b); } 645}
620static int op_eq(int a, int b) { return (a == b); } 646static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) {
621static int op_ne(int a, int b) { return (a != b); } 647 return op_strict(p, a < b, at, bt);
622static int op_or(int a, int b) { return (a || b); } 648}
623static int op_and(int a, int b) { return (a && b); } 649static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) {
650 return op_strict(p, a > b, at, bt);
651}
652static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) {
653 return op_strict(p, a <= b, at, bt);
654}
655static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) {
656 return op_strict(p, a >= b, at, bt);
657}
658static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) {
659 return op_strict(p, a == b, at, bt);
660}
661static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) {
662 return op_strict(p, a != b, at, bt);
663}
664static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) {
665 if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE))
666 return (*p = 1, LT_TRUE);
667 return op_strict(p, a || b, at, bt);
668}
669static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) {
670 if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE))
671 return (*p = 0, LT_FALSE);
672 return op_strict(p, a && b, at, bt);
673}
624 674
625/* 675/*
626 * An evaluation function takes three arguments, as follows: (1) a pointer to 676 * 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); }
629 * value of the expression; and (3) a pointer to a char* that points to the 679 * value of the expression; and (3) a pointer to a char* that points to the
630 * expression to be evaluated and that is updated to the end of the expression 680 * expression to be evaluated and that is updated to the end of the expression
631 * when evaluation is complete. The function returns LT_FALSE if the value of 681 * when evaluation is complete. The function returns LT_FALSE if the value of
632 * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the 682 * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression
633 * expression could not be evaluated. 683 * depends on an unknown symbol, or LT_ERROR if there is a parse failure.
634 */ 684 */
635struct ops; 685struct ops;
636 686
@@ -649,7 +699,7 @@ static const struct ops {
649 eval_fn *inner; 699 eval_fn *inner;
650 struct op { 700 struct op {
651 const char *str; 701 const char *str;
652 int (*fn)(int, int); 702 Linetype (*fn)(int *, Linetype, int, Linetype, int);
653 } op[5]; 703 } op[5];
654} eval_ops[] = { 704} eval_ops[] = {
655 { eval_table, { { "||", op_or } } }, 705 { eval_table, { { "||", op_or } } },
@@ -664,8 +714,8 @@ static const struct ops {
664 714
665/* 715/*
666 * Function for evaluating the innermost parts of expressions, 716 * Function for evaluating the innermost parts of expressions,
667 * viz. !expr (expr) defined(symbol) symbol number 717 * viz. !expr (expr) number defined(symbol) symbol
668 * We reset the keepthis flag when we find a non-constant subexpression. 718 * We reset the constexpr flag in the last two cases.
669 */ 719 */
670static Linetype 720static Linetype
671eval_unary(const struct ops *ops, int *valp, const char **cpp) 721eval_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)
673 const char *cp; 723 const char *cp;
674 char *ep; 724 char *ep;
675 int sym; 725 int sym;
726 bool defparen;
727 Linetype lt;
676 728
677 cp = skipcomment(*cpp); 729 cp = skipcomment(*cpp);
678 if (*cp == '!') { 730 if (*cp == '!') {
679 debug("eval%d !", ops - eval_ops); 731 debug("eval%d !", ops - eval_ops);
680 cp++; 732 cp++;
681 if (eval_unary(ops, valp, &cp) == LT_IF) { 733 lt = eval_unary(ops, valp, &cp);
682 *cpp = cp; 734 if (lt == LT_ERROR)
683 return (LT_IF); 735 return (LT_ERROR);
736 if (lt != LT_IF) {
737 *valp = !*valp;
738 lt = *valp ? LT_TRUE : LT_FALSE;
684 } 739 }
685 *valp = !*valp;
686 } else if (*cp == '(') { 740 } else if (*cp == '(') {
687 cp++; 741 cp++;
688 debug("eval%d (", ops - eval_ops); 742 debug("eval%d (", ops - eval_ops);
689 if (eval_table(eval_ops, valp, &cp) == LT_IF) 743 lt = eval_table(eval_ops, valp, &cp);
690 return (LT_IF); 744 if (lt == LT_ERROR)
745 return (LT_ERROR);
691 cp = skipcomment(cp); 746 cp = skipcomment(cp);
692 if (*cp++ != ')') 747 if (*cp++ != ')')
693 return (LT_IF); 748 return (LT_ERROR);
694 } else if (isdigit((unsigned char)*cp)) { 749 } else if (isdigit((unsigned char)*cp)) {
695 debug("eval%d number", ops - eval_ops); 750 debug("eval%d number", ops - eval_ops);
696 *valp = strtol(cp, &ep, 0); 751 *valp = strtol(cp, &ep, 0);
752 if (ep == cp)
753 return (LT_ERROR);
754 lt = *valp ? LT_TRUE : LT_FALSE;
697 cp = skipsym(cp); 755 cp = skipsym(cp);
698 } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { 756 } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) {
699 cp = skipcomment(cp+7); 757 cp = skipcomment(cp+7);
700 debug("eval%d defined", ops - eval_ops); 758 debug("eval%d defined", ops - eval_ops);
701 if (*cp++ != '(') 759 if (*cp == '(') {
702 return (LT_IF); 760 cp = skipcomment(cp+1);
703 cp = skipcomment(cp); 761 defparen = true;
762 } else {
763 defparen = false;
764 }
704 sym = findsym(cp); 765 sym = findsym(cp);
705 cp = skipsym(cp); 766 if (sym < 0) {
706 cp = skipcomment(cp); 767 lt = LT_IF;
707 if (*cp++ != ')') 768 } else {
708 return (LT_IF);
709 if (sym >= 0)
710 *valp = (value[sym] != NULL); 769 *valp = (value[sym] != NULL);
711 else { 770 lt = *valp ? LT_TRUE : LT_FALSE;
712 *cpp = cp;
713 return (LT_IF);
714 } 771 }
715 keepthis = false; 772 cp = skipsym(cp);
773 cp = skipcomment(cp);
774 if (defparen && *cp++ != ')')
775 return (LT_ERROR);
776 constexpr = false;
716 } else if (!endsym(*cp)) { 777 } else if (!endsym(*cp)) {
717 debug("eval%d symbol", ops - eval_ops); 778 debug("eval%d symbol", ops - eval_ops);
718 sym = findsym(cp); 779 sym = findsym(cp);
719 if (sym < 0) 780 cp = skipsym(cp);
720 return (LT_IF); 781 if (sym < 0) {
721 if (value[sym] == NULL) 782 lt = LT_IF;
783 cp = skipargs(cp);
784 } else if (value[sym] == NULL) {
722 *valp = 0; 785 *valp = 0;
723 else { 786 lt = LT_FALSE;
787 } else {
724 *valp = strtol(value[sym], &ep, 0); 788 *valp = strtol(value[sym], &ep, 0);
725 if (*ep != '\0' || ep == value[sym]) 789 if (*ep != '\0' || ep == value[sym])
726 return (LT_IF); 790 return (LT_ERROR);
791 lt = *valp ? LT_TRUE : LT_FALSE;
792 cp = skipargs(cp);
727 } 793 }
728 cp = skipsym(cp); 794 constexpr = false;
729 keepthis = false;
730 } else { 795 } else {
731 debug("eval%d bad expr", ops - eval_ops); 796 debug("eval%d bad expr", ops - eval_ops);
732 return (LT_IF); 797 return (LT_ERROR);
733 } 798 }
734 799
735 *cpp = cp; 800 *cpp = cp;
736 debug("eval%d = %d", ops - eval_ops, *valp); 801 debug("eval%d = %d", ops - eval_ops, *valp);
737 return (*valp ? LT_TRUE : LT_FALSE); 802 return (lt);
738} 803}
739 804
740/* 805/*
@@ -746,11 +811,13 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
746 const struct op *op; 811 const struct op *op;
747 const char *cp; 812 const char *cp;
748 int val; 813 int val;
749 Linetype lhs, rhs; 814 Linetype lt, rt;
750 815
751 debug("eval%d", ops - eval_ops); 816 debug("eval%d", ops - eval_ops);
752 cp = *cpp; 817 cp = *cpp;
753 lhs = ops->inner(ops+1, valp, &cp); 818 lt = ops->inner(ops+1, valp, &cp);
819 if (lt == LT_ERROR)
820 return (LT_ERROR);
754 for (;;) { 821 for (;;) {
755 cp = skipcomment(cp); 822 cp = skipcomment(cp);
756 for (op = ops->op; op->str != NULL; op++) 823 for (op = ops->op; op->str != NULL; op++)
@@ -760,32 +827,16 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
760 break; 827 break;
761 cp += strlen(op->str); 828 cp += strlen(op->str);
762 debug("eval%d %s", ops - eval_ops, op->str); 829 debug("eval%d %s", ops - eval_ops, op->str);
763 rhs = ops->inner(ops+1, &val, &cp); 830 rt = ops->inner(ops+1, &val, &cp);
764 if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) { 831 if (rt == LT_ERROR)
765 debug("eval%d: and always false", ops - eval_ops); 832 return (LT_ERROR);
766 if (lhs == LT_IF) 833 lt = op->fn(valp, lt, *valp, rt, val);
767 *valp = val;
768 lhs = LT_FALSE;
769 continue;
770 }
771 if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) {
772 debug("eval%d: or always true", ops - eval_ops);
773 if (lhs == LT_IF)
774 *valp = val;
775 lhs = LT_TRUE;
776 continue;
777 }
778 if (rhs == LT_IF)
779 lhs = LT_IF;
780 if (lhs != LT_IF)
781 *valp = op->fn(*valp, val);
782 } 834 }
783 835
784 *cpp = cp; 836 *cpp = cp;
785 debug("eval%d = %d", ops - eval_ops, *valp); 837 debug("eval%d = %d", ops - eval_ops, *valp);
786 if (lhs != LT_IF) 838 debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]);
787 lhs = (*valp ? LT_TRUE : LT_FALSE); 839 return (lt);
788 return lhs;
789} 840}
790 841
791/* 842/*
@@ -796,17 +847,14 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
796static Linetype 847static Linetype
797ifeval(const char **cpp) 848ifeval(const char **cpp)
798{ 849{
799 const char *cp = *cpp;
800 int ret; 850 int ret;
801 int val; 851 int val = 0;
802 852
803 debug("eval %s", *cpp); 853 debug("eval %s", *cpp);
804 keepthis = killconsts ? false : true; 854 constexpr = killconsts ? false : true;
805 ret = eval_table(eval_ops, &val, &cp); 855 ret = eval_table(eval_ops, &val, cpp);
806 if (ret != LT_IF)
807 *cpp = cp;
808 debug("eval = %d", val); 856 debug("eval = %d", val);
809 return (keepthis ? LT_IF : ret); 857 return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
810} 858}
811 859
812/* 860/*
@@ -918,6 +966,31 @@ skipcomment(const char *cp)
918} 966}
919 967
920/* 968/*
969 * Skip macro arguments.
970 */
971static const char *
972skipargs(const char *cp)
973{
974 const char *ocp = cp;
975 int level = 0;
976 cp = skipcomment(cp);
977 if (*cp != '(')
978 return (cp);
979 do {
980 if (*cp == '(')
981 level++;
982 if (*cp == ')')
983 level--;
984 cp = skipcomment(cp+1);
985 } while (level != 0 && *cp != '\0');
986 if (level == 0)
987 return (cp);
988 else
989 /* Rewind and re-detect the syntax error later. */
990 return (ocp);
991}
992
993/*
921 * Skip over an identifier. 994 * Skip over an identifier.
922 */ 995 */
923static const char * 996static const char *
@@ -929,7 +1002,7 @@ skipsym(const char *cp)
929} 1002}
930 1003
931/* 1004/*
932 * Look for the symbol in the symbol table. If is is found, we return 1005 * Look for the symbol in the symbol table. If it is found, we return
933 * the symbol table index, else we return -1. 1006 * the symbol table index, else we return -1.
934 */ 1007 */
935static int 1008static int