aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include8
-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/checkkconfigsymbols.sh4
-rwxr-xr-xscripts/checkpatch.pl86
-rw-r--r--scripts/dtc/data.c2
-rw-r--r--scripts/dtc/dtc-lexer.l2
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped69
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c2
-rw-r--r--scripts/dtc/treesource.c2
-rw-r--r--scripts/genksyms/keywords.c_shipped192
-rw-r--r--scripts/genksyms/keywords.gperf4
-rwxr-xr-xscripts/get_maintainer.pl610
-rwxr-xr-xscripts/headers.sh2
-rw-r--r--scripts/headers_install.pl2
-rw-r--r--scripts/kconfig/Makefile5
-rw-r--r--scripts/kconfig/confdata.c24
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped25
-rw-r--r--scripts/kconfig/mconf.c2
-rw-r--r--scripts/kconfig/streamline_config.pl12
-rw-r--r--scripts/kconfig/zconf.gperf2
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped2
-rw-r--r--scripts/kconfig/zconf.l6
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped379
-rw-r--r--scripts/kconfig/zconf.y13
-rwxr-xr-xscripts/kernel-doc15
-rw-r--r--scripts/markup_oops.pl4
-rwxr-xr-xscripts/mkcompile_h14
-rw-r--r--scripts/mod/Makefile2
-rw-r--r--scripts/mod/file2alias.c97
-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/Makefile31
-rw-r--r--scripts/package/buildtar6
-rwxr-xr-xscripts/package/mkspec2
-rwxr-xr-xscripts/recordmcount.pl280
-rw-r--r--scripts/selinux/Makefile4
-rw-r--r--scripts/selinux/genheaders/.gitignore1
-rw-r--r--scripts/selinux/genheaders/Makefile5
-rw-r--r--scripts/selinux/genheaders/genheaders.c118
-rw-r--r--scripts/selinux/mdp/mdp.c151
-rwxr-xr-xscripts/tags.sh8
-rw-r--r--scripts/unifdef.c341
46 files changed, 1705 insertions, 1105 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 4f9c1908593b..ed2773edfe71 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -100,7 +100,7 @@ as-option = $(call try-run,\
100# Usage: cflags-y += $(call as-instr,instr,option1,option2) 100# Usage: cflags-y += $(call as-instr,instr,option1,option2)
101 101
102as-instr = $(call try-run,\ 102as-instr = $(call try-run,\
103 echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) 103 /bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
104 104
105# cc-option 105# cc-option
106# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) 106# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
@@ -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 7a7778746ea6..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 = 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/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh
index 39677c82747a..46be3c5a62b7 100755
--- a/scripts/checkkconfigsymbols.sh
+++ b/scripts/checkkconfigsymbols.sh
@@ -9,7 +9,7 @@ paths="$@"
9# Doing this once at the beginning saves a lot of time, on a cache-hot tree. 9# Doing this once at the beginning saves a lot of time, on a cache-hot tree.
10Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`" 10Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`"
11 11
12echo -e "File list \tundefined symbol used" 12/bin/echo -e "File list \tundefined symbol used"
13find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i 13find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i
14do 14do
15 # Output the bare Kconfig variable and the filename; the _MODULE part at 15 # Output the bare Kconfig variable and the filename; the _MODULE part at
@@ -54,6 +54,6 @@ while read symb files; do
54 # beyond the purpose of this script. 54 # beyond the purpose of this script.
55 symb_bare=`echo $symb | sed -e 's/_MODULE//'` 55 symb_bare=`echo $symb | sed -e 's/_MODULE//'`
56 if ! grep -q "\<$symb_bare\>" $Kconfigs; then 56 if ! grep -q "\<$symb_bare\>" $Kconfigs; then
57 echo -e "$files: \t$symb" 57 /bin/echo -e "$files: \t$symb"
58 fi 58 fi
59done|sort 59done|sort
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 87bbb8bce9bf..3257d3d96767 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,8 +1,8 @@
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, Andy Whitcroft <apw@canonical.com> 5# (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
6# Licensed under the terms of the GNU GPL License version 2 6# Licensed under the terms of the GNU GPL License version 2
7 7
8use strict; 8use strict;
@@ -10,7 +10,7 @@ use strict;
10my $P = $0; 10my $P = $0;
11$P =~ s@.*/@@g; 11$P =~ s@.*/@@g;
12 12
13my $V = '0.29'; 13my $V = '0.30';
14 14
15use Getopt::Long qw(:config no_auto_abbrev); 15use Getopt::Long qw(:config no_auto_abbrev);
16 16
@@ -130,7 +130,10 @@ if ($tree) {
130 130
131my $emitted_corrupt = 0; 131my $emitted_corrupt = 0;
132 132
133our $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; 133our $Ident = qr{
134 [A-Za-z_][A-Za-z\d_]*
135 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
136 }x;
134our $Storage = qr{extern|static|asmlinkage}; 137our $Storage = qr{extern|static|asmlinkage};
135our $Sparse = qr{ 138our $Sparse = qr{
136 __user| 139 __user|
@@ -997,23 +1000,25 @@ sub annotate_values {
997 1000
998sub possible { 1001sub possible {
999 my ($possible, $line) = @_; 1002 my ($possible, $line) = @_;
1000 1003 my $notPermitted = qr{(?:
1001 print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1002 if ($possible !~ /(?:
1003 ^(?: 1004 ^(?:
1004 $Modifier| 1005 $Modifier|
1005 $Storage| 1006 $Storage|
1006 $Type| 1007 $Type|
1007 DEFINE_\S+| 1008 DEFINE_\S+
1009 )$|
1010 ^(?:
1008 goto| 1011 goto|
1009 return| 1012 return|
1010 case| 1013 case|
1011 else| 1014 else|
1012 asm|__asm__| 1015 asm|__asm__|
1013 do 1016 do
1014 )$| 1017 )(?:\s|$)|
1015 ^(?:typedef|struct|enum)\b 1018 ^(?:typedef|struct|enum)\b
1016 )/x) { 1019 )}x;
1020 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1021 if ($possible !~ $notPermitted) {
1017 # Check for modifiers. 1022 # Check for modifiers.
1018 $possible =~ s/\s*$Storage\s*//g; 1023 $possible =~ s/\s*$Storage\s*//g;
1019 $possible =~ s/\s*$Sparse\s*//g; 1024 $possible =~ s/\s*$Sparse\s*//g;
@@ -1022,8 +1027,10 @@ sub possible {
1022 } elsif ($possible =~ /\s/) { 1027 } elsif ($possible =~ /\s/) {
1023 $possible =~ s/\s*$Type\s*//g; 1028 $possible =~ s/\s*$Type\s*//g;
1024 for my $modifier (split(' ', $possible)) { 1029 for my $modifier (split(' ', $possible)) {
1025 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1030 if ($modifier !~ $notPermitted) {
1026 push(@modifierList, $modifier); 1031 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1032 push(@modifierList, $modifier);
1033 }
1027 } 1034 }
1028 1035
1029 } else { 1036 } else {
@@ -1138,6 +1145,7 @@ sub process {
1138 # suppression flags 1145 # suppression flags
1139 my %suppress_ifbraces; 1146 my %suppress_ifbraces;
1140 my %suppress_whiletrailers; 1147 my %suppress_whiletrailers;
1148 my %suppress_export;
1141 1149
1142 # Pre-scan the patch sanitizing the lines. 1150 # Pre-scan the patch sanitizing the lines.
1143 # Pre-scan the patch looking for any __setup documentation. 1151 # Pre-scan the patch looking for any __setup documentation.
@@ -1230,7 +1238,6 @@ sub process {
1230 $linenr++; 1238 $linenr++;
1231 1239
1232 my $rawline = $rawlines[$linenr - 1]; 1240 my $rawline = $rawlines[$linenr - 1];
1233 my $hunk_line = ($realcnt != 0);
1234 1241
1235#extract the line range in the file after the patch is applied 1242#extract the line range in the file after the patch is applied
1236 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1243 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1247,6 +1254,7 @@ sub process {
1247 1254
1248 %suppress_ifbraces = (); 1255 %suppress_ifbraces = ();
1249 %suppress_whiletrailers = (); 1256 %suppress_whiletrailers = ();
1257 %suppress_export = ();
1250 next; 1258 next;
1251 1259
1252# track the line number as we move through the hunk, note that 1260# track the line number as we move through the hunk, note that
@@ -1270,6 +1278,8 @@ sub process {
1270 $realcnt--; 1278 $realcnt--;
1271 } 1279 }
1272 1280
1281 my $hunk_line = ($realcnt != 0);
1282
1273#make up the handle for any error we report on this line 1283#make up the handle for any error we report on this line
1274 $prefix = "$filename:$realline: " if ($emacs && $file); 1284 $prefix = "$filename:$realline: " if ($emacs && $file);
1275 $prefix = "$filename:$linenr: " if ($emacs && !$file); 1285 $prefix = "$filename:$linenr: " if ($emacs && !$file);
@@ -1420,13 +1430,22 @@ sub process {
1420 } 1430 }
1421 1431
1422# Check for potential 'bare' types 1432# Check for potential 'bare' types
1423 my ($stat, $cond, $line_nr_next, $remain_next, $off_next); 1433 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
1434 $realline_next);
1424 if ($realcnt && $line =~ /.\s*\S/) { 1435 if ($realcnt && $line =~ /.\s*\S/) {
1425 ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 1436 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
1426 ctx_statement_block($linenr, $realcnt, 0); 1437 ctx_statement_block($linenr, $realcnt, 0);
1427 $stat =~ s/\n./\n /g; 1438 $stat =~ s/\n./\n /g;
1428 $cond =~ s/\n./\n /g; 1439 $cond =~ s/\n./\n /g;
1429 1440
1441 # Find the real next line.
1442 $realline_next = $line_nr_next;
1443 if (defined $realline_next &&
1444 (!defined $lines[$realline_next - 1] ||
1445 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
1446 $realline_next++;
1447 }
1448
1430 my $s = $stat; 1449 my $s = $stat;
1431 $s =~ s/{.*$//s; 1450 $s =~ s/{.*$//s;
1432 1451
@@ -1661,8 +1680,8 @@ sub process {
1661 } 1680 }
1662 1681
1663# check for initialisation to aggregates open brace on the next line 1682# check for initialisation to aggregates open brace on the next line
1664 if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && 1683 if ($line =~ /^.\s*{/ &&
1665 $line =~ /^.\s*{/) { 1684 $prevline =~ /(?:^|[^=])=\s*$/) {
1666 ERROR("that open brace { should be on the previous line\n" . $hereprev); 1685 ERROR("that open brace { should be on the previous line\n" . $hereprev);
1667 } 1686 }
1668 1687
@@ -1687,21 +1706,40 @@ sub process {
1687 $line =~ s@//.*@@; 1706 $line =~ s@//.*@@;
1688 $opline =~ s@//.*@@; 1707 $opline =~ s@//.*@@;
1689 1708
1690#EXPORT_SYMBOL should immediately follow its function closing }. 1709# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
1691 if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || 1710# the whole statement.
1692 ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1711#print "APW <$lines[$realline_next - 1]>\n";
1712 if (defined $realline_next &&
1713 exists $lines[$realline_next - 1] &&
1714 !defined $suppress_export{$realline_next} &&
1715 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1716 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1693 my $name = $1; 1717 my $name = $1;
1694 if ($prevline !~ /(?: 1718 if ($stat !~ /(?:
1695 ^.}| 1719 \n.}\s*$|
1696 ^.DEFINE_$Ident\(\Q$name\E\)| 1720 ^.DEFINE_$Ident\(\Q$name\E\)|
1697 ^.DECLARE_$Ident\(\Q$name\E\)| 1721 ^.DECLARE_$Ident\(\Q$name\E\)|
1698 ^.LIST_HEAD\(\Q$name\E\)| 1722 ^.LIST_HEAD\(\Q$name\E\)|
1699 ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 1723 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
1700 \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[) 1724 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
1701 )/x) { 1725 )/x) {
1702 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 1726#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
1727 $suppress_export{$realline_next} = 2;
1728 } else {
1729 $suppress_export{$realline_next} = 1;
1703 } 1730 }
1704 } 1731 }
1732 if (!defined $suppress_export{$linenr} &&
1733 $prevline =~ /^.\s*$/ &&
1734 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1735 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1736#print "FOO B <$lines[$linenr - 1]>\n";
1737 $suppress_export{$linenr} = 2;
1738 }
1739 if (defined $suppress_export{$linenr} &&
1740 $suppress_export{$linenr} == 2) {
1741 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
1742 }
1705 1743
1706# check for external initialisers. 1744# check for external initialisers.
1707 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { 1745 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index dd2e3d39d4c1..fe555e819bf8 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -217,7 +217,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
217 return d; 217 return d;
218} 218}
219 219
220struct data data_append_markers(struct data d, struct marker *m) 220static struct data data_append_markers(struct data d, struct marker *m)
221{ 221{
222 struct marker **mp = &d.markers; 222 struct marker **mp = &d.markers;
223 223
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 44dbfd3f0976..a627bbee91d4 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -18,7 +18,7 @@
18 * USA 18 * USA
19 */ 19 */
20 20
21%option noyywrap nounput yylineno 21%option noyywrap noinput nounput yylineno
22 22
23%x INCLUDE 23%x INCLUDE
24%x BYTESTRING 24%x BYTESTRING
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index ac392cb040f6..e27cc636e326 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -9,7 +9,7 @@
9#define FLEX_SCANNER 9#define FLEX_SCANNER
10#define YY_FLEX_MAJOR_VERSION 2 10#define YY_FLEX_MAJOR_VERSION 2
11#define YY_FLEX_MINOR_VERSION 5 11#define YY_FLEX_MINOR_VERSION 5
12#define YY_FLEX_SUBMINOR_VERSION 34 12#define YY_FLEX_SUBMINOR_VERSION 35
13#if YY_FLEX_SUBMINOR_VERSION > 0 13#if YY_FLEX_SUBMINOR_VERSION > 0
14#define FLEX_BETA 14#define FLEX_BETA
15#endif 15#endif
@@ -54,7 +54,6 @@ typedef int flex_int32_t;
54typedef unsigned char flex_uint8_t; 54typedef unsigned char flex_uint8_t;
55typedef unsigned short int flex_uint16_t; 55typedef unsigned short int flex_uint16_t;
56typedef unsigned int flex_uint32_t; 56typedef unsigned int flex_uint32_t;
57#endif /* ! C99 */
58 57
59/* Limits of integral types. */ 58/* Limits of integral types. */
60#ifndef INT8_MIN 59#ifndef INT8_MIN
@@ -85,6 +84,8 @@ typedef unsigned int flex_uint32_t;
85#define UINT32_MAX (4294967295U) 84#define UINT32_MAX (4294967295U)
86#endif 85#endif
87 86
87#endif /* ! C99 */
88
88#endif /* ! FLEXINT_H */ 89#endif /* ! FLEXINT_H */
89 90
90#ifdef __cplusplus 91#ifdef __cplusplus
@@ -141,7 +142,15 @@ typedef unsigned int flex_uint32_t;
141 142
142/* Size of default input buffer. */ 143/* Size of default input buffer. */
143#ifndef YY_BUF_SIZE 144#ifndef YY_BUF_SIZE
145#ifdef __ia64__
146/* On IA-64, the buffer size is 16k, not 8k.
147 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
148 * Ditto for the __ia64__ case accordingly.
149 */
150#define YY_BUF_SIZE 32768
151#else
144#define YY_BUF_SIZE 16384 152#define YY_BUF_SIZE 16384
153#endif /* __ia64__ */
145#endif 154#endif
146 155
147/* The state buf must be large enough to hold one state per character in the main buffer. 156/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -192,13 +201,6 @@ extern FILE *yyin, *yyout;
192 201
193#define unput(c) yyunput( c, (yytext_ptr) ) 202#define unput(c) yyunput( c, (yytext_ptr) )
194 203
195/* The following is because we cannot portably get our hands on size_t
196 * (without autoconf's help, which isn't available because we want
197 * flex-generated scanners to compile on their own).
198 * Given that the standard has decreed that size_t exists since 1989,
199 * I guess we can afford to depend on it. Manoj.
200 */
201
202#ifndef YY_TYPEDEF_YY_SIZE_T 204#ifndef YY_TYPEDEF_YY_SIZE_T
203#define YY_TYPEDEF_YY_SIZE_T 205#define YY_TYPEDEF_YY_SIZE_T
204typedef size_t yy_size_t; 206typedef size_t yy_size_t;
@@ -604,6 +606,7 @@ char *yytext;
604 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 606 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
605 * USA 607 * USA
606 */ 608 */
609#define YY_NO_INPUT 1
607 610
608 611
609 612
@@ -634,7 +637,7 @@ static int dts_version; /* = 0 */
634 637
635static void push_input_file(const char *filename); 638static void push_input_file(const char *filename);
636static int pop_input_file(void); 639static int pop_input_file(void);
637#line 638 "dtc-lexer.lex.c" 640#line 641 "dtc-lexer.lex.c"
638 641
639#define INITIAL 0 642#define INITIAL 0
640#define INCLUDE 1 643#define INCLUDE 1
@@ -656,6 +659,35 @@ static int pop_input_file(void);
656 659
657static int yy_init_globals (void ); 660static int yy_init_globals (void );
658 661
662/* Accessor methods to globals.
663 These are made visible to non-reentrant scanners for convenience. */
664
665int yylex_destroy (void );
666
667int yyget_debug (void );
668
669void yyset_debug (int debug_flag );
670
671YY_EXTRA_TYPE yyget_extra (void );
672
673void yyset_extra (YY_EXTRA_TYPE user_defined );
674
675FILE *yyget_in (void );
676
677void yyset_in (FILE * in_str );
678
679FILE *yyget_out (void );
680
681void yyset_out (FILE * out_str );
682
683int yyget_leng (void );
684
685char *yyget_text (void );
686
687int yyget_lineno (void );
688
689void yyset_lineno (int line_number );
690
659/* Macros after this point can all be overridden by user definitions in 691/* Macros after this point can all be overridden by user definitions in
660 * section 1. 692 * section 1.
661 */ 693 */
@@ -688,7 +720,12 @@ static int input (void );
688 720
689/* Amount of stuff to slurp up with each read. */ 721/* Amount of stuff to slurp up with each read. */
690#ifndef YY_READ_BUF_SIZE 722#ifndef YY_READ_BUF_SIZE
723#ifdef __ia64__
724/* On IA-64, the buffer size is 16k, not 8k */
725#define YY_READ_BUF_SIZE 16384
726#else
691#define YY_READ_BUF_SIZE 8192 727#define YY_READ_BUF_SIZE 8192
728#endif /* __ia64__ */
692#endif 729#endif
693 730
694/* Copy whatever the last rule matched to the standard output. */ 731/* Copy whatever the last rule matched to the standard output. */
@@ -696,7 +733,7 @@ static int input (void );
696/* This used to be an fputs(), but since the string might contain NUL's, 733/* This used to be an fputs(), but since the string might contain NUL's,
697 * we now use fwrite(). 734 * we now use fwrite().
698 */ 735 */
699#define ECHO fwrite( yytext, yyleng, 1, yyout ) 736#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
700#endif 737#endif
701 738
702/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 739/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -707,7 +744,7 @@ static int input (void );
707 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ 744 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
708 { \ 745 { \
709 int c = '*'; \ 746 int c = '*'; \
710 int n; \ 747 size_t n; \
711 for ( n = 0; n < max_size && \ 748 for ( n = 0; n < max_size && \
712 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 749 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
713 buf[n] = (char) c; \ 750 buf[n] = (char) c; \
@@ -791,7 +828,7 @@ YY_DECL
791 828
792#line 64 "dtc-lexer.l" 829#line 64 "dtc-lexer.l"
793 830
794#line 795 "dtc-lexer.lex.c" 831#line 832 "dtc-lexer.lex.c"
795 832
796 if ( !(yy_init) ) 833 if ( !(yy_init) )
797 { 834 {
@@ -1116,7 +1153,7 @@ YY_RULE_SETUP
1116#line 222 "dtc-lexer.l" 1153#line 222 "dtc-lexer.l"
1117ECHO; 1154ECHO;
1118 YY_BREAK 1155 YY_BREAK
1119#line 1120 "dtc-lexer.lex.c" 1156#line 1157 "dtc-lexer.lex.c"
1120 1157
1121 case YY_END_OF_BUFFER: 1158 case YY_END_OF_BUFFER:
1122 { 1159 {
@@ -1840,8 +1877,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1840 1877
1841/** Setup the input buffer state to scan the given bytes. The next call to yylex() will 1878/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1842 * scan from a @e copy of @a bytes. 1879 * scan from a @e copy of @a bytes.
1843 * @param bytes the byte buffer to scan 1880 * @param yybytes the byte buffer to scan
1844 * @param len the number of bytes in the buffer pointed to by @a bytes. 1881 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
1845 * 1882 *
1846 * @return the newly allocated buffer state object. 1883 * @return the newly allocated buffer state object.
1847 */ 1884 */
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index fbbba44fcd0d..22e692919ff9 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -411,7 +411,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
411 &phandle, sizeof(phandle)); 411 &phandle, sizeof(phandle));
412} 412}
413 413
414int _stringlist_contains(const char *strlist, int listlen, const char *str) 414static int _stringlist_contains(const char *strlist, int listlen, const char *str)
415{ 415{
416 int len = strlen(str); 416 int len = strlen(str);
417 const char *p; 417 const char *p;
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index ebeb6eb27907..1521ff11bb97 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -52,7 +52,7 @@ static void write_prefix(FILE *f, int level)
52 fputc('\t', f); 52 fputc('\t', f);
53} 53}
54 54
55int isstring(char c) 55static int isstring(char c)
56{ 56{
57 return (isprint(c) 57 return (isprint(c)
58 || (c == '\0') 58 || (c == '\0')
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index 971e0113ae7a..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.2 */ 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) \
@@ -30,9 +30,11 @@
30 30
31#line 1 "scripts/genksyms/keywords.gperf" 31#line 1 "scripts/genksyms/keywords.gperf"
32 32
33#line 3 "scripts/genksyms/keywords.gperf" 33struct resword;
34static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
35#line 5 "scripts/genksyms/keywords.gperf"
34struct resword { const char *name; int token; }; 36struct resword { const char *name; int token; };
35/* maximum key range = 62, duplicates = 0 */ 37/* maximum key range = 64, duplicates = 0 */
36 38
37#ifdef __GNUC__ 39#ifdef __GNUC__
38__inline 40__inline
@@ -46,154 +48,160 @@ is_reserved_hash (register const char *str, register unsigned int len)
46{ 48{
47 static const unsigned char asso_values[] = 49 static const unsigned char asso_values[] =
48 { 50 {
49 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 51 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
50 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 52 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
51 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 53 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
52 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 54 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
53 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
54 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 56 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
55 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, 57 67, 67, 67, 67, 67, 67, 67, 67, 67, 0,
56 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, 58 67, 67, 67, 67, 67, 67, 15, 67, 67, 67,
57 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, 59 0, 67, 67, 67, 67, 67, 67, 67, 67, 67,
58 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, 60 67, 67, 67, 67, 67, 0, 67, 0, 67, 5,
59 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, 61 25, 20, 15, 30, 67, 15, 67, 67, 10, 0,
60 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, 62 10, 40, 20, 67, 10, 5, 0, 10, 15, 67,
61 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 63 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
62 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 64 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
63 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
64 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
66 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 68 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
67 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 69 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
68 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
69 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 71 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
70 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 72 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
71 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 73 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
72 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 74 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
73 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 75 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
74 65, 65, 65, 65, 65, 65 76 67, 67, 67, 67, 67, 67
75 }; 77 };
76 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]];
77} 79}
78 80
79#ifdef __GNUC__ 81#ifdef __GNUC__
80__inline 82__inline
83#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
84__attribute__ ((__gnu_inline__))
85#endif
81#endif 86#endif
82const struct resword * 87const struct resword *
83is_reserved_word (register const char *str, register unsigned int len) 88is_reserved_word (register const char *str, register unsigned int len)
84{ 89{
85 enum 90 enum
86 { 91 {
87 TOTAL_KEYWORDS = 43, 92 TOTAL_KEYWORDS = 45,
88 MIN_WORD_LENGTH = 3, 93 MIN_WORD_LENGTH = 3,
89 MAX_WORD_LENGTH = 24, 94 MAX_WORD_LENGTH = 24,
90 MIN_HASH_VALUE = 3, 95 MIN_HASH_VALUE = 3,
91 MAX_HASH_VALUE = 64 96 MAX_HASH_VALUE = 66
92 }; 97 };
93 98
94 static const struct resword wordlist[] = 99 static const struct resword wordlist[] =
95 { 100 {
96 {""}, {""}, {""}, 101 {""}, {""}, {""},
97#line 26 "scripts/genksyms/keywords.gperf" 102#line 30 "scripts/genksyms/keywords.gperf"
98 {"asm", ASM_KEYW}, 103 {"asm", ASM_KEYW},
99 {""}, 104 {""},
100#line 8 "scripts/genksyms/keywords.gperf" 105#line 12 "scripts/genksyms/keywords.gperf"
101 {"__asm", ASM_KEYW}, 106 {"__asm", ASM_KEYW},
102 {""}, 107 {""},
103#line 9 "scripts/genksyms/keywords.gperf" 108#line 13 "scripts/genksyms/keywords.gperf"
104 {"__asm__", ASM_KEYW}, 109 {"__asm__", ASM_KEYW},
105 {""}, {""}, 110 {""}, {""},
106#line 52 "scripts/genksyms/keywords.gperf" 111#line 56 "scripts/genksyms/keywords.gperf"
107 {"__typeof__", TYPEOF_KEYW}, 112 {"__typeof__", TYPEOF_KEYW},
108 {""}, 113 {""},
109#line 12 "scripts/genksyms/keywords.gperf" 114#line 16 "scripts/genksyms/keywords.gperf"
110 {"__const", CONST_KEYW}, 115 {"__const", CONST_KEYW},
111#line 11 "scripts/genksyms/keywords.gperf" 116#line 15 "scripts/genksyms/keywords.gperf"
112 {"__attribute__", ATTRIBUTE_KEYW}, 117 {"__attribute__", ATTRIBUTE_KEYW},
113#line 13 "scripts/genksyms/keywords.gperf" 118#line 17 "scripts/genksyms/keywords.gperf"
114 {"__const__", CONST_KEYW}, 119 {"__const__", CONST_KEYW},
115#line 18 "scripts/genksyms/keywords.gperf" 120#line 22 "scripts/genksyms/keywords.gperf"
116 {"__signed__", SIGNED_KEYW}, 121 {"__signed__", SIGNED_KEYW},
117#line 44 "scripts/genksyms/keywords.gperf" 122#line 48 "scripts/genksyms/keywords.gperf"
118 {"static", STATIC_KEYW}, 123 {"static", STATIC_KEYW},
119#line 20 "scripts/genksyms/keywords.gperf" 124 {""},
120 {"__volatile__", VOLATILE_KEYW}, 125#line 43 "scripts/genksyms/keywords.gperf"
121#line 39 "scripts/genksyms/keywords.gperf"
122 {"int", INT_KEYW}, 126 {"int", INT_KEYW},
123#line 32 "scripts/genksyms/keywords.gperf" 127#line 36 "scripts/genksyms/keywords.gperf"
124 {"char", CHAR_KEYW}, 128 {"char", CHAR_KEYW},
125#line 33 "scripts/genksyms/keywords.gperf" 129#line 37 "scripts/genksyms/keywords.gperf"
126 {"const", CONST_KEYW}, 130 {"const", CONST_KEYW},
127#line 45 "scripts/genksyms/keywords.gperf" 131#line 49 "scripts/genksyms/keywords.gperf"
128 {"struct", STRUCT_KEYW}, 132 {"struct", STRUCT_KEYW},
129#line 24 "scripts/genksyms/keywords.gperf" 133#line 28 "scripts/genksyms/keywords.gperf"
130 {"__restrict__", RESTRICT_KEYW}, 134 {"__restrict__", RESTRICT_KEYW},
131#line 25 "scripts/genksyms/keywords.gperf" 135#line 29 "scripts/genksyms/keywords.gperf"
132 {"restrict", RESTRICT_KEYW}, 136 {"restrict", RESTRICT_KEYW},
133#line 23 "scripts/genksyms/keywords.gperf" 137#line 9 "scripts/genksyms/keywords.gperf"
134 {"_restrict", RESTRICT_KEYW}, 138 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
135#line 16 "scripts/genksyms/keywords.gperf" 139#line 20 "scripts/genksyms/keywords.gperf"
136 {"__inline__", INLINE_KEYW}, 140 {"__inline__", INLINE_KEYW},
137#line 10 "scripts/genksyms/keywords.gperf" 141 {""},
138 {"__attribute", ATTRIBUTE_KEYW}, 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},
139 {""}, 148 {""},
140#line 14 "scripts/genksyms/keywords.gperf" 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"
141 {"__extension__", EXTENSION_KEYW}, 154 {"__extension__", EXTENSION_KEYW},
142#line 35 "scripts/genksyms/keywords.gperf" 155#line 39 "scripts/genksyms/keywords.gperf"
143 {"enum", ENUM_KEYW}, 156 {"enum", ENUM_KEYW},
144#line 19 "scripts/genksyms/keywords.gperf" 157#line 10 "scripts/genksyms/keywords.gperf"
145 {"__volatile", VOLATILE_KEYW}, 158 {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
146#line 36 "scripts/genksyms/keywords.gperf" 159#line 40 "scripts/genksyms/keywords.gperf"
147 {"extern", EXTERN_KEYW}, 160 {"extern", EXTERN_KEYW},
148 {""}, 161 {""},
149#line 17 "scripts/genksyms/keywords.gperf" 162#line 21 "scripts/genksyms/keywords.gperf"
150 {"__signed", SIGNED_KEYW}, 163 {"__signed", SIGNED_KEYW},
151#line 7 "scripts/genksyms/keywords.gperf" 164#line 11 "scripts/genksyms/keywords.gperf"
152 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, 165 {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
153 {""},
154#line 51 "scripts/genksyms/keywords.gperf" 166#line 51 "scripts/genksyms/keywords.gperf"
167 {"union", UNION_KEYW},
168#line 55 "scripts/genksyms/keywords.gperf"
155 {"typeof", TYPEOF_KEYW}, 169 {"typeof", TYPEOF_KEYW},
156#line 46 "scripts/genksyms/keywords.gperf" 170#line 50 "scripts/genksyms/keywords.gperf"
157 {"typedef", TYPEDEF_KEYW}, 171 {"typedef", TYPEDEF_KEYW},
158#line 15 "scripts/genksyms/keywords.gperf" 172#line 19 "scripts/genksyms/keywords.gperf"
159 {"__inline", INLINE_KEYW}, 173 {"__inline", INLINE_KEYW},
160#line 31 "scripts/genksyms/keywords.gperf" 174#line 35 "scripts/genksyms/keywords.gperf"
161 {"auto", AUTO_KEYW}, 175 {"auto", AUTO_KEYW},
162#line 47 "scripts/genksyms/keywords.gperf" 176#line 23 "scripts/genksyms/keywords.gperf"
163 {"union", UNION_KEYW}, 177 {"__volatile", VOLATILE_KEYW},
164 {""}, {""}, 178 {""}, {""},
165#line 48 "scripts/genksyms/keywords.gperf" 179#line 52 "scripts/genksyms/keywords.gperf"
166 {"unsigned", UNSIGNED_KEYW}, 180 {"unsigned", UNSIGNED_KEYW},
167#line 49 "scripts/genksyms/keywords.gperf"
168 {"void", VOID_KEYW},
169#line 42 "scripts/genksyms/keywords.gperf"
170 {"short", SHORT_KEYW},
171 {""}, {""},
172#line 50 "scripts/genksyms/keywords.gperf"
173 {"volatile", VOLATILE_KEYW},
174 {""},
175#line 37 "scripts/genksyms/keywords.gperf"
176 {"float", FLOAT_KEYW},
177#line 34 "scripts/genksyms/keywords.gperf"
178 {"double", DOUBLE_KEYW},
179 {""}, 181 {""},
180#line 5 "scripts/genksyms/keywords.gperf" 182#line 46 "scripts/genksyms/keywords.gperf"
181 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, 183 {"short", SHORT_KEYW},
182 {""}, {""}, 184#line 42 "scripts/genksyms/keywords.gperf"
183#line 38 "scripts/genksyms/keywords.gperf"
184 {"inline", INLINE_KEYW}, 185 {"inline", INLINE_KEYW},
185#line 6 "scripts/genksyms/keywords.gperf"
186 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
187#line 41 "scripts/genksyms/keywords.gperf"
188 {"register", REGISTER_KEYW},
189 {""}, 186 {""},
190#line 22 "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"
191 {"_Bool", BOOL_KEYW}, 192 {"_Bool", BOOL_KEYW},
192#line 43 "scripts/genksyms/keywords.gperf"
193 {"signed", SIGNED_KEYW},
194 {""}, {""}, 193 {""}, {""},
195#line 40 "scripts/genksyms/keywords.gperf" 194#line 45 "scripts/genksyms/keywords.gperf"
196 {"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}
197 }; 205 };
198 206
199 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 5ef3733225fb..e6349acb6f2f 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -1,10 +1,14 @@
1%{ 1%{
2struct resword;
3static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
2%} 4%}
3struct resword { const char *name; int token; } 5struct resword { const char *name; int token; }
4%% 6%%
5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW 7EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW 8EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
7EXPORT_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
8__asm, ASM_KEYW 12__asm, ASM_KEYW
9__asm__, ASM_KEYW 13__asm__, ASM_KEYW
10__attribute, ATTRIBUTE_KEYW 14__attribute, ATTRIBUTE_KEYW
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index cdb44b63342e..2f3230db7ffb 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -5,15 +5,15 @@
5# Print selected MAINTAINERS information for 5# Print selected MAINTAINERS information for
6# the files modified in a patch or for a file 6# the files modified in a patch or for a file
7# 7#
8# usage: perl scripts/get_maintainers.pl [OPTIONS] <patch> 8# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
9# perl scripts/get_maintainers.pl [OPTIONS] -f <file> 9# perl scripts/get_maintainer.pl [OPTIONS] -f <file>
10# 10#
11# Licensed under the terms of the GNU GPL License version 2 11# Licensed under the terms of the GNU GPL License version 2
12 12
13use strict; 13use strict;
14 14
15my $P = $0; 15my $P = $0;
16my $V = '0.20'; 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,20 +23,24 @@ 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;
39my $status = 0; 42my $status = 0;
43my $keywords = 1;
40my $from_filename = 0; 44my $from_filename = 0;
41my $pattern_depth = 0; 45my $pattern_depth = 0;
42my $version = 0; 46my $version = 0;
@@ -63,33 +67,64 @@ my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)";
63my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; 67my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
64my $rfc822_char = '[\\000-\\377]'; 68my $rfc822_char = '[\\000-\\377]';
65 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 --no-color --since=\$email_git_since -- \$file",
78 "find_commit_signers_cmd" => "git log --no-color -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
66if (!GetOptions( 98if (!GetOptions(
67 'email!' => \$email, 99 'email!' => \$email,
68 'git!' => \$email_git, 100 'git!' => \$email_git,
101 'git-blame!' => \$email_git_blame,
69 'git-chief-penguins!' => \$email_git_penguin_chiefs, 102 'git-chief-penguins!' => \$email_git_penguin_chiefs,
70 'git-min-signatures=i' => \$email_git_min_signatures, 103 'git-min-signatures=i' => \$email_git_min_signatures,
71 'git-max-maintainers=i' => \$email_git_max_maintainers, 104 'git-max-maintainers=i' => \$email_git_max_maintainers,
72 'git-min-percent=i' => \$email_git_min_percent, 105 'git-min-percent=i' => \$email_git_min_percent,
73 'git-since=s' => \$email_git_since, 106 'git-since=s' => \$email_git_since,
74 'git-blame!' => \$email_git_blame, 107 'hg-since=s' => \$email_hg_since,
75 'remove-duplicates!' => \$email_remove_duplicates, 108 'remove-duplicates!' => \$email_remove_duplicates,
76 'm!' => \$email_maintainer, 109 'm!' => \$email_maintainer,
77 'n!' => \$email_usename, 110 'n!' => \$email_usename,
78 'l!' => \$email_list, 111 'l!' => \$email_list,
79 's!' => \$email_subscriber_list, 112 's!' => \$email_subscriber_list,
80 'multiline!' => \$output_multiline, 113 'multiline!' => \$output_multiline,
114 'roles!' => \$output_roles,
115 'rolestats!' => \$output_rolestats,
81 'separator=s' => \$output_separator, 116 'separator=s' => \$output_separator,
82 'subsystem!' => \$subsystem, 117 'subsystem!' => \$subsystem,
83 'status!' => \$status, 118 'status!' => \$status,
84 'scm!' => \$scm, 119 'scm!' => \$scm,
85 'web!' => \$web, 120 'web!' => \$web,
86 'pattern-depth=i' => \$pattern_depth, 121 'pattern-depth=i' => \$pattern_depth,
122 'k|keywords!' => \$keywords,
87 'f|file' => \$from_filename, 123 'f|file' => \$from_filename,
88 'v|version' => \$version, 124 'v|version' => \$version,
89 'h|help' => \$help, 125 'h|help' => \$help,
90 )) { 126 )) {
91 usage(); 127 die "$P: invalid argument - use --help if necessary\n";
92 die "$P: invalid argument\n";
93} 128}
94 129
95if ($help != 0) { 130if ($help != 0) {
@@ -111,6 +146,10 @@ if ($output_separator ne ", ") {
111 $output_multiline = 0; 146 $output_multiline = 0;
112} 147}
113 148
149if ($output_rolestats) {
150 $output_roles = 1;
151}
152
114my $selections = $email + $scm + $status + $subsystem + $web; 153my $selections = $email + $scm + $status + $subsystem + $web;
115if ($selections == 0) { 154if ($selections == 0) {
116 usage(); 155 usage();
@@ -132,6 +171,8 @@ if (!top_of_kernel_tree($lk_path)) {
132## Read MAINTAINERS for type/value pairs 171## Read MAINTAINERS for type/value pairs
133 172
134my @typevalue = (); 173my @typevalue = ();
174my %keyword_hash;
175
135open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n"; 176open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n";
136while (<MAINT>) { 177while (<MAINT>) {
137 my $line = $_; 178 my $line = $_;
@@ -149,6 +190,8 @@ while (<MAINT>) {
149 if ((-d $value)) { 190 if ((-d $value)) {
150 $value =~ s@([^/])$@$1/@; 191 $value =~ s@([^/])$@$1/@;
151 } 192 }
193 } elsif ($type eq "K") {
194 $keyword_hash{@typevalue} = $value;
152 } 195 }
153 push(@typevalue, "$type:$value"); 196 push(@typevalue, "$type:$value");
154 } elsif (!/^(\s)*$/) { 197 } elsif (!/^(\s)*$/) {
@@ -169,7 +212,7 @@ if ($email_remove_duplicates) {
169 next if ($line =~ m/^\s*$/); 212 next if ($line =~ m/^\s*$/);
170 213
171 my ($name, $address) = parse_email($line); 214 my ($name, $address) = parse_email($line);
172 $line = format_email($name, $address); 215 $line = format_email($name, $address, $email_usename);
173 216
174 next if ($line =~ m/^\s*$/); 217 next if ($line =~ m/^\s*$/);
175 218
@@ -188,6 +231,7 @@ if ($email_remove_duplicates) {
188 231
189my @files = (); 232my @files = ();
190my @range = (); 233my @range = ();
234my @keyword_tvi = ();
191 235
192foreach my $file (@ARGV) { 236foreach my $file (@ARGV) {
193 ##if $file is a directory and it lacks a trailing slash, add one 237 ##if $file is a directory and it lacks a trailing slash, add one
@@ -198,11 +242,22 @@ foreach my $file (@ARGV) {
198 } 242 }
199 if ($from_filename) { 243 if ($from_filename) {
200 push(@files, $file); 244 push(@files, $file);
245 if (-f $file && $keywords) {
246 open(FILE, "<$file") or die "$P: Can't open ${file}\n";
247 my $text = do { local($/) ; <FILE> };
248 foreach my $line (keys %keyword_hash) {
249 if ($text =~ m/$keyword_hash{$line}/x) {
250 push(@keyword_tvi, $line);
251 }
252 }
253 close(FILE);
254 }
201 } else { 255 } else {
202 my $file_cnt = @files; 256 my $file_cnt = @files;
203 my $lastfile; 257 my $lastfile;
204 open(PATCH, "<$file") or die "$P: Can't open ${file}\n"; 258 open(PATCH, "<$file") or die "$P: Can't open ${file}\n";
205 while (<PATCH>) { 259 while (<PATCH>) {
260 my $patch_line = $_;
206 if (m/^\+\+\+\s+(\S+)/) { 261 if (m/^\+\+\+\s+(\S+)/) {
207 my $filename = $1; 262 my $filename = $1;
208 $filename =~ s@^[^/]*/@@; 263 $filename =~ s@^[^/]*/@@;
@@ -213,6 +268,12 @@ foreach my $file (@ARGV) {
213 if ($email_git_blame) { 268 if ($email_git_blame) {
214 push(@range, "$lastfile:$1:$2"); 269 push(@range, "$lastfile:$1:$2");
215 } 270 }
271 } elsif ($keywords) {
272 foreach my $line (keys %keyword_hash) {
273 if ($patch_line =~ m/^[+-].*$keyword_hash{$line}/x) {
274 push(@keyword_tvi, $line);
275 }
276 }
216 } 277 }
217 } 278 }
218 close(PATCH); 279 close(PATCH);
@@ -235,54 +296,71 @@ my @status = ();
235 296
236foreach my $file (@files) { 297foreach my $file (@files) {
237 298
238#Do not match excluded file patterns 299 my %hash;
239 300 my $tvi = find_first_section();
240 my $exclude = 0; 301 while ($tvi < @typevalue) {
241 foreach my $line (@typevalue) { 302 my $start = find_starting_index($tvi);
242 if ($line =~ m/^(\C):\s*(.*)/) { 303 my $end = find_ending_index($tvi);
243 my $type = $1; 304 my $exclude = 0;
244 my $value = $2; 305 my $i;
245 if ($type eq 'X') {
246 if (file_match_pattern($file, $value)) {
247 $exclude = 1;
248 last;
249 }
250 }
251 }
252 }
253 306
254 if (!$exclude) { 307 #Do not match excluded file patterns
255 my $tvi = 0; 308
256 my %hash; 309 for ($i = $start; $i < $end; $i++) {
257 foreach my $line (@typevalue) { 310 my $line = $typevalue[$i];
258 if ($line =~ m/^(\C):\s*(.*)/) { 311 if ($line =~ m/^(\C):\s*(.*)/) {
259 my $type = $1; 312 my $type = $1;
260 my $value = $2; 313 my $value = $2;
261 if ($type eq 'F') { 314 if ($type eq 'X') {
262 if (file_match_pattern($file, $value)) { 315 if (file_match_pattern($file, $value)) {
263 my $value_pd = ($value =~ tr@/@@); 316 $exclude = 1;
264 my $file_pd = ($file =~ tr@/@@);
265 $value_pd++ if (substr($value,-1,1) ne "/");
266 if ($pattern_depth == 0 ||
267 (($file_pd - $value_pd) < $pattern_depth)) {
268 $hash{$tvi} = $value_pd;
269 }
270 } 317 }
271 } 318 }
272 } 319 }
273 $tvi++;
274 } 320 }
275 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { 321
276 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 }
277 } 341 }
342
343 $tvi += ($end - $start);
344
345 }
346
347 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
348 add_categories($line);
278 } 349 }
279 350
280 if ($email && $email_git) { 351 if ($email && $email_git) {
281 recent_git_signoffs($file); 352 vcs_file_signoffs($file);
282 } 353 }
283 354
284 if ($email && $email_git_blame) { 355 if ($email && $email_git_blame) {
285 git_assign_blame($file); 356 vcs_file_blame($file);
357 }
358}
359
360if ($keywords) {
361 @keyword_tvi = sort_and_uniq(@keyword_tvi);
362 foreach my $line (@keyword_tvi) {
363 add_categories($line);
286 } 364 }
287} 365}
288 366
@@ -291,11 +369,11 @@ if ($email) {
291 if ($chief =~ m/^(.*):(.*)/) { 369 if ($chief =~ m/^(.*):(.*)/) {
292 my $email_address; 370 my $email_address;
293 371
294 $email_address = format_email($1, $2); 372 $email_address = format_email($1, $2, $email_usename);
295 if ($email_git_penguin_chiefs) { 373 if ($email_git_penguin_chiefs) {
296 push(@email_to, $email_address); 374 push(@email_to, [$email_address, 'chief penguin']);
297 } else { 375 } else {
298 @email_to = grep(!/${email_address}/, @email_to); 376 @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
299 } 377 }
300 } 378 }
301 } 379 }
@@ -309,7 +387,7 @@ if ($email || $email_list) {
309 if ($email_list) { 387 if ($email_list) {
310 @to = (@to, @list_to); 388 @to = (@to, @list_to);
311 } 389 }
312 output(uniq(@to)); 390 output(merge_email(@to));
313} 391}
314 392
315if ($scm) { 393if ($scm) {
@@ -365,13 +443,16 @@ MAINTAINER field selection options:
365 --git-min-signatures => number of signatures required (default: 1) 443 --git-min-signatures => number of signatures required (default: 1)
366 --git-max-maintainers => maximum maintainers to add (default: 5) 444 --git-max-maintainers => maximum maintainers to add (default: 5)
367 --git-min-percent => minimum percentage of commits required (default: 5) 445 --git-min-percent => minimum percentage of commits required (default: 5)
368 --git-since => git history to use (default: 1-year-ago)
369 --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)
370 --m => include maintainer(s) if any 449 --m => include maintainer(s) if any
371 --n => include name 'Full Name <addr\@domain.tld>' 450 --n => include name 'Full Name <addr\@domain.tld>'
372 --l => include list(s) if any 451 --l => include list(s) if any
373 --s => include subscriber only list(s) if any 452 --s => include subscriber only list(s) if any
374 --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, %)
375 --scm => print SCM tree(s) if any 456 --scm => print SCM tree(s) if any
376 --status => print status if any 457 --status => print status if any
377 --subsystem => print subsystem name if any 458 --subsystem => print subsystem name if any
@@ -384,6 +465,7 @@ Output type options:
384 465
385Other options: 466Other options:
386 --pattern-depth => Number of pattern directory traversals (default: 0 (all)) 467 --pattern-depth => Number of pattern directory traversals (default: 0 (all))
468 --keywords => scan patch for keywords (default: 1 (on))
387 --version => show version 469 --version => show version
388 --help => show this help information 470 --help => show this help information
389 471
@@ -396,11 +478,24 @@ Notes:
396 directory are examined as git recurses directories. 478 directory are examined as git recurses directories.
397 Any specified X: (exclude) pattern matches are _not_ ignored. 479 Any specified X: (exclude) pattern matches are _not_ ignored.
398 Used with "--nogit", directory is used as a pattern match, 480 Used with "--nogit", directory is used as a pattern match,
399 no individual file within the directory or subdirectory 481 no individual file within the directory or subdirectory
400 is matched. 482 is matched.
401 Used with "--git-blame", does not iterate all files in directory 483 Used with "--git-blame", does not iterate all files in directory
402 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
403 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
404EOT 499EOT
405} 500}
406 501
@@ -459,7 +554,7 @@ sub parse_email {
459} 554}
460 555
461sub format_email { 556sub format_email {
462 my ($name, $address) = @_; 557 my ($name, $address, $usename) = @_;
463 558
464 my $formatted_email; 559 my $formatted_email;
465 560
@@ -472,11 +567,11 @@ sub format_email {
472 $name = "\"$name\""; 567 $name = "\"$name\"";
473 } 568 }
474 569
475 if ($email_usename) { 570 if ($usename) {
476 if ("$name" eq "") { 571 if ("$name" eq "") {
477 $formatted_email = "$address"; 572 $formatted_email = "$address";
478 } else { 573 } else {
479 $formatted_email = "$name <${address}>"; 574 $formatted_email = "$name <$address>";
480 } 575 }
481 } else { 576 } else {
482 $formatted_email = $address; 577 $formatted_email = $address;
@@ -485,8 +580,21 @@ sub format_email {
485 return $formatted_email; 580 return $formatted_email;
486} 581}
487 582
488sub find_starting_index { 583sub find_first_section {
584 my $index = 0;
489 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
597sub find_starting_index {
490 my ($index) = @_; 598 my ($index) = @_;
491 599
492 while ($index > 0) { 600 while ($index > 0) {
@@ -514,6 +622,71 @@ sub find_ending_index {
514 return $index; 622 return $index;
515} 623}
516 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
517sub add_categories { 690sub add_categories {
518 my ($index) = @_; 691 my ($index) = @_;
519 692
@@ -531,17 +704,22 @@ sub add_categories {
531 if ($ptype eq "L") { 704 if ($ptype eq "L") {
532 my $list_address = $pvalue; 705 my $list_address = $pvalue;
533 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 }
534 if ($list_address =~ m/([^\s]+)\s+(.*)$/) { 712 if ($list_address =~ m/([^\s]+)\s+(.*)$/) {
535 $list_address = $1; 713 $list_address = $1;
536 $list_additional = $2; 714 $list_additional = $2;
537 } 715 }
538 if ($list_additional =~ m/subscribers-only/) { 716 if ($list_additional =~ m/subscribers-only/) {
539 if ($email_subscriber_list) { 717 if ($email_subscriber_list) {
540 push(@list_to, $list_address); 718 push(@list_to, [$list_address, "subscriber list${list_role}"]);
541 } 719 }
542 } else { 720 } else {
543 if ($email_list) { 721 if ($email_list) {
544 push(@list_to, $list_address); 722 push(@list_to, [$list_address, "open list${list_role}"]);
545 } 723 }
546 } 724 }
547 } elsif ($ptype eq "M") { 725 } elsif ($ptype eq "M") {
@@ -552,13 +730,14 @@ sub add_categories {
552 if ($tv =~ m/^(\C):\s*(.*)/) { 730 if ($tv =~ m/^(\C):\s*(.*)/) {
553 if ($1 eq "P") { 731 if ($1 eq "P") {
554 $name = $2; 732 $name = $2;
555 $pvalue = format_email($name, $address); 733 $pvalue = format_email($name, $address, $email_usename);
556 } 734 }
557 } 735 }
558 } 736 }
559 } 737 }
560 if ($email_maintainer) { 738 if ($email_maintainer) {
561 push_email_addresses($pvalue); 739 my $role = get_maintainer_role($i);
740 push_email_addresses($pvalue, $role);
562 } 741 }
563 } elsif ($ptype eq "T") { 742 } elsif ($ptype eq "T") {
564 push(@scm, $pvalue); 743 push(@scm, $pvalue);
@@ -585,7 +764,7 @@ sub email_inuse {
585} 764}
586 765
587sub push_email_address { 766sub push_email_address {
588 my ($line) = @_; 767 my ($line, $role) = @_;
589 768
590 my ($name, $address) = parse_email($line); 769 my ($name, $address) = parse_email($line);
591 770
@@ -594,9 +773,9 @@ sub push_email_address {
594 } 773 }
595 774
596 if (!$email_remove_duplicates) { 775 if (!$email_remove_duplicates) {
597 push(@email_to, format_email($name, $address)); 776 push(@email_to, [format_email($name, $address, $email_usename), $role]);
598 } elsif (!email_inuse($name, $address)) { 777 } elsif (!email_inuse($name, $address)) {
599 push(@email_to, format_email($name, $address)); 778 push(@email_to, [format_email($name, $address, $email_usename), $role]);
600 $email_hash_name{$name}++; 779 $email_hash_name{$name}++;
601 $email_hash_address{$address}++; 780 $email_hash_address{$address}++;
602 } 781 }
@@ -605,24 +784,52 @@ sub push_email_address {
605} 784}
606 785
607sub push_email_addresses { 786sub push_email_addresses {
608 my ($address) = @_; 787 my ($address, $role) = @_;
609 788
610 my @address_list = (); 789 my @address_list = ();
611 790
612 if (rfc822_valid($address)) { 791 if (rfc822_valid($address)) {
613 push_email_address($address); 792 push_email_address($address, $role);
614 } elsif (@address_list = rfc822_validlist($address)) { 793 } elsif (@address_list = rfc822_validlist($address)) {
615 my $array_count = shift(@address_list); 794 my $array_count = shift(@address_list);
616 while (my $entry = shift(@address_list)) { 795 while (my $entry = shift(@address_list)) {
617 push_email_address($entry); 796 push_email_address($entry, $role);
618 } 797 }
619 } else { 798 } else {
620 if (!push_email_address($address)) { 799 if (!push_email_address($address, $role)) {
621 warn("Invalid MAINTAINERS address: '" . $address . "'\n"); 800 warn("Invalid MAINTAINERS address: '" . $address . "'\n");
622 } 801 }
623 } 802 }
624} 803}
625 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
626sub which { 833sub which {
627 my ($bin) = @_; 834 my ($bin) = @_;
628 835
@@ -636,7 +843,7 @@ sub which {
636} 843}
637 844
638sub mailmap { 845sub mailmap {
639 my @lines = @_; 846 my (@lines) = @_;
640 my %hash; 847 my %hash;
641 848
642 foreach my $line (@lines) { 849 foreach my $line (@lines) {
@@ -645,14 +852,14 @@ sub mailmap {
645 $hash{$name} = $address; 852 $hash{$name} = $address;
646 } elsif ($address ne $hash{$name}) { 853 } elsif ($address ne $hash{$name}) {
647 $address = $hash{$name}; 854 $address = $hash{$name};
648 $line = format_email($name, $address); 855 $line = format_email($name, $address, $email_usename);
649 } 856 }
650 if (exists($mailmap{$name})) { 857 if (exists($mailmap{$name})) {
651 my $obj = $mailmap{$name}; 858 my $obj = $mailmap{$name};
652 foreach my $map_address (@$obj) { 859 foreach my $map_address (@$obj) {
653 if (($map_address eq $address) && 860 if (($map_address eq $address) &&
654 ($map_address ne $hash{$name})) { 861 ($map_address ne $hash{$name})) {
655 $line = format_email($name, $hash{$name}); 862 $line = format_email($name, $hash{$name}, $email_usename);
656 } 863 }
657 } 864 }
658 } 865 }
@@ -661,34 +868,38 @@ sub mailmap {
661 return @lines; 868 return @lines;
662} 869}
663 870
664sub recent_git_signoffs { 871sub git_execute_cmd {
665 my ($file) = @_; 872 my ($cmd) = @_;
666
667 my $sign_offs = "";
668 my $cmd = "";
669 my $output = "";
670 my $count = 0;
671 my @lines = (); 873 my @lines = ();
672 my %hash;
673 my $total_sign_offs;
674 874
675 if (which("git") eq "") { 875 my $output = `$cmd`;
676 warn("$P: git not found. Add --nogit to options?\n"); 876 $output =~ s/^\s*//gm;
677 return; 877 @lines = split("\n", $output);
678 }
679 if (!(-d ".git")) {
680 warn("$P: .git directory not found. Use a git repository for better results.\n");
681 warn("$P: perhaps 'git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git'\n");
682 return;
683 }
684 878
685 $cmd = "git log --since=${email_git_since} -- ${file}"; 879 return @lines;
880}
686 881
687 $output = `${cmd}`; 882sub hg_execute_cmd {
688 $output =~ s/^\s*//gm; 883 my ($cmd) = @_;
884 my @lines = ();
689 885
886 my $output = `$cmd`;
690 @lines = split("\n", $output); 887 @lines = split("\n", $output);
691 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
692 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); 903 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines);
693 if (!$email_git_penguin_chiefs) { 904 if (!$email_git_penguin_chiefs) {
694 @lines = grep(!/${penguin_chiefs}/i, @lines); 905 @lines = grep(!/${penguin_chiefs}/i, @lines);
@@ -696,111 +907,183 @@ sub recent_git_signoffs {
696 # cut -f2- -d":" 907 # cut -f2- -d":"
697 s/.*:\s*(.+)\s*/$1/ for (@lines); 908 s/.*:\s*(.+)\s*/$1/ for (@lines);
698 909
699 $total_sign_offs = @lines; 910## Reformat email addresses (with names) to avoid badly written signatures
700 911
701 if ($email_remove_duplicates) { 912 foreach my $line (@lines) {
702 @lines = mailmap(@lines); 913 my ($name, $address) = parse_email($line);
914 $line = format_email($name, $address, 1);
703 } 915 }
704 916
705 @lines = sort(@lines); 917 return ($commits, @lines);
706
707 # uniq -c
708 $hash{$_}++ for @lines;
709
710 # sort -rn
711 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
712 my $sign_offs = $hash{$line};
713 $count++;
714 last if ($sign_offs < $email_git_min_signatures ||
715 $count > $email_git_max_maintainers ||
716 $sign_offs * 100 / $total_sign_offs < $email_git_min_percent);
717 push_email_address($line);
718 }
719} 918}
720 919
721sub save_commits { 920sub vcs_save_commits {
722 my ($cmd, @commits) = @_; 921 my ($cmd) = @_;
723 my $output;
724 my @lines = (); 922 my @lines = ();
923 my @commits = ();
725 924
726 $output = `${cmd}`; 925 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
727 926
728 @lines = split("\n", $output);
729 foreach my $line (@lines) { 927 foreach my $line (@lines) {
730 if ($line =~ m/^(\w+) /) { 928 if ($line =~ m/$VCS_cmds{"blame_commit_pattern"}/) {
731 push (@commits, $1); 929 push(@commits, $1);
732 } 930 }
733 } 931 }
932
734 return @commits; 933 return @commits;
735} 934}
736 935
737sub git_assign_blame { 936sub vcs_blame {
738 my ($file) = @_; 937 my ($file) = @_;
739
740 my @lines = ();
741 my @commits = ();
742 my $cmd; 938 my $cmd;
743 my $output; 939 my @commits = ();
744 my %hash; 940
745 my $total_sign_offs; 941 return @commits if (!(-f $file));
746 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);
747 949
748 if (@range) {
749 foreach my $file_range_diff (@range) { 950 foreach my $file_range_diff (@range) {
750 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/)); 951 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
751 my $diff_file = $1; 952 my $diff_file = $1;
752 my $diff_start = $2; 953 my $diff_start = $2;
753 my $diff_length = $3; 954 my $diff_length = $3;
754 next if (!("$file" eq "$diff_file")); 955 next if ("$file" ne "$diff_file");
755 $cmd = "git blame -l -L $diff_start,+$diff_length $file"; 956 for (my $i = $diff_start; $i < $diff_start + $diff_length; $i++) {
756 @commits = save_commits($cmd, @commits); 957 push(@commits, $all_commits[$i]);
958 }
757 } 959 }
758 } else { 960 } elsif (@range) {
759 if (-f $file) { 961 foreach my $file_range_diff (@range) {
760 $cmd = "git blame -l $file"; 962 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
761 @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));
762 } 970 }
971 } else {
972 $cmd = $VCS_cmds{"blame_file_cmd"};
973 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
974 @commits = vcs_save_commits($cmd);
763 } 975 }
764 976
765 $total_sign_offs = 0; 977 return @commits;
766 @commits = uniq(@commits); 978}
767 foreach my $commit (@commits) {
768 $cmd = "git log -1 ${commit}";
769 979
770 $output = `${cmd}`; 980my $printed_novcs = 0;
771 $output =~ s/^\s*//gm; 981sub vcs_exists {
772 @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}
773 996
774 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); 997sub vcs_assign {
775 if (!$email_git_penguin_chiefs) { 998 my ($role, $divisor, @lines) = @_;
776 @lines = grep(!/${penguin_chiefs}/i, @lines);
777 }
778 999
779 # cut -f2- -d":" 1000 my %hash;
780 s/.*:\s*(.+)\s*/$1/ for (@lines); 1001 my $count = 0;
781 1002
782 $total_sign_offs += @lines; 1003 return if (@lines <= 0);
783 1004
784 if ($email_remove_duplicates) { 1005 if ($divisor <= 0) {
785 @lines = mailmap(@lines); 1006 warn("Bad divisor in " . (caller(0))[3] . ": $divisor\n");
786 } 1007 $divisor = 1;
1008 }
787 1009
788 $hash{$_}++ for @lines; 1010 if ($email_remove_duplicates) {
1011 @lines = mailmap(@lines);
789 } 1012 }
790 1013
791 $count = 0; 1014 @lines = sort(@lines);
1015
1016 # uniq -c
1017 $hash{$_}++ for @lines;
1018
1019 # sort -rn
792 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { 1020 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
793 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);
794 $count++; 1025 $count++;
795 last if ($sign_offs < $email_git_min_signatures || 1026 last if ($sign_offs < $email_git_min_signatures ||
796 $count > $email_git_max_maintainers || 1027 $count > $email_git_max_maintainers ||
797 $sign_offs * 100 / $total_sign_offs < $email_git_min_percent); 1028 $percent < $email_git_min_percent);
798 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);
799 } 1082 }
800} 1083}
801 1084
802sub uniq { 1085sub uniq {
803 my @parms = @_; 1086 my (@parms) = @_;
804 1087
805 my %saw; 1088 my %saw;
806 @parms = grep(!$saw{$_}++, @parms); 1089 @parms = grep(!$saw{$_}++, @parms);
@@ -808,7 +1091,7 @@ sub uniq {
808} 1091}
809 1092
810sub sort_and_uniq { 1093sub sort_and_uniq {
811 my @parms = @_; 1094 my (@parms) = @_;
812 1095
813 my %saw; 1096 my %saw;
814 @parms = sort @parms; 1097 @parms = sort @parms;
@@ -816,8 +1099,27 @@ sub sort_and_uniq {
816 return @parms; 1099 return @parms;
817} 1100}
818 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
819sub output { 1121sub output {
820 my @parms = @_; 1122 my (@parms) = @_;
821 1123
822 if ($output_multiline) { 1124 if ($output_multiline) {
823 foreach my $line (@parms) { 1125 foreach my $line (@parms) {
@@ -914,11 +1216,9 @@ sub rfc822_validlist ($) {
914 if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so && 1216 if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so &&
915 $s =~ m/^$rfc822_char*$/) { 1217 $s =~ m/^$rfc822_char*$/) {
916 while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) { 1218 while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) {
917 push @r, $1; 1219 push(@r, $1);
918 } 1220 }
919 return wantarray ? (scalar(@r), @r) : 1; 1221 return wantarray ? (scalar(@r), @r) : 1;
920 } 1222 }
921 else { 1223 return wantarray ? () : 0;
922 return wantarray ? () : 0;
923 }
924} 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/headers_install.pl b/scripts/headers_install.pl
index c6ae4052ab43..b89ca2c58fdb 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -20,7 +20,7 @@ use strict;
20 20
21my ($readdir, $installdir, $arch, @files) = @ARGV; 21my ($readdir, $installdir, $arch, @files) = @ARGV;
22 22
23my $unifdef = "scripts/unifdef -U__KERNEL__"; 23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
24 24
25foreach my $file (@files) { 25foreach my $file (@files) {
26 local *INFILE; 26 local *INFILE;
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 6d69c7ccdcc7..999e8a7d5bf7 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -27,10 +27,11 @@ 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
33 $(Q)perl $< $(Kconfig) > .tmp.config 34 $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
34 $(Q)if [ -f .config ]; then \ 35 $(Q)if [ -f .config ]; then \
35 cmp -s .tmp.config .config || \ 36 cmp -s .tmp.config .config || \
36 (mv -f .config .config.old.1; \ 37 (mv -f .config .config.old.1; \
@@ -44,7 +45,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
44 $(Q)rm -f .tmp.config 45 $(Q)rm -f .tmp.config
45 46
46localyesconfig: $(obj)/streamline_config.pl $(obj)/conf 47localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
47 $(Q)perl $< $(Kconfig) > .tmp.config 48 $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
48 $(Q)sed -i s/=m/=y/ .tmp.config 49 $(Q)sed -i s/=m/=y/ .tmp.config
49 $(Q)if [ -f .config ]; then \ 50 $(Q)if [ -f .config ]; then \
50 cmp -s .tmp.config .config || \ 51 cmp -s .tmp.config .config || \
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/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index dc3e81807d13..fdc7113b08d1 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -160,7 +160,15 @@ typedef unsigned int flex_uint32_t;
160 160
161/* Size of default input buffer. */ 161/* Size of default input buffer. */
162#ifndef YY_BUF_SIZE 162#ifndef YY_BUF_SIZE
163#ifdef __ia64__
164/* On IA-64, the buffer size is 16k, not 8k.
165 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
166 * Ditto for the __ia64__ case accordingly.
167 */
168#define YY_BUF_SIZE 32768
169#else
163#define YY_BUF_SIZE 16384 170#define YY_BUF_SIZE 16384
171#endif /* __ia64__ */
164#endif 172#endif
165 173
166/* The state buf must be large enough to hold one state per character in the main buffer. 174/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -802,7 +810,7 @@ static int last_ts, first_ts;
802static void zconf_endhelp(void); 810static void zconf_endhelp(void);
803static void zconf_endfile(void); 811static void zconf_endfile(void);
804 812
805void new_string(void) 813static void new_string(void)
806{ 814{
807 text = malloc(START_STRSIZE); 815 text = malloc(START_STRSIZE);
808 text_asize = START_STRSIZE; 816 text_asize = START_STRSIZE;
@@ -810,7 +818,7 @@ void new_string(void)
810 *text = 0; 818 *text = 0;
811} 819}
812 820
813void append_string(const char *str, int size) 821static void append_string(const char *str, int size)
814{ 822{
815 int new_size = text_size + size + 1; 823 int new_size = text_size + size + 1;
816 if (new_size > text_asize) { 824 if (new_size > text_asize) {
@@ -824,7 +832,7 @@ void append_string(const char *str, int size)
824 text[text_size] = 0; 832 text[text_size] = 0;
825} 833}
826 834
827void alloc_string(const char *str, int size) 835static void alloc_string(const char *str, int size)
828{ 836{
829 text = malloc(size + 1); 837 text = malloc(size + 1);
830 memcpy(text, str, size); 838 memcpy(text, str, size);
@@ -914,7 +922,12 @@ static int input (void );
914 922
915/* Amount of stuff to slurp up with each read. */ 923/* Amount of stuff to slurp up with each read. */
916#ifndef YY_READ_BUF_SIZE 924#ifndef YY_READ_BUF_SIZE
925#ifdef __ia64__
926/* On IA-64, the buffer size is 16k, not 8k */
927#define YY_READ_BUF_SIZE 16384
928#else
917#define YY_READ_BUF_SIZE 8192 929#define YY_READ_BUF_SIZE 8192
930#endif /* __ia64__ */
918#endif 931#endif
919 932
920/* Copy whatever the last rule matched to the standard output. */ 933/* Copy whatever the last rule matched to the standard output. */
@@ -922,7 +935,7 @@ static int input (void );
922/* This used to be an fputs(), but since the string might contain NUL's, 935/* This used to be an fputs(), but since the string might contain NUL's,
923 * we now use fwrite(). 936 * we now use fwrite().
924 */ 937 */
925#define ECHO fwrite( zconftext, zconfleng, 1, zconfout ) 938#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0)
926#endif 939#endif
927 940
928/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 941/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -2060,8 +2073,8 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
2060 2073
2061/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will 2074/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
2062 * scan from a @e copy of @a bytes. 2075 * scan from a @e copy of @a bytes.
2063 * @param bytes the byte buffer to scan 2076 * @param yybytes the byte buffer to scan
2064 * @param len the number of bytes in the buffer pointed to by @a bytes. 2077 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
2065 * 2078 *
2066 * @return the newly allocated buffer state object. 2079 * @return the newly allocated buffer state object.
2067 */ 2080 */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index d82953573588..8413cf38ed27 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -213,7 +213,7 @@ load_config_help[] = N_(
213 "to modify that configuration.\n" 213 "to modify that configuration.\n"
214 "\n" 214 "\n"
215 "If you are uncertain, then you have probably never used alternate\n" 215 "If you are uncertain, then you have probably never used alternate\n"
216 "configuration files. You should therefor leave this blank to abort.\n"), 216 "configuration files. You should therefore leave this blank to abort.\n"),
217save_config_text[] = N_( 217save_config_text[] = N_(
218 "Enter a filename to which this configuration should be saved " 218 "Enter a filename to which this configuration should be saved "
219 "as an alternate. Leave blank to abort."), 219 "as an alternate. Leave blank to abort."),
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index 95984db8e1e0..0d800820c3cd 100644
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -43,7 +43,6 @@
43# make oldconfig 43# make oldconfig
44# 44#
45my $config = ".config"; 45my $config = ".config";
46my $linuxpath = ".";
47 46
48my $uname = `uname -r`; 47my $uname = `uname -r`;
49chomp $uname; 48chomp $uname;
@@ -111,7 +110,11 @@ sub find_config {
111 110
112find_config; 111find_config;
113 112
114my @makefiles = `find $linuxpath -name Makefile`; 113# Get the build source and top level Kconfig file (passed in)
114my $ksource = $ARGV[0];
115my $kconfig = $ARGV[1];
116
117my @makefiles = `find $ksource -name Makefile`;
115my %depends; 118my %depends;
116my %selects; 119my %selects;
117my %prompts; 120my %prompts;
@@ -119,9 +122,6 @@ my %objects;
119my $var; 122my $var;
120my $cont = 0; 123my $cont = 0;
121 124
122# Get the top level Kconfig file (passed in)
123my $kconfig = $ARGV[0];
124
125# prevent recursion 125# prevent recursion
126my %read_kconfigs; 126my %read_kconfigs;
127 127
@@ -132,7 +132,7 @@ sub read_kconfig {
132 my $config; 132 my $config;
133 my @kconfigs; 133 my @kconfigs;
134 134
135 open(KIN, $kconfig) || die "Can't open $kconfig"; 135 open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig";
136 while (<KIN>) { 136 while (<KIN>) {
137 chomp; 137 chomp;
138 138
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index 25ef5d01c0af..d8bc74249622 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -9,6 +9,8 @@
9 9
10struct kconf_id; 10struct kconf_id;
11 11
12static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
13
12%% 14%%
13mainmenu, T_MAINMENU, TF_COMMAND 15mainmenu, T_MAINMENU, TF_COMMAND
14menu, T_MENU, TF_COMMAND 16menu, T_MENU, TF_COMMAND
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index 5c73d51339d8..c1748faf4634 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -30,6 +30,8 @@
30#endif 30#endif
31 31
32struct kconf_id; 32struct kconf_id;
33
34static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
33/* maximum key range = 47, duplicates = 0 */ 35/* maximum key range = 47, duplicates = 0 */
34 36
35#ifdef __GNUC__ 37#ifdef __GNUC__
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 21ff69c9ad4e..d8f7236cb0a3 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -39,7 +39,7 @@ static int last_ts, first_ts;
39static void zconf_endhelp(void); 39static void zconf_endhelp(void);
40static void zconf_endfile(void); 40static void zconf_endfile(void);
41 41
42void new_string(void) 42static void new_string(void)
43{ 43{
44 text = malloc(START_STRSIZE); 44 text = malloc(START_STRSIZE);
45 text_asize = START_STRSIZE; 45 text_asize = START_STRSIZE;
@@ -47,7 +47,7 @@ void new_string(void)
47 *text = 0; 47 *text = 0;
48} 48}
49 49
50void append_string(const char *str, int size) 50static void append_string(const char *str, int size)
51{ 51{
52 int new_size = text_size + size + 1; 52 int new_size = text_size + size + 1;
53 if (new_size > text_asize) { 53 if (new_size > text_asize) {
@@ -61,7 +61,7 @@ void append_string(const char *str, int size)
61 text[text_size] = 0; 61 text[text_size] = 0;
62} 62}
63 63
64void alloc_string(const char *str, int size) 64static void alloc_string(const char *str, int size)
65{ 65{
66 text = malloc(size + 1); 66 text = malloc(size + 1);
67 memcpy(text, str, size); 67 memcpy(text, str, size);
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 95df833b5a9d..6e9dcd59aa87 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,24 +1,23 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2 1
3/* Skeleton implementation for Bison's Yacc-like parsers in C 2/* A Bison parser, made by GNU Bison 2.4.1. */
4 3
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4/* Skeleton implementation for Bison's Yacc-like parsers in C
5
6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc. 7 Free Software Foundation, Inc.
7 8
8 This program is free software; you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option) 11 the Free Software Foundation, either version 3 of the License, or
11 any later version. 12 (at your option) any later version.
12 13
13 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 17 GNU General Public License for more details.
17 18
18 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22 21
23/* As a special exception, you may create a larger work that contains 22/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work 23 part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +28,7 @@
29 special exception, which will cause the skeleton and the resulting 28 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public 29 Bison output files to be licensed under the GNU General Public
31 License without this special exception. 30 License without this special exception.
32 31
33 This special exception was added by the Free Software Foundation in 32 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */ 33 version 2.2 of Bison. */
35 34
@@ -47,7 +46,7 @@
47#define YYBISON 1 46#define YYBISON 1
48 47
49/* Bison version. */ 48/* Bison version. */
50#define YYBISON_VERSION "2.3" 49#define YYBISON_VERSION "2.4.1"
51 50
52/* Skeleton name. */ 51/* Skeleton name. */
53#define YYSKELETON_NAME "yacc.c" 52#define YYSKELETON_NAME "yacc.c"
@@ -55,94 +54,23 @@
55/* Pure parsers. */ 54/* Pure parsers. */
56#define YYPURE 0 55#define YYPURE 0
57 56
57/* Push parsers. */
58#define YYPUSH 0
59
60/* Pull parsers. */
61#define YYPULL 1
62
58/* Using locations. */ 63/* Using locations. */
59#define YYLSP_NEEDED 0 64#define YYLSP_NEEDED 0
60 65
61/* Substitute the variable and function names. */ 66/* Substitute the variable and function names. */
62#define yyparse zconfparse 67#define yyparse zconfparse
63#define yylex zconflex 68#define yylex zconflex
64#define yyerror zconferror 69#define yyerror zconferror
65#define yylval zconflval 70#define yylval zconflval
66#define yychar zconfchar 71#define yychar zconfchar
67#define yydebug zconfdebug 72#define yydebug zconfdebug
68#define yynerrs zconfnerrs 73#define yynerrs zconfnerrs
69
70
71/* Tokens. */
72#ifndef YYTOKENTYPE
73# define YYTOKENTYPE
74 /* Put the tokens into the symbol table, so that GDB and other debuggers
75 know about them. */
76 enum yytokentype {
77 T_MAINMENU = 258,
78 T_MENU = 259,
79 T_ENDMENU = 260,
80 T_SOURCE = 261,
81 T_CHOICE = 262,
82 T_ENDCHOICE = 263,
83 T_COMMENT = 264,
84 T_CONFIG = 265,
85 T_MENUCONFIG = 266,
86 T_HELP = 267,
87 T_HELPTEXT = 268,
88 T_IF = 269,
89 T_ENDIF = 270,
90 T_DEPENDS = 271,
91 T_OPTIONAL = 272,
92 T_PROMPT = 273,
93 T_TYPE = 274,
94 T_DEFAULT = 275,
95 T_SELECT = 276,
96 T_RANGE = 277,
97 T_OPTION = 278,
98 T_ON = 279,
99 T_WORD = 280,
100 T_WORD_QUOTE = 281,
101 T_UNEQUAL = 282,
102 T_CLOSE_PAREN = 283,
103 T_OPEN_PAREN = 284,
104 T_EOL = 285,
105 T_OR = 286,
106 T_AND = 287,
107 T_EQUAL = 288,
108 T_NOT = 289
109 };
110#endif
111/* Tokens. */
112#define T_MAINMENU 258
113#define T_MENU 259
114#define T_ENDMENU 260
115#define T_SOURCE 261
116#define T_CHOICE 262
117#define T_ENDCHOICE 263
118#define T_COMMENT 264
119#define T_CONFIG 265
120#define T_MENUCONFIG 266
121#define T_HELP 267
122#define T_HELPTEXT 268
123#define T_IF 269
124#define T_ENDIF 270
125#define T_DEPENDS 271
126#define T_OPTIONAL 272
127#define T_PROMPT 273
128#define T_TYPE 274
129#define T_DEFAULT 275
130#define T_SELECT 276
131#define T_RANGE 277
132#define T_OPTION 278
133#define T_ON 279
134#define T_WORD 280
135#define T_WORD_QUOTE 281
136#define T_UNEQUAL 282
137#define T_CLOSE_PAREN 283
138#define T_OPEN_PAREN 284
139#define T_EOL 285
140#define T_OR 286
141#define T_AND 287
142#define T_EQUAL 288
143#define T_NOT 289
144
145
146 74
147 75
148/* Copy the first part of user declarations. */ 76/* Copy the first part of user declarations. */
@@ -163,8 +91,6 @@
163#define LKC_DIRECT_LINK 91#define LKC_DIRECT_LINK
164#include "lkc.h" 92#include "lkc.h"
165 93
166#include "zconf.hash.c"
167
168#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 94#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
169 95
170#define PRINTD 0x0001 96#define PRINTD 0x0001
@@ -188,6 +114,7 @@ static struct menu *current_menu, *current_entry;
188#endif 114#endif
189 115
190 116
117
191/* Enabling traces. */ 118/* Enabling traces. */
192#ifndef YYDEBUG 119#ifndef YYDEBUG
193# define YYDEBUG 0 120# define YYDEBUG 0
@@ -206,31 +133,77 @@ static struct menu *current_menu, *current_entry;
206# define YYTOKEN_TABLE 0 133# define YYTOKEN_TABLE 0
207#endif 134#endif
208 135
136
137/* Tokens. */
138#ifndef YYTOKENTYPE
139# define YYTOKENTYPE
140 /* Put the tokens into the symbol table, so that GDB and other debuggers
141 know about them. */
142 enum yytokentype {
143 T_MAINMENU = 258,
144 T_MENU = 259,
145 T_ENDMENU = 260,
146 T_SOURCE = 261,
147 T_CHOICE = 262,
148 T_ENDCHOICE = 263,
149 T_COMMENT = 264,
150 T_CONFIG = 265,
151 T_MENUCONFIG = 266,
152 T_HELP = 267,
153 T_HELPTEXT = 268,
154 T_IF = 269,
155 T_ENDIF = 270,
156 T_DEPENDS = 271,
157 T_OPTIONAL = 272,
158 T_PROMPT = 273,
159 T_TYPE = 274,
160 T_DEFAULT = 275,
161 T_SELECT = 276,
162 T_RANGE = 277,
163 T_OPTION = 278,
164 T_ON = 279,
165 T_WORD = 280,
166 T_WORD_QUOTE = 281,
167 T_UNEQUAL = 282,
168 T_CLOSE_PAREN = 283,
169 T_OPEN_PAREN = 284,
170 T_EOL = 285,
171 T_OR = 286,
172 T_AND = 287,
173 T_EQUAL = 288,
174 T_NOT = 289
175 };
176#endif
177
178
179
209#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 180#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
210typedef union YYSTYPE 181typedef union YYSTYPE
211
212{ 182{
183
184
213 char *string; 185 char *string;
214 struct file *file; 186 struct file *file;
215 struct symbol *symbol; 187 struct symbol *symbol;
216 struct expr *expr; 188 struct expr *expr;
217 struct menu *menu; 189 struct menu *menu;
218 struct kconf_id *id; 190 struct kconf_id *id;
219}
220/* Line 187 of yacc.c. */
221 191
222 YYSTYPE; 192
193
194} YYSTYPE;
195# define YYSTYPE_IS_TRIVIAL 1
223# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 196# define yystype YYSTYPE /* obsolescent; will be withdrawn */
224# define YYSTYPE_IS_DECLARED 1 197# define YYSTYPE_IS_DECLARED 1
225# define YYSTYPE_IS_TRIVIAL 1
226#endif 198#endif
227 199
228 200
229
230/* Copy the second part of user declarations. */ 201/* Copy the second part of user declarations. */
231 202
232 203
233/* Line 216 of yacc.c. */ 204/* Include zconf.hash.c here so it can see the token constants. */
205#include "zconf.hash.c"
206
234 207
235 208
236#ifdef short 209#ifdef short
@@ -306,14 +279,14 @@ typedef short int yytype_int16;
306#if (defined __STDC__ || defined __C99__FUNC__ \ 279#if (defined __STDC__ || defined __C99__FUNC__ \
307 || defined __cplusplus || defined _MSC_VER) 280 || defined __cplusplus || defined _MSC_VER)
308static int 281static int
309YYID (int i) 282YYID (int yyi)
310#else 283#else
311static int 284static int
312YYID (i) 285YYID (yyi)
313 int i; 286 int yyi;
314#endif 287#endif
315{ 288{
316 return i; 289 return yyi;
317} 290}
318#endif 291#endif
319 292
@@ -394,9 +367,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
394/* A type that is properly aligned for any stack member. */ 367/* A type that is properly aligned for any stack member. */
395union yyalloc 368union yyalloc
396{ 369{
397 yytype_int16 yyss; 370 yytype_int16 yyss_alloc;
398 YYSTYPE yyvs; 371 YYSTYPE yyvs_alloc;
399 }; 372};
400 373
401/* The size of the maximum gap between one aligned stack and the next. */ 374/* The size of the maximum gap between one aligned stack and the next. */
402# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) 375# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -430,12 +403,12 @@ union yyalloc
430 elements in the stack, and YYPTR gives the new location of the 403 elements in the stack, and YYPTR gives the new location of the
431 stack. Advance YYPTR to a properly aligned location for the next 404 stack. Advance YYPTR to a properly aligned location for the next
432 stack. */ 405 stack. */
433# define YYSTACK_RELOCATE(Stack) \ 406# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
434 do \ 407 do \
435 { \ 408 { \
436 YYSIZE_T yynewbytes; \ 409 YYSIZE_T yynewbytes; \
437 YYCOPY (&yyptr->Stack, Stack, yysize); \ 410 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
438 Stack = &yyptr->Stack; \ 411 Stack = &yyptr->Stack_alloc; \
439 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ 412 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
440 yyptr += yynewbytes / sizeof (*yyptr); \ 413 yyptr += yynewbytes / sizeof (*yyptr); \
441 } \ 414 } \
@@ -558,18 +531,18 @@ static const yytype_int8 yyrhs[] =
558/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 531/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
559static const yytype_uint16 yyrline[] = 532static const yytype_uint16 yyrline[] =
560{ 533{
561 0, 104, 104, 106, 108, 109, 110, 111, 112, 113, 534 0, 107, 107, 109, 111, 112, 113, 114, 115, 116,
562 114, 118, 122, 122, 122, 122, 122, 122, 122, 126, 535 117, 121, 125, 125, 125, 125, 125, 125, 125, 129,
563 127, 128, 129, 130, 131, 135, 136, 142, 150, 156, 536 130, 131, 132, 133, 134, 138, 139, 145, 153, 159,
564 164, 174, 176, 177, 178, 179, 180, 181, 184, 192, 537 167, 177, 179, 180, 181, 182, 183, 184, 187, 195,
565 198, 208, 214, 220, 223, 225, 236, 237, 242, 251, 538 201, 211, 217, 223, 226, 228, 239, 240, 245, 254,
566 256, 264, 267, 269, 270, 271, 272, 273, 276, 282, 539 259, 267, 270, 272, 273, 274, 275, 276, 279, 285,
567 293, 299, 309, 311, 316, 324, 332, 335, 337, 338, 540 296, 302, 312, 314, 319, 327, 335, 338, 340, 341,
568 339, 344, 351, 356, 364, 367, 369, 370, 371, 374, 541 342, 347, 354, 359, 367, 370, 372, 373, 374, 377,
569 382, 389, 396, 402, 409, 411, 412, 413, 416, 424, 542 385, 392, 399, 405, 412, 414, 415, 416, 419, 427,
570 426, 431, 432, 435, 436, 437, 441, 442, 445, 446, 543 429, 434, 435, 438, 439, 440, 444, 445, 448, 449,
571 449, 450, 451, 452, 453, 454, 455, 458, 459, 462, 544 452, 453, 454, 455, 456, 457, 458, 461, 462, 465,
572 463 545 466
573}; 546};
574#endif 547#endif
575 548
@@ -985,17 +958,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
985#if (defined __STDC__ || defined __C99__FUNC__ \ 958#if (defined __STDC__ || defined __C99__FUNC__ \
986 || defined __cplusplus || defined _MSC_VER) 959 || defined __cplusplus || defined _MSC_VER)
987static void 960static void
988yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) 961yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
989#else 962#else
990static void 963static void
991yy_stack_print (bottom, top) 964yy_stack_print (yybottom, yytop)
992 yytype_int16 *bottom; 965 yytype_int16 *yybottom;
993 yytype_int16 *top; 966 yytype_int16 *yytop;
994#endif 967#endif
995{ 968{
996 YYFPRINTF (stderr, "Stack now"); 969 YYFPRINTF (stderr, "Stack now");
997 for (; bottom <= top; ++bottom) 970 for (; yybottom <= yytop; yybottom++)
998 YYFPRINTF (stderr, " %d", *bottom); 971 {
972 int yybot = *yybottom;
973 YYFPRINTF (stderr, " %d", yybot);
974 }
999 YYFPRINTF (stderr, "\n"); 975 YYFPRINTF (stderr, "\n");
1000} 976}
1001 977
@@ -1029,11 +1005,11 @@ yy_reduce_print (yyvsp, yyrule)
1029 /* The symbols being reduced. */ 1005 /* The symbols being reduced. */
1030 for (yyi = 0; yyi < yynrhs; yyi++) 1006 for (yyi = 0; yyi < yynrhs; yyi++)
1031 { 1007 {
1032 fprintf (stderr, " $%d = ", yyi + 1); 1008 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1033 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], 1009 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1034 &(yyvsp[(yyi + 1) - (yynrhs)]) 1010 &(yyvsp[(yyi + 1) - (yynrhs)])
1035 ); 1011 );
1036 fprintf (stderr, "\n"); 1012 YYFPRINTF (stderr, "\n");
1037 } 1013 }
1038} 1014}
1039 1015
@@ -1343,10 +1319,8 @@ yydestruct (yymsg, yytype, yyvaluep)
1343 break; 1319 break;
1344 } 1320 }
1345} 1321}
1346
1347 1322
1348/* Prevent warnings from -Wmissing-prototypes. */ 1323/* Prevent warnings from -Wmissing-prototypes. */
1349
1350#ifdef YYPARSE_PARAM 1324#ifdef YYPARSE_PARAM
1351#if defined __STDC__ || defined __cplusplus 1325#if defined __STDC__ || defined __cplusplus
1352int yyparse (void *YYPARSE_PARAM); 1326int yyparse (void *YYPARSE_PARAM);
@@ -1362,11 +1336,10 @@ int yyparse ();
1362#endif /* ! YYPARSE_PARAM */ 1336#endif /* ! YYPARSE_PARAM */
1363 1337
1364 1338
1365 1339/* The lookahead symbol. */
1366/* The look-ahead symbol. */
1367int yychar; 1340int yychar;
1368 1341
1369/* The semantic value of the look-ahead symbol. */ 1342/* The semantic value of the lookahead symbol. */
1370YYSTYPE yylval; 1343YYSTYPE yylval;
1371 1344
1372/* Number of syntax errors so far. */ 1345/* Number of syntax errors so far. */
@@ -1374,9 +1347,9 @@ int yynerrs;
1374 1347
1375 1348
1376 1349
1377/*----------. 1350/*-------------------------.
1378| yyparse. | 1351| yyparse or yypush_parse. |
1379`----------*/ 1352`-------------------------*/
1380 1353
1381#ifdef YYPARSE_PARAM 1354#ifdef YYPARSE_PARAM
1382#if (defined __STDC__ || defined __C99__FUNC__ \ 1355#if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1400,66 +1373,68 @@ yyparse ()
1400#endif 1373#endif
1401#endif 1374#endif
1402{ 1375{
1403
1404 int yystate;
1405 int yyn;
1406 int yyresult;
1407 /* Number of tokens to shift before error messages enabled. */
1408 int yyerrstatus;
1409 /* Look-ahead token as an internal (translated) token number. */
1410 int yytoken = 0;
1411#if YYERROR_VERBOSE
1412 /* Buffer for error messages, and its allocated size. */
1413 char yymsgbuf[128];
1414 char *yymsg = yymsgbuf;
1415 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1416#endif
1417
1418 /* Three stacks and their tools:
1419 `yyss': related to states,
1420 `yyvs': related to semantic values,
1421 `yyls': related to locations.
1422 1376
1423 Refer to the stacks thru separate pointers, to allow yyoverflow
1424 to reallocate them elsewhere. */
1425 1377
1426 /* The state stack. */ 1378 int yystate;
1427 yytype_int16 yyssa[YYINITDEPTH]; 1379 /* Number of tokens to shift before error messages enabled. */
1428 yytype_int16 *yyss = yyssa; 1380 int yyerrstatus;
1429 yytype_int16 *yyssp;
1430 1381
1431 /* The semantic value stack. */ 1382 /* The stacks and their tools:
1432 YYSTYPE yyvsa[YYINITDEPTH]; 1383 `yyss': related to states.
1433 YYSTYPE *yyvs = yyvsa; 1384 `yyvs': related to semantic values.
1434 YYSTYPE *yyvsp;
1435 1385
1386 Refer to the stacks thru separate pointers, to allow yyoverflow
1387 to reallocate them elsewhere. */
1436 1388
1389 /* The state stack. */
1390 yytype_int16 yyssa[YYINITDEPTH];
1391 yytype_int16 *yyss;
1392 yytype_int16 *yyssp;
1437 1393
1438#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) 1394 /* The semantic value stack. */
1395 YYSTYPE yyvsa[YYINITDEPTH];
1396 YYSTYPE *yyvs;
1397 YYSTYPE *yyvsp;
1439 1398
1440 YYSIZE_T yystacksize = YYINITDEPTH; 1399 YYSIZE_T yystacksize;
1441 1400
1401 int yyn;
1402 int yyresult;
1403 /* Lookahead token as an internal (translated) token number. */
1404 int yytoken;
1442 /* The variables used to return semantic value and location from the 1405 /* The variables used to return semantic value and location from the
1443 action routines. */ 1406 action routines. */
1444 YYSTYPE yyval; 1407 YYSTYPE yyval;
1445 1408
1409#if YYERROR_VERBOSE
1410 /* Buffer for error messages, and its allocated size. */
1411 char yymsgbuf[128];
1412 char *yymsg = yymsgbuf;
1413 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1414#endif
1415
1416#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1446 1417
1447 /* The number of symbols on the RHS of the reduced rule. 1418 /* The number of symbols on the RHS of the reduced rule.
1448 Keep to zero when no symbol should be popped. */ 1419 Keep to zero when no symbol should be popped. */
1449 int yylen = 0; 1420 int yylen = 0;
1450 1421
1422 yytoken = 0;
1423 yyss = yyssa;
1424 yyvs = yyvsa;
1425 yystacksize = YYINITDEPTH;
1426
1451 YYDPRINTF ((stderr, "Starting parse\n")); 1427 YYDPRINTF ((stderr, "Starting parse\n"));
1452 1428
1453 yystate = 0; 1429 yystate = 0;
1454 yyerrstatus = 0; 1430 yyerrstatus = 0;
1455 yynerrs = 0; 1431 yynerrs = 0;
1456 yychar = YYEMPTY; /* Cause a token to be read. */ 1432 yychar = YYEMPTY; /* Cause a token to be read. */
1457 1433
1458 /* Initialize stack pointers. 1434 /* Initialize stack pointers.
1459 Waste one element of value and location stack 1435 Waste one element of value and location stack
1460 so that they stay on the same level as the state stack. 1436 so that they stay on the same level as the state stack.
1461 The wasted elements are never initialized. */ 1437 The wasted elements are never initialized. */
1462
1463 yyssp = yyss; 1438 yyssp = yyss;
1464 yyvsp = yyvs; 1439 yyvsp = yyvs;
1465 1440
@@ -1489,7 +1464,6 @@ yyparse ()
1489 YYSTYPE *yyvs1 = yyvs; 1464 YYSTYPE *yyvs1 = yyvs;
1490 yytype_int16 *yyss1 = yyss; 1465 yytype_int16 *yyss1 = yyss;
1491 1466
1492
1493 /* Each stack pointer address is followed by the size of the 1467 /* Each stack pointer address is followed by the size of the
1494 data in use in that stack, in bytes. This used to be a 1468 data in use in that stack, in bytes. This used to be a
1495 conditional around just the two extra args, but that might 1469 conditional around just the two extra args, but that might
@@ -1497,7 +1471,6 @@ yyparse ()
1497 yyoverflow (YY_("memory exhausted"), 1471 yyoverflow (YY_("memory exhausted"),
1498 &yyss1, yysize * sizeof (*yyssp), 1472 &yyss1, yysize * sizeof (*yyssp),
1499 &yyvs1, yysize * sizeof (*yyvsp), 1473 &yyvs1, yysize * sizeof (*yyvsp),
1500
1501 &yystacksize); 1474 &yystacksize);
1502 1475
1503 yyss = yyss1; 1476 yyss = yyss1;
@@ -1520,9 +1493,8 @@ yyparse ()
1520 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1493 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1521 if (! yyptr) 1494 if (! yyptr)
1522 goto yyexhaustedlab; 1495 goto yyexhaustedlab;
1523 YYSTACK_RELOCATE (yyss); 1496 YYSTACK_RELOCATE (yyss_alloc, yyss);
1524 YYSTACK_RELOCATE (yyvs); 1497 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1525
1526# undef YYSTACK_RELOCATE 1498# undef YYSTACK_RELOCATE
1527 if (yyss1 != yyssa) 1499 if (yyss1 != yyssa)
1528 YYSTACK_FREE (yyss1); 1500 YYSTACK_FREE (yyss1);
@@ -1533,7 +1505,6 @@ yyparse ()
1533 yyssp = yyss + yysize - 1; 1505 yyssp = yyss + yysize - 1;
1534 yyvsp = yyvs + yysize - 1; 1506 yyvsp = yyvs + yysize - 1;
1535 1507
1536
1537 YYDPRINTF ((stderr, "Stack size increased to %lu\n", 1508 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1538 (unsigned long int) yystacksize)); 1509 (unsigned long int) yystacksize));
1539 1510
@@ -1543,6 +1514,9 @@ yyparse ()
1543 1514
1544 YYDPRINTF ((stderr, "Entering state %d\n", yystate)); 1515 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1545 1516
1517 if (yystate == YYFINAL)
1518 YYACCEPT;
1519
1546 goto yybackup; 1520 goto yybackup;
1547 1521
1548/*-----------. 1522/*-----------.
@@ -1551,16 +1525,16 @@ yyparse ()
1551yybackup: 1525yybackup:
1552 1526
1553 /* Do appropriate processing given the current state. Read a 1527 /* Do appropriate processing given the current state. Read a
1554 look-ahead token if we need one and don't already have one. */ 1528 lookahead token if we need one and don't already have one. */
1555 1529
1556 /* First try to decide what to do without reference to look-ahead token. */ 1530 /* First try to decide what to do without reference to lookahead token. */
1557 yyn = yypact[yystate]; 1531 yyn = yypact[yystate];
1558 if (yyn == YYPACT_NINF) 1532 if (yyn == YYPACT_NINF)
1559 goto yydefault; 1533 goto yydefault;
1560 1534
1561 /* Not known => get a look-ahead token if don't already have one. */ 1535 /* Not known => get a lookahead token if don't already have one. */
1562 1536
1563 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ 1537 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1564 if (yychar == YYEMPTY) 1538 if (yychar == YYEMPTY)
1565 { 1539 {
1566 YYDPRINTF ((stderr, "Reading a token: ")); 1540 YYDPRINTF ((stderr, "Reading a token: "));
@@ -1592,20 +1566,16 @@ yybackup:
1592 goto yyreduce; 1566 goto yyreduce;
1593 } 1567 }
1594 1568
1595 if (yyn == YYFINAL)
1596 YYACCEPT;
1597
1598 /* Count tokens shifted since error; after three, turn off error 1569 /* Count tokens shifted since error; after three, turn off error
1599 status. */ 1570 status. */
1600 if (yyerrstatus) 1571 if (yyerrstatus)
1601 yyerrstatus--; 1572 yyerrstatus--;
1602 1573
1603 /* Shift the look-ahead token. */ 1574 /* Shift the lookahead token. */
1604 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); 1575 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1605 1576
1606 /* Discard the shifted token unless it is eof. */ 1577 /* Discard the shifted token. */
1607 if (yychar != YYEOF) 1578 yychar = YYEMPTY;
1608 yychar = YYEMPTY;
1609 1579
1610 yystate = yyn; 1580 yystate = yyn;
1611 *++yyvsp = yylval; 1581 *++yyvsp = yylval;
@@ -2029,7 +1999,6 @@ yyreduce:
2029 break; 1999 break;
2030 2000
2031 2001
2032/* Line 1267 of yacc.c. */
2033 2002
2034 default: break; 2003 default: break;
2035 } 2004 }
@@ -2041,7 +2010,6 @@ yyreduce:
2041 2010
2042 *++yyvsp = yyval; 2011 *++yyvsp = yyval;
2043 2012
2044
2045 /* Now `shift' the result of the reduction. Determine what state 2013 /* Now `shift' the result of the reduction. Determine what state
2046 that goes to, based on the state we popped back to and the rule 2014 that goes to, based on the state we popped back to and the rule
2047 number reduced by. */ 2015 number reduced by. */
@@ -2106,7 +2074,7 @@ yyerrlab:
2106 2074
2107 if (yyerrstatus == 3) 2075 if (yyerrstatus == 3)
2108 { 2076 {
2109 /* If just tried and failed to reuse look-ahead token after an 2077 /* If just tried and failed to reuse lookahead token after an
2110 error, discard it. */ 2078 error, discard it. */
2111 2079
2112 if (yychar <= YYEOF) 2080 if (yychar <= YYEOF)
@@ -2123,7 +2091,7 @@ yyerrlab:
2123 } 2091 }
2124 } 2092 }
2125 2093
2126 /* Else will try to reuse look-ahead token after shifting the error 2094 /* Else will try to reuse lookahead token after shifting the error
2127 token. */ 2095 token. */
2128 goto yyerrlab1; 2096 goto yyerrlab1;
2129 2097
@@ -2180,9 +2148,6 @@ yyerrlab1:
2180 YY_STACK_PRINT (yyss, yyssp); 2148 YY_STACK_PRINT (yyss, yyssp);
2181 } 2149 }
2182 2150
2183 if (yyn == YYFINAL)
2184 YYACCEPT;
2185
2186 *++yyvsp = yylval; 2151 *++yyvsp = yylval;
2187 2152
2188 2153
@@ -2207,7 +2172,7 @@ yyabortlab:
2207 yyresult = 1; 2172 yyresult = 1;
2208 goto yyreturn; 2173 goto yyreturn;
2209 2174
2210#ifndef yyoverflow 2175#if !defined(yyoverflow) || YYERROR_VERBOSE
2211/*-------------------------------------------------. 2176/*-------------------------------------------------.
2212| yyexhaustedlab -- memory exhaustion comes here. | 2177| yyexhaustedlab -- memory exhaustion comes here. |
2213`-------------------------------------------------*/ 2178`-------------------------------------------------*/
@@ -2218,7 +2183,7 @@ yyexhaustedlab:
2218#endif 2183#endif
2219 2184
2220yyreturn: 2185yyreturn:
2221 if (yychar != YYEOF && yychar != YYEMPTY) 2186 if (yychar != YYEMPTY)
2222 yydestruct ("Cleanup: discarding lookahead", 2187 yydestruct ("Cleanup: discarding lookahead",
2223 yytoken, &yylval); 2188 yytoken, &yylval);
2224 /* Do not reclaim the symbols of the rule which action triggered 2189 /* Do not reclaim the symbols of the rule which action triggered
@@ -2284,7 +2249,7 @@ void conf_parse(const char *name)
2284 sym_set_change_count(1); 2249 sym_set_change_count(1);
2285} 2250}
2286 2251
2287const char *zconf_tokenname(int token) 2252static const char *zconf_tokenname(int token)
2288{ 2253{
2289 switch (token) { 2254 switch (token) {
2290 case T_MENU: return "menu"; 2255 case T_MENU: return "menu";
@@ -2348,7 +2313,7 @@ static void zconferror(const char *err)
2348#endif 2313#endif
2349} 2314}
2350 2315
2351void print_quoted_string(FILE *out, const char *str) 2316static void print_quoted_string(FILE *out, const char *str)
2352{ 2317{
2353 const char *p; 2318 const char *p;
2354 int len; 2319 int len;
@@ -2365,7 +2330,7 @@ void print_quoted_string(FILE *out, const char *str)
2365 putc('"', out); 2330 putc('"', out);
2366} 2331}
2367 2332
2368void print_symbol(FILE *out, struct menu *menu) 2333static void print_symbol(FILE *out, struct menu *menu)
2369{ 2334{
2370 struct symbol *sym = menu->sym; 2335 struct symbol *sym = menu->sym;
2371 struct property *prop; 2336 struct property *prop;
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 9710b82466f2..8c43491f8cc9 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -14,8 +14,6 @@
14#define LKC_DIRECT_LINK 14#define LKC_DIRECT_LINK
15#include "lkc.h" 15#include "lkc.h"
16 16
17#include "zconf.hash.c"
18
19#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 17#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
20 18
21#define PRINTD 0x0001 19#define PRINTD 0x0001
@@ -100,6 +98,11 @@ static struct menu *current_menu, *current_entry;
100 menu_end_menu(); 98 menu_end_menu();
101} if_entry menu_entry choice_entry 99} if_entry menu_entry choice_entry
102 100
101%{
102/* Include zconf.hash.c here so it can see the token constants. */
103#include "zconf.hash.c"
104%}
105
103%% 106%%
104input: stmt_list; 107input: stmt_list;
105 108
@@ -501,7 +504,7 @@ void conf_parse(const char *name)
501 sym_set_change_count(1); 504 sym_set_change_count(1);
502} 505}
503 506
504const char *zconf_tokenname(int token) 507static const char *zconf_tokenname(int token)
505{ 508{
506 switch (token) { 509 switch (token) {
507 case T_MENU: return "menu"; 510 case T_MENU: return "menu";
@@ -565,7 +568,7 @@ static void zconferror(const char *err)
565#endif 568#endif
566} 569}
567 570
568void print_quoted_string(FILE *out, const char *str) 571static void print_quoted_string(FILE *out, const char *str)
569{ 572{
570 const char *p; 573 const char *p;
571 int len; 574 int len;
@@ -582,7 +585,7 @@ void print_quoted_string(FILE *out, const char *str)
582 putc('"', out); 585 putc('"', out);
583} 586}
584 587
585void print_symbol(FILE *out, struct menu *menu) 588static void print_symbol(FILE *out, struct menu *menu)
586{ 589{
587 struct symbol *sym = menu->sym; 590 struct symbol *sym = menu->sym;
588 struct property *prop; 591 struct property *prop;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index ea9f8a58678f..241310e59cd6 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1852,10 +1852,17 @@ sub tracepoint_munge($) {
1852 my $tracepointname = 0; 1852 my $tracepointname = 0;
1853 my $tracepointargs = 0; 1853 my $tracepointargs = 0;
1854 1854
1855 if($prototype =~ m/TRACE_EVENT\((.*?),/) { 1855 if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
1856 $tracepointname = $1; 1856 $tracepointname = $1;
1857 } 1857 }
1858 if($prototype =~ m/TP_PROTO\((.*?)\)/) { 1858 if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
1859 $tracepointname = $1;
1860 }
1861 if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
1862 $tracepointname = $2;
1863 }
1864 $tracepointname =~ s/^\s+//; #strip leading whitespace
1865 if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
1859 $tracepointargs = $1; 1866 $tracepointargs = $1;
1860 } 1867 }
1861 if (($tracepointname eq 0) || ($tracepointargs eq 0)) { 1868 if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
@@ -1920,7 +1927,9 @@ sub process_state3_function($$) {
1920 if ($prototype =~ /SYSCALL_DEFINE/) { 1927 if ($prototype =~ /SYSCALL_DEFINE/) {
1921 syscall_munge(); 1928 syscall_munge();
1922 } 1929 }
1923 if ($prototype =~ /TRACE_EVENT/) { 1930 if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
1931 $prototype =~ /DEFINE_SINGLE_EVENT/)
1932 {
1924 tracepoint_munge($file); 1933 tracepoint_munge($file);
1925 } 1934 }
1926 dump_function($prototype, $file); 1935 dump_function($prototype, $file);
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index 5f0fcb712e29..e950f9cde019 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -154,11 +154,11 @@ 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 }
161 if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { 161 if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+0x([0-9a-f]+)\/0x[a-f0-9]/) {
162 $function = $1; 162 $function = $1;
163 $func_offset = $2; 163 $func_offset = $2;
164 } 164 }
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 6a12dd9f1181..23dbad80cce9 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -1,3 +1,5 @@
1#!/bin/sh
2
1TARGET=$1 3TARGET=$1
2ARCH=$2 4ARCH=$2
3SMP=$3 5SMP=$3
@@ -12,7 +14,7 @@ vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }
12# So "sudo make install" won't change the "compiled by <user>" 14# So "sudo make install" won't change the "compiled by <user>"
13# do "compiled by root" 15# do "compiled by root"
14 16
15if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then 17if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then
16 vecho " SKIPPED $TARGET" 18 vecho " SKIPPED $TARGET"
17 exit 0 19 exit 0
18fi 20fi
@@ -50,7 +52,7 @@ UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP"
50# Truncate to maximum length 52# Truncate to maximum length
51 53
52UTS_LEN=64 54UTS_LEN=64
53UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" 55UTS_TRUNCATE="cut -b -$UTS_LEN"
54 56
55# Generate a temporary compile.h 57# Generate a temporary compile.h
56 58
@@ -66,9 +68,13 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
66 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" 68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
67 69
68 if [ -x /bin/dnsdomainname ]; then 70 if [ -x /bin/dnsdomainname ]; then
69 echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname | $UTS_TRUNCATE`\" 71 domain=`dnsdomainname 2> /dev/null`
70 elif [ -x /bin/domainname ]; then 72 elif [ -x /bin/domainname ]; then
71 echo \#define LINUX_COMPILE_DOMAIN \"`domainname | $UTS_TRUNCATE`\" 73 domain=`domainname 2> /dev/null`
74 fi
75
76 if [ -n "$domain" ]; then
77 echo \#define LINUX_COMPILE_DOMAIN \"`echo $domain | $UTS_TRUNCATE`\"
72 else 78 else
73 echo \#define LINUX_COMPILE_DOMAIN 79 echo \#define LINUX_COMPILE_DOMAIN
74 fi 80 fi
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 62a9025cdcc7..220213e603db 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -104,7 +104,7 @@ static void device_id_check(const char *modname, const char *device_id,
104static void do_usb_entry(struct usb_device_id *id, 104static void do_usb_entry(struct usb_device_id *id,
105 unsigned int bcdDevice_initial, int bcdDevice_initial_digits, 105 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
106 unsigned char range_lo, unsigned char range_hi, 106 unsigned char range_lo, unsigned char range_hi,
107 struct module *mod) 107 unsigned char max, struct module *mod)
108{ 108{
109 char alias[500]; 109 char alias[500];
110 strcpy(alias, "usb:"); 110 strcpy(alias, "usb:");
@@ -118,9 +118,22 @@ static void do_usb_entry(struct usb_device_id *id,
118 sprintf(alias + strlen(alias), "%0*X", 118 sprintf(alias + strlen(alias), "%0*X",
119 bcdDevice_initial_digits, bcdDevice_initial); 119 bcdDevice_initial_digits, bcdDevice_initial);
120 if (range_lo == range_hi) 120 if (range_lo == range_hi)
121 sprintf(alias + strlen(alias), "%u", range_lo); 121 sprintf(alias + strlen(alias), "%X", range_lo);
122 else if (range_lo > 0 || range_hi < 9) 122 else if (range_lo > 0 || range_hi < max) {
123 sprintf(alias + strlen(alias), "[%u-%u]", range_lo, range_hi); 123 if (range_lo > 0x9 || range_hi < 0xA)
124 sprintf(alias + strlen(alias),
125 "[%X-%X]",
126 range_lo,
127 range_hi);
128 else {
129 sprintf(alias + strlen(alias),
130 range_lo < 0x9 ? "[%X-9" : "[%X",
131 range_lo);
132 sprintf(alias + strlen(alias),
133 range_hi > 0xA ? "a-%X]" : "%X]",
134 range_lo);
135 }
136 }
124 if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1)) 137 if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
125 strcat(alias, "*"); 138 strcat(alias, "*");
126 139
@@ -147,10 +160,49 @@ static void do_usb_entry(struct usb_device_id *id,
147 "MODULE_ALIAS(\"%s\");\n", alias); 160 "MODULE_ALIAS(\"%s\");\n", alias);
148} 161}
149 162
163/* Handles increment/decrement of BCD formatted integers */
164/* Returns the previous value, so it works like i++ or i-- */
165static unsigned int incbcd(unsigned int *bcd,
166 int inc,
167 unsigned char max,
168 size_t chars)
169{
170 unsigned int init = *bcd, i, j;
171 unsigned long long c, dec = 0;
172
173 /* If bcd is not in BCD format, just increment */
174 if (max > 0x9) {
175 *bcd += inc;
176 return init;
177 }
178
179 /* Convert BCD to Decimal */
180 for (i=0 ; i < chars ; i++) {
181 c = (*bcd >> (i << 2)) & 0xf;
182 c = c > 9 ? 9 : c; /* force to bcd just in case */
183 for (j=0 ; j < i ; j++)
184 c = c * 10;
185 dec += c;
186 }
187
188 /* Do our increment/decrement */
189 dec += inc;
190 *bcd = 0;
191
192 /* Convert back to BCD */
193 for (i=0 ; i < chars ; i++) {
194 for (c=1,j=0 ; j < i ; j++)
195 c = c * 10;
196 c = (dec / c) % 10;
197 *bcd += c << (i << 2);
198 }
199 return init;
200}
201
150static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) 202static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
151{ 203{
152 unsigned int devlo, devhi; 204 unsigned int devlo, devhi;
153 unsigned char chi, clo; 205 unsigned char chi, clo, max;
154 int ndigits; 206 int ndigits;
155 207
156 id->match_flags = TO_NATIVE(id->match_flags); 208 id->match_flags = TO_NATIVE(id->match_flags);
@@ -162,6 +214,17 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
162 devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ? 214 devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
163 TO_NATIVE(id->bcdDevice_hi) : ~0x0U; 215 TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
164 216
217 /* Figure out if this entry is in bcd or hex format */
218 max = 0x9; /* Default to decimal format */
219 for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) {
220 clo = (devlo >> (ndigits << 2)) & 0xf;
221 chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf;
222 if (clo > max || chi > max) {
223 max = 0xf;
224 break;
225 }
226 }
227
165 /* 228 /*
166 * Some modules (visor) have empty slots as placeholder for 229 * Some modules (visor) have empty slots as placeholder for
167 * run-time specification that results in catch-all alias 230 * run-time specification that results in catch-all alias
@@ -173,21 +236,27 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
173 for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) { 236 for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
174 clo = devlo & 0xf; 237 clo = devlo & 0xf;
175 chi = devhi & 0xf; 238 chi = devhi & 0xf;
176 if (chi > 9) /* it's bcd not hex */ 239 if (chi > max) /* If we are in bcd mode, truncate if necessary */
177 chi = 9; 240 chi = max;
178 devlo >>= 4; 241 devlo >>= 4;
179 devhi >>= 4; 242 devhi >>= 4;
180 243
181 if (devlo == devhi || !ndigits) { 244 if (devlo == devhi || !ndigits) {
182 do_usb_entry(id, devlo, ndigits, clo, chi, mod); 245 do_usb_entry(id, devlo, ndigits, clo, chi, max, mod);
183 break; 246 break;
184 } 247 }
185 248
186 if (clo > 0) 249 if (clo > 0x0)
187 do_usb_entry(id, devlo++, ndigits, clo, 9, mod); 250 do_usb_entry(id,
188 251 incbcd(&devlo, 1, max,
189 if (chi < 9) 252 sizeof(id->bcdDevice_lo) * 2),
190 do_usb_entry(id, devhi--, ndigits, 0, chi, mod); 253 ndigits, clo, max, max, mod);
254
255 if (chi < max)
256 do_usb_entry(id,
257 incbcd(&devhi, -1, max,
258 sizeof(id->bcdDevice_lo) * 2),
259 ndigits, 0x0, chi, max, mod);
191 } 260 }
192} 261}
193 262
@@ -735,7 +804,7 @@ static inline int sym_is(const char *symbol, const char *name)
735 match = strstr(symbol, name); 804 match = strstr(symbol, name);
736 if (!match) 805 if (!match)
737 return 0; 806 return 0;
738 return match[strlen(symbol)] == '\0'; 807 return match[strlen(name)] == '\0';
739} 808}
740 809
741static 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 fa4a0a17b7e0..62fcc3a7f4d3 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -18,6 +18,9 @@
18# e) generate the rpm files, based on kernel.spec 18# e) generate the rpm files, based on kernel.spec
19# - Use /. to avoid tar packing just the symlink 19# - Use /. to avoid tar packing just the symlink
20 20
21# Note that the rpm-pkg target cannot be used with KBUILD_OUTPUT,
22# but the binrpm-pkg target can; for some reason O= gets ignored.
23
21# Do we have rpmbuild, otherwise fall back to the older rpm 24# Do we have rpmbuild, otherwise fall back to the older rpm
22RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ 25RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
23 else echo rpm; fi) 26 else echo rpm; fi)
@@ -33,6 +36,12 @@ $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
33 $(CONFIG_SHELL) $(MKSPEC) > $@ 36 $(CONFIG_SHELL) $(MKSPEC) > $@
34 37
35rpm-pkg rpm: $(objtree)/kernel.spec FORCE 38rpm-pkg rpm: $(objtree)/kernel.spec FORCE
39 @if test -n "$(KBUILD_OUTPUT)"; then \
40 echo "Building source + binary RPM is not possible outside the"; \
41 echo "kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \
42 echo "binrpm-pkg target instead."; \
43 false; \
44 fi
36 $(MAKE) clean 45 $(MAKE) clean
37 $(PREV) ln -sf $(srctree) $(KERNELPATH) 46 $(PREV) ln -sf $(srctree) $(KERNELPATH)
38 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion 47 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion
@@ -61,16 +70,34 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE
61 set -e; \ 70 set -e; \
62 mv -f $(objtree)/.tmp_version $(objtree)/.version 71 mv -f $(objtree)/.tmp_version $(objtree)/.version
63 72
64 $(RPM) $(RPMOPTS) --define "_builddir $(srctree)" --target \ 73 $(RPM) $(RPMOPTS) --define "_builddir $(objtree)" --target \
65 $(UTS_MACHINE) -bb $< 74 $(UTS_MACHINE) -bb $<
66 75
67clean-files += $(objtree)/binkernel.spec 76clean-files += $(objtree)/binkernel.spec
68 77
69# Deb target 78# Deb target
70# --------------------------------------------------------------------------- 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
71deb-pkg: FORCE 98deb-pkg: FORCE
72 $(MAKE) KBUILD_SRC= 99 $(MAKE) KBUILD_SRC=
73 $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb 100 $(call cmd,builddeb)
74 101
75clean-dirs += $(objtree)/debian/ 102clean-dirs += $(objtree)/debian/
76 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/package/mkspec b/scripts/package/mkspec
index 3d93f8c81252..47bdd2f99b78 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -70,7 +70,7 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware' 70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
71echo "%endif" 71echo "%endif"
72 72
73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install' 73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} KBUILD_SRC= modules_install'
74echo "%ifarch ia64" 74echo "%ifarch ia64"
75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" 75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" 76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 090d300d7394..ea6f6e3adaea 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -6,77 +6,93 @@
6# all the offsets to the calls to mcount. 6# all the offsets to the calls to mcount.
7# 7#
8# 8#
9# What we want to end up with is a section in vmlinux called 9# What we want to end up with this is that each object file will have a
10# __mcount_loc that contains a list of pointers to all the 10# section called __mcount_loc that will hold the list of pointers to mcount
11# call sites in the kernel that call mcount. Later on boot up, the kernel 11# callers. After final linking, the vmlinux will have within .init.data the
12# will read this list, save the locations and turn them into nops. 12# list of all callers to mcount between __start_mcount_loc and __stop_mcount_loc.
13# When tracing or profiling is later enabled, these locations will then 13# Later on boot up, the kernel will read this list, save the locations and turn
14# be converted back to pointers to some function. 14# them into nops. When tracing or profiling is later enabled, these locations
15# will then be converted back to pointers to some function.
15# 16#
16# This is no easy feat. This script is called just after the original 17# This is no easy feat. This script is called just after the original
17# object is compiled and before it is linked. 18# object is compiled and before it is linked.
18# 19#
19# The references to the call sites are offsets from the section of text 20# When parse this object file using 'objdump', the references to the call
20# that the call site is in. Hence, all functions in a section that 21# sites are offsets from the section that the call site is in. Hence, all
21# has a call site to mcount, will have the offset from the beginning of 22# functions in a section that has a call site to mcount, will have the
22# the section and not the beginning of the function. 23# offset from the beginning of the section and not the beginning of the
24# function.
25#
26# But where this section will reside finally in vmlinx is undetermined at
27# this point. So we can't use this kind of offsets to record the final
28# address of this call site.
29#
30# The trick is to change the call offset referring the start of a section to
31# referring a function symbol in this section. During the link step, 'ld' will
32# compute the final address according to the information we record.
23# 33#
24# The trick is to find a way to record the beginning of the section.
25# The way we do this is to look at the first function in the section
26# which will also be the location of that section after final link.
27# e.g. 34# e.g.
28# 35#
29# .section ".sched.text", "ax" 36# .section ".sched.text", "ax"
30# .globl my_func
31# my_func:
32# [...] 37# [...]
33# call mcount (offset: 0x5) 38# func1:
39# [...]
40# call mcount (offset: 0x10)
34# [...] 41# [...]
35# ret 42# ret
36# other_func: 43# .globl fun2
44# func2: (offset: 0x20)
37# [...] 45# [...]
38# call mcount (offset: 0x1b) 46# [...]
47# ret
48# func3:
49# [...]
50# call mcount (offset: 0x30)
39# [...] 51# [...]
40# 52#
41# Both relocation offsets for the mcounts in the above example will be 53# Both relocation offsets for the mcounts in the above example will be
42# offset from .sched.text. If we make another file called tmp.s with: 54# offset from .sched.text. If we choose global symbol func2 as a reference and
55# make another file called tmp.s with the new offsets:
43# 56#
44# .section __mcount_loc 57# .section __mcount_loc
45# .quad my_func + 0x5 58# .quad func2 - 0x10
46# .quad my_func + 0x1b 59# .quad func2 + 0x10
47# 60#
48# We can then compile this tmp.s into tmp.o, and link it to the original 61# We can then compile this tmp.s into tmp.o, and link it back to the original
49# object. 62# object.
50# 63#
51# But this gets hard if my_func is not globl (a static function). 64# In our algorithm, we will choose the first global function we meet in this
52# In such a case we have: 65# section as the reference. But this gets hard if there is no global functions
66# in this section. In such a case we have to select a local one. E.g. func1:
53# 67#
54# .section ".sched.text", "ax" 68# .section ".sched.text", "ax"
55# my_func: 69# func1:
56# [...] 70# [...]
57# call mcount (offset: 0x5) 71# call mcount (offset: 0x10)
58# [...] 72# [...]
59# ret 73# ret
60# other_func: 74# func2:
61# [...] 75# [...]
62# call mcount (offset: 0x1b) 76# call mcount (offset: 0x20)
63# [...] 77# [...]
78# .section "other.section"
64# 79#
65# If we make the tmp.s the same as above, when we link together with 80# If we make the tmp.s the same as above, when we link together with
66# the original object, we will end up with two symbols for my_func: 81# the original object, we will end up with two symbols for func1:
67# one local, one global. After final compile, we will end up with 82# one local, one global. After final compile, we will end up with
68# an undefined reference to my_func. 83# an undefined reference to func1 or a wrong reference to another global
84# func1 in other files.
69# 85#
70# Since local objects can reference local variables, we need to find 86# Since local objects can reference local variables, we need to find
71# a way to make tmp.o reference the local objects of the original object 87# a way to make tmp.o reference the local objects of the original object
72# file after it is linked together. To do this, we convert the my_func 88# file after it is linked together. To do this, we convert func1
73# into a global symbol before linking tmp.o. Then after we link tmp.o 89# into a global symbol before linking tmp.o. Then after we link tmp.o
74# we will only have a single symbol for my_func that is global. 90# we will only have a single symbol for func1 that is global.
75# We can convert my_func back into a local symbol and we are done. 91# We can convert func1 back into a local symbol and we are done.
76# 92#
77# Here are the steps we take: 93# Here are the steps we take:
78# 94#
79# 1) Record all the local symbols by using 'nm' 95# 1) Record all the local and weak symbols by using 'nm'
80# 2) Use objdump to find all the call site offsets and sections for 96# 2) Use objdump to find all the call site offsets and sections for
81# mcount. 97# mcount.
82# 3) Compile the list into its own object. 98# 3) Compile the list into its own object.
@@ -86,10 +102,8 @@
86# 6) Link together this new object with the list object. 102# 6) Link together this new object with the list object.
87# 7) Convert the local functions back to local symbols and rename 103# 7) Convert the local functions back to local symbols and rename
88# the result as the original object. 104# the result as the original object.
89# End.
90# 8) Link the object with the list object. 105# 8) Link the object with the list object.
91# 9) Move the result back to the original object. 106# 9) Move the result back to the original object.
92# End.
93# 107#
94 108
95use strict; 109use strict;
@@ -99,17 +113,17 @@ $P =~ s@.*/@@g;
99 113
100my $V = '0.1'; 114my $V = '0.1';
101 115
102if ($#ARGV < 7) { 116if ($#ARGV != 11) {
103 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";
104 print "version: $V\n"; 118 print "version: $V\n";
105 exit(1); 119 exit(1);
106} 120}
107 121
108my ($arch, $bits, $objdump, $objcopy, $cc, 122my ($arch, $endian, $bits, $objdump, $objcopy, $cc,
109 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; 123 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
110 124
111# 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
112if ($inputfile eq "kernel/trace/ftrace.o") { 126if ($inputfile =~ m,kernel/trace/ftrace\.o$,) {
113 exit(0); 127 exit(0);
114} 128}
115 129
@@ -119,6 +133,7 @@ my %text_sections = (
119 ".sched.text" => 1, 133 ".sched.text" => 1,
120 ".spinlock.text" => 1, 134 ".spinlock.text" => 1,
121 ".irqentry.text" => 1, 135 ".irqentry.text" => 1,
136 ".text.unlikely" => 1,
122); 137);
123 138
124$objdump = "objdump" if ((length $objdump) == 0); 139$objdump = "objdump" if ((length $objdump) == 0);
@@ -137,15 +152,49 @@ my %weak; # List of weak functions
137my %convert; # List of local functions used that needs conversion 152my %convert; # List of local functions used that needs conversion
138 153
139my $type; 154my $type;
140my $nm_regex; # Find the local functions (return function) 155my $local_regex; # Match a local function (return function)
156my $weak_regex; # Match a weak function (return function)
141my $section_regex; # Find the start of a section 157my $section_regex; # Find the start of a section
142my $function_regex; # Find the name of a function 158my $function_regex; # Find the name of a function
143 # (return offset and func name) 159 # (return offset and func name)
144my $mcount_regex; # Find the call site to mcount (return offset) 160my $mcount_regex; # Find the call site to mcount (return offset)
145my $alignment; # The .align value to use for $mcount_section 161my $alignment; # The .align value to use for $mcount_section
146my $section_type; # Section header plus possible alignment command 162my $section_type; # Section header plus possible alignment command
163my $can_use_local = 0; # If we can use local function references
164
165# Shut up recordmcount if user has older objcopy
166my $quiet_recordmcount = ".tmp_quiet_recordmcount";
167my $print_warning = 1;
168$print_warning = 0 if ( -f $quiet_recordmcount);
147 169
148if ($arch eq "x86") { 170##
171# check_objcopy - whether objcopy supports --globalize-symbols
172#
173# --globalize-symbols came out in 2.17, we must test the version
174# of objcopy, and if it is less than 2.17, then we can not
175# record local functions.
176sub check_objcopy
177{
178 open (IN, "$objcopy --version |") or die "error running $objcopy";
179 while (<IN>) {
180 if (/objcopy.*\s(\d+)\.(\d+)/) {
181 $can_use_local = 1 if ($1 > 2 || ($1 == 2 && $2 >= 17));
182 last;
183 }
184 }
185 close (IN);
186
187 if (!$can_use_local && $print_warning) {
188 print STDERR "WARNING: could not find objcopy version or version " .
189 "is less than 2.17.\n" .
190 "\tLocal function references are disabled.\n";
191 open (QUIET, ">$quiet_recordmcount");
192 printf QUIET "Disables the warning from recordmcount.pl\n";
193 close QUIET;
194 }
195}
196
197if ($arch =~ /(x86(_64)?)|(i386)/) {
149 if ($bits == 64) { 198 if ($bits == 64) {
150 $arch = "x86_64"; 199 $arch = "x86_64";
151 } else { 200 } else {
@@ -157,7 +206,8 @@ if ($arch eq "x86") {
157# We base the defaults off of i386, the other archs may 206# We base the defaults off of i386, the other archs may
158# feel free to change them in the below if statements. 207# feel free to change them in the below if statements.
159# 208#
160$nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)"; 209$local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
210$weak_regex = "^[0-9a-fA-F]+\\s+([wW])\\s+(\\S+)";
161$section_regex = "Disassembly of section\\s+(\\S+):"; 211$section_regex = "Disassembly of section\\s+(\\S+):";
162$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; 212$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
163$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; 213$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
@@ -206,7 +256,7 @@ if ($arch eq "x86_64") {
206 $cc .= " -m32"; 256 $cc .= " -m32";
207 257
208} elsif ($arch eq "powerpc") { 258} elsif ($arch eq "powerpc") {
209 $nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)"; 259 $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
210 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:"; 260 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
211 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$"; 261 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
212 262
@@ -245,6 +295,61 @@ if ($arch eq "x86_64") {
245 $ld .= " -m elf64_sparc"; 295 $ld .= " -m elf64_sparc";
246 $cc .= " -m64"; 296 $cc .= " -m64";
247 $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 }
350} elsif ($arch eq "microblaze") {
351 # Microblaze calls '_mcount' instead of plain 'mcount'.
352 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
248} else { 353} else {
249 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 354 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
250} 355}
@@ -278,44 +383,17 @@ if ($filename =~ m,^(.*)(\.\S),) {
278my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s"; 383my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
279my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o"; 384my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
280 385
281# 386check_objcopy();
282# --globalize-symbols came out in 2.17, we must test the version
283# of objcopy, and if it is less than 2.17, then we can not
284# record local functions.
285my $use_locals = 01;
286my $local_warn_once = 0;
287my $found_version = 0;
288
289open (IN, "$objcopy --version |") || die "error running $objcopy";
290while (<IN>) {
291 if (/objcopy.*\s(\d+)\.(\d+)/) {
292 my $major = $1;
293 my $minor = $2;
294
295 $found_version = 1;
296 if ($major < 2 ||
297 ($major == 2 && $minor < 17)) {
298 $use_locals = 0;
299 }
300 last;
301 }
302}
303close (IN);
304
305if (!$found_version) {
306 print STDERR "WARNING: could not find objcopy version.\n" .
307 "\tDisabling local function references.\n";
308}
309 387
310# 388#
311# Step 1: find all the local (static functions) and weak symbols. 389# Step 1: find all the local (static functions) and weak symbols.
312# 't' is local, 'w/W' is weak (we never use a weak function) 390# 't' is local, 'w/W' is weak
313# 391#
314open (IN, "$nm $inputfile|") || die "error running $nm"; 392open (IN, "$nm $inputfile|") || die "error running $nm";
315while (<IN>) { 393while (<IN>) {
316 if (/$nm_regex/) { 394 if (/$local_regex/) {
317 $locals{$1} = 1; 395 $locals{$1} = 1;
318 } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) { 396 } elsif (/$weak_regex/) {
319 $weak{$2} = $1; 397 $weak{$2} = $1;
320 } 398 }
321} 399}
@@ -333,26 +411,20 @@ my $offset = 0; # offset of ref_func to section beginning
333# 411#
334sub update_funcs 412sub update_funcs
335{ 413{
336 return if ($#offsets < 0); 414 return unless ($ref_func and @offsets);
337 415
338 defined($ref_func) || die "No function to reference"; 416 # Sanity check on weak function. A weak function may be overwritten by
339 417 # another function of the same name, making all these offsets incorrect.
340 # A section only had a weak function, to represent it.
341 # Unfortunately, a weak function may be overwritten by another
342 # function of the same name, making all these offsets incorrect.
343 # To be safe, we simply print a warning and bail.
344 if (defined $weak{$ref_func}) { 418 if (defined $weak{$ref_func}) {
345 print STDERR 419 die "$inputfile: ERROR: referencing weak function" .
346 "$inputfile: WARNING: referencing weak function" .
347 " $ref_func for mcount\n"; 420 " $ref_func for mcount\n";
348 return;
349 } 421 }
350 422
351 # is this function static? If so, note this fact. 423 # is this function static? If so, note this fact.
352 if (defined $locals{$ref_func}) { 424 if (defined $locals{$ref_func}) {
353 425
354 # only use locals if objcopy supports globalize-symbols 426 # only use locals if objcopy supports globalize-symbols
355 if (!$use_locals) { 427 if (!$can_use_local) {
356 return; 428 return;
357 } 429 }
358 $convert{$ref_func} = 1; 430 $convert{$ref_func} = 1;
@@ -378,9 +450,27 @@ open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump";
378 450
379my $text; 451my $text;
380 452
453
454# read headers first
381my $read_headers = 1; 455my $read_headers = 1;
382 456
383while (<IN>) { 457while (<IN>) {
458
459 if ($read_headers && /$mcount_section/) {
460 #
461 # Somehow the make process can execute this script on an
462 # object twice. If it does, we would duplicate the mcount
463 # section and it will cause the function tracer self test
464 # to fail. Check if the mcount section exists, and if it does,
465 # warn and exit.
466 #
467 print STDERR "ERROR: $mcount_section already in $inputfile\n" .
468 "\tThis may be an indication that your build is corrupted.\n" .
469 "\tDelete $inputfile and try again. If the same object file\n" .
470 "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
471 exit(-1);
472 }
473
384 # is it a section? 474 # is it a section?
385 if (/$section_regex/) { 475 if (/$section_regex/) {
386 $read_headers = 0; 476 $read_headers = 0;
@@ -392,7 +482,7 @@ while (<IN>) {
392 $read_function = 0; 482 $read_function = 0;
393 } 483 }
394 # print out any recorded offsets 484 # print out any recorded offsets
395 update_funcs() if (defined($ref_func)); 485 update_funcs();
396 486
397 # reset all markers and arrays 487 # reset all markers and arrays
398 $text_found = 0; 488 $text_found = 0;
@@ -421,21 +511,7 @@ while (<IN>) {
421 $offset = hex $1; 511 $offset = hex $1;
422 } 512 }
423 } 513 }
424 } elsif ($read_headers && /$mcount_section/) {
425 #
426 # Somehow the make process can execute this script on an
427 # object twice. If it does, we would duplicate the mcount
428 # section and it will cause the function tracer self test
429 # to fail. Check if the mcount section exists, and if it does,
430 # warn and exit.
431 #
432 print STDERR "ERROR: $mcount_section already in $inputfile\n" .
433 "\tThis may be an indication that your build is corrupted.\n" .
434 "\tDelete $inputfile and try again. If the same object file\n" .
435 "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
436 exit(-1);
437 } 514 }
438
439 # is this a call site to mcount? If so, record it to print later 515 # is this a call site to mcount? If so, record it to print later
440 if ($text_found && /$mcount_regex/) { 516 if ($text_found && /$mcount_regex/) {
441 $offsets[$#offsets + 1] = hex $1; 517 $offsets[$#offsets + 1] = hex $1;
@@ -443,7 +519,7 @@ while (<IN>) {
443} 519}
444 520
445# dump out anymore offsets that may have been found 521# dump out anymore offsets that may have been found
446update_funcs() if (defined($ref_func)); 522update_funcs();
447 523
448# If we did not find any mcount callers, we are done (do nothing). 524# If we did not find any mcount callers, we are done (do nothing).
449if (!$opened) { 525if (!$opened) {
diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile
index ca4b1ec01822..e8049da1831f 100644
--- a/scripts/selinux/Makefile
+++ b/scripts/selinux/Makefile
@@ -1,2 +1,2 @@
1subdir-y := mdp 1subdir-y := mdp genheaders
2subdir- += mdp 2subdir- += mdp genheaders
diff --git a/scripts/selinux/genheaders/.gitignore b/scripts/selinux/genheaders/.gitignore
new file mode 100644
index 000000000000..4c0b646ff8d5
--- /dev/null
+++ b/scripts/selinux/genheaders/.gitignore
@@ -0,0 +1 @@
genheaders
diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile
new file mode 100644
index 000000000000..417b165008ee
--- /dev/null
+++ b/scripts/selinux/genheaders/Makefile
@@ -0,0 +1,5 @@
1hostprogs-y := genheaders
2HOST_EXTRACFLAGS += -Isecurity/selinux/include
3
4always := $(hostprogs-y)
5clean-files := $(hostprogs-y)
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
new file mode 100644
index 000000000000..24626968055d
--- /dev/null
+++ b/scripts/selinux/genheaders/genheaders.c
@@ -0,0 +1,118 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <errno.h>
6#include <ctype.h>
7
8struct security_class_mapping {
9 const char *name;
10 const char *perms[sizeof(unsigned) * 8 + 1];
11};
12
13#include "classmap.h"
14#include "initial_sid_to_string.h"
15
16#define max(x, y) (((int)(x) > (int)(y)) ? x : y)
17
18const char *progname;
19
20static void usage(void)
21{
22 printf("usage: %s flask.h av_permissions.h\n", progname);
23 exit(1);
24}
25
26static char *stoupperx(const char *s)
27{
28 char *s2 = strdup(s);
29 char *p;
30
31 if (!s2) {
32 fprintf(stderr, "%s: out of memory\n", progname);
33 exit(3);
34 }
35
36 for (p = s2; *p; p++)
37 *p = toupper(*p);
38 return s2;
39}
40
41int main(int argc, char *argv[])
42{
43 int i, j, k;
44 int isids_len;
45 FILE *fout;
46
47 progname = argv[0];
48
49 if (argc < 3)
50 usage();
51
52 fout = fopen(argv[1], "w");
53 if (!fout) {
54 fprintf(stderr, "Could not open %s for writing: %s\n",
55 argv[1], strerror(errno));
56 exit(2);
57 }
58
59 for (i = 0; secclass_map[i].name; i++) {
60 struct security_class_mapping *map = &secclass_map[i];
61 map->name = stoupperx(map->name);
62 for (j = 0; map->perms[j]; j++)
63 map->perms[j] = stoupperx(map->perms[j]);
64 }
65
66 isids_len = sizeof(initial_sid_to_string) / sizeof (char *);
67 for (i = 1; i < isids_len; i++)
68 initial_sid_to_string[i] = stoupperx(initial_sid_to_string[i]);
69
70 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
71 fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
72
73 for (i = 0; secclass_map[i].name; i++) {
74 struct security_class_mapping *map = &secclass_map[i];
75 fprintf(fout, "#define SECCLASS_%s", map->name);
76 for (j = 0; j < max(1, 40 - strlen(map->name)); j++)
77 fprintf(fout, " ");
78 fprintf(fout, "%2d\n", i+1);
79 }
80
81 fprintf(fout, "\n");
82
83 for (i = 1; i < isids_len; i++) {
84 char *s = initial_sid_to_string[i];
85 fprintf(fout, "#define SECINITSID_%s", s);
86 for (j = 0; j < max(1, 40 - strlen(s)); j++)
87 fprintf(fout, " ");
88 fprintf(fout, "%2d\n", i);
89 }
90 fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
91 fprintf(fout, "\n#endif\n");
92 fclose(fout);
93
94 fout = fopen(argv[2], "w");
95 if (!fout) {
96 fprintf(stderr, "Could not open %s for writing: %s\n",
97 argv[2], strerror(errno));
98 exit(4);
99 }
100
101 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
102 fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
103
104 for (i = 0; secclass_map[i].name; i++) {
105 struct security_class_mapping *map = &secclass_map[i];
106 for (j = 0; map->perms[j]; j++) {
107 fprintf(fout, "#define %s__%s", map->name,
108 map->perms[j]);
109 for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++)
110 fprintf(fout, " ");
111 fprintf(fout, "0x%08xUL\n", (1<<j));
112 }
113 }
114
115 fprintf(fout, "\n#endif\n");
116 fclose(fout);
117 exit(0);
118}
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index b4ced8562587..62b34ce1f50d 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -29,86 +29,27 @@
29#include <unistd.h> 29#include <unistd.h>
30#include <string.h> 30#include <string.h>
31 31
32#include "flask.h"
33
34static void usage(char *name) 32static void usage(char *name)
35{ 33{
36 printf("usage: %s [-m] policy_file context_file\n", name); 34 printf("usage: %s [-m] policy_file context_file\n", name);
37 exit(1); 35 exit(1);
38} 36}
39 37
40static void find_common_name(char *cname, char *dest, int len) 38/* Class/perm mapping support */
41{ 39struct security_class_mapping {
42 char *start, *end; 40 const char *name;
43 41 const char *perms[sizeof(unsigned) * 8 + 1];
44 start = strchr(cname, '_')+1;
45 end = strchr(start, '_');
46 if (!start || !end || start-cname > len || end-start > len) {
47 printf("Error with commons defines\n");
48 exit(1);
49 }
50 strncpy(dest, start, end-start);
51 dest[end-start] = '\0';
52}
53
54#define S_(x) x,
55static char *classlist[] = {
56#include "class_to_string.h"
57 NULL
58}; 42};
59#undef S_
60 43
44#include "classmap.h"
61#include "initial_sid_to_string.h" 45#include "initial_sid_to_string.h"
62 46
63#define TB_(x) char *x[] = {
64#define TE_(x) NULL };
65#define S_(x) x,
66#include "common_perm_to_string.h"
67#undef TB_
68#undef TE_
69#undef S_
70
71struct common {
72 char *cname;
73 char **perms;
74};
75struct common common[] = {
76#define TB_(x) { #x, x },
77#define S_(x)
78#define TE_(x)
79#include "common_perm_to_string.h"
80#undef TB_
81#undef TE_
82#undef S_
83};
84
85#define S_(x, y, z) {x, #y},
86struct av_inherit {
87 int class;
88 char *common;
89};
90struct av_inherit av_inherit[] = {
91#include "av_inherit.h"
92};
93#undef S_
94
95#include "av_permissions.h"
96#define S_(x, y, z) {x, y, z},
97struct av_perms {
98 int class;
99 int perm_i;
100 char *perm_s;
101};
102struct av_perms av_perms[] = {
103#include "av_perm_to_string.h"
104};
105#undef S_
106
107int main(int argc, char *argv[]) 47int main(int argc, char *argv[])
108{ 48{
109 int i, j, mls = 0; 49 int i, j, mls = 0;
50 int initial_sid_to_string_len;
110 char **arg, *polout, *ctxout; 51 char **arg, *polout, *ctxout;
111 int classlist_len, initial_sid_to_string_len; 52
112 FILE *fout; 53 FILE *fout;
113 54
114 if (argc < 3) 55 if (argc < 3)
@@ -127,64 +68,25 @@ int main(int argc, char *argv[])
127 usage(argv[0]); 68 usage(argv[0]);
128 } 69 }
129 70
130 classlist_len = sizeof(classlist) / sizeof(char *);
131 /* print out the classes */ 71 /* print out the classes */
132 for (i=1; i < classlist_len; i++) { 72 for (i = 0; secclass_map[i].name; i++)
133 if(classlist[i]) 73 fprintf(fout, "class %s\n", secclass_map[i].name);
134 fprintf(fout, "class %s\n", classlist[i]);
135 else
136 fprintf(fout, "class user%d\n", i);
137 }
138 fprintf(fout, "\n"); 74 fprintf(fout, "\n");
139 75
140 initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); 76 initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
141 /* print out the sids */ 77 /* print out the sids */
142 for (i=1; i < initial_sid_to_string_len; i++) 78 for (i = 1; i < initial_sid_to_string_len; i++)
143 fprintf(fout, "sid %s\n", initial_sid_to_string[i]); 79 fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
144 fprintf(fout, "\n"); 80 fprintf(fout, "\n");
145 81
146 /* print out the commons */
147 for (i=0; i< sizeof(common)/sizeof(struct common); i++) {
148 char cname[101];
149 find_common_name(common[i].cname, cname, 100);
150 cname[100] = '\0';
151 fprintf(fout, "common %s\n{\n", cname);
152 for (j=0; common[i].perms[j]; j++)
153 fprintf(fout, "\t%s\n", common[i].perms[j]);
154 fprintf(fout, "}\n\n");
155 }
156 fprintf(fout, "\n");
157
158 /* print out the class permissions */ 82 /* print out the class permissions */
159 for (i=1; i < classlist_len; i++) { 83 for (i = 0; secclass_map[i].name; i++) {
160 if (classlist[i]) { 84 struct security_class_mapping *map = &secclass_map[i];
161 int firstperm = -1, numperms = 0; 85 fprintf(fout, "class %s\n", map->name);
162 86 fprintf(fout, "{\n");
163 fprintf(fout, "class %s\n", classlist[i]); 87 for (j = 0; map->perms[j]; j++)
164 /* does it inherit from a common? */ 88 fprintf(fout, "\t%s\n", map->perms[j]);
165 for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++) 89 fprintf(fout, "}\n\n");
166 if (av_inherit[j].class == i)
167 fprintf(fout, "inherits %s\n", av_inherit[j].common);
168
169 for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) {
170 if (av_perms[j].class == i) {
171 if (firstperm == -1)
172 firstperm = j;
173 numperms++;
174 }
175 }
176 if (!numperms) {
177 fprintf(fout, "\n");
178 continue;
179 }
180
181 fprintf(fout, "{\n");
182 /* print out the av_perms */
183 for (j=0; j < numperms; j++) {
184 fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s);
185 }
186 fprintf(fout, "}\n\n");
187 }
188 } 90 }
189 fprintf(fout, "\n"); 91 fprintf(fout, "\n");
190 92
@@ -197,31 +99,34 @@ int main(int argc, char *argv[])
197 /* types, roles, and allows */ 99 /* types, roles, and allows */
198 fprintf(fout, "type base_t;\n"); 100 fprintf(fout, "type base_t;\n");
199 fprintf(fout, "role base_r types { base_t };\n"); 101 fprintf(fout, "role base_r types { base_t };\n");
200 for (i=1; i < classlist_len; i++) { 102 for (i = 0; secclass_map[i].name; i++)
201 if (classlist[i]) 103 fprintf(fout, "allow base_t base_t:%s *;\n",
202 fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]); 104 secclass_map[i].name);
203 else
204 fprintf(fout, "allow base_t base_t:user%d *;\n", i);
205 }
206 fprintf(fout, "user user_u roles { base_r };\n"); 105 fprintf(fout, "user user_u roles { base_r };\n");
207 fprintf(fout, "\n"); 106 fprintf(fout, "\n");
208 107
209 /* default sids */ 108 /* default sids */
210 for (i=1; i < initial_sid_to_string_len; i++) 109 for (i = 1; i < initial_sid_to_string_len; i++)
211 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); 110 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
212 fprintf(fout, "\n"); 111 fprintf(fout, "\n");
213 112
214
215 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); 113 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
216 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); 114 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
115 fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
217 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); 116 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
218 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); 117 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
219 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); 118 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
119 fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
120 fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
121 fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n");
220 122
123 fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
221 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); 124 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
222 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); 125 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
223 126
127 fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
224 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); 128 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
129 fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
225 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); 130 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
226 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); 131 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
227 132
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