History

Merge commit 'v2.6.37-rc1' into kbuild/kbuild

Michal Marek committed 15 years ago

Commit 8990c1b2 parents 2979076 c8ddb2715045 files · +1541141 −1109449Browse files

Showing the changes to scripts (77 of 15045 files). Show all

Unified · Split

77 files
  1. scripts/Makefile +1 −0
  2. scripts/Makefile.build +12 −1
  3. scripts/Makefile.headersinst +1 −2
  4. scripts/Makefile.help +3 −0
  5. scripts/Makefile.lib +1 −10
  6. scripts/basic/Makefile +1 −1
  7. scripts/basic/docproc.c +131 −1
  8. scripts/basic/hash.c +0 −64
  9. scripts/checkkconfigsymbols.sh +1 −1
  10. scripts/checkpatch.pl +162 −32
  11. scripts/checksyscalls.sh +0 −1
  12. scripts/coccicheck +106 −0
  13. scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci +67 −0
  14. scripts/coccinelle/api/alloc/kzalloc-simple.cocci +86 −0
  15. scripts/coccinelle/api/err_cast.cocci +56 −0
  16. scripts/coccinelle/api/kstrdup.cocci +39 −0
  17. scripts/coccinelle/api/memdup.cocci +40 −0
  18. scripts/coccinelle/api/memdup_user.cocci +35 −0
  19. scripts/coccinelle/api/resource_size.cocci +93 −0
  20. scripts/coccinelle/free/kfree.cocci +117 −0
  21. scripts/coccinelle/iterators/fen.cocci +64 −0
  22. scripts/coccinelle/iterators/itnull.cocci +58 −0
  23. scripts/coccinelle/iterators/list_entry_update.cocci +62 −0
  24. scripts/coccinelle/locks/call_kern.cocci +74 −0
  25. scripts/coccinelle/locks/double_lock.cocci +92 −0
  26. scripts/coccinelle/locks/flags.cocci +80 −0
  27. scripts/coccinelle/locks/mini_lock.cocci +95 −0
  28. scripts/coccinelle/misc/doubleinit.cocci +53 −0
  29. scripts/coccinelle/misc/ifcol.cocci +48 −0
  30. scripts/coccinelle/null/deref_null.cocci +293 −0
  31. scripts/coccinelle/null/eno.cocci +20 −0
  32. scripts/coccinelle/null/kmerr.cocci +72 −0
  33. scripts/coccinelle/tests/doublebitand.cocci +54 −0
  34. scripts/coccinelle/tests/doubletest.cocci +40 −0
  35. scripts/decodecode +5 −5
  36. scripts/dtc/fstree.c +1 −0
  37. scripts/extract-ikconfig +27 −14
  38. scripts/gcc-goto.sh +5 −0
  39. scripts/get_maintainer.pl +948 −214
  40. scripts/kconfig/.gitignore +1 −0
  41. scripts/kconfig/Makefile +87 −77
  42. scripts/kconfig/conf.c +123 −84
  43. scripts/kconfig/confdata.c +285 −151
  44. scripts/kconfig/expr.c +2 −2
  45. scripts/kconfig/expr.h +3 −1
  46. scripts/kconfig/gconf.c +12 −15
  47. scripts/kconfig/gconf.glade +0 −1
  48. scripts/kconfig/kxgettext.c +9 −6
  49. scripts/kconfig/lex.zconf.c_shipped +4 −3
  50. scripts/kconfig/lkc.h +19 −1
  51. scripts/kconfig/lkc_proto.h +4 −0
  52. scripts/kconfig/lxdialog/check-lxdialog.sh +2 −0
  53. scripts/kconfig/lxdialog/checklist.c +8 −2
  54. scripts/kconfig/mconf.c +30 −36
  55. scripts/kconfig/menu.c +24 −6
  56. scripts/kconfig/nconf.c +239 −250
  57. scripts/kconfig/nconf.gui.c +11 −11
  58. scripts/kconfig/nconf.h +2 −1
  59. scripts/kconfig/qconf.cc +149 −125
  60. scripts/kconfig/qconf.h +48 −45
  61. scripts/kconfig/streamline_config.pl +36 −7
  62. scripts/kconfig/symbol.c +310 −33
  63. scripts/kconfig/util.c +5 −2
  64. scripts/kconfig/zconf.l +4 −3
  65. scripts/kconfig/zconf.tab.c_shipped +283 −264
  66. scripts/kconfig/zconf.y +15 −3
  67. scripts/kernel-doc +53 −3
  68. scripts/mkmakefile +3 −1
  69. scripts/mod/modpost.c +57 −16
  70. scripts/namespace.pl +81 −66
  71. scripts/package/Makefile +31 −6
  72. scripts/package/builddeb +6 −3
  73. scripts/package/mkspec +1 −1
  74. scripts/recordmcount.c +407 −0
  75. scripts/recordmcount.h +442 −0
  76. scripts/recordmcount.pl +9 −2
  77. scripts/setlocalversion +2 −2
scripts/Makefile+1−0
@@ -11,6 +11,7 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms · 10 unmodified lines
1111 hostprogs-$(CONFIG_LOGO) += pnmtologo
1212 hostprogs-$(CONFIG_VT) += conmakehash
1313 hostprogs-$(CONFIG_IKCONFIG) += bin2c
14+hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
1415
1516 always := $(hostprogs-y) $(hostprogs-m)
1617
scripts/Makefile.build+12−1
@@ -209,12 +209,23 @@ cmd_modversions = \ · 208 unmodified lines
209209 endif
210210
211211 ifdef CONFIG_FTRACE_MCOUNT_RECORD
212+ifdef BUILD_C_RECORDMCOUNT
213+# Due to recursion, we must skip empty.o.
214+# The empty.o file is created in the make process in order to determine
215+# the target endianness and word size. It is made before all other C
216+# files, including recordmcount.
217+cmd_record_mcount = if [ $(@) != "scripts/mod/empty.o" ]; then \
218+ $(objtree)/scripts/recordmcount "$(@)"; \
219+ fi;
220+else
212221 cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
213222 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
214223 "$(if $(CONFIG_64BIT),64,32)" \
215− "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
224+ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
225+ "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
216226 "$(if $(part-of-module),1,0)" "$(@)";
217227 endif
228+endif
218229
219230 define rule_cc_o_c
220231 $(call echo-cmd,checksrc) $(cmd_checksrc) \
scripts/Makefile.headersinst+1−2
@@ -3,7 +3,6 @@ · 2 unmodified lines
33 #
44 # header-y - list files to be installed. They are preprocessed
55 # to remove __KERNEL__ section of the file
6−# unifdef-y - Same as header-y. Obsolete
76 # objhdr-y - Same as header-y but for generated files
87 #
98 # ==========================================================================
@@ -20,7 +19,7 @@ include scripts/Kbuild.include · 10 unmodified lines
2019
2120 install := $(INSTALL_HDR_PATH)/$(_dst)
2221
23−header-y := $(sort $(header-y) $(unifdef-y))
22+header-y := $(sort $(header-y))
2423 subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
2524 header-y := $(filter-out %/, $(header-y))
2625
scripts/Makefile.help+3−0
@@ -0,0 +1,3 @@
1+
2+checker-help:
3+ @echo ' coccicheck - Check with Coccinelle.'
scripts/Makefile.lib+1−10
@@ -101,14 +101,6 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" · 100 unmodified lines
101101 modname_flags = $(if $(filter 1,$(words $(modname))),\
102102 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
103103
104−#hash values
105−ifdef CONFIG_DYNAMIC_DEBUG
106−debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
107− -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
108−else
109−debug_flags =
110−endif
111−
112104 orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
113105 $(ccflags-y) $(CFLAGS_$(basetarget).o)
114106 _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
@@ -154,8 +146,7 @@ endif · 39 unmodified lines
154146
155147 c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
156148 $(__c_flags) $(modkern_cflags) \
157− -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
158− $(debug_flags)
149+ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
159150
160151 a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
161152 $(__a_flags) $(modkern_aflags)
scripts/basic/Makefile+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
99 # fixdep: Used to generate dependency information during build process
1010 # docproc: Used in Documentation/DocBook
1111
12−hostprogs-y := fixdep docproc hash
12+hostprogs-y := fixdep docproc
1313 always := $(hostprogs-y)
1414
1515 # fixdep is needed to compile other host programs
scripts/basic/docproc.c+131−1
@@ -34,12 +34,14 @@ · 33 unmodified lines
3434 *
3535 */
3636
37+#define _GNU_SOURCE
3738 #include <stdio.h>
3839 #include <stdlib.h>
3940 #include <string.h>
4041 #include <ctype.h>
4142 #include <unistd.h>
4243 #include <limits.h>
44+#include <errno.h>
4345 #include <sys/types.h>
4446 #include <sys/wait.h>
4547
@@ -54,6 +56,7 @@ typedef void FILEONLY(char * file); · 8 unmodified lines
5456 FILEONLY *internalfunctions;
5557 FILEONLY *externalfunctions;
5658 FILEONLY *symbolsonly;
59+FILEONLY *findall;
5760
5861 typedef void FILELINE(char * file, char * line);
5962 FILELINE * singlefunctions;
@@ -65,12 +68,30 @@ FILELINE * docsection; · 5 unmodified lines
6568 #define KERNELDOCPATH "scripts/"
6669 #define KERNELDOC "kernel-doc"
6770 #define DOCBOOK "-docbook"
71+#define LIST "-list"
6872 #define FUNCTION "-function"
6973 #define NOFUNCTION "-nofunction"
7074 #define NODOCSECTIONS "-no-doc-sections"
7175
7276 static char *srctree, *kernsrctree;
7377
78+static char **all_list = NULL;
79+static int all_list_len = 0;
80+
81+static void consume_symbol(const char *sym)
82+{
83+ int i;
84+
85+ for (i = 0; i < all_list_len; i++) {
86+ if (!all_list[i])
87+ continue;
88+ if (strcmp(sym, all_list[i]))
89+ continue;
90+ all_list[i] = NULL;
91+ break;
92+ }
93+}
94+
7495 static void usage (void)
7596 {
7697 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
@@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type) · 171 unmodified lines
248269 struct symfile * sym = &symfilelist[i];
249270 for (j=0; j < sym->symbolcnt; j++) {
250271 vec[idx++] = type;
272+ consume_symbol(sym->symbollist[j].name);
251273 vec[idx++] = sym->symbollist[j].name;
252274 }
253275 }
@@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line) · 33 unmodified lines
287309 vec[idx++] = &line[i];
288310 }
289311 }
312+ for (i = 0; i < idx; i++) {
313+ if (strcmp(vec[i], FUNCTION))
314+ continue;
315+ consume_symbol(vec[i + 1]);
316+ }
290317 vec[idx++] = filename;
291318 vec[idx] = NULL;
292319 exec_kernel_doc(vec);
@@ -306,6 +333,13 @@ static void docsect(char *filename, char *line) · 13 unmodified lines
306333 if (*s == '\n')
307334 *s = '\0';
308335
336+ if (asprintf(&s, "DOC: %s", line) < 0) {
337+ perror("asprintf");
338+ exit(1);
339+ }
340+ consume_symbol(s);
341+ free(s);
342+
309343 vec[0] = KERNELDOC;
310344 vec[1] = DOCBOOK;
311345 vec[2] = FUNCTION;
@@ -315,6 +349,84 @@ static void docsect(char *filename, char *line) · 3 unmodified lines
315349 exec_kernel_doc(vec);
316350 }
317351
352+static void find_all_symbols(char *filename)
353+{
354+ char *vec[4]; /* kerneldoc -list file NULL */
355+ pid_t pid;
356+ int ret, i, count, start;
357+ char real_filename[PATH_MAX + 1];
358+ int pipefd[2];
359+ char *data, *str;
360+ size_t data_len = 0;
361+
362+ vec[0] = KERNELDOC;
363+ vec[1] = LIST;
364+ vec[2] = filename;
365+ vec[3] = NULL;
366+
367+ if (pipe(pipefd)) {
368+ perror("pipe");
369+ exit(1);
370+ }
371+
372+ switch (pid=fork()) {
373+ case -1:
374+ perror("fork");
375+ exit(1);
376+ case 0:
377+ close(pipefd[0]);
378+ dup2(pipefd[1], 1);
379+ memset(real_filename, 0, sizeof(real_filename));
380+ strncat(real_filename, kernsrctree, PATH_MAX);
381+ strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
382+ PATH_MAX - strlen(real_filename));
383+ execvp(real_filename, vec);
384+ fprintf(stderr, "exec ");
385+ perror(real_filename);
386+ exit(1);
387+ default:
388+ close(pipefd[1]);
389+ data = malloc(4096);
390+ do {
391+ while ((ret = read(pipefd[0],
392+ data + data_len,
393+ 4096)) > 0) {
394+ data_len += ret;
395+ data = realloc(data, data_len + 4096);
396+ }
397+ } while (ret == -EAGAIN);
398+ if (ret != 0) {
399+ perror("read");
400+ exit(1);
401+ }
402+ waitpid(pid, &ret ,0);
403+ }
404+ if (WIFEXITED(ret))
405+ exitstatus |= WEXITSTATUS(ret);
406+ else
407+ exitstatus = 0xff;
408+
409+ count = 0;
410+ /* poor man's strtok, but with counting */
411+ for (i = 0; i < data_len; i++) {
412+ if (data[i] == '\n') {
413+ count++;
414+ data[i] = '\0';
415+ }
416+ }
417+ start = all_list_len;
418+ all_list_len += count;
419+ all_list = realloc(all_list, sizeof(char *) * all_list_len);
420+ str = data;
421+ for (i = 0; i < data_len && start != all_list_len; i++) {
422+ if (data[i] == '\0') {
423+ all_list[start] = str;
424+ str = data + i + 1;
425+ start++;
426+ }
427+ }
428+}
429+
318430 /*
319431 * Parse file, calling action specific functions for:
320432 * 1) Lines containing !E
@@ -322,7 +434,8 @@ static void docsect(char *filename, char *line) · 1 unmodified line
322434 * 3) Lines containing !D
323435 * 4) Lines containing !F
324436 * 5) Lines containing !P
325− * 6) Default lines - lines not matching the above
437+ * 6) Lines containing !C
438+ * 7) Default lines - lines not matching the above
326439 */
327440 static void parse_file(FILE *infile)
328441 {
@@ -365,6 +478,12 @@ static void parse_file(FILE *infile) · 36 unmodified lines
365478 s++;
366479 docsection(line + 2, s);
367480 break;
481+ case 'C':
482+ while (*s && !isspace(*s)) s++;
483+ *s = '\0';
484+ if (findall)
485+ findall(line+2);
486+ break;
368487 default:
369488 defaultline(line);
370489 }
@@ -380,6 +499,7 @@ static void parse_file(FILE *infile) · 9 unmodified lines
380499 int main(int argc, char *argv[])
381500 {
382501 FILE * infile;
502+ int i;
383503
384504 srctree = getenv("SRCTREE");
385505 if (!srctree)
@@ -415,6 +535,7 @@ int main(int argc, char *argv[]) · 29 unmodified lines
415535 symbolsonly = find_export_symbols;
416536 singlefunctions = noaction2;
417537 docsection = noaction2;
538+ findall = find_all_symbols;
418539 parse_file(infile);
419540
420541 /* Rewind to start from beginning of file again */
@@ -425,8 +546,16 @@ int main(int argc, char *argv[]) · 4 unmodified lines
425546 symbolsonly = printline;
426547 singlefunctions = singfunc;
427548 docsection = docsect;
549+ findall = NULL;
428550
429551 parse_file(infile);
552+
553+ for (i = 0; i < all_list_len; i++) {
554+ if (!all_list[i])
555+ continue;
556+ fprintf(stderr, "Warning: didn't use docs for %s\n",
557+ all_list[i]);
558+ }
430559 }
431560 else if (strcmp("depend", argv[1]) == 0)
432561 {
@@ -439,6 +568,7 @@ int main(int argc, char *argv[]) · 6 unmodified lines
439568 symbolsonly = adddep;
440569 singlefunctions = adddep2;
441570 docsection = adddep2;
571+ findall = adddep;
442572 parse_file(infile);
443573 printf("\n");
444574 }
scripts/basic/hash.c+0−64
@@ -1,64 +0,0 @@
1−/*
2− * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
3− *
4− */
5−
6−#include <stdio.h>
7−#include <stdlib.h>
8−#include <string.h>
9−
10−#define DYNAMIC_DEBUG_HASH_BITS 6
11−
12−static const char *program;
13−
14−static void usage(void)
15−{
16− printf("Usage: %s <djb2|r5> <modname>\n", program);
17− exit(1);
18−}
19−
20−/* djb2 hashing algorithm by Dan Bernstein. From:
21− * http://www.cse.yorku.ca/~oz/hash.html
22− */
23−
24−static unsigned int djb2_hash(char *str)
25−{
26− unsigned long hash = 5381;
27− int c;
28−
29− c = *str;
30− while (c) {
31− hash = ((hash << 5) + hash) + c;
32− c = *++str;
33− }
34− return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
35−}
36−
37−static unsigned int r5_hash(char *str)
38−{
39− unsigned long hash = 0;
40− int c;
41−
42− c = *str;
43− while (c) {
44− hash = (hash + (c << 4) + (c >> 4)) * 11;
45− c = *++str;
46− }
47− return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
48−}
49−
50−int main(int argc, char *argv[])
51−{
52− program = argv[0];
53−
54− if (argc != 3)
55− usage();
56− if (!strcmp(argv[1], "djb2"))
57− printf("%d\n", djb2_hash(argv[2]));
58− else if (!strcmp(argv[1], "r5"))
59− printf("%d\n", r5_hash(argv[2]));
60− else
61− usage();
62− exit(0);
63−}
64−
scripts/checkkconfigsymbols.sh+1−1
@@ -14,7 +14,7 @@ find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while · 13 unmodified lines
1414 do
1515 # Output the bare Kconfig variable and the filename; the _MODULE part at
1616 # 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
1818 done | \
1919 # Smart "sort|uniq" implemented in awk and tuned to collect the names of all
2020 # files which use a given symbol
scripts/checkpatch.pl+162−32
@@ -2,7 +2,7 @@ · 1 unmodified line
22 # (c) 2001, Dave Jones. (the file handling bit)
33 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
44 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5−# (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
5+# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
66 # Licensed under the terms of the GNU GPL License version 2
77
88 use strict;
@@ -10,7 +10,7 @@ use strict; · 1 unmodified line
1010 my $P = $0;
1111 $P =~ s@.*/@@g;
1212
13−my $V = '0.30';
13+my $V = '0.31';
1414
1515 use Getopt::Long qw(:config no_auto_abbrev);
1616
@@ -103,6 +103,8 @@ for my $key (keys %debug) { · 86 unmodified lines
103103 die "$@" if ($@);
104104 }
105105
106+my $rpt_cleaners = 0;
107+
106108 if ($terse) {
107109 $emacs = 1;
108110 $quiet++;
@@ -150,6 +152,20 @@ our $Sparse = qr{ · 41 unmodified lines
150152 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
151153 our $Attribute = qr{
152154 const|
155+ __percpu|
156+ __nocast|
157+ __safe|
158+ __bitwise__|
159+ __packed__|
160+ __packed2__|
161+ __naked|
162+ __maybe_unused|
163+ __always_unused|
164+ __noreturn|
165+ __used|
166+ __cold|
167+ __noclone|
168+ __deprecated|
153169 __read_mostly|
154170 __kprobes|
155171 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
@@ -195,7 +211,7 @@ our $typeTypedefs = qr{(?x: · 39 unmodified lines
195211 our $logFunctions = qr{(?x:
196212 printk|
197213 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)|
214+ (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
199215 WARN|
200216 panic
201217 )};
@@ -224,6 +240,12 @@ our @modifierList = ( · 22 unmodified lines
224240 qr{fastcall},
225241 );
226242
243+our $allowed_asm_includes = qr{(?x:
244+ irq|
245+ memory
246+)};
247+# memory.h: ARM has a custom one
248+
227249 sub build_types {
228250 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
229251 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
@@ -552,6 +574,9 @@ sub ctx_statement_block { · 322 unmodified lines
552574 $type = ($level != 0)? '{' : '';
553575
554576 if ($level == 0) {
577+ if (substr($blk, $off + 1, 1) eq ';') {
578+ $off++;
579+ }
555580 last;
556581 }
557582 }
@@ -666,15 +691,15 @@ sub ctx_block_get { · 108 unmodified lines
666691 $blk .= $rawlines[$line];
667692
668693 # Handle nested #if/#else.
669− if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
694+ if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
670695 push(@stack, $level);
671− } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
696+ } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
672697 $level = $stack[$#stack - 1];
673− } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
698+ } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
674699 $level = pop(@stack);
675700 }
676701
677− foreach my $c (split(//, $rawlines[$line])) {
702+ foreach my $c (split(//, $lines[$line])) {
678703 ##print "C<$c>L<$level><$open$close>O<$off>\n";
679704 if ($off > 0) {
680705 $off--;
@@ -834,7 +859,12 @@ sub annotate_values { · 153 unmodified lines
834859 $av_preprocessor = 0;
835860 }
836861
837− } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\()/) {
862+ } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) {
863+ print "CAST($1)\n" if ($dbg_values > 1);
864+ push(@av_paren_type, $type);
865+ $type = 'C';
866+
867+ } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
838868 print "DECLARE($1)\n" if ($dbg_values > 1);
839869 $type = 'T';
840870
@@ -1299,7 +1329,11 @@ sub process { · 458 unmodified lines
12991329 $here = "#$realline: " if ($file);
13001330
13011331 # extract the filename as it passes
1302− if ($line=~/^\+\+\+\s+(\S+)/) {
1332+ if ($line =~ /^diff --git.*?(\S+)$/) {
1333+ $realfile = $1;
1334+ $realfile =~ s@^([^/]*)/@@;
1335+
1336+ } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
13031337 $realfile = $1;
13041338 $realfile =~ s@^([^/]*)/@@;
13051339
@@ -1323,6 +1357,14 @@ sub process { · 17 unmodified lines
13231357
13241358 $cnt_lines++ if ($realcnt != 0);
13251359
1360+# Check for incorrect file permissions
1361+ if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
1362+ my $permhere = $here . "FILE: $realfile\n";
1363+ if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) {
1364+ ERROR("do not set execute permissions for source files\n" . $permhere);
1365+ }
1366+ }
1367+
13261368 #check the patch for a signoff:
13271369 if ($line =~ /^\s*signed-off-by:/i) {
13281370 # This is a signoff, if ugly, so do not double report.
@@ -1380,21 +1422,38 @@ sub process { · 51 unmodified lines
13801422 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
13811423 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
13821424 ERROR("trailing whitespace\n" . $herevet);
1425+ $rpt_cleaners = 1;
13831426 }
13841427
13851428 # check for Kconfig help text having a real description
1429+# Only applies when adding the entry originally, after that we do not have
1430+# sufficient context to determine whether it is indeed long enough.
13861431 if ($realfile =~ /Kconfig/ &&
1387− $line =~ /\+?\s*(---)?help(---)?$/) {
1432+ $line =~ /\+\s*(?:---)?help(?:---)?$/) {
13881433 my $length = 0;
1389− for (my $l = $linenr; defined($lines[$l]); $l++) {
1390− my $f = $lines[$l];
1434+ my $cnt = $realcnt;
1435+ my $ln = $linenr + 1;
1436+ my $f;
1437+ my $is_end = 0;
1438+ while ($cnt > 0 && defined $lines[$ln - 1]) {
1439+ $f = $lines[$ln - 1];
1440+ $cnt-- if ($lines[$ln - 1] !~ /^-/);
1441+ $is_end = $lines[$ln - 1] =~ /^\+/;
1442+ $ln++;
1443+
1444+ next if ($f =~ /^-/);
1445+ $f =~ s/^.//;
13911446 $f =~ s/#.*//;
13921447 $f =~ s/^\s+//;
13931448 next if ($f =~ /^$/);
1394− last if ($f =~ /^\s*config\s/);
1449+ if ($f =~ /^\s*config\s/) {
1450+ $is_end = 1;
1451+ last;
1452+ }
13951453 $length++;
13961454 }
1397− WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4);
1455+ WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4);
1456+ #print "is_end<$is_end> length<$length>\n";
13981457 }
13991458
14001459 # check we are in a valid source file if not then ignore this hunk
@@ -1403,7 +1462,8 @@ sub process { · 2 unmodified lines
14031462 #80 column limit
14041463 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
14051464 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
1406− $line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ &&
1465+ !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ ||
1466+ $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
14071467 $length > 80)
14081468 {
14091469 WARN("line over 80 characters\n" . $herecurr);
@@ -1440,6 +1500,7 @@ sub process { · 30 unmodified lines
14401500 $rawline =~ /^\+\s* \s*/) {
14411501 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
14421502 ERROR("code indent should use tabs where possible\n" . $herevet);
1503+ $rpt_cleaners = 1;
14431504 }
14441505
14451506 # check for space before tabs.
@@ -1448,6 +1509,16 @@ sub process { · 2 unmodified lines
14481509 WARN("please, no space before tabs\n" . $herevet);
14491510 }
14501511
1512+# check for spaces at the beginning of a line.
1513+# Exceptions:
1514+# 1) within comments
1515+# 2) indented preprocessor commands
1516+# 3) hanging labels
1517+ if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) {
1518+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1519+ WARN("please, no spaces at the start of a line\n" . $herevet);
1520+ }
1521+
14511522 # check we are in a valid C source file if not then ignore this hunk
14521523 next if ($realfile !~ /\.(h|c)$/);
14531524
@@ -1581,7 +1652,7 @@ sub process { · 127 unmodified lines
15811652
15821653 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
15831654 ERROR("that open brace { should be on the previous line\n" .
1584− "$here\n$ctx\n$lines[$ctx_ln - 1]\n");
1655+ "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
15851656 }
15861657 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
15871658 $ctx =~ /\)\s*\;\s*$/ &&
@@ -1590,7 +1661,7 @@ sub process { · 2 unmodified lines
15901661 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
15911662 if ($nindent > $indent) {
15921663 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
1593− "$here\n$ctx\n$lines[$ctx_ln - 1]\n");
1664+ "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
15941665 }
15951666 }
15961667 }
@@ -1751,8 +1822,17 @@ sub process { · 154 unmodified lines
17511822 !defined $suppress_export{$realline_next} &&
17521823 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
17531824 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1825+ # Handle definitions which produce identifiers with
1826+ # a prefix:
1827+ # XXX(foo);
1828+ # EXPORT_SYMBOL(something_foo);
17541829 my $name = $1;
1755− if ($stat !~ /(?:
1830+ if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ &&
1831+ $name =~ /^${Ident}_$2/) {
1832+#print "FOO C name<$name>\n";
1833+ $suppress_export{$realline_next} = 1;
1834+
1835+ } elsif ($stat !~ /(?:
17561836 \n.}\s*$|
17571837 ^.DEFINE_$Ident\(\Q$name\E\)|
17581838 ^.DECLARE_$Ident\(\Q$name\E\)|
@@ -1778,9 +1858,9 @@ sub process { · 19 unmodified lines
17781858 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
17791859 }
17801860
1781−# check for external initialisers.
1861+# check for global initialisers.
17821862 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
1783− ERROR("do not initialise externals to 0 or NULL\n" .
1863+ ERROR("do not initialise globals to 0 or NULL\n" .
17841864 $herecurr);
17851865 }
17861866 # check for static initialisers.
@@ -1789,6 +1869,23 @@ sub process { · 2 unmodified lines
17891869 $herecurr);
17901870 }
17911871
1872+# check for static const char * arrays.
1873+ if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
1874+ WARN("static const char * array should probably be static const char * const\n" .
1875+ $herecurr);
1876+ }
1877+
1878+# check for static char foo[] = "bar" declarations.
1879+ if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
1880+ WARN("static char array declaration should probably be static const char\n" .
1881+ $herecurr);
1882+ }
1883+
1884+# check for declarations of struct pci_device_id
1885+ if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
1886+ WARN("Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
1887+ }
1888+
17921889 # check for new typedefs, only function parameters and sparse annotations
17931890 # make sense.
17941891 if ($line =~ /\btypedef\s/ &&
@@ -1882,6 +1979,11 @@ sub process { · 87 unmodified lines
18821979 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
18831980 }
18841981
1982+# missing space after union, struct or enum definition
1983+ if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {
1984+ WARN("missing space after $1 definition\n" . $herecurr);
1985+ }
1986+
18851987 # check for spacing round square brackets; allowed:
18861988 # 1. with a type on the left -- int [] a;
18871989 # 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
@@ -2159,21 +2261,29 @@ sub process { · 271 unmodified lines
21592261 my $value = $2;
21602262
21612263 # Flatten any parentheses
2162− $value =~ s/\)\(/\) \(/g;
2264+ $value =~ s/\(/ \(/g;
2265+ $value =~ s/\)/\) /g;
21632266 while ($value =~ s/\[[^\{\}]*\]/1/ ||
21642267 $value !~ /(?:$Ident|-?$Constant)\s*
21652268 $Compare\s*
21662269 (?:$Ident|-?$Constant)/x &&
21672270 $value =~ s/\([^\(\)]*\)/1/) {
21682271 }
2169−
2170− if ($value =~ /^(?:$Ident|-?$Constant)$/) {
2272+#print "value<$value>\n";
2273+ if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
21712274 ERROR("return is not a function, parentheses are not required\n" . $herecurr);
21722275
21732276 } elsif ($spacing !~ /\s+/) {
21742277 ERROR("space required before the open parenthesis '('\n" . $herecurr);
21752278 }
21762279 }
2280+# Return of what appears to be an errno should normally be -'ve
2281+ if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
2282+ my $name = $1;
2283+ if ($name ne 'EOF' && $name ne 'ERROR') {
2284+ WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr);
2285+ }
2286+ }
21772287
21782288 # Need a space before open parenthesis after if, while etc
21792289 if ($line=~/\b(if|while|for|switch)\(/) {
@@ -2308,7 +2418,7 @@ sub process { · 128 unmodified lines
23082418 my $checkfile = "include/linux/$file";
23092419 if (-f "$root/$checkfile" &&
23102420 $realfile ne $checkfile &&
2311− $1 ne 'irq')
2421+ $1 !~ /$allowed_asm_includes/)
23122422 {
23132423 if ($realfile =~ m{^arch/}) {
23142424 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
@@ -2392,8 +2502,8 @@ sub process { · 77 unmodified lines
23922502 \.$Ident\s*=\s*|
23932503 ^\"|\"$
23942504 }x;
2395− #print "REST<$rest> dstat<$dstat>\n";
2396− if ($rest ne '') {
2505+ #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
2506+ if ($rest ne '' && $rest ne ',') {
23972507 if ($rest !~ /while\s*\(/ &&
23982508 $dstat !~ /$exceptions/)
23992509 {
@@ -2570,6 +2680,21 @@ sub process { · 170 unmodified lines
25702680 }
25712681 }
25722682
2683+# prefer usleep_range over udelay
2684+ if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
2685+ # ignore udelay's < 10, however
2686+ if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
2687+ CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
2688+ }
2689+ }
2690+
2691+# warn about unexpectedly long msleep's
2692+ if ($line =~ /\bmsleep\s*\((\d+)\);/) {
2693+ if ($1 < 20) {
2694+ WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
2695+ }
2696+ }
2697+
25732698 # warn about #ifdefs in C files
25742699 # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
25752700 # print "#ifdef in C files should be avoided\n";
@@ -2669,12 +2794,8 @@ sub process { · 93 unmodified lines
26692794 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
26702795 }
26712796
2672−# check for semaphores used as mutexes
2673− if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
2674− WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
2675− }
2676−# check for semaphores used as mutexes
2677− if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
2797+# check for semaphores initialized locked
2798+ if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
26782799 WARN("consider using a completion\n" . $herecurr);
26792800
26802801 }
@@ -2807,6 +2928,15 @@ sub process { · 126 unmodified lines
28072928 print "\n" if ($quiet == 0);
28082929 }
28092930
2931+ if ($quiet == 0) {
2932+ # If there were whitespace errors which cleanpatch can fix
2933+ # then suggest that.
2934+ if ($rpt_cleaners) {
2935+ print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
2936+ print " scripts/cleanfile\n\n";
2937+ }
2938+ }
2939+
28102940 if ($clean == 1 && $quiet == 0) {
28112941 print "$vname has no obvious style problems and is ready for submission.\n"
28122942 }
scripts/checksyscalls.sh+0−1
@@ -183,7 +183,6 @@ cat << EOF · 182 unmodified lines
183183 #define __IGNORE_ustat /* statfs */
184184 #define __IGNORE_utime /* utimes */
185185 #define __IGNORE_vfork /* clone */
186−#define __IGNORE_wait4 /* waitid */
187186
188187 /* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */
189188 #ifdef __NR_sync_file_range2
scripts/coccicheck+106−0
@@ -0,0 +1,106 @@
1+#!/bin/sh
2+
3+SPATCH="`which ${SPATCH:=spatch}`"
4+
5+if [ "$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
16+else
17+ ONLINE=0
18+ FLAGS="-very_quiet"
19+ OPTIONS="-dir $srctree"
20+fi
21+
22+if [ ! -x "$SPATCH" ]; then
23+ echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
24+ exit 1
25+fi
26+
27+if [ "$MODE" = "" ] ; then
28+ if [ "$ONLINE" = "0" ] ; then
29+ echo 'You have not explicitly specified the mode to use. Using default "chain" mode.'
30+ echo 'All available modes will be tried (in that order): patch, report, context, org'
31+ echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
32+ fi
33+ MODE="chain"
34+elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
35+ FLAGS="$FLAGS -no_show_diff"
36+fi
37+
38+if [ "$ONLINE" = "0" ] ; then
39+ echo ''
40+ echo 'Please check for false positives in the output before submitting a patch.'
41+ echo 'When using "patch" mode, carefully review the patch before submitting it.'
42+ echo ''
43+fi
44+
45+coccinelle () {
46+ COCCI="$1"
47+
48+ OPT=`grep "Option" $COCCI | cut -d':' -f2`
49+
50+# The option '-parse_cocci' can be used to syntactically check the SmPL files.
51+#
52+# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
53+
54+ if [ "$ONLINE" = "0" ] ; then
55+
56+ FILE=`echo $COCCI | sed "s|$srctree/||"`
57+
58+ echo "Processing `basename $COCCI`"
59+ echo "with option(s) \"$OPT\""
60+ echo ''
61+ echo 'Message example to submit a patch:'
62+
63+ sed -ne 's|^///||p' $COCCI
64+
65+ if [ "$MODE" = "patch" ] ; then
66+ echo ' The semantic patch that makes this change is available'
67+ elif [ "$MODE" = "report" ] ; then
68+ echo ' The semantic patch that makes this report is available'
69+ elif [ "$MODE" = "context" ] ; then
70+ echo ' The semantic patch that spots this code is available'
71+ elif [ "$MODE" = "org" ] ; then
72+ echo ' The semantic patch that makes this Org report is available'
73+ else
74+ echo ' The semantic patch that makes this output is available'
75+ fi
76+ echo " in $FILE."
77+ echo ''
78+ echo ' More information about semantic patching is available at'
79+ echo ' http://coccinelle.lip6.fr/'
80+ echo ''
81+
82+ if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
83+ echo 'Semantic patch information:'
84+ sed -ne 's|^//#||p' $COCCI
85+ echo ''
86+ fi
87+ fi
88+
89+ if [ "$MODE" = "chain" ] ; then
90+ $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
91+ $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \
92+ $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
93+ $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1
94+ else
95+ $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
96+ fi
97+
98+}
99+
100+if [ "$COCCI" = "" ] ; then
101+ for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
102+ coccinelle $f
103+ done
104+else
105+ coccinelle $COCCI
106+fi
scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci+67−0
@@ -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+
16+virtual context
17+virtual patch
18+virtual org
19+virtual report
20+
21+//----------------------------------------------------------
22+// For context mode
23+//----------------------------------------------------------
24+
25+@depends on context@
26+type T;
27+@@
28+
29+* (T *)
30+ \(kmalloc\|kzalloc\|kcalloc\)(...)
31+
32+//----------------------------------------------------------
33+// For patch mode
34+//----------------------------------------------------------
35+
36+@depends on patch@
37+type 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@
48+type T;
49+position p;
50+@@
51+
52+ (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
53+
54+@script:python depends on org@
55+p << r.p;
56+t << r.T;
57+@@
58+
59+coccilib.org.print_safe_todo(p[0], t)
60+
61+@script:python depends on report@
62+p << r.p;
63+t << r.T;
64+@@
65+
66+msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
67+coccilib.report.print_report(p[0], msg)
scripts/coccinelle/api/alloc/kzalloc-simple.cocci+86−0
@@ -0,0 +1,86 @@
1+///
2+/// Use kzalloc rather than kmalloc followed by memset with 0
3+///
4+/// This considers some simple cases that are common and easy to validate
5+/// Note in particular that there are no ...s in the rule, so all of the
6+/// matched code has to be contiguous
7+///
8+// Confidence: High
9+// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
10+// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
11+// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
12+// Options: -no_includes -include_headers
13+//
14+// Keywords: kmalloc, kzalloc
15+// Version min: < 2.6.12 kmalloc
16+// Version min: 2.6.14 kzalloc
17+//
18+
19+virtual context
20+virtual patch
21+virtual org
22+virtual report
23+
24+//----------------------------------------------------------
25+// For context mode
26+//----------------------------------------------------------
27+
28+@depends on context@
29+type T, T2;
30+expression x;
31+expression E1,E2;
32+statement S;
33+@@
34+
35+* x = (T)kmalloc(E1,E2);
36+ if ((x==NULL) || ...) S
37+* memset((T2)x,0,E1);
38+
39+//----------------------------------------------------------
40+// For patch mode
41+//----------------------------------------------------------
42+
43+@depends on patch@
44+type T, T2;
45+expression x;
46+expression E1,E2;
47+statement S;
48+@@
49+
50+- x = (T)kmalloc(E1,E2);
51++ x = kzalloc(E1,E2);
52+ if ((x==NULL) || ...) S
53+- memset((T2)x,0,E1);
54+
55+//----------------------------------------------------------
56+// For org mode
57+//----------------------------------------------------------
58+
59+@r depends on org || report@
60+type T, T2;
61+expression x;
62+expression E1,E2;
63+statement S;
64+position p;
65+@@
66+
67+ x = (T)kmalloc@p(E1,E2);
68+ if ((x==NULL) || ...) S
69+ memset((T2)x,0,E1);
70+
71+@script:python depends on org@
72+p << r.p;
73+x << r.x;
74+@@
75+
76+msg="%s" % (x)
77+msg_safe=msg.replace("[","@(").replace("]",")")
78+coccilib.org.print_todo(p[0], msg_safe)
79+
80+@script:python depends on report@
81+p << r.p;
82+x << r.x;
83+@@
84+
85+msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
86+coccilib.report.print_report(p[0], msg)
scripts/coccinelle/api/err_cast.cocci+56−0
@@ -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+
15+virtual context
16+virtual patch
17+virtual org
18+virtual report
19+
20+
21+@ depends on context && !patch && !org && !report@
22+expression x;
23+@@
24+
25+* ERR_PTR(PTR_ERR(x))
26+
27+@ depends on !context && patch && !org && !report @
28+expression x;
29+@@
30+
31+- ERR_PTR(PTR_ERR(x))
32++ ERR_CAST(x)
33+
34+@r depends on !context && !patch && (org || report)@
35+expression x;
36+position p;
37+@@
38+
39+ ERR_PTR@p(PTR_ERR(x))
40+
41+@script:python depends on org@
42+p << r.p;
43+x << r.x;
44+@@
45+
46+msg="WARNING ERR_CAST can be used with %s" % (x)
47+msg_safe=msg.replace("[","@(").replace("]",")")
48+coccilib.org.print_todo(p[0], msg_safe)
49+
50+@script:python depends on report@
51+p << r.p;
52+x << r.x;
53+@@
54+
55+msg="WARNING: ERR_CAST can be used with %s" % (x)
56+coccilib.report.print_report(p[0], msg)
scripts/coccinelle/api/kstrdup.cocci+39−0
@@ -0,0 +1,39 @@
1+/// Use kstrdup rather than duplicating its implementation
2+///
3+// Confidence: High
4+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7+// URL: http://coccinelle.lip6.fr/
8+// Comments:
9+// Options: -no_includes -include_headers
10+
11+virtual patch
12+
13+@@
14+expression from,to;
15+expression flag,E1,E2;
16+statement S;
17+@@
18+
19+- to = kmalloc(strlen(from) + 1,flag);
20++ to = kstrdup(from, flag);
21+ ... when != \(from = E1 \| to = E1 \)
22+ if (to==NULL || ...) S
23+ ... when != \(from = E2 \| to = E2 \)
24+- strcpy(to, from);
25+
26+@@
27+expression x,from,to;
28+expression flag,E1,E2,E3;
29+statement S;
30+@@
31+
32+- x = strlen(from) + 1;
33+ ... when != \( x = E1 \| from = E1 \)
34+- to = \(kmalloc\|kzalloc\)(x,flag);
35++ to = kstrdup(from, flag);
36+ ... when != \(x = E2 \| from = E2 \| to = E2 \)
37+ if (to==NULL || ...) S
38+ ... when != \(x = E3 \| from = E3 \| to = E3 \)
39+- memcpy(to, from, x);
scripts/coccinelle/api/memdup.cocci+40−0
@@ -0,0 +1,40 @@
1+/// Use kmemdup rather than duplicating its implementation
2+///
3+// Confidence: High
4+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7+// URL: http://coccinelle.lip6.fr/
8+// Comments:
9+// Options: -no_includes -include_headers
10+
11+virtual patch
12+
13+@r1@
14+expression from,to;
15+expression flag;
16+position p;
17+@@
18+
19+ to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
20+
21+@r2@
22+expression x,from,to;
23+expression flag,E1;
24+position p;
25+@@
26+
27+ x = strlen(from) + 1;
28+ ... when != \( x = E1 \| from = E1 \)
29+ to = \(kmalloc@p\|kzalloc@p\)(x,flag);
30+
31+@@
32+expression from,to,size,flag;
33+position p != {r1.p,r2.p};
34+statement S;
35+@@
36+
37+- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
38++ to = kmemdup(from,size,flag);
39+ if (to==NULL || ...) S
40+- memcpy(to, from, size);
scripts/coccinelle/api/memdup_user.cocci+35−0
@@ -0,0 +1,35 @@
1+/// Use kmemdup_user rather than duplicating its implementation
2+/// This is a little bit restricted to reduce false positives
3+///
4+// Confidence: High
5+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
6+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
7+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
8+// URL: http://coccinelle.lip6.fr/
9+// Comments:
10+// Options: -no_includes -include_headers
11+
12+virtual patch
13+
14+@@
15+expression from,to,size,flag;
16+position p;
17+identifier l1,l2;
18+@@
19+
20+- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
21++ to = memdup_user(from,size);
22+ if (
23+- to==NULL
24++ IS_ERR(to)
25+ || ...) {
26+ <+... when != goto l1;
27+- -ENOMEM
28++ PTR_ERR(to)
29+ ...+>
30+ }
31+- if (copy_from_user(to, from, size) != 0) {
32+- <+... when != goto l2;
33+- -EFAULT
34+- ...+>
35+- }
scripts/coccinelle/api/resource_size.cocci+93−0
@@ -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+
16+virtual context
17+virtual patch
18+virtual org
19+virtual report
20+
21+//----------------------------------------------------------
22+// For context mode
23+//----------------------------------------------------------
24+
25+@r_context depends on context && !patch && !org@
26+struct 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@
36+struct 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)@
48+struct resource *res;
49+position p;
50+@@
51+
52+ (res->end@p - res->start) + 1
53+
54+@rbad_org depends on !context && !patch && (org || report)@
55+struct resource *res;
56+position p != r_org.p;
57+@@
58+
59+ res->end@p - res->start
60+
61+@script:python depends on org@
62+p << r_org.p;
63+x << r_org.res;
64+@@
65+
66+msg="ERROR with %s" % (x)
67+msg_safe=msg.replace("[","@(").replace("]",")")
68+coccilib.org.print_todo(p[0], msg_safe)
69+
70+@script:python depends on report@
71+p << r_org.p;
72+x << r_org.res;
73+@@
74+
75+msg="ERROR: Missing resource_size with %s" % (x)
76+coccilib.report.print_report(p[0], msg)
77+
78+@script:python depends on org@
79+p << rbad_org.p;
80+x << rbad_org.res;
81+@@
82+
83+msg="WARNING with %s" % (x)
84+msg_safe=msg.replace("[","@(").replace("]",")")
85+coccilib.org.print_todo(p[0], msg_safe)
86+
87+@script:python depends on report@
88+p << rbad_org.p;
89+x << rbad_org.res;
90+@@
91+
92+msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
93+coccilib.report.print_report(p[0], msg)
scripts/coccinelle/free/kfree.cocci+117−0
@@ -0,0 +1,117 @@
1+/// Find a use after free.
2+//# Values of variables may imply that some
3+//# execution paths are not possible, resulting in false positives.
4+//# Another source of false positives are macros such as
5+//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
6+///
7+// Confidence: Moderate
8+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11+// URL: http://coccinelle.lip6.fr/
12+// Comments:
13+// Options: -no_includes -include_headers
14+
15+virtual org
16+virtual report
17+
18+@free@
19+expression E;
20+position p1;
21+@@
22+
23+kfree@p1(E)
24+
25+@print expression@
26+constant char *c;
27+expression free.E,E2;
28+type T;
29+position p;
30+identifier f;
31+@@
32+
33+(
34+ f(...,c,...,(T)E@p,...)
35+|
36+ E@p == E2
37+|
38+ E@p != E2
39+|
40+ !E@p
41+|
42+ E@p || ...
43+)
44+
45+@sz@
46+expression free.E;
47+position p;
48+@@
49+
50+ sizeof(<+...E@p...+>)
51+
52+@loop exists@
53+expression E;
54+identifier l;
55+position ok;
56+@@
57+
58+while (1) { ...
59+ kfree@ok(E)
60+ ... when != break;
61+ when != goto l;
62+ when forall
63+}
64+
65+@r exists@
66+expression free.E, subE<=free.E, E2;
67+expression E1;
68+iterator iter;
69+statement S;
70+position free.p1!=loop.ok,p2!={print.p,sz.p};
71+@@
72+
73+kfree@p1(E,...)
74+...
75+(
76+ iter(...,subE,...) S // no use
77+|
78+ list_remove_head(E1,subE,...)
79+|
80+ subE = E2
81+|
82+ subE++
83+|
84+ ++subE
85+|
86+ --subE
87+|
88+ subE--
89+|
90+ &subE
91+|
92+ BUG(...)
93+|
94+ BUG_ON(...)
95+|
96+ return_VALUE(...)
97+|
98+ return_ACPI_STATUS(...)
99+|
100+ E@p2 // bad use
101+)
102+
103+@script:python depends on org@
104+p1 << free.p1;
105+p2 << r.p2;
106+@@
107+
108+cocci.print_main("kfree",p1)
109+cocci.print_secs("ref",p2)
110+
111+@script:python depends on report@
112+p1 << free.p1;
113+p2 << r.p2;
114+@@
115+
116+msg = "reference preceded by free on line %s" % (p1[0].line)
117+coccilib.report.print_report(p2[0],msg)
scripts/coccinelle/iterators/fen.cocci+64−0
@@ -0,0 +1,64 @@
1+/// These iterators only exit normally when the loop cursor is NULL, so there
2+/// is no point to call of_node_put on the final value.
3+///
4+// Confidence: High
5+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
6+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
7+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
8+// URL: http://coccinelle.lip6.fr/
9+// Comments:
10+// Options: -no_includes -include_headers
11+
12+virtual patch
13+
14+@@
15+iterator name for_each_node_by_name;
16+expression np,E;
17+identifier l;
18+@@
19+
20+for_each_node_by_name(np,...) {
21+ ... when != break;
22+ when != goto l;
23+}
24+... when != np = E
25+- of_node_put(np);
26+
27+@@
28+iterator name for_each_node_by_type;
29+expression np,E;
30+identifier l;
31+@@
32+
33+for_each_node_by_type(np,...) {
34+ ... when != break;
35+ when != goto l;
36+}
37+... when != np = E
38+- of_node_put(np);
39+
40+@@
41+iterator name for_each_compatible_node;
42+expression np,E;
43+identifier l;
44+@@
45+
46+for_each_compatible_node(np,...) {
47+ ... when != break;
48+ when != goto l;
49+}
50+... when != np = E
51+- of_node_put(np);
52+
53+@@
54+iterator name for_each_matching_node;
55+expression np,E;
56+identifier l;
57+@@
58+
59+for_each_matching_node(np,...) {
60+ ... when != break;
61+ when != goto l;
62+}
63+... when != np = E
64+- of_node_put(np);
scripts/coccinelle/iterators/itnull.cocci+58−0
@@ -0,0 +1,58 @@
1+/// Many iterators have the property that the first argument is always bound
2+/// to a real list element, never NULL. False positives arise for some
3+/// iterators that do not have this property, or in cases when the loop
4+/// cursor is reassigned. The latter should only happen when the matched
5+/// code is on the way to a loop exit (break, goto, or return).
6+///
7+// Confidence: Moderate
8+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11+// URL: http://coccinelle.lip6.fr/
12+// Comments:
13+// Options: -no_includes -include_headers
14+
15+virtual patch
16+
17+@@
18+iterator I;
19+expression x,E,E1,E2;
20+statement S,S1,S2;
21+@@
22+
23+I(x,...) { <...
24+(
25+- if (x == NULL && ...) S
26+|
27+- if (x != NULL || ...)
28+ S
29+|
30+- (x == NULL) ||
31+ E
32+|
33+- (x != NULL) &&
34+ E
35+|
36+- (x == NULL && ...) ? E1 :
37+ E2
38+|
39+- (x != NULL || ...) ?
40+ E1
41+- : E2
42+|
43+- if (x == NULL && ...) S1 else
44+ S2
45+|
46+- if (x != NULL || ...)
47+ S1
48+- else S2
49+|
50++ BAD(
51+ x == NULL
52++ )
53+|
54++ BAD(
55+ x != NULL
56++ )
57+)
58+ ...> }
scripts/coccinelle/iterators/list_entry_update.cocci+62−0
@@ -0,0 +1,62 @@
1+/// list_for_each_entry uses its first argument to get from one element of
2+/// the list to the next, so it is usually not a good idea to reassign it.
3+/// The first rule finds such a reassignment and the second rule checks
4+/// that there is a path from the reassignment back to the top of the loop.
5+///
6+// Confidence: High
7+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
8+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
9+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
10+// URL: http://coccinelle.lip6.fr/
11+// Comments:
12+// Options: -no_includes -include_headers
13+
14+virtual context
15+virtual org
16+virtual report
17+
18+@r@
19+iterator name list_for_each_entry;
20+expression x,E;
21+position p1,p2;
22+@@
23+
24+list_for_each_entry@p1(x,...) { <... x =@p2 E ...> }
25+
26+@depends on context && !org && !report@
27+expression x,E;
28+position r.p1,r.p2;
29+statement S;
30+@@
31+
32+*x =@p2 E
33+...
34+list_for_each_entry@p1(x,...) S
35+
36+// ------------------------------------------------------------------------
37+
38+@back depends on (org || report) && !context exists@
39+expression x,E;
40+position r.p1,r.p2;
41+statement S;
42+@@
43+
44+x =@p2 E
45+...
46+list_for_each_entry@p1(x,...) S
47+
48+@script:python depends on back && org@
49+p1 << r.p1;
50+p2 << r.p2;
51+@@
52+
53+cocci.print_main("iterator",p1)
54+cocci.print_secs("update",p2)
55+
56+@script:python depends on back && report@
57+p1 << r.p1;
58+p2 << r.p2;
59+@@
60+
61+msg = "iterator with update on line %s" % (p2[0].line)
62+coccilib.report.print_report(p1[0],msg)
scripts/coccinelle/locks/call_kern.cocci+74−0
@@ -0,0 +1,74 @@
1+/// Find functions that refer to GFP_KERNEL but are called with locks held.
2+/// The proposed change of converting the GFP_KERNEL is not necessarily the
3+/// correct one. It may be desired to unlock the lock, or to not call the
4+/// function under the lock in the first place.
5+///
6+// Confidence: Moderate
7+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
8+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
9+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
10+// URL: http://coccinelle.lip6.fr/
11+// Comments:
12+// Options: -no_includes -include_headers
13+
14+virtual patch
15+
16+@gfp exists@
17+identifier fn;
18+position p;
19+@@
20+
21+fn(...) {
22+ ... when != read_unlock_irq(...)
23+ when != write_unlock_irq(...)
24+ when != read_unlock_irqrestore(...)
25+ when != write_unlock_irqrestore(...)
26+ when != spin_unlock(...)
27+ when != spin_unlock_irq(...)
28+ when != spin_unlock_irqrestore(...)
29+ when != local_irq_enable(...)
30+ when any
31+ GFP_KERNEL@p
32+ ... when any
33+}
34+
35+@locked@
36+identifier gfp.fn;
37+@@
38+
39+(
40+read_lock_irq
41+|
42+write_lock_irq
43+|
44+read_lock_irqsave
45+|
46+write_lock_irqsave
47+|
48+spin_lock
49+|
50+spin_trylock
51+|
52+spin_lock_irq
53+|
54+spin_lock_irqsave
55+|
56+local_irq_disable
57+)
58+ (...)
59+... when != read_unlock_irq(...)
60+ when != write_unlock_irq(...)
61+ when != read_unlock_irqrestore(...)
62+ when != write_unlock_irqrestore(...)
63+ when != spin_unlock(...)
64+ when != spin_unlock_irq(...)
65+ when != spin_unlock_irqrestore(...)
66+ when != local_irq_enable(...)
67+fn(...)
68+
69+@depends on locked@
70+position gfp.p;
71+@@
72+
73+- GFP_KERNEL@p
74++ GFP_ATOMIC
scripts/coccinelle/locks/double_lock.cocci+92−0
@@ -0,0 +1,92 @@
1+/// Find double locks. False positives may occur when some paths cannot
2+/// occur at execution, due to the values of variables, and when there is
3+/// an intervening function call that releases the lock.
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:
11+// Options: -no_includes -include_headers
12+
13+virtual org
14+virtual report
15+
16+@locked@
17+position p1;
18+expression E1;
19+position p;
20+@@
21+
22+(
23+mutex_lock@p1
24+|
25+mutex_trylock@p1
26+|
27+spin_lock@p1
28+|
29+spin_trylock@p1
30+|
31+read_lock@p1
32+|
33+read_trylock@p1
34+|
35+write_lock@p1
36+|
37+write_trylock@p1
38+) (E1@p,...);
39+
40+@balanced@
41+position p1 != locked.p1;
42+position locked.p;
43+identifier lock,unlock;
44+expression x <= locked.E1;
45+expression E,locked.E1;
46+expression E2;
47+@@
48+
49+if (E) {
50+ <+... when != E1
51+ lock(E1@p,...)
52+ ...+>
53+}
54+... when != E1
55+ when != \(x = E2\|&x\)
56+ when forall
57+if (E) {
58+ <+... when != E1
59+ unlock@p1(E1,...)
60+ ...+>
61+}
62+
63+@r depends on !balanced exists@
64+expression x <= locked.E1;
65+expression locked.E1;
66+expression E2;
67+identifier lock;
68+position locked.p,p1,p2;
69+@@
70+
71+lock@p1 (E1@p,...);
72+... when != E1
73+ when != \(x = E2\|&x\)
74+lock@p2 (E1,...);
75+
76+@script:python depends on org@
77+p1 << r.p1;
78+p2 << r.p2;
79+lock << r.lock;
80+@@
81+
82+cocci.print_main(lock,p1)
83+cocci.print_secs("second lock",p2)
84+
85+@script:python depends on report@
86+p1 << r.p1;
87+p2 << r.p2;
88+lock << r.lock;
89+@@
90+
91+msg = "second lock on line %s" % (p2[0].line)
92+coccilib.report.print_report(p1[0],msg)
scripts/coccinelle/locks/flags.cocci+80−0
@@ -0,0 +1,80 @@
1+/// Find nested lock+irqsave functions that use the same flags variables
2+///
3+// Confidence: High
4+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7+// URL: http://coccinelle.lip6.fr/
8+// Comments:
9+// Options: -no_includes -include_headers
10+
11+virtual context
12+virtual org
13+virtual report
14+
15+@r@
16+expression lock1,lock2,flags;
17+position p1,p2;
18+@@
19+
20+(
21+spin_lock_irqsave@p1(lock1,flags)
22+|
23+read_lock_irqsave@p1(lock1,flags)
24+|
25+write_lock_irqsave@p1(lock1,flags)
26+)
27+... when != flags
28+(
29+spin_lock_irqsave(lock1,flags)
30+|
31+read_lock_irqsave(lock1,flags)
32+|
33+write_lock_irqsave(lock1,flags)
34+|
35+spin_lock_irqsave@p2(lock2,flags)
36+|
37+read_lock_irqsave@p2(lock2,flags)
38+|
39+write_lock_irqsave@p2(lock2,flags)
40+)
41+
42+@d@
43+expression f <= r.flags;
44+expression lock1,lock2,flags;
45+position r.p1, r.p2;
46+@@
47+
48+(
49+*spin_lock_irqsave@p1(lock1,flags)
50+|
51+*read_lock_irqsave@p1(lock1,flags)
52+|
53+*write_lock_irqsave@p1(lock1,flags)
54+)
55+... when != f
56+(
57+*spin_lock_irqsave@p2(lock2,flags)
58+|
59+*read_lock_irqsave@p2(lock2,flags)
60+|
61+*write_lock_irqsave@p2(lock2,flags)
62+)
63+
64+// ----------------------------------------------------------------------
65+
66+@script:python depends on d && org@
67+p1 << r.p1;
68+p2 << r.p2;
69+@@
70+
71+cocci.print_main("original lock",p1)
72+cocci.print_secs("nested lock+irqsave that reuses flags",p2)
73+
74+@script:python depends on d && report@
75+p1 << r.p1;
76+p2 << r.p2;
77+@@
78+
79+msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line)
80+coccilib.report.print_report(p2[0], msg)
scripts/coccinelle/locks/mini_lock.cocci+95−0
@@ -0,0 +1,95 @@
1+/// Find missing unlocks. This semantic match considers the specific case
2+/// where the unlock is missing from an if branch, and there is a lock
3+/// before the if and an unlock after the if. False positives are due to
4+/// cases where the if branch represents a case where the function is
5+/// supposed to exit with the lock held, or where there is some preceding
6+/// function call that releases the lock.
7+///
8+// Confidence: Moderate
9+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
10+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
11+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
12+// URL: http://coccinelle.lip6.fr/
13+// Comments:
14+// Options: -no_includes -include_headers
15+
16+virtual org
17+virtual report
18+
19+@prelocked@
20+position p1,p;
21+expression E1;
22+@@
23+
24+(
25+mutex_lock@p1
26+|
27+mutex_trylock@p1
28+|
29+spin_lock@p1
30+|
31+spin_trylock@p1
32+|
33+read_lock@p1
34+|
35+read_trylock@p1
36+|
37+write_lock@p1
38+|
39+write_trylock@p1
40+|
41+read_lock_irq@p1
42+|
43+write_lock_irq@p1
44+|
45+read_lock_irqsave@p1
46+|
47+write_lock_irqsave@p1
48+|
49+spin_lock_irq@p1
50+|
51+spin_lock_irqsave@p1
52+) (E1@p,...);
53+
54+@looped@
55+position r;
56+@@
57+
58+for(...;...;...) { <+... return@r ...; ...+> }
59+
60+@err@
61+expression E1;
62+position prelocked.p;
63+position up != prelocked.p1;
64+position r!=looped.r;
65+identifier lock,unlock;
66+@@
67+
68+lock(E1@p,...);
69+<+... when != E1
70+if (...) {
71+ ... when != E1
72+ return@r ...;
73+}
74+...+>
75+unlock@up(E1,...);
76+
77+@script:python depends on org@
78+p << prelocked.p1;
79+lock << err.lock;
80+unlock << err.unlock;
81+p2 << err.r;
82+@@
83+
84+cocci.print_main(lock,p)
85+cocci.print_secs(unlock,p2)
86+
87+@script:python depends on report@
88+p << prelocked.p1;
89+lock << err.lock;
90+unlock << err.unlock;
91+p2 << err.r;
92+@@
93+
94+msg = "preceding lock on line %s" % (p[0].line)
95+coccilib.report.print_report(p2[0],msg)
scripts/coccinelle/misc/doubleinit.cocci+53−0
@@ -0,0 +1,53 @@
1+/// Find duplicate field initializations. This has a high rate of false
2+/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
3+/// initialization.
4+///
5+// Confidence: Low
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:
11+// Options: -no_includes -include_headers
12+
13+virtual org
14+virtual report
15+
16+@r@
17+identifier I, s, fld;
18+position p0,p;
19+expression E;
20+@@
21+
22+struct I s =@p0 { ... .fld@p = E, ...};
23+
24+@s@
25+identifier I, s, r.fld;
26+position r.p0,p;
27+expression E;
28+@@
29+
30+struct I s =@p0 { ... .fld@p = E, ...};
31+
32+@script:python depends on org@
33+p0 << r.p0;
34+fld << r.fld;
35+ps << s.p;
36+pr << r.p;
37+@@
38+
39+if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
40+ cocci.print_main(fld,p0)
41+ cocci.print_secs("s",ps)
42+ cocci.print_secs("r",pr)
43+
44+@script:python depends on report@
45+p0 << r.p0;
46+fld << r.fld;
47+ps << s.p;
48+pr << r.p;
49+@@
50+
51+if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
52+ msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line)
53+ coccilib.report.print_report(p0[0],msg)
scripts/coccinelle/misc/ifcol.cocci+48−0
@@ -0,0 +1,48 @@
1+/// Find confusingly indented code in or after an if. An if branch should
2+/// be indented. The code following an if should not be indented.
3+/// Sometimes, code after an if that is indented is actually intended to be
4+/// part of the if branch.
5+///
6+/// This has a high rate of false positives, because Coccinelle's column
7+/// calculation does not distinguish between spaces and tabs, so code that
8+/// is not visually aligned may be considered to be in the same column.
9+///
10+// Confidence: Low
11+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
12+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
13+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
14+// URL: http://coccinelle.lip6.fr/
15+// Comments:
16+// Options: -no_includes -include_headers
17+
18+virtual org
19+virtual report
20+
21+@r disable braces4@
22+position p1,p2;
23+statement S1,S2;
24+@@
25+
26+(
27+if (...) { ... }
28+|
29+if (...) S1@p1 S2@p2
30+)
31+
32+@script:python depends on org@
33+p1 << r.p1;
34+p2 << r.p2;
35+@@
36+
37+if (p1[0].column == p2[0].column):
38+ cocci.print_main("branch",p1)
39+ cocci.print_secs("after",p2)
40+
41+@script:python depends on report@
42+p1 << r.p1;
43+p2 << r.p2;
44+@@
45+
46+if (p1[0].column == p2[0].column):
47+ msg = "code aligned with following code on line %s" % (p2[0].line)
48+ coccilib.report.print_report(p1[0],msg)
scripts/coccinelle/null/deref_null.cocci+293−0
@@ -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+
13+virtual context
14+virtual patch
15+virtual org
16+virtual report
17+
18+@initialize:python depends on !context && patch && !org && !report@
19+
20+import sys
21+print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
22+
23+@depends on patch@
24+@@
25+
26+this_rule_should_never_matches();
27+
28+@ifm depends on !patch@
29+expression *E;
30+statement S1,S2;
31+position p1;
32+@@
33+
34+if@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@
39+expression *ifm.E;
40+identifier f;
41+position p1;
42+@@
43+
44+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
45+
46+@pr2 depends on !patch expression@
47+expression *ifm.E;
48+identifier f;
49+position 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@
63+expression subE <= ifm.E;
64+expression *ifm.E;
65+expression E1,E2;
66+identifier f;
67+statement S1,S2,S3,S4;
68+iterator iter;
69+position p!={pr1.p1,pr2.p2};
70+position ifm.p1;
71+@@
72+
73+if@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+}
100+else S3
101+
102+@script:python depends on !context && !patch && !org && report@
103+p << r.p;
104+p1 << ifm.p1;
105+x << ifm.E;
106+@@
107+
108+msg="ERROR: %s is NULL but dereferenced." % (x)
109+coccilib.report.print_report(p[0], msg)
110+cocci.include_match(False)
111+
112+@script:python depends on !context && !patch && org && !report@
113+p << r.p;
114+p1 << ifm.p1;
115+x << ifm.E;
116+@@
117+
118+msg="ERROR: %s is NULL but dereferenced." % (x)
119+msg_safe=msg.replace("[","@(").replace("]",")")
120+cocci.print_main(msg_safe,p)
121+cocci.include_match(False)
122+
123+@s depends on !context && !patch && (org || report) exists@
124+expression subE <= ifm.E;
125+expression *ifm.E;
126+expression E1,E2;
127+identifier f;
128+statement S1,S2,S3,S4;
129+iterator iter;
130+position p!={pr1.p1,pr2.p2};
131+position ifm.p1;
132+@@
133+
134+if@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+}
160+else S3
161+
162+@script:python depends on !context && !patch && !org && report@
163+p << s.p;
164+p1 << ifm.p1;
165+x << ifm.E;
166+@@
167+
168+msg="ERROR: %s is NULL but dereferenced." % (x)
169+coccilib.report.print_report(p[0], msg)
170+
171+@script:python depends on !context && !patch && org && !report@
172+p << s.p;
173+p1 << ifm.p1;
174+x << ifm.E;
175+@@
176+
177+msg="ERROR: %s is NULL but dereferenced." % (x)
178+msg_safe=msg.replace("[","@(").replace("]",")")
179+cocci.print_main(msg_safe,p)
180+
181+// For context mode
182+
183+@depends on context && !patch && !org && !report exists@
184+expression subE <= ifm.E;
185+expression *ifm.E;
186+expression E1,E2;
187+identifier f;
188+statement S1,S2,S3,S4;
189+iterator iter;
190+position p!={pr1.p1,pr2.p2};
191+position ifm.p1;
192+@@
193+
194+if@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+}
221+else 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@
227+expression *E;
228+statement S1,S2;
229+position p1;
230+@@
231+
232+if@p1 ((E == NULL && ...) || ...) S1 else S2
233+
234+@pr11 depends on !patch expression@
235+expression *ifm1.E;
236+identifier f;
237+position p1;
238+@@
239+
240+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
241+
242+@pr12 depends on !patch expression@
243+expression *ifm1.E;
244+identifier f;
245+position 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@
257+expression subE <= ifm1.E;
258+expression *ifm1.E;
259+expression E1,E2;
260+identifier f;
261+statement S1,S2,S3,S4;
262+iterator iter;
263+position p!={pr11.p1,pr12.p2};
264+position ifm1.p1;
265+@@
266+
267+if@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+}
293+else S3
scripts/coccinelle/null/eno.cocci+20−0
@@ -0,0 +1,20 @@
1+/// The various basic memory allocation functions don't return ERR_PTR
2+///
3+// Confidence: High
4+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7+// URL: http://coccinelle.lip6.fr/
8+// Comments:
9+// Options: -no_includes -include_headers
10+
11+virtual patch
12+
13+@@
14+expression x,E;
15+@@
16+
17+x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
18+... when != x = E
19+- IS_ERR(x)
20++ !x
scripts/coccinelle/null/kmerr.cocci+72−0
@@ -0,0 +1,72 @@
1+/// This semantic patch looks for kmalloc etc that are not followed by a
2+/// NULL check. It only gives a report in the case where there is some
3+/// error handling code later in the function, which may be helpful
4+/// in determining what the error handling code for the call to kmalloc etc
5+/// should be.
6+///
7+// Confidence: High
8+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11+// URL: http://coccinelle.lip6.fr/
12+// Comments:
13+// Options: -no_includes -include_headers
14+
15+virtual context
16+virtual org
17+virtual report
18+
19+@withtest@
20+expression x;
21+position p;
22+identifier f,fld;
23+@@
24+
25+x@p = f(...);
26+... when != x->fld
27+\(x == NULL \| x != NULL\)
28+
29+@fixed depends on context && !org && !report@
30+expression x,x1;
31+position p1 != withtest.p;
32+statement S;
33+position any withtest.p;
34+identifier f;
35+@@
36+
37+*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
38+...
39+*x1@p = f(...);
40+if (!x1) S
41+
42+// ------------------------------------------------------------------------
43+
44+@rfixed depends on (org || report) && !context exists@
45+expression x,x1;
46+position p1 != withtest.p;
47+position p2;
48+statement S;
49+position any withtest.p;
50+identifier f;
51+@@
52+
53+x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
54+...
55+x1@p = f@p2(...);
56+if (!x1) S
57+
58+@script:python depends on org@
59+p1 << rfixed.p1;
60+p2 << rfixed.p2;
61+@@
62+
63+cocci.print_main("alloc call",p1)
64+cocci.print_secs("possible model",p2)
65+
66+@script:python depends on report@
67+p1 << rfixed.p1;
68+p2 << rfixed.p2;
69+@@
70+
71+msg = "alloc with no test, possible model on line %s" % (p2[0].line)
72+coccilib.report.print_report(p1[0],msg)
scripts/coccinelle/tests/doublebitand.cocci+54−0
@@ -0,0 +1,54 @@
1+/// Find bit operations that include the same argument more than once
2+//# One source of false positives is when the argument performs a side
3+//# effect. Another source of false positives is when a neutral value
4+//# such as 0 for | is used to indicate no information, to maintain the
5+//# same structure as other similar expressions
6+///
7+// Confidence: Moderate
8+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11+// URL: http://coccinelle.lip6.fr/
12+// Comments:
13+// Options: -no_includes -include_headers
14+
15+virtual context
16+virtual org
17+virtual report
18+
19+@r expression@
20+expression E;
21+position p;
22+@@
23+
24+(
25+* E@p
26+ & ... & E
27+|
28+* E@p
29+ | ... | E
30+|
31+* E@p
32+ & ... & !E
33+|
34+* E@p
35+ | ... | !E
36+|
37+* !E@p
38+ & ... & E
39+|
40+* !E@p
41+ | ... | E
42+)
43+
44+@script:python depends on org@
45+p << r.p;
46+@@
47+
48+cocci.print_main("duplicated argument to & or |",p)
49+
50+@script:python depends on report@
51+p << r.p;
52+@@
53+
54+coccilib.report.print_report(p[0],"duplicated argument to & or |")
scripts/coccinelle/tests/doubletest.cocci+40−0
@@ -0,0 +1,40 @@
1+/// Find &&/|| operations that include the same argument more than once
2+//# A common source of false positives is when the argument performs a side
3+//# effect.
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:
11+// Options: -no_includes -include_headers
12+
13+virtual context
14+virtual org
15+virtual report
16+
17+@r expression@
18+expression E;
19+position p;
20+@@
21+
22+(
23+* E@p
24+ || ... || E
25+|
26+* E@p
27+ && ... && E
28+)
29+
30+@script:python depends on org@
31+p << r.p;
32+@@
33+
34+cocci.print_main("duplicated argument to && or ||",p)
35+
36+@script:python depends on report@
37+p << r.p;
38+@@
39+
40+coccilib.report.print_report(p[0],"duplicated argument to && or ||")
scripts/decodecode+5−5
@@ -40,7 +40,7 @@ echo $code · 39 unmodified lines
4040 code=`echo $code | sed -e 's/.*Code: //'`
4141
4242 width=`expr index "$code" ' '`
43−width=$[($width-1)/2]
43+width=$((($width-1)/2))
4444 case $width in
4545 1) type=byte ;;
4646 2) type=2byte ;;
@@ -48,10 +48,10 @@ case $width in · 1 unmodified line
4848 esac
4949
5050 disas() {
51− ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
51+ ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
5252
53− if [ "$ARCH" == "arm" ]; then
54− if [ $width == 2 ]; then
53+ if [ "$ARCH" = "arm" ]; then
54+ if [ $width -eq 2 ]; then
5555 OBJDUMPFLAGS="-M force-thumb"
5656 fi
5757
@@ -59,7 +59,7 @@ disas() { · 1 unmodified line
5959 fi
6060
6161 ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
62− grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
62+ grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
6363 }
6464
6565 marker=`expr index "$code" "\<"`
scripts/dtc/fstree.c+1−0
@@ -77,6 +77,7 @@ static struct node *read_fstree(const char *dirname) · 76 unmodified lines
7777 free(tmpnam);
7878 }
7979
80+ closedir(d);
8081 return tree;
8182 }
8283
scripts/extract-ikconfig+27−14
@@ -7,12 +7,10 @@ · 6 unmodified lines
77 # The obscure use of the "tr" filter is to work around older versions of
88 # "grep" that report the byte offset of the line instead of the pattern.
99 #
10−# (c) 2009, Dick Streefland <dick@streefland.net>
10+# (c) 2009,2010 Dick Streefland <dick@streefland.net>
1111 # Licensed under the terms of the GNU General Public License.
1212 # ----------------------------------------------------------------------
1313
14−gz1='\037\213\010'
15−gz2='01'
1614 cf1='IKCFG_ST\037\213\010'
1715 cf2='0123456789'
1816
@@ -21,11 +19,25 @@ dump_config() · 2 unmodified lines
2119 if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
2220 then
2321 pos=${pos%%:*}
24− tail -c+$(($pos+8)) "$1" | zcat -q
25− exit 0
22+ tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null
23+ if [ $? != 1 ]
24+ then # exit status must be 0 or 2 (trailing garbage warning)
25+ cat $tmp1
26+ exit 0
27+ fi
2628 fi
2729 }
2830
31+try_decompress()
32+{
33+ for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
34+ do
35+ pos=${pos%%:*}
36+ tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null
37+ dump_config $tmp2
38+ done
39+}
40+
2941 # Check invocation:
3042 me=${0##*/}
3143 img=$1
@@ -35,18 +47,19 @@ then · 3 unmodified lines
3547 exit 2
3648 fi
3749
50+# Prepare temp files:
51+tmp1=/tmp/ikconfig$$.1
52+tmp2=/tmp/ikconfig$$.2
53+trap "rm -f $tmp1 $tmp2" 0
54+
3855 # Initial attempt for uncompressed images or objects:
3956 dump_config "$img"
4057
41−# That didn't work, so decompress and try again:
42−tmp=/tmp/ikconfig$$
43−trap "rm -f $tmp" 0
44−for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"`
45−do
46− pos=${pos%%:*}
47− tail -c+$pos "$img" | zcat 2> /dev/null > $tmp
48− dump_config $tmp
49−done
58+# That didn't work, so retry after decompression.
59+try_decompress '\037\213\010' xy gunzip
60+try_decompress 'BZh' xy bunzip2
61+try_decompress '\135\0\0\0' xxx unlzma
62+try_decompress '\211\114\132' xy 'lzop -d'
5063
5164 # Bail out:
5265 echo "$me: Cannot find kernel config." >&2
scripts/gcc-goto.sh+5−0
@@ -0,0 +1,5 @@
1+#!/bin/sh
2+# Test for gcc 'asm goto' suport
3+# Copyright (C) 2010, Jason Baron <jbaron@redhat.com>
4+
5+echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y"
scripts/get_maintainer.pl+948−214
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313 use strict;
1414
1515 my $P = $0;
16−my $V = '0.24';
16+my $V = '0.26-beta6';
1717
1818 use Getopt::Long qw(:config no_auto_abbrev);
1919
@@ -24,15 +24,19 @@ my $email_maintainer = 1; · 4 unmodified lines
2424 my $email_list = 1;
2525 my $email_subscriber_list = 0;
2626 my $email_git_penguin_chiefs = 0;
27−my $email_git = 1;
27+my $email_git = 0;
2828 my $email_git_all_signature_types = 0;
2929 my $email_git_blame = 0;
30+my $email_git_blame_signatures = 1;
31+my $email_git_fallback = 1;
3032 my $email_git_min_signatures = 1;
3133 my $email_git_max_maintainers = 5;
3234 my $email_git_min_percent = 5;
3335 my $email_git_since = "1-year-ago";
3436 my $email_hg_since = "-365";
37+my $interactive = 0;
3538 my $email_remove_duplicates = 1;
39+my $email_use_mailmap = 1;
3640 my $output_multiline = 1;
3741 my $output_separator = ", ";
3842 my $output_roles = 0;
@@ -49,8 +53,13 @@ my $pattern_depth = 0; · 10 unmodified lines
4953 my $version = 0;
5054 my $help = 0;
5155
56+my $vcs_used = 0;
57+
5258 my $exit = 0;
5359
60+my %commit_author_hash;
61+my %commit_signer_hash;
62+
5463 my @penguin_chief = ();
5564 push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org");
5665 #Andrew wants in on most everything - 2009/01/14
@@ -73,7 +82,6 @@ my @signature_tags = (); · 16 unmodified lines
7382 push(@signature_tags, "Signed-off-by:");
7483 push(@signature_tags, "Reviewed-by:");
7584 push(@signature_tags, "Acked-by:");
76−my $signaturePattern = "\(" . join("|", @signature_tags) . "\)";
7785
7886 # rfc822 email address - preloaded methods go here.
7987 my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
@@ -86,31 +94,70 @@ my %VCS_cmds; · 6 unmodified lines
8694 my %VCS_cmds_git = (
8795 "execute_cmd" => \&git_execute_cmd,
8896 "available" => '(which("git") ne "") && (-d ".git")',
89− "find_signers_cmd" => "git log --no-color --since=\$email_git_since -- \$file",
90− "find_commit_signers_cmd" => "git log --no-color -1 \$commit",
97+ "find_signers_cmd" =>
98+ "git log --no-color --since=\$email_git_since " .
99+ '--format="GitCommit: %H%n' .
100+ 'GitAuthor: %an <%ae>%n' .
101+ 'GitDate: %aD%n' .
102+ 'GitSubject: %s%n' .
103+ '%b%n"' .
104+ " -- \$file",
105+ "find_commit_signers_cmd" =>
106+ "git log --no-color " .
107+ '--format="GitCommit: %H%n' .
108+ 'GitAuthor: %an <%ae>%n' .
109+ 'GitDate: %aD%n' .
110+ 'GitSubject: %s%n' .
111+ '%b%n"' .
112+ " -1 \$commit",
113+ "find_commit_author_cmd" =>
114+ "git log --no-color " .
115+ '--format="GitCommit: %H%n' .
116+ 'GitAuthor: %an <%ae>%n' .
117+ 'GitDate: %aD%n' .
118+ 'GitSubject: %s%n"' .
119+ " -1 \$commit",
91120 "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file",
92121 "blame_file_cmd" => "git blame -l \$file",
93− "commit_pattern" => "^commit [0-9a-f]{40,40}",
94− "blame_commit_pattern" => "^([0-9a-f]+) "
122+ "commit_pattern" => "^GitCommit: ([0-9a-f]{40,40})",
123+ "blame_commit_pattern" => "^([0-9a-f]+) ",
124+ "author_pattern" => "^GitAuthor: (.*)",
125+ "subject_pattern" => "^GitSubject: (.*)",
95126 );
96127
97128 my %VCS_cmds_hg = (
98129 "execute_cmd" => \&hg_execute_cmd,
99130 "available" => '(which("hg") ne "") && (-d ".hg")',
100131 "find_signers_cmd" =>
101− "hg log --date=\$email_hg_since" .
102− " --template='commit {node}\\n{desc}\\n' -- \$file",
103− "find_commit_signers_cmd" => "hg log --template='{desc}\\n' -r \$commit",
132+ "hg log --date=\$email_hg_since " .
133+ "--template='HgCommit: {node}\\n" .
134+ "HgAuthor: {author}\\n" .
135+ "HgSubject: {desc}\\n'" .
136+ " -- \$file",
137+ "find_commit_signers_cmd" =>
138+ "hg log " .
139+ "--template='HgSubject: {desc}\\n'" .
140+ " -r \$commit",
141+ "find_commit_author_cmd" =>
142+ "hg log " .
143+ "--template='HgCommit: {node}\\n" .
144+ "HgAuthor: {author}\\n" .
145+ "HgSubject: {desc|firstline}\\n'" .
146+ " -r \$commit",
104147 "blame_range_cmd" => "", # not supported
105− "blame_file_cmd" => "hg blame -c \$file",
106− "commit_pattern" => "^commit [0-9a-f]{40,40}",
107− "blame_commit_pattern" => "^([0-9a-f]+):"
148+ "blame_file_cmd" => "hg blame -n \$file",
149+ "commit_pattern" => "^HgCommit: ([0-9a-f]{40,40})",
150+ "blame_commit_pattern" => "^([ 0-9a-f]+):",
151+ "author_pattern" => "^HgAuthor: (.*)",
152+ "subject_pattern" => "^HgSubject: (.*)",
108153 );
109154
110−if (-f "${lk_path}.get_maintainer.conf") {
155+my $conf = which_conf(".get_maintainer.conf");
156+if (-f $conf) {
111157 my @conf_args;
112− open(my $conffile, '<', "${lk_path}.get_maintainer.conf")
113− or warn "$P: Can't open .get_maintainer.conf: $!\n";
158+ open(my $conffile, '<', "$conf")
159+ or warn "$P: Can't find a readable .get_maintainer.conf file $!\n";
160+
114161 while (<$conffile>) {
115162 my $line = $_;
116163
@@ -136,13 +183,17 @@ if (!GetOptions( · 19 unmodified lines
136183 'git!' => \$email_git,
137184 'git-all-signature-types!' => \$email_git_all_signature_types,
138185 'git-blame!' => \$email_git_blame,
186+ 'git-blame-signatures!' => \$email_git_blame_signatures,
187+ 'git-fallback!' => \$email_git_fallback,
139188 'git-chief-penguins!' => \$email_git_penguin_chiefs,
140189 'git-min-signatures=i' => \$email_git_min_signatures,
141190 'git-max-maintainers=i' => \$email_git_max_maintainers,
142191 'git-min-percent=i' => \$email_git_min_percent,
143192 'git-since=s' => \$email_git_since,
144193 'hg-since=s' => \$email_hg_since,
194+ 'i|interactive!' => \$interactive,
145195 'remove-duplicates!' => \$email_remove_duplicates,
196+ 'mailmap!' => \$email_use_mailmap,
146197 'm!' => \$email_maintainer,
147198 'n!' => \$email_usename,
148199 'l!' => \$email_list,
@@ -181,13 +232,9 @@ if (-t STDIN && !@ARGV) { · 32 unmodified lines
181232 die "$P: missing patchfile or -f file - use --help if necessary\n";
182233 }
183234
184−if ($output_separator ne ", ") {
185− $output_multiline = 0;
186−}
187−
188−if ($output_rolestats) {
189− $output_roles = 1;
190−}
235+$output_multiline = 0 if ($output_separator ne ", ");
236+$output_rolestats = 1 if ($interactive);
237+$output_roles = 1 if ($output_rolestats);
191238
192239 if ($sections) {
193240 $email = 0;
@@ -197,6 +244,7 @@ if ($sections) { · 3 unmodified lines
197244 $subsystem = 0;
198245 $web = 0;
199246 $keywords = 0;
247+ $interactive = 0;
200248 } else {
201249 my $selections = $email + $scm + $status + $subsystem + $web;
202250 if ($selections == 0) {
@@ -215,10 +263,6 @@ if (!top_of_kernel_tree($lk_path)) { · 12 unmodified lines
215263 . "a linux kernel source tree.\n";
216264 }
217265
218−if ($email_git_all_signature_types) {
219− $signaturePattern = "(.+?)[Bb][Yy]:";
220−}
221−
222266 ## Read MAINTAINERS for type/value pairs
223267
224268 my @typevalue = ();
@@ -253,31 +297,82 @@ while (<$maint>) { · 28 unmodified lines
253297 }
254298 close($maint);
255299
256−my %mailmap;
257300
258−if ($email_remove_duplicates) {
259− open(my $mailmap, '<', "${lk_path}.mailmap")
260− or warn "$P: Can't open .mailmap: $!\n";
261− while (<$mailmap>) {
262− my $line = $_;
301+#
302+# Read mail address map
303+#
263304
264− next if ($line =~ m/^\s*#/);
265− next if ($line =~ m/^\s*$/);
305+my $mailmap;
266306
267− my ($name, $address) = parse_email($line);
268− $line = format_email($name, $address, $email_usename);
307+read_mailmap();
269308
270− next if ($line =~ m/^\s*$/);
309+sub read_mailmap {
310+ $mailmap = {
311+ names => {},
312+ addresses => {}
313+ };
271314
272− if (exists($mailmap{$name})) {
273− my $obj = $mailmap{$name};
274− push(@$obj, $address);
275− } else {
276− my @arr = ($address);
277− $mailmap{$name} = \@arr;
315+ return if (!$email_use_mailmap || !(-f "${lk_path}.mailmap"));
316+
317+ open(my $mailmap_file, '<', "${lk_path}.mailmap")
318+ or warn "$P: Can't open .mailmap: $!\n";
319+
320+ while (<$mailmap_file>) {
321+ s/#.*$//; #strip comments
322+ s/^\s+|\s+$//g; #trim
323+
324+ next if (/^\s*$/); #skip empty lines
325+ #entries have one of the following formats:
326+ # name1 <mail1>
327+ # <mail1> <mail2>
328+ # name1 <mail1> <mail2>
329+ # name1 <mail1> name2 <mail2>
330+ # (see man git-shortlog)
331+ if (/^(.+)<(.+)>$/) {
332+ my $real_name = $1;
333+ my $address = $2;
334+
335+ $real_name =~ s/\s+$//;
336+ ($real_name, $address) = parse_email("$real_name <$address>");
337+ $mailmap->{names}->{$address} = $real_name;
338+
339+ } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) {
340+ my $real_address = $1;
341+ my $wrong_address = $2;
342+
343+ $mailmap->{addresses}->{$wrong_address} = $real_address;
344+
345+ } elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) {
346+ my $real_name = $1;
347+ my $real_address = $2;
348+ my $wrong_address = $3;
349+
350+ $real_name =~ s/\s+$//;
351+ ($real_name, $real_address) =
352+ parse_email("$real_name <$real_address>");
353+ $mailmap->{names}->{$wrong_address} = $real_name;
354+ $mailmap->{addresses}->{$wrong_address} = $real_address;
355+
356+ } elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) {
357+ my $real_name = $1;
358+ my $real_address = $2;
359+ my $wrong_name = $3;
360+ my $wrong_address = $4;
361+
362+ $real_name =~ s/\s+$//;
363+ ($real_name, $real_address) =
364+ parse_email("$real_name <$real_address>");
365+
366+ $wrong_name =~ s/\s+$//;
367+ ($wrong_name, $wrong_address) =
368+ parse_email("$wrong_name <$wrong_address>");
369+
370+ my $wrong_email = format_email($wrong_name, $wrong_address, 1);
371+ $mailmap->{names}->{$wrong_email} = $real_name;
372+ $mailmap->{addresses}->{$wrong_email} = $real_address;
278373 }
279374 }
280− close($mailmap);
375+ close($mailmap_file);
281376 }
282377
283378 ## use the filenames on the command line or find the filenames in the patchfiles
@@ -302,7 +397,7 @@ foreach my $file (@ARGV) { · 18 unmodified lines
302397 }
303398 if ($from_filename) {
304399 push(@files, $file);
305− if (-f $file && ($keywords || $file_emails)) {
400+ if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
306401 open(my $f, '<', $file)
307402 or die "$P: Can't open $file: $!\n";
308403 my $text = do { local($/) ; <$f> };
@@ -357,67 +452,127 @@ foreach my $file (@ARGV) { · 48 unmodified lines
357452
358453 @file_emails = uniq(@file_emails);
359454
455+my %email_hash_name;
456+my %email_hash_address;
360457 my @email_to = ();
458+my %hash_list_to;
361459 my @list_to = ();
362460 my @scm = ();
363461 my @web = ();
364462 my @subsystem = ();
365463 my @status = ();
464+my %deduplicate_name_hash = ();
465+my %deduplicate_address_hash = ();
466+my $signature_pattern;
366467
367−# Find responsible parties
468+my @maintainers = get_maintainers();
368469
369−foreach my $file (@files) {
470+if (@maintainers) {
471+ @maintainers = merge_email(@maintainers);
472+ output(@maintainers);
473+}
370474
371− my %hash;
372− my $tvi = find_first_section();
373− while ($tvi < @typevalue) {
374− my $start = find_starting_index($tvi);
375− my $end = find_ending_index($tvi);
376− my $exclude = 0;
377− my $i;
378−
379− #Do not match excluded file patterns
380−
381− for ($i = $start; $i < $end; $i++) {
382− my $line = $typevalue[$i];
383− if ($line =~ m/^(\C):\s*(.*)/) {
384− my $type = $1;
385− my $value = $2;
386− if ($type eq 'X') {
387− if (file_match_pattern($file, $value)) {
388− $exclude = 1;
389− last;
390− }
391− }
392− }
393− }
475+if ($scm) {
476+ @scm = uniq(@scm);
477+ output(@scm);
478+}
479+
480+if ($status) {
481+ @status = uniq(@status);
482+ output(@status);
483+}
484+
485+if ($subsystem) {
486+ @subsystem = uniq(@subsystem);
487+ output(@subsystem);
488+}
489+
490+if ($web) {
491+ @web = uniq(@web);
492+ output(@web);
493+}
494+
495+exit($exit);
496+
497+sub get_maintainers {
498+ %email_hash_name = ();
499+ %email_hash_address = ();
500+ %commit_author_hash = ();
501+ %commit_signer_hash = ();
502+ @email_to = ();
503+ %hash_list_to = ();
504+ @list_to = ();
505+ @scm = ();
506+ @web = ();
507+ @subsystem = ();
508+ @status = ();
509+ %deduplicate_name_hash = ();
510+ %deduplicate_address_hash = ();
511+ if ($email_git_all_signature_types) {
512+ $signature_pattern = "(.+?)[Bb][Yy]:";
513+ } else {
514+ $signature_pattern = "\(" . join("|", @signature_tags) . "\)";
515+ }
516+
517+ # Find responsible parties
518+
519+ my %exact_pattern_match_hash = ();
520+
521+ foreach my $file (@files) {
522+
523+ my %hash;
524+ my $tvi = find_first_section();
525+ while ($tvi < @typevalue) {
526+ my $start = find_starting_index($tvi);
527+ my $end = find_ending_index($tvi);
528+ my $exclude = 0;
529+ my $i;
530+
531+ #Do not match excluded file patterns
394532
395− if (!$exclude) {
396533 for ($i = $start; $i < $end; $i++) {
397534 my $line = $typevalue[$i];
398535 if ($line =~ m/^(\C):\s*(.*)/) {
399536 my $type = $1;
400537 my $value = $2;
401− if ($type eq 'F') {
538+ if ($type eq 'X') {
402539 if (file_match_pattern($file, $value)) {
403− my $value_pd = ($value =~ tr@/@@);
404− my $file_pd = ($file =~ tr@/@@);
405− $value_pd++ if (substr($value,-1,1) ne "/");
406− if ($pattern_depth == 0 ||
407− (($file_pd - $value_pd) < $pattern_depth)) {
408− $hash{$tvi} = $value_pd;
540+ $exclude = 1;
541+ last;
542+ }
543+ }
544+ }
545+ }
546+
547+ if (!$exclude) {
548+ for ($i = $start; $i < $end; $i++) {
549+ my $line = $typevalue[$i];
550+ if ($line =~ m/^(\C):\s*(.*)/) {
551+ my $type = $1;
552+ my $value = $2;
553+ if ($type eq 'F') {
554+ if (file_match_pattern($file, $value)) {
555+ my $value_pd = ($value =~ tr@/@@);
556+ my $file_pd = ($file =~ tr@/@@);
557+ $value_pd++ if (substr($value,-1,1) ne "/");
558+ $value_pd = -1 if ($value =~ /^\.\*/);
559+ if ($value_pd >= $file_pd) {
560+ $exact_pattern_match_hash{$file} = 1;
561+ }
562+ if ($pattern_depth == 0 ||
563+ (($file_pd - $value_pd) < $pattern_depth)) {
564+ $hash{$tvi} = $value_pd;
565+ }
409566 }
410567 }
411568 }
412569 }
413570 }
571+ $tvi = $end + 1;
414572 }
415573
416− $tvi = $end + 1;
417− }
418−
419− foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
420− add_categories($line);
574+ foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
575+ add_categories($line);
421576 if ($sections) {
422577 my $i;
423578 my $start = find_starting_index($line);
@@ -435,80 +590,71 @@ foreach my $file (@files) { · 11 unmodified lines
435590 }
436591 print("\n");
437592 }
593+ }
438594 }
439595
440− if ($email && $email_git) {
441− vcs_file_signoffs($file);
596+ if ($keywords) {
597+ @keyword_tvi = sort_and_uniq(@keyword_tvi);
598+ foreach my $line (@keyword_tvi) {
599+ add_categories($line);
600+ }
442601 }
443602
444− if ($email && $email_git_blame) {
445− vcs_file_blame($file);
603+ foreach my $email (@email_to, @list_to) {
604+ $email->[0] = deduplicate_email($email->[0]);
446605 }
447−}
448606
449−if ($keywords) {
450− @keyword_tvi = sort_and_uniq(@keyword_tvi);
451− foreach my $line (@keyword_tvi) {
452− add_categories($line);
607+ foreach my $file (@files) {
608+ if ($email &&
609+ ($email_git || ($email_git_fallback &&
610+ !$exact_pattern_match_hash{$file}))) {
611+ vcs_file_signoffs($file);
612+ }
613+ if ($email && $email_git_blame) {
614+ vcs_file_blame($file);
615+ }
453616 }
454−}
455617
456−if ($email) {
457− foreach my $chief (@penguin_chief) {
458− if ($chief =~ m/^(.*):(.*)/) {
459− my $email_address;
618+ if ($email) {
619+ foreach my $chief (@penguin_chief) {
620+ if ($chief =~ m/^(.*):(.*)/) {
621+ my $email_address;
460622
461− $email_address = format_email($1, $2, $email_usename);
462− if ($email_git_penguin_chiefs) {
463− push(@email_to, [$email_address, 'chief penguin']);
464− } else {
465− @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
623+ $email_address = format_email($1, $2, $email_usename);
624+ if ($email_git_penguin_chiefs) {
625+ push(@email_to, [$email_address, 'chief penguin']);
626+ } else {
627+ @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
628+ }
466629 }
467630 }
468− }
469631
470− foreach my $email (@file_emails) {
471− my ($name, $address) = parse_email($email);
632+ foreach my $email (@file_emails) {
633+ my ($name, $address) = parse_email($email);
472634
473− my $tmp_email = format_email($name, $address, $email_usename);
474− push_email_address($tmp_email, '');
475− add_role($tmp_email, 'in file');
635+ my $tmp_email = format_email($name, $address, $email_usename);
636+ push_email_address($tmp_email, '');
637+ add_role($tmp_email, 'in file');
638+ }
476639 }
477−}
478640
479−if ($email || $email_list) {
480641 my @to = ();
481− if ($email) {
482− @to = (@to, @email_to);
483− }
484− if ($email_list) {
485− @to = (@to, @list_to);
642+ if ($email || $email_list) {
643+ if ($email) {
644+ @to = (@to, @email_to);
645+ }
646+ if ($email_list) {
647+ @to = (@to, @list_to);
648+ }
486649 }
487− output(merge_email(@to));
488−}
489−
490−if ($scm) {
491− @scm = uniq(@scm);
492− output(@scm);
493−}
494−
495−if ($status) {
496− @status = uniq(@status);
497− output(@status);
498−}
499650
500−if ($subsystem) {
501− @subsystem = uniq(@subsystem);
502− output(@subsystem);
503−}
651+ if ($interactive) {
652+ @to = interactive_get_maintainers(\@to);
653+ }
504654
505−if ($web) {
506− @web = uniq(@web);
507− output(@web);
655+ return @to;
508656 }
509657
510−exit($exit);
511−
512658 sub file_match_pattern {
513659 my ($file, $pattern) = @_;
514660 if (substr($pattern, -1) eq "/") {
@@ -537,7 +683,8 @@ MAINTAINER field selection options: · 22 unmodified lines
537683 --email => print email address(es) if any
538684 --git => include recent git \*-by: signers
539685 --git-all-signature-types => include signers regardless of signature type
540− or use only ${signaturePattern} signers (default: $email_git_all_signature_types)
686+ or use only ${signature_pattern} signers (default: $email_git_all_signature_types)
687+ --git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback)
541688 --git-chief-penguins => include ${penguin_chiefs}
542689 --git-min-signatures => number of signatures required (default: $email_git_min_signatures)
543690 --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
@@ -545,6 +692,7 @@ MAINTAINER field selection options: · 1 unmodified line
545692 --git-blame => use git blame to find modified commits for patch or file
546693 --git-since => git history to use (default: $email_git_since)
547694 --hg-since => hg history to use (default: $email_hg_since)
695+ --interactive => display a menu (mostly useful if used with the --git option)
548696 --m => include maintainer(s) if any
549697 --n => include name 'Full Name <addr\@domain.tld>'
550698 --l => include list(s) if any
@@ -565,8 +713,9 @@ Output type options: · 14 unmodified lines
565713
566714 Other options:
567715 --pattern-depth => Number of pattern directory traversals (default: 0 (all))
568− --keywords => scan patch for keywords (default: 1 (on))
569− --sections => print the entire subsystem sections with pattern matches
716+ --keywords => scan patch for keywords (default: $keywords)
717+ --sections => print all of the subsystem sections with pattern matches
718+ --mailmap => use .mailmap file (default: $email_use_mailmap)
570719 --version => show version
571720 --help => show this help information
572721
@@ -606,30 +755,30 @@ EOT · 33 unmodified lines
606755 }
607756
608757 sub top_of_kernel_tree {
609− my ($lk_path) = @_;
758+ my ($lk_path) = @_;
610759
611− if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
612− $lk_path .= "/";
613− }
614− if ( (-f "${lk_path}COPYING")
615− && (-f "${lk_path}CREDITS")
616− && (-f "${lk_path}Kbuild")
617− && (-f "${lk_path}MAINTAINERS")
618− && (-f "${lk_path}Makefile")
619− && (-f "${lk_path}README")
620− && (-d "${lk_path}Documentation")
621− && (-d "${lk_path}arch")
622− && (-d "${lk_path}include")
623− && (-d "${lk_path}drivers")
624− && (-d "${lk_path}fs")
625− && (-d "${lk_path}init")
626− && (-d "${lk_path}ipc")
627− && (-d "${lk_path}kernel")
628− && (-d "${lk_path}lib")
629− && (-d "${lk_path}scripts")) {
630− return 1;
631− }
632− return 0;
760+ if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
761+ $lk_path .= "/";
762+ }
763+ if ( (-f "${lk_path}COPYING")
764+ && (-f "${lk_path}CREDITS")
765+ && (-f "${lk_path}Kbuild")
766+ && (-f "${lk_path}MAINTAINERS")
767+ && (-f "${lk_path}Makefile")
768+ && (-f "${lk_path}README")
769+ && (-d "${lk_path}Documentation")
770+ && (-d "${lk_path}arch")
771+ && (-d "${lk_path}include")
772+ && (-d "${lk_path}drivers")
773+ && (-d "${lk_path}fs")
774+ && (-d "${lk_path}init")
775+ && (-d "${lk_path}ipc")
776+ && (-d "${lk_path}kernel")
777+ && (-d "${lk_path}lib")
778+ && (-d "${lk_path}scripts")) {
779+ return 1;
780+ }
781+ return 0;
633782 }
634783
635784 sub parse_email {
@@ -821,11 +970,19 @@ sub add_categories { · 185 unmodified lines
821970 }
822971 if ($list_additional =~ m/subscribers-only/) {
823972 if ($email_subscriber_list) {
824− push(@list_to, [$list_address, "subscriber list${list_role}"]);
973+ if (!$hash_list_to{lc($list_address)}) {
974+ $hash_list_to{lc($list_address)} = 1;
975+ push(@list_to, [$list_address,
976+ "subscriber list${list_role}"]);
977+ }
825978 }
826979 } else {
827980 if ($email_list) {
828− push(@list_to, [$list_address, "open list${list_role}"]);
981+ if (!$hash_list_to{lc($list_address)}) {
982+ $hash_list_to{lc($list_address)} = 1;
983+ push(@list_to, [$list_address,
984+ "open list${list_role}"]);
985+ }
829986 }
830987 }
831988 } elsif ($ptype eq "M") {
@@ -856,15 +1013,12 @@ sub add_categories { · 24 unmodified lines
8561013 }
8571014 }
8581015
859−my %email_hash_name;
860−my %email_hash_address;
861−
8621016 sub email_inuse {
8631017 my ($name, $address) = @_;
8641018
8651019 return 1 if (($name eq "") && ($address eq ""));
866− return 1 if (($name ne "") && exists($email_hash_name{$name}));
867− return 1 if (($address ne "") && exists($email_hash_address{$address}));
1020+ return 1 if (($name ne "") && exists($email_hash_name{lc($name)}));
1021+ return 1 if (($address ne "") && exists($email_hash_address{lc($address)}));
8681022
8691023 return 0;
8701024 }
@@ -882,8 +1036,8 @@ sub push_email_address { · 11 unmodified lines
8821036 push(@email_to, [format_email($name, $address, $email_usename), $role]);
8831037 } elsif (!email_inuse($name, $address)) {
8841038 push(@email_to, [format_email($name, $address, $email_usename), $role]);
885− $email_hash_name{$name}++;
886− $email_hash_address{$address}++;
1039+ $email_hash_name{lc($name)}++ if ($name ne "");
1040+ $email_hash_address{lc($address)}++;
8871041 }
8881042
8891043 return 1;
@@ -952,30 +1106,69 @@ sub which { · 62 unmodified lines
9521106 return "";
9531107 }
9541108
955−sub mailmap {
956− my (@lines) = @_;
957− my %hash;
1109+sub which_conf {
1110+ my ($conf) = @_;
9581111
959− foreach my $line (@lines) {
960− my ($name, $address) = parse_email($line);
961− if (!exists($hash{$name})) {
962− $hash{$name} = $address;
963− } elsif ($address ne $hash{$name}) {
964− $address = $hash{$name};
965− $line = format_email($name, $address, $email_usename);
1112+ foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1113+ if (-e "$path/$conf") {
1114+ return "$path/$conf";
9661115 }
967− if (exists($mailmap{$name})) {
968− my $obj = $mailmap{$name};
969− foreach my $map_address (@$obj) {
970− if (($map_address eq $address) &&
971− ($map_address ne $hash{$name})) {
972− $line = format_email($name, $hash{$name}, $email_usename);
973− }
974− }
1116+ }
1117+
1118+ return "";
1119+}
1120+
1121+sub mailmap_email {
1122+ my ($line) = @_;
1123+
1124+ my ($name, $address) = parse_email($line);
1125+ my $email = format_email($name, $address, 1);
1126+ my $real_name = $name;
1127+ my $real_address = $address;
1128+
1129+ if (exists $mailmap->{names}->{$email} ||
1130+ exists $mailmap->{addresses}->{$email}) {
1131+ if (exists $mailmap->{names}->{$email}) {
1132+ $real_name = $mailmap->{names}->{$email};
1133+ }
1134+ if (exists $mailmap->{addresses}->{$email}) {
1135+ $real_address = $mailmap->{addresses}->{$email};
1136+ }
1137+ } else {
1138+ if (exists $mailmap->{names}->{$address}) {
1139+ $real_name = $mailmap->{names}->{$address};
1140+ }
1141+ if (exists $mailmap->{addresses}->{$address}) {
1142+ $real_address = $mailmap->{addresses}->{$address};
9751143 }
9761144 }
1145+ return format_email($real_name, $real_address, 1);
1146+}
9771147
978− return @lines;
1148+sub mailmap {
1149+ my (@addresses) = @_;
1150+
1151+ my @mapped_emails = ();
1152+ foreach my $line (@addresses) {
1153+ push(@mapped_emails, mailmap_email($line));
1154+ }
1155+ merge_by_realname(@mapped_emails) if ($email_use_mailmap);
1156+ return @mapped_emails;
1157+}
1158+
1159+sub merge_by_realname {
1160+ my %address_map;
1161+ my (@emails) = @_;
1162+
1163+ foreach my $email (@emails) {
1164+ my ($name, $address) = parse_email($email);
1165+ if (exists $address_map{$name}) {
1166+ $address = $address_map{$name};
1167+ $email = format_email($name, $address, 1);
1168+ } else {
1169+ $address_map{$name} = $address;
1170+ }
1171+ }
9791172 }
9801173
9811174 sub git_execute_cmd {
@@ -999,10 +1192,30 @@ sub hg_execute_cmd { · 17 unmodified lines
9991192 return @lines;
10001193 }
10011194
1195+sub extract_formatted_signatures {
1196+ my (@signature_lines) = @_;
1197+
1198+ my @type = @signature_lines;
1199+
1200+ s/\s*(.*):.*/$1/ for (@type);
1201+
1202+ # cut -f2- -d":"
1203+ s/\s*.*:\s*(.+)\s*/$1/ for (@signature_lines);
1204+
1205+## Reformat email addresses (with names) to avoid badly written signatures
1206+
1207+ foreach my $signer (@signature_lines) {
1208+ $signer = deduplicate_email($signer);
1209+ }
1210+
1211+ return (\@type, \@signature_lines);
1212+}
1213+
10021214 sub vcs_find_signers {
10031215 my ($cmd) = @_;
1004− my @lines = ();
10051216 my $commits;
1217+ my @lines = ();
1218+ my @signatures = ();
10061219
10071220 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
10081221
@@ -1010,21 +1223,48 @@ sub vcs_find_signers { · 1 unmodified line
10101223
10111224 $commits = grep(/$pattern/, @lines); # of commits
10121225
1013− @lines = grep(/^[ \t]*${signaturePattern}.*\@.*$/, @lines);
1226+ @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines);
1227+
1228+ return (0, @signatures) if !@signatures;
1229+
1230+ save_commits_by_author(@lines) if ($interactive);
1231+ save_commits_by_signer(@lines) if ($interactive);
1232+
1233+ if (!$email_git_penguin_chiefs) {
1234+ @signatures = grep(!/${penguin_chiefs}/i, @signatures);
1235+ }
1236+
1237+ my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
1238+
1239+ return ($commits, @$signers_ref);
1240+}
1241+
1242+sub vcs_find_author {
1243+ my ($cmd) = @_;
1244+ my @lines = ();
1245+
1246+ @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1247+
10141248 if (!$email_git_penguin_chiefs) {
10151249 @lines = grep(!/${penguin_chiefs}/i, @lines);
10161250 }
1017− # cut -f2- -d":"
1018− s/.*:\s*(.+)\s*/$1/ for (@lines);
10191251
1020−## Reformat email addresses (with names) to avoid badly written signatures
1252+ return @lines if !@lines;
10211253
1254+ my @authors = ();
10221255 foreach my $line (@lines) {
1023− my ($name, $address) = parse_email($line);
1024− $line = format_email($name, $address, 1);
1256+ if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
1257+ my $author = $1;
1258+ my ($name, $address) = parse_email($author);
1259+ $author = format_email($name, $address, 1);
1260+ push(@authors, $author);
1261+ }
10251262 }
10261263
1027− return ($commits, @lines);
1264+ save_commits_by_author(@lines) if ($interactive);
1265+ save_commits_by_signer(@lines) if ($interactive);
1266+
1267+ return @authors;
10281268 }
10291269
10301270 sub vcs_save_commits {
@@ -1084,6 +1324,10 @@ sub vcs_blame { · 53 unmodified lines
10841324 @commits = vcs_save_commits($cmd);
10851325 }
10861326
1327+ foreach my $commit (@commits) {
1328+ $commit =~ s/^\^//g;
1329+ }
1330+
10871331 return @commits;
10881332 }
10891333
@@ -1092,7 +1336,7 @@ sub vcs_exists { · 2 unmodified lines
10921336 %VCS_cmds = %VCS_cmds_git;
10931337 return 1 if eval $VCS_cmds{"available"};
10941338 %VCS_cmds = %VCS_cmds_hg;
1095− return 1 if eval $VCS_cmds{"available"};
1339+ return 2 if eval $VCS_cmds{"available"};
10961340 %VCS_cmds = ();
10971341 if (!$printed_novcs) {
10981342 warn("$P: No supported VCS found. Add --nogit to options?\n");
@@ -1104,6 +1348,405 @@ sub vcs_exists { · 5 unmodified lines
11041348 return 0;
11051349 }
11061350
1351+sub vcs_is_git {
1352+ vcs_exists();
1353+ return $vcs_used == 1;
1354+}
1355+
1356+sub vcs_is_hg {
1357+ return $vcs_used == 2;
1358+}
1359+
1360+sub interactive_get_maintainers {
1361+ my ($list_ref) = @_;
1362+ my @list = @$list_ref;
1363+
1364+ vcs_exists();
1365+
1366+ my %selected;
1367+ my %authored;
1368+ my %signed;
1369+ my $count = 0;
1370+ my $maintained = 0;
1371+ foreach my $entry (@list) {
1372+ $maintained = 1 if ($entry->[1] =~ /^(maintainer|supporter)/i);
1373+ $selected{$count} = 1;
1374+ $authored{$count} = 0;
1375+ $signed{$count} = 0;
1376+ $count++;
1377+ }
1378+
1379+ #menu loop
1380+ my $done = 0;
1381+ my $print_options = 0;
1382+ my $redraw = 1;
1383+ while (!$done) {
1384+ $count = 0;
1385+ if ($redraw) {
1386+ printf STDERR "\n%1s %2s %-65s",
1387+ "*", "#", "email/list and role:stats";
1388+ if ($email_git ||
1389+ ($email_git_fallback && !$maintained) ||
1390+ $email_git_blame) {
1391+ print STDERR "auth sign";
1392+ }
1393+ print STDERR "\n";
1394+ foreach my $entry (@list) {
1395+ my $email = $entry->[0];
1396+ my $role = $entry->[1];
1397+ my $sel = "";
1398+ $sel = "*" if ($selected{$count});
1399+ my $commit_author = $commit_author_hash{$email};
1400+ my $commit_signer = $commit_signer_hash{$email};
1401+ my $authored = 0;
1402+ my $signed = 0;
1403+ $authored++ for (@{$commit_author});
1404+ $signed++ for (@{$commit_signer});
1405+ printf STDERR "%1s %2d %-65s", $sel, $count + 1, $email;
1406+ printf STDERR "%4d %4d", $authored, $signed
1407+ if ($authored > 0 || $signed > 0);
1408+ printf STDERR "\n %s\n", $role;
1409+ if ($authored{$count}) {
1410+ my $commit_author = $commit_author_hash{$email};
1411+ foreach my $ref (@{$commit_author}) {
1412+ print STDERR " Author: @{$ref}[1]\n";
1413+ }
1414+ }
1415+ if ($signed{$count}) {
1416+ my $commit_signer = $commit_signer_hash{$email};
1417+ foreach my $ref (@{$commit_signer}) {
1418+ print STDERR " @{$ref}[2]: @{$ref}[1]\n";
1419+ }
1420+ }
1421+
1422+ $count++;
1423+ }
1424+ }
1425+ my $date_ref = \$email_git_since;
1426+ $date_ref = \$email_hg_since if (vcs_is_hg());
1427+ if ($print_options) {
1428+ $print_options = 0;
1429+ if (vcs_exists()) {
1430+ print STDERR <<EOT
1431+
1432+Version Control options:
1433+g use git history [$email_git]
1434+gf use git-fallback [$email_git_fallback]
1435+b use git blame [$email_git_blame]
1436+bs use blame signatures [$email_git_blame_signatures]
1437+c# minimum commits [$email_git_min_signatures]
1438+%# min percent [$email_git_min_percent]
1439+d# history to use [$$date_ref]
1440+x# max maintainers [$email_git_max_maintainers]
1441+t all signature types [$email_git_all_signature_types]
1442+m use .mailmap [$email_use_mailmap]
1443+EOT
1444+ }
1445+ print STDERR <<EOT
1446+
1447+Additional options:
1448+0 toggle all
1449+tm toggle maintainers
1450+tg toggle git entries
1451+tl toggle open list entries
1452+ts toggle subscriber list entries
1453+f emails in file [$file_emails]
1454+k keywords in file [$keywords]
1455+r remove duplicates [$email_remove_duplicates]
1456+p# pattern match depth [$pattern_depth]
1457+EOT
1458+ }
1459+ print STDERR
1460+"\n#(toggle), A#(author), S#(signed) *(all), ^(none), O(options), Y(approve): ";
1461+
1462+ my $input = <STDIN>;
1463+ chomp($input);
1464+
1465+ $redraw = 1;
1466+ my $rerun = 0;
1467+ my @wish = split(/[, ]+/, $input);
1468+ foreach my $nr (@wish) {
1469+ $nr = lc($nr);
1470+ my $sel = substr($nr, 0, 1);
1471+ my $str = substr($nr, 1);
1472+ my $val = 0;
1473+ $val = $1 if $str =~ /^(\d+)$/;
1474+
1475+ if ($sel eq "y") {
1476+ $interactive = 0;
1477+ $done = 1;
1478+ $output_rolestats = 0;
1479+ $output_roles = 0;
1480+ last;
1481+ } elsif ($nr =~ /^\d+$/ && $nr > 0 && $nr <= $count) {
1482+ $selected{$nr - 1} = !$selected{$nr - 1};
1483+ } elsif ($sel eq "*" || $sel eq '^') {
1484+ my $toggle = 0;
1485+ $toggle = 1 if ($sel eq '*');
1486+ for (my $i = 0; $i < $count; $i++) {
1487+ $selected{$i} = $toggle;
1488+ }
1489+ } elsif ($sel eq "0") {
1490+ for (my $i = 0; $i < $count; $i++) {
1491+ $selected{$i} = !$selected{$i};
1492+ }
1493+ } elsif ($sel eq "t") {
1494+ if (lc($str) eq "m") {
1495+ for (my $i = 0; $i < $count; $i++) {
1496+ $selected{$i} = !$selected{$i}
1497+ if ($list[$i]->[1] =~ /^(maintainer|supporter)/i);
1498+ }
1499+ } elsif (lc($str) eq "g") {
1500+ for (my $i = 0; $i < $count; $i++) {
1501+ $selected{$i} = !$selected{$i}
1502+ if ($list[$i]->[1] =~ /^(author|commit|signer)/i);
1503+ }
1504+ } elsif (lc($str) eq "l") {
1505+ for (my $i = 0; $i < $count; $i++) {
1506+ $selected{$i} = !$selected{$i}
1507+ if ($list[$i]->[1] =~ /^(open list)/i);
1508+ }
1509+ } elsif (lc($str) eq "s") {
1510+ for (my $i = 0; $i < $count; $i++) {
1511+ $selected{$i} = !$selected{$i}
1512+ if ($list[$i]->[1] =~ /^(subscriber list)/i);
1513+ }
1514+ }
1515+ } elsif ($sel eq "a") {
1516+ if ($val > 0 && $val <= $count) {
1517+ $authored{$val - 1} = !$authored{$val - 1};
1518+ } elsif ($str eq '*' || $str eq '^') {
1519+ my $toggle = 0;
1520+ $toggle = 1 if ($str eq '*');
1521+ for (my $i = 0; $i < $count; $i++) {
1522+ $authored{$i} = $toggle;
1523+ }
1524+ }
1525+ } elsif ($sel eq "s") {
1526+ if ($val > 0 && $val <= $count) {
1527+ $signed{$val - 1} = !$signed{$val - 1};
1528+ } elsif ($str eq '*' || $str eq '^') {
1529+ my $toggle = 0;
1530+ $toggle = 1 if ($str eq '*');
1531+ for (my $i = 0; $i < $count; $i++) {
1532+ $signed{$i} = $toggle;
1533+ }
1534+ }
1535+ } elsif ($sel eq "o") {
1536+ $print_options = 1;
1537+ $redraw = 1;
1538+ } elsif ($sel eq "g") {
1539+ if ($str eq "f") {
1540+ bool_invert(\$email_git_fallback);
1541+ } else {
1542+ bool_invert(\$email_git);
1543+ }
1544+ $rerun = 1;
1545+ } elsif ($sel eq "b") {
1546+ if ($str eq "s") {
1547+ bool_invert(\$email_git_blame_signatures);
1548+ } else {
1549+ bool_invert(\$email_git_blame);
1550+ }
1551+ $rerun = 1;
1552+ } elsif ($sel eq "c") {
1553+ if ($val > 0) {
1554+ $email_git_min_signatures = $val;
1555+ $rerun = 1;
1556+ }
1557+ } elsif ($sel eq "x") {
1558+ if ($val > 0) {
1559+ $email_git_max_maintainers = $val;
1560+ $rerun = 1;
1561+ }
1562+ } elsif ($sel eq "%") {
1563+ if ($str ne "" && $val >= 0) {
1564+ $email_git_min_percent = $val;
1565+ $rerun = 1;
1566+ }
1567+ } elsif ($sel eq "d") {
1568+ if (vcs_is_git()) {
1569+ $email_git_since = $str;
1570+ } elsif (vcs_is_hg()) {
1571+ $email_hg_since = $str;
1572+ }
1573+ $rerun = 1;
1574+ } elsif ($sel eq "t") {
1575+ bool_invert(\$email_git_all_signature_types);
1576+ $rerun = 1;
1577+ } elsif ($sel eq "f") {
1578+ bool_invert(\$file_emails);
1579+ $rerun = 1;
1580+ } elsif ($sel eq "r") {
1581+ bool_invert(\$email_remove_duplicates);
1582+ $rerun = 1;
1583+ } elsif ($sel eq "m") {
1584+ bool_invert(\$email_use_mailmap);
1585+ read_mailmap();
1586+ $rerun = 1;
1587+ } elsif ($sel eq "k") {
1588+ bool_invert(\$keywords);
1589+ $rerun = 1;
1590+ } elsif ($sel eq "p") {
1591+ if ($str ne "" && $val >= 0) {
1592+ $pattern_depth = $val;
1593+ $rerun = 1;
1594+ }
1595+ } elsif ($sel eq "h" || $sel eq "?") {
1596+ print STDERR <<EOT
1597+
1598+Interactive mode allows you to select the various maintainers, submitters,
1599+commit signers and mailing lists that could be CC'd on a patch.
1600+
1601+Any *'d entry is selected.
1602+
1603+If you have git or hg installed, you can choose to summarize the commit
1604+history of files in the patch. Also, each line of the current file can
1605+be matched to its commit author and that commits signers with blame.
1606+
1607+Various knobs exist to control the length of time for active commit
1608+tracking, the maximum number of commit authors and signers to add,
1609+and such.
1610+
1611+Enter selections at the prompt until you are satisfied that the selected
1612+maintainers are appropriate. You may enter multiple selections separated
1613+by either commas or spaces.
1614+
1615+EOT
1616+ } else {
1617+ print STDERR "invalid option: '$nr'\n";
1618+ $redraw = 0;
1619+ }
1620+ }
1621+ if ($rerun) {
1622+ print STDERR "git-blame can be very slow, please have patience..."
1623+ if ($email_git_blame);
1624+ goto &get_maintainers;
1625+ }
1626+ }
1627+
1628+ #drop not selected entries
1629+ $count = 0;
1630+ my @new_emailto = ();
1631+ foreach my $entry (@list) {
1632+ if ($selected{$count}) {
1633+ push(@new_emailto, $list[$count]);
1634+ }
1635+ $count++;
1636+ }
1637+ return @new_emailto;
1638+}
1639+
1640+sub bool_invert {
1641+ my ($bool_ref) = @_;
1642+
1643+ if ($$bool_ref) {
1644+ $$bool_ref = 0;
1645+ } else {
1646+ $$bool_ref = 1;
1647+ }
1648+}
1649+
1650+sub deduplicate_email {
1651+ my ($email) = @_;
1652+
1653+ my $matched = 0;
1654+ my ($name, $address) = parse_email($email);
1655+ $email = format_email($name, $address, 1);
1656+ $email = mailmap_email($email);
1657+
1658+ return $email if (!$email_remove_duplicates);
1659+
1660+ ($name, $address) = parse_email($email);
1661+
1662+ if ($name ne "" && $deduplicate_name_hash{lc($name)}) {
1663+ $name = $deduplicate_name_hash{lc($name)}->[0];
1664+ $address = $deduplicate_name_hash{lc($name)}->[1];
1665+ $matched = 1;
1666+ } elsif ($deduplicate_address_hash{lc($address)}) {
1667+ $name = $deduplicate_address_hash{lc($address)}->[0];
1668+ $address = $deduplicate_address_hash{lc($address)}->[1];
1669+ $matched = 1;
1670+ }
1671+ if (!$matched) {
1672+ $deduplicate_name_hash{lc($name)} = [ $name, $address ];
1673+ $deduplicate_address_hash{lc($address)} = [ $name, $address ];
1674+ }
1675+ $email = format_email($name, $address, 1);
1676+ $email = mailmap_email($email);
1677+ return $email;
1678+}
1679+
1680+sub save_commits_by_author {
1681+ my (@lines) = @_;
1682+
1683+ my @authors = ();
1684+ my @commits = ();
1685+ my @subjects = ();
1686+
1687+ foreach my $line (@lines) {
1688+ if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
1689+ my $author = $1;
1690+ $author = deduplicate_email($author);
1691+ push(@authors, $author);
1692+ }
1693+ push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
1694+ push(@subjects, $1) if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
1695+ }
1696+
1697+ for (my $i = 0; $i < @authors; $i++) {
1698+ my $exists = 0;
1699+ foreach my $ref(@{$commit_author_hash{$authors[$i]}}) {
1700+ if (@{$ref}[0] eq $commits[$i] &&
1701+ @{$ref}[1] eq $subjects[$i]) {
1702+ $exists = 1;
1703+ last;
1704+ }
1705+ }
1706+ if (!$exists) {
1707+ push(@{$commit_author_hash{$authors[$i]}},
1708+ [ ($commits[$i], $subjects[$i]) ]);
1709+ }
1710+ }
1711+}
1712+
1713+sub save_commits_by_signer {
1714+ my (@lines) = @_;
1715+
1716+ my $commit = "";
1717+ my $subject = "";
1718+
1719+ foreach my $line (@lines) {
1720+ $commit = $1 if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
1721+ $subject = $1 if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
1722+ if ($line =~ /^[ \t]*${signature_pattern}.*\@.*$/) {
1723+ my @signatures = ($line);
1724+ my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
1725+ my @types = @$types_ref;
1726+ my @signers = @$signers_ref;
1727+
1728+ my $type = $types[0];
1729+ my $signer = $signers[0];
1730+
1731+ $signer = deduplicate_email($signer);
1732+
1733+ my $exists = 0;
1734+ foreach my $ref(@{$commit_signer_hash{$signer}}) {
1735+ if (@{$ref}[0] eq $commit &&
1736+ @{$ref}[1] eq $subject &&
1737+ @{$ref}[2] eq $type) {
1738+ $exists = 1;
1739+ last;
1740+ }
1741+ }
1742+ if (!$exists) {
1743+ push(@{$commit_signer_hash{$signer}},
1744+ [ ($commit, $subject, $type) ]);
1745+ }
1746+ }
1747+ }
1748+}
1749+
11071750 sub vcs_assign {
11081751 my ($role, $divisor, @lines) = @_;
11091752
@@ -1117,9 +1760,9 @@ sub vcs_assign { · 7 unmodified lines
11171760 $divisor = 1;
11181761 }
11191762
1120− if ($email_remove_duplicates) {
1121− @lines = mailmap(@lines);
1122− }
1763+ @lines = mailmap(@lines);
1764+
1765+ return if (@lines <= 0);
11231766
11241767 @lines = sort(@lines);
11251768
@@ -1152,12 +1795,18 @@ sub vcs_file_signoffs { · 26 unmodified lines
11521795 my @signers = ();
11531796 my $commits;
11541797
1155− return if (!vcs_exists());
1798+ $vcs_used = vcs_exists();
1799+ return if (!$vcs_used);
11561800
11571801 my $cmd = $VCS_cmds{"find_signers_cmd"};
11581802 $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
11591803
11601804 ($commits, @signers) = vcs_find_signers($cmd);
1805+
1806+ foreach my $signer (@signers) {
1807+ $signer = deduplicate_email($signer);
1808+ }
1809+
11611810 vcs_assign("commit_signer", $commits, @signers);
11621811 }
11631812
@@ -1165,29 +1814,114 @@ sub vcs_file_blame { · 1 unmodified line
11651814 my ($file) = @_;
11661815
11671816 my @signers = ();
1817+ my @all_commits = ();
11681818 my @commits = ();
11691819 my $total_commits;
1820+ my $total_lines;
11701821
1171− return if (!vcs_exists());
1822+ $vcs_used = vcs_exists();
1823+ return if (!$vcs_used);
11721824
1173− @commits = vcs_blame($file);
1174− @commits = uniq(@commits);
1825+ @all_commits = vcs_blame($file);
1826+ @commits = uniq(@all_commits);
11751827 $total_commits = @commits;
1828+ $total_lines = @all_commits;
11761829
1177− foreach my $commit (@commits) {
1178− my $commit_count;
1179− my @commit_signers = ();
1830+ if ($email_git_blame_signatures) {
1831+ if (vcs_is_hg()) {
1832+ my $commit_count;
1833+ my @commit_signers = ();
1834+ my $commit = join(" -r ", @commits);
1835+ my $cmd;
1836+
1837+ $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1838+ $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
1839+
1840+ ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1841+
1842+ push(@signers, @commit_signers);
1843+ } else {
1844+ foreach my $commit (@commits) {
1845+ my $commit_count;
1846+ my @commit_signers = ();
1847+ my $cmd;
11801848
1181− my $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1182− $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1849+ $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1850+ $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
11831851
1184− ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1185− push(@signers, @commit_signers);
1852+ ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1853+
1854+ push(@signers, @commit_signers);
1855+ }
1856+ }
11861857 }
11871858
11881859 if ($from_filename) {
1860+ if ($output_rolestats) {
1861+ my @blame_signers;
1862+ if (vcs_is_hg()) {{ # Double brace for last exit
1863+ my $commit_count;
1864+ my @commit_signers = ();
1865+ @commits = uniq(@commits);
1866+ @commits = sort(@commits);
1867+ my $commit = join(" -r ", @commits);
1868+ my $cmd;
1869+
1870+ $cmd = $VCS_cmds{"find_commit_author_cmd"};
1871+ $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
1872+
1873+ my @lines = ();
1874+
1875+ @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1876+
1877+ if (!$email_git_penguin_chiefs) {
1878+ @lines = grep(!/${penguin_chiefs}/i, @lines);
1879+ }
1880+
1881+ last if !@lines;
1882+
1883+ my @authors = ();
1884+ foreach my $line (@lines) {
1885+ if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
1886+ my $author = $1;
1887+ $author = deduplicate_email($author);
1888+ push(@authors, $author);
1889+ }
1890+ }
1891+
1892+ save_commits_by_author(@lines) if ($interactive);
1893+ save_commits_by_signer(@lines) if ($interactive);
1894+
1895+ push(@signers, @authors);
1896+ }}
1897+ else {
1898+ foreach my $commit (@commits) {
1899+ my $i;
1900+ my $cmd = $VCS_cmds{"find_commit_author_cmd"};
1901+ $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1902+ my @author = vcs_find_author($cmd);
1903+ next if !@author;
1904+
1905+ my $formatted_author = deduplicate_email($author[0]);
1906+
1907+ my $count = grep(/$commit/, @all_commits);
1908+ for ($i = 0; $i < $count ; $i++) {
1909+ push(@blame_signers, $formatted_author);
1910+ }
1911+ }
1912+ }
1913+ if (@blame_signers) {
1914+ vcs_assign("authored lines", $total_lines, @blame_signers);
1915+ }
1916+ }
1917+ foreach my $signer (@signers) {
1918+ $signer = deduplicate_email($signer);
1919+ }
11891920 vcs_assign("commits", $total_commits, @signers);
11901921 } else {
1922+ foreach my $signer (@signers) {
1923+ $signer = deduplicate_email($signer);
1924+ }
11911925 vcs_assign("modified commits", $total_commits, @signers);
11921926 }
11931927 }
scripts/kconfig/.gitignore+1−0
@@ -17,6 +17,7 @@ gconf.glade.h · 16 unmodified lines
1717 #
1818 conf
1919 mconf
20+nconf
2021 qconf
2122 gconf
2223 kxgettext
scripts/kconfig/Makefile+87−77
@@ -8,7 +8,7 @@ PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-c · 7 unmodified lines
88 ifdef KBUILD_KCONFIG
99 Kconfig := $(KBUILD_KCONFIG)
1010 else
11−Kconfig := arch/$(SRCARCH)/Kconfig
11+Kconfig := Kconfig
1212 endif
1313
1414 xconfig: $(obj)/qconf
@@ -21,17 +21,17 @@ menuconfig: $(obj)/mconf · 6 unmodified lines
2121 $< $(Kconfig)
2222
2323 config: $(obj)/conf
24− $< $(Kconfig)
24+ $< --oldaskconfig $(Kconfig)
2525
2626 nconfig: $(obj)/nconf
2727 $< $(Kconfig)
2828
2929 oldconfig: $(obj)/conf
30− $< -o $(Kconfig)
30+ $< --$@ $(Kconfig)
3131
3232 silentoldconfig: $(obj)/conf
3333 $(Q)mkdir -p include/generated
34− $< -s $(Kconfig)
34+ $< --$@ $(Kconfig)
3535
3636 # if no path is given, then use src directory to find file
3737 ifdef LSMOD
@@ -44,15 +44,15 @@ endif · 6 unmodified lines
4444 localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
4545 $(Q)mkdir -p include/generated
4646 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
47− $(Q)if [ -f .config ]; then \
48− cmp -s .tmp.config .config || \
49− (mv -f .config .config.old.1; \
50− mv -f .tmp.config .config; \
51− $(obj)/conf -s $(Kconfig); \
52− mv -f .config.old.1 .config.old) \
53− else \
54− mv -f .tmp.config .config; \
55− $(obj)/conf -s $(Kconfig); \
47+ $(Q)if [ -f .config ]; then \
48+ cmp -s .tmp.config .config || \
49+ (mv -f .config .config.old.1; \
50+ mv -f .tmp.config .config; \
51+ $(obj)/conf --silentoldconfig $(Kconfig); \
52+ mv -f .config.old.1 .config.old) \
53+ else \
54+ mv -f .tmp.config .config; \
55+ $(obj)/conf --silentoldconfig $(Kconfig); \
5656 fi
5757 $(Q)rm -f .tmp.config
5858
@@ -60,15 +60,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf · 1 unmodified line
6060 $(Q)mkdir -p include/generated
6161 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
6262 $(Q)sed -i s/=m/=y/ .tmp.config
63− $(Q)if [ -f .config ]; then \
64− cmp -s .tmp.config .config || \
65− (mv -f .config .config.old.1; \
66− mv -f .tmp.config .config; \
67− $(obj)/conf -s $(Kconfig); \
68− mv -f .config.old.1 .config.old) \
69− else \
70− mv -f .tmp.config .config; \
71− $(obj)/conf -s $(Kconfig); \
63+ $(Q)if [ -f .config ]; then \
64+ cmp -s .tmp.config .config || \
65+ (mv -f .config .config.old.1; \
66+ mv -f .tmp.config .config; \
67+ $(obj)/conf --silentoldconfig $(Kconfig); \
68+ mv -f .config.old.1 .config.old) \
69+ else \
70+ mv -f .tmp.config .config; \
71+ $(obj)/conf --silentoldconfig $(Kconfig); \
7272 fi
7373 $(Q)rm -f .tmp.config
7474
@@ -95,30 +95,29 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h · 20 unmodified lines
9595 $(Q)rm -f arch/um/Kconfig.arch
9696 $(Q)rm -f $(obj)/config.pot
9797
98−PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
98+PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
9999
100−randconfig: $(obj)/conf
101− $< -r $(Kconfig)
100+allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
101+ $< --$@ $(Kconfig)
102102
103−allyesconfig: $(obj)/conf
104− $< -y $(Kconfig)
103+PHONY += listnewconfig oldnoconfig savedefconfig defconfig
105104
106−allnoconfig: $(obj)/conf
107− $< -n $(Kconfig)
105+listnewconfig oldnoconfig: $(obj)/conf
106+ $< --$@ $(Kconfig)
108107
109−allmodconfig: $(obj)/conf
110− $< -m $(Kconfig)
108+savedefconfig: $(obj)/conf
109+ $< --$@=defconfig $(Kconfig)
111110
112111 defconfig: $(obj)/conf
113112 ifeq ($(KBUILD_DEFCONFIG),)
114− $< -d $(Kconfig)
113+ $< --defconfig $(Kconfig)
115114 else
116115 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
117− $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
116+ $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
118117 endif
119118
120119 %_defconfig: $(obj)/conf
121− $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig)
120+ $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
122121
123122 # Help text used by make help
124123 help:
@@ -131,22 +130,23 @@ help: · 6 unmodified lines
131130 @echo ' localmodconfig - Update current config disabling modules not loaded'
132131 @echo ' localyesconfig - Update current config converting local mods to core'
133132 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
134− @echo ' randconfig - New config with random answer to all options'
135− @echo ' defconfig - New config with default answer to all options'
136− @echo ' allmodconfig - New config selecting modules when possible'
137− @echo ' allyesconfig - New config where all options are accepted with yes'
133+ @echo ' defconfig - New config with default from ARCH supplied defconfig'
134+ @echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
138135 @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)'
139142
140143 # lxdialog stuff
141144 check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
142145
143146 # Use recursively expanded variables so we do not call gcc unless
144147 # we really need to do so. (Do not call gcc as part of make mrproper)
145−HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
146−HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
147−
148−HOST_EXTRACFLAGS += -DLOCALE
149−
148+HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
149+ -DLOCALE
150150
151151 # ===========================================================================
152152 # Shared Makefile for the various kconfig executables:
@@ -205,7 +205,7 @@ clean-files += config.pot linux.pot · 52 unmodified lines
205205 PHONY += $(obj)/dochecklxdialog
206206 $(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
207207 $(obj)/dochecklxdialog:
208− $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES)
208+ $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
209209
210210 always := dochecklxdialog
211211
@@ -223,6 +223,8 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl · 11 unmodified lines
223223 HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
224224 -D LKC_DIRECT_LINK
225225
226+HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
227+
226228 HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
227229 $(obj)/qconf.o: $(obj)/.tmp_qtcheck
228230
@@ -233,40 +235,48 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile · 4 unmodified lines
233235 # QT needs some extra effort...
234236 $(obj)/.tmp_qtcheck:
235237 @set -e; echo " CHECK qt"; dir=""; pkg=""; \
236− pkg-config --exists qt 2> /dev/null && pkg=qt; \
237− pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
238− if [ -n "$$pkg" ]; then \
239− cflags="\$$(shell pkg-config $$pkg --cflags)"; \
240− libs="\$$(shell pkg-config $$pkg --libs)"; \
241− moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
242− dir="$$(pkg-config $$pkg --variable=prefix)"; \
238+ if ! pkg-config --exists QtCore 2> /dev/null; then \
239+ echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \
240+ pkg-config --exists qt 2> /dev/null && pkg=qt; \
241+ pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
242+ if [ -n "$$pkg" ]; then \
243+ cflags="\$$(shell pkg-config $$pkg --cflags)"; \
244+ libs="\$$(shell pkg-config $$pkg --libs)"; \
245+ moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
246+ dir="$$(pkg-config $$pkg --variable=prefix)"; \
247+ else \
248+ for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
249+ if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
250+ done; \
251+ if [ -z "$$dir" ]; then \
252+ echo "*"; \
253+ echo "* Unable to find any QT installation. Please make sure that"; \
254+ echo "* the QT4 or QT3 development package is correctly installed and"; \
255+ echo "* either qmake can be found or install pkg-config or set"; \
256+ echo "* the QTDIR environment variable to the correct location."; \
257+ echo "*"; \
258+ false; \
259+ fi; \
260+ libpath=$$dir/lib; lib=qt; osdir=""; \
261+ $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
262+ osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
263+ test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
264+ test -f $$libpath/libqt-mt.so && lib=qt-mt; \
265+ cflags="-I$$dir/include"; \
266+ libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
267+ moc="$$dir/bin/moc"; \
268+ fi; \
269+ if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
270+ echo "*"; \
271+ echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
272+ echo "*"; \
273+ moc="/usr/bin/moc"; \
274+ fi; \
243275 else \
244− for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
245− if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
246− done; \
247− if [ -z "$$dir" ]; then \
248− echo "*"; \
249− echo "* Unable to find the QT3 installation. Please make sure that"; \
250− echo "* the QT3 development package is correctly installed and"; \
251− echo "* either install pkg-config or set the QTDIR environment"; \
252− echo "* variable to the correct location."; \
253− echo "*"; \
254− false; \
255− fi; \
256− libpath=$$dir/lib; lib=qt; osdir=""; \
257− $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
258− osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
259− test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
260− test -f $$libpath/libqt-mt.so && lib=qt-mt; \
261− cflags="-I$$dir/include"; \
262− libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
263− moc="$$dir/bin/moc"; \
264− fi; \
265− if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
266− echo "*"; \
267− echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
268− echo "*"; \
269− moc="/usr/bin/moc"; \
276+ cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \
277+ libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \
278+ binpath="\$$(shell pkg-config QtCore --variable=prefix)"; \
279+ moc="$$binpath/bin/moc"; \
270280 fi; \
271281 echo "KC_QT_CFLAGS=$$cflags" > $@; \
272282 echo "KC_QT_LIBS=$$libs" >> $@; \
scripts/kconfig/conf.c+123−84
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <string.h>
1111 #include <time.h>
1212 #include <unistd.h>
13+#include <getopt.h>
1314 #include <sys/stat.h>
1415 #include <sys/time.h>
1516
@@ -19,16 +20,21 @@ · 3 unmodified lines
1920 static void conf(struct menu *menu);
2021 static void check_conf(struct menu *menu);
2122
22−enum {
23− ask_all,
24− ask_new,
25− ask_silent,
26− set_default,
27− set_yes,
28− set_mod,
29− set_no,
30− set_random
31−} input_mode = ask_all;
23+enum input_mode {
24+ oldaskconfig,
25+ silentoldconfig,
26+ oldconfig,
27+ allnoconfig,
28+ allyesconfig,
29+ allmodconfig,
30+ alldefconfig,
31+ randconfig,
32+ defconfig,
33+ savedefconfig,
34+ listnewconfig,
35+ oldnoconfig,
36+} input_mode = oldaskconfig;
37+
3238 char *defconfig_file;
3339
3440 static int indent = 1;
@@ -93,16 +99,16 @@ static int conf_askvalue(struct symbol *sym, const char *def) · 58 unmodified lines
9399 }
94100
95101 switch (input_mode) {
96− case ask_new:
97− case ask_silent:
102+ case oldconfig:
103+ case silentoldconfig:
98104 if (sym_has_value(sym)) {
99105 printf("%s\n", def);
100106 return 0;
101107 }
102108 check_stdin();
103− case ask_all:
109+ case oldaskconfig:
104110 fflush(stdout);
105− fgets(line, 128, stdin);
111+ xfgets(line, 128, stdin);
106112 return 1;
107113 default:
108114 break;
@@ -156,14 +162,12 @@ static int conf_string(struct menu *menu) · 47 unmodified lines
156162 static int conf_sym(struct menu *menu)
157163 {
158164 struct symbol *sym = menu->sym;
159− int type;
160165 tristate oldval, newval;
161166
162167 while (1) {
163168 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
164169 if (sym->name)
165170 printf("(%s) ", sym->name);
166− type = sym_get_type(sym);
167171 putchar('[');
168172 oldval = sym_get_tristate_value(sym);
169173 switch (oldval) {
@@ -228,11 +232,9 @@ static int conf_choice(struct menu *menu) · 58 unmodified lines
228232 {
229233 struct symbol *sym, *def_sym;
230234 struct menu *child;
231− int type;
232235 bool is_new;
233236
234237 sym = menu->sym;
235− type = sym_get_type(sym);
236238 is_new = !sym_has_value(sym);
237239 if (sym_is_changable(sym)) {
238240 conf_sym(menu);
@@ -294,17 +296,17 @@ static int conf_choice(struct menu *menu) · 55 unmodified lines
294296 printf("?");
295297 printf("]: ");
296298 switch (input_mode) {
297− case ask_new:
298− case ask_silent:
299+ case oldconfig:
300+ case silentoldconfig:
299301 if (!is_new) {
300302 cnt = def;
301303 printf("%d\n", cnt);
302304 break;
303305 }
304306 check_stdin();
305− case ask_all:
307+ case oldaskconfig:
306308 fflush(stdout);
307− fgets(line, 128, stdin);
309+ xfgets(line, 128, stdin);
308310 strip(line);
309311 if (line[0] == '?') {
310312 print_help(menu);
@@ -360,7 +362,10 @@ static void conf(struct menu *menu) · 49 unmodified lines
360362
361363 switch (prop->type) {
362364 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) {
364369 check_conf(menu);
365370 return;
366371 }
@@ -418,10 +423,16 @@ static void check_conf(struct menu *menu) · 51 unmodified lines
418423 if (sym && !sym_has_value(sym)) {
419424 if (sym_is_changable(sym) ||
420425 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
421− if (!conf_cnt++)
422− printf(_("*\n* Restart config...\n*\n"));
423− rootEntry = menu_get_parent_menu(menu);
424− conf(rootEntry);
426+ if (input_mode == listnewconfig) {
427+ if (sym->name && !sym_is_choice_value(sym)) {
428+ printf("%s%s\n", CONFIG_, sym->name);
429+ }
430+ } else if (input_mode != oldnoconfig) {
431+ if (!conf_cnt++)
432+ printf(_("*\n* Restart config...\n*\n"));
433+ rootEntry = menu_get_parent_menu(menu);
434+ conf(rootEntry);
435+ }
425436 }
426437 }
427438
@@ -429,6 +440,22 @@ static void check_conf(struct menu *menu) · 1 unmodified line
429440 check_conf(child);
430441 }
431442
443+static 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+
432459 int main(int ac, char **av)
433460 {
434461 int opt;
@@ -439,32 +466,17 @@ int main(int ac, char **av) · 4 unmodified lines
439466 bindtextdomain(PACKAGE, LOCALEDIR);
440467 textdomain(PACKAGE);
441468
442− while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
469+ while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) {
470+ input_mode = (enum input_mode)opt;
443471 switch (opt) {
444− case 'o':
445− input_mode = ask_silent;
446− break;
447− case 's':
448− input_mode = ask_silent;
472+ case silentoldconfig:
449473 sync_kconfig = 1;
450474 break;
451− case 'd':
452− input_mode = set_default;
453− break;
454− case 'D':
455− input_mode = set_default;
475+ case defconfig:
476+ case savedefconfig:
456477 defconfig_file = optarg;
457478 break;
458− case 'n':
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':
479+ case randconfig:
468480 {
469481 struct timeval now;
470482 unsigned int seed;
@@ -477,17 +489,12 @@ int main(int ac, char **av) · 6 unmodified lines
477489
478490 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
479491 srand(seed);
480−
481− input_mode = set_random;
482492 break;
483493 }
484− case 'h':
485− printf(_("See README for usage info\n"));
486− exit(0);
487− break;
488− default:
494+ case '?':
489495 fprintf(stderr, _("See README for usage info\n"));
490496 exit(1);
497+ break;
491498 }
492499 }
493500 if (ac == optind) {
@@ -501,8 +508,7 @@ int main(int ac, char **av) · 7 unmodified lines
501508 name = conf_get_configname();
502509 if (stat(name, &tmpstat)) {
503510 fprintf(stderr, _("***\n"
504− "*** You have not yet configured your kernel!\n"
505− "*** (missing kernel config file \"%s\")\n"
511+ "*** Configuration file \"%s\" not found!\n"
506512 "***\n"
507513 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
508514 "*** \"make menuconfig\" or \"make xconfig\").\n"
@@ -512,7 +518,7 @@ int main(int ac, char **av) · 3 unmodified lines
512518 }
513519
514520 switch (input_mode) {
515− case set_default:
521+ case defconfig:
516522 if (!defconfig_file)
517523 defconfig_file = conf_get_default_confname();
518524 if (conf_read(defconfig_file)) {
@@ -522,25 +528,32 @@ int main(int ac, char **av) · 3 unmodified lines
522528 exit(1);
523529 }
524530 break;
525− case ask_silent:
526− case ask_all:
527− case ask_new:
531+ case savedefconfig:
532+ conf_read(NULL);
533+ break;
534+ case silentoldconfig:
535+ case oldaskconfig:
536+ case oldconfig:
537+ case listnewconfig:
538+ case oldnoconfig:
528539 conf_read(NULL);
529540 break;
530− case set_no:
531− case set_mod:
532− case set_yes:
533− case set_random:
541+ case allnoconfig:
542+ case allyesconfig:
543+ case allmodconfig:
544+ case alldefconfig:
545+ case randconfig:
534546 name = getenv("KCONFIG_ALLCONFIG");
535547 if (name && !stat(name, &tmpstat)) {
536548 conf_read_simple(name, S_DEF_USER);
537549 break;
538550 }
539551 switch (input_mode) {
540− case set_no: name = "allno.config"; break;
541− case set_mod: name = "allmod.config"; break;
542− case set_yes: name = "allyes.config"; break;
543− case set_random: name = "allrandom.config"; break;
552+ case allnoconfig: name = "allno.config"; break;
553+ case allyesconfig: name = "allyes.config"; break;
554+ case allmodconfig: name = "allmod.config"; break;
555+ case alldefconfig: name = "alldef.config"; break;
556+ case randconfig: name = "allrandom.config"; break;
544557 default: break;
545558 }
546559 if (!stat(name, &tmpstat))
@@ -557,7 +570,7 @@ int main(int ac, char **av) · 10 unmodified lines
557570 name = getenv("KCONFIG_NOSILENTUPDATE");
558571 if (name && *name) {
559572 fprintf(stderr,
560− _("\n*** Kernel configuration requires explicit update.\n\n"));
573+ _("\n*** The configuration requires explicit update.\n\n"));
561574 return 1;
562575 }
563576 }
@@ -565,33 +578,42 @@ int main(int ac, char **av) · 1 unmodified line
565578 }
566579
567580 switch (input_mode) {
568− case set_no:
581+ case allnoconfig:
569582 conf_set_all_new_symbols(def_no);
570583 break;
571− case set_yes:
584+ case allyesconfig:
572585 conf_set_all_new_symbols(def_yes);
573586 break;
574− case set_mod:
587+ case allmodconfig:
575588 conf_set_all_new_symbols(def_mod);
576589 break;
577− case set_random:
590+ case alldefconfig:
591+ conf_set_all_new_symbols(def_default);
592+ break;
593+ case randconfig:
578594 conf_set_all_new_symbols(def_random);
579595 break;
580− case set_default:
596+ case defconfig:
581597 conf_set_all_new_symbols(def_default);
582598 break;
583− case ask_new:
584− case ask_all:
599+ case savedefconfig:
600+ break;
601+ case oldaskconfig:
585602 rootEntry = &rootmenu;
586603 conf(&rootmenu);
587− input_mode = ask_silent;
604+ input_mode = silentoldconfig;
588605 /* fall through */
589− case ask_silent:
606+ case oldconfig:
607+ case listnewconfig:
608+ case oldnoconfig:
609+ case silentoldconfig:
590610 /* Update until a loop caused no more changes */
591611 do {
592612 conf_cnt = 0;
593613 check_conf(&rootmenu);
594− } while (conf_cnt);
614+ } while (conf_cnt &&
615+ (input_mode != listnewconfig &&
616+ input_mode != oldnoconfig));
595617 break;
596618 }
597619
@@ -600,18 +622,35 @@ int main(int ac, char **av) · 2 unmodified lines
600622 * All other commands are only used to generate a config.
601623 */
602624 if (conf_get_changed() && conf_write(NULL)) {
603− fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
625+ fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
604626 exit(1);
605627 }
606628 if (conf_write_autoconf()) {
607− fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
629+ fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
608630 return 1;
609631 }
610− } else {
632+ } else if (input_mode == savedefconfig) {
633+ if (conf_write_defconfig(defconfig_file)) {
634+ fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
635+ defconfig_file);
636+ return 1;
637+ }
638+ } else if (input_mode != listnewconfig) {
611639 if (conf_write(NULL)) {
612− fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
640+ fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
613641 exit(1);
614642 }
615643 }
616644 return 0;
617645 }
646+/*
647+ * Helper function to facilitate fgets() by Jean Sacren.
648+ */
649+void xfgets(str, size, in)
650+ char *str;
651+ int size;
652+ FILE *in;
653+{
654+ if (fgets(str, size, in) == NULL)
655+ fprintf(stderr, "\nError in reading or end of file.\n");
656+}
scripts/kconfig/confdata.c+285−151
@@ -5,6 +5,7 @@ · 4 unmodified lines
55
66 #include <sys/stat.h>
77 #include <ctype.h>
8+#include <errno.h>
89 #include <fcntl.h>
910 #include <stdio.h>
1011 #include <stdlib.h>
@@ -18,6 +19,9 @@ · 7 unmodified lines
1819 static void conf_warning(const char *fmt, ...)
1920 __attribute__ ((format (printf, 1, 2)));
2021
22+static void conf_message(const char *fmt, ...)
23+ __attribute__ ((format (printf, 1, 2)));
24+
2125 static const char *conf_filename;
2226 static int conf_lineno, conf_warnings, conf_unsaved;
2327
@@ -34,6 +38,29 @@ static void conf_warning(const char *fmt, ...) · 10 unmodified lines
3438 conf_warnings++;
3539 }
3640
41+static void conf_default_message_callback(const char *fmt, va_list ap)
42+{
43+ printf("#\n# ");
44+ vprintf(fmt, ap);
45+ printf("\n#\n");
46+}
47+
48+static void (*conf_message_callback) (const char *fmt, va_list ap) =
49+ conf_default_message_callback;
50+void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
51+{
52+ conf_message_callback = fn;
53+}
54+
55+static void conf_message(const char *fmt, ...)
56+{
57+ va_list ap;
58+
59+ va_start(ap, fmt);
60+ if (conf_message_callback)
61+ conf_message_callback(fmt, ap);
62+}
63+
3764 const char *conf_get_configname(void)
3865 {
3966 char *name = getenv("KCONFIG_CONFIG");
@@ -170,8 +197,11 @@ int conf_read_simple(const char *name, int def) · 130 unmodified lines
170197 if (in)
171198 goto load;
172199 sym_add_change_count(1);
173− if (!sym_defconfig_list)
200+ if (!sym_defconfig_list) {
201+ if (modules_sym)
202+ sym_calc_value(modules_sym);
174203 return 1;
204+ }
175205
176206 for_all_defaults(sym_defconfig_list, prop) {
177207 if (expr_calc_value(prop->visible.expr) == no ||
@@ -180,9 +210,8 @@ int conf_read_simple(const char *name, int def) · 2 unmodified lines
180210 name = conf_expand_value(prop->expr->left.sym->name);
181211 in = zconf_fopen(name);
182212 if (in) {
183− printf(_("#\n"
184− "# using defaults found in %s\n"
185− "#\n"), name);
213+ conf_message(_("using defaults found in %s"),
214+ name);
186215 goto load;
187216 }
188217 }
@@ -217,24 +246,23 @@ load: · 28 unmodified lines
217246 while (fgets(line, sizeof(line), in)) {
218247 conf_lineno++;
219248 sym = NULL;
220− switch (line[0]) {
221− case '#':
222− if (memcmp(line + 2, "CONFIG_", 7))
249+ if (line[0] == '#') {
250+ if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
223251 continue;
224− p = strchr(line + 9, ' ');
252+ p = strchr(line + 2 + strlen(CONFIG_), ' ');
225253 if (!p)
226254 continue;
227255 *p++ = 0;
228256 if (strncmp(p, "is not set", 10))
229257 continue;
230258 if (def == S_DEF_USER) {
231− sym = sym_find(line + 9);
259+ sym = sym_find(line + 2 + strlen(CONFIG_));
232260 if (!sym) {
233261 sym_add_change_count(1);
234− break;
262+ goto setsym;
235263 }
236264 } else {
237− sym = sym_lookup(line + 9, 0);
265+ sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
238266 if (sym->type == S_UNKNOWN)
239267 sym->type = S_BOOLEAN;
240268 }
@@ -250,13 +278,8 @@ load: · 9 unmodified lines
250278 default:
251279 ;
252280 }
253− break;
254− case 'C':
255− if (memcmp(line, "CONFIG_", 7)) {
256− conf_warning("unexpected data");
257− continue;
258− }
259− p = strchr(line + 7, '=');
281+ } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
282+ p = strchr(line + strlen(CONFIG_), '=');
260283 if (!p)
261284 continue;
262285 *p++ = 0;
@@ -267,13 +290,13 @@ load: · 4 unmodified lines
267290 *p2 = 0;
268291 }
269292 if (def == S_DEF_USER) {
270− sym = sym_find(line + 7);
293+ sym = sym_find(line + strlen(CONFIG_));
271294 if (!sym) {
272295 sym_add_change_count(1);
273− break;
296+ goto setsym;
274297 }
275298 } else {
276− sym = sym_lookup(line + 7, 0);
299+ sym = sym_lookup(line + strlen(CONFIG_), 0);
277300 if (sym->type == S_UNKNOWN)
278301 sym->type = S_OTHER;
279302 }
@@ -282,14 +305,12 @@ load: · 2 unmodified lines
282305 }
283306 if (conf_set_sym_val(sym, def, def_flags, p))
284307 continue;
285− break;
286− case '\r':
287− case '\n':
288− break;
289− default:
290− conf_warning("unexpected data");
308+ } else {
309+ if (line[0] != '\r' && line[0] != '\n')
310+ conf_warning("unexpected data");
291311 continue;
292312 }
313+setsym:
293314 if (sym && sym_is_choice_value(sym)) {
294315 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
295316 switch (sym->def[def].tri) {
@@ -396,15 +417,151 @@ int conf_read(const char *name) · 100 unmodified lines
396417 return 0;
397418 }
398419
420+/* Write a S_STRING */
421+static void conf_write_string(bool headerfile, const char *name,
422+ const char *str, FILE *out)
423+{
424+ int l;
425+ if (headerfile)
426+ fprintf(out, "#define %s%s \"", CONFIG_, name);
427+ else
428+ fprintf(out, "%s%s=\"", CONFIG_, name);
429+
430+ while (1) {
431+ l = strcspn(str, "\"\\");
432+ if (l) {
433+ xfwrite(str, l, 1, out);
434+ str += l;
435+ }
436+ if (!*str)
437+ break;
438+ fprintf(out, "\\%c", *str++);
439+ }
440+ fputs("\"\n", out);
441+}
442+
443+static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
444+ FILE *out, bool write_no)
445+{
446+ const char *str;
447+
448+ switch (type) {
449+ case S_BOOLEAN:
450+ case S_TRISTATE:
451+ switch (sym_get_tristate_value(sym)) {
452+ case no:
453+ if (write_no)
454+ fprintf(out, "# %s%s is not set\n",
455+ CONFIG_, sym->name);
456+ break;
457+ case mod:
458+ fprintf(out, "%s%s=m\n", CONFIG_, sym->name);
459+ break;
460+ case yes:
461+ fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
462+ break;
463+ }
464+ break;
465+ case S_STRING:
466+ conf_write_string(false, sym->name, sym_get_string_value(sym), out);
467+ break;
468+ case S_HEX:
469+ case S_INT:
470+ str = sym_get_string_value(sym);
471+ fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str);
472+ break;
473+ case S_OTHER:
474+ case S_UNKNOWN:
475+ break;
476+ }
477+}
478+
479+/*
480+ * Write out a minimal config.
481+ * All values that has default values are skipped as this is redundant.
482+ */
483+int conf_write_defconfig(const char *filename)
484+{
485+ struct symbol *sym;
486+ struct menu *menu;
487+ FILE *out;
488+
489+ out = fopen(filename, "w");
490+ if (!out)
491+ return 1;
492+
493+ sym_clear_all_valid();
494+
495+ /* Traverse all menus to find all relevant symbols */
496+ menu = rootmenu.list;
497+
498+ while (menu != NULL)
499+ {
500+ sym = menu->sym;
501+ if (sym == NULL) {
502+ if (!menu_is_visible(menu))
503+ goto next_menu;
504+ } else if (!sym_is_choice(sym)) {
505+ sym_calc_value(sym);
506+ if (!(sym->flags & SYMBOL_WRITE))
507+ goto next_menu;
508+ sym->flags &= ~SYMBOL_WRITE;
509+ /* If we cannot change the symbol - skip */
510+ if (!sym_is_changable(sym))
511+ goto next_menu;
512+ /* If symbol equals to default value - skip */
513+ if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
514+ goto next_menu;
515+
516+ /*
517+ * If symbol is a choice value and equals to the
518+ * default for a choice - skip.
519+ * But only if value is bool and equal to "y" and
520+ * choice is not "optional".
521+ * (If choice is "optional" then all values can be "n")
522+ */
523+ if (sym_is_choice_value(sym)) {
524+ struct symbol *cs;
525+ struct symbol *ds;
526+
527+ cs = prop_get_symbol(sym_get_choice_prop(sym));
528+ ds = sym_choice_default(cs);
529+ if (!sym_is_optional(cs) && sym == ds) {
530+ if ((sym->type == S_BOOLEAN) &&
531+ sym_get_tristate_value(sym) == yes)
532+ goto next_menu;
533+ }
534+ }
535+ conf_write_symbol(sym, sym->type, out, true);
536+ }
537+next_menu:
538+ if (menu->list != NULL) {
539+ menu = menu->list;
540+ }
541+ else if (menu->next != NULL) {
542+ menu = menu->next;
543+ } else {
544+ while ((menu = menu->parent)) {
545+ if (menu->next != NULL) {
546+ menu = menu->next;
547+ break;
548+ }
549+ }
550+ }
551+ }
552+ fclose(out);
553+ return 0;
554+}
555+
399556 int conf_write(const char *name)
400557 {
401558 FILE *out;
402559 struct symbol *sym;
403560 struct menu *menu;
404561 const char *basename;
405− char dirname[128], tmpname[128], newname[128];
406− int type, l;
407562 const char *str;
563+ char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
564+ enum symbol_type type;
408565 time_t now;
409566 int use_timestamp = 1;
410567 char *env;
@@ -443,8 +600,6 @@ int conf_write(const char *name) · 32 unmodified lines
443600 if (!out)
444601 return 1;
445602
446− sym = sym_lookup("KERNELVERSION", 0);
447− sym_calc_value(sym);
448603 time(&now);
449604 env = getenv("KCONFIG_NOTIMESTAMP");
450605 if (env && *env)
@@ -452,10 +607,10 @@ int conf_write(const char *name) · 1 unmodified line
452607
453608 fprintf(out, _("#\n"
454609 "# Automatically generated make config: don't edit\n"
455− "# Linux kernel version: %s\n"
610+ "# %s\n"
456611 "%s%s"
457612 "#\n"),
458− sym_get_string_value(sym),
613+ rootmenu.prompt->text,
459614 use_timestamp ? "# " : "",
460615 use_timestamp ? ctime(&now) : "");
461616
@@ -484,50 +639,11 @@ int conf_write(const char *name) · 22 unmodified lines
484639 if (modules_sym->curr.tri == no)
485640 type = S_BOOLEAN;
486641 }
487− switch (type) {
488− case S_BOOLEAN:
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− }
642+ /* Write config symbol to file */
643+ conf_write_symbol(sym, type, out, true);
528644 }
529645
530− next:
646+next:
531647 if (menu->list) {
532648 menu = menu->list;
533649 continue;
@@ -551,9 +667,7 @@ int conf_write(const char *name) · 17 unmodified lines
551667 return 1;
552668 }
553669
554− printf(_("#\n"
555− "# configuration written to %s\n"
556− "#\n"), newname);
670+ conf_message(_("configuration written to %s"), newname);
557671
558672 sym_set_change_count(0);
559673
@@ -563,7 +677,7 @@ int conf_write(const char *name) · 3 unmodified lines
563677 static int conf_split_config(void)
564678 {
565679 const char *name;
566− char path[128];
680+ char path[PATH_MAX+1];
567681 char *s, *d, c;
568682 struct symbol *sym;
569683 struct stat sb;
@@ -679,7 +793,7 @@ int conf_write_autoconf(void) · 109 unmodified lines
679793 const char *name;
680794 FILE *out, *tristate, *out_h;
681795 time_t now;
682− int i, l;
796+ int i;
683797
684798 sym_clear_all_valid();
685799
@@ -705,30 +819,33 @@ int conf_write_autoconf(void) · 19 unmodified lines
705819 return 1;
706820 }
707821
708− sym = sym_lookup("KERNELVERSION", 0);
709− sym_calc_value(sym);
710822 time(&now);
711823 fprintf(out, "#\n"
712824 "# Automatically generated make config: don't edit\n"
713− "# Linux kernel version: %s\n"
825+ "# %s\n"
714826 "# %s"
715827 "#\n",
716− sym_get_string_value(sym), ctime(&now));
828+ rootmenu.prompt->text, ctime(&now));
717829 fprintf(tristate, "#\n"
718830 "# Automatically generated - do not edit\n"
719831 "\n");
720832 fprintf(out_h, "/*\n"
721833 " * Automatically generated C config: don't edit\n"
722− " * Linux kernel version: %s\n"
834+ " * %s\n"
723835 " * %s"
724836 " */\n"
725837 "#define AUTOCONF_INCLUDED\n",
726− sym_get_string_value(sym), ctime(&now));
838+ rootmenu.prompt->text, ctime(&now));
727839
728840 for_all_symbols(i, sym) {
729841 sym_calc_value(sym);
730842 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
731843 continue;
844+
845+ /* write symbol to config file */
846+ conf_write_symbol(sym, sym->type, out, false);
847+
848+ /* update autoconf and tristate files */
732849 switch (sym->type) {
733850 case S_BOOLEAN:
734851 case S_TRISTATE:
@@ -736,50 +853,34 @@ int conf_write_autoconf(void) · 1 unmodified line
736853 case no:
737854 break;
738855 case mod:
739− fprintf(out, "CONFIG_%s=m\n", sym->name);
740− fprintf(tristate, "CONFIG_%s=M\n", sym->name);
741− fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
856+ fprintf(tristate, "%s%s=M\n",
857+ CONFIG_, sym->name);
858+ fprintf(out_h, "#define %s%s_MODULE 1\n",
859+ CONFIG_, sym->name);
742860 break;
743861 case yes:
744− fprintf(out, "CONFIG_%s=y\n", sym->name);
745862 if (sym->type == S_TRISTATE)
746− fprintf(tristate, "CONFIG_%s=Y\n",
747− sym->name);
748− fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
863+ fprintf(tristate,"%s%s=Y\n",
864+ CONFIG_, sym->name);
865+ fprintf(out_h, "#define %s%s 1\n",
866+ CONFIG_, sym->name);
749867 break;
750868 }
751869 break;
752870 case S_STRING:
753− str = sym_get_string_value(sym);
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);
871+ conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
771872 break;
772873 case S_HEX:
773874 str = sym_get_string_value(sym);
774875 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);
876+ fprintf(out_h, "#define %s%s 0x%s\n",
877+ CONFIG_, sym->name, str);
777878 break;
778879 }
779880 case S_INT:
780881 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);
882+ fprintf(out_h, "#define %s%s %s\n",
883+ CONFIG_, sym->name, str);
783884 break;
784885 default:
785886 break;
@@ -837,13 +938,73 @@ void conf_set_changed_callback(void (*fn)(void)) · 51 unmodified lines
837938 conf_changed_callback = fn;
838939 }
839940
941+static void randomize_choice_values(struct symbol *csym)
942+{
943+ struct property *prop;
944+ struct symbol *sym;
945+ struct expr *e;
946+ int cnt, def;
840947
841−void conf_set_all_new_symbols(enum conf_def_mode mode)
948+ /*
949+ * If choice is mod then we may have more items slected
950+ * and if no then no-one.
951+ * In both cases stop.
952+ */
953+ if (csym->curr.tri != yes)
954+ return;
955+
956+ prop = sym_get_choice_prop(csym);
957+
958+ /* count entries in choice block */
959+ cnt = 0;
960+ expr_list_for_each_sym(prop->expr, e, sym)
961+ cnt++;
962+
963+ /*
964+ * find a random value and set it to yes,
965+ * set the rest to no so we have only one set
966+ */
967+ def = (rand() % cnt);
968+
969+ cnt = 0;
970+ expr_list_for_each_sym(prop->expr, e, sym) {
971+ if (def == cnt++) {
972+ sym->def[S_DEF_USER].tri = yes;
973+ csym->def[S_DEF_USER].val = sym;
974+ }
975+ else {
976+ sym->def[S_DEF_USER].tri = no;
977+ }
978+ }
979+ csym->flags |= SYMBOL_DEF_USER;
980+ /* clear VALID to get value calculated */
981+ csym->flags &= ~(SYMBOL_VALID);
982+}
983+
984+static void set_all_choice_values(struct symbol *csym)
842985 {
843− struct symbol *sym, *csym;
844986 struct property *prop;
987+ struct symbol *sym;
845988 struct expr *e;
846− int i, cnt, def;
989+
990+ prop = sym_get_choice_prop(csym);
991+
992+ /*
993+ * Set all non-assinged choice values to no
994+ */
995+ expr_list_for_each_sym(prop->expr, e, sym) {
996+ if (!sym_has_value(sym))
997+ sym->def[S_DEF_USER].tri = no;
998+ }
999+ csym->flags |= SYMBOL_DEF_USER;
1000+ /* clear VALID to get value calculated */
1001+ csym->flags &= ~(SYMBOL_VALID);
1002+}
1003+
1004+void conf_set_all_new_symbols(enum conf_def_mode mode)
1005+{
1006+ struct symbol *sym, *csym;
1007+ int i, cnt;
8471008
8481009 for_all_symbols(i, sym) {
8491010 if (sym_has_value(sym))
@@ -862,7 +1023,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) · 12 unmodified lines
8621023 sym->def[S_DEF_USER].tri = no;
8631024 break;
8641025 case def_random:
865− sym->def[S_DEF_USER].tri = (tristate)(rand() % 3);
1026+ cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
1027+ sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
8661028 break;
8671029 default:
8681030 continue;
@@ -878,8 +1040,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) · 9 unmodified lines
8781040
8791041 sym_clear_all_valid();
8801042
881− if (mode != def_random)
882− return;
8831043 /*
8841044 * We have different type of choice blocks.
8851045 * If curr.tri equal to mod then we can select several
@@ -894,35 +1054,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) · 8 unmodified lines
8941054 continue;
8951055
8961056 sym_calc_value(csym);
897−
898− if (csym->curr.tri != yes)
899− continue;
900−
901− prop = sym_get_choice_prop(csym);
902−
903− /* count entries in choice block */
904− cnt = 0;
905− expr_list_for_each_sym(prop->expr, e, sym)
906− cnt++;
907−
908− /*
909− * find a random value and set it to yes,
910− * set the rest to no so we have only one set
911− */
912− def = (rand() % cnt);
913−
914− cnt = 0;
915− expr_list_for_each_sym(prop->expr, e, sym) {
916− if (def == cnt++) {
917− sym->def[S_DEF_USER].tri = yes;
918− csym->def[S_DEF_USER].val = sym;
919− }
920− else {
921− sym->def[S_DEF_USER].tri = no;
922− }
923− }
924− csym->flags |= SYMBOL_DEF_USER;
925− /* clear VALID to get value calculated */
926− csym->flags &= ~(SYMBOL_VALID);
1057+ if (mode == def_random)
1058+ randomize_choice_values(csym);
1059+ else
1060+ set_all_choice_values(csym);
9271061 }
9281062 }
scripts/kconfig/expr.c+2−2
@@ -1087,7 +1087,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * · 1086 unmodified lines
10871087
10881088 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
10891089 {
1090− fwrite(str, strlen(str), 1, data);
1090+ xfwrite(str, strlen(str), 1, data);
10911091 }
10921092
10931093 void expr_fprint(struct expr *e, FILE *out)
@@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s · 27 unmodified lines
11211121 }
11221122
11231123 str_append(gs, str);
1124− if (sym)
1124+ if (sym && sym->type != S_UNKNOWN)
11251125 str_printf(gs, " [=%s]", sym_str);
11261126 }
11271127
scripts/kconfig/expr.h+3−1
@@ -18,7 +18,7 @@ extern "C" { · 17 unmodified lines
1818 struct file {
1919 struct file *next;
2020 struct file *parent;
21− char *name;
21+ const char *name;
2222 int lineno;
2323 int flags;
2424 };
@@ -83,6 +83,7 @@ struct symbol { · 58 unmodified lines
8383 tristate visible;
8484 int flags;
8585 struct property *prop;
86+ struct expr_value dir_dep;
8687 struct expr_value rev_dep;
8788 };
8889
@@ -131,6 +132,7 @@ enum prop_type { · 42 unmodified lines
131132 P_SELECT, /* select BAR */
132133 P_RANGE, /* range 7..100 (for a symbol) */
133134 P_ENV, /* value from environment variable */
135+ P_SYMBOL, /* where a symbol is defined */
134136 };
135137
136138 struct property {
scripts/kconfig/gconf.c+12−15
@@ -133,7 +133,6 @@ void init_main_window(const gchar * glade_file) · 132 unmodified lines
133133 GladeXML *xml;
134134 GtkWidget *widget;
135135 GtkTextBuffer *txtbuf;
136− char title[256];
137136 GtkStyle *style;
138137
139138 xml = glade_xml_new(glade_file, "window1", NULL);
@@ -210,9 +209,7 @@ void init_main_window(const gchar * glade_file) · 70 unmodified lines
210209 /*"style", PANGO_STYLE_OBLIQUE, */
211210 NULL);
212211
213− sprintf(title, _("Linux Kernel v%s Configuration"),
214− getenv("KERNELVERSION"));
215− gtk_window_set_title(GTK_WINDOW(main_wnd), title);
212+ gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
216213
217214 gtk_widget_show(main_wnd);
218215 }
@@ -671,8 +668,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) · 452 unmodified lines
671668 {
672669 GtkWidget *dialog;
673670 const gchar *intro_text = _(
674− "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
675− "for Linux.\n"
671+ "Welcome to gkc, the GTK+ graphical configuration tool\n"
676672 "For each option, a blank box indicates the feature is disabled, a\n"
677673 "check indicates it is enabled, and a dot indicates that it is to\n"
678674 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
@@ -1114,7 +1110,7 @@ static gchar **fill_row(struct menu *menu) · 435 unmodified lines
11141110
11151111 row[COL_OPTION] =
11161112 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1117− sym && sym_has_value(sym) ? "(NEW)" : "");
1113+ sym && !sym_has_value(sym) ? "(NEW)" : "");
11181114
11191115 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
11201116 row[COL_COLOR] = g_strdup("DarkGray");
@@ -1343,7 +1339,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) · 222 unmodified lines
13431339 #endif
13441340
13451341 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1346− (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
1342+ (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1343+ (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
13471344
13481345 /* remove node */
13491346 if (gtktree_iter_find_node(dst, menu1) != NULL) {
@@ -1425,7 +1422,7 @@ static void display_tree(struct menu *menu) · 75 unmodified lines
14251422
14261423 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
14271424 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1428− (opt_mode == OPT_ALL))
1425+ (opt_mode == OPT_ALL && menu_get_prompt(child)))
14291426 place_node(child, fill_row(child));
14301427 #ifdef DEBUG
14311428 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
@@ -1530,12 +1527,6 @@ int main(int ac, char *av[]) · 98 unmodified lines
15301527 else
15311528 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
15321529
1533− /* Load the interface and connect signals */
1534− init_main_window(glade_file);
1535− init_tree_model();
1536− init_left_tree();
1537− init_right_tree();
1538−
15391530 /* Conf stuffs */
15401531 if (ac > 1 && av[1][0] == '-') {
15411532 switch (av[1][1]) {
@@ -1555,6 +1546,12 @@ int main(int ac, char *av[]) · 13 unmodified lines
15551546 fixup_rootmenu(&rootmenu);
15561547 conf_read(NULL);
15571548
1549+ /* Load the interface and connect signals */
1550+ init_main_window(glade_file);
1551+ init_tree_model();
1552+ init_left_tree();
1553+ init_right_tree();
1554+
15581555 switch (view_mode) {
15591556 case SINGLE_VIEW:
15601557 display_tree_part();
scripts/kconfig/gconf.glade+0−1
@@ -1,5 +1,4 @@
11 <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2−<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
32
43 <glade-interface>
54
scripts/kconfig/kxgettext.c+9−6
@@ -63,11 +63,11 @@ next: · 62 unmodified lines
6363
6464 struct file_line {
6565 struct file_line *next;
66− char* file;
67− int lineno;
66+ const char *file;
67+ int lineno;
6868 };
6969
70−static struct file_line *file_line__new(char *file, int lineno)
70+static struct file_line *file_line__new(const char *file, int lineno)
7171 {
7272 struct file_line *self = malloc(sizeof(*self));
7373
@@ -90,7 +90,8 @@ struct message { · 16 unmodified lines
9090
9191 static struct message *message__list;
9292
93−static struct message *message__new(const char *msg, char *option, char *file, int lineno)
93+static struct message *message__new(const char *msg, char *option,
94+ const char *file, int lineno)
9495 {
9596 struct message *self = malloc(sizeof(*self));
9697
@@ -130,7 +131,8 @@ static struct message *mesage__find(const char *msg) · 33 unmodified lines
130131 return m;
131132 }
132133
133−static int message__add_file_line(struct message *self, char *file, int lineno)
134+static int message__add_file_line(struct message *self, const char *file,
135+ int lineno)
134136 {
135137 int rc = -1;
136138 struct file_line *fl = file_line__new(file, lineno);
@@ -145,7 +147,8 @@ out: · 8 unmodified lines
145147 return rc;
146148 }
147149
148−static int message__add(const char *msg, char *option, char *file, int lineno)
150+static int message__add(const char *msg, char *option, const char *file,
151+ int lineno)
149152 {
150153 int rc = 0;
151154 char bf[16384];
scripts/kconfig/lex.zconf.c_shipped+4−3
@@ -2373,9 +2373,10 @@ void zconf_nextfile(const char *name) · 2372 unmodified lines
23732373 memset(buf, 0, sizeof(*buf));
23742374
23752375 current_buf->state = YY_CURRENT_BUFFER;
2376− zconfin = zconf_fopen(name);
2376+ zconfin = zconf_fopen(file->name);
23772377 if (!zconfin) {
2378− printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
2378+ printf("%s:%d: can't open file \"%s\"\n",
2379+ zconf_curname(), zconf_lineno(), file->name);
23792380 exit(1);
23802381 }
23812382 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
@@ -2422,7 +2423,7 @@ int zconf_lineno(void) · 40 unmodified lines
24222423 return current_pos.lineno;
24232424 }
24242425
2425−char *zconf_curname(void)
2426+const char *zconf_curname(void)
24262427 {
24272428 return current_pos.file ? current_pos.file->name : "<none>";
24282429 }
scripts/kconfig/lkc.h+19−1
@@ -31,12 +31,18 @@ extern "C" { · 30 unmodified lines
3131
3232 #define SRCTREE "srctree"
3333
34+#ifndef PACKAGE
3435 #define PACKAGE "linux"
36+#endif
37+
3538 #define LOCALEDIR "/usr/share/locale"
3639
3740 #define _(text) gettext(text)
3841 #define N_(text) (text)
3942
43+#ifndef CONFIG_
44+#define CONFIG_ "CONFIG_"
45+#endif
4046
4147 #define TF_COMMAND 0x0001
4248 #define TF_PARAM 0x0002
@@ -70,7 +76,10 @@ FILE *zconf_fopen(const char *name); · 27 unmodified lines
7076 void zconf_initscan(const char *name);
7177 void zconf_nextfile(const char *name);
7278 int zconf_lineno(void);
73−char *zconf_curname(void);
79+const char *zconf_curname(void);
80+
81+/* conf.c */
82+void xfgets(char *str, int size, FILE *in);
7483
7584 /* confdata.c */
7685 const char *conf_get_configname(void);
@@ -80,6 +89,13 @@ void sym_set_change_count(int count); · 3 unmodified lines
8089 void sym_add_change_count(int count);
8190 void conf_set_all_new_symbols(enum conf_def_mode mode);
8291
92+/* confdata.c and expr.c */
93+static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
94+{
95+ if (fwrite(str, len, count, out) < count)
96+ fprintf(stderr, "\nError in writing or end of file.\n");
97+}
98+
8399 /* kconfig_load.c */
84100 void kconfig_load(void);
85101
@@ -126,6 +142,8 @@ void sym_init(void); · 40 unmodified lines
126142 void sym_clear_all_valid(void);
127143 void sym_set_all_changed(void);
128144 void sym_set_changed(struct symbol *sym);
145+struct symbol *sym_choice_default(struct symbol *sym);
146+const char *sym_get_string_default(struct symbol *sym);
129147 struct symbol *sym_check_deps(struct symbol *sym);
130148 struct property *prop_alloc(enum prop_type type, struct symbol *sym);
131149 struct symbol *prop_get_symbol(struct property *prop);
scripts/kconfig/lkc_proto.h+4−0
@@ -1,12 +1,15 @@
1+#include <stdarg.h>
12
23 /* confdata.c */
34 P(conf_parse,void,(const char *name));
45 P(conf_read,int,(const char *name));
56 P(conf_read_simple,int,(const char *name, int));
7+P(conf_write_defconfig,int,(const char *name));
68 P(conf_write,int,(const char *name));
79 P(conf_write_autoconf,int,(void));
810 P(conf_get_changed,bool,(void));
911 P(conf_set_changed_callback, void,(void (*fn)(void)));
12+P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap)));
1013
1114 /* menu.c */
1215 P(rootmenu,struct menu,);
@@ -27,6 +30,7 @@ P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); · 14 unmodified lines
2730
2831 P(sym_lookup,struct symbol *,(const char *name, int flags));
2932 P(sym_find,struct symbol *,(const char *name));
33+P(sym_expand_string_value,const char *,(const char *in));
3034 P(sym_re_search,struct symbol **,(const char *pattern));
3135 P(sym_type_name,const char *,(enum symbol_type type));
3236 P(sym_calc_value,void,(struct symbol *sym));
scripts/kconfig/lxdialog/check-lxdialog.sh+2−0
@@ -23,6 +23,8 @@ ccflags() · 22 unmodified lines
2323 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
2424 elif [ -f /usr/include/ncurses/curses.h ]; then
2525 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
26+ elif [ -f /usr/include/ncursesw/curses.h ]; then
27+ echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"'
2628 elif [ -f /usr/include/ncurses.h ]; then
2729 echo '-DCURSES_LOC="<ncurses.h>"'
2830 else
scripts/kconfig/lxdialog/checklist.c+8−2
@@ -31,6 +31,10 @@ static int list_width, check_x, item_x; · 30 unmodified lines
3131 static void print_item(WINDOW * win, int choice, int selected)
3232 {
3333 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';
3438
3539 /* Clear 'residue' of last item */
3640 wattrset(win, dlg.menubox.atr);
@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected) · 8 unmodified lines
4549 wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
4650
4751 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]);
4953 wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
50− waddstr(win, (char *)item_str() + 1);
54+ waddstr(win, list_item + 1);
5155 if (selected) {
5256 wmove(win, choice, check_x + 1);
5357 wrefresh(win);
5458 }
59+ free(list_item);
5560 }
5661
5762 /*
@@ -175,6 +180,7 @@ do_resize: · 117 unmodified lines
175180 check_x = 0;
176181 item_foreach()
177182 check_x = MAX(check_x, strlen(item_str()) + 4);
183+ check_x = MIN(check_x, list_width);
178184
179185 check_x = (list_width - check_x) / 2;
180186 item_x = check_x + 4;
scripts/kconfig/mconf.c+30−36
@@ -25,11 +25,9 @@ · 24 unmodified lines
2525 static const char mconf_readme[] = N_(
2626 "Overview\n"
2727 "--------\n"
28−"Some kernel features may be built directly into the kernel.\n"
29−"Some may be made into loadable runtime modules. Some features\n"
30−"may be completely removed altogether. There are also certain\n"
31−"kernel parameters which are not really features, but must be\n"
32−"entered in as decimal or hexadecimal numbers or possibly text.\n"
28+"This interface let you select features and parameters for the build.\n"
29+"Features can either be built-in, modularized, or ignored. Parameters\n"
30+"must be entered in as decimal or hexadecimal numbers or text.\n"
3331 "\n"
3432 "Menu items beginning with following braces represent features that\n"
3533 " [ ] can be built in or removed\n"
@@ -74,7 +72,7 @@ static const char mconf_readme[] = N_( · 38 unmodified lines
7472 "\n"
7573 " Shortcut: Press <H> or <?>.\n"
7674 "\n"
77−"o To show hidden options, press <Z>.\n"
75+"o To toggle the display of hidden options, press <Z>.\n"
7876 "\n"
7977 "\n"
8078 "Radiolists (Choice lists)\n"
@@ -117,7 +115,7 @@ static const char mconf_readme[] = N_( · 36 unmodified lines
117115 "-----------------------------\n"
118116 "Menuconfig supports the use of alternate configuration files for\n"
119117 "those who, for various reasons, find it necessary to switch\n"
120−"between different kernel configurations.\n"
118+"between different configurations.\n"
121119 "\n"
122120 "At the end of the main menu you will find two options. One is\n"
123121 "for saving the current configuration to a file of your choosing.\n"
@@ -150,9 +148,9 @@ static const char mconf_readme[] = N_( · 26 unmodified lines
150148 "\n"
151149 "Optional personality available\n"
152150 "------------------------------\n"
153−"If you prefer to have all of the kernel options listed in a single\n"
154−"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
155−"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
151+"If you prefer to have all of the options listed in a single menu, rather\n"
152+"than the default multimenu hierarchy, run the menuconfig with\n"
153+"MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
156154 "\n"
157155 "make MENUCONFIG_MODE=single_menu menuconfig\n"
158156 "\n"
@@ -207,12 +205,12 @@ load_config_text[] = N_( · 48 unmodified lines
207205 "last retrieved. Leave blank to abort."),
208206 load_config_help[] = N_(
209207 "\n"
210− "For various reasons, one may wish to keep several different kernel\n"
208+ "For various reasons, one may wish to keep several different\n"
211209 "configurations available on a single machine.\n"
212210 "\n"
213211 "If you have saved a previous configuration in a file other than the\n"
214− "kernel's default, entering the name of the file here will allow you\n"
215− "to modify that configuration.\n"
212+ "default one, entering its name here will allow you to modify that\n"
213+ "configuration.\n"
216214 "\n"
217215 "If you are uncertain, then you have probably never used alternate\n"
218216 "configuration files. You should therefore leave this blank to abort.\n"),
@@ -221,8 +219,8 @@ save_config_text[] = N_( · 2 unmodified lines
221219 "as an alternate. Leave blank to abort."),
222220 save_config_help[] = N_(
223221 "\n"
224− "For various reasons, one may wish to keep different kernel\n"
225− "configurations available on a single machine.\n"
222+ "For various reasons, one may wish to keep different configurations\n"
223+ "available on a single machine.\n"
226224 "\n"
227225 "Entering a file name here will allow you to later retrieve, modify\n"
228226 "and use the current configuration as an alternate to whatever\n"
@@ -232,7 +230,7 @@ save_config_help[] = N_( · 3 unmodified lines
232230 "leave this blank.\n"),
233231 search_help[] = N_(
234232 "\n"
235− "Search for CONFIG_ symbols and display their relations.\n"
233+ "Search for symbols and display their relations.\n"
236234 "Regular expressions are allowed.\n"
237235 "Example: search for \"^FOO\"\n"
238236 "Result:\n"
@@ -249,7 +247,7 @@ search_help[] = N_( · 10 unmodified lines
249247 "Selected by: BAR\n"
250248 "-----------------------------------------------------------------\n"
251249 "o The line 'Prompt:' shows the text used in the menu structure for\n"
252− " this CONFIG_ symbol\n"
250+ " this symbol\n"
253251 "o The 'Defined at' line tell at what file / line number the symbol\n"
254252 " is defined\n"
255253 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
@@ -265,9 +263,9 @@ search_help[] = N_( · 9 unmodified lines
265263 "Only relevant lines are shown.\n"
266264 "\n\n"
267265 "Search examples:\n"
268− "Examples: USB => find all CONFIG_ symbols containing USB\n"
269− " ^USB => find all CONFIG_ symbols starting with USB\n"
270− " USB$ => find all CONFIG_ symbols ending with USB\n"
266+ "Examples: USB => find all symbols containing USB\n"
267+ " ^USB => find all symbols starting with USB\n"
268+ " USB$ => find all symbols ending with USB\n"
271269 "\n");
272270
273271 static int indent;
@@ -290,13 +288,9 @@ static void set_config_filename(const char *config_filename) · 16 unmodified lines
290288 {
291289 static char menu_backtitle[PATH_MAX+128];
292290 int size;
293− struct symbol *sym;
294291
295− sym = sym_lookup("KERNELVERSION", 0);
296− sym_calc_value(sym);
297292 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
298− _("%s - Linux Kernel v%s Configuration"),
299− config_filename, sym_get_string_value(sym));
293+ "%s - %s", config_filename, rootmenu.prompt->text);
300294 if (size >= sizeof(menu_backtitle))
301295 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
302296 set_dialog_backtitle(menu_backtitle);
@@ -316,8 +310,8 @@ static void search_conf(void) · 13 unmodified lines
316310 again:
317311 dialog_clear();
318312 dres = dialog_inputbox(_("Search Configuration Parameter"),
319− _("Enter CONFIG_ (sub)string to search for "
320− "(with or without \"CONFIG\")"),
313+ _("Enter " CONFIG_ " (sub)string to search for "
314+ "(with or without \"" CONFIG_ "\")"),
321315 10, 75, "");
322316 switch (dres) {
323317 case 0:
@@ -329,10 +323,10 @@ again: · 5 unmodified lines
329323 return;
330324 }
331325
332− /* strip CONFIG_ if necessary */
326+ /* strip the prefix if necessary */
333327 dialog_input = dialog_input_result;
334− if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
335− dialog_input += 7;
328+ if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
329+ dialog_input += strlen(CONFIG_);
336330
337331 sym_arr = sym_re_search(dialog_input);
338332 res = get_relations_str(sym_arr);
@@ -834,7 +828,7 @@ int main(int ac, char **av) · 495 unmodified lines
834828 if (conf_get_changed())
835829 res = dialog_yesno(NULL,
836830 _("Do you wish to save your "
837− "new kernel configuration?\n"
831+ "new configuration?\n"
838832 "<ESC><ESC> to continue."),
839833 6, 60);
840834 else
@@ -846,20 +840,20 @@ int main(int ac, char **av) · 5 unmodified lines
846840 case 0:
847841 if (conf_write(filename)) {
848842 fprintf(stderr, _("\n\n"
849− "Error during writing of the kernel configuration.\n"
850− "Your kernel configuration changes were NOT saved."
843+ "Error while writing of the configuration.\n"
844+ "Your configuration changes were NOT saved."
851845 "\n\n"));
852846 return 1;
853847 }
854848 case -1:
855849 printf(_("\n\n"
856− "*** End of Linux kernel configuration.\n"
857− "*** Execute 'make' to build the kernel or try 'make help'."
850+ "*** End of the configuration.\n"
851+ "*** Execute 'make' to start the build or try 'make help'."
858852 "\n\n"));
859853 break;
860854 default:
861855 fprintf(stderr, _("\n\n"
862− "Your kernel configuration changes were NOT saved."
856+ "Your configuration changes were NOT saved."
863857 "\n\n"));
864858 }
865859
scripts/kconfig/menu.c+24−6
@@ -10,7 +10,7 @@ · 9 unmodified lines
1010 #include "lkc.h"
1111
1212 static const char nohelp_text[] = N_(
13− "There is no help available for this kernel option.\n");
13+ "There is no help available for this option.\n");
1414
1515 struct menu rootmenu;
1616 static struct menu **last_entry_ptr;
@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym) · 41 unmodified lines
5858 *last_entry_ptr = menu;
5959 last_entry_ptr = &menu->next;
6060 current_entry = menu;
61+ if (sym)
62+ menu_add_symbol(P_SYMBOL, sym, NULL);
6163 }
6264
6365 void menu_end_entry(void)
@@ -136,7 +138,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e · 72 unmodified lines
136138 while (isspace(*prompt))
137139 prompt++;
138140 }
139− if (current_entry->prompt)
141+ if (current_entry->prompt && current_entry != &rootmenu)
140142 prop_warn(prop, "prompt redefined");
141143 current_entry->prompt = prop;
142144 }
@@ -318,6 +320,8 @@ void menu_finalize(struct menu *parent) · 175 unmodified lines
318320 parent->next = last_menu->next;
319321 last_menu->next = NULL;
320322 }
323+
324+ sym->dir_dep.expr = parent->dep;
321325 }
322326 for (menu = parent->list; menu; menu = menu->next) {
323327 if (sym && sym_is_choice(sym) &&
@@ -419,9 +423,13 @@ bool menu_is_visible(struct menu *menu) · 95 unmodified lines
419423 if (!sym || sym_get_tristate_value(menu->sym) == no)
420424 return false;
421425
422− for (child = menu->list; child; child = child->next)
423− if (menu_is_visible(child))
426+ for (child = menu->list; child; child = child->next) {
427+ if (menu_is_visible(child)) {
428+ if (sym)
429+ sym->flags |= SYMBOL_DEF_USER;
424430 return true;
431+ }
432+ }
425433
426434 return false;
427435 }
@@ -501,9 +509,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) · 73 unmodified lines
501509 bool hit;
502510 struct property *prop;
503511
504− if (sym && sym->name)
512+ if (sym && sym->name) {
505513 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
506514 sym_get_string_value(sym));
515+ str_printf(r, "Type : %s\n", sym_type_name(sym->type));
516+ if (sym->type == S_INT || sym->type == S_HEX) {
517+ prop = sym_get_range_prop(sym);
518+ if (prop) {
519+ str_printf(r, "Range : ");
520+ expr_gstr_print(prop->expr, r);
521+ str_append(r, "\n");
522+ }
523+ }
524+ }
507525 for_all_prompts(sym, prop)
508526 get_prompt_str(r, prop);
509527 hit = false;
@@ -545,7 +563,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help) · 35 unmodified lines
545563
546564 if (menu_has_help(menu)) {
547565 if (sym->name) {
548− str_printf(help, "CONFIG_%s:\n\n", sym->name);
566+ str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
549567 str_append(help, _(menu_get_help(menu)));
550568 str_append(help, "\n");
551569 }
scripts/kconfig/nconf.c+239−250
@@ -5,25 +5,26 @@ · 4 unmodified lines
55 * Derived from menuconfig.
66 *
77 */
8+#define _GNU_SOURCE
9+#include <string.h>
810 #define LKC_DIRECT_LINK
911 #include "lkc.h"
1012 #include "nconf.h"
13+#include <ctype.h>
1114
1215 static const char nconf_readme[] = N_(
1316 "Overview\n"
1417 "--------\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"
18+"This interface let you select features and parameters for the build.\n"
19+"Features can either be built-in, modularized, or ignored. Parameters\n"
20+"must be entered in as decimal or hexadecimal numbers or text.\n"
2021 "\n"
2122 "Menu items beginning with following braces represent features that\n"
2223 " [ ] can be built in or removed\n"
2324 " < > can be built in, modularized or removed\n"
2425 " { } can be built in or modularized (selected by other feature)\n"
2526 " - - are selected by other feature,\n"
26−" XXX cannot be selected. use Symbol Info to find out why,\n"
27+" XXX cannot be selected. Use Symbol Info to find out why,\n"
2728 "while *, M or whitespace inside braces means to build in, build as\n"
2829 "a module or to exclude the feature respectively.\n"
2930 "\n"
@@ -41,9 +42,13 @@ static const char nconf_readme[] = N_( · 11 unmodified lines
4142 " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
4243 " Submenus are designated by \"--->\".\n"
4344 "\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"
45+" Searching: pressing '/' triggers interactive search mode.\n"
46+" nconfig performs a case insensitive search for the string\n"
47+" in the menu prompts (no regex support).\n"
48+" Pressing the up/down keys highlights the previous/next\n"
49+" matching item. Backspace removes one character from the\n"
50+" match string. Pressing either '/' again or ESC exits\n"
51+" search mode. All other keys behave normally.\n"
4752 "\n"
4853 " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
4954 " unseen options into view.\n"
@@ -88,7 +93,7 @@ static const char nconf_readme[] = N_( · 38 unmodified lines
8893 "-----------------------------\n"
8994 "nconfig supports the use of alternate configuration files for\n"
9095 "those who, for various reasons, find it necessary to switch\n"
91−"between different kernel configurations.\n"
96+"between different configurations.\n"
9297 "\n"
9398 "At the end of the main menu you will find two options. One is\n"
9499 "for saving the current configuration to a file of your choosing.\n"
@@ -121,9 +126,9 @@ static const char nconf_readme[] = N_( · 26 unmodified lines
121126 "\n"
122127 "Optional personality available\n"
123128 "------------------------------\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"
129+"If you prefer to have all of the options listed in a single menu, rather\n"
130+"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
131+"environment variable set to single_menu. Example:\n"
127132 "\n"
128133 "make NCONFIG_MODE=single_menu nconfig\n"
129134 "\n"
@@ -141,21 +146,21 @@ menu_no_f_instructions[] = N_( · 11 unmodified lines
141146 " <Enter> or <right-arrow> selects submenus --->.\n"
142147 " Capital Letters are hotkeys.\n"
143148 " 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"
149+" Pressing SpaceBar toggles between the above options.\n"
150+" Press <Esc> or <left-arrow> to go back one menu,\n"
146151 " <?> or <h> for Help, </> for Search.\n"
147−" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
152+" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
148153 " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
149−" <Esc> always leaves the current window\n"),
154+" <Esc> always leaves the current window.\n"),
150155 menu_instructions[] = N_(
151156 " Arrow keys navigate the menu.\n"
152157 " <Enter> or <right-arrow> selects submenus --->.\n"
153158 " Capital Letters are hotkeys.\n"
154159 " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
155160 " Pressing SpaceBar toggles between the above options\n"
156−" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n"
161+" Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
157162 " <?>, <F1> or <h> for Help, </> for Search.\n"
158−" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
163+" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
159164 " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
160165 " <Esc> always leaves the current window\n"),
161166 radiolist_instructions[] = N_(
@@ -178,19 +183,19 @@ setmod_text[] = N_( · 16 unmodified lines
178183 "has been configured as a module.\n"
179184 "As a result, this feature will be built as a module."),
180185 nohelp_text[] = N_(
181−"There is no help available for this kernel option.\n"),
186+"There is no help available for this option.\n"),
182187 load_config_text[] = N_(
183188 "Enter the name of the configuration file you wish to load.\n"
184189 "Accept the name shown to restore the configuration you\n"
185190 "last retrieved. Leave blank to abort."),
186191 load_config_help[] = N_(
187192 "\n"
188−"For various reasons, one may wish to keep several different kernel\n"
193+"For various reasons, one may wish to keep several different\n"
189194 "configurations available on a single machine.\n"
190195 "\n"
191196 "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"
197+"default one, entering its name here will allow you to modify that\n"
198+"configuration.\n"
194199 "\n"
195200 "If you are uncertain, then you have probably never used alternate\n"
196201 "configuration files. You should therefor leave this blank to abort.\n"),
@@ -199,8 +204,8 @@ save_config_text[] = N_( · 2 unmodified lines
199204 "as an alternate. Leave blank to abort."),
200205 save_config_help[] = N_(
201206 "\n"
202−"For various reasons, one may wish to keep different kernel\n"
203−"configurations available on a single machine.\n"
207+"For various reasons, one may wish to keep different configurations\n"
208+"available on a single machine.\n"
204209 "\n"
205210 "Entering a file name here will allow you to later retrieve, modify\n"
206211 "and use the current configuration as an alternate to whatever\n"
@@ -210,8 +215,8 @@ save_config_help[] = N_( · 3 unmodified lines
210215 "leave this blank.\n"),
211216 search_help[] = N_(
212217 "\n"
213−"Search for CONFIG_ symbols and display their relations.\n"
214−"Regular expressions are allowed.\n"
218+"Search for symbols and display their relations. Regular expressions\n"
219+"are allowed.\n"
215220 "Example: search for \"^FOO\"\n"
216221 "Result:\n"
217222 "-----------------------------------------------------------------\n"
@@ -227,7 +232,7 @@ search_help[] = N_( · 9 unmodified lines
227232 "Selected by: BAR\n"
228233 "-----------------------------------------------------------------\n"
229234 "o The line 'Prompt:' shows the text used in the menu structure for\n"
230−" this CONFIG_ symbol\n"
235+" this symbol\n"
231236 "o The 'Defined at' line tell at what file / line number the symbol\n"
232237 " is defined\n"
233238 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
@@ -243,16 +248,15 @@ search_help[] = N_( · 9 unmodified lines
243248 "Only relevant lines are shown.\n"
244249 "\n\n"
245250 "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"
251+"Examples: USB = > find all symbols containing USB\n"
252+" ^USB => find all symbols starting with USB\n"
253+" USB$ => find all symbols ending with USB\n"
249254 "\n");
250255
251256 struct mitem {
252257 char str[256];
253258 char tag;
254259 void *usrptr;
255− int is_hot;
256260 int is_visible;
257261 };
258262
@@ -275,14 +279,6 @@ static int items_num; · 16 unmodified lines
275279 static int global_exit;
276280 /* the currently selected button */
277281 const 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
282−struct {
283− int count;
284− int ptrs[MAX_MENU_ITEMS];
285−} hotkeys[1<<(sizeof(char)*8)];
286282
287283 static void conf(struct menu *menu);
288284 static void conf_choice(struct menu *menu);
@@ -292,6 +288,7 @@ static void conf_save(void); · 3 unmodified lines
292288 static void show_help(struct menu *menu);
293289 static int do_exit(void);
294290 static void setup_windows(void);
291+static void search_conf(void);
295292
296293 typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297294 static void handle_f1(int *key, struct menu *current_item);
@@ -302,6 +299,7 @@ static void handle_f5(int *key, struct menu *current_item); · 4 unmodified lines
302299 static void handle_f6(int *key, struct menu *current_item);
303300 static void handle_f7(int *key, struct menu *current_item);
304301 static void handle_f8(int *key, struct menu *current_item);
302+static void handle_f9(int *key, struct menu *current_item);
305303
306304 struct function_keys {
307305 const char *key_str;
@@ -310,7 +308,7 @@ struct function_keys { · 2 unmodified lines
310308 function_key_handler_t handler;
311309 };
312310
313−static const int function_keys_num = 8;
311+static const int function_keys_num = 9;
314312 struct function_keys function_keys[] = {
315313 {
316314 .key_str = "F1",
@@ -320,13 +318,13 @@ struct function_keys function_keys[] = { · 3 unmodified lines
320318 },
321319 {
322320 .key_str = "F2",
323− .func = "Symbol Info",
321+ .func = "Sym Info",
324322 .key = F_SYMBOL,
325323 .handler = handle_f2,
326324 },
327325 {
328326 .key_str = "F3",
329− .func = "Instructions",
327+ .func = "Insts",
330328 .key = F_INSTS,
331329 .handler = handle_f3,
332330 },
@@ -356,9 +354,15 @@ struct function_keys function_keys[] = { · 23 unmodified lines
356354 },
357355 {
358356 .key_str = "F8",
357+ .func = "Sym Search",
358+ .key = F_SEARCH,
359+ .handler = handle_f8,
360+ },
361+ {
362+ .key_str = "F9",
359363 .func = "Exit",
360364 .key = F_EXIT,
361− .handler = handle_f8,
365+ .handler = handle_f9,
362366 },
363367 };
364368
@@ -444,8 +448,15 @@ static void handle_f7(int *key, struct menu *current_item) · 79 unmodified lines
444448 return;
445449 }
446450
447−/* exit */
451+/* search */
448452 static void handle_f8(int *key, struct menu *current_item)
453+{
454+ search_conf();
455+ return;
456+}
457+
458+/* exit */
459+static void handle_f9(int *key, struct menu *current_item)
449460 {
450461 do_exit();
451462 return;
@@ -479,110 +490,44 @@ static void clean_items(void) · 27 unmodified lines
479490 free_item(curses_menu_items[i]);
480491 bzero(curses_menu_items, sizeof(curses_menu_items));
481492 bzero(k_menu_items, sizeof(k_menu_items));
482− bzero(hotkeys, sizeof(hotkeys));
483493 items_num = 0;
484494 }
485495
486−/* return the index of the next hot item, or -1 if no such item exists */
487−static 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 */
506−static 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. */
514−static int is_hot(int index)
515−{
516− return k_menu_items[index].is_hot;
517−}
496+typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
497+ FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
518498
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*/
522−static int make_hot(char *dest, int len, const char *org, int index)
499+/* return the index of the matched item, or -1 if no such item exists */
500+static int get_mext_match(const char *match_str, match_f flag)
523501 {
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− }
502+ int match_start = item_index(current_item(curses_menu));
503+ int index;
504+
505+ if (flag == FIND_NEXT_MATCH_DOWN)
506+ ++match_start;
507+ else if (flag == FIND_NEXT_MATCH_UP)
508+ --match_start;
509+
510+ index = match_start;
511+ index = (index + items_num) % items_num;
512+ while (true) {
513+ char *str = k_menu_items[index].str;
514+ if (strcasestr(str, match_str) != 0)
515+ return index;
516+ if (flag == FIND_NEXT_MATCH_UP ||
517+ flag == MATCH_TINKER_PATTERN_UP)
518+ --index;
519+ else
520+ ++index;
521+ index = (index + items_num) % items_num;
522+ if (index == match_start)
523+ return -1;
557524 }
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;
577525 }
578526
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 */
527+/* Make a new item. */
582528 static void item_make(struct menu *menu, char tag, const char *fmt, ...)
583529 {
584530 va_list ap;
585− char tmp_str[256];
586531
587532 if (items_num > MAX_MENU_ITEMS-1)
588533 return;
@@ -597,16 +542,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...) · 8 unmodified lines
597542 k_menu_items[items_num].is_visible = 1;
598543
599544 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);
545+ vsnprintf(k_menu_items[items_num].str,
546+ sizeof(k_menu_items[items_num].str),
547+ fmt, ap);
603548 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));
549+
550+ if (!k_menu_items[items_num].is_visible)
551+ memcpy(k_menu_items[items_num].str, "XXX", 3);
610552
611553 curses_menu_items[items_num] = new_item(
612554 k_menu_items[items_num].str,
@@ -638,11 +580,9 @@ static void item_add_str(const char *fmt, ...) · 25 unmodified lines
638580 va_end(ap);
639581 snprintf(tmp_str, sizeof(tmp_str), "%s%s",
640582 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));
583+ strncpy(k_menu_items[index].str,
584+ tmp_str,
585+ sizeof(k_menu_items[index].str));
646586
647587 free_item(curses_menu_items[index]);
648588 curses_menu_items[index] = new_item(
@@ -676,6 +616,8 @@ static void *item_data(void) · 27 unmodified lines
676616 struct mitem *mcur;
677617
678618 cur = current_item(curses_menu);
619+ if (!cur)
620+ return NULL;
679621 mcur = (struct mitem *) item_userptr(cur);
680622 return mcur->usrptr;
681623
@@ -691,13 +633,9 @@ static char menu_backtitle[PATH_MAX+128]; · 9 unmodified lines
691633 static const char *set_config_filename(const char *config_filename)
692634 {
693635 int size;
694− struct symbol *sym;
695636
696− sym = sym_lookup("KERNELVERSION", 0);
697− sym_calc_value(sym);
698637 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
699− _("%s - Linux Kernel v%s Configuration"),
700− config_filename, sym_get_string_value(sym));
638+ "%s - %s", config_filename, rootmenu.prompt->text);
701639 if (size >= sizeof(menu_backtitle))
702640 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
703641
@@ -707,25 +645,6 @@ static const char *set_config_filename(const char *config_filename) · 3 unmodified lines
707645 return menu_backtitle;
708646 }
709647
710−/* command = 0 is supress, 1 is restore */
711−static 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−
729648 /* return = 0 means we are successful.
730649 * -1 means go on doing what you were doing
731650 */
@@ -737,8 +656,7 @@ static int do_exit(void) · 5 unmodified lines
737656 return 0;
738657 }
739658 res = btn_dialog(main_window,
740− _("Do you wish to save your "
741− "new kernel configuration?\n"
659+ _("Do you wish to save your new configuration?\n"
742660 "<ESC> to cancel and resume nconfig."),
743661 2,
744662 " <save> ",
@@ -751,36 +669,19 @@ static int do_exit(void) · 6 unmodified lines
751669 /* if we got here, the user really wants to exit */
752670 switch (res) {
753671 case 0:
754− supress_stdout(0);
755672 res = conf_write(filename);
756− supress_stdout(1);
757673 if (res)
758674 btn_dialog(
759675 main_window,
760− _("Error during writing of the kernel "
761− "configuration.\n"
762− "Your kernel configuration "
763− "changes were NOT saved."),
676+ _("Error during writing of configuration.\n"
677+ "Your configuration changes were NOT saved."),
764678 1,
765679 "<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− }
779680 break;
780681 default:
781682 btn_dialog(
782683 main_window,
783− _("Your kernel configuration changes were NOT saved."),
684+ _("Your configuration changes were NOT saved."),
784685 1,
785686 "<OK>");
786687 break;
@@ -800,8 +701,8 @@ static void search_conf(void) · 13 unmodified lines
800701 again:
801702 dres = dialog_inputbox(main_window,
802703 _("Search Configuration Parameter"),
803− _("Enter CONFIG_ (sub)string to search for "
804− "(with or without \"CONFIG\")"),
704+ _("Enter " CONFIG_ " (sub)string to search for "
705+ "(with or without \"" CONFIG_ "\")"),
805706 "", dialog_input_result, 99);
806707 switch (dres) {
807708 case 0:
@@ -814,10 +715,10 @@ again: · 6 unmodified lines
814715 return;
815716 }
816717
817− /* strip CONFIG_ if necessary */
718+ /* strip the prefix if necessary */
818719 dialog_input = dialog_input_result;
819− if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
820− dialog_input += 7;
720+ if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
721+ dialog_input += strlen(CONFIG_);
821722
822723 sym_arr = sym_re_search(dialog_input);
823724 res = get_relations_str(sym_arr);
@@ -1025,23 +926,18 @@ static void reset_menu(void) · 201 unmodified lines
1025926 static void center_item(int selected_index, int *last_top_row)
1026927 {
1027928 int toprow;
1028− int maxy, maxx;
1029929
1030− scale_menu(curses_menu, &maxy, &maxx);
1031930 set_top_row(curses_menu, *last_top_row);
1032931 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)
932+ if (selected_index < toprow ||
933+ selected_index >= toprow+mwin_max_lines) {
934+ toprow = max(selected_index-mwin_max_lines/2, 0);
935+ if (toprow >= item_count(curses_menu)-mwin_max_lines)
1040936 toprow = item_count(curses_menu)-mwin_max_lines;
1041937 set_top_row(curses_menu, toprow);
1042− set_current_item(curses_menu,
1043− curses_menu_items[selected_index]);
1044938 }
939+ set_current_item(curses_menu,
940+ curses_menu_items[selected_index]);
1045941 *last_top_row = toprow;
1046942 post_menu(curses_menu);
1047943 refresh_all_windows(main_window);
@@ -1073,7 +969,7 @@ static void show_menu(const char *prompt, const char *instructions, · 25 unmodified lines
1073969 /* position the menu at the middle of the screen */
1074970 scale_menu(curses_menu, &maxy, &maxx);
1075971 maxx = min(maxx, mwin_max_cols-2);
1076− maxy = mwin_max_lines-2;
972+ maxy = mwin_max_lines;
1077973 menu_window = derwin(main_window,
1078974 maxy,
1079975 maxx,
@@ -1097,10 +993,77 @@ static void show_menu(const char *prompt, const char *instructions, · 17 unmodified lines
1097993 refresh_all_windows(main_window);
1098994 }
1099995
996+static void adj_match_dir(match_f *match_direction)
997+{
998+ if (*match_direction == FIND_NEXT_MATCH_DOWN)
999+ *match_direction =
1000+ MATCH_TINKER_PATTERN_DOWN;
1001+ else if (*match_direction == FIND_NEXT_MATCH_UP)
1002+ *match_direction =
1003+ MATCH_TINKER_PATTERN_UP;
1004+ /* else, do no change.. */
1005+}
11001006
1101−static void conf(struct menu *menu)
1007+struct match_state
11021008 {
1009+ int in_search;
1010+ match_f match_direction;
11031011 char pattern[256];
1012+};
1013+
1014+/* Return 0 means I have handled the key. In such a case, ans should hold the
1015+ * item to center, or -1 otherwise.
1016+ * Else return -1 .
1017+ */
1018+static int do_match(int key, struct match_state *state, int *ans)
1019+{
1020+ char c = (char) key;
1021+ int terminate_search = 0;
1022+ *ans = -1;
1023+ if (key == '/' || (state->in_search && key == 27)) {
1024+ move(0, 0);
1025+ refresh();
1026+ clrtoeol();
1027+ state->in_search = 1-state->in_search;
1028+ bzero(state->pattern, sizeof(state->pattern));
1029+ state->match_direction = MATCH_TINKER_PATTERN_DOWN;
1030+ return 0;
1031+ } else if (!state->in_search)
1032+ return 1;
1033+
1034+ if (isalnum(c) || isgraph(c) || c == ' ') {
1035+ state->pattern[strlen(state->pattern)] = c;
1036+ state->pattern[strlen(state->pattern)] = '\0';
1037+ adj_match_dir(&state->match_direction);
1038+ *ans = get_mext_match(state->pattern,
1039+ state->match_direction);
1040+ } else if (key == KEY_DOWN) {
1041+ state->match_direction = FIND_NEXT_MATCH_DOWN;
1042+ *ans = get_mext_match(state->pattern,
1043+ state->match_direction);
1044+ } else if (key == KEY_UP) {
1045+ state->match_direction = FIND_NEXT_MATCH_UP;
1046+ *ans = get_mext_match(state->pattern,
1047+ state->match_direction);
1048+ } else if (key == KEY_BACKSPACE || key == 127) {
1049+ state->pattern[strlen(state->pattern)-1] = '\0';
1050+ adj_match_dir(&state->match_direction);
1051+ } else
1052+ terminate_search = 1;
1053+
1054+ if (terminate_search) {
1055+ state->in_search = 0;
1056+ bzero(state->pattern, sizeof(state->pattern));
1057+ move(0, 0);
1058+ refresh();
1059+ clrtoeol();
1060+ return -1;
1061+ }
1062+ return 0;
1063+}
1064+
1065+static void conf(struct menu *menu)
1066+{
11041067 struct menu *submenu = 0;
11051068 const char *prompt = menu_get_prompt(menu);
11061069 struct symbol *sym;
@@ -1108,8 +1071,11 @@ static void conf(struct menu *menu) · 1 unmodified line
11081071 int res;
11091072 int current_index = 0;
11101073 int last_top_row = 0;
1111−
1112− bzero(pattern, sizeof(pattern));
1074+ struct match_state match_state = {
1075+ .in_search = 0,
1076+ .match_direction = MATCH_TINKER_PATTERN_DOWN,
1077+ .pattern = "",
1078+ };
11131079
11141080 while (!global_exit) {
11151081 reset_menu();
@@ -1122,7 +1088,22 @@ static void conf(struct menu *menu) · 6 unmodified lines
11221088 _(menu_instructions),
11231089 current_index, &last_top_row);
11241090 keypad((menu_win(curses_menu)), TRUE);
1125− while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1091+ while (!global_exit) {
1092+ if (match_state.in_search) {
1093+ mvprintw(0, 0,
1094+ "searching: %s", match_state.pattern);
1095+ clrtoeol();
1096+ }
1097+ refresh_all_windows(main_window);
1098+ res = wgetch(menu_win(curses_menu));
1099+ if (!res)
1100+ break;
1101+ if (do_match(res, &match_state, &current_index) == 0) {
1102+ if (current_index != -1)
1103+ center_item(current_index,
1104+ &last_top_row);
1105+ continue;
1106+ }
11261107 if (process_special_keys(&res,
11271108 (struct menu *) item_data()))
11281109 break;
@@ -1153,19 +1134,13 @@ static void conf(struct menu *menu) · 24 unmodified lines
11531134 if (res == 10 || res == 27 ||
11541135 res == 32 || res == 'n' || res == 'y' ||
11551136 res == KEY_LEFT || res == KEY_RIGHT ||
1156− res == 'm' || res == '/')
1137+ res == 'm')
11571138 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− }
11641139 refresh_all_windows(main_window);
11651140 }
11661141
11671142 refresh_all_windows(main_window);
1168− /* if ESC or left*/
1143+ /* if ESC or left*/
11691144 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
11701145 break;
11711146
@@ -1233,23 +1208,30 @@ static void conf(struct menu *menu) · 61 unmodified lines
12331208 if (item_is_tag('t'))
12341209 sym_set_tristate_value(sym, mod);
12351210 break;
1236− case '/':
1237− search_conf();
1238− break;
12391211 }
12401212 }
12411213 }
12421214
1215+static void conf_message_callback(const char *fmt, va_list ap)
1216+{
1217+ char buf[1024];
1218+
1219+ vsnprintf(buf, sizeof(buf), fmt, ap);
1220+ btn_dialog(main_window, buf, 1, "<OK>");
1221+}
1222+
12431223 static void show_help(struct menu *menu)
12441224 {
12451225 struct gstr help = str_new();
12461226
12471227 if (menu && menu->sym && menu_has_help(menu)) {
12481228 if (menu->sym->name) {
1249− str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name);
1229+ str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name);
12501230 str_append(&help, _(menu_get_help(menu)));
12511231 str_append(&help, "\n");
12521232 get_symbol_str(&help, menu->sym);
1233+ } else {
1234+ str_append(&help, _(menu_get_help(menu)));
12531235 }
12541236 } else {
12551237 str_append(&help, nohelp_text);
@@ -1266,6 +1248,11 @@ static void conf_choice(struct menu *menu) · 10 unmodified lines
12661248 int selected_index = 0;
12671249 int last_top_row = 0;
12681250 int res, i = 0;
1251+ struct match_state match_state = {
1252+ .in_search = 0,
1253+ .match_direction = MATCH_TINKER_PATTERN_DOWN,
1254+ .pattern = "",
1255+ };
12691256
12701257 active = sym_get_choice_value(menu->sym);
12711258 /* this is mostly duplicated from the conf() function. */
@@ -1292,7 +1279,22 @@ static void conf_choice(struct menu *menu) · 20 unmodified lines
12921279 _(radiolist_instructions),
12931280 selected_index,
12941281 &last_top_row);
1295− while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
1282+ while (!global_exit) {
1283+ if (match_state.in_search) {
1284+ mvprintw(0, 0, "searching: %s",
1285+ match_state.pattern);
1286+ clrtoeol();
1287+ }
1288+ refresh_all_windows(main_window);
1289+ res = wgetch(menu_win(curses_menu));
1290+ if (!res)
1291+ break;
1292+ if (do_match(res, &match_state, &selected_index) == 0) {
1293+ if (selected_index != -1)
1294+ center_item(selected_index,
1295+ &last_top_row);
1296+ continue;
1297+ }
12961298 if (process_special_keys(
12971299 &res,
12981300 (struct menu *) item_data()))
@@ -1322,13 +1324,8 @@ static void conf_choice(struct menu *menu) · 23 unmodified lines
13221324 break;
13231325 }
13241326 if (res == 10 || res == 27 || res == ' ' ||
1325− res == KEY_LEFT)
1327+ res == KEY_LEFT){
13261328 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);
13321329 }
13331330 refresh_all_windows(main_window);
13341331 }
@@ -1447,16 +1444,8 @@ static void conf_save(void) · 112 unmodified lines
14471444 case 0:
14481445 if (!dialog_input_result[0])
14491446 return;
1450− supress_stdout(0);
14511447 res = conf_write(dialog_input_result);
1452− supress_stdout(1);
14531448 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>");
14601449 set_config_filename(dialog_input_result);
14611450 return;
14621451 }
@@ -1483,7 +1472,7 @@ void setup_windows(void) · 20 unmodified lines
14831472 /* set up the menu and menu window */
14841473 main_window = newwin(LINES-2, COLS-2, 2, 1);
14851474 keypad(main_window, TRUE);
1486− mwin_max_lines = LINES-6;
1475+ mwin_max_lines = LINES-7;
14871476 mwin_max_cols = COLS-6;
14881477
14891478 /* panels order is from bottom to top */
@@ -1530,9 +1519,10 @@ int main(int ac, char **av) · 40 unmodified lines
15301519 /* set btns menu */
15311520 curses_menu = new_menu(curses_menu_items);
15321521 menu_opts_off(curses_menu, O_SHOWDESC);
1533− menu_opts_off(curses_menu, O_SHOWMATCH);
1522+ menu_opts_on(curses_menu, O_SHOWMATCH);
15341523 menu_opts_on(curses_menu, O_ONEVALUE);
15351524 menu_opts_on(curses_menu, O_NONCYCLIC);
1525+ menu_opts_on(curses_menu, O_IGNORECASE);
15361526 set_menu_mark(curses_menu, " ");
15371527 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
15381528 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
@@ -1548,8 +1538,7 @@ int main(int ac, char **av) · 9 unmodified lines
15481538 _(menu_no_f_instructions));
15491539 }
15501540
1551−
1552−
1541+ conf_set_message_callback(conf_message_callback);
15531542 /* do the work */
15541543 while (!global_exit) {
15551544 conf(&rootmenu);
scripts/kconfig/nconf.gui.c+11−11
@@ -137,7 +137,7 @@ void set_colors() · 136 unmodified lines
137137 if (has_colors()) {
138138 normal_color_theme();
139139 } else {
140− /* give deafults */
140+ /* give defaults */
141141 no_colors_theme();
142142 }
143143 }
@@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win, · 23 unmodified lines
167167 length = strlen(string);
168168 temp = (width - length) / 2;
169169 x = startx + (int)temp;
170− wattrset(win, color);
170+ (void) wattrset(win, color);
171171 mvwprintw(win, y, x, "%s", string);
172172 refresh();
173173 }
@@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) · 123 unmodified lines
297297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
298298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
299299
300− wattrset(win, attributes[DIALOG_BOX]);
300+ (void) wattrset(win, attributes[DIALOG_BOX]);
301301 box(win, 0, 0);
302302
303303 /* print message */
304− wattrset(msg_win, attributes[DIALOG_TEXT]);
304+ (void) wattrset(msg_win, attributes[DIALOG_TEXT]);
305305 fill_window(msg_win, msg);
306306
307307 set_menu_win(menu, win);
@@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window, · 84 unmodified lines
392392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
393393 keypad(form_win, TRUE);
394394
395− wattrset(form_win, attributes[INPUT_FIELD]);
395+ (void) wattrset(form_win, attributes[INPUT_FIELD]);
396396
397− wattrset(win, attributes[INPUT_BOX]);
397+ (void) wattrset(win, attributes[INPUT_BOX]);
398398 box(win, 0, 0);
399− wattrset(win, attributes[INPUT_HEADING]);
399+ (void) wattrset(win, attributes[INPUT_HEADING]);
400400 if (title)
401401 mvwprintw(win, 0, 3, "%s", title);
402402
403403 /* print message */
404− wattrset(prompt_win, attributes[INPUT_TEXT]);
404+ (void) wattrset(prompt_win, attributes[INPUT_TEXT]);
405405 fill_window(prompt_win, prompt);
406406
407407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
@@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window, · 123 unmodified lines
531531
532532 /* create the pad */
533533 pad = newpad(total_lines+10, total_cols+10);
534− wattrset(pad, attributes[SCROLLWIN_TEXT]);
534+ (void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
535535 fill_window(pad, text);
536536
537537 win_lines = min(total_lines+4, LINES-2);
@@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window, · 8 unmodified lines
546546 win = newwin(win_lines, win_cols, y, x);
547547 keypad(win, TRUE);
548548 /* show the help in the help window, and show the help panel */
549− wattrset(win, attributes[SCROLLWIN_BOX]);
549+ (void) wattrset(win, attributes[SCROLLWIN_BOX]);
550550 box(win, 0, 0);
551− wattrset(win, attributes[SCROLLWIN_HEADING]);
551+ (void) wattrset(win, attributes[SCROLLWIN_HEADING]);
552552 mvwprintw(win, 0, 3, " %s ", title);
553553 panel = new_panel(win);
554554
scripts/kconfig/nconf.h+2−1
@@ -69,7 +69,8 @@ typedef enum { · 68 unmodified lines
6969 F_BACK = 5,
7070 F_SAVE = 6,
7171 F_LOAD = 7,
72− F_EXIT = 8
72+ F_SEARCH = 8,
73+ F_EXIT = 9,
7374 } function_key;
7475
7576 void set_colors(void);
scripts/kconfig/qconf.cc+149−125
@@ -3,25 +3,42 @@ · 2 unmodified lines
33 * Released under the terms of the GNU GPL v2.0.
44 */
55
6−#include <qapplication.h>
6+#include <qglobal.h>
7+
8+#if QT_VERSION < 0x040000
79 #include <qmainwindow.h>
10+#include <qvbox.h>
11+#include <qvaluelist.h>
12+#include <qtextbrowser.h>
13+#include <qaction.h>
14+#include <qheader.h>
15+#include <qfiledialog.h>
16+#include <qdragobject.h>
17+#include <qpopupmenu.h>
18+#else
19+#include <q3mainwindow.h>
20+#include <q3vbox.h>
21+#include <q3valuelist.h>
22+#include <q3textbrowser.h>
23+#include <q3action.h>
24+#include <q3header.h>
25+#include <q3filedialog.h>
26+#include <q3dragobject.h>
27+#include <q3popupmenu.h>
28+#endif
29+
30+#include <qapplication.h>
831 #include <qdesktopwidget.h>
932 #include <qtoolbar.h>
1033 #include <qlayout.h>
11−#include <qvbox.h>
1234 #include <qsplitter.h>
13−#include <qlistview.h>
14−#include <qtextbrowser.h>
1535 #include <qlineedit.h>
1636 #include <qlabel.h>
1737 #include <qpushbutton.h>
1838 #include <qmenubar.h>
1939 #include <qmessagebox.h>
20−#include <qaction.h>
21−#include <qheader.h>
22−#include <qfiledialog.h>
23−#include <qdragobject.h>
2440 #include <qregexp.h>
41+#include <qevent.h>
2542
2643 #include <stdlib.h>
2744
@@ -39,7 +56,7 @@ · 11 unmodified lines
3956 static QApplication *configApp;
4057 static ConfigSettings *configSettings;
4158
42−QAction *ConfigMainWindow::saveAction;
59+Q3Action *ConfigMainWindow::saveAction;
4360
4461 static inline QString qgettext(const char* str)
4562 {
@@ -54,15 +71,14 @@ static inline QString qgettext(const QString& str) · 8 unmodified lines
5471 /**
5572 * Reads a list of integer values from the application settings.
5673 */
57−QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
74+Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
5875 {
59− QValueList<int> result;
76+ Q3ValueList<int> result;
6077 QStringList entryList = readListEntry(key, ok);
61− if (ok) {
62− QStringList::Iterator it;
63− for (it = entryList.begin(); it != entryList.end(); ++it)
64− result.push_back((*it).toInt());
65− }
78+ QStringList::Iterator it;
79+
80+ for (it = entryList.begin(); it != entryList.end(); ++it)
81+ result.push_back((*it).toInt());
6682
6783 return result;
6884 }
@@ -70,10 +86,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok) · 1 unmodified line
7086 /**
7187 * Writes a list of integer values to the application settings.
7288 */
73−bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
89+bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
7490 {
7591 QStringList stringList;
76− QValueList<int>::ConstIterator it;
92+ Q3ValueList<int>::ConstIterator it;
7793
7894 for (it = value.begin(); it != value.end(); ++it)
7995 stringList.push_back(QString::number(*it));
@@ -81,7 +97,6 @@ bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value · 1 unmodified line
8197 }
8298
8399
84−#if QT_VERSION >= 300
85100 /*
86101 * set the new data
87102 * TODO check the value
@@ -92,7 +107,6 @@ void ConfigItem::okRename(int col) · 4 unmodified lines
92107 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
93108 listView()->updateList(this);
94109 }
95−#endif
96110
97111 /*
98112 * update the displayed of a menu entry
@@ -149,7 +163,7 @@ void ConfigItem::updateMenu(void) · 50 unmodified lines
149163 case S_TRISTATE:
150164 char ch;
151165
152− if (!sym_is_changable(sym) && !list->showAll) {
166+ if (!sym_is_changable(sym) && list->optMode == normalOpt) {
153167 setPixmap(promptColIdx, 0);
154168 setText(noColIdx, QString::null);
155169 setText(modColIdx, QString::null);
@@ -196,11 +210,9 @@ void ConfigItem::updateMenu(void) · 40 unmodified lines
196210
197211 data = sym_get_string_value(sym);
198212
199−#if QT_VERSION >= 300
200213 int i = list->mapIdx(dataColIdx);
201214 if (i >= 0)
202215 setRenameEnabled(i, TRUE);
203−#endif
204216 setText(dataColIdx, data);
205217 if (type == S_STRING)
206218 prompt = QString("%1: %2").arg(prompt).arg(data);
@@ -320,7 +332,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name) · 113 unmodified lines
320332 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
321333 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
322334 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
323− showAll(false), showName(false), showRange(false), showData(false),
335+ showName(false), showRange(false), showData(false), optMode(normalOpt),
324336 rootEntry(0), headerPopup(0)
325337 {
326338 int i;
@@ -337,10 +349,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name) · 10 unmodified lines
337349
338350 if (name) {
339351 configSettings->beginGroup(name);
340− showAll = configSettings->readBoolEntry("/showAll", false);
341352 showName = configSettings->readBoolEntry("/showName", false);
342353 showRange = configSettings->readBoolEntry("/showRange", false);
343354 showData = configSettings->readBoolEntry("/showData", false);
355+ optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
344356 configSettings->endGroup();
345357 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
346358 }
@@ -352,6 +364,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name) · 5 unmodified lines
352364 reinit();
353365 }
354366
367+bool ConfigList::menuSkip(struct menu *menu)
368+{
369+ if (optMode == normalOpt && menu_is_visible(menu))
370+ return false;
371+ if (optMode == promptOpt && menu_has_prompt(menu))
372+ return false;
373+ if (optMode == allOpt)
374+ return false;
375+ return true;
376+}
377+
355378 void ConfigList::reinit(void)
356379 {
357380 removeColumn(dataColIdx);
@@ -380,7 +403,7 @@ void ConfigList::saveSettings(void) · 22 unmodified lines
380403 configSettings->writeEntry("/showName", showName);
381404 configSettings->writeEntry("/showRange", showRange);
382405 configSettings->writeEntry("/showData", showData);
383− configSettings->writeEntry("/showAll", showAll);
406+ configSettings->writeEntry("/optionMode", (int)optMode);
384407 configSettings->endGroup();
385408 }
386409 }
@@ -422,7 +445,7 @@ void ConfigList::updateList(ConfigItem* item) · 35 unmodified lines
422445 if (!rootEntry) {
423446 if (mode != listMode)
424447 goto update;
425− QListViewItemIterator it(this);
448+ Q3ListViewItemIterator it(this);
426449 ConfigItem* item;
427450
428451 for (; it.current(); ++it) {
@@ -517,11 +540,9 @@ void ConfigList::changeValue(ConfigItem* item) · 88 unmodified lines
517540 case S_INT:
518541 case S_HEX:
519542 case S_STRING:
520−#if QT_VERSION >= 300
521543 if (colMap[dataColIdx] >= 0)
522544 item->startRename(colMap[dataColIdx]);
523545 else
524−#endif
525546 parent()->lineEdit->show(item);
526547 break;
527548 }
@@ -553,7 +574,7 @@ void ConfigList::setParentMenu(void) · 25 unmodified lines
553574 return;
554575 setRootMenu(menu_get_parent_menu(rootEntry->parent));
555576
556− QListViewItemIterator it(this);
577+ Q3ListViewItemIterator it(this);
557578 for (; (item = (ConfigItem*)it.current()); it++) {
558579 if (item->menu == oldroot) {
559580 setCurrentItem(item);
@@ -606,7 +627,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) · 46 unmodified lines
606627 }
607628
608629 visible = menu_is_visible(child);
609− if (showAll || visible) {
630+ if (!menuSkip(child)) {
610631 if (!child->sym && !child->list && !child->prompt)
611632 continue;
612633 if (!item || item->menu != child)
@@ -635,7 +656,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu) · 22 unmodified lines
635656
636657 void ConfigList::keyPressEvent(QKeyEvent* ev)
637658 {
638− QListViewItem* i = currentItem();
659+ Q3ListViewItem* i = currentItem();
639660 ConfigItem* item;
640661 struct menu *menu;
641662 enum prop_type type;
@@ -801,10 +822,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) · 159 unmodified lines
801822 {
802823 if (e->y() <= header()->geometry().bottom()) {
803824 if (!headerPopup) {
804− QAction *action;
825+ Q3Action *action;
805826
806− headerPopup = new QPopupMenu(this);
807− action = new QAction(NULL, _("Show Name"), 0, this);
827+ headerPopup = new Q3PopupMenu(this);
828+ action = new Q3Action(NULL, _("Show Name"), 0, this);
808829 action->setToggleAction(TRUE);
809830 connect(action, SIGNAL(toggled(bool)),
810831 parent(), SLOT(setShowName(bool)));
@@ -812,7 +833,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) · 1 unmodified line
812833 action, SLOT(setOn(bool)));
813834 action->setOn(showName);
814835 action->addTo(headerPopup);
815− action = new QAction(NULL, _("Show Range"), 0, this);
836+ action = new Q3Action(NULL, _("Show Range"), 0, this);
816837 action->setToggleAction(TRUE);
817838 connect(action, SIGNAL(toggled(bool)),
818839 parent(), SLOT(setShowRange(bool)));
@@ -820,7 +841,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) · 1 unmodified line
820841 action, SLOT(setOn(bool)));
821842 action->setOn(showRange);
822843 action->addTo(headerPopup);
823− action = new QAction(NULL, _("Show Data"), 0, this);
844+ action = new Q3Action(NULL, _("Show Data"), 0, this);
824845 action->setToggleAction(TRUE);
825846 connect(action, SIGNAL(toggled(bool)),
826847 parent(), SLOT(setShowData(bool)));
@@ -835,7 +856,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e) · 8 unmodified lines
835856 e->ignore();
836857 }
837858
838−ConfigView* ConfigView::viewList;
859+ConfigView*ConfigView::viewList;
860+QAction *ConfigView::showNormalAction;
861+QAction *ConfigView::showAllAction;
862+QAction *ConfigView::showPromptAction;
839863
840864 ConfigView::ConfigView(QWidget* parent, const char *name)
841865 : Parent(parent, name)
@@ -860,13 +884,16 @@ ConfigView::~ConfigView(void) · 18 unmodified lines
860884 }
861885 }
862886
863−void ConfigView::setShowAll(bool b)
887+void ConfigView::setOptionMode(QAction *act)
864888 {
865− if (list->showAll != b) {
866− list->showAll = b;
867− list->updateListAll();
868− emit showAllChanged(b);
869− }
889+ if (act == showNormalAction)
890+ list->optMode = normalOpt;
891+ else if (act == showAllAction)
892+ list->optMode = allOpt;
893+ else
894+ list->optMode = promptOpt;
895+
896+ list->updateListAll();
870897 }
871898
872899 void ConfigView::setShowName(bool b)
@@ -898,7 +925,7 @@ void ConfigView::setShowData(bool b) · 25 unmodified lines
898925
899926 void ConfigList::setAllOpen(bool open)
900927 {
901− QListViewItemIterator it(this);
928+ Q3ListViewItemIterator it(this);
902929
903930 for (; it.current(); it++)
904931 it.current()->setOpen(open);
@@ -921,7 +948,7 @@ void ConfigView::updateListAll(void) · 16 unmodified lines
921948 }
922949
923950 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
924− : Parent(parent, name), sym(0), menu(0)
951+ : Parent(parent, name), sym(0), _menu(0)
925952 {
926953 if (name) {
927954 configSettings->beginGroup(name);
@@ -944,7 +971,7 @@ void ConfigInfoView::setShowDebug(bool b) · 16 unmodified lines
944971 {
945972 if (_showDebug != b) {
946973 _showDebug = b;
947− if (menu)
974+ if (_menu)
948975 menuInfo();
949976 else if (sym)
950977 symbolInfo();
@@ -954,44 +981,16 @@ void ConfigInfoView::setShowDebug(bool b) · 3 unmodified lines
954981
955982 void ConfigInfoView::setInfo(struct menu *m)
956983 {
957− if (menu == m)
984+ if (_menu == m)
958985 return;
959− menu = m;
986+ _menu = m;
960987 sym = NULL;
961− if (!menu)
988+ if (!_menu)
962989 clear();
963990 else
964991 menuInfo();
965992 }
966993
967−void 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−
995994 void ConfigInfoView::symbolInfo(void)
996995 {
997996 QString str;
@@ -1013,11 +1012,11 @@ void ConfigInfoView::menuInfo(void) · 15 unmodified lines
10131012 struct symbol* sym;
10141013 QString head, debug, help;
10151014
1016− sym = menu->sym;
1015+ sym = _menu->sym;
10171016 if (sym) {
1018− if (menu->prompt) {
1017+ if (_menu->prompt) {
10191018 head += "<big><b>";
1020− head += print_filter(_(menu->prompt->text));
1019+ head += print_filter(_(_menu->prompt->text));
10211020 head += "</b></big>";
10221021 if (sym->name) {
10231022 head += " (";
@@ -1043,23 +1042,23 @@ void ConfigInfoView::menuInfo(void) · 19 unmodified lines
10431042 debug = debug_info(sym);
10441043
10451044 struct gstr help_gstr = str_new();
1046− menu_get_ext_help(menu, &help_gstr);
1045+ menu_get_ext_help(_menu, &help_gstr);
10471046 help = print_filter(str_get(&help_gstr));
10481047 str_free(&help_gstr);
1049− } else if (menu->prompt) {
1048+ } else if (_menu->prompt) {
10501049 head += "<big><b>";
1051− head += print_filter(_(menu->prompt->text));
1050+ head += print_filter(_(_menu->prompt->text));
10521051 head += "</b></big><br><br>";
10531052 if (showDebug()) {
1054− if (menu->prompt->visible.expr) {
1053+ if (_menu->prompt->visible.expr) {
10551054 debug += "&nbsp;&nbsp;dep: ";
1056− expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1055+ expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
10571056 debug += "<br><br>";
10581057 }
10591058 }
10601059 }
10611060 if (showDebug())
1062− debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1061+ debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
10631062
10641063 setText(head + debug + help);
10651064 }
@@ -1162,10 +1161,10 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char · 96 unmodified lines
11621161 *text += str2;
11631162 }
11641163
1165−QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1164+Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
11661165 {
1167− QPopupMenu* popup = Parent::createPopupMenu(pos);
1168− QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
1166+ Q3PopupMenu* popup = Parent::createPopupMenu(pos);
1167+ Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
11691168 action->setToggleAction(TRUE);
11701169 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
11711170 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1222,7 +1221,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam · 50 unmodified lines
12221221 y = configSettings->readNumEntry("/window y", 0, &ok);
12231222 if (ok)
12241223 move(x, y);
1225− QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1224+ Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
12261225 if (ok)
12271226 split->setSizes(sizes);
12281227 configSettings->endGroup();
@@ -1275,8 +1274,14 @@ ConfigMainWindow::ConfigMainWindow(void) · 46 unmodified lines
12751274 char title[256];
12761275
12771276 QDesktopWidget *d = configApp->desktop();
1278− snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
1279− getenv("KERNELVERSION"));
1277+ snprintf(title, sizeof(title), "%s%s",
1278+ rootmenu.prompt->text,
1279+#if QT_VERSION < 0x040000
1280+ " (Qt3)"
1281+#else
1282+ ""
1283+#endif
1284+ );
12801285 setCaption(title);
12811286
12821287 width = configSettings->readNumEntry("/window width", d->width() - 64);
@@ -1309,60 +1314,79 @@ ConfigMainWindow::ConfigMainWindow(void) · 26 unmodified lines
13091314 configList->setFocus();
13101315
13111316 menu = menuBar();
1312− toolBar = new QToolBar("Tools", this);
1317+ toolBar = new Q3ToolBar("Tools", this);
13131318
1314− backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
1319+ backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
13151320 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
13161321 backAction->setEnabled(FALSE);
1317− QAction *quitAction = new QAction("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1322+ Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
13181323 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1319− QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1324+ Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
13201325 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1321− saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1326+ saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
13221327 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
13231328 conf_set_changed_callback(conf_changed);
13241329 // Set saveAction's initial state
13251330 conf_changed();
1326− QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
1331+ Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
13271332 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1328− QAction *searchAction = new QAction("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1333+ Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
13291334 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1330− QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1335+ Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
13311336 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1332− QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1337+ Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
13331338 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1334− QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1339+ Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
13351340 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
13361341
1337− QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
1342+ Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
13381343 showNameAction->setToggleAction(TRUE);
13391344 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
13401345 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
13411346 showNameAction->setOn(configView->showName());
1342− QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
1347+ Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
13431348 showRangeAction->setToggleAction(TRUE);
13441349 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
13451350 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
13461351 showRangeAction->setOn(configList->showRange);
1347− QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
1352+ Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
13481353 showDataAction->setToggleAction(TRUE);
13491354 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
13501355 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
13511356 showDataAction->setOn(configList->showData);
1352− QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
1353− showAllAction->setToggleAction(TRUE);
1354− connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1355− connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1356− showAllAction->setOn(configList->showAll);
1357− QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1357+
1358+ QActionGroup *optGroup = new QActionGroup(this);
1359+ optGroup->setExclusive(TRUE);
1360+ connect(optGroup, SIGNAL(selected(QAction *)), configView,
1361+ SLOT(setOptionMode(QAction *)));
1362+ connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1363+ SLOT(setOptionMode(QAction *)));
1364+
1365+#if QT_VERSION >= 0x040000
1366+ configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1367+ configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1368+ configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1369+#else
1370+ configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
1371+ configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
1372+ configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
1373+#endif
1374+ configView->showNormalAction->setToggleAction(TRUE);
1375+ configView->showNormalAction->setOn(configList->optMode == normalOpt);
1376+ configView->showAllAction->setToggleAction(TRUE);
1377+ configView->showAllAction->setOn(configList->optMode == allOpt);
1378+ configView->showPromptAction->setToggleAction(TRUE);
1379+ configView->showPromptAction->setOn(configList->optMode == promptOpt);
1380+
1381+ Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
13581382 showDebugAction->setToggleAction(TRUE);
13591383 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
13601384 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
13611385 showDebugAction->setOn(helpText->showDebug());
13621386
1363− QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
1387+ Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
13641388 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1365− QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
1389+ Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
13661390 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
13671391
13681392 // init tool bar
@@ -1376,7 +1400,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 7 unmodified lines
13761400 fullViewAction->addTo(toolBar);
13771401
13781402 // create config menu
1379− QPopupMenu* config = new QPopupMenu(this);
1403+ Q3PopupMenu* config = new Q3PopupMenu(this);
13801404 menu->insertItem(_("&File"), config);
13811405 loadAction->addTo(config);
13821406 saveAction->addTo(config);
@@ -1385,22 +1409,22 @@ ConfigMainWindow::ConfigMainWindow(void) · 2 unmodified lines
13851409 quitAction->addTo(config);
13861410
13871411 // create edit menu
1388− QPopupMenu* editMenu = new QPopupMenu(this);
1412+ Q3PopupMenu* editMenu = new Q3PopupMenu(this);
13891413 menu->insertItem(_("&Edit"), editMenu);
13901414 searchAction->addTo(editMenu);
13911415
13921416 // create options menu
1393− QPopupMenu* optionMenu = new QPopupMenu(this);
1417+ Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
13941418 menu->insertItem(_("&Option"), optionMenu);
13951419 showNameAction->addTo(optionMenu);
13961420 showRangeAction->addTo(optionMenu);
13971421 showDataAction->addTo(optionMenu);
13981422 optionMenu->insertSeparator();
1399− showAllAction->addTo(optionMenu);
1400− showDebugAction->addTo(optionMenu);
1423+ optGroup->addTo(optionMenu);
1424+ optionMenu->insertSeparator();
14011425
14021426 // create help menu
1403− QPopupMenu* helpMenu = new QPopupMenu(this);
1427+ Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
14041428 menu->insertSeparator();
14051429 menu->insertItem(_("&Help"), helpMenu);
14061430 showIntroAction->addTo(helpMenu);
@@ -1435,7 +1459,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 28 unmodified lines
14351459 showSplitView();
14361460
14371461 // UI setup done, restore splitter positions
1438− QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1462+ Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
14391463 if (ok)
14401464 split1->setSizes(sizes);
14411465
@@ -1446,7 +1470,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 4 unmodified lines
14461470
14471471 void ConfigMainWindow::loadConfig(void)
14481472 {
1449− QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1473+ QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
14501474 if (s.isNull())
14511475 return;
14521476 if (conf_read(QFile::encodeName(s)))
@@ -1462,7 +1486,7 @@ void ConfigMainWindow::saveConfig(void) · 9 unmodified lines
14621486
14631487 void ConfigMainWindow::saveConfigAs(void)
14641488 {
1465− QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1489+ QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
14661490 if (s.isNull())
14671491 return;
14681492 if (conf_write(QFile::encodeName(s)))
@@ -1491,7 +1515,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) · 22 unmodified lines
14911515 ConfigList* list = NULL;
14921516 ConfigItem* item;
14931517
1494− if (!menu_is_visible(menu) && !configView->showAll())
1518+ if (configList->menuSkip(menu))
14951519 return;
14961520
14971521 switch (configList->mode) {
@@ -1631,7 +1655,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e) · 133 unmodified lines
16311655
16321656 void ConfigMainWindow::showIntro(void)
16331657 {
1634− static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1658+ static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
16351659 "For each option, a blank box indicates the feature is disabled, a check\n"
16361660 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
16371661 "as a module. Clicking on the box will cycle through the three states.\n\n"
scripts/kconfig/qconf.h+48−45
@@ -3,26 +3,25 @@ · 2 unmodified lines
33 * Released under the terms of the GNU GPL v2.0.
44 */
55
6+#if QT_VERSION < 0x040000
67 #include <qlistview.h>
7−#if QT_VERSION >= 300
8−#include <qsettings.h>
98 #else
10−class QSettings {
11−public:
12− void beginGroup(const QString& group) { }
13− void endGroup(void) { }
14− bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const
15− { if (ok) *ok = FALSE; return def; }
16− int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const
17− { if (ok) *ok = FALSE; return def; }
18− QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const
19− { if (ok) *ok = FALSE; return def; }
20− QStringList readListEntry(const QString& key, bool* ok = 0) const
21− { if (ok) *ok = FALSE; return QStringList(); }
22− template <class t>
23− bool writeEntry(const QString& key, t value)
24− { return TRUE; }
25−};
9+#include <q3listview.h>
10+#endif
11+#include <qsettings.h>
12+
13+#if QT_VERSION < 0x040000
14+#define Q3ValueList QValueList
15+#define Q3PopupMenu QPopupMenu
16+#define Q3ListView QListView
17+#define Q3ListViewItem QListViewItem
18+#define Q3VBox QVBox
19+#define Q3TextBrowser QTextBrowser
20+#define Q3MainWindow QMainWindow
21+#define Q3Action QAction
22+#define Q3ToolBar QToolBar
23+#define Q3ListViewItemIterator QListViewItemIterator
24+#define Q3FileDialog QFileDialog
2625 #endif
2726
2827 class ConfigView;
@@ -31,11 +30,10 @@ class ConfigItem; · 2 unmodified lines
3130 class ConfigLineEdit;
3231 class ConfigMainWindow;
3332
34−
3533 class ConfigSettings : public QSettings {
3634 public:
37− QValueList<int> readSizes(const QString& key, bool *ok);
38− bool writeSizes(const QString& key, const QValueList<int>& value);
35+ Q3ValueList<int> readSizes(const QString& key, bool *ok);
36+ bool writeSizes(const QString& key, const Q3ValueList<int>& value);
3937 };
4038
4139 enum colIdx {
@@ -44,10 +42,13 @@ enum colIdx { · 2 unmodified lines
4442 enum listMode {
4543 singleMode, menuMode, symbolMode, fullMode, listMode
4644 };
45+enum optionMode {
46+ normalOpt = 0, allOpt, promptOpt
47+};
4748
48−class ConfigList : public QListView {
49+class ConfigList : public Q3ListView {
4950 Q_OBJECT
50− typedef class QListView Parent;
51+ typedef class Q3ListView Parent;
5152 public:
5253 ConfigList(ConfigView* p, const char *name = 0);
5354 void reinit(void);
@@ -115,6 +116,8 @@ public: · 61 unmodified lines
115116 void setAllOpen(bool open);
116117 void setParentMenu(void);
117118
119+ bool menuSkip(struct menu *);
120+
118121 template <class P>
119122 void updateMenuList(P*, struct menu*);
120123
@@ -124,22 +127,23 @@ public: · 3 unmodified lines
124127 QPixmap choiceYesPix, choiceNoPix;
125128 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
126129
127− bool showAll, showName, showRange, showData;
130+ bool showName, showRange, showData;
128131 enum listMode mode;
132+ enum optionMode optMode;
129133 struct menu *rootEntry;
130134 QColorGroup disabledColorGroup;
131135 QColorGroup inactivedColorGroup;
132− QPopupMenu* headerPopup;
136+ Q3PopupMenu* headerPopup;
133137
134138 private:
135139 int colMap[colNr];
136140 int colRevMap[colNr];
137141 };
138142
139−class ConfigItem : public QListViewItem {
140− typedef class QListViewItem Parent;
143+class ConfigItem : public Q3ListViewItem {
144+ typedef class Q3ListViewItem Parent;
141145 public:
142− ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
146+ ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v)
143147 : Parent(parent, after), menu(m), visible(v), goParent(false)
144148 {
145149 init();
@@ -149,16 +153,14 @@ public: · 3 unmodified lines
149153 {
150154 init();
151155 }
152− ConfigItem(QListView *parent, ConfigItem *after, bool v)
156+ ConfigItem(Q3ListView *parent, ConfigItem *after, bool v)
153157 : Parent(parent, after), menu(0), visible(v), goParent(true)
154158 {
155159 init();
156160 }
157161 ~ConfigItem(void);
158162 void init(void);
159−#if QT_VERSION >= 300
160163 void okRename(int col);
161−#endif
162164 void updateMenu(void);
163165 void testUpdateMenu(bool v);
164166 ConfigList* listView() const
@@ -213,26 +215,24 @@ public: · 48 unmodified lines
213215 ConfigItem *item;
214216 };
215217
216−class ConfigView : public QVBox {
218+class ConfigView : public Q3VBox {
217219 Q_OBJECT
218− typedef class QVBox Parent;
220+ typedef class Q3VBox Parent;
219221 public:
220222 ConfigView(QWidget* parent, const char *name = 0);
221223 ~ConfigView(void);
222224 static void updateList(ConfigItem* item);
223225 static void updateListAll(void);
224226
225− bool showAll(void) const { return list->showAll; }
226227 bool showName(void) const { return list->showName; }
227228 bool showRange(void) const { return list->showRange; }
228229 bool showData(void) const { return list->showData; }
229230 public slots:
230− void setShowAll(bool);
231231 void setShowName(bool);
232232 void setShowRange(bool);
233233 void setShowData(bool);
234+ void setOptionMode(QAction *);
234235 signals:
235− void showAllChanged(bool);
236236 void showNameChanged(bool);
237237 void showRangeChanged(bool);
238238 void showDataChanged(bool);
@@ -242,11 +242,15 @@ public: · 3 unmodified lines
242242
243243 static ConfigView* viewList;
244244 ConfigView* nextView;
245+
246+ static QAction *showNormalAction;
247+ static QAction *showAllAction;
248+ static QAction *showPromptAction;
245249 };
246250
247−class ConfigInfoView : public QTextBrowser {
251+class ConfigInfoView : public Q3TextBrowser {
248252 Q_OBJECT
249− typedef class QTextBrowser Parent;
253+ typedef class Q3TextBrowser Parent;
250254 public:
251255 ConfigInfoView(QWidget* parent, const char *name = 0);
252256 bool showDebug(void) const { return _showDebug; }
@@ -254,7 +258,6 @@ public: · 1 unmodified line
254258 public slots:
255259 void setInfo(struct menu *menu);
256260 void saveSettings(void);
257− void setSource(const QString& name);
258261 void setShowDebug(bool);
259262
260263 signals:
@@ -267,11 +270,11 @@ protected: · 6 unmodified lines
267270 QString debug_info(struct symbol *sym);
268271 static QString print_filter(const QString &str);
269272 static void expr_print_help(void *data, struct symbol *sym, const char *str);
270− QPopupMenu* createPopupMenu(const QPoint& pos);
273+ Q3PopupMenu* createPopupMenu(const QPoint& pos);
271274 void contentsContextMenuEvent(QContextMenuEvent *e);
272275
273276 struct symbol *sym;
274− struct menu *menu;
277+ struct menu *_menu;
275278 bool _showDebug;
276279 };
277280
@@ -295,10 +298,10 @@ protected: · 17 unmodified lines
295298 struct symbol **result;
296299 };
297300
298−class ConfigMainWindow : public QMainWindow {
301+class ConfigMainWindow : public Q3MainWindow {
299302 Q_OBJECT
300303
301− static QAction *saveAction;
304+ static Q3Action *saveAction;
302305 static void conf_changed(void);
303306 public:
304307 ConfigMainWindow(void);
@@ -327,8 +330,8 @@ protected: · 22 unmodified lines
327330 ConfigView *configView;
328331 ConfigList *configList;
329332 ConfigInfoView *helpText;
330− QToolBar *toolBar;
331− QAction *backAction;
333+ Q3ToolBar *toolBar;
334+ Q3Action *backAction;
332335 QSplitter* split1;
333336 QSplitter* split2;
334337 };
scripts/kconfig/streamline_config.pl+36−7
@@ -42,6 +42,8 @@ · 41 unmodified lines
4242 # mv config_strip .config
4343 # make oldconfig
4444 #
45+use strict;
46+
4547 my $config = ".config";
4648
4749 my $uname = `uname -r`;
@@ -123,7 +125,6 @@ my %selects; · 75 unmodified lines
123125 my %prompts;
124126 my %objects;
125127 my $var;
126−my $cont = 0;
127128 my $iflevel = 0;
128129 my @ifdeps;
129130
@@ -137,19 +138,45 @@ sub read_kconfig { · 7 unmodified lines
137138 my $config;
138139 my @kconfigs;
139140
140− open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig";
141+ my $cont = 0;
142+ my $line;
143+
144+ my $source = "$ksource/$kconfig";
145+ my $last_source = "";
146+
147+ # Check for any environment variables used
148+ while ($source =~ /\$(\w+)/ && $last_source ne $source) {
149+ my $env = $1;
150+ $last_source = $source;
151+ $source =~ s/\$$env/$ENV{$env}/;
152+ }
153+
154+ open(KIN, "$source") || die "Can't open $kconfig";
141155 while (<KIN>) {
142156 chomp;
143157
158+ # Make sure that lines ending with \ continue
159+ if ($cont) {
160+ $_ = $line . " " . $_;
161+ }
162+
163+ if (s/\\$//) {
164+ $cont = 1;
165+ $line = $_;
166+ next;
167+ }
168+
169+ $cont = 0;
170+
144171 # collect any Kconfig sources
145172 if (/^source\s*"(.*)"/) {
146173 $kconfigs[$#kconfigs+1] = $1;
147174 }
148175
149176 # configs found
150− if (/^\s*config\s+(\S+)\s*$/) {
177+ if (/^\s*(menu)?config\s+(\S+)\s*$/) {
151178 $state = "NEW";
152− $config = $1;
179+ $config = $2;
153180
154181 for (my $i = 0; $i < $iflevel; $i++) {
155182 if ($i) {
@@ -178,7 +205,7 @@ sub read_kconfig { · 22 unmodified lines
178205 # configs without prompts must be selected
179206 } elsif ($state ne "NONE" && /^\s*tristate\s\S/) {
180207 # note if the config has a prompt
181− $prompt{$config} = 1;
208+ $prompts{$config} = 1;
182209
183210 # Check for if statements
184211 } elsif (/^if\s+(.*\S)\s*$/) {
@@ -218,6 +245,8 @@ if ($kconfig) { · 33 unmodified lines
218245 # Read all Makefiles to map the configs to the objects
219246 foreach my $makefile (@makefiles) {
220247
248+ my $cont = 0;
249+
221250 open(MIN,$makefile) || die "Can't open $makefile";
222251 while (<MIN>) {
223252 my $objs;
@@ -281,7 +310,7 @@ if (defined($lsmod_file)) { · 57 unmodified lines
281310 # see what modules are loaded on this system
282311 my $lsmod;
283312
284− foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
313+ foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
285314 if ( -x "$dir/lsmod" ) {
286315 $lsmod = "$dir/lsmod";
287316 last;
@@ -363,7 +392,7 @@ while ($repeat) { · 75 unmodified lines
363392 parse_config_dep_select $depends{$config};
364393 }
365394
366− if (defined($prompt{$config}) || !defined($selects{$config})) {
395+ if (defined($prompts{$config}) || !defined($selects{$config})) {
367396 next;
368397 }
369398
scripts/kconfig/symbol.c+310−33
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym) · 204 unmodified lines
205205 }
206206 if (sym_is_choice_value(sym))
207207 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+ }
208218 tri = no;
209219 if (sym->rev_dep.expr)
210220 tri = expr_calc_value(sym->rev_dep.expr);
@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym) · 5 unmodified lines
216226 }
217227 }
218228
219−static 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+ */
235+struct symbol *sym_choice_default(struct symbol *sym)
220236 {
221237 struct symbol *def_sym;
222238 struct property *prop;
223239 struct expr *e;
224240
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−
233241 /* any of the defaults visible? */
234242 for_all_defaults(sym, prop) {
235243 prop->visible.tri = expr_calc_value(prop->visible.expr);
236244 if (prop->visible.tri == no)
237245 continue;
238246 def_sym = prop_get_symbol(prop);
239− sym_calc_visibility(def_sym);
240247 if (def_sym->visible != no)
241248 return def_sym;
242249 }
243250
244251 /* just get the first visible value */
245252 prop = sym_get_choice_prop(sym);
246− expr_list_for_each_sym(prop->expr, e, def_sym) {
247− sym_calc_visibility(def_sym);
253+ expr_list_for_each_sym(prop->expr, e, def_sym)
248254 if (def_sym->visible != no)
249255 return def_sym;
250− }
251256
252− /* no choice? reset tristate value */
253− sym->curr.tri = no;
257+ /* failed to locate any defaults */
254258 return NULL;
255259 }
256260
261+static 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+
257286 void sym_calc_value(struct symbol *sym)
258287 {
259288 struct symbol_value newval, oldval;
@@ -321,6 +350,14 @@ void sym_calc_value(struct symbol *sym) · 61 unmodified lines
321350 }
322351 }
323352 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+ }
324361 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
325362 }
326363 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
@@ -365,12 +402,13 @@ void sym_calc_value(struct symbol *sym) · 38 unmodified lines
365402
366403 if (sym_is_choice(sym)) {
367404 struct symbol *choice_sym;
368− int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
369405
370406 prop = sym_get_choice_prop(sym);
371407 expr_list_for_each_sym(prop->expr, e, choice_sym) {
372− choice_sym->flags |= flags;
373− if (flags & SYMBOL_CHANGED)
408+ if ((sym->flags & SYMBOL_WRITE) &&
409+ choice_sym->visible != no)
410+ choice_sym->flags |= SYMBOL_WRITE;
411+ if (sym->flags & SYMBOL_CHANGED)
374412 sym_set_changed(choice_sym);
375413 }
376414 }
@@ -623,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) · 246 unmodified lines
623661 return true;
624662 }
625663
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+ */
671+const 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+
626738 const char *sym_get_string_value(struct symbol *sym)
627739 {
628740 tristate val;
@@ -728,6 +840,55 @@ struct symbol *sym_find(const char *name) · 99 unmodified lines
728840 return symbol;
729841 }
730842
843+/*
844+ * Expand symbol's names embedded in the string given in argument. Symbols'
845+ * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
846+ * the empty string.
847+ */
848+const char *sym_expand_string_value(const char *in)
849+{
850+ const char *src;
851+ char *res;
852+ size_t reslen;
853+
854+ reslen = strlen(in) + 1;
855+ res = malloc(reslen);
856+ res[0] = '\0';
857+
858+ while ((src = strchr(in, '$'))) {
859+ char *p, name[SYMBOL_MAXLENGTH];
860+ const char *symval = "";
861+ struct symbol *sym;
862+ size_t newlen;
863+
864+ strncat(res, in, src - in);
865+ src++;
866+
867+ p = name;
868+ while (isalnum(*src) || *src == '_')
869+ *p++ = *src++;
870+ *p = '\0';
871+
872+ sym = sym_find(name);
873+ if (sym != NULL) {
874+ sym_calc_value(sym);
875+ symval = sym_get_string_value(sym);
876+ }
877+
878+ newlen = strlen(res) + strlen(symval) + strlen(src);
879+ if (newlen > reslen) {
880+ reslen = newlen;
881+ res = realloc(res, reslen);
882+ }
883+
884+ strcat(res, symval);
885+ in = src;
886+ }
887+ strcat(res, in);
888+
889+ return res;
890+}
891+
731892 struct symbol **sym_re_search(const char *pattern)
732893 {
733894 struct symbol *sym, **sym_arr = NULL;
@@ -765,6 +926,112 @@ struct symbol **sym_re_search(const char *pattern) · 31 unmodified lines
765926 return sym_arr;
766927 }
767928
929+/*
930+ * When we check for recursive dependencies we use a stack to save
931+ * current state so we can print out relevant info to user.
932+ * The entries are located on the call stack so no need to free memory.
933+ * Note inser() remove() must always match to properly clear the stack.
934+ */
935+static struct dep_stack {
936+ struct dep_stack *prev, *next;
937+ struct symbol *sym;
938+ struct property *prop;
939+ struct expr *expr;
940+} *check_top;
941+
942+static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
943+{
944+ memset(stack, 0, sizeof(*stack));
945+ if (check_top)
946+ check_top->next = stack;
947+ stack->prev = check_top;
948+ stack->sym = sym;
949+ check_top = stack;
950+}
951+
952+static void dep_stack_remove(void)
953+{
954+ check_top = check_top->prev;
955+ if (check_top)
956+ check_top->next = NULL;
957+}
958+
959+/*
960+ * Called when we have detected a recursive dependency.
961+ * check_top point to the top of the stact so we use
962+ * the ->prev pointer to locate the bottom of the stack.
963+ */
964+static void sym_check_print_recursive(struct symbol *last_sym)
965+{
966+ struct dep_stack *stack;
967+ struct symbol *sym, *next_sym;
968+ struct menu *menu = NULL;
969+ struct property *prop;
970+ struct dep_stack cv_stack;
971+
972+ if (sym_is_choice_value(last_sym)) {
973+ dep_stack_insert(&cv_stack, last_sym);
974+ last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
975+ }
976+
977+ for (stack = check_top; stack != NULL; stack = stack->prev)
978+ if (stack->sym == last_sym)
979+ break;
980+ if (!stack) {
981+ fprintf(stderr, "unexpected recursive dependency error\n");
982+ return;
983+ }
984+
985+ for (; stack; stack = stack->next) {
986+ sym = stack->sym;
987+ next_sym = stack->next ? stack->next->sym : last_sym;
988+ prop = stack->prop;
989+ if (prop == NULL)
990+ prop = stack->sym->prop;
991+
992+ /* for choice values find the menu entry (used below) */
993+ if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
994+ for (prop = sym->prop; prop; prop = prop->next) {
995+ menu = prop->menu;
996+ if (prop->menu)
997+ break;
998+ }
999+ }
1000+ if (stack->sym == last_sym)
1001+ fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
1002+ prop->file->name, prop->lineno);
1003+ if (stack->expr) {
1004+ fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
1005+ prop->file->name, prop->lineno,
1006+ sym->name ? sym->name : "<choice>",
1007+ prop_get_type_name(prop->type),
1008+ next_sym->name ? next_sym->name : "<choice>");
1009+ } else if (stack->prop) {
1010+ fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
1011+ prop->file->name, prop->lineno,
1012+ sym->name ? sym->name : "<choice>",
1013+ next_sym->name ? next_sym->name : "<choice>");
1014+ } else if (sym_is_choice(sym)) {
1015+ fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
1016+ menu->file->name, menu->lineno,
1017+ sym->name ? sym->name : "<choice>",
1018+ next_sym->name ? next_sym->name : "<choice>");
1019+ } else if (sym_is_choice_value(sym)) {
1020+ fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
1021+ menu->file->name, menu->lineno,
1022+ sym->name ? sym->name : "<choice>",
1023+ next_sym->name ? next_sym->name : "<choice>");
1024+ } else {
1025+ fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
1026+ prop->file->name, prop->lineno,
1027+ sym->name ? sym->name : "<choice>",
1028+ next_sym->name ? next_sym->name : "<choice>");
1029+ }
1030+ }
1031+
1032+ if (check_top == &cv_stack)
1033+ dep_stack_remove();
1034+}
7681035
7691036 static struct symbol *sym_check_expr_deps(struct expr *e)
7701037 {
@@ -801,24 +1068,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) · 30 unmodified lines
8011068 {
8021069 struct symbol *sym2;
8031070 struct property *prop;
1071+ struct dep_stack stack;
1072+
1073+ dep_stack_insert(&stack, sym);
8041074
8051075 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
8061076 if (sym2)
807− return sym2;
1077+ goto out;
8081078
8091079 for (prop = sym->prop; prop; prop = prop->next) {
8101080 if (prop->type == P_CHOICE || prop->type == P_SELECT)
8111081 continue;
1082+ stack.prop = prop;
8121083 sym2 = sym_check_expr_deps(prop->visible.expr);
8131084 if (sym2)
8141085 break;
8151086 if (prop->type != P_DEFAULT || sym_is_choice(sym))
8161087 continue;
1088+ stack.expr = prop->expr;
8171089 sym2 = sym_check_expr_deps(prop->expr);
8181090 if (sym2)
8191091 break;
1092+ stack.expr = NULL;
8201093 }
8211094
1095+out:
1096+ dep_stack_remove();
1097+
8221098 return sym2;
8231099 }
8241100
@@ -827,6 +1103,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) · 2 unmodified lines
8271103 struct symbol *sym, *sym2;
8281104 struct property *prop;
8291105 struct expr *e;
1106+ struct dep_stack stack;
1107+
1108+ dep_stack_insert(&stack, choice);
8301109
8311110 prop = sym_get_choice_prop(choice);
8321111 expr_list_for_each_sym(prop->expr, e, sym)
@@ -840,10 +1119,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) · 7 unmodified lines
8401119
8411120 expr_list_for_each_sym(prop->expr, e, sym) {
8421121 sym2 = sym_check_sym_deps(sym);
843− if (sym2) {
844− fprintf(stderr, " -> %s", sym->name);
1122+ if (sym2)
8451123 break;
846− }
8471124 }
8481125 out:
8491126 expr_list_for_each_sym(prop->expr, e, sym)
@@ -853,6 +1130,8 @@ out: · 3 unmodified lines
8531130 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
8541131 sym2 = choice;
8551132
1133+ dep_stack_remove();
1134+
8561135 return sym2;
8571136 }
8581137
@@ -862,18 +1141,20 @@ struct symbol *sym_check_deps(struct symbol *sym) · 3 unmodified lines
8621141 struct property *prop;
8631142
8641143 if (sym->flags & SYMBOL_CHECK) {
865− fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
866− sym->prop->file->name, sym->prop->lineno,
867− sym->name ? sym->name : "<choice>");
1144+ sym_check_print_recursive(sym);
8681145 return sym;
8691146 }
8701147 if (sym->flags & SYMBOL_CHECKED)
8711148 return NULL;
8721149
8731150 if (sym_is_choice_value(sym)) {
1151+ struct dep_stack stack;
1152+
8741153 /* for choice groups start the check with main choice symbol */
1154+ dep_stack_insert(&stack, sym);
8751155 prop = sym_get_choice_prop(sym);
8761156 sym2 = sym_check_deps(prop_get_symbol(prop));
1157+ dep_stack_remove();
8771158 } else if (sym_is_choice(sym)) {
8781159 sym2 = sym_check_choice_deps(sym);
8791160 } else {
@@ -882,14 +1163,8 @@ struct symbol *sym_check_deps(struct symbol *sym) · 2 unmodified lines
8821163 sym->flags &= ~SYMBOL_CHECK;
8831164 }
8841165
885− if (sym2) {
886− fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
887− if (sym2 == sym) {
888− fprintf(stderr, "\n");
889− zconfnerrs++;
890− sym2 = NULL;
891− }
892− }
1166+ if (sym2 && sym2 == sym)
1167+ sym2 = NULL;
8931168
8941169 return sym2;
8951170 }
@@ -943,6 +1218,8 @@ const char *prop_get_type_name(enum prop_type type) · 47 unmodified lines
9431218 return "select";
9441219 case P_RANGE:
9451220 return "range";
1221+ case P_SYMBOL:
1222+ return "symbol";
9461223 case P_UNKNOWN:
9471224 break;
9481225 }
scripts/kconfig/util.c+5−2
@@ -12,15 +12,18 @@ · 11 unmodified lines
1212 struct file *file_lookup(const char *name)
1313 {
1414 struct file *file;
15+ const char *file_name = sym_expand_string_value(name);
1516
1617 for (file = file_list; file; file = file->next) {
17− if (!strcmp(name, file->name))
18+ if (!strcmp(name, file->name)) {
19+ free((void *)file_name);
1820 return file;
21+ }
1922 }
2023
2124 file = malloc(sizeof(*file));
2225 memset(file, 0, sizeof(*file));
23− file->name = strdup(name);
26+ file->name = file_name;
2427 file->next = file_list;
2528 file_list = file;
2629 return file;
scripts/kconfig/zconf.l+4−3
@@ -304,9 +304,10 @@ void zconf_nextfile(const char *name) · 303 unmodified lines
304304 memset(buf, 0, sizeof(*buf));
305305
306306 current_buf->state = YY_CURRENT_BUFFER;
307− yyin = zconf_fopen(name);
307+ yyin = zconf_fopen(file->name);
308308 if (!yyin) {
309− printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
309+ printf("%s:%d: can't open file \"%s\"\n",
310+ zconf_curname(), zconf_lineno(), file->name);
310311 exit(1);
311312 }
312313 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
@@ -353,7 +354,7 @@ int zconf_lineno(void) · 40 unmodified lines
353354 return current_pos.lineno;
354355 }
355356
356−char *zconf_curname(void)
357+const char *zconf_curname(void)
357358 {
358359 return current_pos.file ? current_pos.file->name : "<none>";
359360 }
scripts/kconfig/zconf.tab.c_shipped+283−264
@@ -417,18 +417,18 @@ union yyalloc · 416 unmodified lines
417417 #endif
418418
419419 /* YYFINAL -- State number of the termination state. */
420−#define YYFINAL 3
420+#define YYFINAL 11
421421 /* YYLAST -- Last index in YYTABLE. */
422−#define YYLAST 259
422+#define YYLAST 277
423423
424424 /* YYNTOKENS -- Number of terminals. */
425425 #define YYNTOKENS 35
426426 /* YYNNTS -- Number of nonterminals. */
427−#define YYNNTS 46
427+#define YYNNTS 48
428428 /* YYNRULES -- Number of rules. */
429−#define YYNRULES 110
429+#define YYNRULES 113
430430 /* YYNRULES -- Number of states. */
431−#define YYNSTATES 180
431+#define YYNSTATES 185
432432
433433 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
434434 #define YYUNDEFTOK 2
@@ -476,73 +476,74 @@ static const yytype_uint8 yytranslate[] = · 41 unmodified lines
476476 YYRHS. */
477477 static const yytype_uint16 yyprhs[] =
478478 {
479− 0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
480− 28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
481− 53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
482− 81, 84, 85, 88, 91, 94, 97, 100, 103, 107,
483− 112, 117, 122, 128, 132, 133, 137, 138, 141, 145,
484− 148, 150, 154, 155, 158, 161, 164, 167, 170, 175,
485− 179, 182, 187, 188, 191, 195, 197, 201, 202, 205,
486− 208, 211, 215, 218, 220, 224, 225, 228, 231, 234,
487− 238, 242, 245, 248, 251, 252, 255, 258, 261, 266,
488− 267, 270, 272, 274, 277, 280, 283, 285, 288, 289,
489− 292, 294, 298, 302, 306, 309, 313, 317, 319, 321,
490− 322
479+ 0, 0, 3, 6, 8, 11, 13, 14, 17, 20,
480+ 23, 26, 31, 36, 40, 42, 44, 46, 48, 50,
481+ 52, 54, 56, 58, 60, 62, 64, 66, 70, 73,
482+ 77, 80, 84, 87, 88, 91, 94, 97, 100, 103,
483+ 106, 110, 115, 120, 125, 131, 135, 136, 140, 141,
484+ 144, 148, 151, 153, 157, 158, 161, 164, 167, 170,
485+ 173, 178, 182, 185, 190, 191, 194, 198, 200, 204,
486+ 205, 208, 211, 214, 218, 222, 225, 227, 231, 232,
487+ 235, 238, 241, 245, 249, 252, 255, 258, 259, 262,
488+ 265, 268, 273, 274, 277, 279, 281, 284, 287, 290,
489+ 292, 295, 296, 299, 301, 305, 309, 313, 316, 320,
490+ 324, 326, 328, 329
491491 };
492492
493493 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
494494 static const yytype_int8 yyrhs[] =
495495 {
496− 36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
497− 53, -1, 37, 64, -1, 37, 3, 74, 76, -1,
498− 37, 75, -1, 37, 25, 1, 30, -1, 37, 38,
499− 1, 30, -1, 37, 1, 30, -1, 16, -1, 18,
500− -1, 19, -1, 21, -1, 17, -1, 22, -1, 20,
501− -1, 30, -1, 59, -1, 68, -1, 42, -1, 44,
502− -1, 66, -1, 25, 1, 30, -1, 1, 30, -1,
503− 10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
504− -1, 43, 45, -1, -1, 45, 46, -1, 45, 47,
505− -1, 45, 72, -1, 45, 70, -1, 45, 40, -1,
506− 45, 30, -1, 19, 73, 30, -1, 18, 74, 77,
507− 30, -1, 20, 78, 77, 30, -1, 21, 25, 77,
508− 30, -1, 22, 79, 79, 77, 30, -1, 23, 48,
509− 30, -1, -1, 48, 25, 49, -1, -1, 33, 74,
510− -1, 7, 80, 30, -1, 50, 54, -1, 75, -1,
511− 51, 56, 52, -1, -1, 54, 55, -1, 54, 72,
512− -1, 54, 70, -1, 54, 30, -1, 54, 40, -1,
513− 18, 74, 77, 30, -1, 19, 73, 30, -1, 17,
514− 30, -1, 20, 25, 77, 30, -1, -1, 56, 39,
515− -1, 14, 78, 76, -1, 75, -1, 57, 60, 58,
516− -1, -1, 60, 39, -1, 60, 64, -1, 60, 53,
517− -1, 4, 74, 30, -1, 61, 71, -1, 75, -1,
518− 62, 65, 63, -1, -1, 65, 39, -1, 65, 64,
519− -1, 65, 53, -1, 6, 74, 30, -1, 9, 74,
520− 30, -1, 67, 71, -1, 12, 30, -1, 69, 13,
521− -1, -1, 71, 72, -1, 71, 30, -1, 71, 40,
522− -1, 16, 24, 78, 30, -1, -1, 74, 77, -1,
523− 25, -1, 26, -1, 5, 30, -1, 8, 30, -1,
524− 15, 30, -1, 30, -1, 76, 30, -1, -1, 14,
525− 78, -1, 79, -1, 79, 33, 79, -1, 79, 27,
526− 79, -1, 29, 78, 28, -1, 34, 78, -1, 78,
527− 31, 78, -1, 78, 32, 78, -1, 25, -1, 26,
528− -1, -1, 25, -1
496+ 36, 0, -1, 78, 37, -1, 37, -1, 62, 38,
497+ -1, 38, -1, -1, 38, 40, -1, 38, 54, -1,
498+ 38, 66, -1, 38, 77, -1, 38, 25, 1, 30,
499+ -1, 38, 39, 1, 30, -1, 38, 1, 30, -1,
500+ 16, -1, 18, -1, 19, -1, 21, -1, 17, -1,
501+ 22, -1, 20, -1, 30, -1, 60, -1, 70, -1,
502+ 43, -1, 45, -1, 68, -1, 25, 1, 30, -1,
503+ 1, 30, -1, 10, 25, 30, -1, 42, 46, -1,
504+ 11, 25, 30, -1, 44, 46, -1, -1, 46, 47,
505+ -1, 46, 48, -1, 46, 74, -1, 46, 72, -1,
506+ 46, 41, -1, 46, 30, -1, 19, 75, 30, -1,
507+ 18, 76, 79, 30, -1, 20, 80, 79, 30, -1,
508+ 21, 25, 79, 30, -1, 22, 81, 81, 79, 30,
509+ -1, 23, 49, 30, -1, -1, 49, 25, 50, -1,
510+ -1, 33, 76, -1, 7, 82, 30, -1, 51, 55,
511+ -1, 77, -1, 52, 57, 53, -1, -1, 55, 56,
512+ -1, 55, 74, -1, 55, 72, -1, 55, 30, -1,
513+ 55, 41, -1, 18, 76, 79, 30, -1, 19, 75,
514+ 30, -1, 17, 30, -1, 20, 25, 79, 30, -1,
515+ -1, 57, 40, -1, 14, 80, 78, -1, 77, -1,
516+ 58, 61, 59, -1, -1, 61, 40, -1, 61, 66,
517+ -1, 61, 54, -1, 3, 76, 78, -1, 4, 76,
518+ 30, -1, 63, 73, -1, 77, -1, 64, 67, 65,
519+ -1, -1, 67, 40, -1, 67, 66, -1, 67, 54,
520+ -1, 6, 76, 30, -1, 9, 76, 30, -1, 69,
521+ 73, -1, 12, 30, -1, 71, 13, -1, -1, 73,
522+ 74, -1, 73, 30, -1, 73, 41, -1, 16, 24,
523+ 80, 30, -1, -1, 76, 79, -1, 25, -1, 26,
524+ -1, 5, 30, -1, 8, 30, -1, 15, 30, -1,
525+ 30, -1, 78, 30, -1, -1, 14, 80, -1, 81,
526+ -1, 81, 33, 81, -1, 81, 27, 81, -1, 29,
527+ 80, 28, -1, 34, 80, -1, 80, 31, 80, -1,
528+ 80, 32, 80, -1, 25, -1, 26, -1, -1, 25,
529+ -1
529530 };
530531
531532 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
532533 static const yytype_uint16 yyrline[] =
533534 {
534− 0, 107, 107, 109, 111, 112, 113, 114, 115, 116,
535− 117, 121, 125, 125, 125, 125, 125, 125, 125, 129,
536− 130, 131, 132, 133, 134, 138, 139, 145, 153, 159,
537− 167, 177, 179, 180, 181, 182, 183, 184, 187, 195,
538− 201, 211, 217, 223, 226, 228, 239, 240, 245, 254,
539− 259, 267, 270, 272, 273, 274, 275, 276, 279, 285,
540− 296, 302, 312, 314, 319, 327, 335, 338, 340, 341,
541− 342, 347, 354, 359, 367, 370, 372, 373, 374, 377,
542− 385, 392, 399, 405, 412, 414, 415, 416, 419, 427,
543− 429, 434, 435, 438, 439, 440, 444, 445, 448, 449,
544− 452, 453, 454, 455, 456, 457, 458, 461, 462, 465,
545− 466
535+ 0, 107, 107, 107, 109, 109, 111, 113, 114, 115,
536+ 116, 117, 118, 122, 126, 126, 126, 126, 126, 126,
537+ 126, 130, 131, 132, 133, 134, 135, 139, 140, 146,
538+ 154, 160, 168, 178, 180, 181, 182, 183, 184, 185,
539+ 188, 196, 202, 212, 218, 224, 227, 229, 240, 241,
540+ 246, 255, 260, 268, 271, 273, 274, 275, 276, 277,
541+ 280, 286, 297, 303, 313, 315, 320, 328, 336, 339,
542+ 341, 342, 343, 348, 355, 362, 367, 375, 378, 380,
543+ 381, 382, 385, 393, 400, 407, 413, 420, 422, 423,
544+ 424, 427, 435, 437, 442, 443, 446, 447, 448, 452,
545+ 453, 456, 457, 460, 461, 462, 463, 464, 465, 466,
546+ 469, 470, 473, 474
546547 };
547548 #endif
548549
@@ -557,17 +558,17 @@ static const char *const yytname[] = · 8 unmodified lines
557558 "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
558559 "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
559560 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
560− "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
561− "option_error", "config_entry_start", "config_stmt",
561+ "T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
562+ "common_stmt", "option_error", "config_entry_start", "config_stmt",
562563 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
563564 "config_option", "symbol_option", "symbol_option_list",
564565 "symbol_option_arg", "choice", "choice_entry", "choice_end",
565566 "choice_stmt", "choice_option_list", "choice_option", "choice_block",
566− "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry",
567− "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment",
568− "comment_stmt", "help_start", "help", "depends_list", "depends",
569− "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol",
570− "word_opt", 0
567+ "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
568+ "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
569+ "comment", "comment_stmt", "help_start", "help", "depends_list",
570+ "depends", "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr",
571+ "symbol", "word_opt", 0
571572 };
572573 #endif
573574
@@ -586,35 +587,35 @@ static const yytype_uint16 yytoknum[] = · 12 unmodified lines
586587 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
587588 static const yytype_uint8 yyr1[] =
588589 {
589− 0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
590− 37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
591− 39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
592− 44, 45, 45, 45, 45, 45, 45, 45, 46, 46,
593− 46, 46, 46, 47, 48, 48, 49, 49, 50, 51,
594− 52, 53, 54, 54, 54, 54, 54, 54, 55, 55,
595− 55, 55, 56, 56, 57, 58, 59, 60, 60, 60,
596− 60, 61, 62, 63, 64, 65, 65, 65, 65, 66,
597− 67, 68, 69, 70, 71, 71, 71, 71, 72, 73,
598− 73, 74, 74, 75, 75, 75, 76, 76, 77, 77,
599− 78, 78, 78, 78, 78, 78, 78, 79, 79, 80,
600− 80
590+ 0, 35, 36, 36, 37, 37, 38, 38, 38, 38,
591+ 38, 38, 38, 38, 39, 39, 39, 39, 39, 39,
592+ 39, 40, 40, 40, 40, 40, 40, 41, 41, 42,
593+ 43, 44, 45, 46, 46, 46, 46, 46, 46, 46,
594+ 47, 47, 47, 47, 47, 48, 49, 49, 50, 50,
595+ 51, 52, 53, 54, 55, 55, 55, 55, 55, 55,
596+ 56, 56, 56, 56, 57, 57, 58, 59, 60, 61,
597+ 61, 61, 61, 62, 63, 64, 65, 66, 67, 67,
598+ 67, 67, 68, 69, 70, 71, 72, 73, 73, 73,
599+ 73, 74, 75, 75, 76, 76, 77, 77, 77, 78,
600+ 78, 79, 79, 80, 80, 80, 80, 80, 80, 80,
601+ 81, 81, 82, 82
601602 };
602603
603604 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
604605 static const yytype_uint8 yyr2[] =
605606 {
606− 0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
607− 4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
608− 1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
609− 2, 0, 2, 2, 2, 2, 2, 2, 3, 4,
610− 4, 4, 5, 3, 0, 3, 0, 2, 3, 2,
611− 1, 3, 0, 2, 2, 2, 2, 2, 4, 3,
612− 2, 4, 0, 2, 3, 1, 3, 0, 2, 2,
613− 2, 3, 2, 1, 3, 0, 2, 2, 2, 3,
614− 3, 2, 2, 2, 0, 2, 2, 2, 4, 0,
615− 2, 1, 1, 2, 2, 2, 1, 2, 0, 2,
616− 1, 3, 3, 3, 2, 3, 3, 1, 1, 0,
617− 1
607+ 0, 2, 2, 1, 2, 1, 0, 2, 2, 2,
608+ 2, 4, 4, 3, 1, 1, 1, 1, 1, 1,
609+ 1, 1, 1, 1, 1, 1, 1, 3, 2, 3,
610+ 2, 3, 2, 0, 2, 2, 2, 2, 2, 2,
611+ 3, 4, 4, 4, 5, 3, 0, 3, 0, 2,
612+ 3, 2, 1, 3, 0, 2, 2, 2, 2, 2,
613+ 4, 3, 2, 4, 0, 2, 3, 1, 3, 0,
614+ 2, 2, 2, 3, 3, 2, 1, 3, 0, 2,
615+ 2, 2, 3, 3, 2, 2, 2, 0, 2, 2,
616+ 2, 4, 0, 2, 1, 1, 2, 2, 2, 1,
617+ 2, 0, 2, 1, 3, 3, 3, 2, 3, 3,
618+ 1, 1, 0, 1
618619 };
619620
620621 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -622,158 +623,165 @@ static const yytype_uint8 yyr2[] = · 1 unmodified line
622623 means the default is an error. */
623624 static const yytype_uint8 yydefact[] =
624625 {
625− 3, 0, 0, 1, 0, 0, 0, 0, 0, 109,
626− 0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
627− 18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
628− 23, 52, 62, 5, 67, 20, 84, 75, 6, 24,
629− 84, 21, 8, 11, 91, 92, 0, 0, 93, 0,
630− 110, 0, 94, 0, 0, 0, 107, 108, 0, 0,
631− 0, 100, 95, 0, 0, 0, 0, 0, 0, 0,
632− 0, 0, 0, 96, 7, 71, 79, 48, 80, 27,
633− 29, 0, 104, 0, 0, 64, 0, 0, 9, 10,
634− 0, 0, 0, 0, 89, 0, 0, 0, 44, 0,
635− 37, 36, 32, 33, 0, 35, 34, 0, 0, 89,
636− 0, 56, 57, 53, 55, 54, 63, 51, 50, 68,
637− 70, 66, 69, 65, 86, 87, 85, 76, 78, 74,
638− 77, 73, 97, 103, 105, 106, 102, 101, 26, 82,
639− 0, 98, 0, 98, 98, 98, 0, 0, 0, 83,
640− 60, 98, 0, 98, 0, 0, 0, 38, 90, 0,
641− 0, 98, 46, 43, 25, 0, 59, 0, 88, 99,
642− 39, 40, 41, 0, 0, 45, 58, 61, 42, 47
626+ 6, 0, 99, 0, 3, 0, 6, 6, 94, 95,
627+ 0, 1, 0, 0, 0, 0, 112, 0, 0, 0,
628+ 0, 0, 0, 14, 18, 15, 16, 20, 17, 19,
629+ 0, 21, 0, 7, 33, 24, 33, 25, 54, 64,
630+ 8, 69, 22, 87, 78, 9, 26, 87, 23, 10,
631+ 0, 100, 2, 73, 13, 0, 96, 0, 113, 0,
632+ 97, 0, 0, 0, 110, 111, 0, 0, 0, 103,
633+ 98, 0, 0, 0, 0, 0, 0, 0, 0, 0,
634+ 0, 74, 82, 50, 83, 29, 31, 0, 107, 0,
635+ 0, 66, 0, 0, 11, 12, 0, 0, 0, 0,
636+ 92, 0, 0, 0, 46, 0, 39, 38, 34, 35,
637+ 0, 37, 36, 0, 0, 92, 0, 58, 59, 55,
638+ 57, 56, 65, 53, 52, 70, 72, 68, 71, 67,
639+ 89, 90, 88, 79, 81, 77, 80, 76, 106, 108,
640+ 109, 105, 104, 28, 85, 0, 101, 0, 101, 101,
641+ 101, 0, 0, 0, 86, 62, 101, 0, 101, 0,
642+ 0, 0, 40, 93, 0, 0, 101, 48, 45, 27,
643+ 0, 61, 0, 91, 102, 41, 42, 43, 0, 0,
644+ 47, 60, 63, 44, 49
643645 };
644646
645647 /* YYDEFGOTO[NTERM-NUM]. */
646648 static const yytype_int16 yydefgoto[] =
647649 {
648− -1, 1, 2, 25, 26, 101, 27, 28, 29, 30,
649− 65, 102, 103, 147, 175, 31, 32, 117, 33, 67,
650− 113, 68, 34, 121, 35, 69, 36, 37, 129, 38,
651− 71, 39, 40, 41, 104, 105, 70, 106, 142, 143,
652− 42, 74, 156, 60, 61, 51
650+ -1, 3, 4, 5, 32, 33, 107, 34, 35, 36,
651+ 37, 73, 108, 109, 152, 180, 38, 39, 123, 40,
652+ 75, 119, 76, 41, 127, 42, 77, 6, 43, 44,
653+ 135, 45, 79, 46, 47, 48, 110, 111, 78, 112,
654+ 147, 148, 49, 7, 161, 68, 69, 59
653655 };
654656
655657 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
656658 STATE-NUM. */
657−#define YYPACT_NINF -80
659+#define YYPACT_NINF -89
658660 static const yytype_int16 yypact[] =
659661 {
660− -80, 2, 132, -80, -13, -1, -1, -2, -1, 9,
661− 33, -1, 27, 40, -3, 38, -80, -80, -80, -80,
662− -80, -80, -80, 71, -80, 77, -80, -80, -80, -80,
663− -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
664− -80, -80, -80, -80, -80, -80, 57, 61, -80, 63,
665− -80, 76, -80, 87, 101, 133, -80, -80, -3, -3,
666− 195, -6, -80, 136, 149, 39, 104, 65, 150, 5,
667− 194, 5, 167, -80, 176, -80, -80, -80, -80, -80,
668− -80, 68, -80, -3, -3, 176, 72, 72, -80, -80,
669− 177, 187, 78, -1, -1, -3, 196, 72, -80, 222,
670− -80, -80, -80, -80, 221, -80, -80, 205, -1, -1,
671− 211, -80, -80, -80, -80, -80, -80, -80, -80, -80,
672− -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
673− -80, -80, -80, -80, 206, -80, -80, -80, -80, -80,
674− -3, 223, 209, 223, 197, 223, 72, 7, 210, -80,
675− -80, 223, 212, 223, 201, -3, 213, -80, -80, 214,
676− 215, 223, 208, -80, -80, 216, -80, 217, -80, 113,
677− -80, -80, -80, 218, -1, -80, -80, -80, -80, -80
662+ 3, 4, -89, 20, -89, 100, -89, 7, -89, -89,
663+ -8, -89, 17, 4, 28, 4, 37, 36, 4, 68,
664+ 87, -18, 69, -89, -89, -89, -89, -89, -89, -89,
665+ 128, -89, 138, -89, -89, -89, -89, -89, -89, -89,
666+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
667+ 127, -89, -89, 110, -89, 126, -89, 136, -89, 137,
668+ -89, 147, 150, 152, -89, -89, -18, -18, 171, -14,
669+ -89, 153, 157, 34, 67, 180, 233, 220, 207, 220,
670+ 154, -89, -89, -89, -89, -89, -89, 0, -89, -18,
671+ -18, 110, 44, 44, -89, -89, 163, 174, 182, 4,
672+ 4, -18, 194, 44, -89, 219, -89, -89, -89, -89,
673+ 223, -89, -89, 203, 4, 4, 215, -89, -89, -89,
674+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
675+ -89, -89, -89, -89, -89, -89, -89, -89, -89, 213,
676+ -89, -89, -89, -89, -89, -18, 232, 227, 232, -5,
677+ 232, 44, 35, 234, -89, -89, 232, 235, 232, 224,
678+ -18, 236, -89, -89, 237, 238, 232, 216, -89, -89,
679+ 240, -89, 241, -89, 71, -89, -89, -89, 242, 4,
680+ -89, -89, -89, -89, -89
678681 };
679682
680683 /* YYPGOTO[NTERM-NUM]. */
681684 static const yytype_int16 yypgoto[] =
682685 {
683− -80, -80, -80, -80, 122, -34, -80, -80, -80, -80,
684− 220, -80, -80, -80, -80, -80, -80, -80, 59, -80,
685− -80, -80, -80, -80, -80, -80, -80, -80, -80, 125,
686− -80, -80, -80, -80, -80, 183, 219, 22, 142, -5,
687− 147, 192, 69, -54, -79, -80
686+ -89, -89, 255, 267, -89, 47, -57, -89, -89, -89,
687+ -89, 239, -89, -89, -89, -89, -89, -89, -89, 130,
688+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
689+ -89, 181, -89, -89, -89, -89, -89, 199, 229, 16,
690+ 162, -1, 74, -7, 103, -65, -88, -89
688691 };
689692
690693 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
691694 positive, shift that token. If negative, reduce the rule which
692695 number is the opposite. If zero, do what YYDEFACT says.
693696 If YYTABLE_NINF, syntax error. */
694−#define YYTABLE_NINF -82
697+#define YYTABLE_NINF -85
695698 static const yytype_int16 yytable[] =
696699 {
697− 46, 47, 3, 49, 81, 82, 53, 136, 137, 6,
698− 7, 8, 9, 10, 11, 12, 13, 43, 146, 14,
699− 15, 86, 56, 57, 44, 45, 58, 87, 48, 134,
700− 135, 59, 162, 112, 50, 24, 125, 163, 125, -28,
701− 90, 144, -28, -28, -28, -28, -28, -28, -28, -28,
702− -28, 91, 54, -28, -28, 92, -28, 93, 94, 95,
703− 96, 97, 98, 52, 99, 55, 90, 161, 62, 100,
704− -49, -49, 63, -49, -49, -49, -49, 91, 64, -49,
705− -49, 92, 107, 108, 109, 110, 154, 73, 141, 115,
706− 99, 75, 126, 76, 126, 111, 133, 56, 57, 83,
707− 84, 169, 140, 151, -30, 90, 77, -30, -30, -30,
708− -30, -30, -30, -30, -30, -30, 91, 78, -30, -30,
709− 92, -30, 93, 94, 95, 96, 97, 98, 120, 99,
710− 128, 79, -2, 4, 100, 5, 6, 7, 8, 9,
711− 10, 11, 12, 13, 83, 84, 14, 15, 16, 17,
712− 18, 19, 20, 21, 22, 7, 8, 23, 10, 11,
713− 12, 13, 24, 80, 14, 15, 88, -81, 90, 179,
714− -81, -81, -81, -81, -81, -81, -81, -81, -81, 89,
715− 24, -81, -81, 92, -81, -81, -81, -81, -81, -81,
716− 116, 119, 99, 127, 122, 90, 130, 124, -72, -72,
717− -72, -72, -72, -72, -72, -72, 132, 138, -72, -72,
718− 92, 155, 158, 159, 160, 118, 123, 139, 131, 99,
719− 165, 145, 167, 148, 124, 73, 83, 84, 83, 84,
720− 173, 168, 83, 84, 149, 150, 153, 155, 84, 157,
721− 164, 174, 166, 170, 171, 172, 176, 177, 178, 66,
722− 114, 152, 85, 0, 0, 0, 0, 0, 0, 72
700+ 10, 87, 88, 53, 141, 142, 1, 64, 65, 160,
701+ 1, 66, 55, 92, 57, 151, 67, 61, 118, 93,
702+ 11, 131, 2, 131, 139, 140, 89, 90, 138, 8,
703+ 9, 89, 90, 2, -30, 96, 149, 51, -30, -30,
704+ -30, -30, -30, -30, -30, -30, 97, 54, -30, -30,
705+ 98, -30, 99, 100, 101, 102, 103, 104, 56, 105,
706+ 167, 91, 58, 166, 106, 168, 60, -32, 96, 64,
707+ 65, -32, -32, -32, -32, -32, -32, -32, -32, 97,
708+ 159, -32, -32, 98, -32, 99, 100, 101, 102, 103,
709+ 104, 121, 105, 62, 132, 174, 132, 106, 146, 70,
710+ -5, 12, 89, 90, 13, 14, 15, 16, 17, 18,
711+ 19, 20, 63, 156, 21, 22, 23, 24, 25, 26,
712+ 27, 28, 29, 122, 125, 30, 133, -4, 12, 71,
713+ 31, 13, 14, 15, 16, 17, 18, 19, 20, 72,
714+ 51, 21, 22, 23, 24, 25, 26, 27, 28, 29,
715+ 124, 129, 30, 137, -84, 96, 81, 31, -84, -84,
716+ -84, -84, -84, -84, -84, -84, 82, 83, -84, -84,
717+ 98, -84, -84, -84, -84, -84, -84, 84, 184, 105,
718+ 85, 96, 86, 94, 130, -51, -51, 95, -51, -51,
719+ -51, -51, 97, 143, -51, -51, 98, 113, 114, 115,
720+ 116, 2, 89, 90, 144, 105, 145, 126, 96, 134,
721+ 117, -75, -75, -75, -75, -75, -75, -75, -75, 150,
722+ 153, -75, -75, 98, 13, 14, 15, 16, 17, 18,
723+ 19, 20, 105, 155, 21, 22, 154, 130, 14, 15,
724+ 158, 17, 18, 19, 20, 90, 160, 21, 22, 179,
725+ 31, 163, 164, 165, 173, 89, 90, 162, 128, 170,
726+ 136, 172, 52, 31, 169, 171, 175, 176, 177, 178,
727+ 181, 182, 183, 50, 120, 74, 80, 157
723728 };
724729
725−static const yytype_int16 yycheck[] =
730+static const yytype_uint8 yycheck[] =
726731 {
727− 5, 6, 0, 8, 58, 59, 11, 86, 87, 4,
728− 5, 6, 7, 8, 9, 10, 11, 30, 97, 14,
729− 15, 27, 25, 26, 25, 26, 29, 33, 30, 83,
730− 84, 34, 25, 67, 25, 30, 70, 30, 72, 0,
731− 1, 95, 3, 4, 5, 6, 7, 8, 9, 10,
732− 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
733− 21, 22, 23, 30, 25, 25, 1, 146, 30, 30,
734− 5, 6, 1, 8, 9, 10, 11, 12, 1, 14,
735− 15, 16, 17, 18, 19, 20, 140, 30, 93, 67,
736− 25, 30, 70, 30, 72, 30, 28, 25, 26, 31,
737− 32, 155, 24, 108, 0, 1, 30, 3, 4, 5,
732+ 1, 66, 67, 10, 92, 93, 3, 25, 26, 14,
733+ 3, 29, 13, 27, 15, 103, 34, 18, 75, 33,
734+ 0, 78, 30, 80, 89, 90, 31, 32, 28, 25,
735+ 26, 31, 32, 30, 0, 1, 101, 30, 4, 5,
738736 6, 7, 8, 9, 10, 11, 12, 30, 14, 15,
739− 16, 17, 18, 19, 20, 21, 22, 23, 69, 25,
740− 71, 30, 0, 1, 30, 3, 4, 5, 6, 7,
741− 8, 9, 10, 11, 31, 32, 14, 15, 16, 17,
742− 18, 19, 20, 21, 22, 5, 6, 25, 8, 9,
743− 10, 11, 30, 30, 14, 15, 30, 0, 1, 174,
744− 3, 4, 5, 6, 7, 8, 9, 10, 11, 30,
737+ 16, 17, 18, 19, 20, 21, 22, 23, 30, 25,
738+ 25, 68, 25, 151, 30, 30, 30, 0, 1, 25,
739+ 26, 4, 5, 6, 7, 8, 9, 10, 11, 12,
740+ 145, 14, 15, 16, 17, 18, 19, 20, 21, 22,
741+ 23, 75, 25, 25, 78, 160, 80, 30, 99, 30,
742+ 0, 1, 31, 32, 4, 5, 6, 7, 8, 9,
743+ 10, 11, 25, 114, 14, 15, 16, 17, 18, 19,
744+ 20, 21, 22, 76, 77, 25, 79, 0, 1, 1,
745+ 30, 4, 5, 6, 7, 8, 9, 10, 11, 1,
745746 30, 14, 15, 16, 17, 18, 19, 20, 21, 22,
746− 68, 69, 25, 71, 69, 1, 71, 30, 4, 5,
747+ 76, 77, 25, 79, 0, 1, 30, 30, 4, 5,
747748 6, 7, 8, 9, 10, 11, 30, 30, 14, 15,
748− 16, 14, 143, 144, 145, 68, 69, 30, 71, 25,
749− 151, 25, 153, 1, 30, 30, 31, 32, 31, 32,
750− 161, 30, 31, 32, 13, 30, 25, 14, 32, 30,
751− 30, 33, 30, 30, 30, 30, 30, 30, 30, 29,
752− 67, 109, 60, -1, -1, -1, -1, -1, -1, 40
749+ 16, 17, 18, 19, 20, 21, 22, 30, 179, 25,
750+ 30, 1, 30, 30, 30, 5, 6, 30, 8, 9,
751+ 10, 11, 12, 30, 14, 15, 16, 17, 18, 19,
752+ 20, 30, 31, 32, 30, 25, 24, 77, 1, 79,
753+ 30, 4, 5, 6, 7, 8, 9, 10, 11, 25,
754+ 1, 14, 15, 16, 4, 5, 6, 7, 8, 9,
755+ 10, 11, 25, 30, 14, 15, 13, 30, 5, 6,
756+ 25, 8, 9, 10, 11, 32, 14, 14, 15, 33,
757+ 30, 148, 149, 150, 30, 31, 32, 30, 77, 156,
758+ 79, 158, 7, 30, 30, 30, 30, 30, 30, 166,
759+ 30, 30, 30, 6, 75, 36, 47, 115
753760 };
754761
755762 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
756763 symbol of state STATE-NUM. */
757764 static const yytype_uint8 yystos[] =
758765 {
759− 0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
760− 8, 9, 10, 11, 14, 15, 16, 17, 18, 19,
761− 20, 21, 22, 25, 30, 38, 39, 41, 42, 43,
762− 44, 50, 51, 53, 57, 59, 61, 62, 64, 66,
763− 67, 68, 75, 30, 25, 26, 74, 74, 30, 74,
764− 25, 80, 30, 74, 25, 25, 25, 26, 29, 34,
765− 78, 79, 30, 1, 1, 45, 45, 54, 56, 60,
766− 71, 65, 71, 30, 76, 30, 30, 30, 30, 30,
767− 30, 78, 78, 31, 32, 76, 27, 33, 30, 30,
768− 1, 12, 16, 18, 19, 20, 21, 22, 23, 25,
769− 30, 40, 46, 47, 69, 70, 72, 17, 18, 19,
770− 20, 30, 40, 55, 70, 72, 39, 52, 75, 39,
771− 53, 58, 64, 75, 30, 40, 72, 39, 53, 63,
772− 64, 75, 30, 28, 78, 78, 79, 79, 30, 30,
773− 24, 74, 73, 74, 78, 25, 79, 48, 1, 13,
774− 30, 74, 73, 25, 78, 14, 77, 30, 77, 77,
775− 77, 79, 25, 30, 30, 77, 30, 77, 30, 78,
776− 30, 30, 30, 77, 33, 49, 30, 30, 30, 74
766+ 0, 3, 30, 36, 37, 38, 62, 78, 25, 26,
767+ 76, 0, 1, 4, 5, 6, 7, 8, 9, 10,
768+ 11, 14, 15, 16, 17, 18, 19, 20, 21, 22,
769+ 25, 30, 39, 40, 42, 43, 44, 45, 51, 52,
770+ 54, 58, 60, 63, 64, 66, 68, 69, 70, 77,
771+ 38, 30, 37, 78, 30, 76, 30, 76, 25, 82,
772+ 30, 76, 25, 25, 25, 26, 29, 34, 80, 81,
773+ 30, 1, 1, 46, 46, 55, 57, 61, 73, 67,
774+ 73, 30, 30, 30, 30, 30, 30, 80, 80, 31,
775+ 32, 78, 27, 33, 30, 30, 1, 12, 16, 18,
776+ 19, 20, 21, 22, 23, 25, 30, 41, 47, 48,
777+ 71, 72, 74, 17, 18, 19, 20, 30, 41, 56,
778+ 72, 74, 40, 53, 77, 40, 54, 59, 66, 77,
779+ 30, 41, 74, 40, 54, 65, 66, 77, 28, 80,
780+ 80, 81, 81, 30, 30, 24, 76, 75, 76, 80,
781+ 25, 81, 49, 1, 13, 30, 76, 75, 25, 80,
782+ 14, 79, 30, 79, 79, 79, 81, 25, 30, 30,
783+ 79, 30, 79, 30, 80, 30, 30, 30, 79, 33,
784+ 50, 30, 30, 30, 76
777785 };
778786
779787 #define yyerrok (yyerrstatus = 0)
@@ -1284,7 +1292,7 @@ yydestruct (yymsg, yytype, yyvaluep) · 504 unmodified lines
12841292
12851293 switch (yytype)
12861294 {
1287− case 51: /* "choice_entry" */
1295+ case 52: /* "choice_entry" */
12881296
12891297 {
12901298 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1294,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep) · 3 unmodified lines
12941302 };
12951303
12961304 break;
1297− case 57: /* "if_entry" */
1305+ case 58: /* "if_entry" */
12981306
12991307 {
13001308 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1304,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep) · 3 unmodified lines
13041312 };
13051313
13061314 break;
1307− case 62: /* "menu_entry" */
1315+ case 64: /* "menu_entry" */
13081316
13091317 {
13101318 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1614,39 +1622,39 @@ yyreduce: · 303 unmodified lines
16141622 YY_REDUCE_PRINT (yyn);
16151623 switch (yyn)
16161624 {
1617− case 8:
1625+ case 10:
16181626
16191627 { zconf_error("unexpected end statement"); ;}
16201628 break;
16211629
1622− case 9:
1630+ case 11:
16231631
16241632 { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;}
16251633 break;
16261634
1627− case 10:
1635+ case 12:
16281636
16291637 {
16301638 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name);
16311639 ;}
16321640 break;
16331641
1634− case 11:
1642+ case 13:
16351643
16361644 { zconf_error("invalid statement"); ;}
16371645 break;
16381646
1639− case 25:
1647+ case 27:
16401648
16411649 { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
16421650 break;
16431651
1644− case 26:
1652+ case 28:
16451653
16461654 { zconf_error("invalid option"); ;}
16471655 break;
16481656
1649− case 27:
1657+ case 29:
16501658
16511659 {
16521660 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1656,7 +1664,7 @@ yyreduce: · 3 unmodified lines
16561664 ;}
16571665 break;
16581666
1659− case 28:
1667+ case 30:
16601668
16611669 {
16621670 menu_end_entry();
@@ -1664,7 +1672,7 @@ yyreduce: · 1 unmodified line
16641672 ;}
16651673 break;
16661674
1667− case 29:
1675+ case 31:
16681676
16691677 {
16701678 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1674,7 +1682,7 @@ yyreduce: · 3 unmodified lines
16741682 ;}
16751683 break;
16761684
1677− case 30:
1685+ case 32:
16781686
16791687 {
16801688 if (current_entry->prompt)
@@ -1686,7 +1694,7 @@ yyreduce: · 5 unmodified lines
16861694 ;}
16871695 break;
16881696
1689− case 38:
1697+ case 40:
16901698
16911699 {
16921700 menu_set_type((yyvsp[(1) - (3)].id)->stype);
@@ -1696,7 +1704,7 @@ yyreduce: · 3 unmodified lines
16961704 ;}
16971705 break;
16981706
1699− case 39:
1707+ case 41:
17001708
17011709 {
17021710 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1704,7 +1712,7 @@ yyreduce: · 1 unmodified line
17041712 ;}
17051713 break;
17061714
1707− case 40:
1715+ case 42:
17081716
17091717 {
17101718 menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
@@ -1716,7 +1724,7 @@ yyreduce: · 5 unmodified lines
17161724 ;}
17171725 break;
17181726
1719− case 41:
1727+ case 43:
17201728
17211729 {
17221730 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
@@ -1724,7 +1732,7 @@ yyreduce: · 1 unmodified line
17241732 ;}
17251733 break;
17261734
1727− case 42:
1735+ case 44:
17281736
17291737 {
17301738 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
@@ -1732,7 +1740,7 @@ yyreduce: · 1 unmodified line
17321740 ;}
17331741 break;
17341742
1735− case 45:
1743+ case 47:
17361744
17371745 {
17381746 struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
@@ -1744,17 +1752,17 @@ yyreduce: · 5 unmodified lines
17441752 ;}
17451753 break;
17461754
1747− case 46:
1755+ case 48:
17481756
17491757 { (yyval.string) = NULL; ;}
17501758 break;
17511759
1752− case 47:
1760+ case 49:
17531761
17541762 { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
17551763 break;
17561764
1757− case 48:
1765+ case 50:
17581766
17591767 {
17601768 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
@@ -1765,14 +1773,14 @@ yyreduce: · 4 unmodified lines
17651773 ;}
17661774 break;
17671775
1768− case 49:
1776+ case 51:
17691777
17701778 {
17711779 (yyval.menu) = menu_add_menu();
17721780 ;}
17731781 break;
17741782
1775− case 50:
1783+ case 52:
17761784
17771785 {
17781786 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
@@ -1782,7 +1790,7 @@ yyreduce: · 3 unmodified lines
17821790 ;}
17831791 break;
17841792
1785− case 58:
1793+ case 60:
17861794
17871795 {
17881796 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1790,7 +1798,7 @@ yyreduce: · 1 unmodified line
17901798 ;}
17911799 break;
17921800
1793− case 59:
1801+ case 61:
17941802
17951803 {
17961804 if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
@@ -1803,7 +1811,7 @@ yyreduce: · 6 unmodified lines
18031811 ;}
18041812 break;
18051813
1806− case 60:
1814+ case 62:
18071815
18081816 {
18091817 current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1811,7 +1819,7 @@ yyreduce: · 1 unmodified line
18111819 ;}
18121820 break;
18131821
1814− case 61:
1822+ case 63:
18151823
18161824 {
18171825 if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
@@ -1823,7 +1831,7 @@ yyreduce: · 5 unmodified lines
18231831 ;}
18241832 break;
18251833
1826− case 64:
1834+ case 66:
18271835
18281836 {
18291837 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
@@ -1833,7 +1841,7 @@ yyreduce: · 3 unmodified lines
18331841 ;}
18341842 break;
18351843
1836− case 65:
1844+ case 67:
18371845
18381846 {
18391847 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
@@ -1843,7 +1851,14 @@ yyreduce: · 3 unmodified lines
18431851 ;}
18441852 break;
18451853
1846− case 71:
1854+ case 73:
1855+
1856+ {
1857+ menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
1858+;}
1859+ break;
1860+
1861+ case 74:
18471862
18481863 {
18491864 menu_add_entry(NULL);
@@ -1852,14 +1867,14 @@ yyreduce: · 2 unmodified lines
18521867 ;}
18531868 break;
18541869
1855− case 72:
1870+ case 75:
18561871
18571872 {
18581873 (yyval.menu) = menu_add_menu();
18591874 ;}
18601875 break;
18611876
1862− case 73:
1877+ case 76:
18631878
18641879 {
18651880 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
@@ -1869,7 +1884,7 @@ yyreduce: · 3 unmodified lines
18691884 ;}
18701885 break;
18711886
1872− case 79:
1887+ case 82:
18731888
18741889 {
18751890 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
@@ -1877,7 +1892,7 @@ yyreduce: · 1 unmodified line
18771892 ;}
18781893 break;
18791894
1880− case 80:
1895+ case 83:
18811896
18821897 {
18831898 menu_add_entry(NULL);
@@ -1886,14 +1901,14 @@ yyreduce: · 2 unmodified lines
18861901 ;}
18871902 break;
18881903
1889− case 81:
1904+ case 84:
18901905
18911906 {
18921907 menu_end_entry();
18931908 ;}
18941909 break;
18951910
1896− case 82:
1911+ case 85:
18971912
18981913 {
18991914 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1901,14 +1916,14 @@ yyreduce: · 1 unmodified line
19011916 ;}
19021917 break;
19031918
1904− case 83:
1919+ case 86:
19051920
19061921 {
19071922 current_entry->help = (yyvsp[(2) - (2)].string);
19081923 ;}
19091924 break;
19101925
1911− case 88:
1926+ case 91:
19121927
19131928 {
19141929 menu_add_dep((yyvsp[(3) - (4)].expr));
@@ -1916,84 +1931,84 @@ yyreduce: · 1 unmodified line
19161931 ;}
19171932 break;
19181933
1919− case 90:
1934+ case 93:
19201935
19211936 {
19221937 menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
19231938 ;}
19241939 break;
19251940
1926− case 93:
1941+ case 96:
19271942
19281943 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
19291944 break;
19301945
1931− case 94:
1946+ case 97:
19321947
19331948 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
19341949 break;
19351950
1936− case 95:
1951+ case 98:
19371952
19381953 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
19391954 break;
19401955
1941− case 98:
1956+ case 101:
19421957
19431958 { (yyval.expr) = NULL; ;}
19441959 break;
19451960
1946− case 99:
1961+ case 102:
19471962
19481963 { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
19491964 break;
19501965
1951− case 100:
1966+ case 103:
19521967
19531968 { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
19541969 break;
19551970
1956− case 101:
1971+ case 104:
19571972
19581973 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
19591974 break;
19601975
1961− case 102:
1976+ case 105:
19621977
19631978 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
19641979 break;
19651980
1966− case 103:
1981+ case 106:
19671982
19681983 { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
19691984 break;
19701985
1971− case 104:
1986+ case 107:
19721987
19731988 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
19741989 break;
19751990
1976− case 105:
1991+ case 108:
19771992
19781993 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
19791994 break;
19801995
1981− case 106:
1996+ case 109:
19821997
19831998 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
19841999 break;
19852000
1986− case 107:
2001+ case 110:
19872002
19882003 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
19892004 break;
19902005
1991− case 108:
2006+ case 111:
19922007
19932008 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
19942009 break;
19952010
1996− case 109:
2011+ case 112:
19972012
19982013 { (yyval.string) = NULL; ;}
19992014 break;
@@ -2239,6 +2254,10 @@ void conf_parse(const char *name) · 239 unmodified lines
22392254 prop = prop_alloc(P_DEFAULT, modules_sym);
22402255 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
22412256 }
2257+
2258+ rootmenu.prompt->text = _(rootmenu.prompt->text);
2259+ rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
2260+
22422261 menu_finalize(&rootmenu);
22432262 for_all_symbols(i, sym) {
22442263 if (sym_check_deps(sym))
scripts/kconfig/zconf.y+15−3
@@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry; · 35 unmodified lines
3636 #define YYERROR_VERBOSE
3737 #endif
3838 %}
39−%expect 26
39+%expect 28
4040
4141 %union
4242 {
@@ -104,14 +104,15 @@ static struct menu *current_menu, *current_entry; · 61 unmodified lines
104104 %}
105105
106106 %%
107−input: stmt_list;
107+input: nl start | start;
108+
109+start: mainmenu_stmt stmt_list | stmt_list;
108110
109111 stmt_list:
110112 /* empty */
111113 | stmt_list common_stmt
112114 | stmt_list choice_stmt
113115 | stmt_list menu_stmt
114− | stmt_list T_MAINMENU prompt nl
115116 | stmt_list end { zconf_error("unexpected end statement"); }
116117 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
117118 | stmt_list option_name error T_EOL
@@ -342,6 +343,13 @@ if_block: · 224 unmodified lines
342343 | if_block choice_stmt
343344 ;
344345
346+/* mainmenu entry */
347+
348+mainmenu_stmt: T_MAINMENU prompt nl
349+{
350+ menu_add_prompt(P_MENU, $2, NULL);
351+};
352+
345353 /* menu entry */
346354
347355 menu: T_MENU prompt T_EOL
@@ -494,6 +502,10 @@ void conf_parse(const char *name) · 146 unmodified lines
494502 prop = prop_alloc(P_DEFAULT, modules_sym);
495503 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
496504 }
505+
506+ rootmenu.prompt->text = _(rootmenu.prompt->text);
507+ rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
508+
497509 menu_finalize(&rootmenu);
498510 for_all_symbols(i, sym) {
499511 if (sym_check_deps(sym))
scripts/kernel-doc+53−3
@@ -44,12 +44,13 @@ use strict; · 43 unmodified lines
4444 # Note: This only supports 'c'.
4545
4646 # usage:
47−# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ]
47+# kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ]
4848 # [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
4949 # or
5050 # [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
5151 #
5252 # Set output format using one of -docbook -html -text or -man. Default is man.
53+# The -list format is for internal use by docproc.
5354 #
5455 # -no-doc-sections
5556 # Do not output DOC: sections
@@ -210,9 +211,16 @@ my %highlights_text = ( $type_constant, "\$1", · 154 unmodified lines
210211 $type_param, "\$1" );
211212 my $blankline_text = "";
212213
214+# list mode
215+my %highlights_list = ( $type_constant, "\$1",
216+ $type_func, "\$1",
217+ $type_struct, "\$1",
218+ $type_param, "\$1" );
219+my $blankline_list = "";
213220
214221 sub usage {
215− print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n";
222+ print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n";
223+ print " [ -no-doc-sections ]\n";
216224 print " [ -function funcname [ -function funcname ...] ]\n";
217225 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
218226 print " c source file(s) > outputfile\n";
@@ -318,6 +326,10 @@ while ($ARGV[0] =~ m/^-(.*)/) { · 99 unmodified lines
318326 $output_mode = "xml";
319327 %highlights = %highlights_xml;
320328 $blankline = $blankline_xml;
329+ } elsif ($cmd eq "-list") {
330+ $output_mode = "list";
331+ %highlights = %highlights_list;
332+ $blankline = $blankline_list;
321333 } elsif ($cmd eq "-gnome") {
322334 $output_mode = "gnome";
323335 %highlights = %highlights_gnome;
@@ -1361,6 +1373,42 @@ sub output_blockhead_text(%) { · 1037 unmodified lines
13611373 }
13621374 }
13631375
1376+## list mode output functions
1377+
1378+sub output_function_list(%) {
1379+ my %args = %{$_[0]};
1380+
1381+ print $args{'function'} . "\n";
1382+}
1383+
1384+# output enum in list
1385+sub output_enum_list(%) {
1386+ my %args = %{$_[0]};
1387+ print $args{'enum'} . "\n";
1388+}
1389+
1390+# output typedef in list
1391+sub output_typedef_list(%) {
1392+ my %args = %{$_[0]};
1393+ print $args{'typedef'} . "\n";
1394+}
1395+
1396+# output struct as list
1397+sub output_struct_list(%) {
1398+ my %args = %{$_[0]};
1399+
1400+ print $args{'struct'} . "\n";
1401+}
1402+
1403+sub output_blockhead_list(%) {
1404+ my %args = %{$_[0]};
1405+ my ($parameter, $section);
1406+
1407+ foreach $section (@{$args{'sectionlist'}}) {
1408+ print "DOC: $section\n";
1409+ }
1410+}
1411+
13641412 ##
13651413 # generic output function for all types (function, struct/union, typedef, enum);
13661414 # calls the generated, variable output_ function name based on
@@ -1454,6 +1502,8 @@ sub dump_enum($$) { · 87 unmodified lines
14541502 my $file = shift;
14551503
14561504 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1505+ $x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums
1506+
14571507 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
14581508 $declaration_name = $1;
14591509 my $members = $2;
@@ -1677,7 +1727,7 @@ sub check_sections($$$$$$) { · 217 unmodified lines
16771727 foreach $px (0 .. $#prms) {
16781728 $prm_clean = $prms[$px];
16791729 $prm_clean =~ s/\[.*\]//;
1680− $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//;
1730+ $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
16811731 # ignore array size in a parameter string;
16821732 # however, the original param string may contain
16831733 # spaces, e.g.: addr[6 + 2]
scripts/mkmakefile+3−1
@@ -44,7 +44,9 @@ all: · 43 unmodified lines
4444
4545 Makefile:;
4646
47−\$(all) %/: all
47+\$(all): all
4848 @:
4949
50+%/: all
51+ @:
5052 EOF
scripts/mod/modpost.c+57−16
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #define _GNU_SOURCE
1515 #include <stdio.h>
1616 #include <ctype.h>
17+#include <string.h>
1718 #include "modpost.h"
1819 #include "../../include/generated/autoconf.h"
1920 #include "../../include/linux/license.h"
@@ -789,6 +790,7 @@ static const char *section_white_list[] = · 769 unmodified lines
789790 {
790791 ".comment*",
791792 ".debug*",
793+ ".GCC-command-line", /* mn10300 */
792794 ".mdebug*", /* alpha, score, mips etc. */
793795 ".pdr", /* alpha, score, mips etc. */
794796 ".stab*",
@@ -1033,6 +1035,13 @@ static const struct sectioncheck *section_mismatch( · 238 unmodified lines
10331035 * fromsec = .data*
10341036 * atsym =__param*
10351037 *
1038+ * Pattern 1a:
1039+ * module_param_call() ops can refer to __init set function if permissions=0
1040+ * The pattern is identified by:
1041+ * tosec = .init.text
1042+ * fromsec = .data*
1043+ * atsym = __param_ops_*
1044+ *
10361045 * Pattern 2:
10371046 * Many drivers utilise a *driver container with references to
10381047 * add, remove, probe functions etc.
@@ -1067,6 +1076,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch, · 28 unmodified lines
10671076 (strncmp(fromsym, "__param", strlen("__param")) == 0))
10681077 return 0;
10691078
1079+ /* Check for pattern 1a */
1080+ if (strcmp(tosec, ".init.text") == 0 &&
1081+ match(fromsec, data_sections) &&
1082+ (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0))
1083+ return 0;
1084+
10701085 /* Check for pattern 2 */
10711086 if (match(tosec, init_exit_sections) &&
10721087 match(fromsec, data_sections) &&
@@ -1220,7 +1235,7 @@ static char *sec2annotation(const char *s) · 147 unmodified lines
12201235 strcat(p, " ");
12211236 return r;
12221237 } else {
1223− return "";
1238+ return strdup("");
12241239 }
12251240 }
12261241
@@ -1248,6 +1263,8 @@ static void report_sec_mismatch(const char *modname, · 21 unmodified lines
12481263 {
12491264 const char *from, *from_p;
12501265 const char *to, *to_p;
1266+ char *prl_from;
1267+ char *prl_to;
12511268
12521269 switch (from_is_func) {
12531270 case 0: from = "variable"; from_p = ""; break;
@@ -1271,16 +1288,21 @@ static void report_sec_mismatch(const char *modname, · 17 unmodified lines
12711288
12721289 switch (mismatch->mismatch) {
12731290 case TEXT_TO_ANY_INIT:
1291+ prl_from = sec2annotation(fromsec);
1292+ prl_to = sec2annotation(tosec);
12741293 fprintf(stderr,
12751294 "The function %s%s() references\n"
12761295 "the %s %s%s%s.\n"
12771296 "This is often because %s lacks a %s\n"
12781297 "annotation or the annotation of %s is wrong.\n",
1279− sec2annotation(fromsec), fromsym,
1280− to, sec2annotation(tosec), tosym, to_p,
1281− fromsym, sec2annotation(tosec), tosym);
1298+ prl_from, fromsym,
1299+ to, prl_to, tosym, to_p,
1300+ fromsym, prl_to, tosym);
1301+ free(prl_from);
1302+ free(prl_to);
12821303 break;
12831304 case DATA_TO_ANY_INIT: {
1305+ prl_to = sec2annotation(tosec);
12841306 const char *const *s = mismatch->symbol_white_list;
12851307 fprintf(stderr,
12861308 "The variable %s references\n"
@@ -1288,20 +1310,24 @@ static void report_sec_mismatch(const char *modname, · 1 unmodified line
12881310 "If the reference is valid then annotate the\n"
12891311 "variable with __init* or __refdata (see linux/init.h) "
12901312 "or name the variable:\n",
1291− fromsym, to, sec2annotation(tosec), tosym, to_p);
1313+ fromsym, to, prl_to, tosym, to_p);
12921314 while (*s)
12931315 fprintf(stderr, "%s, ", *s++);
12941316 fprintf(stderr, "\n");
1317+ free(prl_to);
12951318 break;
12961319 }
12971320 case TEXT_TO_ANY_EXIT:
1321+ prl_to = sec2annotation(tosec);
12981322 fprintf(stderr,
12991323 "The function %s() references a %s in an exit section.\n"
13001324 "Often the %s %s%s has valid usage outside the exit section\n"
13011325 "and the fix is to remove the %sannotation of %s.\n",
1302− fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
1326+ fromsym, to, to, tosym, to_p, prl_to, tosym);
1327+ free(prl_to);
13031328 break;
13041329 case DATA_TO_ANY_EXIT: {
1330+ prl_to = sec2annotation(tosec);
13051331 const char *const *s = mismatch->symbol_white_list;
13061332 fprintf(stderr,
13071333 "The variable %s references\n"
@@ -1309,24 +1335,31 @@ static void report_sec_mismatch(const char *modname, · 1 unmodified line
13091335 "If the reference is valid then annotate the\n"
13101336 "variable with __exit* (see linux/init.h) or "
13111337 "name the variable:\n",
1312− fromsym, to, sec2annotation(tosec), tosym, to_p);
1338+ fromsym, to, prl_to, tosym, to_p);
13131339 while (*s)
13141340 fprintf(stderr, "%s, ", *s++);
13151341 fprintf(stderr, "\n");
1342+ free(prl_to);
13161343 break;
13171344 }
13181345 case XXXINIT_TO_SOME_INIT:
13191346 case XXXEXIT_TO_SOME_EXIT:
1347+ prl_from = sec2annotation(fromsec);
1348+ prl_to = sec2annotation(tosec);
13201349 fprintf(stderr,
13211350 "The %s %s%s%s references\n"
13221351 "a %s %s%s%s.\n"
13231352 "If %s is only used by %s then\n"
13241353 "annotate %s with a matching annotation.\n",
1325− from, sec2annotation(fromsec), fromsym, from_p,
1326− to, sec2annotation(tosec), tosym, to_p,
1354+ from, prl_from, fromsym, from_p,
1355+ to, prl_to, tosym, to_p,
13271356 tosym, fromsym, tosym);
1357+ free(prl_from);
1358+ free(prl_to);
13281359 break;
13291360 case ANY_INIT_TO_ANY_EXIT:
1361+ prl_from = sec2annotation(fromsec);
1362+ prl_to = sec2annotation(tosec);
13301363 fprintf(stderr,
13311364 "The %s %s%s%s references\n"
13321365 "a %s %s%s%s.\n"
@@ -1335,11 +1368,15 @@ static void report_sec_mismatch(const char *modname, · 2 unmodified lines
13351368 "uses functionality in the exit path.\n"
13361369 "The fix is often to remove the %sannotation of\n"
13371370 "%s%s so it may be used outside an exit section.\n",
1338− from, sec2annotation(fromsec), fromsym, from_p,
1339− to, sec2annotation(tosec), tosym, to_p,
1340− sec2annotation(tosec), tosym, to_p);
1371+ from, prl_from, fromsym, from_p,
1372+ to, prl_to, tosym, to_p,
1373+ prl_to, tosym, to_p);
1374+ free(prl_from);
1375+ free(prl_to);
13411376 break;
13421377 case ANY_EXIT_TO_ANY_INIT:
1378+ prl_from = sec2annotation(fromsec);
1379+ prl_to = sec2annotation(tosec);
13431380 fprintf(stderr,
13441381 "The %s %s%s%s references\n"
13451382 "a %s %s%s%s.\n"
@@ -1348,16 +1385,20 @@ static void report_sec_mismatch(const char *modname, · 2 unmodified lines
13481385 "uses functionality in the init path.\n"
13491386 "The fix is often to remove the %sannotation of\n"
13501387 "%s%s so it may be used outside an init section.\n",
1351− from, sec2annotation(fromsec), fromsym, from_p,
1352− to, sec2annotation(tosec), tosym, to_p,
1353− sec2annotation(tosec), tosym, to_p);
1388+ from, prl_from, fromsym, from_p,
1389+ to, prl_to, tosym, to_p,
1390+ prl_to, tosym, to_p);
1391+ free(prl_from);
1392+ free(prl_to);
13541393 break;
13551394 case EXPORT_TO_INIT_EXIT:
1395+ prl_to = sec2annotation(tosec);
13561396 fprintf(stderr,
13571397 "The symbol %s is exported and annotated %s\n"
13581398 "Fix this by removing the %sannotation of %s "
13591399 "or drop the export.\n",
1360− tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
1400+ tosym, prl_to, prl_to, tosym);
1401+ free(prl_to);
13611402 break;
13621403 }
13631404 fprintf(stderr, "\n");
scripts/namespace.pl+81−66
@@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_ · 83 unmodified lines
8484 my %ref = (); # $ref{$name} exists if there is a true external reference to $name
8585 my %export = (); # $export{$name} exists if there is an EXPORT_... of $name
8686
87+my %nmexception = (
88+ 'fs/ext3/bitmap' => 1,
89+ 'fs/ext4/bitmap' => 1,
90+ 'arch/x86/lib/thunk_32' => 1,
91+ 'arch/x86/lib/cmpxchg' => 1,
92+ 'arch/x86/vdso/vdso32/note' => 1,
93+ 'lib/irq_regs' => 1,
94+ 'usr/initramfs_data' => 1,
95+ 'drivers/scsi/aic94xx/aic94xx_dump' => 1,
96+ 'drivers/scsi/libsas/sas_dump' => 1,
97+ 'lib/dec_and_lock' => 1,
98+ 'drivers/ide/ide-probe-mini' => 1,
99+ 'usr/initramfs_data' => 1,
100+ 'drivers/acpi/acpia/exdump' => 1,
101+ 'drivers/acpi/acpia/rsdump' => 1,
102+ 'drivers/acpi/acpia/nsdumpdv' => 1,
103+ 'drivers/acpi/acpia/nsdump' => 1,
104+ 'arch/ia64/sn/kernel/sn2/io' => 1,
105+ 'arch/ia64/kernel/gate-data' => 1,
106+ 'security/capability' => 1,
107+ 'fs/ntfs/sysctl' => 1,
108+ 'fs/jfs/jfs_debug' => 1,
109+);
110+
111+my %nameexception = (
112+ 'mod_use_count_' => 1,
113+ '__initramfs_end' => 1,
114+ '__initramfs_start' => 1,
115+ '_einittext' => 1,
116+ '_sinittext' => 1,
117+ 'kallsyms_names' => 1,
118+ 'kallsyms_num_syms' => 1,
119+ 'kallsyms_addresses'=> 1,
120+ '__this_module' => 1,
121+ '_etext' => 1,
122+ '_edata' => 1,
123+ '_end' => 1,
124+ '__bss_start' => 1,
125+ '_text' => 1,
126+ '_stext' => 1,
127+ '__gp' => 1,
128+ 'ia64_unw_start' => 1,
129+ 'ia64_unw_end' => 1,
130+ '__init_begin' => 1,
131+ '__init_end' => 1,
132+ '__bss_stop' => 1,
133+ '__nosave_begin' => 1,
134+ '__nosave_end' => 1,
135+ 'pg0' => 1,
136+ 'vdso_enabled' => 1,
137+ '__stack_chk_fail' => 1,
138+ 'VDSO32_PRELINK' => 1,
139+ 'VDSO32_vsyscall' => 1,
140+ 'VDSO32_rt_sigreturn'=>1,
141+ 'VDSO32_sigreturn' => 1,
142+);
143+
144+
87145 &find(\&linux_objects, '.'); # find the objects and do_nm on them
88146 &list_multiply_defined();
89147 &resolve_external_references();
@@ -105,7 +163,8 @@ sub linux_objects · 15 unmodified lines
105163 if (/.*\.o$/ &&
106164 ! (
107165 m:/built-in.o$:
108− || m:arch/x86/kernel/vsyscall-syms.o$:
166+ || m:arch/x86/vdso/:
167+ || m:arch/x86/boot/:
109168 || m:arch/ia64/ia32/ia32.o$:
110169 || m:arch/ia64/kernel/gate-syms.o$:
111170 || m:arch/ia64/lib/__divdi3.o$:
@@ -148,6 +207,7 @@ sub linux_objects · 36 unmodified lines
148207 || m:^.*/\.tmp_:
149208 || m:^\.tmp_:
150209 || m:/vmlinux-obj.o$:
210+ || m:^tools/:
151211 )
152212 ) {
153213 do_nm($basename, $_);
@@ -167,11 +227,11 @@ sub do_nm · 13 unmodified lines
167227 printf STDERR "$fullname is not an object file\n";
168228 return;
169229 }
170− ($source = $fullname) =~ s/\.o$//;
171− if (-e "$objtree$source.c" || -e "$objtree$source.S") {
172− $source = "$objtree$source";
230+ ($source = $basename) =~ s/\.o$//;
231+ if (-e "$source.c" || -e "$source.S") {
232+ $source = "$objtree$File::Find::dir/$source";
173233 } else {
174− $source = "$srctree$source";
234+ $source = "$srctree$File::Find::dir/$source";
175235 }
176236 if (! -e "$source.c" && ! -e "$source.S") {
177237 # No obvious source, exclude the object if it is conglomerate
@@ -214,6 +274,7 @@ sub do_nm · 36 unmodified lines
214274 # T global label/procedure
215275 # U external reference
216276 # W weak external reference to text that has been resolved
277+ # V similar to W, but the value of the weak symbol becomes zero with no error.
217278 # a assembler equate
218279 # b static variable, uninitialised
219280 # d static variable, initialised
@@ -222,8 +283,9 @@ sub do_nm · 2 unmodified lines
222283 # s static variable, uninitialised, small bss
223284 # t static label/procedures
224285 # w weak external reference to text that has not been resolved
286+ # v similar to w
225287 # ? undefined type, used a lot by modules
226− if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) {
288+ if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) {
227289 printf STDERR "nm output for $fullname contains unknown type '$_'\n";
228290 }
229291 elsif ($name =~ /\./) {
@@ -234,7 +296,7 @@ sub do_nm · 4 unmodified lines
234296 # binutils keeps changing the type for exported symbols, force it to R
235297 $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
236298 $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this
237− if ($type =~ /[ABCDGRSTW]/ &&
299+ if ($type =~ /[ABCDGRSTWV]/ &&
238300 $name ne 'init_module' &&
239301 $name ne 'cleanup_module' &&
240302 $name ne 'Using_Versions' &&
@@ -270,27 +332,9 @@ sub do_nm · 29 unmodified lines
270332 close($nmdata);
271333
272334 if ($#nmdata < 0) {
273− if (
274− $fullname ne "lib/brlock.o"
275− && $fullname ne "lib/dec_and_lock.o"
276− && $fullname ne "fs/xfs/xfs_macros.o"
277− && $fullname ne "drivers/ide/ide-probe-mini.o"
278− && $fullname ne "usr/initramfs_data.o"
279− && $fullname ne "drivers/acpi/executer/exdump.o"
280− && $fullname ne "drivers/acpi/resources/rsdump.o"
281− && $fullname ne "drivers/acpi/namespace/nsdumpdv.o"
282− && $fullname ne "drivers/acpi/namespace/nsdump.o"
283− && $fullname ne "arch/ia64/sn/kernel/sn2/io.o"
284− && $fullname ne "arch/ia64/kernel/gate-data.o"
285− && $fullname ne "drivers/ieee1394/oui.o"
286− && $fullname ne "security/capability.o"
287− && $fullname ne "sound/core/wrappers.o"
288− && $fullname ne "fs/ntfs/sysctl.o"
289− && $fullname ne "fs/jfs/jfs_debug.o"
290− ) {
291− printf "No nm data for $fullname\n";
292− }
293− return;
335+ printf "No nm data for $fullname\n"
336+ unless $nmexception{$fullname};
337+ return;
294338 }
295339 $nmdata{$fullname} = \@nmdata;
296340 }
@@ -319,18 +363,14 @@ sub list_multiply_defined · 22 unmodified lines
319363 foreach my $name (keys(%def)) {
320364 if ($#{$def{$name}} > 0) {
321365 # Special case for cond_syscall
322− if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
323− ($def{$name}[0] eq "kernel/sys.o" ||
324− $def{$name}[1] eq "kernel/sys.o")) {
325− &drop_def("kernel/sys.o", $name);
326− next;
327− }
328− # Special case for i386 entry code
329− if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ &&
330− $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" &&
331− $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") {
332− &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
333− next;
366+ if ($#{$def{$name}} == 1 &&
367+ ($name =~ /^sys_/ || $name =~ /^compat_sys_/ ||
368+ $name =~ /^sys32_/)) {
369+ if($def{$name}[0] eq "kernel/sys_ni.o" ||
370+ $def{$name}[1] eq "kernel/sys_ni.o") {
371+ &drop_def("kernel/sys_ni.o", $name);
372+ next;
373+ }
334374 }
335375
336376 printf "$name is multiply defined in :-\n";
@@ -372,31 +412,7 @@ sub resolve_external_references · 35 unmodified lines
372412 $ref{$name} = ""
373413 }
374414 }
375− elsif ( $name ne "mod_use_count_"
376− && $name ne "__initramfs_end"
377− && $name ne "__initramfs_start"
378− && $name ne "_einittext"
379− && $name ne "_sinittext"
380− && $name ne "kallsyms_names"
381− && $name ne "kallsyms_num_syms"
382− && $name ne "kallsyms_addresses"
383− && $name ne "__this_module"
384− && $name ne "_etext"
385− && $name ne "_edata"
386− && $name ne "_end"
387− && $name ne "__bss_start"
388− && $name ne "_text"
389− && $name ne "_stext"
390− && $name ne "__gp"
391− && $name ne "ia64_unw_start"
392− && $name ne "ia64_unw_end"
393− && $name ne "__init_begin"
394− && $name ne "__init_end"
395− && $name ne "__bss_stop"
396− && $name ne "__nosave_begin"
397− && $name ne "__nosave_end"
398− && $name ne "pg0"
399− && $name ne "__module_text_address"
415+ elsif ( ! $nameexception{$name}
400416 && $name !~ /^__sched_text_/
401417 && $name !~ /^__start_/
402418 && $name !~ /^__end_/
@@ -407,7 +423,6 @@ sub resolve_external_references · 4 unmodified lines
407423 && $name !~ /^__.*per_cpu_end/
408424 && $name !~ /^__alt_instructions/
409425 && $name !~ /^__setup_/
410− && $name !~ /^jiffies/
411426 && $name !~ /^__mod_timer/
412427 && $name !~ /^__mod_page_state/
413428 && $name !~ /^init_module/
scripts/package/Makefile+31−6
@@ -111,13 +111,38 @@ tar%pkg: FORCE · 110 unmodified lines
111111 clean-dirs += $(objtree)/tar-install/
112112
113113
114+# perf-pkg - generate a source tarball with perf source
115+# ---------------------------------------------------------------------------
116+
117+perf-tar=perf-$(KERNELVERSION)
118+
119+quiet_cmd_perf_tar = TAR
120+ cmd_perf_tar = \
121+git archive --prefix=$(perf-tar)/ HEAD^{tree} \
122+ $$(cat $(srctree)/tools/perf/MANIFEST) -o $(perf-tar).tar; \
123+mkdir -p $(perf-tar); \
124+git rev-parse HEAD > $(perf-tar)/HEAD; \
125+tar rf $(perf-tar).tar $(perf-tar)/HEAD; \
126+rm -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+
133+perf-%pkg: FORCE
134+ $(call cmd,perf_tar)
135+
114136 # Help text displayed when executing 'make help'
115137 # ---------------------------------------------------------------------------
116138 help: FORCE
117− @echo ' rpm-pkg - Build both source and binary RPM kernel packages'
118− @echo ' binrpm-pkg - Build only the binary kernel package'
119− @echo ' deb-pkg - Build the kernel as an deb package'
120− @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
121− @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
122− @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball'
139+ @echo ' rpm-pkg - Build both source and binary RPM kernel packages'
140+ @echo ' binrpm-pkg - Build only the binary kernel package'
141+ @echo ' deb-pkg - Build the kernel as an deb package'
142+ @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
143+ @echo ' targz-pkg - Build the kernel as a gzip 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'
123148
scripts/package/builddeb+6−3
@@ -66,7 +66,9 @@ else · 65 unmodified lines
6666 cp System.map "$tmpdir/boot/System.map-$version"
6767 cp .config "$tmpdir/boot/config-$version"
6868 # Not all arches include the boot path in KBUILD_IMAGE
69− if ! cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"; then
69+ if [ -e $KBUILD_IMAGE ]; then
70+ cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
71+ else
7072 cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
7173 fi
7274 fi
@@ -148,10 +150,11 @@ EOF · 75 unmodified lines
148150 # Generate a control file
149151 cat <<EOF > debian/control
150152 Source: linux-upstream
151−Section: admin
153+Section: kernel
152154 Priority: optional
153155 Maintainer: $maintainer
154−Standards-Version: 3.8.1
156+Standards-Version: 3.8.4
157+Homepage: http://www.kernel.org/
155158 EOF
156159
157160 if [ "$ARCH" = "um" ]; then
scripts/package/mkspec+1−1
@@ -70,7 +70,7 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules' · 69 unmodified lines
7070 echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
7171 echo "%endif"
7272
73−echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} KBUILD_SRC= modules_install'
73+echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install'
7474 echo "%ifarch ia64"
7575 echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
7676 echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
scripts/recordmcount.c+407−0
@@ -0,0 +1,407 @@
1+/*
2+ * recordmcount.c: construct a table of the locations of calls to 'mcount'
3+ * so that ftrace can find them quickly.
4+ * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
5+ * Licensed under the GNU General Public License, version 2 (GPLv2).
6+ *
7+ * Restructured to fit Linux format, as well as other updates:
8+ * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
9+ */
10+
11+/*
12+ * Strategy: alter the .o file in-place.
13+ *
14+ * Append a new STRTAB that has the new section names, followed by a new array
15+ * ElfXX_Shdr[] that has the new section headers, followed by the section
16+ * contents for __mcount_loc and its relocations. The old shstrtab strings,
17+ * and the old ElfXX_Shdr[] array, remain as "garbage" (commonly, a couple
18+ * kilobytes.) Subsequent processing by /bin/ld (or the kernel module loader)
19+ * will ignore the garbage regions, because they are not designated by the
20+ * new .e_shoff nor the new ElfXX_Shdr[]. [In order to remove the garbage,
21+ * then use "ld -r" to create a new file that omits the garbage.]
22+ */
23+
24+#include <sys/types.h>
25+#include <sys/mman.h>
26+#include <sys/stat.h>
27+#include <elf.h>
28+#include <fcntl.h>
29+#include <setjmp.h>
30+#include <stdio.h>
31+#include <stdlib.h>
32+#include <string.h>
33+#include <unistd.h>
34+
35+static int fd_map; /* File descriptor for file being modified. */
36+static int mmap_failed; /* Boolean flag. */
37+static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
38+static char gpfx; /* prefix for global symbol name (sometimes '_') */
39+static struct stat sb; /* Remember .st_size, etc. */
40+static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
41+
42+/* setjmp() return values */
43+enum {
44+ SJ_SETJMP = 0, /* hardwired first return */
45+ SJ_FAIL,
46+ SJ_SUCCEED
47+};
48+
49+/* Per-file resource cleanup when multiple files. */
50+static void
51+cleanup(void)
52+{
53+ if (!mmap_failed)
54+ munmap(ehdr_curr, sb.st_size);
55+ else
56+ free(ehdr_curr);
57+ close(fd_map);
58+}
59+
60+static void __attribute__((noreturn))
61+fail_file(void)
62+{
63+ cleanup();
64+ longjmp(jmpenv, SJ_FAIL);
65+}
66+
67+static void __attribute__((noreturn))
68+succeed_file(void)
69+{
70+ cleanup();
71+ longjmp(jmpenv, SJ_SUCCEED);
72+}
73+
74+/* ulseek, uread, ...: Check return value for errors. */
75+
76+static off_t
77+ulseek(int const fd, off_t const offset, int const whence)
78+{
79+ off_t const w = lseek(fd, offset, whence);
80+ if ((off_t)-1 == w) {
81+ perror("lseek");
82+ fail_file();
83+ }
84+ return w;
85+}
86+
87+static size_t
88+uread(int const fd, void *const buf, size_t const count)
89+{
90+ size_t const n = read(fd, buf, count);
91+ if (n != count) {
92+ perror("read");
93+ fail_file();
94+ }
95+ return n;
96+}
97+
98+static size_t
99+uwrite(int const fd, void const *const buf, size_t const count)
100+{
101+ size_t const n = write(fd, buf, count);
102+ if (n != count) {
103+ perror("write");
104+ fail_file();
105+ }
106+ return n;
107+}
108+
109+static void *
110+umalloc(size_t size)
111+{
112+ void *const addr = malloc(size);
113+ if (0 == addr) {
114+ fprintf(stderr, "malloc failed: %zu bytes\n", size);
115+ fail_file();
116+ }
117+ return addr;
118+}
119+
120+/*
121+ * Get the whole file as a programming convenience in order to avoid
122+ * malloc+lseek+read+free of many pieces. If successful, then mmap
123+ * avoids copying unused pieces; else just read the whole file.
124+ * Open for both read and write; new info will be appended to the file.
125+ * Use MAP_PRIVATE so that a few changes to the in-memory ElfXX_Ehdr
126+ * do not propagate to the file until an explicit overwrite at the last.
127+ * This preserves most aspects of consistency (all except .st_size)
128+ * for simultaneous readers of the file while we are appending to it.
129+ * However, multiple writers still are bad. We choose not to use
130+ * locking because it is expensive and the use case of kernel build
131+ * makes multiple writers unlikely.
132+ */
133+static void *mmap_file(char const *fname)
134+{
135+ void *addr;
136+
137+ fd_map = open(fname, O_RDWR);
138+ if (0 > fd_map || 0 > fstat(fd_map, &sb)) {
139+ perror(fname);
140+ fail_file();
141+ }
142+ if (!S_ISREG(sb.st_mode)) {
143+ fprintf(stderr, "not a regular file: %s\n", fname);
144+ fail_file();
145+ }
146+ addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
147+ fd_map, 0);
148+ mmap_failed = 0;
149+ if (MAP_FAILED == addr) {
150+ mmap_failed = 1;
151+ addr = umalloc(sb.st_size);
152+ uread(fd_map, addr, sb.st_size);
153+ }
154+ return addr;
155+}
156+
157+/* w8rev, w8nat, ...: Handle endianness. */
158+
159+static uint64_t w8rev(uint64_t const x)
160+{
161+ return ((0xff & (x >> (0 * 8))) << (7 * 8))
162+ | ((0xff & (x >> (1 * 8))) << (6 * 8))
163+ | ((0xff & (x >> (2 * 8))) << (5 * 8))
164+ | ((0xff & (x >> (3 * 8))) << (4 * 8))
165+ | ((0xff & (x >> (4 * 8))) << (3 * 8))
166+ | ((0xff & (x >> (5 * 8))) << (2 * 8))
167+ | ((0xff & (x >> (6 * 8))) << (1 * 8))
168+ | ((0xff & (x >> (7 * 8))) << (0 * 8));
169+}
170+
171+static uint32_t w4rev(uint32_t const x)
172+{
173+ return ((0xff & (x >> (0 * 8))) << (3 * 8))
174+ | ((0xff & (x >> (1 * 8))) << (2 * 8))
175+ | ((0xff & (x >> (2 * 8))) << (1 * 8))
176+ | ((0xff & (x >> (3 * 8))) << (0 * 8));
177+}
178+
179+static uint32_t w2rev(uint16_t const x)
180+{
181+ return ((0xff & (x >> (0 * 8))) << (1 * 8))
182+ | ((0xff & (x >> (1 * 8))) << (0 * 8));
183+}
184+
185+static uint64_t w8nat(uint64_t const x)
186+{
187+ return x;
188+}
189+
190+static uint32_t w4nat(uint32_t const x)
191+{
192+ return x;
193+}
194+
195+static uint32_t w2nat(uint16_t const x)
196+{
197+ return x;
198+}
199+
200+static uint64_t (*w8)(uint64_t);
201+static uint32_t (*w)(uint32_t);
202+static uint32_t (*w2)(uint16_t);
203+
204+/* Names of the sections that could contain calls to mcount. */
205+static int
206+is_mcounted_section_name(char const *const txtname)
207+{
208+ return 0 == strcmp(".text", txtname) ||
209+ 0 == strcmp(".sched.text", txtname) ||
210+ 0 == strcmp(".spinlock.text", txtname) ||
211+ 0 == strcmp(".irqentry.text", txtname) ||
212+ 0 == strcmp(".text.unlikely", txtname);
213+}
214+
215+/* 32 bit and 64 bit are very similar */
216+#include "recordmcount.h"
217+#define RECORD_MCOUNT_64
218+#include "recordmcount.h"
219+
220+/* 64-bit EM_MIPS has weird ELF64_Rela.r_info.
221+ * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
222+ * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40]
223+ * to imply the order of the members; the spec does not say so.
224+ * typedef unsigned char Elf64_Byte;
225+ * fails on MIPS64 because their <elf.h> already has it!
226+ */
227+
228+typedef uint8_t myElf64_Byte; /* Type for a 8-bit quantity. */
229+
230+union mips_r_info {
231+ Elf64_Xword r_info;
232+ struct {
233+ Elf64_Word r_sym; /* Symbol index. */
234+ myElf64_Byte r_ssym; /* Special symbol. */
235+ myElf64_Byte r_type3; /* Third relocation. */
236+ myElf64_Byte r_type2; /* Second relocation. */
237+ myElf64_Byte r_type; /* First relocation. */
238+ } r_mips;
239+};
240+
241+static uint64_t MIPS64_r_sym(Elf64_Rel const *rp)
242+{
243+ return w(((union mips_r_info){ .r_info = rp->r_info }).r_mips.r_sym);
244+}
245+
246+static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type)
247+{
248+ rp->r_info = ((union mips_r_info){
249+ .r_mips = { .r_sym = w(sym), .r_type = type }
250+ }).r_info;
251+}
252+
253+static void
254+do_file(char const *const fname)
255+{
256+ Elf32_Ehdr *const ehdr = mmap_file(fname);
257+ unsigned int reltype = 0;
258+
259+ ehdr_curr = ehdr;
260+ w = w4nat;
261+ w2 = w2nat;
262+ w8 = w8nat;
263+ switch (ehdr->e_ident[EI_DATA]) {
264+ static unsigned int const endian = 1;
265+ default: {
266+ fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
267+ ehdr->e_ident[EI_DATA], fname);
268+ fail_file();
269+ } break;
270+ case ELFDATA2LSB: {
271+ if (1 != *(unsigned char const *)&endian) {
272+ /* main() is big endian, file.o is little endian. */
273+ w = w4rev;
274+ w2 = w2rev;
275+ w8 = w8rev;
276+ }
277+ } break;
278+ case ELFDATA2MSB: {
279+ if (0 != *(unsigned char const *)&endian) {
280+ /* main() is little endian, file.o is big endian. */
281+ w = w4rev;
282+ w2 = w2rev;
283+ w8 = w8rev;
284+ }
285+ } break;
286+ } /* end switch */
287+ if (0 != memcmp(ELFMAG, ehdr->e_ident, SELFMAG)
288+ || ET_REL != w2(ehdr->e_type)
289+ || EV_CURRENT != ehdr->e_ident[EI_VERSION]) {
290+ fprintf(stderr, "unrecognized ET_REL file %s\n", fname);
291+ fail_file();
292+ }
293+
294+ gpfx = 0;
295+ switch (w2(ehdr->e_machine)) {
296+ default: {
297+ fprintf(stderr, "unrecognized e_machine %d %s\n",
298+ w2(ehdr->e_machine), fname);
299+ fail_file();
300+ } break;
301+ case EM_386: reltype = R_386_32; break;
302+ case EM_ARM: reltype = R_ARM_ABS32; break;
303+ case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
304+ case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break;
305+ case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break;
306+ case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break;
307+ case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
308+ case EM_SH: reltype = R_SH_DIR32; break;
309+ case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break;
310+ case EM_X86_64: reltype = R_X86_64_64; break;
311+ } /* end switch */
312+
313+ switch (ehdr->e_ident[EI_CLASS]) {
314+ default: {
315+ fprintf(stderr, "unrecognized ELF class %d %s\n",
316+ ehdr->e_ident[EI_CLASS], fname);
317+ fail_file();
318+ } break;
319+ case ELFCLASS32: {
320+ if (sizeof(Elf32_Ehdr) != w2(ehdr->e_ehsize)
321+ || sizeof(Elf32_Shdr) != w2(ehdr->e_shentsize)) {
322+ fprintf(stderr,
323+ "unrecognized ET_REL file: %s\n", fname);
324+ fail_file();
325+ }
326+ if (EM_S390 == w2(ehdr->e_machine))
327+ reltype = R_390_32;
328+ if (EM_MIPS == w2(ehdr->e_machine)) {
329+ reltype = R_MIPS_32;
330+ is_fake_mcount32 = MIPS32_is_fake_mcount;
331+ }
332+ do32(ehdr, fname, reltype);
333+ } break;
334+ case ELFCLASS64: {
335+ Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr;
336+ if (sizeof(Elf64_Ehdr) != w2(ghdr->e_ehsize)
337+ || sizeof(Elf64_Shdr) != w2(ghdr->e_shentsize)) {
338+ fprintf(stderr,
339+ "unrecognized ET_REL file: %s\n", fname);
340+ fail_file();
341+ }
342+ if (EM_S390 == w2(ghdr->e_machine))
343+ reltype = R_390_64;
344+ if (EM_MIPS == w2(ghdr->e_machine)) {
345+ reltype = R_MIPS_64;
346+ Elf64_r_sym = MIPS64_r_sym;
347+ Elf64_r_info = MIPS64_r_info;
348+ is_fake_mcount64 = MIPS64_is_fake_mcount;
349+ }
350+ do64(ghdr, fname, reltype);
351+ } break;
352+ } /* end switch */
353+
354+ cleanup();
355+}
356+
357+int
358+main(int argc, char const *argv[])
359+{
360+ const char ftrace[] = "kernel/trace/ftrace.o";
361+ int ftrace_size = sizeof(ftrace) - 1;
362+ int n_error = 0; /* gcc-4.3.0 false positive complaint */
363+
364+ if (argc <= 1) {
365+ fprintf(stderr, "usage: recordmcount file.o...\n");
366+ return 0;
367+ }
368+
369+ /* Process each file in turn, allowing deep failure. */
370+ for (--argc, ++argv; 0 < argc; --argc, ++argv) {
371+ int const sjval = setjmp(jmpenv);
372+ int len;
373+
374+ /*
375+ * The file kernel/trace/ftrace.o references the mcount
376+ * function but does not call it. Since ftrace.o should
377+ * not be traced anyway, we just skip it.
378+ */
379+ len = strlen(argv[0]);
380+ if (len >= ftrace_size &&
381+ strcmp(argv[0] + (len - ftrace_size), ftrace) == 0)
382+ continue;
383+
384+ switch (sjval) {
385+ default: {
386+ fprintf(stderr, "internal error: %s\n", argv[0]);
387+ exit(1);
388+ } break;
389+ case SJ_SETJMP: { /* normal sequence */
390+ /* Avoid problems if early cleanup() */
391+ fd_map = -1;
392+ ehdr_curr = NULL;
393+ mmap_failed = 1;
394+ do_file(argv[0]);
395+ } break;
396+ case SJ_FAIL: { /* error in do_file or below */
397+ ++n_error;
398+ } break;
399+ case SJ_SUCCEED: { /* premature success */
400+ /* do nothing */
401+ } break;
402+ } /* end switch */
403+ }
404+ return !!n_error;
405+}
406+
407+
scripts/recordmcount.h+442−0
@@ -0,0 +1,442 @@
1+/*
2+ * recordmcount.h
3+ *
4+ * This code was taken out of recordmcount.c written by
5+ * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
6+ *
7+ * The original code had the same algorithms for both 32bit
8+ * and 64bit ELF files, but the code was duplicated to support
9+ * the difference in structures that were used. This
10+ * file creates a macro of everything that is different between
11+ * the 64 and 32 bit code, such that by including this header
12+ * twice we can create both sets of functions by including this
13+ * header once with RECORD_MCOUNT_64 undefined, and again with
14+ * it defined.
15+ *
16+ * This conversion to macros was done by:
17+ * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
18+ *
19+ * Licensed under the GNU General Public License, version 2 (GPLv2).
20+ */
21+#undef append_func
22+#undef is_fake_mcount
23+#undef fn_is_fake_mcount
24+#undef MIPS_is_fake_mcount
25+#undef sift_rel_mcount
26+#undef find_secsym_ndx
27+#undef __has_rel_mcount
28+#undef has_rel_mcount
29+#undef tot_relsize
30+#undef do_func
31+#undef Elf_Addr
32+#undef Elf_Ehdr
33+#undef Elf_Shdr
34+#undef Elf_Rel
35+#undef Elf_Rela
36+#undef Elf_Sym
37+#undef ELF_R_SYM
38+#undef Elf_r_sym
39+#undef ELF_R_INFO
40+#undef Elf_r_info
41+#undef ELF_ST_BIND
42+#undef fn_ELF_R_SYM
43+#undef fn_ELF_R_INFO
44+#undef uint_t
45+#undef _w
46+#undef _align
47+#undef _size
48+
49+#ifdef RECORD_MCOUNT_64
50+# define append_func append64
51+# define sift_rel_mcount sift64_rel_mcount
52+# define find_secsym_ndx find64_secsym_ndx
53+# define __has_rel_mcount __has64_rel_mcount
54+# define has_rel_mcount has64_rel_mcount
55+# define tot_relsize tot64_relsize
56+# define do_func do64
57+# define is_fake_mcount is_fake_mcount64
58+# define fn_is_fake_mcount fn_is_fake_mcount64
59+# define MIPS_is_fake_mcount MIPS64_is_fake_mcount
60+# define Elf_Addr Elf64_Addr
61+# define Elf_Ehdr Elf64_Ehdr
62+# define Elf_Shdr Elf64_Shdr
63+# define Elf_Rel Elf64_Rel
64+# define Elf_Rela Elf64_Rela
65+# define Elf_Sym Elf64_Sym
66+# define ELF_R_SYM ELF64_R_SYM
67+# define Elf_r_sym Elf64_r_sym
68+# define ELF_R_INFO ELF64_R_INFO
69+# define Elf_r_info Elf64_r_info
70+# define ELF_ST_BIND ELF64_ST_BIND
71+# define fn_ELF_R_SYM fn_ELF64_R_SYM
72+# define fn_ELF_R_INFO fn_ELF64_R_INFO
73+# define uint_t uint64_t
74+# define _w w8
75+# define _align 7u
76+# define _size 8
77+#else
78+# define append_func append32
79+# define sift_rel_mcount sift32_rel_mcount
80+# define find_secsym_ndx find32_secsym_ndx
81+# define __has_rel_mcount __has32_rel_mcount
82+# define has_rel_mcount has32_rel_mcount
83+# define tot_relsize tot32_relsize
84+# define do_func do32
85+# define is_fake_mcount is_fake_mcount32
86+# define fn_is_fake_mcount fn_is_fake_mcount32
87+# define MIPS_is_fake_mcount MIPS32_is_fake_mcount
88+# define Elf_Addr Elf32_Addr
89+# define Elf_Ehdr Elf32_Ehdr
90+# define Elf_Shdr Elf32_Shdr
91+# define Elf_Rel Elf32_Rel
92+# define Elf_Rela Elf32_Rela
93+# define Elf_Sym Elf32_Sym
94+# define ELF_R_SYM ELF32_R_SYM
95+# define Elf_r_sym Elf32_r_sym
96+# define ELF_R_INFO ELF32_R_INFO
97+# define Elf_r_info Elf32_r_info
98+# define ELF_ST_BIND ELF32_ST_BIND
99+# define fn_ELF_R_SYM fn_ELF32_R_SYM
100+# define fn_ELF_R_INFO fn_ELF32_R_INFO
101+# define uint_t uint32_t
102+# define _w w
103+# define _align 3u
104+# define _size 4
105+#endif
106+
107+/* Functions and pointers that do_file() may override for specific e_machine. */
108+static int fn_is_fake_mcount(Elf_Rel const *rp)
109+{
110+ return 0;
111+}
112+static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount;
113+
114+static uint_t fn_ELF_R_SYM(Elf_Rel const *rp)
115+{
116+ return ELF_R_SYM(_w(rp->r_info));
117+}
118+static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
119+
120+static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
121+{
122+ rp->r_info = ELF_R_INFO(sym, type);
123+}
124+static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
125+
126+/*
127+ * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st
128+ * _mcount symbol is needed for dynamic function tracer, with it, to disable
129+ * tracing(ftrace_make_nop), the instruction in the position is replaced with
130+ * the "b label" instruction, to enable tracing(ftrace_make_call), replace the
131+ * instruction back. So, here, we set the 2nd one as fake and filter it.
132+ *
133+ * c: 3c030000 lui v1,0x0 <--> b label
134+ * c: R_MIPS_HI16 _mcount
135+ * c: R_MIPS_NONE *ABS*
136+ * c: R_MIPS_NONE *ABS*
137+ * 10: 64630000 daddiu v1,v1,0
138+ * 10: R_MIPS_LO16 _mcount
139+ * 10: R_MIPS_NONE *ABS*
140+ * 10: R_MIPS_NONE *ABS*
141+ * 14: 03e0082d move at,ra
142+ * 18: 0060f809 jalr v1
143+ * label:
144+ */
145+#define MIPS_FAKEMCOUNT_OFFSET 4
146+
147+static int MIPS_is_fake_mcount(Elf_Rel const *rp)
148+{
149+ static Elf_Addr old_r_offset;
150+ Elf_Addr current_r_offset = _w(rp->r_offset);
151+ int is_fake;
152+
153+ is_fake = old_r_offset &&
154+ (current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET);
155+ old_r_offset = current_r_offset;
156+
157+ return is_fake;
158+}
159+
160+/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
161+static void append_func(Elf_Ehdr *const ehdr,
162+ Elf_Shdr *const shstr,
163+ uint_t const *const mloc0,
164+ uint_t const *const mlocp,
165+ Elf_Rel const *const mrel0,
166+ Elf_Rel const *const mrelp,
167+ unsigned int const rel_entsize,
168+ unsigned int const symsec_sh_link)
169+{
170+ /* Begin constructing output file */
171+ Elf_Shdr mcsec;
172+ char const *mc_name = (sizeof(Elf_Rela) == rel_entsize)
173+ ? ".rela__mcount_loc"
174+ : ".rel__mcount_loc";
175+ unsigned const old_shnum = w2(ehdr->e_shnum);
176+ uint_t const old_shoff = _w(ehdr->e_shoff);
177+ uint_t const old_shstr_sh_size = _w(shstr->sh_size);
178+ uint_t const old_shstr_sh_offset = _w(shstr->sh_offset);
179+ uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size);
180+ uint_t new_e_shoff;
181+
182+ shstr->sh_size = _w(t);
183+ shstr->sh_offset = _w(sb.st_size);
184+ t += sb.st_size;
185+ t += (_align & -t); /* word-byte align */
186+ new_e_shoff = t;
187+
188+ /* body for new shstrtab */
189+ ulseek(fd_map, sb.st_size, SEEK_SET);
190+ uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size);
191+ uwrite(fd_map, mc_name, 1 + strlen(mc_name));
192+
193+ /* old(modified) Elf_Shdr table, word-byte aligned */
194+ ulseek(fd_map, t, SEEK_SET);
195+ t += sizeof(Elf_Shdr) * old_shnum;
196+ uwrite(fd_map, old_shoff + (void *)ehdr,
197+ sizeof(Elf_Shdr) * old_shnum);
198+
199+ /* new sections __mcount_loc and .rel__mcount_loc */
200+ t += 2*sizeof(mcsec);
201+ mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel")
202+ + old_shstr_sh_size);
203+ mcsec.sh_type = w(SHT_PROGBITS);
204+ mcsec.sh_flags = _w(SHF_ALLOC);
205+ mcsec.sh_addr = 0;
206+ mcsec.sh_offset = _w(t);
207+ mcsec.sh_size = _w((void *)mlocp - (void *)mloc0);
208+ mcsec.sh_link = 0;
209+ mcsec.sh_info = 0;
210+ mcsec.sh_addralign = _w(_size);
211+ mcsec.sh_entsize = _w(_size);
212+ uwrite(fd_map, &mcsec, sizeof(mcsec));
213+
214+ mcsec.sh_name = w(old_shstr_sh_size);
215+ mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize)
216+ ? w(SHT_RELA)
217+ : w(SHT_REL);
218+ mcsec.sh_flags = 0;
219+ mcsec.sh_addr = 0;
220+ mcsec.sh_offset = _w((void *)mlocp - (void *)mloc0 + t);
221+ mcsec.sh_size = _w((void *)mrelp - (void *)mrel0);
222+ mcsec.sh_link = w(symsec_sh_link);
223+ mcsec.sh_info = w(old_shnum);
224+ mcsec.sh_addralign = _w(_size);
225+ mcsec.sh_entsize = _w(rel_entsize);
226+ uwrite(fd_map, &mcsec, sizeof(mcsec));
227+
228+ uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0);
229+ uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0);
230+
231+ ehdr->e_shoff = _w(new_e_shoff);
232+ ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */
233+ ulseek(fd_map, 0, SEEK_SET);
234+ uwrite(fd_map, ehdr, sizeof(*ehdr));
235+}
236+
237+/*
238+ * Look at the relocations in order to find the calls to mcount.
239+ * Accumulate the section offsets that are found, and their relocation info,
240+ * onto the end of the existing arrays.
241+ */
242+static uint_t *sift_rel_mcount(uint_t *mlocp,
243+ unsigned const offbase,
244+ Elf_Rel **const mrelpp,
245+ Elf_Shdr const *const relhdr,
246+ Elf_Ehdr const *const ehdr,
247+ unsigned const recsym,
248+ uint_t const recval,
249+ unsigned const reltype)
250+{
251+ uint_t *const mloc0 = mlocp;
252+ Elf_Rel *mrelp = *mrelpp;
253+ Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
254+ + (void *)ehdr);
255+ unsigned const symsec_sh_link = w(relhdr->sh_link);
256+ Elf_Shdr const *const symsec = &shdr0[symsec_sh_link];
257+ Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset)
258+ + (void *)ehdr);
259+
260+ Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)];
261+ char const *const str0 = (char const *)(_w(strsec->sh_offset)
262+ + (void *)ehdr);
263+
264+ Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset)
265+ + (void *)ehdr);
266+ unsigned rel_entsize = _w(relhdr->sh_entsize);
267+ unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
268+ Elf_Rel const *relp = rel0;
269+
270+ unsigned mcountsym = 0;
271+ unsigned t;
272+
273+ for (t = nrel; t; --t) {
274+ if (!mcountsym) {
275+ Elf_Sym const *const symp =
276+ &sym0[Elf_r_sym(relp)];
277+ char const *symname = &str0[w(symp->st_name)];
278+
279+ if ('.' == symname[0])
280+ ++symname; /* ppc64 hack */
281+ if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"),
282+ symname))
283+ mcountsym = Elf_r_sym(relp);
284+ }
285+
286+ if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
287+ uint_t const addend = _w(_w(relp->r_offset) - recval);
288+
289+ mrelp->r_offset = _w(offbase
290+ + ((void *)mlocp - (void *)mloc0));
291+ Elf_r_info(mrelp, recsym, reltype);
292+ if (sizeof(Elf_Rela) == rel_entsize) {
293+ ((Elf_Rela *)mrelp)->r_addend = addend;
294+ *mlocp++ = 0;
295+ } else
296+ *mlocp++ = addend;
297+
298+ mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp);
299+ }
300+ relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
301+ }
302+ *mrelpp = mrelp;
303+ return mlocp;
304+}
305+
306+
307+/*
308+ * Find a symbol in the given section, to be used as the base for relocating
309+ * the table of offsets of calls to mcount. A local or global symbol suffices,
310+ * but avoid a Weak symbol because it may be overridden; the change in value
311+ * would invalidate the relocations of the offsets of the calls to mcount.
312+ * Often the found symbol will be the unnamed local symbol generated by
313+ * GNU 'as' for the start of each section. For example:
314+ * Num: Value Size Type Bind Vis Ndx Name
315+ * 2: 00000000 0 SECTION LOCAL DEFAULT 1
316+ */
317+static unsigned find_secsym_ndx(unsigned const txtndx,
318+ char const *const txtname,
319+ uint_t *const recvalp,
320+ Elf_Shdr const *const symhdr,
321+ Elf_Ehdr const *const ehdr)
322+{
323+ Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset)
324+ + (void *)ehdr);
325+ unsigned const nsym = _w(symhdr->sh_size) / _w(symhdr->sh_entsize);
326+ Elf_Sym const *symp;
327+ unsigned t;
328+
329+ for (symp = sym0, t = nsym; t; --t, ++symp) {
330+ unsigned int const st_bind = ELF_ST_BIND(symp->st_info);
331+
332+ if (txtndx == w2(symp->st_shndx)
333+ /* avoid STB_WEAK */
334+ && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
335+ *recvalp = _w(symp->st_value);
336+ return symp - sym0;
337+ }
338+ }
339+ fprintf(stderr, "Cannot find symbol for section %d: %s.\n",
340+ txtndx, txtname);
341+ fail_file();
342+}
343+
344+
345+/* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */
346+static char const *
347+__has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
348+ Elf_Shdr const *const shdr0,
349+ char const *const shstrtab,
350+ char const *const fname)
351+{
352+ /* .sh_info depends on .sh_type == SHT_REL[,A] */
353+ Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
354+ char const *const txtname = &shstrtab[w(txthdr->sh_name)];
355+
356+ if (0 == strcmp("__mcount_loc", txtname)) {
357+ fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
358+ fname);
359+ succeed_file();
360+ }
361+ if (SHT_PROGBITS != w(txthdr->sh_type) ||
362+ !is_mcounted_section_name(txtname))
363+ return NULL;
364+ return txtname;
365+}
366+
367+static char const *has_rel_mcount(Elf_Shdr const *const relhdr,
368+ Elf_Shdr const *const shdr0,
369+ char const *const shstrtab,
370+ char const *const fname)
371+{
372+ if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type))
373+ return NULL;
374+ return __has_rel_mcount(relhdr, shdr0, shstrtab, fname);
375+}
376+
377+
378+static unsigned tot_relsize(Elf_Shdr const *const shdr0,
379+ unsigned nhdr,
380+ const char *const shstrtab,
381+ const char *const fname)
382+{
383+ unsigned totrelsz = 0;
384+ Elf_Shdr const *shdrp = shdr0;
385+
386+ for (; nhdr; --nhdr, ++shdrp) {
387+ if (has_rel_mcount(shdrp, shdr0, shstrtab, fname))
388+ totrelsz += _w(shdrp->sh_size);
389+ }
390+ return totrelsz;
391+}
392+
393+
394+/* Overall supervision for Elf32 ET_REL file. */
395+static void
396+do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
397+{
398+ Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
399+ + (void *)ehdr);
400+ unsigned const nhdr = w2(ehdr->e_shnum);
401+ Elf_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)];
402+ char const *const shstrtab = (char const *)(_w(shstr->sh_offset)
403+ + (void *)ehdr);
404+
405+ Elf_Shdr const *relhdr;
406+ unsigned k;
407+
408+ /* Upper bound on space: assume all relevant relocs are for mcount. */
409+ unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname);
410+ Elf_Rel *const mrel0 = umalloc(totrelsz);
411+ Elf_Rel * mrelp = mrel0;
412+
413+ /* 2*sizeof(address) <= sizeof(Elf_Rel) */
414+ uint_t *const mloc0 = umalloc(totrelsz>>1);
415+ uint_t * mlocp = mloc0;
416+
417+ unsigned rel_entsize = 0;
418+ unsigned symsec_sh_link = 0;
419+
420+ for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
421+ char const *const txtname = has_rel_mcount(relhdr, shdr0,
422+ shstrtab, fname);
423+ if (txtname) {
424+ uint_t recval = 0;
425+ unsigned const recsym = find_secsym_ndx(
426+ w(relhdr->sh_info), txtname, &recval,
427+ &shdr0[symsec_sh_link = w(relhdr->sh_link)],
428+ ehdr);
429+
430+ rel_entsize = _w(relhdr->sh_entsize);
431+ mlocp = sift_rel_mcount(mlocp,
432+ (void *)mlocp - (void *)mloc0, &mrelp,
433+ relhdr, ehdr, recsym, recval, reltype);
434+ }
435+ }
436+ if (mloc0 != mlocp) {
437+ append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
438+ rel_entsize, symsec_sh_link);
439+ }
440+ free(mrel0);
441+ free(mloc0);
442+}
scripts/recordmcount.pl+9−2
@@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section · 158 unmodified lines
159159 my $function_regex; # Find the name of a function
160160 # (return offset and func name)
161161 my $mcount_regex; # Find the call site to mcount (return offset)
162+my $mcount_adjust; # Address adjustment to mcount offset
162163 my $alignment; # The .align value to use for $mcount_section
163164 my $section_type; # Section header plus possible alignment command
164165 my $can_use_local = 0; # If we can use local function references
@@ -213,6 +214,7 @@ $section_regex = "Disassembly of section\\s+(\\S+):"; · 48 unmodified lines
213214 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
214215 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
215216 $section_type = '@progbits';
217+$mcount_adjust = 0;
216218 $type = ".long";
217219
218220 if ($arch eq "x86_64") {
@@ -268,6 +270,8 @@ if ($arch eq "x86_64") { · 49 unmodified lines
268270 } elsif ($arch eq "arm") {
269271 $alignment = 2;
270272 $section_type = '%progbits';
273+ $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" .
274+ "\\s+(__gnu_mcount_nc|mcount)\$";
271275
272276 } elsif ($arch eq "ia64") {
273277 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
@@ -326,7 +330,7 @@ if ($arch eq "x86_64") { · 52 unmodified lines
326330 # 14: R_MIPS_NONE *ABS*
327331 # 18: 00020021 nop
328332 if ($is_module eq "0") {
329− $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
333+ $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_26\\s+_mcount\$";
330334 } else {
331335 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$";
332336 }
@@ -351,6 +355,9 @@ if ($arch eq "x86_64") { · 18 unmodified lines
351355 } elsif ($arch eq "microblaze") {
352356 # Microblaze calls '_mcount' instead of plain 'mcount'.
353357 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
358+} elsif ($arch eq "blackfin") {
359+ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
360+ $mcount_adjust = -4;
354361 } else {
355362 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
356363 }
@@ -511,7 +518,7 @@ while (<IN>) { · 154 unmodified lines
511518 }
512519 # is this a call site to mcount? If so, record it to print later
513520 if ($text_found && /$mcount_regex/) {
514− push(@offsets, hex $1);
521+ push(@offsets, (hex $1) + $mcount_adjust);
515522 }
516523 }
517524
scripts/setlocalversion+2−2
@@ -43,7 +43,7 @@ scm_version() · 42 unmodified lines
4343 fi
4444
4545 # Check for git and a git repo.
46− if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
46+ if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
4747
4848 # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
4949 # it, because this version is defined in the top level Makefile.
@@ -85,7 +85,7 @@ scm_version() · 35 unmodified lines
8585 fi
8686
8787 # Check for mercurial and a mercurial repo.
88− if hgid=`hg id 2>/dev/null`; then
88+ if test -d .hg && hgid=`hg id 2>/dev/null`; then
8989 tag=`printf '%s' "$hgid" | cut -s -d' ' -f2`
9090
9191 # Do we have an untagged version?