aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.build39
-rw-r--r--scripts/Makefile.help3
-rw-r--r--scripts/Makefile.lib6
-rw-r--r--scripts/Makefile.modbuiltin5
-rw-r--r--scripts/Makefile.modpost9
-rwxr-xr-xscripts/checkincludes.pl24
-rwxr-xr-xscripts/checkkconfigsymbols.sh2
-rwxr-xr-xscripts/checkpatch.pl73
-rwxr-xr-xscripts/checkstack.pl16
-rwxr-xr-xscripts/checksyscalls.sh1
-rwxr-xr-xscripts/checkversion.pl23
-rwxr-xr-xscripts/coccicheck80
-rw-r--r--scripts/coccinelle/alloc/drop_kmalloc_cast.cocci67
-rw-r--r--scripts/coccinelle/alloc/kzalloc-simple.cocci82
-rw-r--r--scripts/coccinelle/deref_null.cocci293
-rw-r--r--scripts/coccinelle/err_cast.cocci56
-rw-r--r--scripts/coccinelle/resource_size.cocci93
-rwxr-xr-xscripts/decodecode48
-rw-r--r--scripts/dtc/fstree.c1
-rw-r--r--scripts/export_report.pl37
-rw-r--r--scripts/gen_initramfs_list.sh4
-rw-r--r--scripts/genksyms/genksyms.c4
-rwxr-xr-xscripts/get_maintainer.pl66
-rwxr-xr-xscripts/headerdep.pl3
-rw-r--r--scripts/headers_check.pl11
-rw-r--r--scripts/headers_install.pl19
-rw-r--r--scripts/kallsyms.c6
-rw-r--r--scripts/kconfig/.gitignore1
-rw-r--r--scripts/kconfig/Makefile93
-rw-r--r--scripts/kconfig/conf.c181
-rw-r--r--scripts/kconfig/confdata.c221
-rw-r--r--scripts/kconfig/expr.c27
-rw-r--r--scripts/kconfig/expr.h8
-rw-r--r--scripts/kconfig/gconf.c116
-rw-r--r--scripts/kconfig/gconf.glade26
-rw-r--r--scripts/kconfig/lkc.h9
-rw-r--r--scripts/kconfig/lkc_proto.h7
-rw-r--r--scripts/kconfig/lxdialog/checklist.c10
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c4
-rw-r--r--scripts/kconfig/lxdialog/menubox.c22
-rw-r--r--scripts/kconfig/mconf.c36
-rw-r--r--scripts/kconfig/menu.c55
-rw-r--r--scripts/kconfig/nconf.c1568
-rw-r--r--scripts/kconfig/nconf.gui.c617
-rw-r--r--scripts/kconfig/nconf.h95
-rw-r--r--scripts/kconfig/qconf.cc106
-rw-r--r--scripts/kconfig/qconf.h17
-rw-r--r--scripts/kconfig/streamline_config.pl9
-rw-r--r--scripts/kconfig/symbol.c322
-rw-r--r--scripts/kconfig/util.c4
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped25
-rw-r--r--scripts/kconfig/zconf.y25
-rwxr-xr-xscripts/kernel-doc2
-rw-r--r--scripts/markup_oops.pl54
-rwxr-xr-xscripts/mkcompile_h5
-rw-r--r--scripts/mod/file2alias.c63
-rw-r--r--scripts/mod/modpost.c320
-rw-r--r--scripts/mod/modpost.h43
-rwxr-xr-xscripts/namespace.pl65
-rw-r--r--scripts/package/Makefile39
-rw-r--r--scripts/package/builddeb7
-rwxr-xr-xscripts/package/mkspec4
-rw-r--r--scripts/profile2linkerlist.pl8
-rwxr-xr-xscripts/recordmcount.pl2
-rw-r--r--scripts/rt-tester/rt-tester.py2
-rw-r--r--scripts/selinux/genheaders/genheaders.c2
-rwxr-xr-xscripts/setlocalversion183
-rwxr-xr-xscripts/show_delta2
-rwxr-xr-xscripts/tags.sh45
69 files changed, 4726 insertions, 795 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0b94d2fa3a88..a1a5cf95a68d 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -82,7 +82,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
82lib-target := $(obj)/lib.a 82lib-target := $(obj)/lib.a
83endif 83endif
84 84
85ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),) 85ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target)),)
86builtin-target := $(obj)/built-in.o 86builtin-target := $(obj)/built-in.o
87endif 87endif
88 88
@@ -115,7 +115,10 @@ endif
115# --------------------------------------------------------------------------- 115# ---------------------------------------------------------------------------
116 116
117# Default is built-in, unless we know otherwise 117# Default is built-in, unless we know otherwise
118modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL)) 118modkern_cflags = \
119 $(if $(part-of-module), \
120 $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
121 $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
119quiet_modtag := $(empty) $(empty) 122quiet_modtag := $(empty) $(empty)
120 123
121$(real-objs-m) : part-of-module := y 124$(real-objs-m) : part-of-module := y
@@ -156,14 +159,14 @@ $(obj)/%.i: $(src)/%.c FORCE
156 159
157cmd_gensymtypes = \ 160cmd_gensymtypes = \
158 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ 161 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
159 $(GENKSYMS) -T $@ -a $(ARCH) \ 162 $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH) \
160 $(if $(KBUILD_PRESERVE),-p) \ 163 $(if $(KBUILD_PRESERVE),-p) \
161 $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null))) 164 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
162 165
163quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ 166quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
164cmd_cc_symtypes_c = \ 167cmd_cc_symtypes_c = \
165 set -e; \ 168 set -e; \
166 $(call cmd_gensymtypes, true) >/dev/null; \ 169 $(call cmd_gensymtypes,true,$@) >/dev/null; \
167 test -s $@ || rm -f $@ 170 test -s $@ || rm -f $@
168 171
169$(obj)/%.symtypes : $(src)/%.c FORCE 172$(obj)/%.symtypes : $(src)/%.c FORCE
@@ -192,16 +195,16 @@ else
192# the actual value of the checksum generated by genksyms 195# the actual value of the checksum generated by genksyms
193 196
194cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< 197cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
195cmd_modversions = \ 198cmd_modversions = \
196 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ 199 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
197 $(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \ 200 $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
198 > $(@D)/.tmp_$(@F:.o=.ver); \ 201 > $(@D)/.tmp_$(@F:.o=.ver); \
199 \ 202 \
200 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ 203 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
201 -T $(@D)/.tmp_$(@F:.o=.ver); \ 204 -T $(@D)/.tmp_$(@F:.o=.ver); \
202 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ 205 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
203 else \ 206 else \
204 mv -f $(@D)/.tmp_$(@F) $@; \ 207 mv -f $(@D)/.tmp_$(@F) $@; \
205 fi; 208 fi;
206endif 209endif
207 210
@@ -248,10 +251,10 @@ $(obj)/%.lst: $(src)/%.c FORCE
248# Compile assembler sources (.S) 251# Compile assembler sources (.S)
249# --------------------------------------------------------------------------- 252# ---------------------------------------------------------------------------
250 253
251modkern_aflags := $(AFLAGS_KERNEL) 254modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
252 255
253$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE) 256$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
254$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE) 257$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
255 258
256quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ 259quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
257cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< 260cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
diff --git a/scripts/Makefile.help b/scripts/Makefile.help
new file mode 100644
index 000000000000..d03608f5db04
--- /dev/null
+++ b/scripts/Makefile.help
@@ -0,0 +1,3 @@
1
2checker-help:
3 @echo ' coccicheck - Check with Coccinelle.'
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index f9bdf264473d..54fd1b700131 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -241,7 +241,11 @@ cmd_lzma = (cat $(filter-out FORCE,$^) | \
241 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 241 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
242 (rm -f $@ ; false) 242 (rm -f $@ ; false)
243 243
244quiet_cmd_lzo = LZO $@ 244quiet_cmd_lzo = LZO $@
245cmd_lzo = (cat $(filter-out FORCE,$^) | \ 245cmd_lzo = (cat $(filter-out FORCE,$^) | \
246 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 246 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
247 (rm -f $@ ; false) 247 (rm -f $@ ; false)
248
249# misc stuff
250# ---------------------------------------------------------------------------
251quote:="
diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin
index 102a276f6eea..1adb974e6950 100644
--- a/scripts/Makefile.modbuiltin
+++ b/scripts/Makefile.modbuiltin
@@ -14,6 +14,11 @@ __modbuiltin:
14 14
15include scripts/Kbuild.include 15include scripts/Kbuild.include
16 16
17ifneq ($(KBUILD_SRC),)
18# Create output directory if not already present
19_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
20endif
21
17# The filename Kbuild has precedence over Makefile 22# The filename Kbuild has precedence over Makefile
18kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 23kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
19kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) 24kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 8f14c81abbc7..7d22056582c1 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -30,7 +30,7 @@
30# - See include/linux/module.h for more details 30# - See include/linux/module.h for more details
31 31
32# Step 4 is solely used to allow module versioning in external modules, 32# Step 4 is solely used to allow module versioning in external modules,
33# where the CRC of each module is retrieved from the Module.symers file. 33# where the CRC of each module is retrieved from the Module.symvers file.
34 34
35# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined 35# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
36# symbols in the final module linking stage 36# symbols in the final module linking stage
@@ -107,7 +107,7 @@ $(modules:.ko=.mod.c): __modpost ;
107modname = $(notdir $(@:.mod.o=)) 107modname = $(notdir $(@:.mod.o=))
108 108
109quiet_cmd_cc_o_c = CC $@ 109quiet_cmd_cc_o_c = CC $@
110 cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ 110 cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \
111 -c -o $@ $< 111 -c -o $@ $<
112 112
113$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE 113$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
@@ -117,8 +117,9 @@ targets += $(modules:.ko=.mod.o)
117 117
118# Step 6), final link of the modules 118# Step 6), final link of the modules
119quiet_cmd_ld_ko_o = LD [M] $@ 119quiet_cmd_ld_ko_o = LD [M] $@
120 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ 120 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
121 $(filter-out FORCE,$^) 121 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
122 -o $@ $(filter-out FORCE,$^)
122 123
123$(modules): %.ko :%.o %.mod.o FORCE 124$(modules): %.ko :%.o %.mod.o FORCE
124 $(call if_changed,ld_ko_o) 125 $(call if_changed,ld_ko_o)
diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl
index 676ddc07d6fa..97b2c6143fe4 100755
--- a/scripts/checkincludes.pl
+++ b/scripts/checkincludes.pl
@@ -11,6 +11,8 @@
11# you do have real dups and do not have them under #ifdef's. You 11# you do have real dups and do not have them under #ifdef's. You
12# could also just review the results. 12# could also just review the results.
13 13
14use strict;
15
14sub usage { 16sub usage {
15 print "Usage: checkincludes.pl [-r]\n"; 17 print "Usage: checkincludes.pl [-r]\n";
16 print "By default we just warn of duplicates\n"; 18 print "By default we just warn of duplicates\n";
@@ -35,23 +37,24 @@ if ($#ARGV >= 1) {
35 } 37 }
36} 38}
37 39
38foreach $file (@ARGV) { 40foreach my $file (@ARGV) {
39 open(FILE, $file) or die "Cannot open $file: $!.\n"; 41 open(my $f, '<', $file)
42 or die "Cannot open $file: $!.\n";
40 43
41 my %includedfiles = (); 44 my %includedfiles = ();
42 my @file_lines = (); 45 my @file_lines = ();
43 46
44 while (<FILE>) { 47 while (<$f>) {
45 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 48 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
46 ++$includedfiles{$1}; 49 ++$includedfiles{$1};
47 } 50 }
48 push(@file_lines, $_); 51 push(@file_lines, $_);
49 } 52 }
50 53
51 close(FILE); 54 close($f);
52 55
53 if (!$remove) { 56 if (!$remove) {
54 foreach $filename (keys %includedfiles) { 57 foreach my $filename (keys %includedfiles) {
55 if ($includedfiles{$filename} > 1) { 58 if ($includedfiles{$filename} > 1) {
56 print "$file: $filename is included more than once.\n"; 59 print "$file: $filename is included more than once.\n";
57 } 60 }
@@ -59,27 +62,28 @@ foreach $file (@ARGV) {
59 next; 62 next;
60 } 63 }
61 64
62 open(FILE,">$file") || die("Cannot write to $file: $!"); 65 open($f, '>', $file)
66 or die("Cannot write to $file: $!");
63 67
64 my $dups = 0; 68 my $dups = 0;
65 foreach (@file_lines) { 69 foreach (@file_lines) {
66 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 70 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
67 foreach $filename (keys %includedfiles) { 71 foreach my $filename (keys %includedfiles) {
68 if ($1 eq $filename) { 72 if ($1 eq $filename) {
69 if ($includedfiles{$filename} > 1) { 73 if ($includedfiles{$filename} > 1) {
70 $includedfiles{$filename}--; 74 $includedfiles{$filename}--;
71 $dups++; 75 $dups++;
72 } else { 76 } else {
73 print FILE $_; 77 print {$f} $_;
74 } 78 }
75 } 79 }
76 } 80 }
77 } else { 81 } else {
78 print FILE $_; 82 print {$f} $_;
79 } 83 }
80 } 84 }
81 if ($dups > 0) { 85 if ($dups > 0) {
82 print "$file: removed $dups duplicate includes\n"; 86 print "$file: removed $dups duplicate includes\n";
83 } 87 }
84 close(FILE); 88 close($f);
85} 89}
diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh
index 46be3c5a62b7..2ca49bb31efc 100755
--- a/scripts/checkkconfigsymbols.sh
+++ b/scripts/checkkconfigsymbols.sh
@@ -14,7 +14,7 @@ find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while
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
16 # the end is not removed here (would need perl an not-hungry regexp for that). 16 # the end is not removed here (would need perl an not-hungry regexp for that).
17 sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Z_]\+\).*!\2 '$i'!p' < $i 17 sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i
18done | \ 18done | \
19# Smart "sort|uniq" implemented in awk and tuned to collect the names of all 19# Smart "sort|uniq" implemented in awk and tuned to collect the names of all
20# files which use a given symbol 20# files which use a given symbol
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index a4d74344d805..2039acdf5122 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -195,7 +195,7 @@ our $typeTypedefs = qr{(?x:
195our $logFunctions = qr{(?x: 195our $logFunctions = qr{(?x:
196 printk| 196 printk|
197 pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)| 197 pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
198 dev_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)| 198 (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
199 WARN| 199 WARN|
200 panic 200 panic
201)}; 201)};
@@ -224,6 +224,12 @@ our @modifierList = (
224 qr{fastcall}, 224 qr{fastcall},
225); 225);
226 226
227our $allowed_asm_includes = qr{(?x:
228 irq|
229 memory
230)};
231# memory.h: ARM has a custom one
232
227sub build_types { 233sub build_types {
228 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 234 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
229 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 235 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
@@ -552,6 +558,9 @@ sub ctx_statement_block {
552 $type = ($level != 0)? '{' : ''; 558 $type = ($level != 0)? '{' : '';
553 559
554 if ($level == 0) { 560 if ($level == 0) {
561 if (substr($blk, $off + 1, 1) eq ';') {
562 $off++;
563 }
555 last; 564 last;
556 } 565 }
557 } 566 }
@@ -1382,13 +1391,29 @@ sub process {
1382 ERROR("trailing whitespace\n" . $herevet); 1391 ERROR("trailing whitespace\n" . $herevet);
1383 } 1392 }
1384 1393
1394# check for Kconfig help text having a real description
1395 if ($realfile =~ /Kconfig/ &&
1396 $line =~ /\+?\s*(---)?help(---)?$/) {
1397 my $length = 0;
1398 for (my $l = $linenr; defined($lines[$l]); $l++) {
1399 my $f = $lines[$l];
1400 $f =~ s/#.*//;
1401 $f =~ s/^\s+//;
1402 next if ($f =~ /^$/);
1403 last if ($f =~ /^\s*config\s/);
1404 $length++;
1405 }
1406 WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4);
1407 }
1408
1385# check we are in a valid source file if not then ignore this hunk 1409# check we are in a valid source file if not then ignore this hunk
1386 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 1410 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
1387 1411
1388#80 column limit 1412#80 column limit
1389 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1413 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1390 $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 1414 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
1391 $line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ && 1415 !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ ||
1416 $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
1392 $length > 80) 1417 $length > 80)
1393 { 1418 {
1394 WARN("line over 80 characters\n" . $herecurr); 1419 WARN("line over 80 characters\n" . $herecurr);
@@ -1433,6 +1458,13 @@ sub process {
1433 WARN("please, no space before tabs\n" . $herevet); 1458 WARN("please, no space before tabs\n" . $herevet);
1434 } 1459 }
1435 1460
1461# check for spaces at the beginning of a line.
1462 if ($rawline =~ /^\+ / && $rawline !~ /\+ +\*/) {
1463 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1464 WARN("please, no space for starting a line, \
1465 excluding comments\n" . $herevet);
1466 }
1467
1436# check we are in a valid C source file if not then ignore this hunk 1468# check we are in a valid C source file if not then ignore this hunk
1437 next if ($realfile !~ /\.(h|c)$/); 1469 next if ($realfile !~ /\.(h|c)$/);
1438 1470
@@ -1763,9 +1795,9 @@ sub process {
1763 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 1795 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
1764 } 1796 }
1765 1797
1766# check for external initialisers. 1798# check for global initialisers.
1767 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { 1799 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
1768 ERROR("do not initialise externals to 0 or NULL\n" . 1800 ERROR("do not initialise globals to 0 or NULL\n" .
1769 $herecurr); 1801 $herecurr);
1770 } 1802 }
1771# check for static initialisers. 1803# check for static initialisers.
@@ -2293,7 +2325,7 @@ sub process {
2293 my $checkfile = "include/linux/$file"; 2325 my $checkfile = "include/linux/$file";
2294 if (-f "$root/$checkfile" && 2326 if (-f "$root/$checkfile" &&
2295 $realfile ne $checkfile && 2327 $realfile ne $checkfile &&
2296 $1 ne 'irq') 2328 $1 !~ /$allowed_asm_includes/)
2297 { 2329 {
2298 if ($realfile =~ m{^arch/}) { 2330 if ($realfile =~ m{^arch/}) {
2299 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 2331 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
@@ -2555,6 +2587,21 @@ sub process {
2555 } 2587 }
2556 } 2588 }
2557 2589
2590# prefer usleep_range over udelay
2591 if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
2592 # ignore udelay's < 10, however
2593 if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
2594 CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
2595 }
2596 }
2597
2598# warn about unexpectedly long msleep's
2599 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
2600 if ($1 < 20) {
2601 WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
2602 }
2603 }
2604
2558# warn about #ifdefs in C files 2605# warn about #ifdefs in C files
2559# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 2606# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
2560# print "#ifdef in C files should be avoided\n"; 2607# print "#ifdef in C files should be avoided\n";
@@ -2586,6 +2633,11 @@ sub process {
2586 CHK("architecture specific defines should be avoided\n" . $herecurr); 2633 CHK("architecture specific defines should be avoided\n" . $herecurr);
2587 } 2634 }
2588 2635
2636# Check that the storage class is at the beginning of a declaration
2637 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
2638 WARN("storage class should be at the beginning of the declaration\n" . $herecurr)
2639 }
2640
2589# check the location of the inline attribute, that it is between 2641# check the location of the inline attribute, that it is between
2590# storage class and type. 2642# storage class and type.
2591 if ($line =~ /\b$Type\s+$Inline\b/ || 2643 if ($line =~ /\b$Type\s+$Inline\b/ ||
@@ -2656,6 +2708,7 @@ sub process {
2656# check for semaphores used as mutexes 2708# check for semaphores used as mutexes
2657 if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) { 2709 if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
2658 WARN("consider using a completion\n" . $herecurr); 2710 WARN("consider using a completion\n" . $herecurr);
2711
2659 } 2712 }
2660# recommend strict_strto* over simple_strto* 2713# recommend strict_strto* over simple_strto*
2661 if ($line =~ /\bsimple_(strto.*?)\s*\(/) { 2714 if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
@@ -2740,6 +2793,16 @@ sub process {
2740 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 2793 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
2741 } 2794 }
2742 } 2795 }
2796
2797# check for lockdep_set_novalidate_class
2798 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
2799 $line =~ /__lockdep_no_validate__\s*\)/ ) {
2800 if ($realfile !~ m@^kernel/lockdep@ &&
2801 $realfile !~ m@^include/linux/lockdep@ &&
2802 $realfile !~ m@^drivers/base/core@) {
2803 ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
2804 }
2805 }
2743 } 2806 }
2744 2807
2745 # If we have no input at all, then there is nothing to report on 2808 # If we have no input at all, then there is nothing to report on
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 14ee68e991dd..1afff6658a7d 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -21,6 +21,8 @@
21# 21#
22# TODO : Port to all architectures (one regex per arch) 22# TODO : Port to all architectures (one regex per arch)
23 23
24use strict;
25
24# check for arch 26# check for arch
25# 27#
26# $re is used for two matches: 28# $re is used for two matches:
@@ -104,19 +106,11 @@ my (@stack, $re, $dre, $x, $xs);
104 } 106 }
105} 107}
106 108
107sub bysize($) {
108 my ($asize, $bsize);
109 ($asize = $a) =~ s/.*: *(.*)$/$1/;
110 ($bsize = $b) =~ s/.*: *(.*)$/$1/;
111 $bsize <=> $asize
112}
113
114# 109#
115# main() 110# main()
116# 111#
117my $funcre = qr/^$x* <(.*)>:$/; 112my $funcre = qr/^$x* <(.*)>:$/;
118my $func; 113my ($func, $file, $lastslash);
119my $file, $lastslash;
120 114
121while (my $line = <STDIN>) { 115while (my $line = <STDIN>) {
122 if ($line =~ m/$funcre/) { 116 if ($line =~ m/$funcre/) {
@@ -173,4 +167,6 @@ while (my $line = <STDIN>) {
173 } 167 }
174} 168}
175 169
176print sort bysize @stack; 170# Sort output by size (last field)
171print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
172
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh
index 66ad375612f2..6bb42e72e0e5 100755
--- a/scripts/checksyscalls.sh
+++ b/scripts/checksyscalls.sh
@@ -183,7 +183,6 @@ cat << EOF
183#define __IGNORE_ustat /* statfs */ 183#define __IGNORE_ustat /* statfs */
184#define __IGNORE_utime /* utimes */ 184#define __IGNORE_utime /* utimes */
185#define __IGNORE_vfork /* clone */ 185#define __IGNORE_vfork /* clone */
186#define __IGNORE_wait4 /* waitid */
187 186
188/* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */ 187/* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */
189#ifdef __NR_sync_file_range2 188#ifdef __NR_sync_file_range2
diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl
index ec7d21161bdc..b444e89a0095 100755
--- a/scripts/checkversion.pl
+++ b/scripts/checkversion.pl
@@ -5,23 +5,22 @@
5# including <linux/version.h> that don't need it. 5# including <linux/version.h> that don't need it.
6# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net> 6# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
7 7
8use strict;
9
8$| = 1; 10$| = 1;
9 11
10my $debugging = 0; 12my $debugging;
11 13
12foreach $file (@ARGV) 14foreach my $file (@ARGV) {
13{
14 # Open this file. 15 # Open this file.
15 open(FILE, $file) || die "Can't open $file: $!\n"; 16 open( my $f, '<', $file )
17 or die "Can't open $file: $!\n";
16 18
17 # Initialize variables. 19 # Initialize variables.
18 my $fInComment = 0; 20 my ($fInComment, $fInString, $fUseVersion);
19 my $fInString = 0;
20 my $fUseVersion = 0;
21 my $iLinuxVersion = 0; 21 my $iLinuxVersion = 0;
22 22
23 LINE: while ( <FILE> ) 23 while (<$f>) {
24 {
25 # Strip comments. 24 # Strip comments.
26 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); 25 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
27 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); 26 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
@@ -43,8 +42,8 @@ foreach $file (@ARGV)
43 # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE 42 # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
44 if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) { 43 if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) {
45 $fUseVersion = 1; 44 $fUseVersion = 1;
46 last LINE if $iLinuxVersion; 45 last if $iLinuxVersion;
47 } 46 }
48 } 47 }
49 48
50 # Report used version IDs without include? 49 # Report used version IDs without include?
@@ -67,5 +66,5 @@ foreach $file (@ARGV)
67 } 66 }
68 } 67 }
69 68
70 close(FILE); 69 close($f);
71} 70}
diff --git a/scripts/coccicheck b/scripts/coccicheck
new file mode 100755
index 000000000000..b8bcf1f7bed7
--- /dev/null
+++ b/scripts/coccicheck
@@ -0,0 +1,80 @@
1#!/bin/sh
2
3SPATCH="`which ${SPATCH:=spatch}`"
4
5if [ "$C" = "1" -o "$C" = "2" ]; then
6 ONLINE=1
7
8# This requires Coccinelle >= 0.2.3
9# FLAGS="-ignore_unknown_options -very_quiet"
10# OPTIONS=$*
11
12# Workaround for Coccinelle < 0.2.3
13 FLAGS="-I $srctree/include -very_quiet"
14 shift $(( $# - 1 ))
15 OPTIONS=$1
16else
17 ONLINE=0
18 FLAGS="-very_quiet"
19fi
20
21if [ ! -x "$SPATCH" ]; then
22 echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
23 exit 1
24fi
25
26if [ "$MODE" = "" ] ; then
27 if [ "$ONLINE" = "0" ] ; then
28 echo 'You have not explicitly specify the mode to use. Fallback to "report".'
29 echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
30 echo 'Available modes are: report, patch, context, org'
31 fi
32 MODE="report"
33fi
34
35if [ "$ONLINE" = "0" ] ; then
36 echo ''
37 echo 'Please check for false positives in the output before submitting a patch.'
38 echo 'When using "patch" mode, carefully review the patch before submitting it.'
39 echo ''
40fi
41
42coccinelle () {
43 COCCI="$1"
44
45 OPT=`grep "Option" $COCCI | cut -d':' -f2`
46
47# The option '-parse_cocci' can be used to syntaxically check the SmPL files.
48#
49# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
50
51 if [ "$ONLINE" = "0" ] ; then
52
53 FILE=`echo $COCCI | sed "s|$srctree/||"`
54
55 echo "Processing `basename $COCCI` with option(s) \"$OPT\""
56 echo 'Message example to submit a patch:'
57
58 sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
59
60 echo ' The semantic patch that makes this change is available'
61 echo " in $FILE."
62 echo ''
63 echo ' More information about semantic patching is available at'
64 echo ' http://coccinelle.lip6.fr/'
65 echo ''
66
67 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1
68 else
69 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
70 fi
71
72}
73
74if [ "$COCCI" = "" ] ; then
75 for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
76 coccinelle $f
77 done
78else
79 coccinelle $COCCI
80fi
diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
new file mode 100644
index 000000000000..7d4771d449c3
--- /dev/null
+++ b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
@@ -0,0 +1,67 @@
1///
2/// Casting (void *) value returned by kmalloc is useless
3/// as mentioned in Documentation/CodingStyle, Chap 14.
4///
5// Confidence: High
6// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2.
7// URL: http://coccinelle.lip6.fr/
8// Options: -no_includes -include_headers
9//
10// Keywords: kmalloc, kzalloc, kcalloc
11// Version min: < 2.6.12 kmalloc
12// Version min: < 2.6.12 kcalloc
13// Version min: 2.6.14 kzalloc
14//
15
16virtual context
17virtual patch
18virtual org
19virtual report
20
21//----------------------------------------------------------
22// For context mode
23//----------------------------------------------------------
24
25@depends on context@
26type T;
27@@
28
29* (T *)
30 \(kmalloc\|kzalloc\|kcalloc\)(...)
31
32//----------------------------------------------------------
33// For patch mode
34//----------------------------------------------------------
35
36@depends on patch@
37type T;
38@@
39
40- (T *)
41 \(kmalloc\|kzalloc\|kcalloc\)(...)
42
43//----------------------------------------------------------
44// For org and report mode
45//----------------------------------------------------------
46
47@r depends on org || report@
48type T;
49position p;
50@@
51
52 (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
53
54@script:python depends on org@
55p << r.p;
56t << r.T;
57@@
58
59coccilib.org.print_safe_todo(p[0], t)
60
61@script:python depends on report@
62p << r.p;
63t << r.T;
64@@
65
66msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
67coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/alloc/kzalloc-simple.cocci
new file mode 100644
index 000000000000..2eae828fc657
--- /dev/null
+++ b/scripts/coccinelle/alloc/kzalloc-simple.cocci
@@ -0,0 +1,82 @@
1///
2/// kzalloc should be used rather than kmalloc followed by memset 0
3///
4// Confidence: High
5// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
6// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
7// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
8// Options: -no_includes -include_headers
9//
10// Keywords: kmalloc, kzalloc
11// Version min: < 2.6.12 kmalloc
12// Version min: 2.6.14 kzalloc
13//
14
15virtual context
16virtual patch
17virtual org
18virtual report
19
20//----------------------------------------------------------
21// For context mode
22//----------------------------------------------------------
23
24@depends on context@
25type T, T2;
26expression x;
27expression E1,E2;
28statement S;
29@@
30
31* x = (T)kmalloc(E1,E2);
32 if ((x==NULL) || ...) S
33* memset((T2)x,0,E1);
34
35//----------------------------------------------------------
36// For patch mode
37//----------------------------------------------------------
38
39@depends on patch@
40type T, T2;
41expression x;
42expression E1,E2;
43statement S;
44@@
45
46- x = (T)kmalloc(E1,E2);
47+ x = kzalloc(E1,E2);
48 if ((x==NULL) || ...) S
49- memset((T2)x,0,E1);
50
51//----------------------------------------------------------
52// For org mode
53//----------------------------------------------------------
54
55@r depends on org || report@
56type T, T2;
57expression x;
58expression E1,E2;
59statement S;
60position p;
61@@
62
63 x = (T)kmalloc@p(E1,E2);
64 if ((x==NULL) || ...) S
65 memset((T2)x,0,E1);
66
67@script:python depends on org@
68p << r.p;
69x << r.x;
70@@
71
72msg="%s" % (x)
73msg_safe=msg.replace("[","@(").replace("]",")")
74coccilib.org.print_todo(p[0], msg_safe)
75
76@script:python depends on report@
77p << r.p;
78x << r.x;
79@@
80
81msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
82coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/deref_null.cocci
new file mode 100644
index 000000000000..9969d76d0f4b
--- /dev/null
+++ b/scripts/coccinelle/deref_null.cocci
@@ -0,0 +1,293 @@
1///
2/// A variable is dereference under a NULL test.
3/// Even though it is know to be NULL.
4///
5// Confidence: Moderate
6// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
7// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
8// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
9// URL: http://coccinelle.lip6.fr/
10// Comments: -I ... -all_includes can give more complete results
11// Options:
12
13virtual context
14virtual patch
15virtual org
16virtual report
17
18@initialize:python depends on !context && patch && !org && !report@
19
20import sys
21print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
22
23@depends on patch@
24@@
25
26this_rule_should_never_matches();
27
28@ifm depends on !patch@
29expression *E;
30statement S1,S2;
31position p1;
32@@
33
34if@p1 ((E == NULL && ...) || ...) S1 else S2
35
36// The following two rules are separate, because both can match a single
37// expression in different ways
38@pr1 depends on !patch expression@
39expression *ifm.E;
40identifier f;
41position p1;
42@@
43
44 (E != NULL && ...) ? <+...E->f@p1...+> : ...
45
46@pr2 depends on !patch expression@
47expression *ifm.E;
48identifier f;
49position p2;
50@@
51
52(
53 (E != NULL) && ... && <+...E->f@p2...+>
54|
55 (E == NULL) || ... || <+...E->f@p2...+>
56|
57 sizeof(<+...E->f@p2...+>)
58)
59
60// For org and report modes
61
62@r depends on !context && !patch && (org || report) exists@
63expression subE <= ifm.E;
64expression *ifm.E;
65expression E1,E2;
66identifier f;
67statement S1,S2,S3,S4;
68iterator iter;
69position p!={pr1.p1,pr2.p2};
70position ifm.p1;
71@@
72
73if@p1 ((E == NULL && ...) || ...)
74{
75 ... when != if (...) S1 else S2
76(
77 iter(subE,...) S4 // no use
78|
79 list_remove_head(E2,subE,...)
80|
81 subE = E1
82|
83 for(subE = E1;...;...) S4
84|
85 subE++
86|
87 ++subE
88|
89 --subE
90|
91 subE--
92|
93 &subE
94|
95 E->f@p // bad use
96)
97 ... when any
98 return ...;
99}
100else S3
101
102@script:python depends on !context && !patch && !org && report@
103p << r.p;
104p1 << ifm.p1;
105x << ifm.E;
106@@
107
108msg="ERROR: %s is NULL but dereferenced." % (x)
109coccilib.report.print_report(p[0], msg)
110cocci.include_match(False)
111
112@script:python depends on !context && !patch && org && !report@
113p << r.p;
114p1 << ifm.p1;
115x << ifm.E;
116@@
117
118msg="ERROR: %s is NULL but dereferenced." % (x)
119msg_safe=msg.replace("[","@(").replace("]",")")
120cocci.print_main(msg_safe,p)
121cocci.include_match(False)
122
123@s depends on !context && !patch && (org || report) exists@
124expression subE <= ifm.E;
125expression *ifm.E;
126expression E1,E2;
127identifier f;
128statement S1,S2,S3,S4;
129iterator iter;
130position p!={pr1.p1,pr2.p2};
131position ifm.p1;
132@@
133
134if@p1 ((E == NULL && ...) || ...)
135{
136 ... when != if (...) S1 else S2
137(
138 iter(subE,...) S4 // no use
139|
140 list_remove_head(E2,subE,...)
141|
142 subE = E1
143|
144 for(subE = E1;...;...) S4
145|
146 subE++
147|
148 ++subE
149|
150 --subE
151|
152 subE--
153|
154 &subE
155|
156 E->f@p // bad use
157)
158 ... when any
159}
160else S3
161
162@script:python depends on !context && !patch && !org && report@
163p << s.p;
164p1 << ifm.p1;
165x << ifm.E;
166@@
167
168msg="ERROR: %s is NULL but dereferenced." % (x)
169coccilib.report.print_report(p[0], msg)
170
171@script:python depends on !context && !patch && org && !report@
172p << s.p;
173p1 << ifm.p1;
174x << ifm.E;
175@@
176
177msg="ERROR: %s is NULL but dereferenced." % (x)
178msg_safe=msg.replace("[","@(").replace("]",")")
179cocci.print_main(msg_safe,p)
180
181// For context mode
182
183@depends on context && !patch && !org && !report exists@
184expression subE <= ifm.E;
185expression *ifm.E;
186expression E1,E2;
187identifier f;
188statement S1,S2,S3,S4;
189iterator iter;
190position p!={pr1.p1,pr2.p2};
191position ifm.p1;
192@@
193
194if@p1 ((E == NULL && ...) || ...)
195{
196 ... when != if (...) S1 else S2
197(
198 iter(subE,...) S4 // no use
199|
200 list_remove_head(E2,subE,...)
201|
202 subE = E1
203|
204 for(subE = E1;...;...) S4
205|
206 subE++
207|
208 ++subE
209|
210 --subE
211|
212 subE--
213|
214 &subE
215|
216* E->f@p // bad use
217)
218 ... when any
219 return ...;
220}
221else S3
222
223// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
224// It is need because the previous rule as already made a "change".
225
226@ifm1 depends on !patch@
227expression *E;
228statement S1,S2;
229position p1;
230@@
231
232if@p1 ((E == NULL && ...) || ...) S1 else S2
233
234@pr11 depends on !patch expression@
235expression *ifm1.E;
236identifier f;
237position p1;
238@@
239
240 (E != NULL && ...) ? <+...E->f@p1...+> : ...
241
242@pr12 depends on !patch expression@
243expression *ifm1.E;
244identifier f;
245position p2;
246@@
247
248(
249 (E != NULL) && ... && <+...E->f@p2...+>
250|
251 (E == NULL) || ... || <+...E->f@p2...+>
252|
253 sizeof(<+...E->f@p2...+>)
254)
255
256@depends on context && !patch && !org && !report exists@
257expression subE <= ifm1.E;
258expression *ifm1.E;
259expression E1,E2;
260identifier f;
261statement S1,S2,S3,S4;
262iterator iter;
263position p!={pr11.p1,pr12.p2};
264position ifm1.p1;
265@@
266
267if@p1 ((E == NULL && ...) || ...)
268{
269 ... when != if (...) S1 else S2
270(
271 iter(subE,...) S4 // no use
272|
273 list_remove_head(E2,subE,...)
274|
275 subE = E1
276|
277 for(subE = E1;...;...) S4
278|
279 subE++
280|
281 ++subE
282|
283 --subE
284|
285 subE--
286|
287 &subE
288|
289* E->f@p // bad use
290)
291 ... when any
292}
293else S3
diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/err_cast.cocci
new file mode 100644
index 000000000000..2ce115000af6
--- /dev/null
+++ b/scripts/coccinelle/err_cast.cocci
@@ -0,0 +1,56 @@
1///
2/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
3///
4// Confidence: High
5// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
6// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
7// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
8// URL: http://coccinelle.lip6.fr/
9// Options:
10//
11// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
12// Version min: 2.6.25
13//
14
15virtual context
16virtual patch
17virtual org
18virtual report
19
20
21@ depends on context && !patch && !org && !report@
22expression x;
23@@
24
25* ERR_PTR(PTR_ERR(x))
26
27@ depends on !context && patch && !org && !report @
28expression x;
29@@
30
31- ERR_PTR(PTR_ERR(x))
32+ ERR_CAST(x)
33
34@r depends on !context && !patch && (org || report)@
35expression x;
36position p;
37@@
38
39 ERR_PTR@p(PTR_ERR(x))
40
41@script:python depends on org@
42p << r.p;
43x << r.x;
44@@
45
46msg="WARNING ERR_CAST can be used with %s" % (x)
47msg_safe=msg.replace("[","@(").replace("]",")")
48coccilib.org.print_todo(p[0], msg_safe)
49
50@script:python depends on report@
51p << r.p;
52x << r.x;
53@@
54
55msg="WARNING: ERR_CAST can be used with %s" % (x)
56coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/resource_size.cocci
new file mode 100644
index 000000000000..1935a58b39d9
--- /dev/null
+++ b/scripts/coccinelle/resource_size.cocci
@@ -0,0 +1,93 @@
1///
2/// Use resource_size function on resource object
3/// instead of explicit computation.
4///
5// Confidence: High
6// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
7// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
8// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
9// URL: http://coccinelle.lip6.fr/
10// Options:
11//
12// Keywords: resource_size
13// Version min: 2.6.27 resource_size
14//
15
16virtual context
17virtual patch
18virtual org
19virtual report
20
21//----------------------------------------------------------
22// For context mode
23//----------------------------------------------------------
24
25@r_context depends on context && !patch && !org@
26struct resource *res;
27@@
28
29* (res->end - res->start) + 1
30
31//----------------------------------------------------------
32// For patch mode
33//----------------------------------------------------------
34
35@r_patch depends on !context && patch && !org@
36struct resource *res;
37@@
38
39- (res->end - res->start) + 1
40+ resource_size(res)
41
42//----------------------------------------------------------
43// For org mode
44//----------------------------------------------------------
45
46
47@r_org depends on !context && !patch && (org || report)@
48struct resource *res;
49position p;
50@@
51
52 (res->end@p - res->start) + 1
53
54@rbad_org depends on !context && !patch && (org || report)@
55struct resource *res;
56position p != r_org.p;
57@@
58
59 res->end@p - res->start
60
61@script:python depends on org@
62p << r_org.p;
63x << r_org.res;
64@@
65
66msg="ERROR with %s" % (x)
67msg_safe=msg.replace("[","@(").replace("]",")")
68coccilib.org.print_todo(p[0], msg_safe)
69
70@script:python depends on report@
71p << r_org.p;
72x << r_org.res;
73@@
74
75msg="ERROR: Missing resource_size with %s" % (x)
76coccilib.report.print_report(p[0], msg)
77
78@script:python depends on org@
79p << rbad_org.p;
80x << rbad_org.res;
81@@
82
83msg="WARNING with %s" % (x)
84msg_safe=msg.replace("[","@(").replace("]",")")
85coccilib.org.print_todo(p[0], msg_safe)
86
87@script:python depends on report@
88p << rbad_org.p;
89x << rbad_org.res;
90@@
91
92msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
93coccilib.report.print_report(p[0], msg)
diff --git a/scripts/decodecode b/scripts/decodecode
index 4b00647814bc..18ba881c3415 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -7,7 +7,7 @@
7# AFLAGS=--32 decodecode < 386.oops 7# AFLAGS=--32 decodecode < 386.oops
8 8
9cleanup() { 9cleanup() {
10 rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa 10 rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
11 exit 1 11 exit 1
12} 12}
13 13
@@ -39,6 +39,29 @@ fi
39echo $code 39echo $code
40code=`echo $code | sed -e 's/.*Code: //'` 40code=`echo $code | sed -e 's/.*Code: //'`
41 41
42width=`expr index "$code" ' '`
43width=$((($width-1)/2))
44case $width in
451) type=byte ;;
462) type=2byte ;;
474) type=4byte ;;
48esac
49
50disas() {
51 ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
52
53 if [ "$ARCH" = "arm" ]; then
54 if [ $width -eq 2 ]; then
55 OBJDUMPFLAGS="-M force-thumb"
56 fi
57
58 ${CROSS_COMPILE}strip $1.o
59 fi
60
61 ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
62 grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
63}
64
42marker=`expr index "$code" "\<"` 65marker=`expr index "$code" "\<"`
43if [ $marker -eq 0 ]; then 66if [ $marker -eq 0 ]; then
44 marker=`expr index "$code" "\("` 67 marker=`expr index "$code" "\("`
@@ -49,26 +72,25 @@ if [ $marker -ne 0 ]; then
49 echo All code >> $T.oo 72 echo All code >> $T.oo
50 echo ======== >> $T.oo 73 echo ======== >> $T.oo
51 beforemark=`echo "$code"` 74 beforemark=`echo "$code"`
52 echo -n " .byte 0x" > $T.s 75 echo -n " .$type 0x" > $T.s
53 echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s 76 echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
54 as $AFLAGS -o $T.o $T.s &> /dev/null 77 disas $T
55 objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo 78 cat $T.dis >> $T.oo
56 cat $T.ooo >> $T.oo 79 rm -f $T.o $T.s $T.dis
57 rm -f $T.o $T.s $T.ooo
58 80
59# and fix code at-and-after marker 81# and fix code at-and-after marker
60 code=`echo "$code" | cut -c$((${marker} + 1))-` 82 code=`echo "$code" | cut -c$((${marker} + 1))-`
61fi 83fi
62echo Code starting with the faulting instruction > $T.aa 84echo Code starting with the faulting instruction > $T.aa
63echo =========================================== >> $T.aa 85echo =========================================== >> $T.aa
64code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` 86code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
65echo -n " .byte 0x" > $T.s 87echo -n " .$type 0x" > $T.s
66echo $code >> $T.s 88echo $code >> $T.s
67as $AFLAGS -o $T.o $T.s &> /dev/null 89disas $T
68objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa 90cat $T.dis >> $T.aa
69cat $T.aaa >> $T.aa
70 91
71faultline=`cat $T.aaa | head -1 | cut -d":" -f2` 92faultline=`cat $T.dis | head -1 | cut -d":" -f2`
93faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
72 94
73cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g" 95cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g"
74echo 96echo
diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
index 766b2694d935..8fe1bdf239f0 100644
--- a/scripts/dtc/fstree.c
+++ b/scripts/dtc/fstree.c
@@ -77,6 +77,7 @@ static struct node *read_fstree(const char *dirname)
77 free(tmpnam); 77 free(tmpnam);
78 } 78 }
79 79
80 closedir(d);
80 return tree; 81 return tree;
81} 82}
82 83
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index 705b5ba7c152..04dce7c15f83 100644
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -49,10 +49,10 @@ sub usage {
49} 49}
50 50
51sub collectcfiles { 51sub collectcfiles {
52 my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`; 52 my @file
53 @file = grep {s/\.ko/.mod.c/} @file; 53 = `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`;
54 chomp @file; 54 chomp @file;
55 return @file; 55 return @file;
56} 56}
57 57
58my (%SYMBOL, %MODULE, %opt, @allcfiles); 58my (%SYMBOL, %MODULE, %opt, @allcfiles);
@@ -71,37 +71,40 @@ if (not defined $opt{'k'}) {
71 $opt{'k'} = "Module.symvers"; 71 $opt{'k'} = "Module.symvers";
72} 72}
73 73
74unless (open(MODULE_SYMVERS, $opt{'k'})) { 74open (my $module_symvers, '<', $opt{'k'})
75 die "Sorry, cannot open $opt{'k'}: $!\n"; 75 or die "Sorry, cannot open $opt{'k'}: $!\n";
76}
77 76
78if (defined $opt{'o'}) { 77if (defined $opt{'o'}) {
79 unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) { 78 open (my $out, '>', $opt{'o'})
80 die "Sorry, cannot open $opt{'o'} $!\n"; 79 or die "Sorry, cannot open $opt{'o'} $!\n";
81 } 80
82 select OUTPUT_HANDLE; 81 select $out;
83} 82}
83
84# 84#
85# collect all the symbols and their attributes from the 85# collect all the symbols and their attributes from the
86# Module.symvers file 86# Module.symvers file
87# 87#
88while ( <MODULE_SYMVERS> ) { 88while ( <$module_symvers> ) {
89 chomp; 89 chomp;
90 my (undef, $symbol, $module, $gpl) = split; 90 my (undef, $symbol, $module, $gpl) = split;
91 $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; 91 $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
92} 92}
93close(MODULE_SYMVERS); 93close($module_symvers);
94 94
95# 95#
96# collect the usage count of each symbol. 96# collect the usage count of each symbol.
97# 97#
98foreach my $thismod (@allcfiles) { 98foreach my $thismod (@allcfiles) {
99 unless (open(MODULE_MODULE, $thismod)) { 99 my $module;
100 print "Sorry, cannot open $thismod: $!\n"; 100
101 unless (open ($module, '<', $thismod)) {
102 warn "Sorry, cannot open $thismod: $!\n";
101 next; 103 next;
102 } 104 }
105
103 my $state=0; 106 my $state=0;
104 while ( <MODULE_MODULE> ) { 107 while ( <$module> ) {
105 chomp; 108 chomp;
106 if ($state == 0) { 109 if ($state == 0) {
107 $state = 1 if ($_ =~ /static const struct modversion_info/); 110 $state = 1 if ($_ =~ /static const struct modversion_info/);
@@ -124,7 +127,7 @@ foreach my $thismod (@allcfiles) {
124 if ($state != 2) { 127 if ($state != 2) {
125 print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n"; 128 print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
126 } 129 }
127 close(MODULE_MODULE); 130 close($module);
128} 131}
129 132
130print "\tThis file reports the exported symbols usage patterns by in-tree\n", 133print "\tThis file reports the exported symbols usage patterns by in-tree\n",
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 76af5f9623e3..5958fffb2114 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -202,6 +202,7 @@ input_file() {
202 print_mtime "$1" >> ${output} 202 print_mtime "$1" >> ${output}
203 cat "$1" >> ${output} 203 cat "$1" >> ${output}
204 else 204 else
205 echo "$1 \\"
205 cat "$1" | while read type dir file perm ; do 206 cat "$1" | while read type dir file perm ; do
206 if [ "$type" == "file" ]; then 207 if [ "$type" == "file" ]; then
207 echo "$file \\"; 208 echo "$file \\";
@@ -231,7 +232,7 @@ arg="$1"
231case "$arg" in 232case "$arg" in
232 "-l") # files included in initramfs - used by kbuild 233 "-l") # files included in initramfs - used by kbuild
233 dep_list="list_" 234 dep_list="list_"
234 echo "deps_initramfs := \\" 235 echo "deps_initramfs := $0 \\"
235 shift 236 shift
236 ;; 237 ;;
237 "-o") # generate compressed cpio image named $1 238 "-o") # generate compressed cpio image named $1
@@ -242,6 +243,7 @@ case "$arg" in
242 echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f" 243 echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f"
243 echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f" 244 echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f"
244 echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f" 245 echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f"
246 echo "$output_file" | grep -q "\.lzo$" && compr="lzop -9 -f"
245 echo "$output_file" | grep -q "\.cpio$" && compr="cat" 247 echo "$output_file" | grep -q "\.cpio$" && compr="cat"
246 shift 248 shift
247 ;; 249 ;;
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index af6b8363a2d5..f99115ebe925 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -758,8 +758,10 @@ int main(int argc, char **argv)
758 /* setlinebuf(debugfile); */ 758 /* setlinebuf(debugfile); */
759 } 759 }
760 760
761 if (flag_reference) 761 if (flag_reference) {
762 read_reference(ref_file); 762 read_reference(ref_file);
763 fclose(ref_file);
764 }
763 765
764 yyparse(); 766 yyparse();
765 767
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 6f97a13bcee4..b2281982f52f 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -13,7 +13,7 @@
13use strict; 13use strict;
14 14
15my $P = $0; 15my $P = $0;
16my $V = '0.23'; 16my $V = '0.24';
17 17
18use Getopt::Long qw(:config no_auto_abbrev); 18use Getopt::Long qw(:config no_auto_abbrev);
19 19
@@ -25,6 +25,7 @@ my $email_list = 1;
25my $email_subscriber_list = 0; 25my $email_subscriber_list = 0;
26my $email_git_penguin_chiefs = 0; 26my $email_git_penguin_chiefs = 0;
27my $email_git = 1; 27my $email_git = 1;
28my $email_git_all_signature_types = 0;
28my $email_git_blame = 0; 29my $email_git_blame = 0;
29my $email_git_min_signatures = 1; 30my $email_git_min_signatures = 1;
30my $email_git_max_maintainers = 5; 31my $email_git_max_maintainers = 5;
@@ -51,9 +52,9 @@ my $help = 0;
51my $exit = 0; 52my $exit = 0;
52 53
53my @penguin_chief = (); 54my @penguin_chief = ();
54push(@penguin_chief,"Linus Torvalds:torvalds\@linux-foundation.org"); 55push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org");
55#Andrew wants in on most everything - 2009/01/14 56#Andrew wants in on most everything - 2009/01/14
56#push(@penguin_chief,"Andrew Morton:akpm\@linux-foundation.org"); 57#push(@penguin_chief, "Andrew Morton:akpm\@linux-foundation.org");
57 58
58my @penguin_chief_names = (); 59my @penguin_chief_names = ();
59foreach my $chief (@penguin_chief) { 60foreach my $chief (@penguin_chief) {
@@ -63,7 +64,16 @@ foreach my $chief (@penguin_chief) {
63 push(@penguin_chief_names, $chief_name); 64 push(@penguin_chief_names, $chief_name);
64 } 65 }
65} 66}
66my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)"; 67my $penguin_chiefs = "\(" . join("|", @penguin_chief_names) . "\)";
68
69# Signature types of people who are either
70# a) responsible for the code in question, or
71# b) familiar enough with it to give relevant feedback
72my @signature_tags = ();
73push(@signature_tags, "Signed-off-by:");
74push(@signature_tags, "Reviewed-by:");
75push(@signature_tags, "Acked-by:");
76my $signaturePattern = "\(" . join("|", @signature_tags) . "\)";
67 77
68# rfc822 email address - preloaded methods go here. 78# rfc822 email address - preloaded methods go here.
69my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; 79my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
@@ -97,9 +107,34 @@ my %VCS_cmds_hg = (
97 "blame_commit_pattern" => "^([0-9a-f]+):" 107 "blame_commit_pattern" => "^([0-9a-f]+):"
98); 108);
99 109
110if (-f "${lk_path}.get_maintainer.conf") {
111 my @conf_args;
112 open(my $conffile, '<', "${lk_path}.get_maintainer.conf")
113 or warn "$P: Can't open .get_maintainer.conf: $!\n";
114 while (<$conffile>) {
115 my $line = $_;
116
117 $line =~ s/\s*\n?$//g;
118 $line =~ s/^\s*//g;
119 $line =~ s/\s+/ /g;
120
121 next if ($line =~ m/^\s*#/);
122 next if ($line =~ m/^\s*$/);
123
124 my @words = split(" ", $line);
125 foreach my $word (@words) {
126 last if ($word =~ m/^#/);
127 push (@conf_args, $word);
128 }
129 }
130 close($conffile);
131 unshift(@ARGV, @conf_args) if @conf_args;
132}
133
100if (!GetOptions( 134if (!GetOptions(
101 'email!' => \$email, 135 'email!' => \$email,
102 'git!' => \$email_git, 136 'git!' => \$email_git,
137 'git-all-signature-types!' => \$email_git_all_signature_types,
103 'git-blame!' => \$email_git_blame, 138 'git-blame!' => \$email_git_blame,
104 'git-chief-penguins!' => \$email_git_penguin_chiefs, 139 'git-chief-penguins!' => \$email_git_penguin_chiefs,
105 'git-min-signatures=i' => \$email_git_min_signatures, 140 'git-min-signatures=i' => \$email_git_min_signatures,
@@ -180,6 +215,10 @@ if (!top_of_kernel_tree($lk_path)) {
180 . "a linux kernel source tree.\n"; 215 . "a linux kernel source tree.\n";
181} 216}
182 217
218if ($email_git_all_signature_types) {
219 $signaturePattern = "(.+?)[Bb][Yy]:";
220}
221
183## Read MAINTAINERS for type/value pairs 222## Read MAINTAINERS for type/value pairs
184 223
185my @typevalue = (); 224my @typevalue = ();
@@ -497,13 +536,15 @@ version: $V
497MAINTAINER field selection options: 536MAINTAINER field selection options:
498 --email => print email address(es) if any 537 --email => print email address(es) if any
499 --git => include recent git \*-by: signers 538 --git => include recent git \*-by: signers
539 --git-all-signature-types => include signers regardless of signature type
540 or use only ${signaturePattern} signers (default: $email_git_all_signature_types)
500 --git-chief-penguins => include ${penguin_chiefs} 541 --git-chief-penguins => include ${penguin_chiefs}
501 --git-min-signatures => number of signatures required (default: 1) 542 --git-min-signatures => number of signatures required (default: $email_git_min_signatures)
502 --git-max-maintainers => maximum maintainers to add (default: 5) 543 --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
503 --git-min-percent => minimum percentage of commits required (default: 5) 544 --git-min-percent => minimum percentage of commits required (default: $email_git_min_percent)
504 --git-blame => use git blame to find modified commits for patch or file 545 --git-blame => use git blame to find modified commits for patch or file
505 --git-since => git history to use (default: 1-year-ago) 546 --git-since => git history to use (default: $email_git_since)
506 --hg-since => hg history to use (default: -365) 547 --hg-since => hg history to use (default: $email_hg_since)
507 --m => include maintainer(s) if any 548 --m => include maintainer(s) if any
508 --n => include name 'Full Name <addr\@domain.tld>' 549 --n => include name 'Full Name <addr\@domain.tld>'
509 --l => include list(s) if any 550 --l => include list(s) if any
@@ -556,6 +597,11 @@ Notes:
556 --git-min-signatures, --git-max-maintainers, --git-min-percent, and 597 --git-min-signatures, --git-max-maintainers, --git-min-percent, and
557 --git-blame 598 --git-blame
558 Use --hg-since not --git-since to control date selection 599 Use --hg-since not --git-since to control date selection
600 File ".get_maintainer.conf", if it exists in the linux kernel source root
601 directory, can change whatever get_maintainer defaults are desired.
602 Entries in this file can be any command line argument.
603 This file is prepended to any additional command line arguments.
604 Multiple lines and # comments are allowed.
559EOT 605EOT
560} 606}
561 607
@@ -964,7 +1010,7 @@ sub vcs_find_signers {
964 1010
965 $commits = grep(/$pattern/, @lines); # of commits 1011 $commits = grep(/$pattern/, @lines); # of commits
966 1012
967 @lines = grep(/^[-_ a-z]+by:.*\@.*$/i, @lines); 1013 @lines = grep(/^[ \t]*${signaturePattern}.*\@.*$/, @lines);
968 if (!$email_git_penguin_chiefs) { 1014 if (!$email_git_penguin_chiefs) {
969 @lines = grep(!/${penguin_chiefs}/i, @lines); 1015 @lines = grep(!/${penguin_chiefs}/i, @lines);
970 } 1016 }
diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl
index b7f6c560e24d..8dd019bc5a73 100755
--- a/scripts/headerdep.pl
+++ b/scripts/headerdep.pl
@@ -80,8 +80,7 @@ sub search {
80 my $path = "$i/$filename"; 80 my $path = "$i/$filename";
81 return $path if -f $path; 81 return $path if -f $path;
82 } 82 }
83 83 return;
84 return undef;
85} 84}
86 85
87sub parse_all { 86sub parse_all {
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl
index db1dd7a549f2..50d6cfd1fa77 100644
--- a/scripts/headers_check.pl
+++ b/scripts/headers_check.pl
@@ -28,11 +28,12 @@ my $lineno = 0;
28my $filename; 28my $filename;
29 29
30foreach my $file (@files) { 30foreach my $file (@files) {
31 local *FH;
32 $filename = $file; 31 $filename = $file;
33 open(FH, "<$filename") or die "$filename: $!\n"; 32
33 open(my $fh, '<', $filename)
34 or die "$filename: $!\n";
34 $lineno = 0; 35 $lineno = 0;
35 while ($line = <FH>) { 36 while ($line = <$fh>) {
36 $lineno++; 37 $lineno++;
37 &check_include(); 38 &check_include();
38 &check_asm_types(); 39 &check_asm_types();
@@ -40,7 +41,7 @@ foreach my $file (@files) {
40 &check_declarations(); 41 &check_declarations();
41 # Dropped for now. Too much noise &check_config(); 42 # Dropped for now. Too much noise &check_config();
42 } 43 }
43 close FH; 44 close $fh;
44} 45}
45exit $ret; 46exit $ret;
46 47
@@ -78,7 +79,7 @@ sub check_config
78} 79}
79 80
80my $linux_asm_types; 81my $linux_asm_types;
81sub check_asm_types() 82sub check_asm_types
82{ 83{
83 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { 84 if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
84 return; 85 return;
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index b89ca2c58fdb..4ca3be3b2e50 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -23,13 +23,13 @@ my ($readdir, $installdir, $arch, @files) = @ARGV;
23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__"; 23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
24 24
25foreach my $file (@files) { 25foreach my $file (@files) {
26 local *INFILE;
27 local *OUTFILE;
28 my $tmpfile = "$installdir/$file.tmp"; 26 my $tmpfile = "$installdir/$file.tmp";
29 open(INFILE, "<$readdir/$file") 27
30 or die "$readdir/$file: $!\n"; 28 open(my $in, '<', "$readdir/$file")
31 open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n"; 29 or die "$readdir/$file: $!\n";
32 while (my $line = <INFILE>) { 30 open(my $out, '>', $tmpfile)
31 or die "$tmpfile: $!\n";
32 while (my $line = <$in>) {
33 $line =~ s/([\s(])__user\s/$1/g; 33 $line =~ s/([\s(])__user\s/$1/g;
34 $line =~ s/([\s(])__force\s/$1/g; 34 $line =~ s/([\s(])__force\s/$1/g;
35 $line =~ s/([\s(])__iomem\s/$1/g; 35 $line =~ s/([\s(])__iomem\s/$1/g;
@@ -39,10 +39,11 @@ foreach my $file (@files) {
39 $line =~ s/(^|\s)(inline)\b/$1__$2__/g; 39 $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
40 $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; 40 $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
41 $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; 41 $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
42 printf OUTFILE "%s", $line; 42 printf {$out} "%s", $line;
43 } 43 }
44 close OUTFILE; 44 close $out;
45 close INFILE; 45 close $in;
46
46 system $unifdef . " $tmpfile > $installdir/$file"; 47 system $unifdef . " $tmpfile > $installdir/$file";
47 unlink $tmpfile; 48 unlink $tmpfile;
48} 49}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 86c3896a1e01..e3902fb39afd 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -108,8 +108,10 @@ static int read_symbol(FILE *in, struct sym_entry *s)
108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); 108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
109 if (rc != 3) { 109 if (rc != 3) {
110 if (rc != EOF) { 110 if (rc != EOF) {
111 /* skip line */ 111 /* skip line. sym is used as dummy to
112 fgets(str, 500, in); 112 * shut of "warn_unused_result" warning.
113 */
114 sym = fgets(str, 500, in);
113 } 115 }
114 return -1; 116 return -1;
115 } 117 }
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index 6a36a76e6606..624f6502e03e 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -17,6 +17,7 @@ gconf.glade.h
17# 17#
18conf 18conf
19mconf 19mconf
20nconf
20qconf 21qconf
21gconf 22gconf
22kxgettext 23kxgettext
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 186c46604d06..de934def410f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -21,14 +21,17 @@ menuconfig: $(obj)/mconf
21 $< $(Kconfig) 21 $< $(Kconfig)
22 22
23config: $(obj)/conf 23config: $(obj)/conf
24 $< --oldaskconfig $(Kconfig)
25
26nconfig: $(obj)/nconf
24 $< $(Kconfig) 27 $< $(Kconfig)
25 28
26oldconfig: $(obj)/conf 29oldconfig: $(obj)/conf
27 $< -o $(Kconfig) 30 $< --$@ $(Kconfig)
28 31
29silentoldconfig: $(obj)/conf 32silentoldconfig: $(obj)/conf
30 $(Q)mkdir -p include/generated 33 $(Q)mkdir -p include/generated
31 $< -s $(Kconfig) 34 $< --$@ $(Kconfig)
32 35
33# if no path is given, then use src directory to find file 36# if no path is given, then use src directory to find file
34ifdef LSMOD 37ifdef LSMOD
@@ -41,15 +44,15 @@ endif
41localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 44localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
42 $(Q)mkdir -p include/generated 45 $(Q)mkdir -p include/generated
43 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config 46 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
44 $(Q)if [ -f .config ]; then \ 47 $(Q)if [ -f .config ]; then \
45 cmp -s .tmp.config .config || \ 48 cmp -s .tmp.config .config || \
46 (mv -f .config .config.old.1; \ 49 (mv -f .config .config.old.1; \
47 mv -f .tmp.config .config; \ 50 mv -f .tmp.config .config; \
48 $(obj)/conf -s $(Kconfig); \ 51 $(obj)/conf --silentoldconfig $(Kconfig); \
49 mv -f .config.old.1 .config.old) \ 52 mv -f .config.old.1 .config.old) \
50 else \ 53 else \
51 mv -f .tmp.config .config; \ 54 mv -f .tmp.config .config; \
52 $(obj)/conf -s $(Kconfig); \ 55 $(obj)/conf --silentoldconfig $(Kconfig); \
53 fi 56 fi
54 $(Q)rm -f .tmp.config 57 $(Q)rm -f .tmp.config
55 58
@@ -57,15 +60,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
57 $(Q)mkdir -p include/generated 60 $(Q)mkdir -p include/generated
58 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config 61 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
59 $(Q)sed -i s/=m/=y/ .tmp.config 62 $(Q)sed -i s/=m/=y/ .tmp.config
60 $(Q)if [ -f .config ]; then \ 63 $(Q)if [ -f .config ]; then \
61 cmp -s .tmp.config .config || \ 64 cmp -s .tmp.config .config || \
62 (mv -f .config .config.old.1; \ 65 (mv -f .config .config.old.1; \
63 mv -f .tmp.config .config; \ 66 mv -f .tmp.config .config; \
64 $(obj)/conf -s $(Kconfig); \ 67 $(obj)/conf --silentoldconfig $(Kconfig); \
65 mv -f .config.old.1 .config.old) \ 68 mv -f .config.old.1 .config.old) \
66 else \ 69 else \
67 mv -f .tmp.config .config; \ 70 mv -f .tmp.config .config; \
68 $(obj)/conf -s $(Kconfig); \ 71 $(obj)/conf --silentoldconfig $(Kconfig); \
69 fi 72 fi
70 $(Q)rm -f .tmp.config 73 $(Q)rm -f .tmp.config
71 74
@@ -92,34 +95,34 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
92 $(Q)rm -f arch/um/Kconfig.arch 95 $(Q)rm -f arch/um/Kconfig.arch
93 $(Q)rm -f $(obj)/config.pot 96 $(Q)rm -f $(obj)/config.pot
94 97
95PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig 98PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
96 99
97randconfig: $(obj)/conf 100allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
98 $< -r $(Kconfig) 101 $< --$@ $(Kconfig)
99 102
100allyesconfig: $(obj)/conf 103PHONY += listnewconfig oldnoconfig savedefconfig defconfig
101 $< -y $(Kconfig)
102 104
103allnoconfig: $(obj)/conf 105listnewconfig oldnoconfig: $(obj)/conf
104 $< -n $(Kconfig) 106 $< --$@ $(Kconfig)
105 107
106allmodconfig: $(obj)/conf 108savedefconfig: $(obj)/conf
107 $< -m $(Kconfig) 109 $< --$@=defconfig $(Kconfig)
108 110
109defconfig: $(obj)/conf 111defconfig: $(obj)/conf
110ifeq ($(KBUILD_DEFCONFIG),) 112ifeq ($(KBUILD_DEFCONFIG),)
111 $< -d $(Kconfig) 113 $< --defconfig $(Kconfig)
112else 114else
113 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" 115 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
114 $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) 116 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
115endif 117endif
116 118
117%_defconfig: $(obj)/conf 119%_defconfig: $(obj)/conf
118 $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) 120 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
119 121
120# Help text used by make help 122# Help text used by make help
121help: 123help:
122 @echo ' config - Update current config utilising a line-oriented program' 124 @echo ' config - Update current config utilising a line-oriented program'
125 @echo ' nconfig - Update current config utilising a ncurses menu based program'
123 @echo ' menuconfig - Update current config utilising a menu based program' 126 @echo ' menuconfig - Update current config utilising a menu based program'
124 @echo ' xconfig - Update current config utilising a QT based front-end' 127 @echo ' xconfig - Update current config utilising a QT based front-end'
125 @echo ' gconfig - Update current config utilising a GTK based front-end' 128 @echo ' gconfig - Update current config utilising a GTK based front-end'
@@ -127,11 +130,15 @@ help:
127 @echo ' localmodconfig - Update current config disabling modules not loaded' 130 @echo ' localmodconfig - Update current config disabling modules not loaded'
128 @echo ' localyesconfig - Update current config converting local mods to core' 131 @echo ' localyesconfig - Update current config converting local mods to core'
129 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' 132 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
130 @echo ' randconfig - New config with random answer to all options' 133 @echo ' defconfig - New config with default from ARCH supplied defconfig'
131 @echo ' defconfig - New config with default answer to all options' 134 @echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
132 @echo ' allmodconfig - New config selecting modules when possible'
133 @echo ' allyesconfig - New config where all options are accepted with yes'
134 @echo ' allnoconfig - New config where all options are answered with no' 135 @echo ' allnoconfig - New config where all options are answered with no'
136 @echo ' allyesconfig - New config where all options are accepted with yes'
137 @echo ' allmodconfig - New config selecting modules when possible'
138 @echo ' alldefconfig - New config with all symbols set to default'
139 @echo ' randconfig - New config with random answer to all options'
140 @echo ' listnewconfig - List new options'
141 @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)'
135 142
136# lxdialog stuff 143# lxdialog stuff
137check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh 144check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
@@ -147,6 +154,8 @@ HOST_EXTRACFLAGS += -DLOCALE
147# =========================================================================== 154# ===========================================================================
148# Shared Makefile for the various kconfig executables: 155# Shared Makefile for the various kconfig executables:
149# conf: Used for defconfig, oldconfig and related targets 156# conf: Used for defconfig, oldconfig and related targets
157# nconf: Used for the nconfig target.
158# Utilizes ncurses
150# mconf: Used for the menuconfig target 159# mconf: Used for the menuconfig target
151# Utilizes the lxdialog package 160# Utilizes the lxdialog package
152# qconf: Used for the xconfig target 161# qconf: Used for the xconfig target
@@ -159,11 +168,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
159lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o 168lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
160 169
161conf-objs := conf.o zconf.tab.o 170conf-objs := conf.o zconf.tab.o
162mconf-objs := mconf.o zconf.tab.o $(lxdialog) 171mconf-objs := mconf.o zconf.tab.o $(lxdialog)
172nconf-objs := nconf.o zconf.tab.o nconf.gui.o
163kxgettext-objs := kxgettext.o zconf.tab.o 173kxgettext-objs := kxgettext.o zconf.tab.o
164 174
165hostprogs-y := conf qconf gconf kxgettext 175hostprogs-y := conf qconf gconf kxgettext
166 176
177ifeq ($(MAKECMDGOALS),nconfig)
178 hostprogs-y += nconf
179endif
180
167ifeq ($(MAKECMDGOALS),menuconfig) 181ifeq ($(MAKECMDGOALS),menuconfig)
168 hostprogs-y += mconf 182 hostprogs-y += mconf
169endif 183endif
@@ -187,7 +201,7 @@ endif
187 201
188clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ 202clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
189 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h 203 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
190clean-files += mconf qconf gconf 204clean-files += mconf qconf gconf nconf
191clean-files += config.pot linux.pot 205clean-files += config.pot linux.pot
192 206
193# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) 207# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
@@ -208,10 +222,11 @@ HOSTCFLAGS_zconf.tab.o := -I$(src)
208HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl 222HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl
209HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK 223HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
210 224
211HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` 225HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
212HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ 226HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
213 -D LKC_DIRECT_LINK 227 -D LKC_DIRECT_LINK
214 228
229HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
215$(obj)/qconf.o: $(obj)/.tmp_qtcheck 230$(obj)/qconf.o: $(obj)/.tmp_qtcheck
216 231
217ifeq ($(qconf-target),1) 232ifeq ($(qconf-target),1)
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 9960d1c303f8..274f2716b03e 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -10,6 +10,7 @@
10#include <string.h> 10#include <string.h>
11#include <time.h> 11#include <time.h>
12#include <unistd.h> 12#include <unistd.h>
13#include <getopt.h>
13#include <sys/stat.h> 14#include <sys/stat.h>
14#include <sys/time.h> 15#include <sys/time.h>
15 16
@@ -19,16 +20,21 @@
19static void conf(struct menu *menu); 20static void conf(struct menu *menu);
20static void check_conf(struct menu *menu); 21static void check_conf(struct menu *menu);
21 22
22enum { 23enum input_mode {
23 ask_all, 24 oldaskconfig,
24 ask_new, 25 silentoldconfig,
25 ask_silent, 26 oldconfig,
26 set_default, 27 allnoconfig,
27 set_yes, 28 allyesconfig,
28 set_mod, 29 allmodconfig,
29 set_no, 30 alldefconfig,
30 set_random 31 randconfig,
31} input_mode = ask_all; 32 defconfig,
33 savedefconfig,
34 listnewconfig,
35 oldnoconfig,
36} input_mode = oldaskconfig;
37
32char *defconfig_file; 38char *defconfig_file;
33 39
34static int indent = 1; 40static int indent = 1;
@@ -93,14 +99,14 @@ static int conf_askvalue(struct symbol *sym, const char *def)
93 } 99 }
94 100
95 switch (input_mode) { 101 switch (input_mode) {
96 case ask_new: 102 case oldconfig:
97 case ask_silent: 103 case silentoldconfig:
98 if (sym_has_value(sym)) { 104 if (sym_has_value(sym)) {
99 printf("%s\n", def); 105 printf("%s\n", def);
100 return 0; 106 return 0;
101 } 107 }
102 check_stdin(); 108 check_stdin();
103 case ask_all: 109 case oldaskconfig:
104 fflush(stdout); 110 fflush(stdout);
105 fgets(line, 128, stdin); 111 fgets(line, 128, stdin);
106 return 1; 112 return 1;
@@ -156,14 +162,12 @@ static int conf_string(struct menu *menu)
156static int conf_sym(struct menu *menu) 162static int conf_sym(struct menu *menu)
157{ 163{
158 struct symbol *sym = menu->sym; 164 struct symbol *sym = menu->sym;
159 int type;
160 tristate oldval, newval; 165 tristate oldval, newval;
161 166
162 while (1) { 167 while (1) {
163 printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); 168 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
164 if (sym->name) 169 if (sym->name)
165 printf("(%s) ", sym->name); 170 printf("(%s) ", sym->name);
166 type = sym_get_type(sym);
167 putchar('['); 171 putchar('[');
168 oldval = sym_get_tristate_value(sym); 172 oldval = sym_get_tristate_value(sym);
169 switch (oldval) { 173 switch (oldval) {
@@ -228,11 +232,9 @@ static int conf_choice(struct menu *menu)
228{ 232{
229 struct symbol *sym, *def_sym; 233 struct symbol *sym, *def_sym;
230 struct menu *child; 234 struct menu *child;
231 int type;
232 bool is_new; 235 bool is_new;
233 236
234 sym = menu->sym; 237 sym = menu->sym;
235 type = sym_get_type(sym);
236 is_new = !sym_has_value(sym); 238 is_new = !sym_has_value(sym);
237 if (sym_is_changable(sym)) { 239 if (sym_is_changable(sym)) {
238 conf_sym(menu); 240 conf_sym(menu);
@@ -294,15 +296,15 @@ static int conf_choice(struct menu *menu)
294 printf("?"); 296 printf("?");
295 printf("]: "); 297 printf("]: ");
296 switch (input_mode) { 298 switch (input_mode) {
297 case ask_new: 299 case oldconfig:
298 case ask_silent: 300 case silentoldconfig:
299 if (!is_new) { 301 if (!is_new) {
300 cnt = def; 302 cnt = def;
301 printf("%d\n", cnt); 303 printf("%d\n", cnt);
302 break; 304 break;
303 } 305 }
304 check_stdin(); 306 check_stdin();
305 case ask_all: 307 case oldaskconfig:
306 fflush(stdout); 308 fflush(stdout);
307 fgets(line, 128, stdin); 309 fgets(line, 128, stdin);
308 strip(line); 310 strip(line);
@@ -360,7 +362,10 @@ static void conf(struct menu *menu)
360 362
361 switch (prop->type) { 363 switch (prop->type) {
362 case P_MENU: 364 case P_MENU:
363 if (input_mode == ask_silent && rootEntry != menu) { 365 if ((input_mode == silentoldconfig ||
366 input_mode == listnewconfig ||
367 input_mode == oldnoconfig) &&
368 rootEntry != menu) {
364 check_conf(menu); 369 check_conf(menu);
365 return; 370 return;
366 } 371 }
@@ -418,10 +423,16 @@ static void check_conf(struct menu *menu)
418 if (sym && !sym_has_value(sym)) { 423 if (sym && !sym_has_value(sym)) {
419 if (sym_is_changable(sym) || 424 if (sym_is_changable(sym) ||
420 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { 425 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
421 if (!conf_cnt++) 426 if (input_mode == listnewconfig) {
422 printf(_("*\n* Restart config...\n*\n")); 427 if (sym->name && !sym_is_choice_value(sym)) {
423 rootEntry = menu_get_parent_menu(menu); 428 printf("CONFIG_%s\n", sym->name);
424 conf(rootEntry); 429 }
430 } else {
431 if (!conf_cnt++)
432 printf(_("*\n* Restart config...\n*\n"));
433 rootEntry = menu_get_parent_menu(menu);
434 conf(rootEntry);
435 }
425 } 436 }
426 } 437 }
427 438
@@ -429,6 +440,22 @@ static void check_conf(struct menu *menu)
429 check_conf(child); 440 check_conf(child);
430} 441}
431 442
443static struct option long_opts[] = {
444 {"oldaskconfig", no_argument, NULL, oldaskconfig},
445 {"oldconfig", no_argument, NULL, oldconfig},
446 {"silentoldconfig", no_argument, NULL, silentoldconfig},
447 {"defconfig", optional_argument, NULL, defconfig},
448 {"savedefconfig", required_argument, NULL, savedefconfig},
449 {"allnoconfig", no_argument, NULL, allnoconfig},
450 {"allyesconfig", no_argument, NULL, allyesconfig},
451 {"allmodconfig", no_argument, NULL, allmodconfig},
452 {"alldefconfig", no_argument, NULL, alldefconfig},
453 {"randconfig", no_argument, NULL, randconfig},
454 {"listnewconfig", no_argument, NULL, listnewconfig},
455 {"oldnoconfig", no_argument, NULL, oldnoconfig},
456 {NULL, 0, NULL, 0}
457};
458
432int main(int ac, char **av) 459int main(int ac, char **av)
433{ 460{
434 int opt; 461 int opt;
@@ -439,32 +466,17 @@ int main(int ac, char **av)
439 bindtextdomain(PACKAGE, LOCALEDIR); 466 bindtextdomain(PACKAGE, LOCALEDIR);
440 textdomain(PACKAGE); 467 textdomain(PACKAGE);
441 468
442 while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { 469 while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) {
470 input_mode = (enum input_mode)opt;
443 switch (opt) { 471 switch (opt) {
444 case 'o': 472 case silentoldconfig:
445 input_mode = ask_silent;
446 break;
447 case 's':
448 input_mode = ask_silent;
449 sync_kconfig = 1; 473 sync_kconfig = 1;
450 break; 474 break;
451 case 'd': 475 case defconfig:
452 input_mode = set_default; 476 case savedefconfig:
453 break;
454 case 'D':
455 input_mode = set_default;
456 defconfig_file = optarg; 477 defconfig_file = optarg;
457 break; 478 break;
458 case 'n': 479 case randconfig:
459 input_mode = set_no;
460 break;
461 case 'm':
462 input_mode = set_mod;
463 break;
464 case 'y':
465 input_mode = set_yes;
466 break;
467 case 'r':
468 { 480 {
469 struct timeval now; 481 struct timeval now;
470 unsigned int seed; 482 unsigned int seed;
@@ -477,17 +489,12 @@ int main(int ac, char **av)
477 489
478 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); 490 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
479 srand(seed); 491 srand(seed);
480
481 input_mode = set_random;
482 break; 492 break;
483 } 493 }
484 case 'h': 494 case '?':
485 printf(_("See README for usage info\n"));
486 exit(0);
487 break;
488 default:
489 fprintf(stderr, _("See README for usage info\n")); 495 fprintf(stderr, _("See README for usage info\n"));
490 exit(1); 496 exit(1);
497 break;
491 } 498 }
492 } 499 }
493 if (ac == optind) { 500 if (ac == optind) {
@@ -512,7 +519,7 @@ int main(int ac, char **av)
512 } 519 }
513 520
514 switch (input_mode) { 521 switch (input_mode) {
515 case set_default: 522 case defconfig:
516 if (!defconfig_file) 523 if (!defconfig_file)
517 defconfig_file = conf_get_default_confname(); 524 defconfig_file = conf_get_default_confname();
518 if (conf_read(defconfig_file)) { 525 if (conf_read(defconfig_file)) {
@@ -522,25 +529,32 @@ int main(int ac, char **av)
522 exit(1); 529 exit(1);
523 } 530 }
524 break; 531 break;
525 case ask_silent: 532 case savedefconfig:
526 case ask_all: 533 conf_read(NULL);
527 case ask_new: 534 break;
535 case silentoldconfig:
536 case oldaskconfig:
537 case oldconfig:
538 case listnewconfig:
539 case oldnoconfig:
528 conf_read(NULL); 540 conf_read(NULL);
529 break; 541 break;
530 case set_no: 542 case allnoconfig:
531 case set_mod: 543 case allyesconfig:
532 case set_yes: 544 case allmodconfig:
533 case set_random: 545 case alldefconfig:
546 case randconfig:
534 name = getenv("KCONFIG_ALLCONFIG"); 547 name = getenv("KCONFIG_ALLCONFIG");
535 if (name && !stat(name, &tmpstat)) { 548 if (name && !stat(name, &tmpstat)) {
536 conf_read_simple(name, S_DEF_USER); 549 conf_read_simple(name, S_DEF_USER);
537 break; 550 break;
538 } 551 }
539 switch (input_mode) { 552 switch (input_mode) {
540 case set_no: name = "allno.config"; break; 553 case allnoconfig: name = "allno.config"; break;
541 case set_mod: name = "allmod.config"; break; 554 case allyesconfig: name = "allyes.config"; break;
542 case set_yes: name = "allyes.config"; break; 555 case allmodconfig: name = "allmod.config"; break;
543 case set_random: name = "allrandom.config"; break; 556 case alldefconfig: name = "alldef.config"; break;
557 case randconfig: name = "allrandom.config"; break;
544 default: break; 558 default: break;
545 } 559 }
546 if (!stat(name, &tmpstat)) 560 if (!stat(name, &tmpstat))
@@ -565,33 +579,42 @@ int main(int ac, char **av)
565 } 579 }
566 580
567 switch (input_mode) { 581 switch (input_mode) {
568 case set_no: 582 case allnoconfig:
569 conf_set_all_new_symbols(def_no); 583 conf_set_all_new_symbols(def_no);
570 break; 584 break;
571 case set_yes: 585 case allyesconfig:
572 conf_set_all_new_symbols(def_yes); 586 conf_set_all_new_symbols(def_yes);
573 break; 587 break;
574 case set_mod: 588 case allmodconfig:
575 conf_set_all_new_symbols(def_mod); 589 conf_set_all_new_symbols(def_mod);
576 break; 590 break;
577 case set_random: 591 case alldefconfig:
592 conf_set_all_new_symbols(def_default);
593 break;
594 case randconfig:
578 conf_set_all_new_symbols(def_random); 595 conf_set_all_new_symbols(def_random);
579 break; 596 break;
580 case set_default: 597 case defconfig:
581 conf_set_all_new_symbols(def_default); 598 conf_set_all_new_symbols(def_default);
582 break; 599 break;
583 case ask_new: 600 case savedefconfig:
584 case ask_all: 601 break;
602 case oldaskconfig:
585 rootEntry = &rootmenu; 603 rootEntry = &rootmenu;
586 conf(&rootmenu); 604 conf(&rootmenu);
587 input_mode = ask_silent; 605 input_mode = silentoldconfig;
588 /* fall through */ 606 /* fall through */
589 case ask_silent: 607 case oldconfig:
608 case listnewconfig:
609 case oldnoconfig:
610 case silentoldconfig:
590 /* Update until a loop caused no more changes */ 611 /* Update until a loop caused no more changes */
591 do { 612 do {
592 conf_cnt = 0; 613 conf_cnt = 0;
593 check_conf(&rootmenu); 614 check_conf(&rootmenu);
594 } while (conf_cnt); 615 } while (conf_cnt &&
616 (input_mode != listnewconfig &&
617 input_mode != oldnoconfig));
595 break; 618 break;
596 } 619 }
597 620
@@ -607,7 +630,13 @@ int main(int ac, char **av)
607 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); 630 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
608 return 1; 631 return 1;
609 } 632 }
610 } else { 633 } else if (input_mode == savedefconfig) {
634 if (conf_write_defconfig(defconfig_file)) {
635 fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
636 defconfig_file);
637 return 1;
638 }
639 } else if (input_mode != listnewconfig) {
611 if (conf_write(NULL)) { 640 if (conf_write(NULL)) {
612 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); 641 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
613 exit(1); 642 exit(1);
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index c4dec80cfd8e..f81f263b64f2 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def)
170 if (in) 170 if (in)
171 goto load; 171 goto load;
172 sym_add_change_count(1); 172 sym_add_change_count(1);
173 if (!sym_defconfig_list) 173 if (!sym_defconfig_list) {
174 if (modules_sym)
175 sym_calc_value(modules_sym);
174 return 1; 176 return 1;
177 }
175 178
176 for_all_defaults(sym_defconfig_list, prop) { 179 for_all_defaults(sym_defconfig_list, prop) {
177 if (expr_calc_value(prop->visible.expr) == no || 180 if (expr_calc_value(prop->visible.expr) == no ||
@@ -396,15 +399,149 @@ int conf_read(const char *name)
396 return 0; 399 return 0;
397} 400}
398 401
402/* Write a S_STRING */
403static void conf_write_string(bool headerfile, const char *name,
404 const char *str, FILE *out)
405{
406 int l;
407 if (headerfile)
408 fprintf(out, "#define CONFIG_%s \"", name);
409 else
410 fprintf(out, "CONFIG_%s=\"", name);
411
412 while (1) {
413 l = strcspn(str, "\"\\");
414 if (l) {
415 fwrite(str, l, 1, out);
416 str += l;
417 }
418 if (!*str)
419 break;
420 fprintf(out, "\\%c", *str++);
421 }
422 fputs("\"\n", out);
423}
424
425static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
426 FILE *out, bool write_no)
427{
428 const char *str;
429
430 switch (type) {
431 case S_BOOLEAN:
432 case S_TRISTATE:
433 switch (sym_get_tristate_value(sym)) {
434 case no:
435 if (write_no)
436 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
437 break;
438 case mod:
439 fprintf(out, "CONFIG_%s=m\n", sym->name);
440 break;
441 case yes:
442 fprintf(out, "CONFIG_%s=y\n", sym->name);
443 break;
444 }
445 break;
446 case S_STRING:
447 conf_write_string(false, sym->name, sym_get_string_value(sym), out);
448 break;
449 case S_HEX:
450 case S_INT:
451 str = sym_get_string_value(sym);
452 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
453 break;
454 case S_OTHER:
455 case S_UNKNOWN:
456 break;
457 }
458}
459
460/*
461 * Write out a minimal config.
462 * All values that has default values are skipped as this is redundant.
463 */
464int conf_write_defconfig(const char *filename)
465{
466 struct symbol *sym;
467 struct menu *menu;
468 FILE *out;
469
470 out = fopen(filename, "w");
471 if (!out)
472 return 1;
473
474 sym_clear_all_valid();
475
476 /* Traverse all menus to find all relevant symbols */
477 menu = rootmenu.list;
478
479 while (menu != NULL)
480 {
481 sym = menu->sym;
482 if (sym == NULL) {
483 if (!menu_is_visible(menu))
484 goto next_menu;
485 } else if (!sym_is_choice(sym)) {
486 sym_calc_value(sym);
487 if (!(sym->flags & SYMBOL_WRITE))
488 goto next_menu;
489 sym->flags &= ~SYMBOL_WRITE;
490 /* If we cannot change the symbol - skip */
491 if (!sym_is_changable(sym))
492 goto next_menu;
493 /* If symbol equals to default value - skip */
494 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
495 goto next_menu;
496
497 /*
498 * If symbol is a choice value and equals to the
499 * default for a choice - skip.
500 * But only if value equal to "y".
501 */
502 if (sym_is_choice_value(sym)) {
503 struct symbol *cs;
504 struct symbol *ds;
505
506 cs = prop_get_symbol(sym_get_choice_prop(sym));
507 ds = sym_choice_default(cs);
508 if (sym == ds) {
509 if ((sym->type == S_BOOLEAN ||
510 sym->type == S_TRISTATE) &&
511 sym_get_tristate_value(sym) == yes)
512 goto next_menu;
513 }
514 }
515 conf_write_symbol(sym, sym->type, out, true);
516 }
517next_menu:
518 if (menu->list != NULL) {
519 menu = menu->list;
520 }
521 else if (menu->next != NULL) {
522 menu = menu->next;
523 } else {
524 while ((menu = menu->parent)) {
525 if (menu->next != NULL) {
526 menu = menu->next;
527 break;
528 }
529 }
530 }
531 }
532 fclose(out);
533 return 0;
534}
535
399int conf_write(const char *name) 536int conf_write(const char *name)
400{ 537{
401 FILE *out; 538 FILE *out;
402 struct symbol *sym; 539 struct symbol *sym;
403 struct menu *menu; 540 struct menu *menu;
404 const char *basename; 541 const char *basename;
405 char dirname[128], tmpname[128], newname[128];
406 int type, l;
407 const char *str; 542 const char *str;
543 char dirname[128], tmpname[128], newname[128];
544 enum symbol_type type;
408 time_t now; 545 time_t now;
409 int use_timestamp = 1; 546 int use_timestamp = 1;
410 char *env; 547 char *env;
@@ -484,50 +621,11 @@ int conf_write(const char *name)
484 if (modules_sym->curr.tri == no) 621 if (modules_sym->curr.tri == no)
485 type = S_BOOLEAN; 622 type = S_BOOLEAN;
486 } 623 }
487 switch (type) { 624 /* Write config symbol to file */
488 case S_BOOLEAN: 625 conf_write_symbol(sym, type, out, true);
489 case S_TRISTATE:
490 switch (sym_get_tristate_value(sym)) {
491 case no:
492 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
493 break;
494 case mod:
495 fprintf(out, "CONFIG_%s=m\n", sym->name);
496 break;
497 case yes:
498 fprintf(out, "CONFIG_%s=y\n", sym->name);
499 break;
500 }
501 break;
502 case S_STRING:
503 str = sym_get_string_value(sym);
504 fprintf(out, "CONFIG_%s=\"", sym->name);
505 while (1) {
506 l = strcspn(str, "\"\\");
507 if (l) {
508 fwrite(str, l, 1, out);
509 str += l;
510 }
511 if (!*str)
512 break;
513 fprintf(out, "\\%c", *str++);
514 }
515 fputs("\"\n", out);
516 break;
517 case S_HEX:
518 str = sym_get_string_value(sym);
519 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
520 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
521 break;
522 }
523 case S_INT:
524 str = sym_get_string_value(sym);
525 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
526 break;
527 }
528 } 626 }
529 627
530 next: 628next:
531 if (menu->list) { 629 if (menu->list) {
532 menu = menu->list; 630 menu = menu->list;
533 continue; 631 continue;
@@ -679,7 +777,7 @@ int conf_write_autoconf(void)
679 const char *name; 777 const char *name;
680 FILE *out, *tristate, *out_h; 778 FILE *out, *tristate, *out_h;
681 time_t now; 779 time_t now;
682 int i, l; 780 int i;
683 781
684 sym_clear_all_valid(); 782 sym_clear_all_valid();
685 783
@@ -729,6 +827,11 @@ int conf_write_autoconf(void)
729 sym_calc_value(sym); 827 sym_calc_value(sym);
730 if (!(sym->flags & SYMBOL_WRITE) || !sym->name) 828 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
731 continue; 829 continue;
830
831 /* write symbol to config file */
832 conf_write_symbol(sym, sym->type, out, false);
833
834 /* update autoconf and tristate files */
732 switch (sym->type) { 835 switch (sym->type) {
733 case S_BOOLEAN: 836 case S_BOOLEAN:
734 case S_TRISTATE: 837 case S_TRISTATE:
@@ -736,12 +839,10 @@ int conf_write_autoconf(void)
736 case no: 839 case no:
737 break; 840 break;
738 case mod: 841 case mod:
739 fprintf(out, "CONFIG_%s=m\n", sym->name);
740 fprintf(tristate, "CONFIG_%s=M\n", sym->name); 842 fprintf(tristate, "CONFIG_%s=M\n", sym->name);
741 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 843 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
742 break; 844 break;
743 case yes: 845 case yes:
744 fprintf(out, "CONFIG_%s=y\n", sym->name);
745 if (sym->type == S_TRISTATE) 846 if (sym->type == S_TRISTATE)
746 fprintf(tristate, "CONFIG_%s=Y\n", 847 fprintf(tristate, "CONFIG_%s=Y\n",
747 sym->name); 848 sym->name);
@@ -750,35 +851,16 @@ int conf_write_autoconf(void)
750 } 851 }
751 break; 852 break;
752 case S_STRING: 853 case S_STRING:
753 str = sym_get_string_value(sym); 854 conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
754 fprintf(out, "CONFIG_%s=\"", sym->name);
755 fprintf(out_h, "#define CONFIG_%s \"", sym->name);
756 while (1) {
757 l = strcspn(str, "\"\\");
758 if (l) {
759 fwrite(str, l, 1, out);
760 fwrite(str, l, 1, out_h);
761 str += l;
762 }
763 if (!*str)
764 break;
765 fprintf(out, "\\%c", *str);
766 fprintf(out_h, "\\%c", *str);
767 str++;
768 }
769 fputs("\"\n", out);
770 fputs("\"\n", out_h);
771 break; 855 break;
772 case S_HEX: 856 case S_HEX:
773 str = sym_get_string_value(sym); 857 str = sym_get_string_value(sym);
774 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 858 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
775 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
776 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 859 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
777 break; 860 break;
778 } 861 }
779 case S_INT: 862 case S_INT:
780 str = sym_get_string_value(sym); 863 str = sym_get_string_value(sym);
781 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
782 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 864 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
783 break; 865 break;
784 default: 866 default:
@@ -862,7 +944,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
862 sym->def[S_DEF_USER].tri = no; 944 sym->def[S_DEF_USER].tri = no;
863 break; 945 break;
864 case def_random: 946 case def_random:
865 sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); 947 cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
948 sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
866 break; 949 break;
867 default: 950 default:
868 continue; 951 continue;
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index edd3f39a080a..8f18e37892cb 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1097,9 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out)
1097 1097
1098static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) 1098static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1099{ 1099{
1100 str_append((struct gstr*)data, str); 1100 struct gstr *gs = (struct gstr*)data;
1101 const char *sym_str = NULL;
1102
1101 if (sym) 1103 if (sym)
1102 str_printf((struct gstr*)data, " [=%s]", sym_get_string_value(sym)); 1104 sym_str = sym_get_string_value(sym);
1105
1106 if (gs->max_width) {
1107 unsigned extra_length = strlen(str);
1108 const char *last_cr = strrchr(gs->s, '\n');
1109 unsigned last_line_length;
1110
1111 if (sym_str)
1112 extra_length += 4 + strlen(sym_str);
1113
1114 if (!last_cr)
1115 last_cr = gs->s;
1116
1117 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1118
1119 if ((last_line_length + extra_length) > gs->max_width)
1120 str_append(gs, "\\\n");
1121 }
1122
1123 str_append(gs, str);
1124 if (sym && sym->type != S_UNKNOWN)
1125 str_printf(gs, " [=%s]", sym_str);
1103} 1126}
1104 1127
1105void expr_gstr_print(struct expr *e, struct gstr *gs) 1128void expr_gstr_print(struct expr *e, struct gstr *gs)
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 6408fefae083..6ee2e4fb1481 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -83,10 +83,11 @@ struct symbol {
83 tristate visible; 83 tristate visible;
84 int flags; 84 int flags;
85 struct property *prop; 85 struct property *prop;
86 struct expr_value dir_dep;
86 struct expr_value rev_dep; 87 struct expr_value rev_dep;
87}; 88};
88 89
89#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) 90#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
90 91
91#define SYMBOL_CONST 0x0001 /* symbol is const */ 92#define SYMBOL_CONST 0x0001 /* symbol is const */
92#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ 93#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
@@ -108,8 +109,7 @@ struct symbol {
108#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 109#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
109 110
110#define SYMBOL_MAXLENGTH 256 111#define SYMBOL_MAXLENGTH 256
111#define SYMBOL_HASHSIZE 257 112#define SYMBOL_HASHSIZE 9973
112#define SYMBOL_HASHMASK 0xff
113 113
114/* A property represent the config options that can be associated 114/* A property represent the config options that can be associated
115 * with a config "symbol". 115 * with a config "symbol".
@@ -132,6 +132,7 @@ enum prop_type {
132 P_SELECT, /* select BAR */ 132 P_SELECT, /* select BAR */
133 P_RANGE, /* range 7..100 (for a symbol) */ 133 P_RANGE, /* range 7..100 (for a symbol) */
134 P_ENV, /* value from environment variable */ 134 P_ENV, /* value from environment variable */
135 P_SYMBOL, /* where a symbol is defined */
135}; 136};
136 137
137struct property { 138struct property {
@@ -164,6 +165,7 @@ struct menu {
164 struct symbol *sym; 165 struct symbol *sym;
165 struct property *prompt; 166 struct property *prompt;
166 struct expr *dep; 167 struct expr *dep;
168 struct expr *dir_dep;
167 unsigned int flags; 169 unsigned int flags;
168 char *help; 170 char *help;
169 struct file *file; 171 struct file *file;
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 65464366fe38..d66988265f89 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -30,13 +30,16 @@ enum {
30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW 30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
31}; 31};
32 32
33enum {
34 OPT_NORMAL, OPT_ALL, OPT_PROMPT
35};
36
33static gint view_mode = FULL_VIEW; 37static gint view_mode = FULL_VIEW;
34static gboolean show_name = TRUE; 38static gboolean show_name = TRUE;
35static gboolean show_range = TRUE; 39static gboolean show_range = TRUE;
36static gboolean show_value = TRUE; 40static gboolean show_value = TRUE;
37static gboolean show_all = FALSE;
38static gboolean show_debug = FALSE;
39static gboolean resizeable = FALSE; 41static gboolean resizeable = FALSE;
42static int opt_mode = OPT_NORMAL;
40 43
41GtkWidget *main_wnd = NULL; 44GtkWidget *main_wnd = NULL;
42GtkWidget *tree1_w = NULL; // left frame 45GtkWidget *tree1_w = NULL; // left frame
@@ -76,36 +79,7 @@ static void conf_changed(void);
76 79
77/* Helping/Debugging Functions */ 80/* Helping/Debugging Functions */
78 81
79 82const char *dbg_sym_flags(int val)
80const char *dbg_print_stype(int val)
81{
82 static char buf[256];
83
84 bzero(buf, 256);
85
86 if (val == S_UNKNOWN)
87 strcpy(buf, "unknown");
88 if (val == S_BOOLEAN)
89 strcpy(buf, "boolean");
90 if (val == S_TRISTATE)
91 strcpy(buf, "tristate");
92 if (val == S_INT)
93 strcpy(buf, "int");
94 if (val == S_HEX)
95 strcpy(buf, "hex");
96 if (val == S_STRING)
97 strcpy(buf, "string");
98 if (val == S_OTHER)
99 strcpy(buf, "other");
100
101#ifdef DEBUG
102 printf("%s", buf);
103#endif
104
105 return buf;
106}
107
108const char *dbg_print_flags(int val)
109{ 83{
110 static char buf[256]; 84 static char buf[256];
111 85
@@ -131,40 +105,10 @@ const char *dbg_print_flags(int val)
131 strcat(buf, "auto/"); 105 strcat(buf, "auto/");
132 106
133 buf[strlen(buf) - 1] = '\0'; 107 buf[strlen(buf) - 1] = '\0';
134#ifdef DEBUG
135 printf("%s", buf);
136#endif
137
138 return buf;
139}
140
141const char *dbg_print_ptype(int val)
142{
143 static char buf[256];
144
145 bzero(buf, 256);
146
147 if (val == P_UNKNOWN)
148 strcpy(buf, "unknown");
149 if (val == P_PROMPT)
150 strcpy(buf, "prompt");
151 if (val == P_COMMENT)
152 strcpy(buf, "comment");
153 if (val == P_MENU)
154 strcpy(buf, "menu");
155 if (val == P_DEFAULT)
156 strcpy(buf, "default");
157 if (val == P_CHOICE)
158 strcpy(buf, "choice");
159
160#ifdef DEBUG
161 printf("%s", buf);
162#endif
163 108
164 return buf; 109 return buf;
165} 110}
166 111
167
168void replace_button_icon(GladeXML * xml, GdkDrawable * window, 112void replace_button_icon(GladeXML * xml, GdkDrawable * window,
169 GtkStyle * style, gchar * btn_name, gchar ** xpm) 113 GtkStyle * style, gchar * btn_name, gchar ** xpm)
170{ 114{
@@ -697,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
697 641
698 642
699void 643void
700on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) 644on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
701{ 645{
702 show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; 646 opt_mode = OPT_NORMAL;
647 gtk_tree_store_clear(tree2);
648 display_tree(&rootmenu); /* instead of update_tree to speed-up */
649}
650
703 651
652void
653on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
654{
655 opt_mode = OPT_ALL;
704 gtk_tree_store_clear(tree2); 656 gtk_tree_store_clear(tree2);
705 display_tree(&rootmenu); // instead of update_tree to speed-up 657 display_tree(&rootmenu); /* instead of update_tree to speed-up */
706} 658}
707 659
708 660
709void 661void
710on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) 662on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
711{ 663{
712 show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; 664 opt_mode = OPT_PROMPT;
713 update_tree(&rootmenu, NULL); 665 gtk_tree_store_clear(tree2);
666 display_tree(&rootmenu); /* instead of update_tree to speed-up */
714} 667}
715 668
716 669
@@ -1161,9 +1114,12 @@ static gchar **fill_row(struct menu *menu)
1161 1114
1162 row[COL_OPTION] = 1115 row[COL_OPTION] =
1163 g_strdup_printf("%s %s", _(menu_get_prompt(menu)), 1116 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1164 sym && sym_has_value(sym) ? "(NEW)" : ""); 1117 sym && !sym_has_value(sym) ? "(NEW)" : "");
1165 1118
1166 if (show_all && !menu_is_visible(menu)) 1119 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1120 row[COL_COLOR] = g_strdup("DarkGray");
1121 else if (opt_mode == OPT_PROMPT &&
1122 menu_has_prompt(menu) && !menu_is_visible(menu))
1167 row[COL_COLOR] = g_strdup("DarkGray"); 1123 row[COL_COLOR] = g_strdup("DarkGray");
1168 else 1124 else
1169 row[COL_COLOR] = g_strdup("Black"); 1125 row[COL_COLOR] = g_strdup("Black");
@@ -1386,16 +1342,20 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
1386 menu2 ? menu_get_prompt(menu2) : "nil"); 1342 menu2 ? menu_get_prompt(menu2) : "nil");
1387#endif 1343#endif
1388 1344
1389 if (!menu_is_visible(child1) && !show_all) { // remove node 1345 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1346 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1347 (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
1348
1349 /* remove node */
1390 if (gtktree_iter_find_node(dst, menu1) != NULL) { 1350 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1391 memcpy(&tmp, child2, sizeof(GtkTreeIter)); 1351 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1392 valid = gtk_tree_model_iter_next(model2, 1352 valid = gtk_tree_model_iter_next(model2,
1393 child2); 1353 child2);
1394 gtk_tree_store_remove(tree2, &tmp); 1354 gtk_tree_store_remove(tree2, &tmp);
1395 if (!valid) 1355 if (!valid)
1396 return; // next parent 1356 return; /* next parent */
1397 else 1357 else
1398 goto reparse; // next child 1358 goto reparse; /* next child */
1399 } else 1359 } else
1400 continue; 1360 continue;
1401 } 1361 }
@@ -1464,17 +1424,19 @@ static void display_tree(struct menu *menu)
1464 && (tree == tree2)) 1424 && (tree == tree2))
1465 continue; 1425 continue;
1466 1426
1467 if (menu_is_visible(child) || show_all) 1427 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1428 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1429 (opt_mode == OPT_ALL && menu_get_prompt(child)))
1468 place_node(child, fill_row(child)); 1430 place_node(child, fill_row(child));
1469#ifdef DEBUG 1431#ifdef DEBUG
1470 printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); 1432 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1471 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); 1433 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1472 dbg_print_ptype(ptype); 1434 printf("%s", prop_get_type_name(ptype));
1473 printf(" | "); 1435 printf(" | ");
1474 if (sym) { 1436 if (sym) {
1475 dbg_print_stype(sym->type); 1437 printf("%s", sym_type_name(sym->type));
1476 printf(" | "); 1438 printf(" | ");
1477 dbg_print_flags(sym->flags); 1439 printf("%s", dbg_sym_flags(sym->flags));
1478 printf("\n"); 1440 printf("\n");
1479 } else 1441 } else
1480 printf("\n"); 1442 printf("\n");
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index b1c86c19292c..d52b0a75d824 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -190,26 +190,40 @@
190 </child> 190 </child>
191 191
192 <child> 192 <child>
193 <widget class="GtkCheckMenuItem" id="show_all_options1"> 193 <widget class="GtkRadioMenuItem" id="set_option_mode1">
194 <property name="visible">True</property>
195 <property name="tooltip" translatable="yes">Show normal options</property>
196 <property name="label" translatable="yes">Show normal options</property>
197 <property name="use_underline">True</property>
198 <property name="active">True</property>
199 <signal name="activate" handler="on_set_option_mode1_activate"/>
200 </widget>
201 </child>
202
203 <child>
204 <widget class="GtkRadioMenuItem" id="set_option_mode2">
194 <property name="visible">True</property> 205 <property name="visible">True</property>
195 <property name="tooltip" translatable="yes">Show all options</property> 206 <property name="tooltip" translatable="yes">Show all options</property>
196 <property name="label" translatable="yes">Show all _options</property> 207 <property name="label" translatable="yes">Show all _options</property>
197 <property name="use_underline">True</property> 208 <property name="use_underline">True</property>
198 <property name="active">False</property> 209 <property name="active">False</property>
199 <signal name="activate" handler="on_show_all_options1_activate"/> 210 <property name="group">set_option_mode1</property>
211 <signal name="activate" handler="on_set_option_mode2_activate"/>
200 </widget> 212 </widget>
201 </child> 213 </child>
202 214
203 <child> 215 <child>
204 <widget class="GtkCheckMenuItem" id="show_debug_info1"> 216 <widget class="GtkRadioMenuItem" id="set_option_mode3">
205 <property name="visible">True</property> 217 <property name="visible">True</property>
206 <property name="tooltip" translatable="yes">Show masked options</property> 218 <property name="tooltip" translatable="yes">Show all options with prompts</property>
207 <property name="label" translatable="yes">Show _debug info</property> 219 <property name="label" translatable="yes">Show all prompt options</property>
208 <property name="use_underline">True</property> 220 <property name="use_underline">True</property>
209 <property name="active">False</property> 221 <property name="active">False</property>
210 <signal name="activate" handler="on_show_debug_info1_activate"/> 222 <property name="group">set_option_mode1</property>
223 <signal name="activate" handler="on_set_option_mode3_activate"/>
211 </widget> 224 </widget>
212 </child> 225 </child>
226
213 </widget> 227 </widget>
214 </child> 228 </child>
215 </widget> 229 </widget>
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index f379b0bf8c9e..76db065ed72c 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -84,7 +84,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode);
84void kconfig_load(void); 84void kconfig_load(void);
85 85
86/* menu.c */ 86/* menu.c */
87void menu_init(void); 87void _menu_init(void);
88void menu_warn(struct menu *menu, const char *fmt, ...); 88void menu_warn(struct menu *menu, const char *fmt, ...);
89struct menu *menu_add_menu(void); 89struct menu *menu_add_menu(void);
90void menu_end_menu(void); 90void menu_end_menu(void);
@@ -106,6 +106,11 @@ int file_write_dep(const char *name);
106struct gstr { 106struct gstr {
107 size_t len; 107 size_t len;
108 char *s; 108 char *s;
109 /*
110 * when max_width is not zero long lines in string s (if any) get
111 * wrapped not to exceed the max_width value
112 */
113 int max_width;
109}; 114};
110struct gstr str_new(void); 115struct gstr str_new(void);
111struct gstr str_assign(const char *s); 116struct gstr str_assign(const char *s);
@@ -121,6 +126,8 @@ void sym_init(void);
121void sym_clear_all_valid(void); 126void sym_clear_all_valid(void);
122void sym_set_all_changed(void); 127void sym_set_all_changed(void);
123void sym_set_changed(struct symbol *sym); 128void sym_set_changed(struct symbol *sym);
129struct symbol *sym_choice_default(struct symbol *sym);
130const char *sym_get_string_default(struct symbol *sym);
124struct symbol *sym_check_deps(struct symbol *sym); 131struct symbol *sym_check_deps(struct symbol *sym);
125struct property *prop_alloc(enum prop_type type, struct symbol *sym); 132struct property *prop_alloc(enum prop_type type, struct symbol *sym);
126struct symbol *prop_get_symbol(struct property *prop); 133struct symbol *prop_get_symbol(struct property *prop);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index ffeb532b2cff..9a948c9ce44e 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -3,6 +3,7 @@
3P(conf_parse,void,(const char *name)); 3P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name)); 4P(conf_read,int,(const char *name));
5P(conf_read_simple,int,(const char *name, int)); 5P(conf_read_simple,int,(const char *name, int));
6P(conf_write_defconfig,int,(const char *name));
6P(conf_write,int,(const char *name)); 7P(conf_write,int,(const char *name));
7P(conf_write_autoconf,int,(void)); 8P(conf_write_autoconf,int,(void));
8P(conf_get_changed,bool,(void)); 9P(conf_get_changed,bool,(void));
@@ -11,13 +12,15 @@ P(conf_set_changed_callback, void,(void (*fn)(void)));
11/* menu.c */ 12/* menu.c */
12P(rootmenu,struct menu,); 13P(rootmenu,struct menu,);
13 14
14P(menu_is_visible,bool,(struct menu *menu)); 15P(menu_is_visible, bool, (struct menu *menu));
16P(menu_has_prompt, bool, (struct menu *menu));
15P(menu_get_prompt,const char *,(struct menu *menu)); 17P(menu_get_prompt,const char *,(struct menu *menu));
16P(menu_get_root_menu,struct menu *,(struct menu *menu)); 18P(menu_get_root_menu,struct menu *,(struct menu *menu));
17P(menu_get_parent_menu,struct menu *,(struct menu *menu)); 19P(menu_get_parent_menu,struct menu *,(struct menu *menu));
18P(menu_has_help,bool,(struct menu *menu)); 20P(menu_has_help,bool,(struct menu *menu));
19P(menu_get_help,const char *,(struct menu *menu)); 21P(menu_get_help,const char *,(struct menu *menu));
20P(get_symbol_str,void,(struct gstr *r, struct symbol *sym)); 22P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
23P(get_relations_str, struct gstr, (struct symbol **sym_arr));
21P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); 24P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
22 25
23/* symbol.c */ 26/* symbol.c */
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index bcc6f19c3a35..a2eb80fbc896 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -31,6 +31,10 @@ static int list_width, check_x, item_x;
31static void print_item(WINDOW * win, int choice, int selected) 31static void print_item(WINDOW * win, int choice, int selected)
32{ 32{
33 int i; 33 int i;
34 char *list_item = malloc(list_width + 1);
35
36 strncpy(list_item, item_str(), list_width - item_x);
37 list_item[list_width - item_x] = '\0';
34 38
35 /* Clear 'residue' of last item */ 39 /* Clear 'residue' of last item */
36 wattrset(win, dlg.menubox.atr); 40 wattrset(win, dlg.menubox.atr);
@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected)
45 wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); 49 wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
46 50
47 wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); 51 wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
48 mvwaddch(win, choice, item_x, item_str()[0]); 52 mvwaddch(win, choice, item_x, list_item[0]);
49 wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); 53 wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
50 waddstr(win, (char *)item_str() + 1); 54 waddstr(win, list_item + 1);
51 if (selected) { 55 if (selected) {
52 wmove(win, choice, check_x + 1); 56 wmove(win, choice, check_x + 1);
53 wrefresh(win); 57 wrefresh(win);
54 } 58 }
59 free(list_item);
55} 60}
56 61
57/* 62/*
@@ -175,6 +180,7 @@ do_resize:
175 check_x = 0; 180 check_x = 0;
176 item_foreach() 181 item_foreach()
177 check_x = MAX(check_x, strlen(item_str()) + 4); 182 check_x = MAX(check_x, strlen(item_str()) + 4);
183 check_x = MIN(check_x, list_width);
178 184
179 check_x = (list_width - check_x) / 2; 185 check_x = (list_width - check_x) / 2;
180 item_x = check_x + 4; 186 item_x = check_x + 4;
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 616c60138183..dd8e587c50e2 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -180,7 +180,7 @@ do_resize:
180 case KEY_LEFT: 180 case KEY_LEFT:
181 switch (button) { 181 switch (button) {
182 case -1: 182 case -1:
183 button = 1; /* Indicates "Cancel" button is selected */ 183 button = 1; /* Indicates "Help" button is selected */
184 print_buttons(dialog, height, width, 1); 184 print_buttons(dialog, height, width, 1);
185 break; 185 break;
186 case 0: 186 case 0:
@@ -204,7 +204,7 @@ do_resize:
204 print_buttons(dialog, height, width, 0); 204 print_buttons(dialog, height, width, 0);
205 break; 205 break;
206 case 0: 206 case 0:
207 button = 1; /* Indicates "Cancel" button is selected */ 207 button = 1; /* Indicates "Help" button is selected */
208 print_buttons(dialog, height, width, 1); 208 print_buttons(dialog, height, width, 1);
209 break; 209 break;
210 case 1: 210 case 1:
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index fa9d633f293c..1d604738fa13 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -383,6 +383,10 @@ do_resize:
383 case 'n': 383 case 'n':
384 case 'm': 384 case 'm':
385 case '/': 385 case '/':
386 case 'h':
387 case '?':
388 case 'z':
389 case '\n':
386 /* save scroll info */ 390 /* save scroll info */
387 *s_scroll = scroll; 391 *s_scroll = scroll;
388 delwin(menu); 392 delwin(menu);
@@ -390,8 +394,10 @@ do_resize:
390 item_set(scroll + choice); 394 item_set(scroll + choice);
391 item_set_selected(1); 395 item_set_selected(1);
392 switch (key) { 396 switch (key) {
397 case 'h':
398 case '?':
399 return 2;
393 case 's': 400 case 's':
394 return 3;
395 case 'y': 401 case 'y':
396 return 3; 402 return 3;
397 case 'n': 403 case 'n':
@@ -402,18 +408,12 @@ do_resize:
402 return 6; 408 return 6;
403 case '/': 409 case '/':
404 return 7; 410 return 7;
411 case 'z':
412 return 8;
413 case '\n':
414 return button;
405 } 415 }
406 return 0; 416 return 0;
407 case 'h':
408 case '?':
409 button = 2;
410 case '\n':
411 *s_scroll = scroll;
412 delwin(menu);
413 delwin(dialog);
414 item_set(scroll + choice);
415 item_set_selected(1);
416 return button;
417 case 'e': 417 case 'e':
418 case 'x': 418 case 'x':
419 key = KEY_ESC; 419 key = KEY_ESC;
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 8413cf38ed27..d2f6e056c058 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -67,13 +67,15 @@ static const char mconf_readme[] = N_(
67" there is a delayed response which you may find annoying.\n" 67" there is a delayed response which you may find annoying.\n"
68"\n" 68"\n"
69" Also, the <TAB> and cursor keys will cycle between <Select>,\n" 69" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
70" <Exit> and <Help>\n" 70" <Exit> and <Help>.\n"
71"\n" 71"\n"
72"o To get help with an item, use the cursor keys to highlight <Help>\n" 72"o To get help with an item, use the cursor keys to highlight <Help>\n"
73" and Press <ENTER>.\n" 73" and press <ENTER>.\n"
74"\n" 74"\n"
75" Shortcut: Press <H> or <?>.\n" 75" Shortcut: Press <H> or <?>.\n"
76"\n" 76"\n"
77"o To toggle the display of hidden options, press <Z>.\n"
78"\n"
77"\n" 79"\n"
78"Radiolists (Choice lists)\n" 80"Radiolists (Choice lists)\n"
79"-----------\n" 81"-----------\n"
@@ -272,6 +274,7 @@ static int indent;
272static struct menu *current_menu; 274static struct menu *current_menu;
273static int child_count; 275static int child_count;
274static int single_menu_mode; 276static int single_menu_mode;
277static int show_all_options;
275 278
276static void conf(struct menu *menu); 279static void conf(struct menu *menu);
277static void conf_choice(struct menu *menu); 280static void conf_choice(struct menu *menu);
@@ -282,19 +285,6 @@ static void show_textbox(const char *title, const char *text, int r, int c);
282static void show_helptext(const char *title, const char *text); 285static void show_helptext(const char *title, const char *text);
283static void show_help(struct menu *menu); 286static void show_help(struct menu *menu);
284 287
285static struct gstr get_relations_str(struct symbol **sym_arr)
286{
287 struct symbol *sym;
288 struct gstr res = str_new();
289 int i;
290
291 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
292 get_symbol_str(&res, sym);
293 if (!i)
294 str_append(&res, _("No matches found.\n"));
295 return res;
296}
297
298static char filename[PATH_MAX+1]; 288static char filename[PATH_MAX+1];
299static void set_config_filename(const char *config_filename) 289static void set_config_filename(const char *config_filename)
300{ 290{
@@ -359,8 +349,16 @@ static void build_conf(struct menu *menu)
359 int type, tmp, doint = 2; 349 int type, tmp, doint = 2;
360 tristate val; 350 tristate val;
361 char ch; 351 char ch;
362 352 bool visible;
363 if (!menu_is_visible(menu)) 353
354 /*
355 * note: menu_is_visible() has side effect that it will
356 * recalc the value of the symbol.
357 */
358 visible = menu_is_visible(menu);
359 if (show_all_options && !menu_has_prompt(menu))
360 return;
361 else if (!show_all_options && !visible)
364 return; 362 return;
365 363
366 sym = menu->sym; 364 sym = menu->sym;
@@ -619,6 +617,9 @@ static void conf(struct menu *menu)
619 case 7: 617 case 7:
620 search_conf(); 618 search_conf();
621 break; 619 break;
620 case 8:
621 show_all_options = !show_all_options;
622 break;
622 } 623 }
623 } 624 }
624} 625}
@@ -638,6 +639,7 @@ static void show_help(struct menu *menu)
638{ 639{
639 struct gstr help = str_new(); 640 struct gstr help = str_new();
640 641
642 help.max_width = getmaxx(stdscr) - 10;
641 menu_get_ext_help(menu, &help); 643 menu_get_ext_help(menu, &help);
642 644
643 show_helptext(_(menu_get_prompt(menu)), str_get(&help)); 645 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 059a2465c574..4fb590247f33 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
38 va_end(ap); 38 va_end(ap);
39} 39}
40 40
41void menu_init(void) 41void _menu_init(void)
42{ 42{
43 current_entry = current_menu = &rootmenu; 43 current_entry = current_menu = &rootmenu;
44 last_entry_ptr = &rootmenu.list; 44 last_entry_ptr = &rootmenu.list;
@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
58 *last_entry_ptr = menu; 58 *last_entry_ptr = menu;
59 last_entry_ptr = &menu->next; 59 last_entry_ptr = &menu->next;
60 current_entry = menu; 60 current_entry = menu;
61 if (sym)
62 menu_add_symbol(P_SYMBOL, sym, NULL);
61} 63}
62 64
63void menu_end_entry(void) 65void menu_end_entry(void)
@@ -105,6 +107,7 @@ static struct expr *menu_check_dep(struct expr *e)
105void menu_add_dep(struct expr *dep) 107void menu_add_dep(struct expr *dep)
106{ 108{
107 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); 109 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
110 current_entry->dir_dep = current_entry->dep;
108} 111}
109 112
110void menu_set_type(int type) 113void menu_set_type(int type)
@@ -197,7 +200,7 @@ static void sym_check_prop(struct symbol *sym)
197 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && 200 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
198 prop->expr->type != E_SYMBOL) 201 prop->expr->type != E_SYMBOL)
199 prop_warn(prop, 202 prop_warn(prop,
200 "default for config symbol '%'" 203 "default for config symbol '%s'"
201 " must be a single symbol", sym->name); 204 " must be a single symbol", sym->name);
202 break; 205 break;
203 case P_SELECT: 206 case P_SELECT:
@@ -288,6 +291,10 @@ void menu_finalize(struct menu *parent)
288 for (menu = parent->list; menu; menu = menu->next) 291 for (menu = parent->list; menu; menu = menu->next)
289 menu_finalize(menu); 292 menu_finalize(menu);
290 } else if (sym) { 293 } else if (sym) {
294 /* ignore inherited dependencies for dir_dep */
295 sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
296 sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
297
291 basedep = parent->prompt ? parent->prompt->visible.expr : NULL; 298 basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
292 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); 299 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
293 basedep = expr_eliminate_dups(expr_transform(basedep)); 300 basedep = expr_eliminate_dups(expr_transform(basedep));
@@ -390,6 +397,13 @@ void menu_finalize(struct menu *parent)
390 } 397 }
391} 398}
392 399
400bool menu_has_prompt(struct menu *menu)
401{
402 if (!menu->prompt)
403 return false;
404 return true;
405}
406
393bool menu_is_visible(struct menu *menu) 407bool menu_is_visible(struct menu *menu)
394{ 408{
395 struct menu *child; 409 struct menu *child;
@@ -398,6 +412,7 @@ bool menu_is_visible(struct menu *menu)
398 412
399 if (!menu->prompt) 413 if (!menu->prompt)
400 return false; 414 return false;
415
401 sym = menu->sym; 416 sym = menu->sym;
402 if (sym) { 417 if (sym) {
403 sym_calc_value(sym); 418 sym_calc_value(sym);
@@ -407,12 +422,18 @@ bool menu_is_visible(struct menu *menu)
407 422
408 if (visible != no) 423 if (visible != no)
409 return true; 424 return true;
425
410 if (!sym || sym_get_tristate_value(menu->sym) == no) 426 if (!sym || sym_get_tristate_value(menu->sym) == no)
411 return false; 427 return false;
412 428
413 for (child = menu->list; child; child = child->next) 429 for (child = menu->list; child; child = child->next) {
414 if (menu_is_visible(child)) 430 if (menu_is_visible(child)) {
431 if (sym)
432 sym->flags |= SYMBOL_DEF_USER;
415 return true; 433 return true;
434 }
435 }
436
416 return false; 437 return false;
417} 438}
418 439
@@ -491,9 +512,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
491 bool hit; 512 bool hit;
492 struct property *prop; 513 struct property *prop;
493 514
494 if (sym && sym->name) 515 if (sym && sym->name) {
495 str_printf(r, "Symbol: %s [=%s]\n", sym->name, 516 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
496 sym_get_string_value(sym)); 517 sym_get_string_value(sym));
518 str_printf(r, "Type : %s\n", sym_type_name(sym->type));
519 if (sym->type == S_INT || sym->type == S_HEX) {
520 prop = sym_get_range_prop(sym);
521 if (prop) {
522 str_printf(r, "Range : ");
523 expr_gstr_print(prop->expr, r);
524 str_append(r, "\n");
525 }
526 }
527 }
497 for_all_prompts(sym, prop) 528 for_all_prompts(sym, prop)
498 get_prompt_str(r, prop); 529 get_prompt_str(r, prop);
499 hit = false; 530 hit = false;
@@ -515,6 +546,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
515 str_append(r, "\n\n"); 546 str_append(r, "\n\n");
516} 547}
517 548
549struct gstr get_relations_str(struct symbol **sym_arr)
550{
551 struct symbol *sym;
552 struct gstr res = str_new();
553 int i;
554
555 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
556 get_symbol_str(&res, sym);
557 if (!i)
558 str_append(&res, _("No matches found.\n"));
559 return res;
560}
561
562
518void menu_get_ext_help(struct menu *menu, struct gstr *help) 563void menu_get_ext_help(struct menu *menu, struct gstr *help)
519{ 564{
520 struct symbol *sym = menu->sym; 565 struct symbol *sym = menu->sym;
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
new file mode 100644
index 000000000000..762caf80ce37
--- /dev/null
+++ b/scripts/kconfig/nconf.c
@@ -0,0 +1,1568 @@
1/*
2 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Derived from menuconfig.
6 *
7 */
8#define LKC_DIRECT_LINK
9#include "lkc.h"
10#include "nconf.h"
11
12static const char nconf_readme[] = N_(
13"Overview\n"
14"--------\n"
15"Some kernel features may be built directly into the kernel.\n"
16"Some may be made into loadable runtime modules. Some features\n"
17"may be completely removed altogether. There are also certain\n"
18"kernel parameters which are not really features, but must be\n"
19"entered in as decimal or hexadecimal numbers or possibly text.\n"
20"\n"
21"Menu items beginning with following braces represent features that\n"
22" [ ] can be built in or removed\n"
23" < > can be built in, modularized or removed\n"
24" { } can be built in or modularized (selected by other feature)\n"
25" - - are selected by other feature,\n"
26" XXX cannot be selected. use Symbol Info to find out why,\n"
27"while *, M or whitespace inside braces means to build in, build as\n"
28"a module or to exclude the feature respectively.\n"
29"\n"
30"To change any of these features, highlight it with the cursor\n"
31"keys and press <Y> to build it in, <M> to make it a module or\n"
32"<N> to removed it. You may also press the <Space Bar> to cycle\n"
33"through the available options (ie. Y->N->M->Y).\n"
34"\n"
35"Some additional keyboard hints:\n"
36"\n"
37"Menus\n"
38"----------\n"
39"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
40" you wish to change use <Enter> or <Space>. Goto submenu by \n"
41" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
42" Submenus are designated by \"--->\".\n"
43"\n"
44" Shortcut: Press the option's highlighted letter (hotkey).\n"
45" Pressing a hotkey more than once will sequence\n"
46" through all visible items which use that hotkey.\n"
47"\n"
48" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
49" unseen options into view.\n"
50"\n"
51"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
52"\n"
53"o To get help with an item, press <F1>\n"
54" Shortcut: Press <h> or <?>.\n"
55"\n"
56"\n"
57"Radiolists (Choice lists)\n"
58"-----------\n"
59"o Use the cursor keys to select the option you wish to set and press\n"
60" <S> or the <SPACE BAR>.\n"
61"\n"
62" Shortcut: Press the first letter of the option you wish to set then\n"
63" press <S> or <SPACE BAR>.\n"
64"\n"
65"o To see available help for the item, press <F1>\n"
66" Shortcut: Press <H> or <?>.\n"
67"\n"
68"\n"
69"Data Entry\n"
70"-----------\n"
71"o Enter the requested information and press <ENTER>\n"
72" If you are entering hexadecimal values, it is not necessary to\n"
73" add the '0x' prefix to the entry.\n"
74"\n"
75"o For help, press <F1>.\n"
76"\n"
77"\n"
78"Text Box (Help Window)\n"
79"--------\n"
80"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
81" keys h,j,k,l function here as do <SPACE BAR> for those\n"
82" who are familiar with less and lynx.\n"
83"\n"
84"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
85"\n"
86"\n"
87"Alternate Configuration Files\n"
88"-----------------------------\n"
89"nconfig supports the use of alternate configuration files for\n"
90"those who, for various reasons, find it necessary to switch\n"
91"between different kernel configurations.\n"
92"\n"
93"At the end of the main menu you will find two options. One is\n"
94"for saving the current configuration to a file of your choosing.\n"
95"The other option is for loading a previously saved alternate\n"
96"configuration.\n"
97"\n"
98"Even if you don't use alternate configuration files, but you\n"
99"find during a nconfig session that you have completely messed\n"
100"up your settings, you may use the \"Load Alternate...\" option to\n"
101"restore your previously saved settings from \".config\" without\n"
102"restarting nconfig.\n"
103"\n"
104"Other information\n"
105"-----------------\n"
106"If you use nconfig in an XTERM window make sure you have your\n"
107"$TERM variable set to point to a xterm definition which supports color.\n"
108"Otherwise, nconfig will look rather bad. nconfig will not\n"
109"display correctly in a RXVT window because rxvt displays only one\n"
110"intensity of color, bright.\n"
111"\n"
112"nconfig will display larger menus on screens or xterms which are\n"
113"set to display more than the standard 25 row by 80 column geometry.\n"
114"In order for this to work, the \"stty size\" command must be able to\n"
115"display the screen's current row and column geometry. I STRONGLY\n"
116"RECOMMEND that you make sure you do NOT have the shell variables\n"
117"LINES and COLUMNS exported into your environment. Some distributions\n"
118"export those variables via /etc/profile. Some ncurses programs can\n"
119"become confused when those variables (LINES & COLUMNS) don't reflect\n"
120"the true screen size.\n"
121"\n"
122"Optional personality available\n"
123"------------------------------\n"
124"If you prefer to have all of the kernel options listed in a single\n"
125"menu, rather than the default multimenu hierarchy, run the nconfig\n"
126"with NCONFIG_MODE environment variable set to single_menu. Example:\n"
127"\n"
128"make NCONFIG_MODE=single_menu nconfig\n"
129"\n"
130"<Enter> will then unroll the appropriate category, or enfold it if it\n"
131"is already unrolled.\n"
132"\n"
133"Note that this mode can eventually be a little more CPU expensive\n"
134"(especially with a larger number of unrolled categories) than the\n"
135"default mode.\n"
136"\n"),
137menu_no_f_instructions[] = N_(
138" You do not have function keys support. Please follow the\n"
139" following instructions:\n"
140" Arrow keys navigate the menu.\n"
141" <Enter> or <right-arrow> selects submenus --->.\n"
142" Capital Letters are hotkeys.\n"
143" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
144" Pressing SpaceBar toggles between the above options\n"
145" Press <Esc> or <left-arrow> to go back one menu, \n"
146" <?> or <h> for Help, </> for Search.\n"
147" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
148" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
149" <Esc> always leaves the current window\n"),
150menu_instructions[] = N_(
151" Arrow keys navigate the menu.\n"
152" <Enter> or <right-arrow> selects submenus --->.\n"
153" Capital Letters are hotkeys.\n"
154" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
155" Pressing SpaceBar toggles between the above options\n"
156" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n"
157" <?>, <F1> or <h> for Help, </> for Search.\n"
158" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
159" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
160" <Esc> always leaves the current window\n"),
161radiolist_instructions[] = N_(
162" Use the arrow keys to navigate this window or\n"
163" press the hotkey of the item you wish to select\n"
164" followed by the <SPACE BAR>.\n"
165" Press <?>, <F1> or <h> for additional information about this option.\n"),
166inputbox_instructions_int[] = N_(
167"Please enter a decimal value.\n"
168"Fractions will not be accepted.\n"
169"Press <RETURN> to accept, <ESC> to cancel."),
170inputbox_instructions_hex[] = N_(
171"Please enter a hexadecimal value.\n"
172"Press <RETURN> to accept, <ESC> to cancel."),
173inputbox_instructions_string[] = N_(
174"Please enter a string value.\n"
175"Press <RETURN> to accept, <ESC> to cancel."),
176setmod_text[] = N_(
177"This feature depends on another which\n"
178"has been configured as a module.\n"
179"As a result, this feature will be built as a module."),
180nohelp_text[] = N_(
181"There is no help available for this kernel option.\n"),
182load_config_text[] = N_(
183"Enter the name of the configuration file you wish to load.\n"
184"Accept the name shown to restore the configuration you\n"
185"last retrieved. Leave blank to abort."),
186load_config_help[] = N_(
187"\n"
188"For various reasons, one may wish to keep several different kernel\n"
189"configurations available on a single machine.\n"
190"\n"
191"If you have saved a previous configuration in a file other than the\n"
192"kernel's default, entering the name of the file here will allow you\n"
193"to modify that configuration.\n"
194"\n"
195"If you are uncertain, then you have probably never used alternate\n"
196"configuration files. You should therefor leave this blank to abort.\n"),
197save_config_text[] = N_(
198"Enter a filename to which this configuration should be saved\n"
199"as an alternate. Leave blank to abort."),
200save_config_help[] = N_(
201"\n"
202"For various reasons, one may wish to keep different kernel\n"
203"configurations available on a single machine.\n"
204"\n"
205"Entering a file name here will allow you to later retrieve, modify\n"
206"and use the current configuration as an alternate to whatever\n"
207"configuration options you have selected at that time.\n"
208"\n"
209"If you are uncertain what all this means then you should probably\n"
210"leave this blank.\n"),
211search_help[] = N_(
212"\n"
213"Search for CONFIG_ symbols and display their relations.\n"
214"Regular expressions are allowed.\n"
215"Example: search for \"^FOO\"\n"
216"Result:\n"
217"-----------------------------------------------------------------\n"
218"Symbol: FOO [ = m]\n"
219"Prompt: Foo bus is used to drive the bar HW\n"
220"Defined at drivers/pci/Kconfig:47\n"
221"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
222"Location:\n"
223" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
224" -> PCI support (PCI [ = y])\n"
225" -> PCI access mode (<choice> [ = y])\n"
226"Selects: LIBCRC32\n"
227"Selected by: BAR\n"
228"-----------------------------------------------------------------\n"
229"o The line 'Prompt:' shows the text used in the menu structure for\n"
230" this CONFIG_ symbol\n"
231"o The 'Defined at' line tell at what file / line number the symbol\n"
232" is defined\n"
233"o The 'Depends on:' line tell what symbols needs to be defined for\n"
234" this symbol to be visible in the menu (selectable)\n"
235"o The 'Location:' lines tell where in the menu structure this symbol\n"
236" is located\n"
237" A location followed by a [ = y] indicate that this is a selectable\n"
238" menu item - and current value is displayed inside brackets.\n"
239"o The 'Selects:' line tell what symbol will be automatically\n"
240" selected if this symbol is selected (y or m)\n"
241"o The 'Selected by' line tell what symbol has selected this symbol\n"
242"\n"
243"Only relevant lines are shown.\n"
244"\n\n"
245"Search examples:\n"
246"Examples: USB = > find all CONFIG_ symbols containing USB\n"
247" ^USB => find all CONFIG_ symbols starting with USB\n"
248" USB$ => find all CONFIG_ symbols ending with USB\n"
249"\n");
250
251struct mitem {
252 char str[256];
253 char tag;
254 void *usrptr;
255 int is_hot;
256 int is_visible;
257};
258
259#define MAX_MENU_ITEMS 4096
260static int show_all_items;
261static int indent;
262static struct menu *current_menu;
263static int child_count;
264static int single_menu_mode;
265/* the window in which all information appears */
266static WINDOW *main_window;
267/* the largest size of the menu window */
268static int mwin_max_lines;
269static int mwin_max_cols;
270/* the window in which we show option buttons */
271static MENU *curses_menu;
272static ITEM *curses_menu_items[MAX_MENU_ITEMS];
273static struct mitem k_menu_items[MAX_MENU_ITEMS];
274static int items_num;
275static int global_exit;
276/* the currently selected button */
277const char *current_instructions = menu_instructions;
278/* this array is used to implement hot keys. it is updated in item_make and
279 * resetted in clean_items. It would be better to use a hash, but lets keep it
280 * simple... */
281#define MAX_SAME_KEY MAX_MENU_ITEMS
282struct {
283 int count;
284 int ptrs[MAX_MENU_ITEMS];
285} hotkeys[1<<(sizeof(char)*8)];
286
287static void conf(struct menu *menu);
288static void conf_choice(struct menu *menu);
289static void conf_string(struct menu *menu);
290static void conf_load(void);
291static void conf_save(void);
292static void show_help(struct menu *menu);
293static int do_exit(void);
294static void setup_windows(void);
295
296typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297static void handle_f1(int *key, struct menu *current_item);
298static void handle_f2(int *key, struct menu *current_item);
299static void handle_f3(int *key, struct menu *current_item);
300static void handle_f4(int *key, struct menu *current_item);
301static void handle_f5(int *key, struct menu *current_item);
302static void handle_f6(int *key, struct menu *current_item);
303static void handle_f7(int *key, struct menu *current_item);
304static void handle_f8(int *key, struct menu *current_item);
305
306struct function_keys {
307 const char *key_str;
308 const char *func;
309 function_key key;
310 function_key_handler_t handler;
311};
312
313static const int function_keys_num = 8;
314struct function_keys function_keys[] = {
315 {
316 .key_str = "F1",
317 .func = "Help",
318 .key = F_HELP,
319 .handler = handle_f1,
320 },
321 {
322 .key_str = "F2",
323 .func = "Symbol Info",
324 .key = F_SYMBOL,
325 .handler = handle_f2,
326 },
327 {
328 .key_str = "F3",
329 .func = "Instructions",
330 .key = F_INSTS,
331 .handler = handle_f3,
332 },
333 {
334 .key_str = "F4",
335 .func = "Config",
336 .key = F_CONF,
337 .handler = handle_f4,
338 },
339 {
340 .key_str = "F5",
341 .func = "Back",
342 .key = F_BACK,
343 .handler = handle_f5,
344 },
345 {
346 .key_str = "F6",
347 .func = "Save",
348 .key = F_SAVE,
349 .handler = handle_f6,
350 },
351 {
352 .key_str = "F7",
353 .func = "Load",
354 .key = F_LOAD,
355 .handler = handle_f7,
356 },
357 {
358 .key_str = "F8",
359 .func = "Exit",
360 .key = F_EXIT,
361 .handler = handle_f8,
362 },
363};
364
365static void print_function_line(void)
366{
367 int i;
368 int offset = 1;
369 const int skip = 1;
370
371 for (i = 0; i < function_keys_num; i++) {
372 wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
373 mvwprintw(main_window, LINES-3, offset,
374 "%s",
375 function_keys[i].key_str);
376 wattrset(main_window, attributes[FUNCTION_TEXT]);
377 offset += strlen(function_keys[i].key_str);
378 mvwprintw(main_window, LINES-3,
379 offset, "%s",
380 function_keys[i].func);
381 offset += strlen(function_keys[i].func) + skip;
382 }
383 wattrset(main_window, attributes[NORMAL]);
384}
385
386/* help */
387static void handle_f1(int *key, struct menu *current_item)
388{
389 show_scroll_win(main_window,
390 _("README"), _(nconf_readme));
391 return;
392}
393
394/* symbole help */
395static void handle_f2(int *key, struct menu *current_item)
396{
397 show_help(current_item);
398 return;
399}
400
401/* instructions */
402static void handle_f3(int *key, struct menu *current_item)
403{
404 show_scroll_win(main_window,
405 _("Instructions"),
406 _(current_instructions));
407 return;
408}
409
410/* config */
411static void handle_f4(int *key, struct menu *current_item)
412{
413 int res = btn_dialog(main_window,
414 _("Show all symbols?"),
415 2,
416 " <Show All> ",
417 "<Don't show all>");
418 if (res == 0)
419 show_all_items = 1;
420 else if (res == 1)
421 show_all_items = 0;
422
423 return;
424}
425
426/* back */
427static void handle_f5(int *key, struct menu *current_item)
428{
429 *key = KEY_LEFT;
430 return;
431}
432
433/* save */
434static void handle_f6(int *key, struct menu *current_item)
435{
436 conf_save();
437 return;
438}
439
440/* load */
441static void handle_f7(int *key, struct menu *current_item)
442{
443 conf_load();
444 return;
445}
446
447/* exit */
448static void handle_f8(int *key, struct menu *current_item)
449{
450 do_exit();
451 return;
452}
453
454/* return != 0 to indicate the key was handles */
455static int process_special_keys(int *key, struct menu *menu)
456{
457 int i;
458
459 if (*key == KEY_RESIZE) {
460 setup_windows();
461 return 1;
462 }
463
464 for (i = 0; i < function_keys_num; i++) {
465 if (*key == KEY_F(function_keys[i].key) ||
466 *key == '0' + function_keys[i].key){
467 function_keys[i].handler(key, menu);
468 return 1;
469 }
470 }
471
472 return 0;
473}
474
475static void clean_items(void)
476{
477 int i;
478 for (i = 0; curses_menu_items[i]; i++)
479 free_item(curses_menu_items[i]);
480 bzero(curses_menu_items, sizeof(curses_menu_items));
481 bzero(k_menu_items, sizeof(k_menu_items));
482 bzero(hotkeys, sizeof(hotkeys));
483 items_num = 0;
484}
485
486/* return the index of the next hot item, or -1 if no such item exists */
487static int get_next_hot(int c)
488{
489 static int hot_index;
490 static int hot_char;
491
492 if (c < 0 || c > 255 || hotkeys[c].count <= 0)
493 return -1;
494
495 if (hot_char == c) {
496 hot_index = (hot_index+1)%hotkeys[c].count;
497 return hotkeys[c].ptrs[hot_index];
498 } else {
499 hot_char = c;
500 hot_index = 0;
501 return hotkeys[c].ptrs[0];
502 }
503}
504
505/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
506static int canbhot(char c)
507{
508 c = tolower(c);
509 return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
510 c != 'n' && c != '?';
511}
512
513/* check if str already contains a hot key. */
514static int is_hot(int index)
515{
516 return k_menu_items[index].is_hot;
517}
518
519/* find the first possible hot key, and mark it.
520 * index is the index of the item in the menu
521 * return 0 on success*/
522static int make_hot(char *dest, int len, const char *org, int index)
523{
524 int position = -1;
525 int i;
526 int tmp;
527 int c;
528 int org_len = strlen(org);
529
530 if (org == NULL || is_hot(index))
531 return 1;
532
533 /* make sure not to make hot keys out of markers.
534 * find where to start looking for a hot key
535 */
536 i = 0;
537 /* skip white space */
538 while (i < org_len && org[i] == ' ')
539 i++;
540 if (i == org_len)
541 return -1;
542 /* if encountering '(' or '<' or '[', find the match and look from there
543 **/
544 if (org[i] == '[' || org[i] == '<' || org[i] == '(') {
545 i++;
546 for (; i < org_len; i++)
547 if (org[i] == ']' || org[i] == '>' || org[i] == ')')
548 break;
549 }
550 if (i == org_len)
551 return -1;
552 for (; i < org_len; i++) {
553 if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
554 position = i;
555 break;
556 }
557 }
558 if (position == -1)
559 return 1;
560
561 /* ok, char at org[position] should be a hot key to this item */
562 c = tolower(org[position]);
563 tmp = hotkeys[c].count;
564 hotkeys[c].ptrs[tmp] = index;
565 hotkeys[c].count++;
566 /*
567 snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
568 &org[position+1]);
569 */
570 /* make org[position] uppercase, and all leading letter small case */
571 strncpy(dest, org, len);
572 for (i = 0; i < position; i++)
573 dest[i] = tolower(dest[i]);
574 dest[position] = toupper(dest[position]);
575 k_menu_items[index].is_hot = 1;
576 return 0;
577}
578
579/* Make a new item. Add a hotkey mark in the first possible letter.
580 * As ncurses does not allow any attributes inside menue item, we mark the
581 * hot key as the first capitalized letter in the string */
582static void item_make(struct menu *menu, char tag, const char *fmt, ...)
583{
584 va_list ap;
585 char tmp_str[256];
586
587 if (items_num > MAX_MENU_ITEMS-1)
588 return;
589
590 bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
591 k_menu_items[items_num].tag = tag;
592 k_menu_items[items_num].usrptr = menu;
593 if (menu != NULL)
594 k_menu_items[items_num].is_visible =
595 menu_is_visible(menu);
596 else
597 k_menu_items[items_num].is_visible = 1;
598
599 va_start(ap, fmt);
600 vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap);
601 if (!k_menu_items[items_num].is_visible)
602 memcpy(tmp_str, "XXX", 3);
603 va_end(ap);
604 if (make_hot(
605 k_menu_items[items_num].str,
606 sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0)
607 strncpy(k_menu_items[items_num].str,
608 tmp_str,
609 sizeof(k_menu_items[items_num].str));
610
611 curses_menu_items[items_num] = new_item(
612 k_menu_items[items_num].str,
613 k_menu_items[items_num].str);
614 set_item_userptr(curses_menu_items[items_num],
615 &k_menu_items[items_num]);
616 /*
617 if (!k_menu_items[items_num].is_visible)
618 item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
619 */
620
621 items_num++;
622 curses_menu_items[items_num] = NULL;
623}
624
625/* very hackish. adds a string to the last item added */
626static void item_add_str(const char *fmt, ...)
627{
628 va_list ap;
629 int index = items_num-1;
630 char new_str[256];
631 char tmp_str[256];
632
633 if (index < 0)
634 return;
635
636 va_start(ap, fmt);
637 vsnprintf(new_str, sizeof(new_str), fmt, ap);
638 va_end(ap);
639 snprintf(tmp_str, sizeof(tmp_str), "%s%s",
640 k_menu_items[index].str, new_str);
641 if (make_hot(k_menu_items[index].str,
642 sizeof(k_menu_items[index].str), tmp_str, index) != 0)
643 strncpy(k_menu_items[index].str,
644 tmp_str,
645 sizeof(k_menu_items[index].str));
646
647 free_item(curses_menu_items[index]);
648 curses_menu_items[index] = new_item(
649 k_menu_items[index].str,
650 k_menu_items[index].str);
651 set_item_userptr(curses_menu_items[index],
652 &k_menu_items[index]);
653}
654
655/* get the tag of the currently selected item */
656static char item_tag(void)
657{
658 ITEM *cur;
659 struct mitem *mcur;
660
661 cur = current_item(curses_menu);
662 if (cur == NULL)
663 return 0;
664 mcur = (struct mitem *) item_userptr(cur);
665 return mcur->tag;
666}
667
668static int curses_item_index(void)
669{
670 return item_index(current_item(curses_menu));
671}
672
673static void *item_data(void)
674{
675 ITEM *cur;
676 struct mitem *mcur;
677
678 cur = current_item(curses_menu);
679 mcur = (struct mitem *) item_userptr(cur);
680 return mcur->usrptr;
681
682}
683
684static int item_is_tag(char tag)
685{
686 return item_tag() == tag;
687}
688
689static char filename[PATH_MAX+1];
690static char menu_backtitle[PATH_MAX+128];
691static const char *set_config_filename(const char *config_filename)
692{
693 int size;
694 struct symbol *sym;
695
696 sym = sym_lookup("KERNELVERSION", 0);
697 sym_calc_value(sym);
698 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
699 _("%s - Linux Kernel v%s Configuration"),
700 config_filename, sym_get_string_value(sym));
701 if (size >= sizeof(menu_backtitle))
702 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
703
704 size = snprintf(filename, sizeof(filename), "%s", config_filename);
705 if (size >= sizeof(filename))
706 filename[sizeof(filename)-1] = '\0';
707 return menu_backtitle;
708}
709
710/* command = 0 is supress, 1 is restore */
711static void supress_stdout(int command)
712{
713 static FILE *org_stdout;
714 static FILE *org_stderr;
715
716 if (command == 0) {
717 org_stdout = stdout;
718 org_stderr = stderr;
719 stdout = fopen("/dev/null", "a");
720 stderr = fopen("/dev/null", "a");
721 } else {
722 fclose(stdout);
723 fclose(stderr);
724 stdout = org_stdout;
725 stderr = org_stderr;
726 }
727}
728
729/* return = 0 means we are successful.
730 * -1 means go on doing what you were doing
731 */
732static int do_exit(void)
733{
734 int res;
735 if (!conf_get_changed()) {
736 global_exit = 1;
737 return 0;
738 }
739 res = btn_dialog(main_window,
740 _("Do you wish to save your "
741 "new kernel configuration?\n"
742 "<ESC> to cancel and resume nconfig."),
743 2,
744 " <save> ",
745 "<don't save>");
746 if (res == KEY_EXIT) {
747 global_exit = 0;
748 return -1;
749 }
750
751 /* if we got here, the user really wants to exit */
752 switch (res) {
753 case 0:
754 supress_stdout(0);
755 res = conf_write(filename);
756 supress_stdout(1);
757 if (res)
758 btn_dialog(
759 main_window,
760 _("Error during writing of the kernel "
761 "configuration.\n"
762 "Your kernel configuration "
763 "changes were NOT saved."),
764 1,
765 "<OK>");
766 else {
767 char buf[1024];
768 snprintf(buf, 1024,
769 _("Configuration written to %s\n"
770 "End of Linux kernel configuration.\n"
771 "Execute 'make' to build the kernel or try"
772 " 'make help'."), filename);
773 btn_dialog(
774 main_window,
775 buf,
776 1,
777 "<OK>");
778 }
779 break;
780 default:
781 btn_dialog(
782 main_window,
783 _("Your kernel configuration changes were NOT saved."),
784 1,
785 "<OK>");
786 break;
787 }
788 global_exit = 1;
789 return 0;
790}
791
792
793static void search_conf(void)
794{
795 struct symbol **sym_arr;
796 struct gstr res;
797 char dialog_input_result[100];
798 char *dialog_input;
799 int dres;
800again:
801 dres = dialog_inputbox(main_window,
802 _("Search Configuration Parameter"),
803 _("Enter CONFIG_ (sub)string to search for "
804 "(with or without \"CONFIG\")"),
805 "", dialog_input_result, 99);
806 switch (dres) {
807 case 0:
808 break;
809 case 1:
810 show_scroll_win(main_window,
811 _("Search Configuration"), search_help);
812 goto again;
813 default:
814 return;
815 }
816
817 /* strip CONFIG_ if necessary */
818 dialog_input = dialog_input_result;
819 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
820 dialog_input += 7;
821
822 sym_arr = sym_re_search(dialog_input);
823 res = get_relations_str(sym_arr);
824 free(sym_arr);
825 show_scroll_win(main_window,
826 _("Search Results"), str_get(&res));
827 str_free(&res);
828}
829
830
831static void build_conf(struct menu *menu)
832{
833 struct symbol *sym;
834 struct property *prop;
835 struct menu *child;
836 int type, tmp, doint = 2;
837 tristate val;
838 char ch;
839
840 if (!menu || (!show_all_items && !menu_is_visible(menu)))
841 return;
842
843 sym = menu->sym;
844 prop = menu->prompt;
845 if (!sym) {
846 if (prop && menu != current_menu) {
847 const char *prompt = menu_get_prompt(menu);
848 enum prop_type ptype;
849 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
850 switch (ptype) {
851 case P_MENU:
852 child_count++;
853 prompt = _(prompt);
854 if (single_menu_mode) {
855 item_make(menu, 'm',
856 "%s%*c%s",
857 menu->data ? "-->" : "++>",
858 indent + 1, ' ', prompt);
859 } else
860 item_make(menu, 'm',
861 " %*c%s --->",
862 indent + 1,
863 ' ', prompt);
864
865 if (single_menu_mode && menu->data)
866 goto conf_childs;
867 return;
868 case P_COMMENT:
869 if (prompt) {
870 child_count++;
871 item_make(menu, ':',
872 " %*c*** %s ***",
873 indent + 1, ' ',
874 _(prompt));
875 }
876 break;
877 default:
878 if (prompt) {
879 child_count++;
880 item_make(menu, ':', "---%*c%s",
881 indent + 1, ' ',
882 _(prompt));
883 }
884 }
885 } else
886 doint = 0;
887 goto conf_childs;
888 }
889
890 type = sym_get_type(sym);
891 if (sym_is_choice(sym)) {
892 struct symbol *def_sym = sym_get_choice_value(sym);
893 struct menu *def_menu = NULL;
894
895 child_count++;
896 for (child = menu->list; child; child = child->next) {
897 if (menu_is_visible(child) && child->sym == def_sym)
898 def_menu = child;
899 }
900
901 val = sym_get_tristate_value(sym);
902 if (sym_is_changable(sym)) {
903 switch (type) {
904 case S_BOOLEAN:
905 item_make(menu, 't', "[%c]",
906 val == no ? ' ' : '*');
907 break;
908 case S_TRISTATE:
909 switch (val) {
910 case yes:
911 ch = '*';
912 break;
913 case mod:
914 ch = 'M';
915 break;
916 default:
917 ch = ' ';
918 break;
919 }
920 item_make(menu, 't', "<%c>", ch);
921 break;
922 }
923 } else {
924 item_make(menu, def_menu ? 't' : ':', " ");
925 }
926
927 item_add_str("%*c%s", indent + 1,
928 ' ', _(menu_get_prompt(menu)));
929 if (val == yes) {
930 if (def_menu) {
931 item_add_str(" (%s)",
932 _(menu_get_prompt(def_menu)));
933 item_add_str(" --->");
934 if (def_menu->list) {
935 indent += 2;
936 build_conf(def_menu);
937 indent -= 2;
938 }
939 }
940 return;
941 }
942 } else {
943 if (menu == current_menu) {
944 item_make(menu, ':',
945 "---%*c%s", indent + 1,
946 ' ', _(menu_get_prompt(menu)));
947 goto conf_childs;
948 }
949 child_count++;
950 val = sym_get_tristate_value(sym);
951 if (sym_is_choice_value(sym) && val == yes) {
952 item_make(menu, ':', " ");
953 } else {
954 switch (type) {
955 case S_BOOLEAN:
956 if (sym_is_changable(sym))
957 item_make(menu, 't', "[%c]",
958 val == no ? ' ' : '*');
959 else
960 item_make(menu, 't', "-%c-",
961 val == no ? ' ' : '*');
962 break;
963 case S_TRISTATE:
964 switch (val) {
965 case yes:
966 ch = '*';
967 break;
968 case mod:
969 ch = 'M';
970 break;
971 default:
972 ch = ' ';
973 break;
974 }
975 if (sym_is_changable(sym)) {
976 if (sym->rev_dep.tri == mod)
977 item_make(menu,
978 't', "{%c}", ch);
979 else
980 item_make(menu,
981 't', "<%c>", ch);
982 } else
983 item_make(menu, 't', "-%c-", ch);
984 break;
985 default:
986 tmp = 2 + strlen(sym_get_string_value(sym));
987 item_make(menu, 's', " (%s)",
988 sym_get_string_value(sym));
989 tmp = indent - tmp + 4;
990 if (tmp < 0)
991 tmp = 0;
992 item_add_str("%*c%s%s", tmp, ' ',
993 _(menu_get_prompt(menu)),
994 (sym_has_value(sym) ||
995 !sym_is_changable(sym)) ? "" :
996 _(" (NEW)"));
997 goto conf_childs;
998 }
999 }
1000 item_add_str("%*c%s%s", indent + 1, ' ',
1001 _(menu_get_prompt(menu)),
1002 (sym_has_value(sym) || !sym_is_changable(sym)) ?
1003 "" : _(" (NEW)"));
1004 if (menu->prompt && menu->prompt->type == P_MENU) {
1005 item_add_str(" --->");
1006 return;
1007 }
1008 }
1009
1010conf_childs:
1011 indent += doint;
1012 for (child = menu->list; child; child = child->next)
1013 build_conf(child);
1014 indent -= doint;
1015}
1016
1017static void reset_menu(void)
1018{
1019 unpost_menu(curses_menu);
1020 clean_items();
1021}
1022
1023/* adjust the menu to show this item.
1024 * prefer not to scroll the menu if possible*/
1025static void center_item(int selected_index, int *last_top_row)
1026{
1027 int toprow;
1028 int maxy, maxx;
1029
1030 scale_menu(curses_menu, &maxy, &maxx);
1031 set_top_row(curses_menu, *last_top_row);
1032 toprow = top_row(curses_menu);
1033 if (selected_index >= toprow && selected_index < toprow+maxy) {
1034 /* we can only move the selected item. no need to scroll */
1035 set_current_item(curses_menu,
1036 curses_menu_items[selected_index]);
1037 } else {
1038 toprow = max(selected_index-maxy/2, 0);
1039 if (toprow >= item_count(curses_menu)-maxy)
1040 toprow = item_count(curses_menu)-mwin_max_lines;
1041 set_top_row(curses_menu, toprow);
1042 set_current_item(curses_menu,
1043 curses_menu_items[selected_index]);
1044 }
1045 *last_top_row = toprow;
1046 post_menu(curses_menu);
1047 refresh_all_windows(main_window);
1048}
1049
1050/* this function assumes reset_menu has been called before */
1051static void show_menu(const char *prompt, const char *instructions,
1052 int selected_index, int *last_top_row)
1053{
1054 int maxx, maxy;
1055 WINDOW *menu_window;
1056
1057 current_instructions = instructions;
1058
1059 clear();
1060 wattrset(main_window, attributes[NORMAL]);
1061 print_in_middle(stdscr, 1, 0, COLS,
1062 menu_backtitle,
1063 attributes[MAIN_HEADING]);
1064
1065 wattrset(main_window, attributes[MAIN_MENU_BOX]);
1066 box(main_window, 0, 0);
1067 wattrset(main_window, attributes[MAIN_MENU_HEADING]);
1068 mvwprintw(main_window, 0, 3, " %s ", prompt);
1069 wattrset(main_window, attributes[NORMAL]);
1070
1071 set_menu_items(curses_menu, curses_menu_items);
1072
1073 /* position the menu at the middle of the screen */
1074 scale_menu(curses_menu, &maxy, &maxx);
1075 maxx = min(maxx, mwin_max_cols-2);
1076 maxy = mwin_max_lines-2;
1077 menu_window = derwin(main_window,
1078 maxy,
1079 maxx,
1080 2,
1081 (mwin_max_cols-maxx)/2);
1082 keypad(menu_window, TRUE);
1083 set_menu_win(curses_menu, menu_window);
1084 set_menu_sub(curses_menu, menu_window);
1085
1086 /* must reassert this after changing items, otherwise returns to a
1087 * default of 16
1088 */
1089 set_menu_format(curses_menu, maxy, 1);
1090 center_item(selected_index, last_top_row);
1091 set_menu_format(curses_menu, maxy, 1);
1092
1093 print_function_line();
1094
1095 /* Post the menu */
1096 post_menu(curses_menu);
1097 refresh_all_windows(main_window);
1098}
1099
1100
1101static void conf(struct menu *menu)
1102{
1103 char pattern[256];
1104 struct menu *submenu = 0;
1105 const char *prompt = menu_get_prompt(menu);
1106 struct symbol *sym;
1107 struct menu *active_menu = NULL;
1108 int res;
1109 int current_index = 0;
1110 int last_top_row = 0;
1111
1112 bzero(pattern, sizeof(pattern));
1113
1114 while (!global_exit) {
1115 reset_menu();
1116 current_menu = menu;
1117 build_conf(menu);
1118 if (!child_count)
1119 break;
1120
1121 show_menu(prompt ? _(prompt) : _("Main Menu"),
1122 _(menu_instructions),
1123 current_index, &last_top_row);
1124 keypad((menu_win(curses_menu)), TRUE);
1125 while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1126 if (process_special_keys(&res,
1127 (struct menu *) item_data()))
1128 break;
1129 switch (res) {
1130 case KEY_DOWN:
1131 menu_driver(curses_menu, REQ_DOWN_ITEM);
1132 break;
1133 case KEY_UP:
1134 menu_driver(curses_menu, REQ_UP_ITEM);
1135 break;
1136 case KEY_NPAGE:
1137 menu_driver(curses_menu, REQ_SCR_DPAGE);
1138 break;
1139 case KEY_PPAGE:
1140 menu_driver(curses_menu, REQ_SCR_UPAGE);
1141 break;
1142 case KEY_HOME:
1143 menu_driver(curses_menu, REQ_FIRST_ITEM);
1144 break;
1145 case KEY_END:
1146 menu_driver(curses_menu, REQ_LAST_ITEM);
1147 break;
1148 case 'h':
1149 case '?':
1150 show_help((struct menu *) item_data());
1151 break;
1152 }
1153 if (res == 10 || res == 27 ||
1154 res == 32 || res == 'n' || res == 'y' ||
1155 res == KEY_LEFT || res == KEY_RIGHT ||
1156 res == 'm' || res == '/')
1157 break;
1158 else if (canbhot(res)) {
1159 /* check for hot keys: */
1160 int tmp = get_next_hot(res);
1161 if (tmp != -1)
1162 center_item(tmp, &last_top_row);
1163 }
1164 refresh_all_windows(main_window);
1165 }
1166
1167 refresh_all_windows(main_window);
1168 /* if ESC or left*/
1169 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1170 break;
1171
1172 /* remember location in the menu */
1173 last_top_row = top_row(curses_menu);
1174 current_index = curses_item_index();
1175
1176 if (!item_tag())
1177 continue;
1178
1179 submenu = (struct menu *) item_data();
1180 active_menu = (struct menu *)item_data();
1181 if (!submenu || !menu_is_visible(submenu))
1182 continue;
1183 if (submenu)
1184 sym = submenu->sym;
1185 else
1186 sym = NULL;
1187
1188 switch (res) {
1189 case ' ':
1190 if (item_is_tag('t'))
1191 sym_toggle_tristate_value(sym);
1192 else if (item_is_tag('m'))
1193 conf(submenu);
1194 break;
1195 case KEY_RIGHT:
1196 case 10: /* ENTER WAS PRESSED */
1197 switch (item_tag()) {
1198 case 'm':
1199 if (single_menu_mode)
1200 submenu->data =
1201 (void *) (long) !submenu->data;
1202 else
1203 conf(submenu);
1204 break;
1205 case 't':
1206 if (sym_is_choice(sym) &&
1207 sym_get_tristate_value(sym) == yes)
1208 conf_choice(submenu);
1209 else if (submenu->prompt &&
1210 submenu->prompt->type == P_MENU)
1211 conf(submenu);
1212 else if (res == 10)
1213 sym_toggle_tristate_value(sym);
1214 break;
1215 case 's':
1216 conf_string(submenu);
1217 break;
1218 }
1219 break;
1220 case 'y':
1221 if (item_is_tag('t')) {
1222 if (sym_set_tristate_value(sym, yes))
1223 break;
1224 if (sym_set_tristate_value(sym, mod))
1225 btn_dialog(main_window, setmod_text, 0);
1226 }
1227 break;
1228 case 'n':
1229 if (item_is_tag('t'))
1230 sym_set_tristate_value(sym, no);
1231 break;
1232 case 'm':
1233 if (item_is_tag('t'))
1234 sym_set_tristate_value(sym, mod);
1235 break;
1236 case '/':
1237 search_conf();
1238 break;
1239 }
1240 }
1241}
1242
1243static void show_help(struct menu *menu)
1244{
1245 struct gstr help = str_new();
1246
1247 if (menu && menu->sym && menu_has_help(menu)) {
1248 if (menu->sym->name) {
1249 str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name);
1250 str_append(&help, _(menu_get_help(menu)));
1251 str_append(&help, "\n");
1252 get_symbol_str(&help, menu->sym);
1253 }
1254 } else {
1255 str_append(&help, nohelp_text);
1256 }
1257 show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1258 str_free(&help);
1259}
1260
1261static void conf_choice(struct menu *menu)
1262{
1263 const char *prompt = _(menu_get_prompt(menu));
1264 struct menu *child = 0;
1265 struct symbol *active;
1266 int selected_index = 0;
1267 int last_top_row = 0;
1268 int res, i = 0;
1269
1270 active = sym_get_choice_value(menu->sym);
1271 /* this is mostly duplicated from the conf() function. */
1272 while (!global_exit) {
1273 reset_menu();
1274
1275 for (i = 0, child = menu->list; child; child = child->next) {
1276 if (!show_all_items && !menu_is_visible(child))
1277 continue;
1278
1279 if (child->sym == sym_get_choice_value(menu->sym))
1280 item_make(child, ':', "<X> %s",
1281 _(menu_get_prompt(child)));
1282 else
1283 item_make(child, ':', " %s",
1284 _(menu_get_prompt(child)));
1285 if (child->sym == active){
1286 last_top_row = top_row(curses_menu);
1287 selected_index = i;
1288 }
1289 i++;
1290 }
1291 show_menu(prompt ? _(prompt) : _("Choice Menu"),
1292 _(radiolist_instructions),
1293 selected_index,
1294 &last_top_row);
1295 while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1296 if (process_special_keys(
1297 &res,
1298 (struct menu *) item_data()))
1299 break;
1300 switch (res) {
1301 case KEY_DOWN:
1302 menu_driver(curses_menu, REQ_DOWN_ITEM);
1303 break;
1304 case KEY_UP:
1305 menu_driver(curses_menu, REQ_UP_ITEM);
1306 break;
1307 case KEY_NPAGE:
1308 menu_driver(curses_menu, REQ_SCR_DPAGE);
1309 break;
1310 case KEY_PPAGE:
1311 menu_driver(curses_menu, REQ_SCR_UPAGE);
1312 break;
1313 case KEY_HOME:
1314 menu_driver(curses_menu, REQ_FIRST_ITEM);
1315 break;
1316 case KEY_END:
1317 menu_driver(curses_menu, REQ_LAST_ITEM);
1318 break;
1319 case 'h':
1320 case '?':
1321 show_help((struct menu *) item_data());
1322 break;
1323 }
1324 if (res == 10 || res == 27 || res == ' ' ||
1325 res == KEY_LEFT)
1326 break;
1327 else if (canbhot(res)) {
1328 /* check for hot keys: */
1329 int tmp = get_next_hot(res);
1330 if (tmp != -1)
1331 center_item(tmp, &last_top_row);
1332 }
1333 refresh_all_windows(main_window);
1334 }
1335 /* if ESC or left */
1336 if (res == 27 || res == KEY_LEFT)
1337 break;
1338
1339 child = item_data();
1340 if (!child || !menu_is_visible(child))
1341 continue;
1342 switch (res) {
1343 case ' ':
1344 case 10:
1345 case KEY_RIGHT:
1346 sym_set_tristate_value(child->sym, yes);
1347 return;
1348 case 'h':
1349 case '?':
1350 show_help(child);
1351 active = child->sym;
1352 break;
1353 case KEY_EXIT:
1354 return;
1355 }
1356 }
1357}
1358
1359static void conf_string(struct menu *menu)
1360{
1361 const char *prompt = menu_get_prompt(menu);
1362 char dialog_input_result[256];
1363
1364 while (1) {
1365 int res;
1366 const char *heading;
1367
1368 switch (sym_get_type(menu->sym)) {
1369 case S_INT:
1370 heading = _(inputbox_instructions_int);
1371 break;
1372 case S_HEX:
1373 heading = _(inputbox_instructions_hex);
1374 break;
1375 case S_STRING:
1376 heading = _(inputbox_instructions_string);
1377 break;
1378 default:
1379 heading = _("Internal nconf error!");
1380 }
1381 res = dialog_inputbox(main_window,
1382 prompt ? _(prompt) : _("Main Menu"),
1383 heading,
1384 sym_get_string_value(menu->sym),
1385 dialog_input_result,
1386 sizeof(dialog_input_result));
1387 switch (res) {
1388 case 0:
1389 if (sym_set_string_value(menu->sym,
1390 dialog_input_result))
1391 return;
1392 btn_dialog(main_window,
1393 _("You have made an invalid entry."), 0);
1394 break;
1395 case 1:
1396 show_help(menu);
1397 break;
1398 case KEY_EXIT:
1399 return;
1400 }
1401 }
1402}
1403
1404static void conf_load(void)
1405{
1406 char dialog_input_result[256];
1407 while (1) {
1408 int res;
1409 res = dialog_inputbox(main_window,
1410 NULL, load_config_text,
1411 filename,
1412 dialog_input_result,
1413 sizeof(dialog_input_result));
1414 switch (res) {
1415 case 0:
1416 if (!dialog_input_result[0])
1417 return;
1418 if (!conf_read(dialog_input_result)) {
1419 set_config_filename(dialog_input_result);
1420 sym_set_change_count(1);
1421 return;
1422 }
1423 btn_dialog(main_window, _("File does not exist!"), 0);
1424 break;
1425 case 1:
1426 show_scroll_win(main_window,
1427 _("Load Alternate Configuration"),
1428 load_config_help);
1429 break;
1430 case KEY_EXIT:
1431 return;
1432 }
1433 }
1434}
1435
1436static void conf_save(void)
1437{
1438 char dialog_input_result[256];
1439 while (1) {
1440 int res;
1441 res = dialog_inputbox(main_window,
1442 NULL, save_config_text,
1443 filename,
1444 dialog_input_result,
1445 sizeof(dialog_input_result));
1446 switch (res) {
1447 case 0:
1448 if (!dialog_input_result[0])
1449 return;
1450 supress_stdout(0);
1451 res = conf_write(dialog_input_result);
1452 supress_stdout(1);
1453 if (!res) {
1454 char buf[1024];
1455 sprintf(buf, "%s %s",
1456 _("configuration file saved to: "),
1457 dialog_input_result);
1458 btn_dialog(main_window,
1459 buf, 1, "<OK>");
1460 set_config_filename(dialog_input_result);
1461 return;
1462 }
1463 btn_dialog(main_window, _("Can't create file! "
1464 "Probably a nonexistent directory."),
1465 1, "<OK>");
1466 break;
1467 case 1:
1468 show_scroll_win(main_window,
1469 _("Save Alternate Configuration"),
1470 save_config_help);
1471 break;
1472 case KEY_EXIT:
1473 return;
1474 }
1475 }
1476}
1477
1478void setup_windows(void)
1479{
1480 if (main_window != NULL)
1481 delwin(main_window);
1482
1483 /* set up the menu and menu window */
1484 main_window = newwin(LINES-2, COLS-2, 2, 1);
1485 keypad(main_window, TRUE);
1486 mwin_max_lines = LINES-6;
1487 mwin_max_cols = COLS-6;
1488
1489 /* panels order is from bottom to top */
1490 new_panel(main_window);
1491}
1492
1493int main(int ac, char **av)
1494{
1495 char *mode;
1496
1497 setlocale(LC_ALL, "");
1498 bindtextdomain(PACKAGE, LOCALEDIR);
1499 textdomain(PACKAGE);
1500
1501 conf_parse(av[1]);
1502 conf_read(NULL);
1503
1504 mode = getenv("NCONFIG_MODE");
1505 if (mode) {
1506 if (!strcasecmp(mode, "single_menu"))
1507 single_menu_mode = 1;
1508 }
1509
1510 /* Initialize curses */
1511 initscr();
1512 /* set color theme */
1513 set_colors();
1514
1515 cbreak();
1516 noecho();
1517 keypad(stdscr, TRUE);
1518 curs_set(0);
1519
1520 if (COLS < 75 || LINES < 20) {
1521 endwin();
1522 printf("Your terminal should have at "
1523 "least 20 lines and 75 columns\n");
1524 return 1;
1525 }
1526
1527 notimeout(stdscr, FALSE);
1528 ESCDELAY = 1;
1529
1530 /* set btns menu */
1531 curses_menu = new_menu(curses_menu_items);
1532 menu_opts_off(curses_menu, O_SHOWDESC);
1533 menu_opts_off(curses_menu, O_SHOWMATCH);
1534 menu_opts_on(curses_menu, O_ONEVALUE);
1535 menu_opts_on(curses_menu, O_NONCYCLIC);
1536 set_menu_mark(curses_menu, " ");
1537 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1538 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1539 set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1540
1541 set_config_filename(conf_get_configname());
1542 setup_windows();
1543
1544 /* check for KEY_FUNC(1) */
1545 if (has_key(KEY_F(1)) == FALSE) {
1546 show_scroll_win(main_window,
1547 _("Instructions"),
1548 _(menu_no_f_instructions));
1549 }
1550
1551
1552
1553 /* do the work */
1554 while (!global_exit) {
1555 conf(&rootmenu);
1556 if (!global_exit && do_exit() == 0)
1557 break;
1558 }
1559 /* ok, we are done */
1560 unpost_menu(curses_menu);
1561 free_menu(curses_menu);
1562 delwin(main_window);
1563 clear();
1564 refresh();
1565 endwin();
1566 return 0;
1567}
1568
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
new file mode 100644
index 000000000000..a9d9344e1365
--- /dev/null
+++ b/scripts/kconfig/nconf.gui.c
@@ -0,0 +1,617 @@
1/*
2 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Derived from menuconfig.
6 *
7 */
8#include "nconf.h"
9
10/* a list of all the different widgets we use */
11attributes_t attributes[ATTR_MAX+1] = {0};
12
13/* available colors:
14 COLOR_BLACK 0
15 COLOR_RED 1
16 COLOR_GREEN 2
17 COLOR_YELLOW 3
18 COLOR_BLUE 4
19 COLOR_MAGENTA 5
20 COLOR_CYAN 6
21 COLOR_WHITE 7
22 */
23static void set_normal_colors(void)
24{
25 init_pair(NORMAL, -1, -1);
26 init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
27
28 /* FORE is for the selected item */
29 init_pair(MAIN_MENU_FORE, -1, -1);
30 /* BACK for all the rest */
31 init_pair(MAIN_MENU_BACK, -1, -1);
32 init_pair(MAIN_MENU_GREY, -1, -1);
33 init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
34 init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
35
36 init_pair(SCROLLWIN_TEXT, -1, -1);
37 init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
38 init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
39
40 init_pair(DIALOG_TEXT, -1, -1);
41 init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
42 init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
43 init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
44
45 init_pair(INPUT_BOX, COLOR_YELLOW, -1);
46 init_pair(INPUT_HEADING, COLOR_GREEN, -1);
47 init_pair(INPUT_TEXT, -1, -1);
48 init_pair(INPUT_FIELD, -1, -1);
49
50 init_pair(FUNCTION_HIGHLIGHT, -1, -1);
51 init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
52}
53
54/* available attributes:
55 A_NORMAL Normal display (no highlight)
56 A_STANDOUT Best highlighting mode of the terminal.
57 A_UNDERLINE Underlining
58 A_REVERSE Reverse video
59 A_BLINK Blinking
60 A_DIM Half bright
61 A_BOLD Extra bright or bold
62 A_PROTECT Protected mode
63 A_INVIS Invisible or blank mode
64 A_ALTCHARSET Alternate character set
65 A_CHARTEXT Bit-mask to extract a character
66 COLOR_PAIR(n) Color-pair number n
67 */
68static void normal_color_theme(void)
69{
70 /* automatically add color... */
71#define mkattr(name, attr) do { \
72attributes[name] = attr | COLOR_PAIR(name); } while (0)
73 mkattr(NORMAL, NORMAL);
74 mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
75
76 mkattr(MAIN_MENU_FORE, A_REVERSE);
77 mkattr(MAIN_MENU_BACK, A_NORMAL);
78 mkattr(MAIN_MENU_GREY, A_NORMAL);
79 mkattr(MAIN_MENU_HEADING, A_BOLD);
80 mkattr(MAIN_MENU_BOX, A_NORMAL);
81
82 mkattr(SCROLLWIN_TEXT, A_NORMAL);
83 mkattr(SCROLLWIN_HEADING, A_BOLD);
84 mkattr(SCROLLWIN_BOX, A_BOLD);
85
86 mkattr(DIALOG_TEXT, A_BOLD);
87 mkattr(DIALOG_BOX, A_BOLD);
88 mkattr(DIALOG_MENU_FORE, A_STANDOUT);
89 mkattr(DIALOG_MENU_BACK, A_NORMAL);
90
91 mkattr(INPUT_BOX, A_NORMAL);
92 mkattr(INPUT_HEADING, A_BOLD);
93 mkattr(INPUT_TEXT, A_NORMAL);
94 mkattr(INPUT_FIELD, A_UNDERLINE);
95
96 mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
97 mkattr(FUNCTION_TEXT, A_REVERSE);
98}
99
100static void no_colors_theme(void)
101{
102 /* automatically add highlight, no color */
103#define mkattrn(name, attr) { attributes[name] = attr; }
104
105 mkattrn(NORMAL, NORMAL);
106 mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
107
108 mkattrn(MAIN_MENU_FORE, A_STANDOUT);
109 mkattrn(MAIN_MENU_BACK, A_NORMAL);
110 mkattrn(MAIN_MENU_GREY, A_NORMAL);
111 mkattrn(MAIN_MENU_HEADING, A_BOLD);
112 mkattrn(MAIN_MENU_BOX, A_NORMAL);
113
114 mkattrn(SCROLLWIN_TEXT, A_NORMAL);
115 mkattrn(SCROLLWIN_HEADING, A_BOLD);
116 mkattrn(SCROLLWIN_BOX, A_BOLD);
117
118 mkattrn(DIALOG_TEXT, A_NORMAL);
119 mkattrn(DIALOG_BOX, A_BOLD);
120 mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
121 mkattrn(DIALOG_MENU_BACK, A_NORMAL);
122
123 mkattrn(INPUT_BOX, A_BOLD);
124 mkattrn(INPUT_HEADING, A_BOLD);
125 mkattrn(INPUT_TEXT, A_NORMAL);
126 mkattrn(INPUT_FIELD, A_UNDERLINE);
127
128 mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
129 mkattrn(FUNCTION_TEXT, A_REVERSE);
130}
131
132void set_colors()
133{
134 start_color();
135 use_default_colors();
136 set_normal_colors();
137 if (has_colors()) {
138 normal_color_theme();
139 } else {
140 /* give deafults */
141 no_colors_theme();
142 }
143}
144
145
146/* this changes the windows attributes !!! */
147void print_in_middle(WINDOW *win,
148 int starty,
149 int startx,
150 int width,
151 const char *string,
152 chtype color)
153{ int length, x, y;
154 float temp;
155
156
157 if (win == NULL)
158 win = stdscr;
159 getyx(win, y, x);
160 if (startx != 0)
161 x = startx;
162 if (starty != 0)
163 y = starty;
164 if (width == 0)
165 width = 80;
166
167 length = strlen(string);
168 temp = (width - length) / 2;
169 x = startx + (int)temp;
170 wattrset(win, color);
171 mvwprintw(win, y, x, "%s", string);
172 refresh();
173}
174
175int get_line_no(const char *text)
176{
177 int i;
178 int total = 1;
179
180 if (!text)
181 return 0;
182
183 for (i = 0; text[i] != '\0'; i++)
184 if (text[i] == '\n')
185 total++;
186 return total;
187}
188
189const char *get_line(const char *text, int line_no)
190{
191 int i;
192 int lines = 0;
193
194 if (!text)
195 return 0;
196
197 for (i = 0; text[i] != '\0' && lines < line_no; i++)
198 if (text[i] == '\n')
199 lines++;
200 return text+i;
201}
202
203int get_line_length(const char *line)
204{
205 int res = 0;
206 while (*line != '\0' && *line != '\n') {
207 line++;
208 res++;
209 }
210 return res;
211}
212
213/* print all lines to the window. */
214void fill_window(WINDOW *win, const char *text)
215{
216 int x, y;
217 int total_lines = get_line_no(text);
218 int i;
219
220 getmaxyx(win, y, x);
221 /* do not go over end of line */
222 total_lines = min(total_lines, y);
223 for (i = 0; i < total_lines; i++) {
224 char tmp[x+10];
225 const char *line = get_line(text, i);
226 int len = get_line_length(line);
227 strncpy(tmp, line, min(len, x));
228 tmp[len] = '\0';
229 mvwprintw(win, i, 0, "%s", tmp);
230 }
231}
232
233/* get the message, and buttons.
234 * each button must be a char*
235 * return the selected button
236 *
237 * this dialog is used for 2 different things:
238 * 1) show a text box, no buttons.
239 * 2) show a dialog, with horizontal buttons
240 */
241int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
242{
243 va_list ap;
244 char *btn;
245 int btns_width = 0;
246 int msg_lines = 0;
247 int msg_width = 0;
248 int total_width;
249 int win_rows = 0;
250 WINDOW *win;
251 WINDOW *msg_win;
252 WINDOW *menu_win;
253 MENU *menu;
254 ITEM *btns[btn_num+1];
255 int i, x, y;
256 int res = -1;
257
258
259 va_start(ap, btn_num);
260 for (i = 0; i < btn_num; i++) {
261 btn = va_arg(ap, char *);
262 btns[i] = new_item(btn, "");
263 btns_width += strlen(btn)+1;
264 }
265 va_end(ap);
266 btns[btn_num] = NULL;
267
268 /* find the widest line of msg: */
269 msg_lines = get_line_no(msg);
270 for (i = 0; i < msg_lines; i++) {
271 const char *line = get_line(msg, i);
272 int len = get_line_length(line);
273 if (msg_width < len)
274 msg_width = len;
275 }
276
277 total_width = max(msg_width, btns_width);
278 /* place dialog in middle of screen */
279 y = (LINES-(msg_lines+4))/2;
280 x = (COLS-(total_width+4))/2;
281
282
283 /* create the windows */
284 if (btn_num > 0)
285 win_rows = msg_lines+4;
286 else
287 win_rows = msg_lines+2;
288
289 win = newwin(win_rows, total_width+4, y, x);
290 keypad(win, TRUE);
291 menu_win = derwin(win, 1, btns_width, win_rows-2,
292 1+(total_width+2-btns_width)/2);
293 menu = new_menu(btns);
294 msg_win = derwin(win, win_rows-2, msg_width, 1,
295 1+(total_width+2-msg_width)/2);
296
297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
299
300 wattrset(win, attributes[DIALOG_BOX]);
301 box(win, 0, 0);
302
303 /* print message */
304 wattrset(msg_win, attributes[DIALOG_TEXT]);
305 fill_window(msg_win, msg);
306
307 set_menu_win(menu, win);
308 set_menu_sub(menu, menu_win);
309 set_menu_format(menu, 1, btn_num);
310 menu_opts_off(menu, O_SHOWDESC);
311 menu_opts_off(menu, O_SHOWMATCH);
312 menu_opts_on(menu, O_ONEVALUE);
313 menu_opts_on(menu, O_NONCYCLIC);
314 set_menu_mark(menu, "");
315 post_menu(menu);
316
317
318 touchwin(win);
319 refresh_all_windows(main_window);
320 while ((res = wgetch(win))) {
321 switch (res) {
322 case KEY_LEFT:
323 menu_driver(menu, REQ_LEFT_ITEM);
324 break;
325 case KEY_RIGHT:
326 menu_driver(menu, REQ_RIGHT_ITEM);
327 break;
328 case 10: /* ENTER */
329 case 27: /* ESCAPE */
330 case ' ':
331 case KEY_F(F_BACK):
332 case KEY_F(F_EXIT):
333 break;
334 }
335 touchwin(win);
336 refresh_all_windows(main_window);
337
338 if (res == 10 || res == ' ') {
339 res = item_index(current_item(menu));
340 break;
341 } else if (res == 27 || res == KEY_F(F_BACK) ||
342 res == KEY_F(F_EXIT)) {
343 res = KEY_EXIT;
344 break;
345 }
346 }
347
348 unpost_menu(menu);
349 free_menu(menu);
350 for (i = 0; i < btn_num; i++)
351 free_item(btns[i]);
352
353 delwin(win);
354 return res;
355}
356
357int dialog_inputbox(WINDOW *main_window,
358 const char *title, const char *prompt,
359 const char *init, char *result, int result_len)
360{
361 int prompt_lines = 0;
362 int prompt_width = 0;
363 WINDOW *win;
364 WINDOW *prompt_win;
365 WINDOW *form_win;
366 PANEL *panel;
367 int i, x, y;
368 int res = -1;
369 int cursor_position = strlen(init);
370
371
372 /* find the widest line of msg: */
373 prompt_lines = get_line_no(prompt);
374 for (i = 0; i < prompt_lines; i++) {
375 const char *line = get_line(prompt, i);
376 int len = get_line_length(line);
377 prompt_width = max(prompt_width, len);
378 }
379
380 if (title)
381 prompt_width = max(prompt_width, strlen(title));
382
383 /* place dialog in middle of screen */
384 y = (LINES-(prompt_lines+4))/2;
385 x = (COLS-(prompt_width+4))/2;
386
387 strncpy(result, init, result_len);
388
389 /* create the windows */
390 win = newwin(prompt_lines+6, prompt_width+7, y, x);
391 prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
393 keypad(form_win, TRUE);
394
395 wattrset(form_win, attributes[INPUT_FIELD]);
396
397 wattrset(win, attributes[INPUT_BOX]);
398 box(win, 0, 0);
399 wattrset(win, attributes[INPUT_HEADING]);
400 if (title)
401 mvwprintw(win, 0, 3, "%s", title);
402
403 /* print message */
404 wattrset(prompt_win, attributes[INPUT_TEXT]);
405 fill_window(prompt_win, prompt);
406
407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
408 mvwprintw(form_win, 0, 0, "%s", result);
409
410 /* create panels */
411 panel = new_panel(win);
412
413 /* show the cursor */
414 curs_set(1);
415
416 touchwin(win);
417 refresh_all_windows(main_window);
418 while ((res = wgetch(form_win))) {
419 int len = strlen(result);
420 switch (res) {
421 case 10: /* ENTER */
422 case 27: /* ESCAPE */
423 case KEY_F(F_HELP):
424 case KEY_F(F_EXIT):
425 case KEY_F(F_BACK):
426 break;
427 case 127:
428 case KEY_BACKSPACE:
429 if (cursor_position > 0) {
430 memmove(&result[cursor_position-1],
431 &result[cursor_position],
432 len-cursor_position+1);
433 cursor_position--;
434 }
435 break;
436 case KEY_DC:
437 if (cursor_position >= 0 && cursor_position < len) {
438 memmove(&result[cursor_position],
439 &result[cursor_position+1],
440 len-cursor_position+1);
441 }
442 break;
443 case KEY_UP:
444 case KEY_RIGHT:
445 if (cursor_position < len &&
446 cursor_position < min(result_len, prompt_width))
447 cursor_position++;
448 break;
449 case KEY_DOWN:
450 case KEY_LEFT:
451 if (cursor_position > 0)
452 cursor_position--;
453 break;
454 default:
455 if ((isgraph(res) || isspace(res)) &&
456 len-2 < result_len) {
457 /* insert the char at the proper position */
458 memmove(&result[cursor_position+1],
459 &result[cursor_position],
460 len+1);
461 result[cursor_position] = res;
462 cursor_position++;
463 } else {
464 mvprintw(0, 0, "unknow key: %d\n", res);
465 }
466 break;
467 }
468 wmove(form_win, 0, 0);
469 wclrtoeol(form_win);
470 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
471 mvwprintw(form_win, 0, 0, "%s", result);
472 wmove(form_win, 0, cursor_position);
473 touchwin(win);
474 refresh_all_windows(main_window);
475
476 if (res == 10) {
477 res = 0;
478 break;
479 } else if (res == 27 || res == KEY_F(F_BACK) ||
480 res == KEY_F(F_EXIT)) {
481 res = KEY_EXIT;
482 break;
483 } else if (res == KEY_F(F_HELP)) {
484 res = 1;
485 break;
486 }
487 }
488
489 /* hide the cursor */
490 curs_set(0);
491 del_panel(panel);
492 delwin(prompt_win);
493 delwin(form_win);
494 delwin(win);
495 return res;
496}
497
498/* refresh all windows in the correct order */
499void refresh_all_windows(WINDOW *main_window)
500{
501 update_panels();
502 touchwin(main_window);
503 refresh();
504}
505
506/* layman's scrollable window... */
507void show_scroll_win(WINDOW *main_window,
508 const char *title,
509 const char *text)
510{
511 int res;
512 int total_lines = get_line_no(text);
513 int x, y;
514 int start_x = 0, start_y = 0;
515 int text_lines = 0, text_cols = 0;
516 int total_cols = 0;
517 int win_cols = 0;
518 int win_lines = 0;
519 int i = 0;
520 WINDOW *win;
521 WINDOW *pad;
522 PANEL *panel;
523
524 /* find the widest line of msg: */
525 total_lines = get_line_no(text);
526 for (i = 0; i < total_lines; i++) {
527 const char *line = get_line(text, i);
528 int len = get_line_length(line);
529 total_cols = max(total_cols, len+2);
530 }
531
532 /* create the pad */
533 pad = newpad(total_lines+10, total_cols+10);
534 wattrset(pad, attributes[SCROLLWIN_TEXT]);
535 fill_window(pad, text);
536
537 win_lines = min(total_lines+4, LINES-2);
538 win_cols = min(total_cols+2, COLS-2);
539 text_lines = max(win_lines-4, 0);
540 text_cols = max(win_cols-2, 0);
541
542 /* place window in middle of screen */
543 y = (LINES-win_lines)/2;
544 x = (COLS-win_cols)/2;
545
546 win = newwin(win_lines, win_cols, y, x);
547 keypad(win, TRUE);
548 /* show the help in the help window, and show the help panel */
549 wattrset(win, attributes[SCROLLWIN_BOX]);
550 box(win, 0, 0);
551 wattrset(win, attributes[SCROLLWIN_HEADING]);
552 mvwprintw(win, 0, 3, " %s ", title);
553 panel = new_panel(win);
554
555 /* handle scrolling */
556 do {
557
558 copywin(pad, win, start_y, start_x, 2, 2, text_lines,
559 text_cols, 0);
560 print_in_middle(win,
561 text_lines+2,
562 0,
563 text_cols,
564 "<OK>",
565 attributes[DIALOG_MENU_FORE]);
566 wrefresh(win);
567
568 res = wgetch(win);
569 switch (res) {
570 case KEY_NPAGE:
571 case ' ':
572 start_y += text_lines-2;
573 break;
574 case KEY_PPAGE:
575 start_y -= text_lines+2;
576 break;
577 case KEY_HOME:
578 start_y = 0;
579 break;
580 case KEY_END:
581 start_y = total_lines-text_lines;
582 break;
583 case KEY_DOWN:
584 case 'j':
585 start_y++;
586 break;
587 case KEY_UP:
588 case 'k':
589 start_y--;
590 break;
591 case KEY_LEFT:
592 case 'h':
593 start_x--;
594 break;
595 case KEY_RIGHT:
596 case 'l':
597 start_x++;
598 break;
599 }
600 if (res == 10 || res == 27 || res == 'q'
601 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
602 break;
603 }
604 if (start_y < 0)
605 start_y = 0;
606 if (start_y >= total_lines-text_lines)
607 start_y = total_lines-text_lines;
608 if (start_x < 0)
609 start_x = 0;
610 if (start_x >= total_cols-text_cols)
611 start_x = total_cols-text_cols;
612 } while (res);
613
614 del_panel(panel);
615 delwin(win);
616 refresh_all_windows(main_window);
617}
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
new file mode 100644
index 000000000000..fb4296666004
--- /dev/null
+++ b/scripts/kconfig/nconf.h
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Derived from menuconfig.
6 *
7 */
8
9#include <ctype.h>
10#include <errno.h>
11#include <fcntl.h>
12#include <limits.h>
13#include <stdarg.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17#include <locale.h>
18#include <curses.h>
19#include <menu.h>
20#include <panel.h>
21#include <form.h>
22
23#include <stdio.h>
24#include <time.h>
25#include <sys/time.h>
26
27#include "ncurses.h"
28
29#define max(a, b) ({\
30 typeof(a) _a = a;\
31 typeof(b) _b = b;\
32 _a > _b ? _a : _b; })
33
34#define min(a, b) ({\
35 typeof(a) _a = a;\
36 typeof(b) _b = b;\
37 _a < _b ? _a : _b; })
38
39typedef enum {
40 NORMAL = 1,
41 MAIN_HEADING,
42 MAIN_MENU_BOX,
43 MAIN_MENU_FORE,
44 MAIN_MENU_BACK,
45 MAIN_MENU_GREY,
46 MAIN_MENU_HEADING,
47 SCROLLWIN_TEXT,
48 SCROLLWIN_HEADING,
49 SCROLLWIN_BOX,
50 DIALOG_TEXT,
51 DIALOG_MENU_FORE,
52 DIALOG_MENU_BACK,
53 DIALOG_BOX,
54 INPUT_BOX,
55 INPUT_HEADING,
56 INPUT_TEXT,
57 INPUT_FIELD,
58 FUNCTION_TEXT,
59 FUNCTION_HIGHLIGHT,
60 ATTR_MAX
61} attributes_t;
62extern attributes_t attributes[];
63
64typedef enum {
65 F_HELP = 1,
66 F_SYMBOL = 2,
67 F_INSTS = 3,
68 F_CONF = 4,
69 F_BACK = 5,
70 F_SAVE = 6,
71 F_LOAD = 7,
72 F_EXIT = 8
73} function_key;
74
75void set_colors(void);
76
77/* this changes the windows attributes !!! */
78void print_in_middle(WINDOW *win,
79 int starty,
80 int startx,
81 int width,
82 const char *string,
83 chtype color);
84int get_line_length(const char *line);
85int get_line_no(const char *text);
86const char *get_line(const char *text, int line_no);
87void fill_window(WINDOW *win, const char *text);
88int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
89int dialog_inputbox(WINDOW *main_window,
90 const char *title, const char *prompt,
91 const char *init, char *result, int result_len);
92void refresh_all_windows(WINDOW *main_window);
93void show_scroll_win(WINDOW *main_window,
94 const char *title,
95 const char *text);
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 00c51507cfcc..820df2d1217b 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58{ 58{
59 QValueList<int> result; 59 QValueList<int> result;
60 QStringList entryList = readListEntry(key, ok); 60 QStringList entryList = readListEntry(key, ok);
61 if (ok) { 61 QStringList::Iterator it;
62 QStringList::Iterator it; 62
63 for (it = entryList.begin(); it != entryList.end(); ++it) 63 for (it = entryList.begin(); it != entryList.end(); ++it)
64 result.push_back((*it).toInt()); 64 result.push_back((*it).toInt());
65 }
66 65
67 return result; 66 return result;
68} 67}
@@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void)
149 case S_TRISTATE: 148 case S_TRISTATE:
150 char ch; 149 char ch;
151 150
152 if (!sym_is_changable(sym) && !list->showAll) { 151 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
153 setPixmap(promptColIdx, 0); 152 setPixmap(promptColIdx, 0);
154 setText(noColIdx, QString::null); 153 setText(noColIdx, QString::null);
155 setText(modColIdx, QString::null); 154 setText(modColIdx, QString::null);
@@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
320 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), 319 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
321 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), 320 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
322 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), 321 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
323 showAll(false), showName(false), showRange(false), showData(false), 322 showName(false), showRange(false), showData(false), optMode(normalOpt),
324 rootEntry(0), headerPopup(0) 323 rootEntry(0), headerPopup(0)
325{ 324{
326 int i; 325 int i;
@@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
337 336
338 if (name) { 337 if (name) {
339 configSettings->beginGroup(name); 338 configSettings->beginGroup(name);
340 showAll = configSettings->readBoolEntry("/showAll", false);
341 showName = configSettings->readBoolEntry("/showName", false); 339 showName = configSettings->readBoolEntry("/showName", false);
342 showRange = configSettings->readBoolEntry("/showRange", false); 340 showRange = configSettings->readBoolEntry("/showRange", false);
343 showData = configSettings->readBoolEntry("/showData", false); 341 showData = configSettings->readBoolEntry("/showData", false);
342 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
344 configSettings->endGroup(); 343 configSettings->endGroup();
345 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); 344 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
346 } 345 }
@@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
352 reinit(); 351 reinit();
353} 352}
354 353
354bool ConfigList::menuSkip(struct menu *menu)
355{
356 if (optMode == normalOpt && menu_is_visible(menu))
357 return false;
358 if (optMode == promptOpt && menu_has_prompt(menu))
359 return false;
360 if (optMode == allOpt)
361 return false;
362 return true;
363}
364
355void ConfigList::reinit(void) 365void ConfigList::reinit(void)
356{ 366{
357 removeColumn(dataColIdx); 367 removeColumn(dataColIdx);
@@ -380,7 +390,7 @@ void ConfigList::saveSettings(void)
380 configSettings->writeEntry("/showName", showName); 390 configSettings->writeEntry("/showName", showName);
381 configSettings->writeEntry("/showRange", showRange); 391 configSettings->writeEntry("/showRange", showRange);
382 configSettings->writeEntry("/showData", showData); 392 configSettings->writeEntry("/showData", showData);
383 configSettings->writeEntry("/showAll", showAll); 393 configSettings->writeEntry("/optionMode", (int)optMode);
384 configSettings->endGroup(); 394 configSettings->endGroup();
385 } 395 }
386} 396}
@@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
606 } 616 }
607 617
608 visible = menu_is_visible(child); 618 visible = menu_is_visible(child);
609 if (showAll || visible) { 619 if (!menuSkip(child)) {
610 if (!child->sym && !child->list && !child->prompt) 620 if (!child->sym && !child->list && !child->prompt)
611 continue; 621 continue;
612 if (!item || item->menu != child) 622 if (!item || item->menu != child)
@@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
835 e->ignore(); 845 e->ignore();
836} 846}
837 847
838ConfigView* ConfigView::viewList; 848ConfigView*ConfigView::viewList;
849QAction *ConfigView::showNormalAction;
850QAction *ConfigView::showAllAction;
851QAction *ConfigView::showPromptAction;
839 852
840ConfigView::ConfigView(QWidget* parent, const char *name) 853ConfigView::ConfigView(QWidget* parent, const char *name)
841 : Parent(parent, name) 854 : Parent(parent, name)
@@ -860,13 +873,16 @@ ConfigView::~ConfigView(void)
860 } 873 }
861} 874}
862 875
863void ConfigView::setShowAll(bool b) 876void ConfigView::setOptionMode(QAction *act)
864{ 877{
865 if (list->showAll != b) { 878 if (act == showNormalAction)
866 list->showAll = b; 879 list->optMode = normalOpt;
867 list->updateListAll(); 880 else if (act == showAllAction)
868 emit showAllChanged(b); 881 list->optMode = allOpt;
869 } 882 else
883 list->optMode = promptOpt;
884
885 list->updateListAll();
870} 886}
871 887
872void ConfigView::setShowName(bool b) 888void ConfigView::setShowName(bool b)
@@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m)
964 menuInfo(); 980 menuInfo();
965} 981}
966 982
967void ConfigInfoView::setSource(const QString& name)
968{
969 const char *p = name.latin1();
970
971 menu = NULL;
972 sym = NULL;
973
974 switch (p[0]) {
975 case 'm':
976 struct menu *m;
977
978 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
979 menu = m;
980 menuInfo();
981 emit menuSelected(menu);
982 }
983 break;
984 case 's':
985 struct symbol *s;
986
987 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
988 sym = s;
989 symbolInfo();
990 }
991 break;
992 }
993}
994
995void ConfigInfoView::symbolInfo(void) 983void ConfigInfoView::symbolInfo(void)
996{ 984{
997 QString str; 985 QString str;
@@ -1349,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void)
1349 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); 1337 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1350 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); 1338 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1351 showDataAction->setOn(configList->showData); 1339 showDataAction->setOn(configList->showData);
1352 QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this); 1340
1353 showAllAction->setToggleAction(TRUE); 1341 QActionGroup *optGroup = new QActionGroup(this);
1354 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); 1342 optGroup->setExclusive(TRUE);
1355 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); 1343 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1356 showAllAction->setOn(configList->showAll); 1344 SLOT(setOptionMode(QAction *)));
1345 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1346 SLOT(setOptionMode(QAction *)));
1347
1348 configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup);
1349 configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup);
1350 configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup);
1351 configView->showNormalAction->setToggleAction(TRUE);
1352 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1353 configView->showAllAction->setToggleAction(TRUE);
1354 configView->showAllAction->setOn(configList->optMode == allOpt);
1355 configView->showPromptAction->setToggleAction(TRUE);
1356 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1357
1357 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); 1358 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1358 showDebugAction->setToggleAction(TRUE); 1359 showDebugAction->setToggleAction(TRUE);
1359 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); 1360 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
@@ -1396,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void)
1396 showRangeAction->addTo(optionMenu); 1397 showRangeAction->addTo(optionMenu);
1397 showDataAction->addTo(optionMenu); 1398 showDataAction->addTo(optionMenu);
1398 optionMenu->insertSeparator(); 1399 optionMenu->insertSeparator();
1399 showAllAction->addTo(optionMenu); 1400 optGroup->addTo(optionMenu);
1401 optionMenu->insertSeparator();
1400 showDebugAction->addTo(optionMenu); 1402 showDebugAction->addTo(optionMenu);
1401 1403
1402 // create help menu 1404 // create help menu
@@ -1491,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
1491 ConfigList* list = NULL; 1493 ConfigList* list = NULL;
1492 ConfigItem* item; 1494 ConfigItem* item;
1493 1495
1494 if (!menu_is_visible(menu) && !configView->showAll()) 1496 if (configList->menuSkip(menu))
1495 return; 1497 return;
1496 1498
1497 switch (configList->mode) { 1499 switch (configList->mode) {
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index b3b5657b6b35..636a74b23bf9 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -44,6 +44,9 @@ enum colIdx {
44enum listMode { 44enum listMode {
45 singleMode, menuMode, symbolMode, fullMode, listMode 45 singleMode, menuMode, symbolMode, fullMode, listMode
46}; 46};
47enum optionMode {
48 normalOpt = 0, allOpt, promptOpt
49};
47 50
48class ConfigList : public QListView { 51class ConfigList : public QListView {
49 Q_OBJECT 52 Q_OBJECT
@@ -115,6 +118,8 @@ public:
115 void setAllOpen(bool open); 118 void setAllOpen(bool open);
116 void setParentMenu(void); 119 void setParentMenu(void);
117 120
121 bool menuSkip(struct menu *);
122
118 template <class P> 123 template <class P>
119 void updateMenuList(P*, struct menu*); 124 void updateMenuList(P*, struct menu*);
120 125
@@ -124,8 +129,9 @@ public:
124 QPixmap choiceYesPix, choiceNoPix; 129 QPixmap choiceYesPix, choiceNoPix;
125 QPixmap menuPix, menuInvPix, menuBackPix, voidPix; 130 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
126 131
127 bool showAll, showName, showRange, showData; 132 bool showName, showRange, showData;
128 enum listMode mode; 133 enum listMode mode;
134 enum optionMode optMode;
129 struct menu *rootEntry; 135 struct menu *rootEntry;
130 QColorGroup disabledColorGroup; 136 QColorGroup disabledColorGroup;
131 QColorGroup inactivedColorGroup; 137 QColorGroup inactivedColorGroup;
@@ -222,17 +228,15 @@ public:
222 static void updateList(ConfigItem* item); 228 static void updateList(ConfigItem* item);
223 static void updateListAll(void); 229 static void updateListAll(void);
224 230
225 bool showAll(void) const { return list->showAll; }
226 bool showName(void) const { return list->showName; } 231 bool showName(void) const { return list->showName; }
227 bool showRange(void) const { return list->showRange; } 232 bool showRange(void) const { return list->showRange; }
228 bool showData(void) const { return list->showData; } 233 bool showData(void) const { return list->showData; }
229public slots: 234public slots:
230 void setShowAll(bool);
231 void setShowName(bool); 235 void setShowName(bool);
232 void setShowRange(bool); 236 void setShowRange(bool);
233 void setShowData(bool); 237 void setShowData(bool);
238 void setOptionMode(QAction *);
234signals: 239signals:
235 void showAllChanged(bool);
236 void showNameChanged(bool); 240 void showNameChanged(bool);
237 void showRangeChanged(bool); 241 void showRangeChanged(bool);
238 void showDataChanged(bool); 242 void showDataChanged(bool);
@@ -242,6 +246,10 @@ public:
242 246
243 static ConfigView* viewList; 247 static ConfigView* viewList;
244 ConfigView* nextView; 248 ConfigView* nextView;
249
250 static QAction *showNormalAction;
251 static QAction *showAllAction;
252 static QAction *showPromptAction;
245}; 253};
246 254
247class ConfigInfoView : public QTextBrowser { 255class ConfigInfoView : public QTextBrowser {
@@ -254,7 +262,6 @@ public:
254public slots: 262public slots:
255 void setInfo(struct menu *menu); 263 void setInfo(struct menu *menu);
256 void saveSettings(void); 264 void saveSettings(void);
257 void setSource(const QString& name);
258 void setShowDebug(bool); 265 void setShowDebug(bool);
259 266
260signals: 267signals:
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index afbd54ac1d83..c70a27d924f0 100644
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -115,7 +115,9 @@ my $ksource = $ARGV[0];
115my $kconfig = $ARGV[1]; 115my $kconfig = $ARGV[1];
116my $lsmod_file = $ARGV[2]; 116my $lsmod_file = $ARGV[2];
117 117
118my @makefiles = `find $ksource -name Makefile`; 118my @makefiles = `find $ksource -name Makefile 2>/dev/null`;
119chomp @makefiles;
120
119my %depends; 121my %depends;
120my %selects; 122my %selects;
121my %prompts; 123my %prompts;
@@ -215,7 +217,6 @@ if ($kconfig) {
215 217
216# Read all Makefiles to map the configs to the objects 218# Read all Makefiles to map the configs to the objects
217foreach my $makefile (@makefiles) { 219foreach my $makefile (@makefiles) {
218 chomp $makefile;
219 220
220 open(MIN,$makefile) || die "Can't open $makefile"; 221 open(MIN,$makefile) || die "Can't open $makefile";
221 while (<MIN>) { 222 while (<MIN>) {
@@ -242,7 +243,7 @@ foreach my $makefile (@makefiles) {
242 foreach my $obj (split /\s+/,$objs) { 243 foreach my $obj (split /\s+/,$objs) {
243 $obj =~ s/-/_/g; 244 $obj =~ s/-/_/g;
244 if ($obj =~ /(.*)\.o$/) { 245 if ($obj =~ /(.*)\.o$/) {
245 # Objects may bes enabled by more than one config. 246 # Objects may be enabled by more than one config.
246 # Store configs in an array. 247 # Store configs in an array.
247 my @arr; 248 my @arr;
248 249
@@ -307,7 +308,7 @@ close (LIN);
307my %configs; 308my %configs;
308foreach my $module (keys(%modules)) { 309foreach my $module (keys(%modules)) {
309 if (defined($objects{$module})) { 310 if (defined($objects{$module})) {
310 @arr = @{$objects{$module}}; 311 my @arr = @{$objects{$module}};
311 foreach my $conf (@arr) { 312 foreach my $conf (@arr) {
312 $configs{$conf} = $module; 313 $configs{$conf} = $module;
313 } 314 }
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 6c8fbbb66ebc..e95718fea355 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym)
205 } 205 }
206 if (sym_is_choice_value(sym)) 206 if (sym_is_choice_value(sym))
207 return; 207 return;
208 /* defaulting to "yes" if no explicit "depends on" are given */
209 tri = yes;
210 if (sym->dir_dep.expr)
211 tri = expr_calc_value(sym->dir_dep.expr);
212 if (tri == mod)
213 tri = yes;
214 if (sym->dir_dep.tri != tri) {
215 sym->dir_dep.tri = tri;
216 sym_set_changed(sym);
217 }
208 tri = no; 218 tri = no;
209 if (sym->rev_dep.expr) 219 if (sym->rev_dep.expr)
210 tri = expr_calc_value(sym->rev_dep.expr); 220 tri = expr_calc_value(sym->rev_dep.expr);
@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym)
216 } 226 }
217} 227}
218 228
219static struct symbol *sym_calc_choice(struct symbol *sym) 229/*
230 * Find the default symbol for a choice.
231 * First try the default values for the choice symbol
232 * Next locate the first visible choice value
233 * Return NULL if none was found
234 */
235struct symbol *sym_choice_default(struct symbol *sym)
220{ 236{
221 struct symbol *def_sym; 237 struct symbol *def_sym;
222 struct property *prop; 238 struct property *prop;
223 struct expr *e; 239 struct expr *e;
224 240
225 /* is the user choice visible? */
226 def_sym = sym->def[S_DEF_USER].val;
227 if (def_sym) {
228 sym_calc_visibility(def_sym);
229 if (def_sym->visible != no)
230 return def_sym;
231 }
232
233 /* any of the defaults visible? */ 241 /* any of the defaults visible? */
234 for_all_defaults(sym, prop) { 242 for_all_defaults(sym, prop) {
235 prop->visible.tri = expr_calc_value(prop->visible.expr); 243 prop->visible.tri = expr_calc_value(prop->visible.expr);
236 if (prop->visible.tri == no) 244 if (prop->visible.tri == no)
237 continue; 245 continue;
238 def_sym = prop_get_symbol(prop); 246 def_sym = prop_get_symbol(prop);
239 sym_calc_visibility(def_sym);
240 if (def_sym->visible != no) 247 if (def_sym->visible != no)
241 return def_sym; 248 return def_sym;
242 } 249 }
243 250
244 /* just get the first visible value */ 251 /* just get the first visible value */
245 prop = sym_get_choice_prop(sym); 252 prop = sym_get_choice_prop(sym);
246 expr_list_for_each_sym(prop->expr, e, def_sym) { 253 expr_list_for_each_sym(prop->expr, e, def_sym)
247 sym_calc_visibility(def_sym);
248 if (def_sym->visible != no) 254 if (def_sym->visible != no)
249 return def_sym; 255 return def_sym;
250 }
251 256
252 /* no choice? reset tristate value */ 257 /* failed to locate any defaults */
253 sym->curr.tri = no;
254 return NULL; 258 return NULL;
255} 259}
256 260
261static struct symbol *sym_calc_choice(struct symbol *sym)
262{
263 struct symbol *def_sym;
264 struct property *prop;
265 struct expr *e;
266
267 /* first calculate all choice values' visibilities */
268 prop = sym_get_choice_prop(sym);
269 expr_list_for_each_sym(prop->expr, e, def_sym)
270 sym_calc_visibility(def_sym);
271
272 /* is the user choice visible? */
273 def_sym = sym->def[S_DEF_USER].val;
274 if (def_sym && def_sym->visible != no)
275 return def_sym;
276
277 def_sym = sym_choice_default(sym);
278
279 if (def_sym == NULL)
280 /* no choice? reset tristate value */
281 sym->curr.tri = no;
282
283 return def_sym;
284}
285
257void sym_calc_value(struct symbol *sym) 286void sym_calc_value(struct symbol *sym)
258{ 287{
259 struct symbol_value newval, oldval; 288 struct symbol_value newval, oldval;
@@ -321,6 +350,14 @@ void sym_calc_value(struct symbol *sym)
321 } 350 }
322 } 351 }
323 calc_newval: 352 calc_newval:
353 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
354 fprintf(stderr, "warning: (");
355 expr_fprint(sym->rev_dep.expr, stderr);
356 fprintf(stderr, ") selects %s which has unmet direct dependencies (",
357 sym->name);
358 expr_fprint(sym->dir_dep.expr, stderr);
359 fprintf(stderr, ")\n");
360 }
324 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); 361 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
325 } 362 }
326 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) 363 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
@@ -365,12 +402,13 @@ void sym_calc_value(struct symbol *sym)
365 402
366 if (sym_is_choice(sym)) { 403 if (sym_is_choice(sym)) {
367 struct symbol *choice_sym; 404 struct symbol *choice_sym;
368 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
369 405
370 prop = sym_get_choice_prop(sym); 406 prop = sym_get_choice_prop(sym);
371 expr_list_for_each_sym(prop->expr, e, choice_sym) { 407 expr_list_for_each_sym(prop->expr, e, choice_sym) {
372 choice_sym->flags |= flags; 408 if ((sym->flags & SYMBOL_WRITE) &&
373 if (flags & SYMBOL_CHANGED) 409 choice_sym->visible != no)
410 choice_sym->flags |= SYMBOL_WRITE;
411 if (sym->flags & SYMBOL_CHANGED)
374 sym_set_changed(choice_sym); 412 sym_set_changed(choice_sym);
375 } 413 }
376 } 414 }
@@ -623,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
623 return true; 661 return true;
624} 662}
625 663
664/*
665 * Find the default value associated to a symbol.
666 * For tristate symbol handle the modules=n case
667 * in which case "m" becomes "y".
668 * If the symbol does not have any default then fallback
669 * to the fixed default values.
670 */
671const char *sym_get_string_default(struct symbol *sym)
672{
673 struct property *prop;
674 struct symbol *ds;
675 const char *str;
676 tristate val;
677
678 sym_calc_visibility(sym);
679 sym_calc_value(modules_sym);
680 val = symbol_no.curr.tri;
681 str = symbol_empty.curr.val;
682
683 /* If symbol has a default value look it up */
684 prop = sym_get_default_prop(sym);
685 if (prop != NULL) {
686 switch (sym->type) {
687 case S_BOOLEAN:
688 case S_TRISTATE:
689 /* The visibility imay limit the value from yes => mod */
690 val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
691 break;
692 default:
693 /*
694 * The following fails to handle the situation
695 * where a default value is further limited by
696 * the valid range.
697 */
698 ds = prop_get_symbol(prop);
699 if (ds != NULL) {
700 sym_calc_value(ds);
701 str = (const char *)ds->curr.val;
702 }
703 }
704 }
705
706 /* Handle select statements */
707 val = EXPR_OR(val, sym->rev_dep.tri);
708
709 /* transpose mod to yes if modules are not enabled */
710 if (val == mod)
711 if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
712 val = yes;
713
714 /* transpose mod to yes if type is bool */
715 if (sym->type == S_BOOLEAN && val == mod)
716 val = yes;
717
718 switch (sym->type) {
719 case S_BOOLEAN:
720 case S_TRISTATE:
721 switch (val) {
722 case no: return "n";
723 case mod: return "m";
724 case yes: return "y";
725 }
726 case S_INT:
727 case S_HEX:
728 return str;
729 case S_STRING:
730 return str;
731 case S_OTHER:
732 case S_UNKNOWN:
733 break;
734 }
735 return "";
736}
737
626const char *sym_get_string_value(struct symbol *sym) 738const char *sym_get_string_value(struct symbol *sym)
627{ 739{
628 tristate val; 740 tristate val;
@@ -651,12 +763,20 @@ bool sym_is_changable(struct symbol *sym)
651 return sym->visible > sym->rev_dep.tri; 763 return sym->visible > sym->rev_dep.tri;
652} 764}
653 765
766static unsigned strhash(const char *s)
767{
768 /* fnv32 hash */
769 unsigned hash = 2166136261U;
770 for (; *s; s++)
771 hash = (hash ^ *s) * 0x01000193;
772 return hash;
773}
774
654struct symbol *sym_lookup(const char *name, int flags) 775struct symbol *sym_lookup(const char *name, int flags)
655{ 776{
656 struct symbol *symbol; 777 struct symbol *symbol;
657 const char *ptr;
658 char *new_name; 778 char *new_name;
659 int hash = 0; 779 int hash;
660 780
661 if (name) { 781 if (name) {
662 if (name[0] && !name[1]) { 782 if (name[0] && !name[1]) {
@@ -666,12 +786,11 @@ struct symbol *sym_lookup(const char *name, int flags)
666 case 'n': return &symbol_no; 786 case 'n': return &symbol_no;
667 } 787 }
668 } 788 }
669 for (ptr = name; *ptr; ptr++) 789 hash = strhash(name) % SYMBOL_HASHSIZE;
670 hash += *ptr;
671 hash &= 0xff;
672 790
673 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 791 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
674 if (!strcmp(symbol->name, name) && 792 if (symbol->name &&
793 !strcmp(symbol->name, name) &&
675 (flags ? symbol->flags & flags 794 (flags ? symbol->flags & flags
676 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) 795 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
677 return symbol; 796 return symbol;
@@ -679,7 +798,7 @@ struct symbol *sym_lookup(const char *name, int flags)
679 new_name = strdup(name); 798 new_name = strdup(name);
680 } else { 799 } else {
681 new_name = NULL; 800 new_name = NULL;
682 hash = 256; 801 hash = 0;
683 } 802 }
684 803
685 symbol = malloc(sizeof(*symbol)); 804 symbol = malloc(sizeof(*symbol));
@@ -697,7 +816,6 @@ struct symbol *sym_lookup(const char *name, int flags)
697struct symbol *sym_find(const char *name) 816struct symbol *sym_find(const char *name)
698{ 817{
699 struct symbol *symbol = NULL; 818 struct symbol *symbol = NULL;
700 const char *ptr;
701 int hash = 0; 819 int hash = 0;
702 820
703 if (!name) 821 if (!name)
@@ -710,12 +828,11 @@ struct symbol *sym_find(const char *name)
710 case 'n': return &symbol_no; 828 case 'n': return &symbol_no;
711 } 829 }
712 } 830 }
713 for (ptr = name; *ptr; ptr++) 831 hash = strhash(name) % SYMBOL_HASHSIZE;
714 hash += *ptr;
715 hash &= 0xff;
716 832
717 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 833 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
718 if (!strcmp(symbol->name, name) && 834 if (symbol->name &&
835 !strcmp(symbol->name, name) &&
719 !(symbol->flags & SYMBOL_CONST)) 836 !(symbol->flags & SYMBOL_CONST))
720 break; 837 break;
721 } 838 }
@@ -750,6 +867,7 @@ struct symbol **sym_re_search(const char *pattern)
750 return NULL; 867 return NULL;
751 } 868 }
752 } 869 }
870 sym_calc_value(sym);
753 sym_arr[cnt++] = sym; 871 sym_arr[cnt++] = sym;
754 } 872 }
755 if (sym_arr) 873 if (sym_arr)
@@ -759,6 +877,110 @@ struct symbol **sym_re_search(const char *pattern)
759 return sym_arr; 877 return sym_arr;
760} 878}
761 879
880/*
881 * When we check for recursive dependencies we use a stack to save
882 * current state so we can print out relevant info to user.
883 * The entries are located on the call stack so no need to free memory.
884 * Note inser() remove() must always match to properly clear the stack.
885 */
886static struct dep_stack {
887 struct dep_stack *prev, *next;
888 struct symbol *sym;
889 struct property *prop;
890 struct expr *expr;
891} *check_top;
892
893static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
894{
895 memset(stack, 0, sizeof(*stack));
896 if (check_top)
897 check_top->next = stack;
898 stack->prev = check_top;
899 stack->sym = sym;
900 check_top = stack;
901}
902
903static void dep_stack_remove(void)
904{
905 check_top = check_top->prev;
906 if (check_top)
907 check_top->next = NULL;
908}
909
910/*
911 * Called when we have detected a recursive dependency.
912 * check_top point to the top of the stact so we use
913 * the ->prev pointer to locate the bottom of the stack.
914 */
915static void sym_check_print_recursive(struct symbol *last_sym)
916{
917 struct dep_stack *stack;
918 struct symbol *sym, *next_sym;
919 struct menu *menu = NULL;
920 struct property *prop;
921 struct dep_stack cv_stack;
922
923 if (sym_is_choice_value(last_sym)) {
924 dep_stack_insert(&cv_stack, last_sym);
925 last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
926 }
927
928 for (stack = check_top; stack != NULL; stack = stack->prev)
929 if (stack->sym == last_sym)
930 break;
931 if (!stack) {
932 fprintf(stderr, "unexpected recursive dependency error\n");
933 return;
934 }
935
936 for (; stack; stack = stack->next) {
937 sym = stack->sym;
938 next_sym = stack->next ? stack->next->sym : last_sym;
939 prop = stack->prop;
940
941 /* for choice values find the menu entry (used below) */
942 if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
943 for (prop = sym->prop; prop; prop = prop->next) {
944 menu = prop->menu;
945 if (prop->menu)
946 break;
947 }
948 }
949 if (stack->sym == last_sym)
950 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
951 prop->file->name, prop->lineno);
952 if (stack->expr) {
953 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
954 prop->file->name, prop->lineno,
955 sym->name ? sym->name : "<choice>",
956 prop_get_type_name(prop->type),
957 next_sym->name ? next_sym->name : "<choice>");
958 } else if (stack->prop) {
959 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
960 prop->file->name, prop->lineno,
961 sym->name ? sym->name : "<choice>",
962 next_sym->name ? next_sym->name : "<choice>");
963 } else if (sym_is_choice(sym)) {
964 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
965 menu->file->name, menu->lineno,
966 sym->name ? sym->name : "<choice>",
967 next_sym->name ? next_sym->name : "<choice>");
968 } else if (sym_is_choice_value(sym)) {
969 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
970 menu->file->name, menu->lineno,
971 sym->name ? sym->name : "<choice>",
972 next_sym->name ? next_sym->name : "<choice>");
973 } else {
974 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
975 prop->file->name, prop->lineno,
976 sym->name ? sym->name : "<choice>",
977 next_sym->name ? next_sym->name : "<choice>");
978 }
979 }
980
981 if (check_top == &cv_stack)
982 dep_stack_remove();
983}
762 984
763static struct symbol *sym_check_expr_deps(struct expr *e) 985static struct symbol *sym_check_expr_deps(struct expr *e)
764{ 986{
@@ -795,24 +1017,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
795{ 1017{
796 struct symbol *sym2; 1018 struct symbol *sym2;
797 struct property *prop; 1019 struct property *prop;
1020 struct dep_stack stack;
1021
1022 dep_stack_insert(&stack, sym);
798 1023
799 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 1024 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
800 if (sym2) 1025 if (sym2)
801 return sym2; 1026 goto out;
802 1027
803 for (prop = sym->prop; prop; prop = prop->next) { 1028 for (prop = sym->prop; prop; prop = prop->next) {
804 if (prop->type == P_CHOICE || prop->type == P_SELECT) 1029 if (prop->type == P_CHOICE || prop->type == P_SELECT)
805 continue; 1030 continue;
1031 stack.prop = prop;
806 sym2 = sym_check_expr_deps(prop->visible.expr); 1032 sym2 = sym_check_expr_deps(prop->visible.expr);
807 if (sym2) 1033 if (sym2)
808 break; 1034 break;
809 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 1035 if (prop->type != P_DEFAULT || sym_is_choice(sym))
810 continue; 1036 continue;
1037 stack.expr = prop->expr;
811 sym2 = sym_check_expr_deps(prop->expr); 1038 sym2 = sym_check_expr_deps(prop->expr);
812 if (sym2) 1039 if (sym2)
813 break; 1040 break;
1041 stack.expr = NULL;
814 } 1042 }
815 1043
1044out:
1045 dep_stack_remove();
1046
816 return sym2; 1047 return sym2;
817} 1048}
818 1049
@@ -821,6 +1052,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
821 struct symbol *sym, *sym2; 1052 struct symbol *sym, *sym2;
822 struct property *prop; 1053 struct property *prop;
823 struct expr *e; 1054 struct expr *e;
1055 struct dep_stack stack;
1056
1057 dep_stack_insert(&stack, choice);
824 1058
825 prop = sym_get_choice_prop(choice); 1059 prop = sym_get_choice_prop(choice);
826 expr_list_for_each_sym(prop->expr, e, sym) 1060 expr_list_for_each_sym(prop->expr, e, sym)
@@ -834,10 +1068,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
834 1068
835 expr_list_for_each_sym(prop->expr, e, sym) { 1069 expr_list_for_each_sym(prop->expr, e, sym) {
836 sym2 = sym_check_sym_deps(sym); 1070 sym2 = sym_check_sym_deps(sym);
837 if (sym2) { 1071 if (sym2)
838 fprintf(stderr, " -> %s", sym->name);
839 break; 1072 break;
840 }
841 } 1073 }
842out: 1074out:
843 expr_list_for_each_sym(prop->expr, e, sym) 1075 expr_list_for_each_sym(prop->expr, e, sym)
@@ -847,6 +1079,8 @@ out:
847 prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 1079 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
848 sym2 = choice; 1080 sym2 = choice;
849 1081
1082 dep_stack_remove();
1083
850 return sym2; 1084 return sym2;
851} 1085}
852 1086
@@ -856,18 +1090,20 @@ struct symbol *sym_check_deps(struct symbol *sym)
856 struct property *prop; 1090 struct property *prop;
857 1091
858 if (sym->flags & SYMBOL_CHECK) { 1092 if (sym->flags & SYMBOL_CHECK) {
859 fprintf(stderr, "%s:%d:error: found recursive dependency: %s", 1093 sym_check_print_recursive(sym);
860 sym->prop->file->name, sym->prop->lineno,
861 sym->name ? sym->name : "<choice>");
862 return sym; 1094 return sym;
863 } 1095 }
864 if (sym->flags & SYMBOL_CHECKED) 1096 if (sym->flags & SYMBOL_CHECKED)
865 return NULL; 1097 return NULL;
866 1098
867 if (sym_is_choice_value(sym)) { 1099 if (sym_is_choice_value(sym)) {
1100 struct dep_stack stack;
1101
868 /* for choice groups start the check with main choice symbol */ 1102 /* for choice groups start the check with main choice symbol */
1103 dep_stack_insert(&stack, sym);
869 prop = sym_get_choice_prop(sym); 1104 prop = sym_get_choice_prop(sym);
870 sym2 = sym_check_deps(prop_get_symbol(prop)); 1105 sym2 = sym_check_deps(prop_get_symbol(prop));
1106 dep_stack_remove();
871 } else if (sym_is_choice(sym)) { 1107 } else if (sym_is_choice(sym)) {
872 sym2 = sym_check_choice_deps(sym); 1108 sym2 = sym_check_choice_deps(sym);
873 } else { 1109 } else {
@@ -876,14 +1112,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
876 sym->flags &= ~SYMBOL_CHECK; 1112 sym->flags &= ~SYMBOL_CHECK;
877 } 1113 }
878 1114
879 if (sym2) { 1115 if (sym2 && sym2 == sym)
880 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); 1116 sym2 = NULL;
881 if (sym2 == sym) {
882 fprintf(stderr, "\n");
883 zconfnerrs++;
884 sym2 = NULL;
885 }
886 }
887 1117
888 return sym2; 1118 return sym2;
889} 1119}
@@ -937,6 +1167,8 @@ const char *prop_get_type_name(enum prop_type type)
937 return "select"; 1167 return "select";
938 case P_RANGE: 1168 case P_RANGE:
939 return "range"; 1169 return "range";
1170 case P_SYMBOL:
1171 return "symbol";
940 case P_UNKNOWN: 1172 case P_UNKNOWN:
941 break; 1173 break;
942 } 1174 }
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index b6b2a46af14c..78b5c04e736b 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -72,12 +72,13 @@ int file_write_dep(const char *name)
72} 72}
73 73
74 74
75/* Allocate initial growable sting */ 75/* Allocate initial growable string */
76struct gstr str_new(void) 76struct gstr str_new(void)
77{ 77{
78 struct gstr gs; 78 struct gstr gs;
79 gs.s = malloc(sizeof(char) * 64); 79 gs.s = malloc(sizeof(char) * 64);
80 gs.len = 64; 80 gs.len = 64;
81 gs.max_width = 0;
81 strcpy(gs.s, "\0"); 82 strcpy(gs.s, "\0");
82 return gs; 83 return gs;
83} 84}
@@ -88,6 +89,7 @@ struct gstr str_assign(const char *s)
88 struct gstr gs; 89 struct gstr gs;
89 gs.s = strdup(s); 90 gs.s = strdup(s);
90 gs.len = strlen(s) + 1; 91 gs.len = strlen(s) + 1;
92 gs.max_width = 0;
91 return gs; 93 return gs;
92} 94}
93 95
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 6e9dcd59aa87..32a9eefd842c 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -104,7 +104,7 @@ static void zconf_error(const char *err, ...);
104static void zconferror(const char *err); 104static void zconferror(const char *err);
105static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); 105static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
106 106
107struct symbol *symbol_hash[257]; 107struct symbol *symbol_hash[SYMBOL_HASHSIZE];
108 108
109static struct menu *current_menu, *current_entry; 109static struct menu *current_menu, *current_entry;
110 110
@@ -2220,7 +2220,7 @@ void conf_parse(const char *name)
2220 zconf_initscan(name); 2220 zconf_initscan(name);
2221 2221
2222 sym_init(); 2222 sym_init();
2223 menu_init(); 2223 _menu_init();
2224 modules_sym = sym_lookup(NULL, 0); 2224 modules_sym = sym_lookup(NULL, 0);
2225 modules_sym->type = S_BOOLEAN; 2225 modules_sym->type = S_BOOLEAN;
2226 modules_sym->flags |= SYMBOL_AUTO; 2226 modules_sym->flags |= SYMBOL_AUTO;
@@ -2336,9 +2336,9 @@ static void print_symbol(FILE *out, struct menu *menu)
2336 struct property *prop; 2336 struct property *prop;
2337 2337
2338 if (sym_is_choice(sym)) 2338 if (sym_is_choice(sym))
2339 fprintf(out, "choice\n"); 2339 fprintf(out, "\nchoice\n");
2340 else 2340 else
2341 fprintf(out, "config %s\n", sym->name); 2341 fprintf(out, "\nconfig %s\n", sym->name);
2342 switch (sym->type) { 2342 switch (sym->type) {
2343 case S_BOOLEAN: 2343 case S_BOOLEAN:
2344 fputs(" boolean\n", out); 2344 fputs(" boolean\n", out);
@@ -2384,6 +2384,21 @@ static void print_symbol(FILE *out, struct menu *menu)
2384 case P_CHOICE: 2384 case P_CHOICE:
2385 fputs(" #choice value\n", out); 2385 fputs(" #choice value\n", out);
2386 break; 2386 break;
2387 case P_SELECT:
2388 fputs( " select ", out);
2389 expr_fprint(prop->expr, out);
2390 fputc('\n', out);
2391 break;
2392 case P_RANGE:
2393 fputs( " range ", out);
2394 expr_fprint(prop->expr, out);
2395 fputc('\n', out);
2396 break;
2397 case P_MENU:
2398 fputs( " menu ", out);
2399 print_quoted_string(out, prop->text);
2400 fputc('\n', out);
2401 break;
2387 default: 2402 default:
2388 fprintf(out, " unknown prop %d!\n", prop->type); 2403 fprintf(out, " unknown prop %d!\n", prop->type);
2389 break; 2404 break;
@@ -2395,7 +2410,6 @@ static void print_symbol(FILE *out, struct menu *menu)
2395 menu->help[len] = 0; 2410 menu->help[len] = 0;
2396 fprintf(out, " help\n%s\n", menu->help); 2411 fprintf(out, " help\n%s\n", menu->help);
2397 } 2412 }
2398 fputc('\n', out);
2399} 2413}
2400 2414
2401void zconfdump(FILE *out) 2415void zconfdump(FILE *out)
@@ -2428,7 +2442,6 @@ void zconfdump(FILE *out)
2428 expr_fprint(prop->visible.expr, out); 2442 expr_fprint(prop->visible.expr, out);
2429 fputc('\n', out); 2443 fputc('\n', out);
2430 } 2444 }
2431 fputs("\n", out);
2432 } 2445 }
2433 2446
2434 if (menu->list) 2447 if (menu->list)
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 8c43491f8cc9..23dfd3baa7a1 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -27,7 +27,7 @@ static void zconf_error(const char *err, ...);
27static void zconferror(const char *err); 27static void zconferror(const char *err);
28static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); 28static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
29 29
30struct symbol *symbol_hash[257]; 30struct symbol *symbol_hash[SYMBOL_HASHSIZE];
31 31
32static struct menu *current_menu, *current_entry; 32static struct menu *current_menu, *current_entry;
33 33
@@ -475,7 +475,7 @@ void conf_parse(const char *name)
475 zconf_initscan(name); 475 zconf_initscan(name);
476 476
477 sym_init(); 477 sym_init();
478 menu_init(); 478 _menu_init();
479 modules_sym = sym_lookup(NULL, 0); 479 modules_sym = sym_lookup(NULL, 0);
480 modules_sym->type = S_BOOLEAN; 480 modules_sym->type = S_BOOLEAN;
481 modules_sym->flags |= SYMBOL_AUTO; 481 modules_sym->flags |= SYMBOL_AUTO;
@@ -591,9 +591,9 @@ static void print_symbol(FILE *out, struct menu *menu)
591 struct property *prop; 591 struct property *prop;
592 592
593 if (sym_is_choice(sym)) 593 if (sym_is_choice(sym))
594 fprintf(out, "choice\n"); 594 fprintf(out, "\nchoice\n");
595 else 595 else
596 fprintf(out, "config %s\n", sym->name); 596 fprintf(out, "\nconfig %s\n", sym->name);
597 switch (sym->type) { 597 switch (sym->type) {
598 case S_BOOLEAN: 598 case S_BOOLEAN:
599 fputs(" boolean\n", out); 599 fputs(" boolean\n", out);
@@ -639,6 +639,21 @@ static void print_symbol(FILE *out, struct menu *menu)
639 case P_CHOICE: 639 case P_CHOICE:
640 fputs(" #choice value\n", out); 640 fputs(" #choice value\n", out);
641 break; 641 break;
642 case P_SELECT:
643 fputs( " select ", out);
644 expr_fprint(prop->expr, out);
645 fputc('\n', out);
646 break;
647 case P_RANGE:
648 fputs( " range ", out);
649 expr_fprint(prop->expr, out);
650 fputc('\n', out);
651 break;
652 case P_MENU:
653 fputs( " menu ", out);
654 print_quoted_string(out, prop->text);
655 fputc('\n', out);
656 break;
642 default: 657 default:
643 fprintf(out, " unknown prop %d!\n", prop->type); 658 fprintf(out, " unknown prop %d!\n", prop->type);
644 break; 659 break;
@@ -650,7 +665,6 @@ static void print_symbol(FILE *out, struct menu *menu)
650 menu->help[len] = 0; 665 menu->help[len] = 0;
651 fprintf(out, " help\n%s\n", menu->help); 666 fprintf(out, " help\n%s\n", menu->help);
652 } 667 }
653 fputc('\n', out);
654} 668}
655 669
656void zconfdump(FILE *out) 670void zconfdump(FILE *out)
@@ -683,7 +697,6 @@ void zconfdump(FILE *out)
683 expr_fprint(prop->visible.expr, out); 697 expr_fprint(prop->visible.expr, out);
684 fputc('\n', out); 698 fputc('\n', out);
685 } 699 }
686 fputs("\n", out);
687 } 700 }
688 701
689 if (menu->list) 702 if (menu->list)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index fcdfb245a575..102e1235fd5c 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1454,6 +1454,8 @@ sub dump_enum($$) {
1454 my $file = shift; 1454 my $file = shift;
1455 1455
1456 $x =~ s@/\*.*?\*/@@gos; # strip comments. 1456 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1457 $x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums
1458
1457 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { 1459 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
1458 $declaration_name = $1; 1460 $declaration_name = $1;
1459 my $members = $2; 1461 my $members = $2;
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index e950f9cde019..827896f56501 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -2,6 +2,7 @@
2 2
3use File::Basename; 3use File::Basename;
4use Math::BigInt; 4use Math::BigInt;
5use Getopt::Long;
5 6
6# Copyright 2008, Intel Corporation 7# Copyright 2008, Intel Corporation
7# 8#
@@ -15,6 +16,16 @@ use Math::BigInt;
15# Arjan van de Ven <arjan@linux.intel.com> 16# Arjan van de Ven <arjan@linux.intel.com>
16 17
17 18
19my $cross_compile = "";
20my $vmlinux_name = "";
21my $modulefile = "";
22
23# Get options
24Getopt::Long::GetOptions(
25 'cross-compile|c=s' => \$cross_compile,
26 'module|m=s' => \$modulefile,
27 'help|h' => \&usage,
28) || usage ();
18my $vmlinux_name = $ARGV[0]; 29my $vmlinux_name = $ARGV[0];
19if (!defined($vmlinux_name)) { 30if (!defined($vmlinux_name)) {
20 my $kerver = `uname -r`; 31 my $kerver = `uname -r`;
@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) {
23 print "No vmlinux specified, assuming $vmlinux_name\n"; 34 print "No vmlinux specified, assuming $vmlinux_name\n";
24} 35}
25my $filename = $vmlinux_name; 36my $filename = $vmlinux_name;
26# 37
27# Step 1: Parse the oops to find the EIP value 38# Parse the oops to find the EIP value
28#
29 39
30my $target = "0"; 40my $target = "0";
31my $function; 41my $function;
@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("
177my $decodestop = Math::BigInt->from_hex("0x$target") + 8192; 187my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
178if ($target eq "0") { 188if ($target eq "0") {
179 print "No oops found!\n"; 189 print "No oops found!\n";
180 print "Usage: \n"; 190 usage();
181 print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
182 exit;
183} 191}
184 192
185# if it's a module, we need to find the .ko file and calculate a load offset 193# if it's a module, we need to find the .ko file and calculate a load offset
186if ($module ne "") { 194if ($module ne "") {
187 my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; 195 if ($modulefile eq "") {
188 chomp($modulefile); 196 $modulefile = `modinfo -F filename $module`;
197 chomp($modulefile);
198 }
189 $filename = $modulefile; 199 $filename = $modulefile;
190 if ($filename eq "") { 200 if ($filename eq "") {
191 print "Module .ko file for $module not found. Aborting\n"; 201 print "Module .ko file for $module not found. Aborting\n";
192 exit; 202 exit;
193 } 203 }
194 # ok so we found the module, now we need to calculate the vma offset 204 # ok so we found the module, now we need to calculate the vma offset
195 open(FILE, "objdump -dS $filename |") || die "Cannot start objdump"; 205 open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
196 while (<FILE>) { 206 while (<FILE>) {
197 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) { 207 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
198 my $fu = $1; 208 my $fu = $1;
199 $vmaoffset = hex($target) - hex($fu) - hex($func_offset); 209 $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset");
200 } 210 }
201 } 211 }
202 close(FILE); 212 close(FILE);
@@ -204,7 +214,7 @@ if ($module ne "") {
204 214
205my $counter = 0; 215my $counter = 0;
206my $state = 0; 216my $state = 0;
207my $center = 0; 217my $center = -1;
208my @lines; 218my @lines;
209my @reglines; 219my @reglines;
210 220
@@ -212,7 +222,7 @@ sub InRange {
212 my ($address, $target) = @_; 222 my ($address, $target) = @_;
213 my $ad = "0x".$address; 223 my $ad = "0x".$address;
214 my $ta = "0x".$target; 224 my $ta = "0x".$target;
215 my $delta = hex($ad) - hex($ta); 225 my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
216 226
217 if (($delta > -4096) && ($delta < 4096)) { 227 if (($delta > -4096) && ($delta < 4096)) {
218 return 1; 228 return 1;
@@ -225,7 +235,7 @@ sub InRange {
225# first, parse the input into the lines array, but to keep size down, 235# first, parse the input into the lines array, but to keep size down,
226# we only do this for 4Kb around the sweet spot 236# we only do this for 4Kb around the sweet spot
227 237
228open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; 238open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
229 239
230while (<FILE>) { 240while (<FILE>) {
231 my $line = $_; 241 my $line = $_;
@@ -236,7 +246,8 @@ while (<FILE>) {
236 $state = 1; 246 $state = 1;
237 } 247 }
238 } 248 }
239 } else { 249 }
250 if ($state == 1) {
240 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) { 251 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
241 my $val = $1; 252 my $val = $1;
242 if (!InRange($val, $target)) { 253 if (!InRange($val, $target)) {
@@ -259,7 +270,7 @@ if ($counter == 0) {
259 exit; 270 exit;
260} 271}
261 272
262if ($center == 0) { 273if ($center == -1) {
263 print "No matching code found \n"; 274 print "No matching code found \n";
264 exit; 275 exit;
265} 276}
@@ -344,3 +355,16 @@ while ($i < $finish) {
344 $i = $i +1; 355 $i = $i +1;
345} 356}
346 357
358sub usage {
359 print <<EOT;
360Usage:
361 dmesg | perl $0 [OPTION] [VMLINUX]
362
363OPTION:
364 -c, --cross-compile CROSS_COMPILE Specify the prefix used for toolchain.
365 -m, --module MODULE_DIRNAME Specify the module filename.
366 -h, --help Help.
367EOT
368 exit;
369}
370
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 23dbad80cce9..50ad317a4bf9 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -67,9 +67,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
67 echo \#define LINUX_COMPILE_BY \"`whoami`\" 67 echo \#define LINUX_COMPILE_BY \"`whoami`\"
68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" 68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
69 69
70 if [ -x /bin/dnsdomainname ]; then 70 domain=`dnsdomainname 2> /dev/null`
71 domain=`dnsdomainname 2> /dev/null` 71 if [ -z "$domain" ]; then
72 elif [ -x /bin/domainname ]; then
73 domain=`domainname 2> /dev/null` 72 domain=`domainname 2> /dev/null`
74 fi 73 fi
75 74
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 220213e603db..88f3f07205f8 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -796,6 +796,51 @@ static int do_platform_entry(const char *filename,
796 return 1; 796 return 1;
797} 797}
798 798
799static int do_mdio_entry(const char *filename,
800 struct mdio_device_id *id, char *alias)
801{
802 int i;
803
804 alias += sprintf(alias, MDIO_MODULE_PREFIX);
805
806 for (i = 0; i < 32; i++) {
807 if (!((id->phy_id_mask >> (31-i)) & 1))
808 *(alias++) = '?';
809 else if ((id->phy_id >> (31-i)) & 1)
810 *(alias++) = '1';
811 else
812 *(alias++) = '0';
813 }
814
815 /* Terminate the string */
816 *alias = 0;
817
818 return 1;
819}
820
821/* Looks like: zorro:iN. */
822static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
823 char *alias)
824{
825 id->id = TO_NATIVE(id->id);
826 strcpy(alias, "zorro:");
827 ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
828 return 1;
829}
830
831/* looks like: "pnp:dD" */
832static int do_isapnp_entry(const char *filename,
833 struct isapnp_device_id *id, char *alias)
834{
835 sprintf(alias, "pnp:d%c%c%c%x%x%x%x*",
836 'A' + ((id->vendor >> 2) & 0x3f) - 1,
837 'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1,
838 'A' + ((id->vendor >> 8) & 0x1f) - 1,
839 (id->function >> 4) & 0x0f, id->function & 0x0f,
840 (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
841 return 1;
842}
843
799/* Ignore any prefix, eg. some architectures prepend _ */ 844/* Ignore any prefix, eg. some architectures prepend _ */
800static inline int sym_is(const char *symbol, const char *name) 845static inline int sym_is(const char *symbol, const char *name)
801{ 846{
@@ -839,16 +884,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
839 char *zeros = NULL; 884 char *zeros = NULL;
840 885
841 /* We're looking for a section relative symbol */ 886 /* We're looking for a section relative symbol */
842 if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum) 887 if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
843 return; 888 return;
844 889
845 /* Handle all-NULL symbols allocated into .bss */ 890 /* Handle all-NULL symbols allocated into .bss */
846 if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) { 891 if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
847 zeros = calloc(1, sym->st_size); 892 zeros = calloc(1, sym->st_size);
848 symval = zeros; 893 symval = zeros;
849 } else { 894 } else {
850 symval = (void *)info->hdr 895 symval = (void *)info->hdr
851 + info->sechdrs[sym->st_shndx].sh_offset 896 + info->sechdrs[get_secindex(info, sym)].sh_offset
852 + sym->st_value; 897 + sym->st_value;
853 } 898 }
854 899
@@ -943,6 +988,18 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
943 do_table(symval, sym->st_size, 988 do_table(symval, sym->st_size,
944 sizeof(struct platform_device_id), "platform", 989 sizeof(struct platform_device_id), "platform",
945 do_platform_entry, mod); 990 do_platform_entry, mod);
991 else if (sym_is(symname, "__mod_mdio_device_table"))
992 do_table(symval, sym->st_size,
993 sizeof(struct mdio_device_id), "mdio",
994 do_mdio_entry, mod);
995 else if (sym_is(symname, "__mod_zorro_device_table"))
996 do_table(symval, sym->st_size,
997 sizeof(struct zorro_device_id), "zorro",
998 do_zorro_entry, mod);
999 else if (sym_is(symname, "__mod_isapnp_device_table"))
1000 do_table(symval, sym->st_size,
1001 sizeof(struct isapnp_device_id), "isa",
1002 do_isapnp_entry, mod);
946 free(zeros); 1003 free(zeros);
947} 1004}
948 1005
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 20923613467c..7acbdd8fcaed 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -14,6 +14,7 @@
14#define _GNU_SOURCE 14#define _GNU_SOURCE
15#include <stdio.h> 15#include <stdio.h>
16#include <ctype.h> 16#include <ctype.h>
17#include <string.h>
17#include "modpost.h" 18#include "modpost.h"
18#include "../../include/generated/autoconf.h" 19#include "../../include/generated/autoconf.h"
19#include "../../include/linux/license.h" 20#include "../../include/linux/license.h"
@@ -253,7 +254,7 @@ static enum export export_no(const char *s)
253 return export_unknown; 254 return export_unknown;
254} 255}
255 256
256static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) 257static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
257{ 258{
258 if (sec == elf->export_sec) 259 if (sec == elf->export_sec)
259 return export_plain; 260 return export_plain;
@@ -373,6 +374,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
373 Elf_Ehdr *hdr; 374 Elf_Ehdr *hdr;
374 Elf_Shdr *sechdrs; 375 Elf_Shdr *sechdrs;
375 Elf_Sym *sym; 376 Elf_Sym *sym;
377 const char *secstrings;
378 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
376 379
377 hdr = grab_file(filename, &info->size); 380 hdr = grab_file(filename, &info->size);
378 if (!hdr) { 381 if (!hdr) {
@@ -417,8 +420,27 @@ static int parse_elf(struct elf_info *info, const char *filename)
417 return 0; 420 return 0;
418 } 421 }
419 422
423 if (hdr->e_shnum == 0) {
424 /*
425 * There are more than 64k sections,
426 * read count from .sh_size.
427 * note: it doesn't need shndx2secindex()
428 */
429 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
430 }
431 else {
432 info->num_sections = hdr->e_shnum;
433 }
434 if (hdr->e_shstrndx == SHN_XINDEX) {
435 info->secindex_strings =
436 shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
437 }
438 else {
439 info->secindex_strings = hdr->e_shstrndx;
440 }
441
420 /* Fix endianness in section headers */ 442 /* Fix endianness in section headers */
421 for (i = 0; i < hdr->e_shnum; i++) { 443 for (i = 0; i < info->num_sections; i++) {
422 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); 444 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
423 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); 445 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
424 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); 446 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
@@ -431,9 +453,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
431 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); 453 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
432 } 454 }
433 /* Find symbol table. */ 455 /* Find symbol table. */
434 for (i = 1; i < hdr->e_shnum; i++) { 456 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
435 const char *secstrings 457 for (i = 1; i < info->num_sections; i++) {
436 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
437 const char *secname; 458 const char *secname;
438 int nobits = sechdrs[i].sh_type == SHT_NOBITS; 459 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
439 460
@@ -461,14 +482,26 @@ static int parse_elf(struct elf_info *info, const char *filename)
461 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 482 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
462 info->export_gpl_future_sec = i; 483 info->export_gpl_future_sec = i;
463 484
464 if (sechdrs[i].sh_type != SHT_SYMTAB) 485 if (sechdrs[i].sh_type == SHT_SYMTAB) {
465 continue; 486 unsigned int sh_link_idx;
487 symtab_idx = i;
488 info->symtab_start = (void *)hdr +
489 sechdrs[i].sh_offset;
490 info->symtab_stop = (void *)hdr +
491 sechdrs[i].sh_offset + sechdrs[i].sh_size;
492 sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
493 info->strtab = (void *)hdr +
494 sechdrs[sh_link_idx].sh_offset;
495 }
466 496
467 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; 497 /* 32bit section no. table? ("more than 64k sections") */
468 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset 498 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
469 + sechdrs[i].sh_size; 499 symtab_shndx_idx = i;
470 info->strtab = (void *)hdr + 500 info->symtab_shndx_start = (void *)hdr +
471 sechdrs[sechdrs[i].sh_link].sh_offset; 501 sechdrs[i].sh_offset;
502 info->symtab_shndx_stop = (void *)hdr +
503 sechdrs[i].sh_offset + sechdrs[i].sh_size;
504 }
472 } 505 }
473 if (!info->symtab_start) 506 if (!info->symtab_start)
474 fatal("%s has no symtab?\n", filename); 507 fatal("%s has no symtab?\n", filename);
@@ -480,6 +513,21 @@ static int parse_elf(struct elf_info *info, const char *filename)
480 sym->st_value = TO_NATIVE(sym->st_value); 513 sym->st_value = TO_NATIVE(sym->st_value);
481 sym->st_size = TO_NATIVE(sym->st_size); 514 sym->st_size = TO_NATIVE(sym->st_size);
482 } 515 }
516
517 if (symtab_shndx_idx != ~0U) {
518 Elf32_Word *p;
519 if (symtab_idx !=
520 shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
521 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
522 filename,
523 shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
524 symtab_idx);
525 /* Fix endianness */
526 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
527 p++)
528 *p = TO_NATIVE(*p);
529 }
530
483 return 1; 531 return 1;
484} 532}
485 533
@@ -503,6 +551,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
503 strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || 551 strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 ||
504 strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) 552 strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0)
505 return 1; 553 return 1;
554 if (info->hdr->e_machine == EM_PPC64)
555 /* Special register function linked on all modules during final link of .ko */
556 if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 ||
557 strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0)
558 return 1;
506 /* Do not ignore this symbol */ 559 /* Do not ignore this symbol */
507 return 0; 560 return 0;
508} 561}
@@ -514,7 +567,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
514 Elf_Sym *sym, const char *symname) 567 Elf_Sym *sym, const char *symname)
515{ 568{
516 unsigned int crc; 569 unsigned int crc;
517 enum export export = export_from_sec(info, sym->st_shndx); 570 enum export export = export_from_sec(info, get_secindex(info, sym));
518 571
519 switch (sym->st_shndx) { 572 switch (sym->st_shndx) {
520 case SHN_COMMON: 573 case SHN_COMMON:
@@ -656,19 +709,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
656 return "(unknown)"; 709 return "(unknown)";
657} 710}
658 711
659static const char *sec_name(struct elf_info *elf, int shndx) 712static const char *sec_name(struct elf_info *elf, int secindex)
660{ 713{
661 Elf_Shdr *sechdrs = elf->sechdrs; 714 Elf_Shdr *sechdrs = elf->sechdrs;
662 return (void *)elf->hdr + 715 return (void *)elf->hdr +
663 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 716 elf->sechdrs[elf->secindex_strings].sh_offset +
664 sechdrs[shndx].sh_name; 717 sechdrs[secindex].sh_name;
665} 718}
666 719
667static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) 720static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
668{ 721{
669 return (void *)elf->hdr + 722 return (void *)elf->hdr +
670 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 723 elf->sechdrs[elf->secindex_strings].sh_offset +
671 sechdr->sh_name; 724 sechdr->sh_name;
672} 725}
673 726
674/* if sym is empty or point to a string 727/* if sym is empty or point to a string
@@ -781,10 +834,13 @@ static void check_section(const char *modname, struct elf_info *elf,
781#define ALL_EXIT_TEXT_SECTIONS \ 834#define ALL_EXIT_TEXT_SECTIONS \
782 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" 835 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
783 836
784#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \ 837#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
785 CPU_INIT_SECTIONS, MEM_INIT_SECTIONS 838 MEM_INIT_SECTIONS
786#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \ 839#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
787 CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS 840 MEM_EXIT_SECTIONS
841
842#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
843#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
788 844
789#define DATA_SECTIONS ".data$", ".data.rel$" 845#define DATA_SECTIONS ".data$", ".data.rel$"
790#define TEXT_SECTIONS ".text$" 846#define TEXT_SECTIONS ".text$"
@@ -814,33 +870,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
814 870
815 871
816/* symbols in .data that may refer to init/exit sections */ 872/* symbols in .data that may refer to init/exit sections */
817static const char *symbol_white_list[] = 873#define DEFAULT_SYMBOL_WHITE_LIST \
818{ 874 "*driver", \
819 "*driver", 875 "*_template", /* scsi uses *_template a lot */ \
820 "*_template", /* scsi uses *_template a lot */ 876 "*_timer", /* arm uses ops structures named _timer a lot */ \
821 "*_timer", /* arm uses ops structures named _timer a lot */ 877 "*_sht", /* scsi also used *_sht to some extent */ \
822 "*_sht", /* scsi also used *_sht to some extent */ 878 "*_ops", \
823 "*_ops", 879 "*_probe", \
824 "*_probe", 880 "*_probe_one", \
825 "*_probe_one", 881 "*_console"
826 "*_console",
827 NULL
828};
829 882
830static const char *head_sections[] = { ".head.text*", NULL }; 883static const char *head_sections[] = { ".head.text*", NULL };
831static const char *linker_symbols[] = 884static const char *linker_symbols[] =
832 { "__init_begin", "_sinittext", "_einittext", NULL }; 885 { "__init_begin", "_sinittext", "_einittext", NULL };
833 886
834enum mismatch { 887enum mismatch {
835 NO_MISMATCH, 888 TEXT_TO_ANY_INIT,
836 TEXT_TO_INIT, 889 DATA_TO_ANY_INIT,
837 DATA_TO_INIT, 890 TEXT_TO_ANY_EXIT,
838 TEXT_TO_EXIT, 891 DATA_TO_ANY_EXIT,
839 DATA_TO_EXIT, 892 XXXINIT_TO_SOME_INIT,
840 XXXINIT_TO_INIT, 893 XXXEXIT_TO_SOME_EXIT,
841 XXXEXIT_TO_EXIT, 894 ANY_INIT_TO_ANY_EXIT,
842 INIT_TO_EXIT, 895 ANY_EXIT_TO_ANY_INIT,
843 EXIT_TO_INIT,
844 EXPORT_TO_INIT_EXIT, 896 EXPORT_TO_INIT_EXIT,
845}; 897};
846 898
@@ -848,6 +900,7 @@ struct sectioncheck {
848 const char *fromsec[20]; 900 const char *fromsec[20];
849 const char *tosec[20]; 901 const char *tosec[20];
850 enum mismatch mismatch; 902 enum mismatch mismatch;
903 const char *symbol_white_list[20];
851}; 904};
852 905
853const struct sectioncheck sectioncheck[] = { 906const struct sectioncheck sectioncheck[] = {
@@ -857,80 +910,103 @@ const struct sectioncheck sectioncheck[] = {
857{ 910{
858 .fromsec = { TEXT_SECTIONS, NULL }, 911 .fromsec = { TEXT_SECTIONS, NULL },
859 .tosec = { ALL_INIT_SECTIONS, NULL }, 912 .tosec = { ALL_INIT_SECTIONS, NULL },
860 .mismatch = TEXT_TO_INIT, 913 .mismatch = TEXT_TO_ANY_INIT,
914 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
861}, 915},
862{ 916{
863 .fromsec = { DATA_SECTIONS, NULL }, 917 .fromsec = { DATA_SECTIONS, NULL },
864 .tosec = { ALL_INIT_SECTIONS, NULL }, 918 .tosec = { ALL_XXXINIT_SECTIONS, NULL },
865 .mismatch = DATA_TO_INIT, 919 .mismatch = DATA_TO_ANY_INIT,
920 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
921},
922{
923 .fromsec = { DATA_SECTIONS, NULL },
924 .tosec = { INIT_SECTIONS, NULL },
925 .mismatch = DATA_TO_ANY_INIT,
926 .symbol_white_list = {
927 "*_template", "*_timer", "*_sht", "*_ops",
928 "*_probe", "*_probe_one", "*_console", NULL
929 },
866}, 930},
867{ 931{
868 .fromsec = { TEXT_SECTIONS, NULL }, 932 .fromsec = { TEXT_SECTIONS, NULL },
869 .tosec = { ALL_EXIT_SECTIONS, NULL }, 933 .tosec = { ALL_EXIT_SECTIONS, NULL },
870 .mismatch = TEXT_TO_EXIT, 934 .mismatch = TEXT_TO_ANY_EXIT,
935 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
871}, 936},
872{ 937{
873 .fromsec = { DATA_SECTIONS, NULL }, 938 .fromsec = { DATA_SECTIONS, NULL },
874 .tosec = { ALL_EXIT_SECTIONS, NULL }, 939 .tosec = { ALL_EXIT_SECTIONS, NULL },
875 .mismatch = DATA_TO_EXIT, 940 .mismatch = DATA_TO_ANY_EXIT,
941 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
876}, 942},
877/* Do not reference init code/data from devinit/cpuinit/meminit code/data */ 943/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
878{ 944{
879 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, 945 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
880 .tosec = { INIT_SECTIONS, NULL }, 946 .tosec = { INIT_SECTIONS, NULL },
881 .mismatch = XXXINIT_TO_INIT, 947 .mismatch = XXXINIT_TO_SOME_INIT,
948 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
882}, 949},
883/* Do not reference cpuinit code/data from meminit code/data */ 950/* Do not reference cpuinit code/data from meminit code/data */
884{ 951{
885 .fromsec = { MEM_INIT_SECTIONS, NULL }, 952 .fromsec = { MEM_INIT_SECTIONS, NULL },
886 .tosec = { CPU_INIT_SECTIONS, NULL }, 953 .tosec = { CPU_INIT_SECTIONS, NULL },
887 .mismatch = XXXINIT_TO_INIT, 954 .mismatch = XXXINIT_TO_SOME_INIT,
955 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
888}, 956},
889/* Do not reference meminit code/data from cpuinit code/data */ 957/* Do not reference meminit code/data from cpuinit code/data */
890{ 958{
891 .fromsec = { CPU_INIT_SECTIONS, NULL }, 959 .fromsec = { CPU_INIT_SECTIONS, NULL },
892 .tosec = { MEM_INIT_SECTIONS, NULL }, 960 .tosec = { MEM_INIT_SECTIONS, NULL },
893 .mismatch = XXXINIT_TO_INIT, 961 .mismatch = XXXINIT_TO_SOME_INIT,
962 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
894}, 963},
895/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ 964/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
896{ 965{
897 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, 966 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
898 .tosec = { EXIT_SECTIONS, NULL }, 967 .tosec = { EXIT_SECTIONS, NULL },
899 .mismatch = XXXEXIT_TO_EXIT, 968 .mismatch = XXXEXIT_TO_SOME_EXIT,
969 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
900}, 970},
901/* Do not reference cpuexit code/data from memexit code/data */ 971/* Do not reference cpuexit code/data from memexit code/data */
902{ 972{
903 .fromsec = { MEM_EXIT_SECTIONS, NULL }, 973 .fromsec = { MEM_EXIT_SECTIONS, NULL },
904 .tosec = { CPU_EXIT_SECTIONS, NULL }, 974 .tosec = { CPU_EXIT_SECTIONS, NULL },
905 .mismatch = XXXEXIT_TO_EXIT, 975 .mismatch = XXXEXIT_TO_SOME_EXIT,
976 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
906}, 977},
907/* Do not reference memexit code/data from cpuexit code/data */ 978/* Do not reference memexit code/data from cpuexit code/data */
908{ 979{
909 .fromsec = { CPU_EXIT_SECTIONS, NULL }, 980 .fromsec = { CPU_EXIT_SECTIONS, NULL },
910 .tosec = { MEM_EXIT_SECTIONS, NULL }, 981 .tosec = { MEM_EXIT_SECTIONS, NULL },
911 .mismatch = XXXEXIT_TO_EXIT, 982 .mismatch = XXXEXIT_TO_SOME_EXIT,
983 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
912}, 984},
913/* Do not use exit code/data from init code */ 985/* Do not use exit code/data from init code */
914{ 986{
915 .fromsec = { ALL_INIT_SECTIONS, NULL }, 987 .fromsec = { ALL_INIT_SECTIONS, NULL },
916 .tosec = { ALL_EXIT_SECTIONS, NULL }, 988 .tosec = { ALL_EXIT_SECTIONS, NULL },
917 .mismatch = INIT_TO_EXIT, 989 .mismatch = ANY_INIT_TO_ANY_EXIT,
990 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
918}, 991},
919/* Do not use init code/data from exit code */ 992/* Do not use init code/data from exit code */
920{ 993{
921 .fromsec = { ALL_EXIT_SECTIONS, NULL }, 994 .fromsec = { ALL_EXIT_SECTIONS, NULL },
922 .tosec = { ALL_INIT_SECTIONS, NULL }, 995 .tosec = { ALL_INIT_SECTIONS, NULL },
923 .mismatch = EXIT_TO_INIT, 996 .mismatch = ANY_EXIT_TO_ANY_INIT,
997 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
924}, 998},
925/* Do not export init/exit functions or data */ 999/* Do not export init/exit functions or data */
926{ 1000{
927 .fromsec = { "__ksymtab*", NULL }, 1001 .fromsec = { "__ksymtab*", NULL },
928 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, 1002 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
929 .mismatch = EXPORT_TO_INIT_EXIT 1003 .mismatch = EXPORT_TO_INIT_EXIT,
1004 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
930} 1005}
931}; 1006};
932 1007
933static int section_mismatch(const char *fromsec, const char *tosec) 1008static const struct sectioncheck *section_mismatch(
1009 const char *fromsec, const char *tosec)
934{ 1010{
935 int i; 1011 int i;
936 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); 1012 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
@@ -939,10 +1015,10 @@ static int section_mismatch(const char *fromsec, const char *tosec)
939 for (i = 0; i < elems; i++) { 1015 for (i = 0; i < elems; i++) {
940 if (match(fromsec, check->fromsec) && 1016 if (match(fromsec, check->fromsec) &&
941 match(tosec, check->tosec)) 1017 match(tosec, check->tosec))
942 return check->mismatch; 1018 return check;
943 check++; 1019 check++;
944 } 1020 }
945 return NO_MISMATCH; 1021 return NULL;
946} 1022}
947 1023
948/** 1024/**
@@ -961,7 +1037,7 @@ static int section_mismatch(const char *fromsec, const char *tosec)
961 * Pattern 2: 1037 * Pattern 2:
962 * Many drivers utilise a *driver container with references to 1038 * Many drivers utilise a *driver container with references to
963 * add, remove, probe functions etc. 1039 * add, remove, probe functions etc.
964 * These functions may often be marked __init and we do not want to 1040 * These functions may often be marked __devinit and we do not want to
965 * warn here. 1041 * warn here.
966 * the pattern is identified by: 1042 * the pattern is identified by:
967 * tosec = init or exit section 1043 * tosec = init or exit section
@@ -982,7 +1058,8 @@ static int section_mismatch(const char *fromsec, const char *tosec)
982 * refsymname = __init_begin, _sinittext, _einittext 1058 * refsymname = __init_begin, _sinittext, _einittext
983 * 1059 *
984 **/ 1060 **/
985static int secref_whitelist(const char *fromsec, const char *fromsym, 1061static int secref_whitelist(const struct sectioncheck *mismatch,
1062 const char *fromsec, const char *fromsym,
986 const char *tosec, const char *tosym) 1063 const char *tosec, const char *tosym)
987{ 1064{
988 /* Check for pattern 1 */ 1065 /* Check for pattern 1 */
@@ -994,7 +1071,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
994 /* Check for pattern 2 */ 1071 /* Check for pattern 2 */
995 if (match(tosec, init_exit_sections) && 1072 if (match(tosec, init_exit_sections) &&
996 match(fromsec, data_sections) && 1073 match(fromsec, data_sections) &&
997 match(fromsym, symbol_white_list)) 1074 match(fromsym, mismatch->symbol_white_list))
998 return 0; 1075 return 0;
999 1076
1000 /* Check for pattern 3 */ 1077 /* Check for pattern 3 */
@@ -1023,11 +1100,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
1023 Elf_Sym *near = NULL; 1100 Elf_Sym *near = NULL;
1024 Elf64_Sword distance = 20; 1101 Elf64_Sword distance = 20;
1025 Elf64_Sword d; 1102 Elf64_Sword d;
1103 unsigned int relsym_secindex;
1026 1104
1027 if (relsym->st_name != 0) 1105 if (relsym->st_name != 0)
1028 return relsym; 1106 return relsym;
1107
1108 relsym_secindex = get_secindex(elf, relsym);
1029 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1109 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1030 if (sym->st_shndx != relsym->st_shndx) 1110 if (get_secindex(elf, sym) != relsym_secindex)
1031 continue; 1111 continue;
1032 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) 1112 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1033 continue; 1113 continue;
@@ -1089,9 +1169,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1089 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1169 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1090 const char *symsec; 1170 const char *symsec;
1091 1171
1092 if (sym->st_shndx >= SHN_LORESERVE) 1172 if (is_shndx_special(sym->st_shndx))
1093 continue; 1173 continue;
1094 symsec = sec_name(elf, sym->st_shndx); 1174 symsec = sec_name(elf, get_secindex(elf, sym));
1095 if (strcmp(symsec, sec) != 0) 1175 if (strcmp(symsec, sec) != 0)
1096 continue; 1176 continue;
1097 if (!is_valid_name(elf, sym)) 1177 if (!is_valid_name(elf, sym))
@@ -1138,7 +1218,7 @@ static char *sec2annotation(const char *s)
1138 strcat(p, " "); 1218 strcat(p, " ");
1139 return r; /* we leak her but we do not care */ 1219 return r; /* we leak her but we do not care */
1140 } else { 1220 } else {
1141 return ""; 1221 return strdup("");
1142 } 1222 }
1143} 1223}
1144 1224
@@ -1155,7 +1235,8 @@ static int is_function(Elf_Sym *sym)
1155 * Try to find symbols near it so user can find it. 1235 * Try to find symbols near it so user can find it.
1156 * Check whitelist before warning - it may be a false positive. 1236 * Check whitelist before warning - it may be a false positive.
1157 */ 1237 */
1158static void report_sec_mismatch(const char *modname, enum mismatch mismatch, 1238static void report_sec_mismatch(const char *modname,
1239 const struct sectioncheck *mismatch,
1159 const char *fromsec, 1240 const char *fromsec,
1160 unsigned long long fromaddr, 1241 unsigned long long fromaddr,
1161 const char *fromsym, 1242 const char *fromsym,
@@ -1165,6 +1246,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1165{ 1246{
1166 const char *from, *from_p; 1247 const char *from, *from_p;
1167 const char *to, *to_p; 1248 const char *to, *to_p;
1249 char *prl_from;
1250 char *prl_to;
1168 1251
1169 switch (from_is_func) { 1252 switch (from_is_func) {
1170 case 0: from = "variable"; from_p = ""; break; 1253 case 0: from = "variable"; from_p = ""; break;
@@ -1186,64 +1269,80 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1186 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, 1269 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1187 tosym, to_p); 1270 tosym, to_p);
1188 1271
1189 switch (mismatch) { 1272 switch (mismatch->mismatch) {
1190 case TEXT_TO_INIT: 1273 case TEXT_TO_ANY_INIT:
1274 prl_from = sec2annotation(fromsec);
1275 prl_to = sec2annotation(tosec);
1191 fprintf(stderr, 1276 fprintf(stderr,
1192 "The function %s%s() references\n" 1277 "The function %s%s() references\n"
1193 "the %s %s%s%s.\n" 1278 "the %s %s%s%s.\n"
1194 "This is often because %s lacks a %s\n" 1279 "This is often because %s lacks a %s\n"
1195 "annotation or the annotation of %s is wrong.\n", 1280 "annotation or the annotation of %s is wrong.\n",
1196 sec2annotation(fromsec), fromsym, 1281 prl_from, fromsym,
1197 to, sec2annotation(tosec), tosym, to_p, 1282 to, prl_to, tosym, to_p,
1198 fromsym, sec2annotation(tosec), tosym); 1283 fromsym, prl_to, tosym);
1284 free(prl_from);
1285 free(prl_to);
1199 break; 1286 break;
1200 case DATA_TO_INIT: { 1287 case DATA_TO_ANY_INIT: {
1201 const char **s = symbol_white_list; 1288 prl_to = sec2annotation(tosec);
1289 const char *const *s = mismatch->symbol_white_list;
1202 fprintf(stderr, 1290 fprintf(stderr,
1203 "The variable %s references\n" 1291 "The variable %s references\n"
1204 "the %s %s%s%s\n" 1292 "the %s %s%s%s\n"
1205 "If the reference is valid then annotate the\n" 1293 "If the reference is valid then annotate the\n"
1206 "variable with __init* or __refdata (see linux/init.h) " 1294 "variable with __init* or __refdata (see linux/init.h) "
1207 "or name the variable:\n", 1295 "or name the variable:\n",
1208 fromsym, to, sec2annotation(tosec), tosym, to_p); 1296 fromsym, to, prl_to, tosym, to_p);
1209 while (*s) 1297 while (*s)
1210 fprintf(stderr, "%s, ", *s++); 1298 fprintf(stderr, "%s, ", *s++);
1211 fprintf(stderr, "\n"); 1299 fprintf(stderr, "\n");
1300 free(prl_to);
1212 break; 1301 break;
1213 } 1302 }
1214 case TEXT_TO_EXIT: 1303 case TEXT_TO_ANY_EXIT:
1304 prl_to = sec2annotation(tosec);
1215 fprintf(stderr, 1305 fprintf(stderr,
1216 "The function %s() references a %s in an exit section.\n" 1306 "The function %s() references a %s in an exit section.\n"
1217 "Often the %s %s%s has valid usage outside the exit section\n" 1307 "Often the %s %s%s has valid usage outside the exit section\n"
1218 "and the fix is to remove the %sannotation of %s.\n", 1308 "and the fix is to remove the %sannotation of %s.\n",
1219 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); 1309 fromsym, to, to, tosym, to_p, prl_to, tosym);
1310 free(prl_to);
1220 break; 1311 break;
1221 case DATA_TO_EXIT: { 1312 case DATA_TO_ANY_EXIT: {
1222 const char **s = symbol_white_list; 1313 prl_to = sec2annotation(tosec);
1314 const char *const *s = mismatch->symbol_white_list;
1223 fprintf(stderr, 1315 fprintf(stderr,
1224 "The variable %s references\n" 1316 "The variable %s references\n"
1225 "the %s %s%s%s\n" 1317 "the %s %s%s%s\n"
1226 "If the reference is valid then annotate the\n" 1318 "If the reference is valid then annotate the\n"
1227 "variable with __exit* (see linux/init.h) or " 1319 "variable with __exit* (see linux/init.h) or "
1228 "name the variable:\n", 1320 "name the variable:\n",
1229 fromsym, to, sec2annotation(tosec), tosym, to_p); 1321 fromsym, to, prl_to, tosym, to_p);
1230 while (*s) 1322 while (*s)
1231 fprintf(stderr, "%s, ", *s++); 1323 fprintf(stderr, "%s, ", *s++);
1232 fprintf(stderr, "\n"); 1324 fprintf(stderr, "\n");
1325 free(prl_to);
1233 break; 1326 break;
1234 } 1327 }
1235 case XXXINIT_TO_INIT: 1328 case XXXINIT_TO_SOME_INIT:
1236 case XXXEXIT_TO_EXIT: 1329 case XXXEXIT_TO_SOME_EXIT:
1330 prl_from = sec2annotation(fromsec);
1331 prl_to = sec2annotation(tosec);
1237 fprintf(stderr, 1332 fprintf(stderr,
1238 "The %s %s%s%s references\n" 1333 "The %s %s%s%s references\n"
1239 "a %s %s%s%s.\n" 1334 "a %s %s%s%s.\n"
1240 "If %s is only used by %s then\n" 1335 "If %s is only used by %s then\n"
1241 "annotate %s with a matching annotation.\n", 1336 "annotate %s with a matching annotation.\n",
1242 from, sec2annotation(fromsec), fromsym, from_p, 1337 from, prl_from, fromsym, from_p,
1243 to, sec2annotation(tosec), tosym, to_p, 1338 to, prl_to, tosym, to_p,
1244 tosym, fromsym, tosym); 1339 tosym, fromsym, tosym);
1340 free(prl_from);
1341 free(prl_to);
1245 break; 1342 break;
1246 case INIT_TO_EXIT: 1343 case ANY_INIT_TO_ANY_EXIT:
1344 prl_from = sec2annotation(fromsec);
1345 prl_to = sec2annotation(tosec);
1247 fprintf(stderr, 1346 fprintf(stderr,
1248 "The %s %s%s%s references\n" 1347 "The %s %s%s%s references\n"
1249 "a %s %s%s%s.\n" 1348 "a %s %s%s%s.\n"
@@ -1252,11 +1351,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1252 "uses functionality in the exit path.\n" 1351 "uses functionality in the exit path.\n"
1253 "The fix is often to remove the %sannotation of\n" 1352 "The fix is often to remove the %sannotation of\n"
1254 "%s%s so it may be used outside an exit section.\n", 1353 "%s%s so it may be used outside an exit section.\n",
1255 from, sec2annotation(fromsec), fromsym, from_p, 1354 from, prl_from, fromsym, from_p,
1256 to, sec2annotation(tosec), tosym, to_p, 1355 to, prl_to, tosym, to_p,
1257 sec2annotation(tosec), tosym, to_p); 1356 prl_to, tosym, to_p);
1357 free(prl_from);
1358 free(prl_to);
1258 break; 1359 break;
1259 case EXIT_TO_INIT: 1360 case ANY_EXIT_TO_ANY_INIT:
1361 prl_from = sec2annotation(fromsec);
1362 prl_to = sec2annotation(tosec);
1260 fprintf(stderr, 1363 fprintf(stderr,
1261 "The %s %s%s%s references\n" 1364 "The %s %s%s%s references\n"
1262 "a %s %s%s%s.\n" 1365 "a %s %s%s%s.\n"
@@ -1265,18 +1368,20 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1265 "uses functionality in the init path.\n" 1368 "uses functionality in the init path.\n"
1266 "The fix is often to remove the %sannotation of\n" 1369 "The fix is often to remove the %sannotation of\n"
1267 "%s%s so it may be used outside an init section.\n", 1370 "%s%s so it may be used outside an init section.\n",
1268 from, sec2annotation(fromsec), fromsym, from_p, 1371 from, prl_from, fromsym, from_p,
1269 to, sec2annotation(tosec), tosym, to_p, 1372 to, prl_to, tosym, to_p,
1270 sec2annotation(tosec), tosym, to_p); 1373 prl_to, tosym, to_p);
1374 free(prl_from);
1375 free(prl_to);
1271 break; 1376 break;
1272 case EXPORT_TO_INIT_EXIT: 1377 case EXPORT_TO_INIT_EXIT:
1378 prl_to = sec2annotation(tosec);
1273 fprintf(stderr, 1379 fprintf(stderr,
1274 "The symbol %s is exported and annotated %s\n" 1380 "The symbol %s is exported and annotated %s\n"
1275 "Fix this by removing the %sannotation of %s " 1381 "Fix this by removing the %sannotation of %s "
1276 "or drop the export.\n", 1382 "or drop the export.\n",
1277 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); 1383 tosym, prl_to, prl_to, tosym);
1278 case NO_MISMATCH: 1384 free(prl_to);
1279 /* To get warnings on missing members */
1280 break; 1385 break;
1281 } 1386 }
1282 fprintf(stderr, "\n"); 1387 fprintf(stderr, "\n");
@@ -1286,11 +1391,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1286 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1391 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1287{ 1392{
1288 const char *tosec; 1393 const char *tosec;
1289 enum mismatch mismatch; 1394 const struct sectioncheck *mismatch;
1290 1395
1291 tosec = sec_name(elf, sym->st_shndx); 1396 tosec = sec_name(elf, get_secindex(elf, sym));
1292 mismatch = section_mismatch(fromsec, tosec); 1397 mismatch = section_mismatch(fromsec, tosec);
1293 if (mismatch != NO_MISMATCH) { 1398 if (mismatch) {
1294 Elf_Sym *to; 1399 Elf_Sym *to;
1295 Elf_Sym *from; 1400 Elf_Sym *from;
1296 const char *tosym; 1401 const char *tosym;
@@ -1302,7 +1407,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1302 tosym = sym_name(elf, to); 1407 tosym = sym_name(elf, to);
1303 1408
1304 /* check whitelist - we may ignore it */ 1409 /* check whitelist - we may ignore it */
1305 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { 1410 if (secref_whitelist(mismatch,
1411 fromsec, fromsym, tosec, tosym)) {
1306 report_sec_mismatch(modname, mismatch, 1412 report_sec_mismatch(modname, mismatch,
1307 fromsec, r->r_offset, fromsym, 1413 fromsec, r->r_offset, fromsym,
1308 is_function(from), tosec, tosym, 1414 is_function(from), tosec, tosym,
@@ -1315,10 +1421,10 @@ static unsigned int *reloc_location(struct elf_info *elf,
1315 Elf_Shdr *sechdr, Elf_Rela *r) 1421 Elf_Shdr *sechdr, Elf_Rela *r)
1316{ 1422{
1317 Elf_Shdr *sechdrs = elf->sechdrs; 1423 Elf_Shdr *sechdrs = elf->sechdrs;
1318 int section = sechdr->sh_info; 1424 int section = shndx2secindex(sechdr->sh_info);
1319 1425
1320 return (void *)elf->hdr + sechdrs[section].sh_offset + 1426 return (void *)elf->hdr + sechdrs[section].sh_offset +
1321 (r->r_offset - sechdrs[section].sh_addr); 1427 r->r_offset - sechdrs[section].sh_addr;
1322} 1428}
1323 1429
1324static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) 1430static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
@@ -1423,7 +1529,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
1423 r.r_addend = TO_NATIVE(rela->r_addend); 1529 r.r_addend = TO_NATIVE(rela->r_addend);
1424 sym = elf->symtab_start + r_sym; 1530 sym = elf->symtab_start + r_sym;
1425 /* Skip special sections */ 1531 /* Skip special sections */
1426 if (sym->st_shndx >= SHN_LORESERVE) 1532 if (is_shndx_special(sym->st_shndx))
1427 continue; 1533 continue;
1428 check_section_mismatch(modname, elf, &r, sym, fromsec); 1534 check_section_mismatch(modname, elf, &r, sym, fromsec);
1429 } 1535 }
@@ -1481,7 +1587,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
1481 } 1587 }
1482 sym = elf->symtab_start + r_sym; 1588 sym = elf->symtab_start + r_sym;
1483 /* Skip special sections */ 1589 /* Skip special sections */
1484 if (sym->st_shndx >= SHN_LORESERVE) 1590 if (is_shndx_special(sym->st_shndx))
1485 continue; 1591 continue;
1486 check_section_mismatch(modname, elf, &r, sym, fromsec); 1592 check_section_mismatch(modname, elf, &r, sym, fromsec);
1487 } 1593 }
@@ -1506,7 +1612,7 @@ static void check_sec_ref(struct module *mod, const char *modname,
1506 Elf_Shdr *sechdrs = elf->sechdrs; 1612 Elf_Shdr *sechdrs = elf->sechdrs;
1507 1613
1508 /* Walk through all sections */ 1614 /* Walk through all sections */
1509 for (i = 0; i < elf->hdr->e_shnum; i++) { 1615 for (i = 0; i < elf->num_sections; i++) {
1510 check_section(modname, elf, &elf->sechdrs[i]); 1616 check_section(modname, elf, &elf->sechdrs[i]);
1511 /* We want to process only relocation sections and not .init */ 1617 /* We want to process only relocation sections and not .init */
1512 if (sechdrs[i].sh_type == SHT_RELA) 1618 if (sechdrs[i].sh_type == SHT_RELA)
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index be987a44f250..0388cfccac8d 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -129,8 +129,51 @@ struct elf_info {
129 const char *strtab; 129 const char *strtab;
130 char *modinfo; 130 char *modinfo;
131 unsigned int modinfo_len; 131 unsigned int modinfo_len;
132
133 /* support for 32bit section numbers */
134
135 unsigned int num_sections; /* max_secindex + 1 */
136 unsigned int secindex_strings;
137 /* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
138 * take shndx from symtab_shndx_start[N] instead */
139 Elf32_Word *symtab_shndx_start;
140 Elf32_Word *symtab_shndx_stop;
132}; 141};
133 142
143static inline int is_shndx_special(unsigned int i)
144{
145 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
146}
147
148/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
149 * shndx == 0 <=> sechdrs[0]
150 * ......
151 * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
152 * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
153 * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
154 * ......
155 * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
156 * so basically we map 0000..feff -> 0000..feff
157 * ff00..ffff -> (you are a bad boy, dont do it)
158 * 10000..xxxx -> ff00..(xxxx-0x100)
159 */
160static inline unsigned int shndx2secindex(unsigned int i)
161{
162 if (i <= SHN_HIRESERVE)
163 return i;
164 return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
165}
166
167/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
168static inline unsigned int get_secindex(const struct elf_info *info,
169 const Elf_Sym *sym)
170{
171 if (sym->st_shndx != SHN_XINDEX)
172 return sym->st_shndx;
173 return shndx2secindex(info->symtab_shndx_start[sym -
174 info->symtab_start]);
175}
176
134/* file2alias.c */ 177/* file2alias.c */
135extern unsigned int cross_build; 178extern unsigned int cross_build;
136void handle_moddevtable(struct module *mod, struct elf_info *info, 179void handle_moddevtable(struct module *mod, struct elf_info *info,
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index c6e88c652c2f..361d0f71184b 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -175,12 +175,11 @@ sub do_nm
175 } 175 }
176 if (! -e "$source.c" && ! -e "$source.S") { 176 if (! -e "$source.c" && ! -e "$source.S") {
177 # No obvious source, exclude the object if it is conglomerate 177 # No obvious source, exclude the object if it is conglomerate
178 if (! open(OBJDUMPDATA, "$objdump $basename|")) { 178 open(my $objdumpdata, "$objdump $basename|")
179 printf STDERR "$objdump $fullname failed $!\n"; 179 or die "$objdump $fullname failed $!\n";
180 return; 180
181 }
182 my $comment; 181 my $comment;
183 while (<OBJDUMPDATA>) { 182 while (<$objdumpdata>) {
184 chomp(); 183 chomp();
185 if (/^In archive/) { 184 if (/^In archive/) {
186 # Archives are always conglomerate 185 # Archives are always conglomerate
@@ -190,18 +189,18 @@ sub do_nm
190 next if (! /^[ 0-9a-f]{5,} /); 189 next if (! /^[ 0-9a-f]{5,} /);
191 $comment .= substr($_, 43); 190 $comment .= substr($_, 43);
192 } 191 }
193 close(OBJDUMPDATA); 192 close($objdumpdata);
193
194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) { 194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
195 printf STDERR "No source file found for $fullname\n"; 195 printf STDERR "No source file found for $fullname\n";
196 } 196 }
197 return; 197 return;
198 } 198 }
199 if (! open(NMDATA, "$nm $basename|")) { 199 open (my $nmdata, "$nm $basename|")
200 printf STDERR "$nm $fullname failed $!\n"; 200 or die "$nm $fullname failed $!\n";
201 return; 201
202 }
203 my @nmdata; 202 my @nmdata;
204 while (<NMDATA>) { 203 while (<$nmdata>) {
205 chop; 204 chop;
206 ($type, $name) = (split(/ +/, $_, 3))[1..2]; 205 ($type, $name) = (split(/ +/, $_, 3))[1..2];
207 # Expected types 206 # Expected types
@@ -268,7 +267,8 @@ sub do_nm
268 } 267 }
269 } 268 }
270 } 269 }
271 close(NMDATA); 270 close($nmdata);
271
272 if ($#nmdata < 0) { 272 if ($#nmdata < 0) {
273 if ( 273 if (
274 $fullname ne "lib/brlock.o" 274 $fullname ne "lib/brlock.o"
@@ -316,8 +316,7 @@ sub drop_def
316 316
317sub list_multiply_defined 317sub list_multiply_defined
318{ 318{
319 my ($name, $module); 319 foreach my $name (keys(%def)) {
320 foreach $name (keys(%def)) {
321 if ($#{$def{$name}} > 0) { 320 if ($#{$def{$name}} > 0) {
322 # Special case for cond_syscall 321 # Special case for cond_syscall
323 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && 322 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
@@ -333,8 +332,9 @@ sub list_multiply_defined
333 &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name); 332 &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
334 next; 333 next;
335 } 334 }
335
336 printf "$name is multiply defined in :-\n"; 336 printf "$name is multiply defined in :-\n";
337 foreach $module (@{$def{$name}}) { 337 foreach my $module (@{$def{$name}}) {
338 printf "\t$module\n"; 338 printf "\t$module\n";
339 } 339 }
340 } 340 }
@@ -343,12 +343,13 @@ sub list_multiply_defined
343 343
344sub resolve_external_references 344sub resolve_external_references
345{ 345{
346 my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export); 346 my ($kstrtab, $ksymtab, $export);
347
347 printf "\n"; 348 printf "\n";
348 foreach $object (keys(%nmdata)) { 349 foreach my $object (keys(%nmdata)) {
349 my $nmdata = $nmdata{$object}; 350 my $nmdata = $nmdata{$object};
350 for ($i = 0; $i <= $#{$nmdata}; ++$i) { 351 for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
351 ($type, $name) = split(' ', $nmdata->[$i], 2); 352 my ($type, $name) = split(' ', $nmdata->[$i], 2);
352 if ($type eq "U" || $type eq "w") { 353 if ($type eq "U" || $type eq "w") {
353 if (exists($def{$name}) || exists($ksymtab{$name})) { 354 if (exists($def{$name}) || exists($ksymtab{$name})) {
354 # add the owning object to the nmdata 355 # add the owning object to the nmdata
@@ -357,7 +358,7 @@ sub resolve_external_references
357 $kstrtab = "R __kstrtab_$name"; 358 $kstrtab = "R __kstrtab_$name";
358 $ksymtab = "R __ksymtab_$name"; 359 $ksymtab = "R __ksymtab_$name";
359 $export = 0; 360 $export = 0;
360 for ($j = 0; $j <= $#{$nmdata}; ++$j) { 361 for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
361 if ($nmdata->[$j] eq $kstrtab || 362 if ($nmdata->[$j] eq $kstrtab ||
362 $nmdata->[$j] eq $ksymtab) { 363 $nmdata->[$j] eq $ksymtab) {
363 $export = 1; 364 $export = 1;
@@ -424,11 +425,11 @@ sub resolve_external_references
424sub list_extra_externals 425sub list_extra_externals
425{ 426{
426 my %noref = (); 427 my %noref = ();
427 my ($name, @module, $module, $export); 428
428 foreach $name (keys(%def)) { 429 foreach my $name (keys(%def)) {
429 if (! exists($ref{$name})) { 430 if (! exists($ref{$name})) {
430 @module = @{$def{$name}}; 431 my @module = @{$def{$name}};
431 foreach $module (@module) { 432 foreach my $module (@module) {
432 if (! exists($noref{$module})) { 433 if (! exists($noref{$module})) {
433 $noref{$module} = []; 434 $noref{$module} = [];
434 } 435 }
@@ -438,16 +439,16 @@ sub list_extra_externals
438 } 439 }
439 if (%noref) { 440 if (%noref) {
440 printf "\nExternally defined symbols with no external references\n"; 441 printf "\nExternally defined symbols with no external references\n";
441 foreach $module (sort(keys(%noref))) { 442 foreach my $module (sort(keys(%noref))) {
442 printf " $module\n"; 443 printf " $module\n";
443 foreach (sort(@{$noref{$module}})) { 444 foreach (sort(@{$noref{$module}})) {
444 if (exists($export{$_})) { 445 my $export;
445 $export = " (export only)"; 446 if (exists($export{$_})) {
446 } 447 $export = " (export only)";
447 else { 448 } else {
448 $export = ""; 449 $export = "";
449 } 450 }
450 printf " $_$export\n"; 451 printf " $_$export\n";
451 } 452 }
452 } 453 }
453 } 454 }
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index 62fcc3a7f4d3..d0b931b994fc 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -44,7 +44,7 @@ rpm-pkg rpm: $(objtree)/kernel.spec FORCE
44 fi 44 fi
45 $(MAKE) clean 45 $(MAKE) clean
46 $(PREV) ln -sf $(srctree) $(KERNELPATH) 46 $(PREV) ln -sf $(srctree) $(KERNELPATH)
47 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion 47 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --save-scmversion
48 $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. 48 $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
49 $(PREV) rm $(KERNELPATH) 49 $(PREV) rm $(KERNELPATH)
50 rm -f $(objtree)/.scmversion 50 rm -f $(objtree)/.scmversion
@@ -111,13 +111,38 @@ tar%pkg: FORCE
111clean-dirs += $(objtree)/tar-install/ 111clean-dirs += $(objtree)/tar-install/
112 112
113 113
114# perf-pkg - generate a source tarball with perf source
115# ---------------------------------------------------------------------------
116
117perf-tar=perf-$(KERNELVERSION)
118
119quiet_cmd_perf_tar = TAR
120 cmd_perf_tar = \
121git archive --prefix=$(perf-tar)/ HEAD^{tree} \
122 $$(cat $(srctree)/tools/perf/MANIFEST) -o $(perf-tar).tar; \
123mkdir -p $(perf-tar); \
124git rev-parse HEAD > $(perf-tar)/HEAD; \
125tar rf $(perf-tar).tar $(perf-tar)/HEAD; \
126rm -r $(perf-tar); \
127$(if $(findstring tar-src,$@),, \
128$(if $(findstring bz2,$@),bzip2, \
129$(if $(findstring gz,$@),gzip, \
130$(error unknown target $@))) \
131 -f -9 $(perf-tar).tar)
132
133perf-%pkg: FORCE
134 $(call cmd,perf_tar)
135
114# Help text displayed when executing 'make help' 136# Help text displayed when executing 'make help'
115# --------------------------------------------------------------------------- 137# ---------------------------------------------------------------------------
116help: FORCE 138help: FORCE
117 @echo ' rpm-pkg - Build both source and binary RPM kernel packages' 139 @echo ' rpm-pkg - Build both source and binary RPM kernel packages'
118 @echo ' binrpm-pkg - Build only the binary kernel package' 140 @echo ' binrpm-pkg - Build only the binary kernel package'
119 @echo ' deb-pkg - Build the kernel as an deb package' 141 @echo ' deb-pkg - Build the kernel as an deb package'
120 @echo ' tar-pkg - Build the kernel as an uncompressed tarball' 142 @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
121 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' 143 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
122 @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' 144 @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball'
145 @echo ' perf-tar-src-pkg - Build $(perf-tar).tar source tarball'
146 @echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball'
147 @echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
123 148
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 8b357b0bd250..5f1e2fc7f171 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -18,6 +18,8 @@ create_package() {
18 cp debian/copyright "$pdir/usr/share/doc/$pname/" 18 cp debian/copyright "$pdir/usr/share/doc/$pname/"
19 cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian" 19 cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
20 gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian" 20 gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
21 sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
22 | xargs -r0 md5sum > DEBIAN/md5sums"
21 23
22 # Fix ownership and permissions 24 # Fix ownership and permissions
23 chown -R root:root "$pdir" 25 chown -R root:root "$pdir"
@@ -146,10 +148,11 @@ EOF
146# Generate a control file 148# Generate a control file
147cat <<EOF > debian/control 149cat <<EOF > debian/control
148Source: linux-upstream 150Source: linux-upstream
149Section: admin 151Section: kernel
150Priority: optional 152Priority: optional
151Maintainer: $maintainer 153Maintainer: $maintainer
152Standards-Version: 3.8.1 154Standards-Version: 3.8.4
155Homepage: http://www.kernel.org/
153EOF 156EOF
154 157
155if [ "$ARCH" = "um" ]; then 158if [ "$ARCH" = "um" ]; then
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 47bdd2f99b78..15440f55aef6 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2# 2#
3# Output a simple RPM spec file that uses no fancy features requring 3# Output a simple RPM spec file that uses no fancy features requiring
4# RPM v4. This is intended to work with any RPM distro. 4# RPM v4. This is intended to work with any RPM distro.
5# 5#
6# The only gothic bit here is redefining install_post to avoid 6# The only gothic bit here is redefining install_post to avoid
@@ -39,7 +39,7 @@ if ! $PREBUILT; then
39echo "Source: kernel-$__KERNELRELEASE.tar.gz" 39echo "Source: kernel-$__KERNELRELEASE.tar.gz"
40fi 40fi
41 41
42echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root" 42echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root"
43echo "Provides: $PROVIDES" 43echo "Provides: $PROVIDES"
44echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" 44echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
45echo "%define debug_package %{nil}" 45echo "%define debug_package %{nil}"
diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl
index cb4260ebdb91..6943fa7cc95b 100644
--- a/scripts/profile2linkerlist.pl
+++ b/scripts/profile2linkerlist.pl
@@ -7,15 +7,13 @@
7# usage: 7# usage:
8# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist 8# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist
9# 9#
10use strict;
10 11
11while (<>) { 12while (<>) {
12 my $line = $_; 13 my $line = $_;
13 14
14 $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/; 15 $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/;
15 16
16 if ( ($line =~ /unknown/) || ($line =~ /total/)) { 17 print "*(.text.$1)\n"
17 18 unless ($line =~ /unknown/) || ($line =~ /total/);
18 } else {
19 print "*(.text.$1)\n";
20 }
21} 19}
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index f3c9c0a90b98..0171060b5fd6 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -326,7 +326,7 @@ if ($arch eq "x86_64") {
326 # 14: R_MIPS_NONE *ABS* 326 # 14: R_MIPS_NONE *ABS*
327 # 18: 00020021 nop 327 # 18: 00020021 nop
328 if ($is_module eq "0") { 328 if ($is_module eq "0") {
329 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; 329 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_26\\s+_mcount\$";
330 } else { 330 } else {
331 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$"; 331 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$";
332 } 332 }
diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py
index 4c79660793cf..44423b4dcb82 100644
--- a/scripts/rt-tester/rt-tester.py
+++ b/scripts/rt-tester/rt-tester.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python 1#!/usr/bin/python
2# 2#
3# rt-mutex tester 3# rt-mutex tester
4# 4#
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
index 24626968055d..58a12c278706 100644
--- a/scripts/selinux/genheaders/genheaders.c
+++ b/scripts/selinux/genheaders/genheaders.c
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
81 fprintf(fout, "\n"); 81 fprintf(fout, "\n");
82 82
83 for (i = 1; i < isids_len; i++) { 83 for (i = 1; i < isids_len; i++) {
84 char *s = initial_sid_to_string[i]; 84 const char *s = initial_sid_to_string[i];
85 fprintf(fout, "#define SECINITSID_%s", s); 85 fprintf(fout, "#define SECINITSID_%s", s);
86 for (j = 0; j < max(1, 40 - strlen(s)); j++) 86 for (j = 0; j < max(1, 40 - strlen(s)); j++)
87 fprintf(fout, " "); 87 fprintf(fout, " ");
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 46989b88d734..64a9cb5556cd 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -10,73 +10,162 @@
10# 10#
11 11
12usage() { 12usage() {
13 echo "Usage: $0 [srctree]" >&2 13 echo "Usage: $0 [--save-scmversion] [srctree]" >&2
14 exit 1 14 exit 1
15} 15}
16 16
17cd "${1:-.}" || usage 17scm_only=false
18srctree=.
19if test "$1" = "--save-scmversion"; then
20 scm_only=true
21 shift
22fi
23if test $# -gt 0; then
24 srctree=$1
25 shift
26fi
27if test $# -gt 0 -o ! -d "$srctree"; then
28 usage
29fi
18 30
19# Check for git and a git repo. 31scm_version()
20if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then 32{
33 local short
34 short=false
21 35
22 # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it, 36 cd "$srctree"
23 # because this version is defined in the top level Makefile. 37 if test -e .scmversion; then
24 if [ -z "`git describe --exact-match 2>/dev/null`" ]; then 38 cat .scmversion
39 return
40 fi
41 if test "$1" = "--short"; then
42 short=true
43 fi
25 44
26 # If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"), 45 # Check for git and a git repo.
27 # we pretty print it. 46 if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
28 if atag="`git describe 2>/dev/null`"; then 47
29 echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' 48 # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
49 # it, because this version is defined in the top level Makefile.
50 if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
51
52 # If only the short version is requested, don't bother
53 # running further git commands
54 if $short; then
55 echo "+"
56 return
57 fi
58 # If we are past a tagged commit (like
59 # "v2.6.30-rc5-302-g72357d5"), we pretty print it.
60 if atag="`git describe 2>/dev/null`"; then
61 echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
62
63 # If we don't have a tag at all we print -g{commitish}.
64 else
65 printf '%s%s' -g $head
66 fi
67 fi
30 68
31 # If we don't have a tag at all we print -g{commitish}. 69 # Is this git on svn?
32 else 70 if git config --get svn-remote.svn.url >/dev/null; then
33 printf '%s%s' -g $head 71 printf -- '-svn%s' "`git svn find-rev $head`"
34 fi 72 fi
35 fi
36 73
37 # Is this git on svn? 74 # Update index only on r/w media
38 if git config --get svn-remote.svn.url >/dev/null; then 75 [ -w . ] && git update-index --refresh --unmerged > /dev/null
39 printf -- '-svn%s' "`git svn find-rev $head`"
40 fi
41 76
42 # Update index only on r/w media 77 # Check for uncommitted changes
43 [ -w . ] && git update-index --refresh --unmerged > /dev/null 78 if git diff-index --name-only HEAD | grep -v "^scripts/package" \
79 | read dummy; then
80 printf '%s' -dirty
81 fi
44 82
45 # Check for uncommitted changes 83 # All done with git
46 if git diff-index --name-only HEAD | grep -v "^scripts/package" \ 84 return
47 | read dummy; then
48 printf '%s' -dirty
49 fi 85 fi
50 86
51 # All done with git 87 # Check for mercurial and a mercurial repo.
52 exit 88 if hgid=`hg id 2>/dev/null`; then
53fi 89 tag=`printf '%s' "$hgid" | cut -d' ' -f2`
54 90
55# Check for mercurial and a mercurial repo. 91 # Do we have an untagged version?
56if hgid=`hg id 2>/dev/null`; then 92 if [ -z "$tag" -o "$tag" = tip ]; then
57 tag=`printf '%s' "$hgid" | cut -d' ' -f2` 93 id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
94 printf '%s%s' -hg "$id"
95 fi
96
97 # Are there uncommitted changes?
98 # These are represented by + after the changeset id.
99 case "$hgid" in
100 *+|*+\ *) printf '%s' -dirty ;;
101 esac
58 102
59 # Do we have an untagged version? 103 # All done with mercurial
60 if [ -z "$tag" -o "$tag" = tip ]; then 104 return
61 id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
62 printf '%s%s' -hg "$id"
63 fi 105 fi
64 106
65 # Are there uncommitted changes? 107 # Check for svn and a svn repo.
66 # These are represented by + after the changeset id. 108 if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
67 case "$hgid" in 109 rev=`echo $rev | awk '{print $NF}'`
68 *+|*+\ *) printf '%s' -dirty ;; 110 printf -- '-svn%s' "$rev"
69 esac
70 111
71 # All done with mercurial 112 # All done with svn
113 return
114 fi
115}
116
117collect_files()
118{
119 local file res
120
121 for file; do
122 case "$file" in
123 *\~*)
124 continue
125 ;;
126 esac
127 if test -e "$file"; then
128 res="$res$(cat "$file")"
129 fi
130 done
131 echo "$res"
132}
133
134if $scm_only; then
135 if test ! -e .scmversion; then
136 res=$(scm_version)
137 echo "$res" >.scmversion
138 fi
72 exit 139 exit
73fi 140fi
74 141
75# Check for svn and a svn repo. 142if test -e include/config/auto.conf; then
76if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then 143 . include/config/auto.conf
77 rev=`echo $rev | awk '{print $NF}'` 144else
78 printf -- '-svn%s' "$rev" 145 echo "Error: kernelrelease not valid - run 'make prepare' to update it"
146 exit 1
147fi
79 148
80 # All done with svn 149# localversion* files in the build and source directory
81 exit 150res="$(collect_files localversion*)"
151if test ! "$srctree" -ef .; then
152 res="$res$(collect_files "$srctree"/localversion*)"
153fi
154
155# CONFIG_LOCALVERSION and LOCALVERSION (if set)
156res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
157
158# scm version string if not at a tagged commit
159if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
160 # full scm version string
161 res="$res$(scm_version)"
162else
163 # apped a plus sign if the repository is not in a clean tagged
164 # state and LOCALVERSION= is not specified
165 if test "${LOCALVERSION+set}" != "set"; then
166 scm=$(scm_version --short)
167 res="$res${scm:++}"
168 fi
82fi 169fi
170
171echo "$res"
diff --git a/scripts/show_delta b/scripts/show_delta
index 48a706ab3d0c..17df3051747a 100755
--- a/scripts/show_delta
+++ b/scripts/show_delta
@@ -1,4 +1,4 @@
1#!/usr/bin/env python 1#!/usr/bin/python
2# 2#
3# show_deltas: Read list of printk messages instrumented with 3# show_deltas: Read list of printk messages instrumented with
4# time data, and format with time deltas. 4# time data, and format with time deltas.
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 1a0c44d7c4a7..8509bb512935 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -5,7 +5,7 @@
5# mode may be any of: tags, TAGS, cscope 5# mode may be any of: tags, TAGS, cscope
6# 6#
7# Uses the following environment variables: 7# Uses the following environment variables:
8# ARCH, SUBARCH, srctree, src, obj 8# ARCH, SUBARCH, SRCARCH, srctree, src, obj
9 9
10if [ "$KBUILD_VERBOSE" = "1" ]; then 10if [ "$KBUILD_VERBOSE" = "1" ]; then
11 set -x 11 set -x
@@ -17,28 +17,48 @@ ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \
17 -name .git ) \ 17 -name .git ) \
18 -prune -o" 18 -prune -o"
19 19
20# Do not use full path is we do not use O=.. builds 20# Do not use full path if we do not use O=.. builds
21# Use make O=. {tags|cscope}
22# to force full paths for a non-O= build
21if [ "${KBUILD_SRC}" = "" ]; then 23if [ "${KBUILD_SRC}" = "" ]; then
22 tree= 24 tree=
23else 25else
24 tree=${srctree}/ 26 tree=${srctree}/
25fi 27fi
26 28
29# Find all available archs
30find_all_archs()
31{
32 ALLSOURCE_ARCHS=""
33 for arch in `ls ${tree}arch`; do
34 ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
35 done
36}
37
27# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH 38# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
28if [ "${ALLSOURCE_ARCHS}" = "" ]; then 39if [ "${ALLSOURCE_ARCHS}" = "" ]; then
29 ALLSOURCE_ARCHS=${SRCARCH} 40 ALLSOURCE_ARCHS=${SRCARCH}
41elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
42 find_all_archs
30fi 43fi
31 44
32# find sources in arch/$ARCH 45# find sources in arch/$ARCH
33find_arch_sources() 46find_arch_sources()
34{ 47{
35 find ${tree}arch/$1 $ignore -name "$2" -print; 48 for i in $archincludedir; do
49 prune="$prune -wholename $i -prune -o"
50 done
51 find ${tree}arch/$1 $ignore $prune -name "$2" -print;
36} 52}
37 53
38# find sources in arch/$1/include 54# find sources in arch/$1/include
39find_arch_include_sources() 55find_arch_include_sources()
40{ 56{
41 find ${tree}arch/$1/include $ignore -name "$2" -print; 57 include=$(find ${tree}arch/$1/ -name include -type d);
58 if [ -n "$include" ]; then
59 archincludedir="$archincludedir $include"
60 find $include $ignore -name "$2" -print;
61 fi
42} 62}
43 63
44# find sources in include/ 64# find sources in include/
@@ -63,14 +83,15 @@ find_sources()
63 83
64all_sources() 84all_sources()
65{ 85{
66 for arch in $ALLSOURCE_ARCHS 86 find_arch_include_sources ${SRCARCH} '*.[chS]'
67 do
68 find_sources $arch '*.[chS]'
69 done
70 if [ ! -z "$archinclude" ]; then 87 if [ ! -z "$archinclude" ]; then
71 find_arch_include_sources $archinclude '*.[chS]' 88 find_arch_include_sources $archinclude '*.[chS]'
72 fi 89 fi
73 find_include_sources '*.[chS]' 90 find_include_sources '*.[chS]'
91 for arch in $ALLSOURCE_ARCHS
92 do
93 find_sources $arch '*.[chS]'
94 done
74 find_other_sources '*.[chS]' 95 find_other_sources '*.[chS]'
75} 96}
76 97
@@ -89,13 +110,7 @@ all_defconfigs()
89 110
90docscope() 111docscope()
91{ 112{
92 # always use absolute paths for cscope, as recommended by cscope 113 (echo \-k; echo \-q; all_sources) > cscope.files
93 # upstream
94 case "$tree" in
95 /*) ;;
96 *) tree=$PWD/$tree ;;
97 esac
98 (cd /; echo \-k; echo \-q; all_sources) > cscope.files
99 cscope -b -f cscope.out 114 cscope -b -f cscope.out
100} 115}
101 116