aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:20:30 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:21:47 -0500
commitd392da5207352f09030e95d9ea335a4225667ec0 (patch)
tree7d6cd1932afcad0a5619a5c504a6d93ca318187c /scripts
parente39d5ef678045d61812c1401f04fe8edb14d6359 (diff)
parent387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff)
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile1
-rw-r--r--scripts/Makefile.build13
-rw-r--r--scripts/Makefile.clean2
-rw-r--r--scripts/Makefile.headersinst3
-rw-r--r--scripts/Makefile.lib15
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/docproc.c132
-rw-r--r--scripts/basic/hash.c64
-rwxr-xr-xscripts/checkpatch.pl158
-rwxr-xr-xscripts/coccicheck46
-rw-r--r--scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci (renamed from scripts/coccinelle/alloc/drop_kmalloc_cast.cocci)0
-rw-r--r--scripts/coccinelle/api/alloc/kzalloc-simple.cocci (renamed from scripts/coccinelle/alloc/kzalloc-simple.cocci)6
-rw-r--r--scripts/coccinelle/api/err_cast.cocci (renamed from scripts/coccinelle/err_cast.cocci)0
-rw-r--r--scripts/coccinelle/api/kstrdup.cocci39
-rw-r--r--scripts/coccinelle/api/memdup.cocci40
-rw-r--r--scripts/coccinelle/api/memdup_user.cocci35
-rw-r--r--scripts/coccinelle/api/resource_size.cocci (renamed from scripts/coccinelle/resource_size.cocci)0
-rw-r--r--scripts/coccinelle/free/kfree.cocci117
-rw-r--r--scripts/coccinelle/iterators/fen.cocci64
-rw-r--r--scripts/coccinelle/iterators/itnull.cocci58
-rw-r--r--scripts/coccinelle/iterators/list_entry_update.cocci62
-rw-r--r--scripts/coccinelle/locks/call_kern.cocci74
-rw-r--r--scripts/coccinelle/locks/double_lock.cocci92
-rw-r--r--scripts/coccinelle/locks/flags.cocci80
-rw-r--r--scripts/coccinelle/locks/mini_lock.cocci95
-rw-r--r--scripts/coccinelle/misc/doubleinit.cocci53
-rw-r--r--scripts/coccinelle/misc/ifcol.cocci48
-rw-r--r--scripts/coccinelle/null/deref_null.cocci (renamed from scripts/coccinelle/deref_null.cocci)0
-rw-r--r--scripts/coccinelle/null/eno.cocci20
-rw-r--r--scripts/coccinelle/null/kmerr.cocci72
-rw-r--r--scripts/coccinelle/tests/doublebitand.cocci54
-rw-r--r--scripts/coccinelle/tests/doubletest.cocci40
-rwxr-xr-xscripts/extract-ikconfig41
-rw-r--r--scripts/gcc-goto.sh5
-rwxr-xr-xscripts/get_maintainer.pl1162
-rw-r--r--scripts/gfp-translate7
-rw-r--r--scripts/kallsyms.c8
-rw-r--r--scripts/kconfig/Makefile87
-rw-r--r--scripts/kconfig/conf.c32
-rw-r--r--scripts/kconfig/confdata.c241
-rw-r--r--scripts/kconfig/expr.c2
-rw-r--r--scripts/kconfig/expr.h4
-rw-r--r--scripts/kconfig/gconf.c20
-rw-r--r--scripts/kconfig/gconf.glade1
-rw-r--r--scripts/kconfig/kxgettext.c15
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped7
-rw-r--r--scripts/kconfig/lkc.h19
-rw-r--r--scripts/kconfig/lkc_proto.h3
-rw-r--r--scripts/kconfig/lxdialog/check-lxdialog.sh2
-rw-r--r--scripts/kconfig/mconf.c64
-rw-r--r--scripts/kconfig/menu.c24
-rw-r--r--scripts/kconfig/nconf.c489
-rw-r--r--scripts/kconfig/nconf.gui.c22
-rw-r--r--scripts/kconfig/nconf.h3
-rw-r--r--scripts/kconfig/qconf.cc174
-rw-r--r--scripts/kconfig/qconf.h76
-rw-r--r--scripts/kconfig/streamline_config.pl43
-rw-r--r--scripts/kconfig/symbol.c51
-rw-r--r--scripts/kconfig/util.c7
-rw-r--r--scripts/kconfig/zconf.gperf1
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped122
-rw-r--r--scripts/kconfig/zconf.l7
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped603
-rw-r--r--scripts/kconfig/zconf.y37
-rwxr-xr-xscripts/kernel-doc68
-rw-r--r--scripts/mkmakefile4
-rw-r--r--scripts/mod/modpost.c24
-rwxr-xr-xscripts/namespace.pl147
-rw-r--r--scripts/package/builddeb4
-rwxr-xr-xscripts/package/mkspec2
-rw-r--r--scripts/recordmcount.c407
-rw-r--r--scripts/recordmcount.h442
-rwxr-xr-xscripts/recordmcount.pl9
-rwxr-xr-xscripts/setlocalversion12
-rwxr-xr-xscripts/tags.sh4
75 files changed, 4595 insertions, 1392 deletions
diff --git a/scripts/Makefile b/scripts/Makefile
index 842dbc2d5aed..2e088109fbd5 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -11,6 +11,7 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms
11hostprogs-$(CONFIG_LOGO) += pnmtologo 11hostprogs-$(CONFIG_LOGO) += pnmtologo
12hostprogs-$(CONFIG_VT) += conmakehash 12hostprogs-$(CONFIG_VT) += conmakehash
13hostprogs-$(CONFIG_IKCONFIG) += bin2c 13hostprogs-$(CONFIG_IKCONFIG) += bin2c
14hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
14 15
15always := $(hostprogs-y) $(hostprogs-m) 16always := $(hostprogs-y) $(hostprogs-m)
16 17
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index a1a5cf95a68d..5ad25e17b6cb 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -209,12 +209,23 @@ cmd_modversions = \
209endif 209endif
210 210
211ifdef CONFIG_FTRACE_MCOUNT_RECORD 211ifdef CONFIG_FTRACE_MCOUNT_RECORD
212ifdef 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.
217cmd_record_mcount = if [ $(@) != "scripts/mod/empty.o" ]; then \
218 $(objtree)/scripts/recordmcount "$(@)"; \
219 fi;
220else
212cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ 221cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
213 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ 222 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
214 "$(if $(CONFIG_64BIT),64,32)" \ 223 "$(if $(CONFIG_64BIT),64,32)" \
215 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ 224 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
225 "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
216 "$(if $(part-of-module),1,0)" "$(@)"; 226 "$(if $(part-of-module),1,0)" "$(@)";
217endif 227endif
228endif
218 229
219define rule_cc_o_c 230define rule_cc_o_c
220 $(call echo-cmd,checksrc) $(cmd_checksrc) \ 231 $(call echo-cmd,checksrc) $(cmd_checksrc) \
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 6f89fbb56256..686cb0d31c7c 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -45,6 +45,8 @@ __clean-files := $(extra-y) $(always) \
45 $(host-progs) \ 45 $(host-progs) \
46 $(hostprogs-y) $(hostprogs-m) $(hostprogs-) 46 $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
47 47
48__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
49
48# as clean-files is given relative to the current directory, this adds 50# as clean-files is given relative to the current directory, this adds
49# a $(obj) prefix, except for absolute paths 51# a $(obj) prefix, except for absolute paths
50 52
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 0fcd83838771..f89cb87f5c01 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -3,7 +3,6 @@
3# 3#
4# header-y - list files to be installed. They are preprocessed 4# header-y - list files to be installed. They are preprocessed
5# to remove __KERNEL__ section of the file 5# to remove __KERNEL__ section of the file
6# unifdef-y - Same as header-y. Obsolete
7# objhdr-y - Same as header-y but for generated files 6# objhdr-y - Same as header-y but for generated files
8# 7#
9# ========================================================================== 8# ==========================================================================
@@ -20,7 +19,7 @@ include scripts/Kbuild.include
20 19
21install := $(INSTALL_HDR_PATH)/$(_dst) 20install := $(INSTALL_HDR_PATH)/$(_dst)
22 21
23header-y := $(sort $(header-y) $(unifdef-y)) 22header-y := $(sort $(header-y))
24subdirs := $(patsubst %/,%,$(filter %/, $(header-y))) 23subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
25header-y := $(filter-out %/, $(header-y)) 24header-y := $(filter-out %/, $(header-y))
26 25
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 54fd1b700131..4c72c1189479 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -101,14 +101,6 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
101modname_flags = $(if $(filter 1,$(words $(modname))),\ 101modname_flags = $(if $(filter 1,$(words $(modname))),\
102 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") 102 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
103 103
104#hash values
105ifdef CONFIG_DYNAMIC_DEBUG
106debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
107 -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
108else
109debug_flags =
110endif
111
112orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ 104orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
113 $(ccflags-y) $(CFLAGS_$(basetarget).o) 105 $(ccflags-y) $(CFLAGS_$(basetarget).o)
114_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) 106_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
@@ -128,7 +120,9 @@ _c_flags += $(if $(patsubst n%,, \
128endif 120endif
129 121
130ifdef CONFIG_SYMBOL_PREFIX 122ifdef CONFIG_SYMBOL_PREFIX
131_cpp_flags += -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX)) 123_sym_flags = -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))
124_cpp_flags += $(_sym_flags)
125_a_flags += $(_sym_flags)
132endif 126endif
133 127
134 128
@@ -152,8 +146,7 @@ endif
152 146
153c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 147c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
154 $(__c_flags) $(modkern_cflags) \ 148 $(__c_flags) $(modkern_cflags) \
155 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ 149 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
156 $(debug_flags)
157 150
158a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 151a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
159 $(__a_flags) $(modkern_aflags) 152 $(__a_flags) $(modkern_aflags)
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 09559951df12..4c324a1f1e0e 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,7 @@
9# fixdep: Used to generate dependency information during build process 9# fixdep: Used to generate dependency information during build process
10# docproc: Used in Documentation/DocBook 10# docproc: Used in Documentation/DocBook
11 11
12hostprogs-y := fixdep docproc hash 12hostprogs-y := fixdep docproc
13always := $(hostprogs-y) 13always := $(hostprogs-y)
14 14
15# fixdep is needed to compile other host programs 15# fixdep is needed to compile other host programs
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 79ab973fb43a..98dec87974d0 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -34,12 +34,14 @@
34 * 34 *
35 */ 35 */
36 36
37#define _GNU_SOURCE
37#include <stdio.h> 38#include <stdio.h>
38#include <stdlib.h> 39#include <stdlib.h>
39#include <string.h> 40#include <string.h>
40#include <ctype.h> 41#include <ctype.h>
41#include <unistd.h> 42#include <unistd.h>
42#include <limits.h> 43#include <limits.h>
44#include <errno.h>
43#include <sys/types.h> 45#include <sys/types.h>
44#include <sys/wait.h> 46#include <sys/wait.h>
45 47
@@ -54,6 +56,7 @@ typedef void FILEONLY(char * file);
54FILEONLY *internalfunctions; 56FILEONLY *internalfunctions;
55FILEONLY *externalfunctions; 57FILEONLY *externalfunctions;
56FILEONLY *symbolsonly; 58FILEONLY *symbolsonly;
59FILEONLY *findall;
57 60
58typedef void FILELINE(char * file, char * line); 61typedef void FILELINE(char * file, char * line);
59FILELINE * singlefunctions; 62FILELINE * singlefunctions;
@@ -65,12 +68,30 @@ FILELINE * docsection;
65#define KERNELDOCPATH "scripts/" 68#define KERNELDOCPATH "scripts/"
66#define KERNELDOC "kernel-doc" 69#define KERNELDOC "kernel-doc"
67#define DOCBOOK "-docbook" 70#define DOCBOOK "-docbook"
71#define LIST "-list"
68#define FUNCTION "-function" 72#define FUNCTION "-function"
69#define NOFUNCTION "-nofunction" 73#define NOFUNCTION "-nofunction"
70#define NODOCSECTIONS "-no-doc-sections" 74#define NODOCSECTIONS "-no-doc-sections"
71 75
72static char *srctree, *kernsrctree; 76static char *srctree, *kernsrctree;
73 77
78static char **all_list = NULL;
79static int all_list_len = 0;
80
81static 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
74static void usage (void) 95static void usage (void)
75{ 96{
76 fprintf(stderr, "Usage: docproc {doc|depend} file\n"); 97 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
@@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type)
248 struct symfile * sym = &symfilelist[i]; 269 struct symfile * sym = &symfilelist[i];
249 for (j=0; j < sym->symbolcnt; j++) { 270 for (j=0; j < sym->symbolcnt; j++) {
250 vec[idx++] = type; 271 vec[idx++] = type;
272 consume_symbol(sym->symbollist[j].name);
251 vec[idx++] = sym->symbollist[j].name; 273 vec[idx++] = sym->symbollist[j].name;
252 } 274 }
253 } 275 }
@@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line)
287 vec[idx++] = &line[i]; 309 vec[idx++] = &line[i];
288 } 310 }
289 } 311 }
312 for (i = 0; i < idx; i++) {
313 if (strcmp(vec[i], FUNCTION))
314 continue;
315 consume_symbol(vec[i + 1]);
316 }
290 vec[idx++] = filename; 317 vec[idx++] = filename;
291 vec[idx] = NULL; 318 vec[idx] = NULL;
292 exec_kernel_doc(vec); 319 exec_kernel_doc(vec);
@@ -306,6 +333,13 @@ static void docsect(char *filename, char *line)
306 if (*s == '\n') 333 if (*s == '\n')
307 *s = '\0'; 334 *s = '\0';
308 335
336 if (asprintf(&s, "DOC: %s", line) < 0) {
337 perror("asprintf");
338 exit(1);
339 }
340 consume_symbol(s);
341 free(s);
342
309 vec[0] = KERNELDOC; 343 vec[0] = KERNELDOC;
310 vec[1] = DOCBOOK; 344 vec[1] = DOCBOOK;
311 vec[2] = FUNCTION; 345 vec[2] = FUNCTION;
@@ -315,6 +349,84 @@ static void docsect(char *filename, char *line)
315 exec_kernel_doc(vec); 349 exec_kernel_doc(vec);
316} 350}
317 351
352static 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
318/* 430/*
319 * Parse file, calling action specific functions for: 431 * Parse file, calling action specific functions for:
320 * 1) Lines containing !E 432 * 1) Lines containing !E
@@ -322,7 +434,8 @@ static void docsect(char *filename, char *line)
322 * 3) Lines containing !D 434 * 3) Lines containing !D
323 * 4) Lines containing !F 435 * 4) Lines containing !F
324 * 5) Lines containing !P 436 * 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
326 */ 439 */
327static void parse_file(FILE *infile) 440static void parse_file(FILE *infile)
328{ 441{
@@ -365,6 +478,12 @@ static void parse_file(FILE *infile)
365 s++; 478 s++;
366 docsection(line + 2, s); 479 docsection(line + 2, s);
367 break; 480 break;
481 case 'C':
482 while (*s && !isspace(*s)) s++;
483 *s = '\0';
484 if (findall)
485 findall(line+2);
486 break;
368 default: 487 default:
369 defaultline(line); 488 defaultline(line);
370 } 489 }
@@ -380,6 +499,7 @@ static void parse_file(FILE *infile)
380int main(int argc, char *argv[]) 499int main(int argc, char *argv[])
381{ 500{
382 FILE * infile; 501 FILE * infile;
502 int i;
383 503
384 srctree = getenv("SRCTREE"); 504 srctree = getenv("SRCTREE");
385 if (!srctree) 505 if (!srctree)
@@ -415,6 +535,7 @@ int main(int argc, char *argv[])
415 symbolsonly = find_export_symbols; 535 symbolsonly = find_export_symbols;
416 singlefunctions = noaction2; 536 singlefunctions = noaction2;
417 docsection = noaction2; 537 docsection = noaction2;
538 findall = find_all_symbols;
418 parse_file(infile); 539 parse_file(infile);
419 540
420 /* Rewind to start from beginning of file again */ 541 /* Rewind to start from beginning of file again */
@@ -425,8 +546,16 @@ int main(int argc, char *argv[])
425 symbolsonly = printline; 546 symbolsonly = printline;
426 singlefunctions = singfunc; 547 singlefunctions = singfunc;
427 docsection = docsect; 548 docsection = docsect;
549 findall = NULL;
428 550
429 parse_file(infile); 551 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 }
430 } 559 }
431 else if (strcmp("depend", argv[1]) == 0) 560 else if (strcmp("depend", argv[1]) == 0)
432 { 561 {
@@ -439,6 +568,7 @@ int main(int argc, char *argv[])
439 symbolsonly = adddep; 568 symbolsonly = adddep;
440 singlefunctions = adddep2; 569 singlefunctions = adddep2;
441 docsection = adddep2; 570 docsection = adddep2;
571 findall = adddep;
442 parse_file(infile); 572 parse_file(infile);
443 printf("\n"); 573 printf("\n");
444 } 574 }
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
deleted file mode 100644
index 2ef5d3f666b8..000000000000
--- a/scripts/basic/hash.c
+++ /dev/null
@@ -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
12static const char *program;
13
14static 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
24static 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
37static 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
50int 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
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 2039acdf5122..e3c7fc0dca38 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2,7 +2,7 @@
2# (c) 2001, Dave Jones. (the file handling bit) 2# (c) 2001, Dave Jones. (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5# (c) 2008,2009, Andy Whitcroft <apw@canonical.com> 5# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
6# Licensed under the terms of the GNU GPL License version 2 6# Licensed under the terms of the GNU GPL License version 2
7 7
8use strict; 8use strict;
@@ -10,7 +10,7 @@ use strict;
10my $P = $0; 10my $P = $0;
11$P =~ s@.*/@@g; 11$P =~ s@.*/@@g;
12 12
13my $V = '0.30'; 13my $V = '0.31';
14 14
15use Getopt::Long qw(:config no_auto_abbrev); 15use Getopt::Long qw(:config no_auto_abbrev);
16 16
@@ -103,6 +103,8 @@ for my $key (keys %debug) {
103 die "$@" if ($@); 103 die "$@" if ($@);
104} 104}
105 105
106my $rpt_cleaners = 0;
107
106if ($terse) { 108if ($terse) {
107 $emacs = 1; 109 $emacs = 1;
108 $quiet++; 110 $quiet++;
@@ -150,6 +152,20 @@ our $Sparse = qr{
150# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 152# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
151our $Attribute = qr{ 153our $Attribute = qr{
152 const| 154 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|
153 __read_mostly| 169 __read_mostly|
154 __kprobes| 170 __kprobes|
155 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| 171 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
@@ -675,15 +691,15 @@ sub ctx_block_get {
675 $blk .= $rawlines[$line]; 691 $blk .= $rawlines[$line];
676 692
677 # Handle nested #if/#else. 693 # Handle nested #if/#else.
678 if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 694 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
679 push(@stack, $level); 695 push(@stack, $level);
680 } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 696 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
681 $level = $stack[$#stack - 1]; 697 $level = $stack[$#stack - 1];
682 } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) { 698 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
683 $level = pop(@stack); 699 $level = pop(@stack);
684 } 700 }
685 701
686 foreach my $c (split(//, $rawlines[$line])) { 702 foreach my $c (split(//, $lines[$line])) {
687 ##print "C<$c>L<$level><$open$close>O<$off>\n"; 703 ##print "C<$c>L<$level><$open$close>O<$off>\n";
688 if ($off > 0) { 704 if ($off > 0) {
689 $off--; 705 $off--;
@@ -843,7 +859,12 @@ sub annotate_values {
843 $av_preprocessor = 0; 859 $av_preprocessor = 0;
844 } 860 }
845 861
846 } 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*$)/) {
847 print "DECLARE($1)\n" if ($dbg_values > 1); 868 print "DECLARE($1)\n" if ($dbg_values > 1);
848 $type = 'T'; 869 $type = 'T';
849 870
@@ -1308,7 +1329,11 @@ sub process {
1308 $here = "#$realline: " if ($file); 1329 $here = "#$realline: " if ($file);
1309 1330
1310 # extract the filename as it passes 1331 # extract the filename as it passes
1311 if ($line=~/^\+\+\+\s+(\S+)/) { 1332 if ($line =~ /^diff --git.*?(\S+)$/) {
1333 $realfile = $1;
1334 $realfile =~ s@^([^/]*)/@@;
1335
1336 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1312 $realfile = $1; 1337 $realfile = $1;
1313 $realfile =~ s@^([^/]*)/@@; 1338 $realfile =~ s@^([^/]*)/@@;
1314 1339
@@ -1332,6 +1357,14 @@ sub process {
1332 1357
1333 $cnt_lines++ if ($realcnt != 0); 1358 $cnt_lines++ if ($realcnt != 0);
1334 1359
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
1335#check the patch for a signoff: 1368#check the patch for a signoff:
1336 if ($line =~ /^\s*signed-off-by:/i) { 1369 if ($line =~ /^\s*signed-off-by:/i) {
1337 # This is a signoff, if ugly, so do not double report. 1370 # This is a signoff, if ugly, so do not double report.
@@ -1389,21 +1422,38 @@ sub process {
1389 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1422 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1390 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1423 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1391 ERROR("trailing whitespace\n" . $herevet); 1424 ERROR("trailing whitespace\n" . $herevet);
1425 $rpt_cleaners = 1;
1392 } 1426 }
1393 1427
1394# check for Kconfig help text having a real description 1428# 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.
1395 if ($realfile =~ /Kconfig/ && 1431 if ($realfile =~ /Kconfig/ &&
1396 $line =~ /\+?\s*(---)?help(---)?$/) { 1432 $line =~ /\+\s*(?:---)?help(?:---)?$/) {
1397 my $length = 0; 1433 my $length = 0;
1398 for (my $l = $linenr; defined($lines[$l]); $l++) { 1434 my $cnt = $realcnt;
1399 my $f = $lines[$l]; 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/^.//;
1400 $f =~ s/#.*//; 1446 $f =~ s/#.*//;
1401 $f =~ s/^\s+//; 1447 $f =~ s/^\s+//;
1402 next if ($f =~ /^$/); 1448 next if ($f =~ /^$/);
1403 last if ($f =~ /^\s*config\s/); 1449 if ($f =~ /^\s*config\s/) {
1450 $is_end = 1;
1451 last;
1452 }
1404 $length++; 1453 $length++;
1405 } 1454 }
1406 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";
1407 } 1457 }
1408 1458
1409# check we are in a valid source file if not then ignore this hunk 1459# check we are in a valid source file if not then ignore this hunk
@@ -1450,6 +1500,7 @@ sub process {
1450 $rawline =~ /^\+\s* \s*/) { 1500 $rawline =~ /^\+\s* \s*/) {
1451 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1501 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1452 ERROR("code indent should use tabs where possible\n" . $herevet); 1502 ERROR("code indent should use tabs where possible\n" . $herevet);
1503 $rpt_cleaners = 1;
1453 } 1504 }
1454 1505
1455# check for space before tabs. 1506# check for space before tabs.
@@ -1459,10 +1510,13 @@ sub process {
1459 } 1510 }
1460 1511
1461# check for spaces at the beginning of a line. 1512# check for spaces at the beginning of a line.
1462 if ($rawline =~ /^\+ / && $rawline !~ /\+ +\*/) { 1513# Exceptions:
1514# 1) within comments
1515# 2) indented preprocessor commands
1516# 3) hanging labels
1517 if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) {
1463 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1518 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1464 WARN("please, no space for starting a line, \ 1519 WARN("please, no spaces at the start of a line\n" . $herevet);
1465 excluding comments\n" . $herevet);
1466 } 1520 }
1467 1521
1468# check we are in a valid C source file if not then ignore this hunk 1522# check we are in a valid C source file if not then ignore this hunk
@@ -1598,7 +1652,7 @@ sub process {
1598 1652
1599 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 1653 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
1600 ERROR("that open brace { should be on the previous line\n" . 1654 ERROR("that open brace { should be on the previous line\n" .
1601 "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); 1655 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
1602 } 1656 }
1603 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 1657 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
1604 $ctx =~ /\)\s*\;\s*$/ && 1658 $ctx =~ /\)\s*\;\s*$/ &&
@@ -1607,7 +1661,7 @@ sub process {
1607 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 1661 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
1608 if ($nindent > $indent) { 1662 if ($nindent > $indent) {
1609 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . 1663 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
1610 "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); 1664 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
1611 } 1665 }
1612 } 1666 }
1613 } 1667 }
@@ -1768,8 +1822,17 @@ sub process {
1768 !defined $suppress_export{$realline_next} && 1822 !defined $suppress_export{$realline_next} &&
1769 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 1823 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1770 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1824 $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);
1771 my $name = $1; 1829 my $name = $1;
1772 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 !~ /(?:
1773 \n.}\s*$| 1836 \n.}\s*$|
1774 ^.DEFINE_$Ident\(\Q$name\E\)| 1837 ^.DEFINE_$Ident\(\Q$name\E\)|
1775 ^.DECLARE_$Ident\(\Q$name\E\)| 1838 ^.DECLARE_$Ident\(\Q$name\E\)|
@@ -1806,6 +1869,23 @@ sub process {
1806 $herecurr); 1869 $herecurr);
1807 } 1870 }
1808 1871
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
1809# check for new typedefs, only function parameters and sparse annotations 1889# check for new typedefs, only function parameters and sparse annotations
1810# make sense. 1890# make sense.
1811 if ($line =~ /\btypedef\s/ && 1891 if ($line =~ /\btypedef\s/ &&
@@ -1899,6 +1979,11 @@ sub process {
1899 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); 1979 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
1900 } 1980 }
1901 1981
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
1902# check for spacing round square brackets; allowed: 1987# check for spacing round square brackets; allowed:
1903# 1. with a type on the left -- int [] a; 1988# 1. with a type on the left -- int [] a;
1904# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 1989# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
@@ -2176,21 +2261,29 @@ sub process {
2176 my $value = $2; 2261 my $value = $2;
2177 2262
2178 # Flatten any parentheses 2263 # Flatten any parentheses
2179 $value =~ s/\)\(/\) \(/g; 2264 $value =~ s/\(/ \(/g;
2265 $value =~ s/\)/\) /g;
2180 while ($value =~ s/\[[^\{\}]*\]/1/ || 2266 while ($value =~ s/\[[^\{\}]*\]/1/ ||
2181 $value !~ /(?:$Ident|-?$Constant)\s* 2267 $value !~ /(?:$Ident|-?$Constant)\s*
2182 $Compare\s* 2268 $Compare\s*
2183 (?:$Ident|-?$Constant)/x && 2269 (?:$Ident|-?$Constant)/x &&
2184 $value =~ s/\([^\(\)]*\)/1/) { 2270 $value =~ s/\([^\(\)]*\)/1/) {
2185 } 2271 }
2186 2272#print "value<$value>\n";
2187 if ($value =~ /^(?:$Ident|-?$Constant)$/) { 2273 if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
2188 ERROR("return is not a function, parentheses are not required\n" . $herecurr); 2274 ERROR("return is not a function, parentheses are not required\n" . $herecurr);
2189 2275
2190 } elsif ($spacing !~ /\s+/) { 2276 } elsif ($spacing !~ /\s+/) {
2191 ERROR("space required before the open parenthesis '('\n" . $herecurr); 2277 ERROR("space required before the open parenthesis '('\n" . $herecurr);
2192 } 2278 }
2193 } 2279 }
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 }
2194 2287
2195# Need a space before open parenthesis after if, while etc 2288# Need a space before open parenthesis after if, while etc
2196 if ($line=~/\b(if|while|for|switch)\(/) { 2289 if ($line=~/\b(if|while|for|switch)\(/) {
@@ -2409,8 +2502,8 @@ sub process {
2409 \.$Ident\s*=\s*| 2502 \.$Ident\s*=\s*|
2410 ^\"|\"$ 2503 ^\"|\"$
2411 }x; 2504 }x;
2412 #print "REST<$rest> dstat<$dstat>\n"; 2505 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
2413 if ($rest ne '') { 2506 if ($rest ne '' && $rest ne ',') {
2414 if ($rest !~ /while\s*\(/ && 2507 if ($rest !~ /while\s*\(/ &&
2415 $dstat !~ /$exceptions/) 2508 $dstat !~ /$exceptions/)
2416 { 2509 {
@@ -2701,12 +2794,8 @@ sub process {
2701 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); 2794 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
2702 } 2795 }
2703 2796
2704# check for semaphores used as mutexes 2797# check for semaphores initialized locked
2705 if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) { 2798 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
2706 WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
2707 }
2708# check for semaphores used as mutexes
2709 if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
2710 WARN("consider using a completion\n" . $herecurr); 2799 WARN("consider using a completion\n" . $herecurr);
2711 2800
2712 } 2801 }
@@ -2839,6 +2928,15 @@ sub process {
2839 print "\n" if ($quiet == 0); 2928 print "\n" if ($quiet == 0);
2840 } 2929 }
2841 2930
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
2842 if ($clean == 1 && $quiet == 0) { 2940 if ($clean == 1 && $quiet == 0) {
2843 print "$vname has no obvious style problems and is ready for submission.\n" 2941 print "$vname has no obvious style problems and is ready for submission.\n"
2844 } 2942 }
diff --git a/scripts/coccicheck b/scripts/coccicheck
index b8bcf1f7bed7..1bb1a1bd2daa 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -16,6 +16,7 @@ if [ "$C" = "1" -o "$C" = "2" ]; then
16else 16else
17 ONLINE=0 17 ONLINE=0
18 FLAGS="-very_quiet" 18 FLAGS="-very_quiet"
19 OPTIONS="-dir $srctree"
19fi 20fi
20 21
21if [ ! -x "$SPATCH" ]; then 22if [ ! -x "$SPATCH" ]; then
@@ -25,11 +26,13 @@ fi
25 26
26if [ "$MODE" = "" ] ; then 27if [ "$MODE" = "" ] ; then
27 if [ "$ONLINE" = "0" ] ; then 28 if [ "$ONLINE" = "0" ] ; then
28 echo 'You have not explicitly specify the mode to use. Fallback to "report".' 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'
29 echo 'You can specify the mode with "make coccicheck MODE=<mode>"' 31 echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
30 echo 'Available modes are: report, patch, context, org'
31 fi 32 fi
32 MODE="report" 33 MODE="chain"
34elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
35 FLAGS="$FLAGS -no_show_diff"
33fi 36fi
34 37
35if [ "$ONLINE" = "0" ] ; then 38if [ "$ONLINE" = "0" ] ; then
@@ -44,7 +47,7 @@ coccinelle () {
44 47
45 OPT=`grep "Option" $COCCI | cut -d':' -f2` 48 OPT=`grep "Option" $COCCI | cut -d':' -f2`
46 49
47# The option '-parse_cocci' can be used to syntaxically check the SmPL files. 50# The option '-parse_cocci' can be used to syntactically check the SmPL files.
48# 51#
49# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null 52# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
50 53
@@ -52,21 +55,44 @@ coccinelle () {
52 55
53 FILE=`echo $COCCI | sed "s|$srctree/||"` 56 FILE=`echo $COCCI | sed "s|$srctree/||"`
54 57
55 echo "Processing `basename $COCCI` with option(s) \"$OPT\"" 58 echo "Processing `basename $COCCI`"
59 echo "with option(s) \"$OPT\""
60 echo ''
56 echo 'Message example to submit a patch:' 61 echo 'Message example to submit a patch:'
57 62
58 sed -e '/\/\/\//!d' -e 's|^///||' $COCCI 63 sed -ne 's|^///||p' $COCCI
59 64
60 echo ' The semantic patch that makes this change is available' 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
61 echo " in $FILE." 76 echo " in $FILE."
62 echo '' 77 echo ''
63 echo ' More information about semantic patching is available at' 78 echo ' More information about semantic patching is available at'
64 echo ' http://coccinelle.lip6.fr/' 79 echo ' http://coccinelle.lip6.fr/'
65 echo '' 80 echo ''
66 81
67 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 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
68 else 94 else
69 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 95 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
70 fi 96 fi
71 97
72} 98}
diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci
index 7d4771d449c3..7d4771d449c3 100644
--- a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
+++ b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci
diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci
index 2eae828fc657..046b9b16f8f9 100644
--- a/scripts/coccinelle/alloc/kzalloc-simple.cocci
+++ b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci
@@ -1,5 +1,9 @@
1/// 1///
2/// kzalloc should be used rather than kmalloc followed by memset 0 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
3/// 7///
4// Confidence: High 8// Confidence: High
5// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. 9// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci
index 2ce115000af6..2ce115000af6 100644
--- a/scripts/coccinelle/err_cast.cocci
+++ b/scripts/coccinelle/api/err_cast.cocci
diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci
new file mode 100644
index 000000000000..e0805ad08d39
--- /dev/null
+++ b/scripts/coccinelle/api/kstrdup.cocci
@@ -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
11virtual patch
12
13@@
14expression from,to;
15expression flag,E1,E2;
16statement 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@@
27expression x,from,to;
28expression flag,E1,E2,E3;
29statement 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);
diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci
new file mode 100644
index 000000000000..b5d722077dc1
--- /dev/null
+++ b/scripts/coccinelle/api/memdup.cocci
@@ -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
11virtual patch
12
13@r1@
14expression from,to;
15expression flag;
16position p;
17@@
18
19 to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
20
21@r2@
22expression x,from,to;
23expression flag,E1;
24position p;
25@@
26
27 x = strlen(from) + 1;
28 ... when != \( x = E1 \| from = E1 \)
29 to = \(kmalloc@p\|kzalloc@p\)(x,flag);
30
31@@
32expression from,to,size,flag;
33position p != {r1.p,r2.p};
34statement 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);
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci
new file mode 100644
index 000000000000..72ce012e878a
--- /dev/null
+++ b/scripts/coccinelle/api/memdup_user.cocci
@@ -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
12virtual patch
13
14@@
15expression from,to,size,flag;
16position p;
17identifier 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- }
diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci
index 1935a58b39d9..1935a58b39d9 100644
--- a/scripts/coccinelle/resource_size.cocci
+++ b/scripts/coccinelle/api/resource_size.cocci
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci
new file mode 100644
index 000000000000..f9f79d9245ee
--- /dev/null
+++ b/scripts/coccinelle/free/kfree.cocci
@@ -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
15virtual org
16virtual report
17
18@free@
19expression E;
20position p1;
21@@
22
23kfree@p1(E)
24
25@print expression@
26constant char *c;
27expression free.E,E2;
28type T;
29position p;
30identifier 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@
46expression free.E;
47position p;
48@@
49
50 sizeof(<+...E@p...+>)
51
52@loop exists@
53expression E;
54identifier l;
55position ok;
56@@
57
58while (1) { ...
59 kfree@ok(E)
60 ... when != break;
61 when != goto l;
62 when forall
63}
64
65@r exists@
66expression free.E, subE<=free.E, E2;
67expression E1;
68iterator iter;
69statement S;
70position free.p1!=loop.ok,p2!={print.p,sz.p};
71@@
72
73kfree@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@
104p1 << free.p1;
105p2 << r.p2;
106@@
107
108cocci.print_main("kfree",p1)
109cocci.print_secs("ref",p2)
110
111@script:python depends on report@
112p1 << free.p1;
113p2 << r.p2;
114@@
115
116msg = "reference preceded by free on line %s" % (p1[0].line)
117coccilib.report.print_report(p2[0],msg)
diff --git a/scripts/coccinelle/iterators/fen.cocci b/scripts/coccinelle/iterators/fen.cocci
new file mode 100644
index 000000000000..77bc108c3f59
--- /dev/null
+++ b/scripts/coccinelle/iterators/fen.cocci
@@ -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
12virtual patch
13
14@@
15iterator name for_each_node_by_name;
16expression np,E;
17identifier l;
18@@
19
20for_each_node_by_name(np,...) {
21 ... when != break;
22 when != goto l;
23}
24... when != np = E
25- of_node_put(np);
26
27@@
28iterator name for_each_node_by_type;
29expression np,E;
30identifier l;
31@@
32
33for_each_node_by_type(np,...) {
34 ... when != break;
35 when != goto l;
36}
37... when != np = E
38- of_node_put(np);
39
40@@
41iterator name for_each_compatible_node;
42expression np,E;
43identifier l;
44@@
45
46for_each_compatible_node(np,...) {
47 ... when != break;
48 when != goto l;
49}
50... when != np = E
51- of_node_put(np);
52
53@@
54iterator name for_each_matching_node;
55expression np,E;
56identifier l;
57@@
58
59for_each_matching_node(np,...) {
60 ... when != break;
61 when != goto l;
62}
63... when != np = E
64- of_node_put(np);
diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci
new file mode 100644
index 000000000000..baa4297a4ed1
--- /dev/null
+++ b/scripts/coccinelle/iterators/itnull.cocci
@@ -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
15virtual patch
16
17@@
18iterator I;
19expression x,E,E1,E2;
20statement S,S1,S2;
21@@
22
23I(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 ...> } \ No newline at end of file
diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci
new file mode 100644
index 000000000000..b2967475679b
--- /dev/null
+++ b/scripts/coccinelle/iterators/list_entry_update.cocci
@@ -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
14virtual context
15virtual org
16virtual report
17
18@r@
19iterator name list_for_each_entry;
20expression x,E;
21position p1,p2;
22@@
23
24list_for_each_entry@p1(x,...) { <... x =@p2 E ...> }
25
26@depends on context && !org && !report@
27expression x,E;
28position r.p1,r.p2;
29statement S;
30@@
31
32*x =@p2 E
33...
34list_for_each_entry@p1(x,...) S
35
36// ------------------------------------------------------------------------
37
38@back depends on (org || report) && !context exists@
39expression x,E;
40position r.p1,r.p2;
41statement S;
42@@
43
44x =@p2 E
45...
46list_for_each_entry@p1(x,...) S
47
48@script:python depends on back && org@
49p1 << r.p1;
50p2 << r.p2;
51@@
52
53cocci.print_main("iterator",p1)
54cocci.print_secs("update",p2)
55
56@script:python depends on back && report@
57p1 << r.p1;
58p2 << r.p2;
59@@
60
61msg = "iterator with update on line %s" % (p2[0].line)
62coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci
new file mode 100644
index 000000000000..00af5344a68f
--- /dev/null
+++ b/scripts/coccinelle/locks/call_kern.cocci
@@ -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
14virtual patch
15
16@gfp exists@
17identifier fn;
18position p;
19@@
20
21fn(...) {
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@
36identifier gfp.fn;
37@@
38
39(
40read_lock_irq
41|
42write_lock_irq
43|
44read_lock_irqsave
45|
46write_lock_irqsave
47|
48spin_lock
49|
50spin_trylock
51|
52spin_lock_irq
53|
54spin_lock_irqsave
55|
56local_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(...)
67fn(...)
68
69@depends on locked@
70position gfp.p;
71@@
72
73- GFP_KERNEL@p
74+ GFP_ATOMIC
diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci
new file mode 100644
index 000000000000..63b24e682fad
--- /dev/null
+++ b/scripts/coccinelle/locks/double_lock.cocci
@@ -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
13virtual org
14virtual report
15
16@locked@
17position p1;
18expression E1;
19position p;
20@@
21
22(
23mutex_lock@p1
24|
25mutex_trylock@p1
26|
27spin_lock@p1
28|
29spin_trylock@p1
30|
31read_lock@p1
32|
33read_trylock@p1
34|
35write_lock@p1
36|
37write_trylock@p1
38) (E1@p,...);
39
40@balanced@
41position p1 != locked.p1;
42position locked.p;
43identifier lock,unlock;
44expression x <= locked.E1;
45expression E,locked.E1;
46expression E2;
47@@
48
49if (E) {
50 <+... when != E1
51 lock(E1@p,...)
52 ...+>
53}
54... when != E1
55 when != \(x = E2\|&x\)
56 when forall
57if (E) {
58 <+... when != E1
59 unlock@p1(E1,...)
60 ...+>
61}
62
63@r depends on !balanced exists@
64expression x <= locked.E1;
65expression locked.E1;
66expression E2;
67identifier lock;
68position locked.p,p1,p2;
69@@
70
71lock@p1 (E1@p,...);
72... when != E1
73 when != \(x = E2\|&x\)
74lock@p2 (E1,...);
75
76@script:python depends on org@
77p1 << r.p1;
78p2 << r.p2;
79lock << r.lock;
80@@
81
82cocci.print_main(lock,p1)
83cocci.print_secs("second lock",p2)
84
85@script:python depends on report@
86p1 << r.p1;
87p2 << r.p2;
88lock << r.lock;
89@@
90
91msg = "second lock on line %s" % (p2[0].line)
92coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci
new file mode 100644
index 000000000000..b4344d838097
--- /dev/null
+++ b/scripts/coccinelle/locks/flags.cocci
@@ -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
11virtual context
12virtual org
13virtual report
14
15@r@
16expression lock1,lock2,flags;
17position p1,p2;
18@@
19
20(
21spin_lock_irqsave@p1(lock1,flags)
22|
23read_lock_irqsave@p1(lock1,flags)
24|
25write_lock_irqsave@p1(lock1,flags)
26)
27... when != flags
28(
29spin_lock_irqsave(lock1,flags)
30|
31read_lock_irqsave(lock1,flags)
32|
33write_lock_irqsave(lock1,flags)
34|
35spin_lock_irqsave@p2(lock2,flags)
36|
37read_lock_irqsave@p2(lock2,flags)
38|
39write_lock_irqsave@p2(lock2,flags)
40)
41
42@d@
43expression f <= r.flags;
44expression lock1,lock2,flags;
45position 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@
67p1 << r.p1;
68p2 << r.p2;
69@@
70
71cocci.print_main("original lock",p1)
72cocci.print_secs("nested lock+irqsave that reuses flags",p2)
73
74@script:python depends on d && report@
75p1 << r.p1;
76p2 << r.p2;
77@@
78
79msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line)
80coccilib.report.print_report(p2[0], msg)
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci
new file mode 100644
index 000000000000..7641a2925434
--- /dev/null
+++ b/scripts/coccinelle/locks/mini_lock.cocci
@@ -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
16virtual org
17virtual report
18
19@prelocked@
20position p1,p;
21expression E1;
22@@
23
24(
25mutex_lock@p1
26|
27mutex_trylock@p1
28|
29spin_lock@p1
30|
31spin_trylock@p1
32|
33read_lock@p1
34|
35read_trylock@p1
36|
37write_lock@p1
38|
39write_trylock@p1
40|
41read_lock_irq@p1
42|
43write_lock_irq@p1
44|
45read_lock_irqsave@p1
46|
47write_lock_irqsave@p1
48|
49spin_lock_irq@p1
50|
51spin_lock_irqsave@p1
52) (E1@p,...);
53
54@looped@
55position r;
56@@
57
58for(...;...;...) { <+... return@r ...; ...+> }
59
60@err@
61expression E1;
62position prelocked.p;
63position up != prelocked.p1;
64position r!=looped.r;
65identifier lock,unlock;
66@@
67
68lock(E1@p,...);
69<+... when != E1
70if (...) {
71 ... when != E1
72 return@r ...;
73}
74...+>
75unlock@up(E1,...);
76
77@script:python depends on org@
78p << prelocked.p1;
79lock << err.lock;
80unlock << err.unlock;
81p2 << err.r;
82@@
83
84cocci.print_main(lock,p)
85cocci.print_secs(unlock,p2)
86
87@script:python depends on report@
88p << prelocked.p1;
89lock << err.lock;
90unlock << err.unlock;
91p2 << err.r;
92@@
93
94msg = "preceding lock on line %s" % (p[0].line)
95coccilib.report.print_report(p2[0],msg)
diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci
new file mode 100644
index 000000000000..55d7dc19dfe0
--- /dev/null
+++ b/scripts/coccinelle/misc/doubleinit.cocci
@@ -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
13virtual org
14virtual report
15
16@r@
17identifier I, s, fld;
18position p0,p;
19expression E;
20@@
21
22struct I s =@p0 { ... .fld@p = E, ...};
23
24@s@
25identifier I, s, r.fld;
26position r.p0,p;
27expression E;
28@@
29
30struct I s =@p0 { ... .fld@p = E, ...};
31
32@script:python depends on org@
33p0 << r.p0;
34fld << r.fld;
35ps << s.p;
36pr << r.p;
37@@
38
39if 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@
45p0 << r.p0;
46fld << r.fld;
47ps << s.p;
48pr << r.p;
49@@
50
51if 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)
diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci
new file mode 100644
index 000000000000..b7ed91dbeb95
--- /dev/null
+++ b/scripts/coccinelle/misc/ifcol.cocci
@@ -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
18virtual org
19virtual report
20
21@r disable braces4@
22position p1,p2;
23statement S1,S2;
24@@
25
26(
27if (...) { ... }
28|
29if (...) S1@p1 S2@p2
30)
31
32@script:python depends on org@
33p1 << r.p1;
34p2 << r.p2;
35@@
36
37if (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@
42p1 << r.p1;
43p2 << r.p2;
44@@
45
46if (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)
diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci
index 9969d76d0f4b..9969d76d0f4b 100644
--- a/scripts/coccinelle/deref_null.cocci
+++ b/scripts/coccinelle/null/deref_null.cocci
diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci
new file mode 100644
index 000000000000..4c9c52b9c413
--- /dev/null
+++ b/scripts/coccinelle/null/eno.cocci
@@ -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
11virtual patch
12
13@@
14expression x,E;
15@@
16
17x = \(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
diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci
new file mode 100644
index 000000000000..949bf656c64c
--- /dev/null
+++ b/scripts/coccinelle/null/kmerr.cocci
@@ -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
15virtual context
16virtual org
17virtual report
18
19@withtest@
20expression x;
21position p;
22identifier f,fld;
23@@
24
25x@p = f(...);
26... when != x->fld
27\(x == NULL \| x != NULL\)
28
29@fixed depends on context && !org && !report@
30expression x,x1;
31position p1 != withtest.p;
32statement S;
33position any withtest.p;
34identifier f;
35@@
36
37*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
38...
39*x1@p = f(...);
40if (!x1) S
41
42// ------------------------------------------------------------------------
43
44@rfixed depends on (org || report) && !context exists@
45expression x,x1;
46position p1 != withtest.p;
47position p2;
48statement S;
49position any withtest.p;
50identifier f;
51@@
52
53x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
54...
55x1@p = f@p2(...);
56if (!x1) S
57
58@script:python depends on org@
59p1 << rfixed.p1;
60p2 << rfixed.p2;
61@@
62
63cocci.print_main("alloc call",p1)
64cocci.print_secs("possible model",p2)
65
66@script:python depends on report@
67p1 << rfixed.p1;
68p2 << rfixed.p2;
69@@
70
71msg = "alloc with no test, possible model on line %s" % (p2[0].line)
72coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/tests/doublebitand.cocci b/scripts/coccinelle/tests/doublebitand.cocci
new file mode 100644
index 000000000000..9ba73d05a77e
--- /dev/null
+++ b/scripts/coccinelle/tests/doublebitand.cocci
@@ -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
15virtual context
16virtual org
17virtual report
18
19@r expression@
20expression E;
21position 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@
45p << r.p;
46@@
47
48cocci.print_main("duplicated argument to & or |",p)
49
50@script:python depends on report@
51p << r.p;
52@@
53
54coccilib.report.print_report(p[0],"duplicated argument to & or |")
diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci
new file mode 100644
index 000000000000..13a2c0e8a4bf
--- /dev/null
+++ b/scripts/coccinelle/tests/doubletest.cocci
@@ -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
13virtual context
14virtual org
15virtual report
16
17@r expression@
18expression E;
19position p;
20@@
21
22(
23* E@p
24 || ... || E
25|
26* E@p
27 && ... && E
28)
29
30@script:python depends on org@
31p << r.p;
32@@
33
34cocci.print_main("duplicated argument to && or ||",p)
35
36@script:python depends on report@
37p << r.p;
38@@
39
40coccilib.report.print_report(p[0],"duplicated argument to && or ||")
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig
index 37f30d36c944..1512c0a755ac 100755
--- a/scripts/extract-ikconfig
+++ b/scripts/extract-ikconfig
@@ -7,12 +7,10 @@
7# The obscure use of the "tr" filter is to work around older versions of 7# The obscure use of the "tr" filter is to work around older versions of
8# "grep" that report the byte offset of the line instead of the pattern. 8# "grep" that report the byte offset of the line instead of the pattern.
9# 9#
10# (c) 2009, Dick Streefland <dick@streefland.net> 10# (c) 2009,2010 Dick Streefland <dick@streefland.net>
11# Licensed under the terms of the GNU General Public License. 11# Licensed under the terms of the GNU General Public License.
12# ---------------------------------------------------------------------- 12# ----------------------------------------------------------------------
13 13
14gz1='\037\213\010'
15gz2='01'
16cf1='IKCFG_ST\037\213\010' 14cf1='IKCFG_ST\037\213\010'
17cf2='0123456789' 15cf2='0123456789'
18 16
@@ -21,11 +19,25 @@ dump_config()
21 if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` 19 if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
22 then 20 then
23 pos=${pos%%:*} 21 pos=${pos%%:*}
24 tail -c+$(($pos+8)) "$1" | zcat -q 22 tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null
25 exit 0 23 if [ $? != 1 ]
24 then # exit status must be 0 or 2 (trailing garbage warning)
25 cat $tmp1
26 exit 0
27 fi
26 fi 28 fi
27} 29}
28 30
31try_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
29# Check invocation: 41# Check invocation:
30me=${0##*/} 42me=${0##*/}
31img=$1 43img=$1
@@ -35,18 +47,19 @@ then
35 exit 2 47 exit 2
36fi 48fi
37 49
50# Prepare temp files:
51tmp1=/tmp/ikconfig$$.1
52tmp2=/tmp/ikconfig$$.2
53trap "rm -f $tmp1 $tmp2" 0
54
38# Initial attempt for uncompressed images or objects: 55# Initial attempt for uncompressed images or objects:
39dump_config "$img" 56dump_config "$img"
40 57
41# That didn't work, so decompress and try again: 58# That didn't work, so retry after decompression.
42tmp=/tmp/ikconfig$$ 59try_decompress '\037\213\010' xy gunzip
43trap "rm -f $tmp" 0 60try_decompress 'BZh' xy bunzip2
44for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"` 61try_decompress '\135\0\0\0' xxx unlzma
45do 62try_decompress '\211\114\132' xy 'lzop -d'
46 pos=${pos%%:*}
47 tail -c+$pos "$img" | zcat 2> /dev/null > $tmp
48 dump_config $tmp
49done
50 63
51# Bail out: 64# Bail out:
52echo "$me: Cannot find kernel config." >&2 65echo "$me: Cannot find kernel config." >&2
diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh
new file mode 100644
index 000000000000..520d16b1ffaf
--- /dev/null
+++ b/scripts/gcc-goto.sh
@@ -0,0 +1,5 @@
1#!/bin/sh
2# Test for gcc 'asm goto' suport
3# Copyright (C) 2010, Jason Baron <jbaron@redhat.com>
4
5echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y"
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index b2281982f52f..d21ec3a89603 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -13,7 +13,7 @@
13use strict; 13use strict;
14 14
15my $P = $0; 15my $P = $0;
16my $V = '0.24'; 16my $V = '0.26-beta6';
17 17
18use Getopt::Long qw(:config no_auto_abbrev); 18use Getopt::Long qw(:config no_auto_abbrev);
19 19
@@ -24,15 +24,19 @@ my $email_maintainer = 1;
24my $email_list = 1; 24my $email_list = 1;
25my $email_subscriber_list = 0; 25my $email_subscriber_list = 0;
26my $email_git_penguin_chiefs = 0; 26my $email_git_penguin_chiefs = 0;
27my $email_git = 1; 27my $email_git = 0;
28my $email_git_all_signature_types = 0; 28my $email_git_all_signature_types = 0;
29my $email_git_blame = 0; 29my $email_git_blame = 0;
30my $email_git_blame_signatures = 1;
31my $email_git_fallback = 1;
30my $email_git_min_signatures = 1; 32my $email_git_min_signatures = 1;
31my $email_git_max_maintainers = 5; 33my $email_git_max_maintainers = 5;
32my $email_git_min_percent = 5; 34my $email_git_min_percent = 5;
33my $email_git_since = "1-year-ago"; 35my $email_git_since = "1-year-ago";
34my $email_hg_since = "-365"; 36my $email_hg_since = "-365";
37my $interactive = 0;
35my $email_remove_duplicates = 1; 38my $email_remove_duplicates = 1;
39my $email_use_mailmap = 1;
36my $output_multiline = 1; 40my $output_multiline = 1;
37my $output_separator = ", "; 41my $output_separator = ", ";
38my $output_roles = 0; 42my $output_roles = 0;
@@ -49,8 +53,13 @@ my $pattern_depth = 0;
49my $version = 0; 53my $version = 0;
50my $help = 0; 54my $help = 0;
51 55
56my $vcs_used = 0;
57
52my $exit = 0; 58my $exit = 0;
53 59
60my %commit_author_hash;
61my %commit_signer_hash;
62
54my @penguin_chief = (); 63my @penguin_chief = ();
55push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org"); 64push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org");
56#Andrew wants in on most everything - 2009/01/14 65#Andrew wants in on most everything - 2009/01/14
@@ -73,7 +82,6 @@ my @signature_tags = ();
73push(@signature_tags, "Signed-off-by:"); 82push(@signature_tags, "Signed-off-by:");
74push(@signature_tags, "Reviewed-by:"); 83push(@signature_tags, "Reviewed-by:");
75push(@signature_tags, "Acked-by:"); 84push(@signature_tags, "Acked-by:");
76my $signaturePattern = "\(" . join("|", @signature_tags) . "\)";
77 85
78# rfc822 email address - preloaded methods go here. 86# rfc822 email address - preloaded methods go here.
79my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; 87my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
@@ -86,31 +94,70 @@ my %VCS_cmds;
86my %VCS_cmds_git = ( 94my %VCS_cmds_git = (
87 "execute_cmd" => \&git_execute_cmd, 95 "execute_cmd" => \&git_execute_cmd,
88 "available" => '(which("git") ne "") && (-d ".git")', 96 "available" => '(which("git") ne "") && (-d ".git")',
89 "find_signers_cmd" => "git log --no-color --since=\$email_git_since -- \$file", 97 "find_signers_cmd" =>
90 "find_commit_signers_cmd" => "git log --no-color -1 \$commit", 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",
91 "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file", 120 "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file",
92 "blame_file_cmd" => "git blame -l \$file", 121 "blame_file_cmd" => "git blame -l \$file",
93 "commit_pattern" => "^commit [0-9a-f]{40,40}", 122 "commit_pattern" => "^GitCommit: ([0-9a-f]{40,40})",
94 "blame_commit_pattern" => "^([0-9a-f]+) " 123 "blame_commit_pattern" => "^([0-9a-f]+) ",
124 "author_pattern" => "^GitAuthor: (.*)",
125 "subject_pattern" => "^GitSubject: (.*)",
95); 126);
96 127
97my %VCS_cmds_hg = ( 128my %VCS_cmds_hg = (
98 "execute_cmd" => \&hg_execute_cmd, 129 "execute_cmd" => \&hg_execute_cmd,
99 "available" => '(which("hg") ne "") && (-d ".hg")', 130 "available" => '(which("hg") ne "") && (-d ".hg")',
100 "find_signers_cmd" => 131 "find_signers_cmd" =>
101 "hg log --date=\$email_hg_since" . 132 "hg log --date=\$email_hg_since " .
102 " --template='commit {node}\\n{desc}\\n' -- \$file", 133 "--template='HgCommit: {node}\\n" .
103 "find_commit_signers_cmd" => "hg log --template='{desc}\\n' -r \$commit", 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",
104 "blame_range_cmd" => "", # not supported 147 "blame_range_cmd" => "", # not supported
105 "blame_file_cmd" => "hg blame -c \$file", 148 "blame_file_cmd" => "hg blame -n \$file",
106 "commit_pattern" => "^commit [0-9a-f]{40,40}", 149 "commit_pattern" => "^HgCommit: ([0-9a-f]{40,40})",
107 "blame_commit_pattern" => "^([0-9a-f]+):" 150 "blame_commit_pattern" => "^([ 0-9a-f]+):",
151 "author_pattern" => "^HgAuthor: (.*)",
152 "subject_pattern" => "^HgSubject: (.*)",
108); 153);
109 154
110if (-f "${lk_path}.get_maintainer.conf") { 155my $conf = which_conf(".get_maintainer.conf");
156if (-f $conf) {
111 my @conf_args; 157 my @conf_args;
112 open(my $conffile, '<', "${lk_path}.get_maintainer.conf") 158 open(my $conffile, '<', "$conf")
113 or warn "$P: Can't open .get_maintainer.conf: $!\n"; 159 or warn "$P: Can't find a readable .get_maintainer.conf file $!\n";
160
114 while (<$conffile>) { 161 while (<$conffile>) {
115 my $line = $_; 162 my $line = $_;
116 163
@@ -136,13 +183,17 @@ if (!GetOptions(
136 'git!' => \$email_git, 183 'git!' => \$email_git,
137 'git-all-signature-types!' => \$email_git_all_signature_types, 184 'git-all-signature-types!' => \$email_git_all_signature_types,
138 'git-blame!' => \$email_git_blame, 185 'git-blame!' => \$email_git_blame,
186 'git-blame-signatures!' => \$email_git_blame_signatures,
187 'git-fallback!' => \$email_git_fallback,
139 'git-chief-penguins!' => \$email_git_penguin_chiefs, 188 'git-chief-penguins!' => \$email_git_penguin_chiefs,
140 'git-min-signatures=i' => \$email_git_min_signatures, 189 'git-min-signatures=i' => \$email_git_min_signatures,
141 'git-max-maintainers=i' => \$email_git_max_maintainers, 190 'git-max-maintainers=i' => \$email_git_max_maintainers,
142 'git-min-percent=i' => \$email_git_min_percent, 191 'git-min-percent=i' => \$email_git_min_percent,
143 'git-since=s' => \$email_git_since, 192 'git-since=s' => \$email_git_since,
144 'hg-since=s' => \$email_hg_since, 193 'hg-since=s' => \$email_hg_since,
194 'i|interactive!' => \$interactive,
145 'remove-duplicates!' => \$email_remove_duplicates, 195 'remove-duplicates!' => \$email_remove_duplicates,
196 'mailmap!' => \$email_use_mailmap,
146 'm!' => \$email_maintainer, 197 'm!' => \$email_maintainer,
147 'n!' => \$email_usename, 198 'n!' => \$email_usename,
148 'l!' => \$email_list, 199 'l!' => \$email_list,
@@ -181,13 +232,9 @@ if (-t STDIN && !@ARGV) {
181 die "$P: missing patchfile or -f file - use --help if necessary\n"; 232 die "$P: missing patchfile or -f file - use --help if necessary\n";
182} 233}
183 234
184if ($output_separator ne ", ") { 235$output_multiline = 0 if ($output_separator ne ", ");
185 $output_multiline = 0; 236$output_rolestats = 1 if ($interactive);
186} 237$output_roles = 1 if ($output_rolestats);
187
188if ($output_rolestats) {
189 $output_roles = 1;
190}
191 238
192if ($sections) { 239if ($sections) {
193 $email = 0; 240 $email = 0;
@@ -197,6 +244,7 @@ if ($sections) {
197 $subsystem = 0; 244 $subsystem = 0;
198 $web = 0; 245 $web = 0;
199 $keywords = 0; 246 $keywords = 0;
247 $interactive = 0;
200} else { 248} else {
201 my $selections = $email + $scm + $status + $subsystem + $web; 249 my $selections = $email + $scm + $status + $subsystem + $web;
202 if ($selections == 0) { 250 if ($selections == 0) {
@@ -215,10 +263,6 @@ if (!top_of_kernel_tree($lk_path)) {
215 . "a linux kernel source tree.\n"; 263 . "a linux kernel source tree.\n";
216} 264}
217 265
218if ($email_git_all_signature_types) {
219 $signaturePattern = "(.+?)[Bb][Yy]:";
220}
221
222## Read MAINTAINERS for type/value pairs 266## Read MAINTAINERS for type/value pairs
223 267
224my @typevalue = (); 268my @typevalue = ();
@@ -253,31 +297,82 @@ while (<$maint>) {
253} 297}
254close($maint); 298close($maint);
255 299
256my %mailmap;
257 300
258if ($email_remove_duplicates) { 301#
259 open(my $mailmap, '<', "${lk_path}.mailmap") 302# Read mail address map
260 or warn "$P: Can't open .mailmap: $!\n"; 303#
261 while (<$mailmap>) {
262 my $line = $_;
263 304
264 next if ($line =~ m/^\s*#/); 305my $mailmap;
265 next if ($line =~ m/^\s*$/);
266 306
267 my ($name, $address) = parse_email($line); 307read_mailmap();
268 $line = format_email($name, $address, $email_usename);
269 308
270 next if ($line =~ m/^\s*$/); 309sub read_mailmap {
310 $mailmap = {
311 names => {},
312 addresses => {}
313 };
271 314
272 if (exists($mailmap{$name})) { 315 return if (!$email_use_mailmap || !(-f "${lk_path}.mailmap"));
273 my $obj = $mailmap{$name}; 316
274 push(@$obj, $address); 317 open(my $mailmap_file, '<', "${lk_path}.mailmap")
275 } else { 318 or warn "$P: Can't open .mailmap: $!\n";
276 my @arr = ($address); 319
277 $mailmap{$name} = \@arr; 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;
278 } 373 }
279 } 374 }
280 close($mailmap); 375 close($mailmap_file);
281} 376}
282 377
283## use the filenames on the command line or find the filenames in the patchfiles 378## use the filenames on the command line or find the filenames in the patchfiles
@@ -302,7 +397,7 @@ foreach my $file (@ARGV) {
302 } 397 }
303 if ($from_filename) { 398 if ($from_filename) {
304 push(@files, $file); 399 push(@files, $file);
305 if (-f $file && ($keywords || $file_emails)) { 400 if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
306 open(my $f, '<', $file) 401 open(my $f, '<', $file)
307 or die "$P: Can't open $file: $!\n"; 402 or die "$P: Can't open $file: $!\n";
308 my $text = do { local($/) ; <$f> }; 403 my $text = do { local($/) ; <$f> };
@@ -357,67 +452,127 @@ foreach my $file (@ARGV) {
357 452
358@file_emails = uniq(@file_emails); 453@file_emails = uniq(@file_emails);
359 454
455my %email_hash_name;
456my %email_hash_address;
360my @email_to = (); 457my @email_to = ();
458my %hash_list_to;
361my @list_to = (); 459my @list_to = ();
362my @scm = (); 460my @scm = ();
363my @web = (); 461my @web = ();
364my @subsystem = (); 462my @subsystem = ();
365my @status = (); 463my @status = ();
464my %deduplicate_name_hash = ();
465my %deduplicate_address_hash = ();
466my $signature_pattern;
366 467
367# Find responsible parties 468my @maintainers = get_maintainers();
368 469
369foreach my $file (@files) { 470if (@maintainers) {
471 @maintainers = merge_email(@maintainers);
472 output(@maintainers);
473}
370 474
371 my %hash; 475if ($scm) {
372 my $tvi = find_first_section(); 476 @scm = uniq(@scm);
373 while ($tvi < @typevalue) { 477 output(@scm);
374 my $start = find_starting_index($tvi); 478}
375 my $end = find_ending_index($tvi); 479
376 my $exclude = 0; 480if ($status) {
377 my $i; 481 @status = uniq(@status);
378 482 output(@status);
379 #Do not match excluded file patterns 483}
380 484
381 for ($i = $start; $i < $end; $i++) { 485if ($subsystem) {
382 my $line = $typevalue[$i]; 486 @subsystem = uniq(@subsystem);
383 if ($line =~ m/^(\C):\s*(.*)/) { 487 output(@subsystem);
384 my $type = $1; 488}
385 my $value = $2; 489
386 if ($type eq 'X') { 490if ($web) {
387 if (file_match_pattern($file, $value)) { 491 @web = uniq(@web);
388 $exclude = 1; 492 output(@web);
389 last; 493}
390 } 494
391 } 495exit($exit);
392 } 496
393 } 497sub 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
394 532
395 if (!$exclude) {
396 for ($i = $start; $i < $end; $i++) { 533 for ($i = $start; $i < $end; $i++) {
397 my $line = $typevalue[$i]; 534 my $line = $typevalue[$i];
398 if ($line =~ m/^(\C):\s*(.*)/) { 535 if ($line =~ m/^(\C):\s*(.*)/) {
399 my $type = $1; 536 my $type = $1;
400 my $value = $2; 537 my $value = $2;
401 if ($type eq 'F') { 538 if ($type eq 'X') {
402 if (file_match_pattern($file, $value)) { 539 if (file_match_pattern($file, $value)) {
403 my $value_pd = ($value =~ tr@/@@); 540 $exclude = 1;
404 my $file_pd = ($file =~ tr@/@@); 541 last;
405 $value_pd++ if (substr($value,-1,1) ne "/"); 542 }
406 if ($pattern_depth == 0 || 543 }
407 (($file_pd - $value_pd) < $pattern_depth)) { 544 }
408 $hash{$tvi} = $value_pd; 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 }
409 } 566 }
410 } 567 }
411 } 568 }
412 } 569 }
413 } 570 }
571 $tvi = $end + 1;
414 } 572 }
415 573
416 $tvi = $end + 1; 574 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
417 } 575 add_categories($line);
418
419 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
420 add_categories($line);
421 if ($sections) { 576 if ($sections) {
422 my $i; 577 my $i;
423 my $start = find_starting_index($line); 578 my $start = find_starting_index($line);
@@ -435,80 +590,71 @@ foreach my $file (@files) {
435 } 590 }
436 print("\n"); 591 print("\n");
437 } 592 }
593 }
438 } 594 }
439 595
440 if ($email && $email_git) { 596 if ($keywords) {
441 vcs_file_signoffs($file); 597 @keyword_tvi = sort_and_uniq(@keyword_tvi);
598 foreach my $line (@keyword_tvi) {
599 add_categories($line);
600 }
442 } 601 }
443 602
444 if ($email && $email_git_blame) { 603 foreach my $email (@email_to, @list_to) {
445 vcs_file_blame($file); 604 $email->[0] = deduplicate_email($email->[0]);
446 } 605 }
447}
448 606
449if ($keywords) { 607 foreach my $file (@files) {
450 @keyword_tvi = sort_and_uniq(@keyword_tvi); 608 if ($email &&
451 foreach my $line (@keyword_tvi) { 609 ($email_git || ($email_git_fallback &&
452 add_categories($line); 610 !$exact_pattern_match_hash{$file}))) {
611 vcs_file_signoffs($file);
612 }
613 if ($email && $email_git_blame) {
614 vcs_file_blame($file);
615 }
453 } 616 }
454}
455 617
456if ($email) { 618 if ($email) {
457 foreach my $chief (@penguin_chief) { 619 foreach my $chief (@penguin_chief) {
458 if ($chief =~ m/^(.*):(.*)/) { 620 if ($chief =~ m/^(.*):(.*)/) {
459 my $email_address; 621 my $email_address;
460 622
461 $email_address = format_email($1, $2, $email_usename); 623 $email_address = format_email($1, $2, $email_usename);
462 if ($email_git_penguin_chiefs) { 624 if ($email_git_penguin_chiefs) {
463 push(@email_to, [$email_address, 'chief penguin']); 625 push(@email_to, [$email_address, 'chief penguin']);
464 } else { 626 } else {
465 @email_to = grep($_->[0] !~ /${email_address}/, @email_to); 627 @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
628 }
466 } 629 }
467 } 630 }
468 }
469 631
470 foreach my $email (@file_emails) { 632 foreach my $email (@file_emails) {
471 my ($name, $address) = parse_email($email); 633 my ($name, $address) = parse_email($email);
472 634
473 my $tmp_email = format_email($name, $address, $email_usename); 635 my $tmp_email = format_email($name, $address, $email_usename);
474 push_email_address($tmp_email, ''); 636 push_email_address($tmp_email, '');
475 add_role($tmp_email, 'in file'); 637 add_role($tmp_email, 'in file');
638 }
476 } 639 }
477}
478 640
479if ($email || $email_list) {
480 my @to = (); 641 my @to = ();
481 if ($email) { 642 if ($email || $email_list) {
482 @to = (@to, @email_to); 643 if ($email) {
483 } 644 @to = (@to, @email_to);
484 if ($email_list) { 645 }
485 @to = (@to, @list_to); 646 if ($email_list) {
647 @to = (@to, @list_to);
648 }
486 } 649 }
487 output(merge_email(@to));
488}
489
490if ($scm) {
491 @scm = uniq(@scm);
492 output(@scm);
493}
494
495if ($status) {
496 @status = uniq(@status);
497 output(@status);
498}
499 650
500if ($subsystem) { 651 if ($interactive) {
501 @subsystem = uniq(@subsystem); 652 @to = interactive_get_maintainers(\@to);
502 output(@subsystem); 653 }
503}
504 654
505if ($web) { 655 return @to;
506 @web = uniq(@web);
507 output(@web);
508} 656}
509 657
510exit($exit);
511
512sub file_match_pattern { 658sub file_match_pattern {
513 my ($file, $pattern) = @_; 659 my ($file, $pattern) = @_;
514 if (substr($pattern, -1) eq "/") { 660 if (substr($pattern, -1) eq "/") {
@@ -537,7 +683,8 @@ MAINTAINER field selection options:
537 --email => print email address(es) if any 683 --email => print email address(es) if any
538 --git => include recent git \*-by: signers 684 --git => include recent git \*-by: signers
539 --git-all-signature-types => include signers regardless of signature type 685 --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)
541 --git-chief-penguins => include ${penguin_chiefs} 688 --git-chief-penguins => include ${penguin_chiefs}
542 --git-min-signatures => number of signatures required (default: $email_git_min_signatures) 689 --git-min-signatures => number of signatures required (default: $email_git_min_signatures)
543 --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers) 690 --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
@@ -545,6 +692,7 @@ MAINTAINER field selection options:
545 --git-blame => use git blame to find modified commits for patch or file 692 --git-blame => use git blame to find modified commits for patch or file
546 --git-since => git history to use (default: $email_git_since) 693 --git-since => git history to use (default: $email_git_since)
547 --hg-since => hg history to use (default: $email_hg_since) 694 --hg-since => hg history to use (default: $email_hg_since)
695 --interactive => display a menu (mostly useful if used with the --git option)
548 --m => include maintainer(s) if any 696 --m => include maintainer(s) if any
549 --n => include name 'Full Name <addr\@domain.tld>' 697 --n => include name 'Full Name <addr\@domain.tld>'
550 --l => include list(s) if any 698 --l => include list(s) if any
@@ -565,8 +713,9 @@ Output type options:
565 713
566Other options: 714Other options:
567 --pattern-depth => Number of pattern directory traversals (default: 0 (all)) 715 --pattern-depth => Number of pattern directory traversals (default: 0 (all))
568 --keywords => scan patch for keywords (default: 1 (on)) 716 --keywords => scan patch for keywords (default: $keywords)
569 --sections => print the entire subsystem sections with pattern matches 717 --sections => print all of the subsystem sections with pattern matches
718 --mailmap => use .mailmap file (default: $email_use_mailmap)
570 --version => show version 719 --version => show version
571 --help => show this help information 720 --help => show this help information
572 721
@@ -606,30 +755,30 @@ EOT
606} 755}
607 756
608sub top_of_kernel_tree { 757sub top_of_kernel_tree {
609 my ($lk_path) = @_; 758 my ($lk_path) = @_;
610 759
611 if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") { 760 if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
612 $lk_path .= "/"; 761 $lk_path .= "/";
613 } 762 }
614 if ( (-f "${lk_path}COPYING") 763 if ( (-f "${lk_path}COPYING")
615 && (-f "${lk_path}CREDITS") 764 && (-f "${lk_path}CREDITS")
616 && (-f "${lk_path}Kbuild") 765 && (-f "${lk_path}Kbuild")
617 && (-f "${lk_path}MAINTAINERS") 766 && (-f "${lk_path}MAINTAINERS")
618 && (-f "${lk_path}Makefile") 767 && (-f "${lk_path}Makefile")
619 && (-f "${lk_path}README") 768 && (-f "${lk_path}README")
620 && (-d "${lk_path}Documentation") 769 && (-d "${lk_path}Documentation")
621 && (-d "${lk_path}arch") 770 && (-d "${lk_path}arch")
622 && (-d "${lk_path}include") 771 && (-d "${lk_path}include")
623 && (-d "${lk_path}drivers") 772 && (-d "${lk_path}drivers")
624 && (-d "${lk_path}fs") 773 && (-d "${lk_path}fs")
625 && (-d "${lk_path}init") 774 && (-d "${lk_path}init")
626 && (-d "${lk_path}ipc") 775 && (-d "${lk_path}ipc")
627 && (-d "${lk_path}kernel") 776 && (-d "${lk_path}kernel")
628 && (-d "${lk_path}lib") 777 && (-d "${lk_path}lib")
629 && (-d "${lk_path}scripts")) { 778 && (-d "${lk_path}scripts")) {
630 return 1; 779 return 1;
631 } 780 }
632 return 0; 781 return 0;
633} 782}
634 783
635sub parse_email { 784sub parse_email {
@@ -821,11 +970,19 @@ sub add_categories {
821 } 970 }
822 if ($list_additional =~ m/subscribers-only/) { 971 if ($list_additional =~ m/subscribers-only/) {
823 if ($email_subscriber_list) { 972 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 }
825 } 978 }
826 } else { 979 } else {
827 if ($email_list) { 980 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 }
829 } 986 }
830 } 987 }
831 } elsif ($ptype eq "M") { 988 } elsif ($ptype eq "M") {
@@ -856,15 +1013,12 @@ sub add_categories {
856 } 1013 }
857} 1014}
858 1015
859my %email_hash_name;
860my %email_hash_address;
861
862sub email_inuse { 1016sub email_inuse {
863 my ($name, $address) = @_; 1017 my ($name, $address) = @_;
864 1018
865 return 1 if (($name eq "") && ($address eq "")); 1019 return 1 if (($name eq "") && ($address eq ""));
866 return 1 if (($name ne "") && exists($email_hash_name{$name})); 1020 return 1 if (($name ne "") && exists($email_hash_name{lc($name)}));
867 return 1 if (($address ne "") && exists($email_hash_address{$address})); 1021 return 1 if (($address ne "") && exists($email_hash_address{lc($address)}));
868 1022
869 return 0; 1023 return 0;
870} 1024}
@@ -882,8 +1036,8 @@ sub push_email_address {
882 push(@email_to, [format_email($name, $address, $email_usename), $role]); 1036 push(@email_to, [format_email($name, $address, $email_usename), $role]);
883 } elsif (!email_inuse($name, $address)) { 1037 } elsif (!email_inuse($name, $address)) {
884 push(@email_to, [format_email($name, $address, $email_usename), $role]); 1038 push(@email_to, [format_email($name, $address, $email_usename), $role]);
885 $email_hash_name{$name}++; 1039 $email_hash_name{lc($name)}++ if ($name ne "");
886 $email_hash_address{$address}++; 1040 $email_hash_address{lc($address)}++;
887 } 1041 }
888 1042
889 return 1; 1043 return 1;
@@ -952,30 +1106,69 @@ sub which {
952 return ""; 1106 return "";
953} 1107}
954 1108
955sub mailmap { 1109sub which_conf {
956 my (@lines) = @_; 1110 my ($conf) = @_;
957 my %hash;
958 1111
959 foreach my $line (@lines) { 1112 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
960 my ($name, $address) = parse_email($line); 1113 if (-e "$path/$conf") {
961 if (!exists($hash{$name})) { 1114 return "$path/$conf";
962 $hash{$name} = $address;
963 } elsif ($address ne $hash{$name}) {
964 $address = $hash{$name};
965 $line = format_email($name, $address, $email_usename);
966 } 1115 }
967 if (exists($mailmap{$name})) { 1116 }
968 my $obj = $mailmap{$name}; 1117
969 foreach my $map_address (@$obj) { 1118 return "";
970 if (($map_address eq $address) && 1119}
971 ($map_address ne $hash{$name})) { 1120
972 $line = format_email($name, $hash{$name}, $email_usename); 1121sub mailmap_email {
973 } 1122 my ($line) = @_;
974 } 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};
975 } 1143 }
976 } 1144 }
1145 return format_email($real_name, $real_address, 1);
1146}
977 1147
978 return @lines; 1148sub 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
1159sub 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 }
979} 1172}
980 1173
981sub git_execute_cmd { 1174sub git_execute_cmd {
@@ -999,10 +1192,30 @@ sub hg_execute_cmd {
999 return @lines; 1192 return @lines;
1000} 1193}
1001 1194
1195sub 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
1002sub vcs_find_signers { 1214sub vcs_find_signers {
1003 my ($cmd) = @_; 1215 my ($cmd) = @_;
1004 my @lines = ();
1005 my $commits; 1216 my $commits;
1217 my @lines = ();
1218 my @signatures = ();
1006 1219
1007 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); 1220 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1008 1221
@@ -1010,21 +1223,48 @@ sub vcs_find_signers {
1010 1223
1011 $commits = grep(/$pattern/, @lines); # of commits 1224 $commits = grep(/$pattern/, @lines); # of commits
1012 1225
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
1242sub vcs_find_author {
1243 my ($cmd) = @_;
1244 my @lines = ();
1245
1246 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1247
1014 if (!$email_git_penguin_chiefs) { 1248 if (!$email_git_penguin_chiefs) {
1015 @lines = grep(!/${penguin_chiefs}/i, @lines); 1249 @lines = grep(!/${penguin_chiefs}/i, @lines);
1016 } 1250 }
1017 # cut -f2- -d":"
1018 s/.*:\s*(.+)\s*/$1/ for (@lines);
1019 1251
1020## Reformat email addresses (with names) to avoid badly written signatures 1252 return @lines if !@lines;
1021 1253
1254 my @authors = ();
1022 foreach my $line (@lines) { 1255 foreach my $line (@lines) {
1023 my ($name, $address) = parse_email($line); 1256 if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
1024 $line = format_email($name, $address, 1); 1257 my $author = $1;
1258 my ($name, $address) = parse_email($author);
1259 $author = format_email($name, $address, 1);
1260 push(@authors, $author);
1261 }
1025 } 1262 }
1026 1263
1027 return ($commits, @lines); 1264 save_commits_by_author(@lines) if ($interactive);
1265 save_commits_by_signer(@lines) if ($interactive);
1266
1267 return @authors;
1028} 1268}
1029 1269
1030sub vcs_save_commits { 1270sub vcs_save_commits {
@@ -1084,6 +1324,10 @@ sub vcs_blame {
1084 @commits = vcs_save_commits($cmd); 1324 @commits = vcs_save_commits($cmd);
1085 } 1325 }
1086 1326
1327 foreach my $commit (@commits) {
1328 $commit =~ s/^\^//g;
1329 }
1330
1087 return @commits; 1331 return @commits;
1088} 1332}
1089 1333
@@ -1092,7 +1336,7 @@ sub vcs_exists {
1092 %VCS_cmds = %VCS_cmds_git; 1336 %VCS_cmds = %VCS_cmds_git;
1093 return 1 if eval $VCS_cmds{"available"}; 1337 return 1 if eval $VCS_cmds{"available"};
1094 %VCS_cmds = %VCS_cmds_hg; 1338 %VCS_cmds = %VCS_cmds_hg;
1095 return 1 if eval $VCS_cmds{"available"}; 1339 return 2 if eval $VCS_cmds{"available"};
1096 %VCS_cmds = (); 1340 %VCS_cmds = ();
1097 if (!$printed_novcs) { 1341 if (!$printed_novcs) {
1098 warn("$P: No supported VCS found. Add --nogit to options?\n"); 1342 warn("$P: No supported VCS found. Add --nogit to options?\n");
@@ -1104,6 +1348,405 @@ sub vcs_exists {
1104 return 0; 1348 return 0;
1105} 1349}
1106 1350
1351sub vcs_is_git {
1352 vcs_exists();
1353 return $vcs_used == 1;
1354}
1355
1356sub vcs_is_hg {
1357 return $vcs_used == 2;
1358}
1359
1360sub 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
1432Version Control options:
1433g use git history [$email_git]
1434gf use git-fallback [$email_git_fallback]
1435b use git blame [$email_git_blame]
1436bs use blame signatures [$email_git_blame_signatures]
1437c# minimum commits [$email_git_min_signatures]
1438%# min percent [$email_git_min_percent]
1439d# history to use [$$date_ref]
1440x# max maintainers [$email_git_max_maintainers]
1441t all signature types [$email_git_all_signature_types]
1442m use .mailmap [$email_use_mailmap]
1443EOT
1444 }
1445 print STDERR <<EOT
1446
1447Additional options:
14480 toggle all
1449tm toggle maintainers
1450tg toggle git entries
1451tl toggle open list entries
1452ts toggle subscriber list entries
1453f emails in file [$file_emails]
1454k keywords in file [$keywords]
1455r remove duplicates [$email_remove_duplicates]
1456p# pattern match depth [$pattern_depth]
1457EOT
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
1598Interactive mode allows you to select the various maintainers, submitters,
1599commit signers and mailing lists that could be CC'd on a patch.
1600
1601Any *'d entry is selected.
1602
1603If you have git or hg installed, you can choose to summarize the commit
1604history of files in the patch. Also, each line of the current file can
1605be matched to its commit author and that commits signers with blame.
1606
1607Various knobs exist to control the length of time for active commit
1608tracking, the maximum number of commit authors and signers to add,
1609and such.
1610
1611Enter selections at the prompt until you are satisfied that the selected
1612maintainers are appropriate. You may enter multiple selections separated
1613by either commas or spaces.
1614
1615EOT
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
1640sub bool_invert {
1641 my ($bool_ref) = @_;
1642
1643 if ($$bool_ref) {
1644 $$bool_ref = 0;
1645 } else {
1646 $$bool_ref = 1;
1647 }
1648}
1649
1650sub 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
1680sub 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
1713sub 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
1107sub vcs_assign { 1750sub vcs_assign {
1108 my ($role, $divisor, @lines) = @_; 1751 my ($role, $divisor, @lines) = @_;
1109 1752
@@ -1117,9 +1760,9 @@ sub vcs_assign {
1117 $divisor = 1; 1760 $divisor = 1;
1118 } 1761 }
1119 1762
1120 if ($email_remove_duplicates) { 1763 @lines = mailmap(@lines);
1121 @lines = mailmap(@lines); 1764
1122 } 1765 return if (@lines <= 0);
1123 1766
1124 @lines = sort(@lines); 1767 @lines = sort(@lines);
1125 1768
@@ -1152,12 +1795,18 @@ sub vcs_file_signoffs {
1152 my @signers = (); 1795 my @signers = ();
1153 my $commits; 1796 my $commits;
1154 1797
1155 return if (!vcs_exists()); 1798 $vcs_used = vcs_exists();
1799 return if (!$vcs_used);
1156 1800
1157 my $cmd = $VCS_cmds{"find_signers_cmd"}; 1801 my $cmd = $VCS_cmds{"find_signers_cmd"};
1158 $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd 1802 $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
1159 1803
1160 ($commits, @signers) = vcs_find_signers($cmd); 1804 ($commits, @signers) = vcs_find_signers($cmd);
1805
1806 foreach my $signer (@signers) {
1807 $signer = deduplicate_email($signer);
1808 }
1809
1161 vcs_assign("commit_signer", $commits, @signers); 1810 vcs_assign("commit_signer", $commits, @signers);
1162} 1811}
1163 1812
@@ -1165,29 +1814,114 @@ sub vcs_file_blame {
1165 my ($file) = @_; 1814 my ($file) = @_;
1166 1815
1167 my @signers = (); 1816 my @signers = ();
1817 my @all_commits = ();
1168 my @commits = (); 1818 my @commits = ();
1169 my $total_commits; 1819 my $total_commits;
1820 my $total_lines;
1170 1821
1171 return if (!vcs_exists()); 1822 $vcs_used = vcs_exists();
1823 return if (!$vcs_used);
1172 1824
1173 @commits = vcs_blame($file); 1825 @all_commits = vcs_blame($file);
1174 @commits = uniq(@commits); 1826 @commits = uniq(@all_commits);
1175 $total_commits = @commits; 1827 $total_commits = @commits;
1828 $total_lines = @all_commits;
1176 1829
1177 foreach my $commit (@commits) { 1830 if ($email_git_blame_signatures) {
1178 my $commit_count; 1831 if (vcs_is_hg()) {
1179 my @commit_signers = (); 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;
1180 1848
1181 my $cmd = $VCS_cmds{"find_commit_signers_cmd"}; 1849 $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1182 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd 1850 $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
1183 1851
1184 ($commit_count, @commit_signers) = vcs_find_signers($cmd); 1852 ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1185 push(@signers, @commit_signers); 1853
1854 push(@signers, @commit_signers);
1855 }
1856 }
1186 } 1857 }
1187 1858
1188 if ($from_filename) { 1859 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 }
1189 vcs_assign("commits", $total_commits, @signers); 1920 vcs_assign("commits", $total_commits, @signers);
1190 } else { 1921 } else {
1922 foreach my $signer (@signers) {
1923 $signer = deduplicate_email($signer);
1924 }
1191 vcs_assign("modified commits", $total_commits, @signers); 1925 vcs_assign("modified commits", $total_commits, @signers);
1192 } 1926 }
1193} 1927}
diff --git a/scripts/gfp-translate b/scripts/gfp-translate
index d81b968d864e..c9230e158a8f 100644
--- a/scripts/gfp-translate
+++ b/scripts/gfp-translate
@@ -63,7 +63,12 @@ fi
63 63
64# Extract GFP flags from the kernel source 64# Extract GFP flags from the kernel source
65TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 65TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1
66grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE 66grep -q ___GFP $SOURCE/include/linux/gfp.h
67if [ $? -eq 0 ]; then
68 grep "^#define ___GFP" $SOURCE/include/linux/gfp.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE
69else
70 grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE
71fi
67 72
68# Parse the flags 73# Parse the flags
69IFS=" 74IFS="
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index e3902fb39afd..60dd3eb9366e 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -107,12 +107,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
107 107
108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); 108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
109 if (rc != 3) { 109 if (rc != 3) {
110 if (rc != EOF) { 110 if (rc != EOF && fgets(str, 500, in) == NULL)
111 /* skip line. sym is used as dummy to 111 fprintf(stderr, "Read error or end of file.\n");
112 * shut of "warn_unused_result" warning.
113 */
114 sym = fgets(str, 500, in);
115 }
116 return -1; 112 return -1;
117 } 113 }
118 114
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index de934def410f..368ae306aee4 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -8,7 +8,7 @@ PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-c
8ifdef KBUILD_KCONFIG 8ifdef KBUILD_KCONFIG
9Kconfig := $(KBUILD_KCONFIG) 9Kconfig := $(KBUILD_KCONFIG)
10else 10else
11Kconfig := arch/$(SRCARCH)/Kconfig 11Kconfig := Kconfig
12endif 12endif
13 13
14xconfig: $(obj)/qconf 14xconfig: $(obj)/qconf
@@ -145,11 +145,8 @@ check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
145 145
146# Use recursively expanded variables so we do not call gcc unless 146# Use recursively expanded variables so we do not call gcc unless
147# we really need to do so. (Do not call gcc as part of make mrproper) 147# we really need to do so. (Do not call gcc as part of make mrproper)
148HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) 148HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
149HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) 149 -DLOCALE
150
151HOST_EXTRACFLAGS += -DLOCALE
152
153 150
154# =========================================================================== 151# ===========================================================================
155# Shared Makefile for the various kconfig executables: 152# Shared Makefile for the various kconfig executables:
@@ -208,7 +205,7 @@ clean-files += config.pot linux.pot
208PHONY += $(obj)/dochecklxdialog 205PHONY += $(obj)/dochecklxdialog
209$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog 206$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
210$(obj)/dochecklxdialog: 207$(obj)/dochecklxdialog:
211 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) 208 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
212 209
213always := dochecklxdialog 210always := dochecklxdialog
214 211
@@ -226,6 +223,8 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
226HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ 223HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
227 -D LKC_DIRECT_LINK 224 -D LKC_DIRECT_LINK
228 225
226HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
227
229HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses 228HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
230$(obj)/qconf.o: $(obj)/.tmp_qtcheck 229$(obj)/qconf.o: $(obj)/.tmp_qtcheck
231 230
@@ -236,40 +235,48 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile
236# QT needs some extra effort... 235# QT needs some extra effort...
237$(obj)/.tmp_qtcheck: 236$(obj)/.tmp_qtcheck:
238 @set -e; echo " CHECK qt"; dir=""; pkg=""; \ 237 @set -e; echo " CHECK qt"; dir=""; pkg=""; \
239 pkg-config --exists qt 2> /dev/null && pkg=qt; \ 238 if ! pkg-config --exists QtCore 2> /dev/null; then \
240 pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ 239 echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \
241 if [ -n "$$pkg" ]; then \ 240 pkg-config --exists qt 2> /dev/null && pkg=qt; \
242 cflags="\$$(shell pkg-config $$pkg --cflags)"; \ 241 pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
243 libs="\$$(shell pkg-config $$pkg --libs)"; \ 242 if [ -n "$$pkg" ]; then \
244 moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ 243 cflags="\$$(shell pkg-config $$pkg --cflags)"; \
245 dir="$$(pkg-config $$pkg --variable=prefix)"; \ 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; \
246 else \ 275 else \
247 for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ 276 cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \
248 if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ 277 libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \
249 done; \ 278 binpath="\$$(shell pkg-config QtCore --variable=prefix)"; \
250 if [ -z "$$dir" ]; then \ 279 moc="$$binpath/bin/moc"; \
251 echo "*"; \
252 echo "* Unable to find the QT3 installation. Please make sure that"; \
253 echo "* the QT3 development package is correctly installed and"; \
254 echo "* either install pkg-config or set the QTDIR environment"; \
255 echo "* variable to the correct location."; \
256 echo "*"; \
257 false; \
258 fi; \
259 libpath=$$dir/lib; lib=qt; osdir=""; \
260 $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
261 osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
262 test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
263 test -f $$libpath/libqt-mt.so && lib=qt-mt; \
264 cflags="-I$$dir/include"; \
265 libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
266 moc="$$dir/bin/moc"; \
267 fi; \
268 if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
269 echo "*"; \
270 echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
271 echo "*"; \
272 moc="/usr/bin/moc"; \
273 fi; \ 280 fi; \
274 echo "KC_QT_CFLAGS=$$cflags" > $@; \ 281 echo "KC_QT_CFLAGS=$$cflags" > $@; \
275 echo "KC_QT_LIBS=$$libs" >> $@; \ 282 echo "KC_QT_LIBS=$$libs" >> $@; \
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 274f2716b03e..5459a38be866 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -108,7 +108,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
108 check_stdin(); 108 check_stdin();
109 case oldaskconfig: 109 case oldaskconfig:
110 fflush(stdout); 110 fflush(stdout);
111 fgets(line, 128, stdin); 111 xfgets(line, 128, stdin);
112 return 1; 112 return 1;
113 default: 113 default:
114 break; 114 break;
@@ -306,7 +306,7 @@ static int conf_choice(struct menu *menu)
306 check_stdin(); 306 check_stdin();
307 case oldaskconfig: 307 case oldaskconfig:
308 fflush(stdout); 308 fflush(stdout);
309 fgets(line, 128, stdin); 309 xfgets(line, 128, stdin);
310 strip(line); 310 strip(line);
311 if (line[0] == '?') { 311 if (line[0] == '?') {
312 print_help(menu); 312 print_help(menu);
@@ -425,9 +425,9 @@ static void check_conf(struct menu *menu)
425 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { 425 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
426 if (input_mode == listnewconfig) { 426 if (input_mode == listnewconfig) {
427 if (sym->name && !sym_is_choice_value(sym)) { 427 if (sym->name && !sym_is_choice_value(sym)) {
428 printf("CONFIG_%s\n", sym->name); 428 printf("%s%s\n", CONFIG_, sym->name);
429 } 429 }
430 } else { 430 } else if (input_mode != oldnoconfig) {
431 if (!conf_cnt++) 431 if (!conf_cnt++)
432 printf(_("*\n* Restart config...\n*\n")); 432 printf(_("*\n* Restart config...\n*\n"));
433 rootEntry = menu_get_parent_menu(menu); 433 rootEntry = menu_get_parent_menu(menu);
@@ -466,7 +466,7 @@ int main(int ac, char **av)
466 bindtextdomain(PACKAGE, LOCALEDIR); 466 bindtextdomain(PACKAGE, LOCALEDIR);
467 textdomain(PACKAGE); 467 textdomain(PACKAGE);
468 468
469 while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) { 469 while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) {
470 input_mode = (enum input_mode)opt; 470 input_mode = (enum input_mode)opt;
471 switch (opt) { 471 switch (opt) {
472 case silentoldconfig: 472 case silentoldconfig:
@@ -508,8 +508,7 @@ int main(int ac, char **av)
508 name = conf_get_configname(); 508 name = conf_get_configname();
509 if (stat(name, &tmpstat)) { 509 if (stat(name, &tmpstat)) {
510 fprintf(stderr, _("***\n" 510 fprintf(stderr, _("***\n"
511 "*** You have not yet configured your kernel!\n" 511 "*** Configuration file \"%s\" not found!\n"
512 "*** (missing kernel config file \"%s\")\n"
513 "***\n" 512 "***\n"
514 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 513 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
515 "*** \"make menuconfig\" or \"make xconfig\").\n" 514 "*** \"make menuconfig\" or \"make xconfig\").\n"
@@ -571,7 +570,7 @@ int main(int ac, char **av)
571 name = getenv("KCONFIG_NOSILENTUPDATE"); 570 name = getenv("KCONFIG_NOSILENTUPDATE");
572 if (name && *name) { 571 if (name && *name) {
573 fprintf(stderr, 572 fprintf(stderr,
574 _("\n*** Kernel configuration requires explicit update.\n\n")); 573 _("\n*** The configuration requires explicit update.\n\n"));
575 return 1; 574 return 1;
576 } 575 }
577 } 576 }
@@ -623,11 +622,11 @@ int main(int ac, char **av)
623 * All other commands are only used to generate a config. 622 * All other commands are only used to generate a config.
624 */ 623 */
625 if (conf_get_changed() && conf_write(NULL)) { 624 if (conf_get_changed() && conf_write(NULL)) {
626 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); 625 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
627 exit(1); 626 exit(1);
628 } 627 }
629 if (conf_write_autoconf()) { 628 if (conf_write_autoconf()) {
630 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); 629 fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
631 return 1; 630 return 1;
632 } 631 }
633 } else if (input_mode == savedefconfig) { 632 } else if (input_mode == savedefconfig) {
@@ -638,9 +637,20 @@ int main(int ac, char **av)
638 } 637 }
639 } else if (input_mode != listnewconfig) { 638 } else if (input_mode != listnewconfig) {
640 if (conf_write(NULL)) { 639 if (conf_write(NULL)) {
641 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); 640 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
642 exit(1); 641 exit(1);
643 } 642 }
644 } 643 }
645 return 0; 644 return 0;
646} 645}
646/*
647 * Helper function to facilitate fgets() by Jean Sacren.
648 */
649void 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}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index f81f263b64f2..9df80114b47b 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -5,6 +5,7 @@
5 5
6#include <sys/stat.h> 6#include <sys/stat.h>
7#include <ctype.h> 7#include <ctype.h>
8#include <errno.h>
8#include <fcntl.h> 9#include <fcntl.h>
9#include <stdio.h> 10#include <stdio.h>
10#include <stdlib.h> 11#include <stdlib.h>
@@ -18,6 +19,9 @@
18static void conf_warning(const char *fmt, ...) 19static void conf_warning(const char *fmt, ...)
19 __attribute__ ((format (printf, 1, 2))); 20 __attribute__ ((format (printf, 1, 2)));
20 21
22static void conf_message(const char *fmt, ...)
23 __attribute__ ((format (printf, 1, 2)));
24
21static const char *conf_filename; 25static const char *conf_filename;
22static int conf_lineno, conf_warnings, conf_unsaved; 26static int conf_lineno, conf_warnings, conf_unsaved;
23 27
@@ -34,6 +38,29 @@ static void conf_warning(const char *fmt, ...)
34 conf_warnings++; 38 conf_warnings++;
35} 39}
36 40
41static 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
48static void (*conf_message_callback) (const char *fmt, va_list ap) =
49 conf_default_message_callback;
50void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
51{
52 conf_message_callback = fn;
53}
54
55static 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
37const char *conf_get_configname(void) 64const char *conf_get_configname(void)
38{ 65{
39 char *name = getenv("KCONFIG_CONFIG"); 66 char *name = getenv("KCONFIG_CONFIG");
@@ -183,9 +210,8 @@ int conf_read_simple(const char *name, int def)
183 name = conf_expand_value(prop->expr->left.sym->name); 210 name = conf_expand_value(prop->expr->left.sym->name);
184 in = zconf_fopen(name); 211 in = zconf_fopen(name);
185 if (in) { 212 if (in) {
186 printf(_("#\n" 213 conf_message(_("using defaults found in %s"),
187 "# using defaults found in %s\n" 214 name);
188 "#\n"), name);
189 goto load; 215 goto load;
190 } 216 }
191 } 217 }
@@ -220,24 +246,23 @@ load:
220 while (fgets(line, sizeof(line), in)) { 246 while (fgets(line, sizeof(line), in)) {
221 conf_lineno++; 247 conf_lineno++;
222 sym = NULL; 248 sym = NULL;
223 switch (line[0]) { 249 if (line[0] == '#') {
224 case '#': 250 if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
225 if (memcmp(line + 2, "CONFIG_", 7))
226 continue; 251 continue;
227 p = strchr(line + 9, ' '); 252 p = strchr(line + 2 + strlen(CONFIG_), ' ');
228 if (!p) 253 if (!p)
229 continue; 254 continue;
230 *p++ = 0; 255 *p++ = 0;
231 if (strncmp(p, "is not set", 10)) 256 if (strncmp(p, "is not set", 10))
232 continue; 257 continue;
233 if (def == S_DEF_USER) { 258 if (def == S_DEF_USER) {
234 sym = sym_find(line + 9); 259 sym = sym_find(line + 2 + strlen(CONFIG_));
235 if (!sym) { 260 if (!sym) {
236 sym_add_change_count(1); 261 sym_add_change_count(1);
237 break; 262 goto setsym;
238 } 263 }
239 } else { 264 } else {
240 sym = sym_lookup(line + 9, 0); 265 sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
241 if (sym->type == S_UNKNOWN) 266 if (sym->type == S_UNKNOWN)
242 sym->type = S_BOOLEAN; 267 sym->type = S_BOOLEAN;
243 } 268 }
@@ -253,13 +278,8 @@ load:
253 default: 278 default:
254 ; 279 ;
255 } 280 }
256 break; 281 } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
257 case 'C': 282 p = strchr(line + strlen(CONFIG_), '=');
258 if (memcmp(line, "CONFIG_", 7)) {
259 conf_warning("unexpected data");
260 continue;
261 }
262 p = strchr(line + 7, '=');
263 if (!p) 283 if (!p)
264 continue; 284 continue;
265 *p++ = 0; 285 *p++ = 0;
@@ -270,13 +290,13 @@ load:
270 *p2 = 0; 290 *p2 = 0;
271 } 291 }
272 if (def == S_DEF_USER) { 292 if (def == S_DEF_USER) {
273 sym = sym_find(line + 7); 293 sym = sym_find(line + strlen(CONFIG_));
274 if (!sym) { 294 if (!sym) {
275 sym_add_change_count(1); 295 sym_add_change_count(1);
276 break; 296 goto setsym;
277 } 297 }
278 } else { 298 } else {
279 sym = sym_lookup(line + 7, 0); 299 sym = sym_lookup(line + strlen(CONFIG_), 0);
280 if (sym->type == S_UNKNOWN) 300 if (sym->type == S_UNKNOWN)
281 sym->type = S_OTHER; 301 sym->type = S_OTHER;
282 } 302 }
@@ -285,14 +305,12 @@ load:
285 } 305 }
286 if (conf_set_sym_val(sym, def, def_flags, p)) 306 if (conf_set_sym_val(sym, def, def_flags, p))
287 continue; 307 continue;
288 break; 308 } else {
289 case '\r': 309 if (line[0] != '\r' && line[0] != '\n')
290 case '\n': 310 conf_warning("unexpected data");
291 break;
292 default:
293 conf_warning("unexpected data");
294 continue; 311 continue;
295 } 312 }
313setsym:
296 if (sym && sym_is_choice_value(sym)) { 314 if (sym && sym_is_choice_value(sym)) {
297 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 315 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
298 switch (sym->def[def].tri) { 316 switch (sym->def[def].tri) {
@@ -405,14 +423,14 @@ static void conf_write_string(bool headerfile, const char *name,
405{ 423{
406 int l; 424 int l;
407 if (headerfile) 425 if (headerfile)
408 fprintf(out, "#define CONFIG_%s \"", name); 426 fprintf(out, "#define %s%s \"", CONFIG_, name);
409 else 427 else
410 fprintf(out, "CONFIG_%s=\"", name); 428 fprintf(out, "%s%s=\"", CONFIG_, name);
411 429
412 while (1) { 430 while (1) {
413 l = strcspn(str, "\"\\"); 431 l = strcspn(str, "\"\\");
414 if (l) { 432 if (l) {
415 fwrite(str, l, 1, out); 433 xfwrite(str, l, 1, out);
416 str += l; 434 str += l;
417 } 435 }
418 if (!*str) 436 if (!*str)
@@ -433,13 +451,14 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
433 switch (sym_get_tristate_value(sym)) { 451 switch (sym_get_tristate_value(sym)) {
434 case no: 452 case no:
435 if (write_no) 453 if (write_no)
436 fprintf(out, "# CONFIG_%s is not set\n", sym->name); 454 fprintf(out, "# %s%s is not set\n",
455 CONFIG_, sym->name);
437 break; 456 break;
438 case mod: 457 case mod:
439 fprintf(out, "CONFIG_%s=m\n", sym->name); 458 fprintf(out, "%s%s=m\n", CONFIG_, sym->name);
440 break; 459 break;
441 case yes: 460 case yes:
442 fprintf(out, "CONFIG_%s=y\n", sym->name); 461 fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
443 break; 462 break;
444 } 463 }
445 break; 464 break;
@@ -449,7 +468,7 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
449 case S_HEX: 468 case S_HEX:
450 case S_INT: 469 case S_INT:
451 str = sym_get_string_value(sym); 470 str = sym_get_string_value(sym);
452 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 471 fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str);
453 break; 472 break;
454 case S_OTHER: 473 case S_OTHER:
455 case S_UNKNOWN: 474 case S_UNKNOWN:
@@ -497,7 +516,9 @@ int conf_write_defconfig(const char *filename)
497 /* 516 /*
498 * If symbol is a choice value and equals to the 517 * If symbol is a choice value and equals to the
499 * default for a choice - skip. 518 * default for a choice - skip.
500 * But only if value equal to "y". 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")
501 */ 522 */
502 if (sym_is_choice_value(sym)) { 523 if (sym_is_choice_value(sym)) {
503 struct symbol *cs; 524 struct symbol *cs;
@@ -505,10 +526,9 @@ int conf_write_defconfig(const char *filename)
505 526
506 cs = prop_get_symbol(sym_get_choice_prop(sym)); 527 cs = prop_get_symbol(sym_get_choice_prop(sym));
507 ds = sym_choice_default(cs); 528 ds = sym_choice_default(cs);
508 if (sym == ds) { 529 if (!sym_is_optional(cs) && sym == ds) {
509 if ((sym->type == S_BOOLEAN || 530 if ((sym->type == S_BOOLEAN) &&
510 sym->type == S_TRISTATE) && 531 sym_get_tristate_value(sym) == yes)
511 sym_get_tristate_value(sym) == yes)
512 goto next_menu; 532 goto next_menu;
513 } 533 }
514 } 534 }
@@ -540,7 +560,7 @@ int conf_write(const char *name)
540 struct menu *menu; 560 struct menu *menu;
541 const char *basename; 561 const char *basename;
542 const char *str; 562 const char *str;
543 char dirname[128], tmpname[128], newname[128]; 563 char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
544 enum symbol_type type; 564 enum symbol_type type;
545 time_t now; 565 time_t now;
546 int use_timestamp = 1; 566 int use_timestamp = 1;
@@ -580,8 +600,6 @@ int conf_write(const char *name)
580 if (!out) 600 if (!out)
581 return 1; 601 return 1;
582 602
583 sym = sym_lookup("KERNELVERSION", 0);
584 sym_calc_value(sym);
585 time(&now); 603 time(&now);
586 env = getenv("KCONFIG_NOTIMESTAMP"); 604 env = getenv("KCONFIG_NOTIMESTAMP");
587 if (env && *env) 605 if (env && *env)
@@ -589,10 +607,10 @@ int conf_write(const char *name)
589 607
590 fprintf(out, _("#\n" 608 fprintf(out, _("#\n"
591 "# Automatically generated make config: don't edit\n" 609 "# Automatically generated make config: don't edit\n"
592 "# Linux kernel version: %s\n" 610 "# %s\n"
593 "%s%s" 611 "%s%s"
594 "#\n"), 612 "#\n"),
595 sym_get_string_value(sym), 613 rootmenu.prompt->text,
596 use_timestamp ? "# " : "", 614 use_timestamp ? "# " : "",
597 use_timestamp ? ctime(&now) : ""); 615 use_timestamp ? ctime(&now) : "");
598 616
@@ -649,9 +667,7 @@ next:
649 return 1; 667 return 1;
650 } 668 }
651 669
652 printf(_("#\n" 670 conf_message(_("configuration written to %s"), newname);
653 "# configuration written to %s\n"
654 "#\n"), newname);
655 671
656 sym_set_change_count(0); 672 sym_set_change_count(0);
657 673
@@ -661,7 +677,7 @@ next:
661static int conf_split_config(void) 677static int conf_split_config(void)
662{ 678{
663 const char *name; 679 const char *name;
664 char path[128]; 680 char path[PATH_MAX+1];
665 char *s, *d, c; 681 char *s, *d, c;
666 struct symbol *sym; 682 struct symbol *sym;
667 struct stat sb; 683 struct stat sb;
@@ -803,25 +819,23 @@ int conf_write_autoconf(void)
803 return 1; 819 return 1;
804 } 820 }
805 821
806 sym = sym_lookup("KERNELVERSION", 0);
807 sym_calc_value(sym);
808 time(&now); 822 time(&now);
809 fprintf(out, "#\n" 823 fprintf(out, "#\n"
810 "# Automatically generated make config: don't edit\n" 824 "# Automatically generated make config: don't edit\n"
811 "# Linux kernel version: %s\n" 825 "# %s\n"
812 "# %s" 826 "# %s"
813 "#\n", 827 "#\n",
814 sym_get_string_value(sym), ctime(&now)); 828 rootmenu.prompt->text, ctime(&now));
815 fprintf(tristate, "#\n" 829 fprintf(tristate, "#\n"
816 "# Automatically generated - do not edit\n" 830 "# Automatically generated - do not edit\n"
817 "\n"); 831 "\n");
818 fprintf(out_h, "/*\n" 832 fprintf(out_h, "/*\n"
819 " * Automatically generated C config: don't edit\n" 833 " * Automatically generated C config: don't edit\n"
820 " * Linux kernel version: %s\n" 834 " * %s\n"
821 " * %s" 835 " * %s"
822 " */\n" 836 " */\n"
823 "#define AUTOCONF_INCLUDED\n", 837 "#define AUTOCONF_INCLUDED\n",
824 sym_get_string_value(sym), ctime(&now)); 838 rootmenu.prompt->text, ctime(&now));
825 839
826 for_all_symbols(i, sym) { 840 for_all_symbols(i, sym) {
827 sym_calc_value(sym); 841 sym_calc_value(sym);
@@ -839,14 +853,17 @@ int conf_write_autoconf(void)
839 case no: 853 case no:
840 break; 854 break;
841 case mod: 855 case mod:
842 fprintf(tristate, "CONFIG_%s=M\n", sym->name); 856 fprintf(tristate, "%s%s=M\n",
843 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 857 CONFIG_, sym->name);
858 fprintf(out_h, "#define %s%s_MODULE 1\n",
859 CONFIG_, sym->name);
844 break; 860 break;
845 case yes: 861 case yes:
846 if (sym->type == S_TRISTATE) 862 if (sym->type == S_TRISTATE)
847 fprintf(tristate, "CONFIG_%s=Y\n", 863 fprintf(tristate,"%s%s=Y\n",
848 sym->name); 864 CONFIG_, sym->name);
849 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 865 fprintf(out_h, "#define %s%s 1\n",
866 CONFIG_, sym->name);
850 break; 867 break;
851 } 868 }
852 break; 869 break;
@@ -856,12 +873,14 @@ int conf_write_autoconf(void)
856 case S_HEX: 873 case S_HEX:
857 str = sym_get_string_value(sym); 874 str = sym_get_string_value(sym);
858 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 875 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
859 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);
860 break; 878 break;
861 } 879 }
862 case S_INT: 880 case S_INT:
863 str = sym_get_string_value(sym); 881 str = sym_get_string_value(sym);
864 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);
865 break; 884 break;
866 default: 885 default:
867 break; 886 break;
@@ -919,13 +938,73 @@ void conf_set_changed_callback(void (*fn)(void))
919 conf_changed_callback = fn; 938 conf_changed_callback = fn;
920} 939}
921 940
941static void randomize_choice_values(struct symbol *csym)
942{
943 struct property *prop;
944 struct symbol *sym;
945 struct expr *e;
946 int cnt, def;
922 947
923void 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
984static void set_all_choice_values(struct symbol *csym)
924{ 985{
925 struct symbol *sym, *csym;
926 struct property *prop; 986 struct property *prop;
987 struct symbol *sym;
927 struct expr *e; 988 struct expr *e;
928 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
1004void conf_set_all_new_symbols(enum conf_def_mode mode)
1005{
1006 struct symbol *sym, *csym;
1007 int i, cnt;
929 1008
930 for_all_symbols(i, sym) { 1009 for_all_symbols(i, sym) {
931 if (sym_has_value(sym)) 1010 if (sym_has_value(sym))
@@ -961,8 +1040,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
961 1040
962 sym_clear_all_valid(); 1041 sym_clear_all_valid();
963 1042
964 if (mode != def_random)
965 return;
966 /* 1043 /*
967 * We have different type of choice blocks. 1044 * We have different type of choice blocks.
968 * If curr.tri equal to mod then we can select several 1045 * If curr.tri equal to mod then we can select several
@@ -977,35 +1054,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
977 continue; 1054 continue;
978 1055
979 sym_calc_value(csym); 1056 sym_calc_value(csym);
980 1057 if (mode == def_random)
981 if (csym->curr.tri != yes) 1058 randomize_choice_values(csym);
982 continue; 1059 else
983 1060 set_all_choice_values(csym);
984 prop = sym_get_choice_prop(csym);
985
986 /* count entries in choice block */
987 cnt = 0;
988 expr_list_for_each_sym(prop->expr, e, sym)
989 cnt++;
990
991 /*
992 * find a random value and set it to yes,
993 * set the rest to no so we have only one set
994 */
995 def = (rand() % cnt);
996
997 cnt = 0;
998 expr_list_for_each_sym(prop->expr, e, sym) {
999 if (def == cnt++) {
1000 sym->def[S_DEF_USER].tri = yes;
1001 csym->def[S_DEF_USER].val = sym;
1002 }
1003 else {
1004 sym->def[S_DEF_USER].tri = no;
1005 }
1006 }
1007 csym->flags |= SYMBOL_DEF_USER;
1008 /* clear VALID to get value calculated */
1009 csym->flags &= ~(SYMBOL_VALID);
1010 } 1061 }
1011} 1062}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 8f18e37892cb..330e7c0048a8 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1087,7 +1087,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
1087 1087
1088static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 1088static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1089{ 1089{
1090 fwrite(str, strlen(str), 1, data); 1090 xfwrite(str, strlen(str), 1, data);
1091} 1091}
1092 1092
1093void expr_fprint(struct expr *e, FILE *out) 1093void expr_fprint(struct expr *e, FILE *out)
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 6ee2e4fb1481..e57826ced380 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -18,7 +18,7 @@ extern "C" {
18struct file { 18struct file {
19 struct file *next; 19 struct file *next;
20 struct file *parent; 20 struct file *parent;
21 char *name; 21 const char *name;
22 int lineno; 22 int lineno;
23 int flags; 23 int flags;
24}; 24};
@@ -164,8 +164,8 @@ struct menu {
164 struct menu *list; 164 struct menu *list;
165 struct symbol *sym; 165 struct symbol *sym;
166 struct property *prompt; 166 struct property *prompt;
167 struct expr *visibility;
167 struct expr *dep; 168 struct expr *dep;
168 struct expr *dir_dep;
169 unsigned int flags; 169 unsigned int flags;
170 char *help; 170 char *help;
171 struct file *file; 171 struct file *file;
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index d66988265f89..455896164d72 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -133,7 +133,6 @@ void init_main_window(const gchar * glade_file)
133 GladeXML *xml; 133 GladeXML *xml;
134 GtkWidget *widget; 134 GtkWidget *widget;
135 GtkTextBuffer *txtbuf; 135 GtkTextBuffer *txtbuf;
136 char title[256];
137 GtkStyle *style; 136 GtkStyle *style;
138 137
139 xml = glade_xml_new(glade_file, "window1", NULL); 138 xml = glade_xml_new(glade_file, "window1", NULL);
@@ -210,9 +209,7 @@ void init_main_window(const gchar * glade_file)
210 /*"style", PANGO_STYLE_OBLIQUE, */ 209 /*"style", PANGO_STYLE_OBLIQUE, */
211 NULL); 210 NULL);
212 211
213 sprintf(title, _("Linux Kernel v%s Configuration"), 212 gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
214 getenv("KERNELVERSION"));
215 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
216 213
217 gtk_widget_show(main_wnd); 214 gtk_widget_show(main_wnd);
218} 215}
@@ -671,8 +668,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
671{ 668{
672 GtkWidget *dialog; 669 GtkWidget *dialog;
673 const gchar *intro_text = _( 670 const gchar *intro_text = _(
674 "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" 671 "Welcome to gkc, the GTK+ graphical configuration tool\n"
675 "for Linux.\n"
676 "For each option, a blank box indicates the feature is disabled, a\n" 672 "For each option, a blank box indicates the feature is disabled, a\n"
677 "check indicates it is enabled, and a dot indicates that it is to\n" 673 "check indicates it is enabled, and a dot indicates that it is to\n"
678 "be compiled as a module. Clicking on the box will cycle through the three states.\n" 674 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
@@ -1531,12 +1527,6 @@ int main(int ac, char *av[])
1531 else 1527 else
1532 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); 1528 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
1533 1529
1534 /* Load the interface and connect signals */
1535 init_main_window(glade_file);
1536 init_tree_model();
1537 init_left_tree();
1538 init_right_tree();
1539
1540 /* Conf stuffs */ 1530 /* Conf stuffs */
1541 if (ac > 1 && av[1][0] == '-') { 1531 if (ac > 1 && av[1][0] == '-') {
1542 switch (av[1][1]) { 1532 switch (av[1][1]) {
@@ -1556,6 +1546,12 @@ int main(int ac, char *av[])
1556 fixup_rootmenu(&rootmenu); 1546 fixup_rootmenu(&rootmenu);
1557 conf_read(NULL); 1547 conf_read(NULL);
1558 1548
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
1559 switch (view_mode) { 1555 switch (view_mode) {
1560 case SINGLE_VIEW: 1556 case SINGLE_VIEW:
1561 display_tree_part(); 1557 display_tree_part();
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index d52b0a75d824..aa483cb32755 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -1,5 +1,4 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> 1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3 2
4<glade-interface> 3<glade-interface>
5 4
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
index dcc3fcc0cc9a..e9d8e791bf0d 100644
--- a/scripts/kconfig/kxgettext.c
+++ b/scripts/kconfig/kxgettext.c
@@ -63,11 +63,11 @@ next:
63 63
64struct file_line { 64struct file_line {
65 struct file_line *next; 65 struct file_line *next;
66 char* file; 66 const char *file;
67 int lineno; 67 int lineno;
68}; 68};
69 69
70static struct file_line *file_line__new(char *file, int lineno) 70static struct file_line *file_line__new(const char *file, int lineno)
71{ 71{
72 struct file_line *self = malloc(sizeof(*self)); 72 struct file_line *self = malloc(sizeof(*self));
73 73
@@ -90,7 +90,8 @@ struct message {
90 90
91static struct message *message__list; 91static struct message *message__list;
92 92
93static struct message *message__new(const char *msg, char *option, char *file, int lineno) 93static struct message *message__new(const char *msg, char *option,
94 const char *file, int lineno)
94{ 95{
95 struct message *self = malloc(sizeof(*self)); 96 struct message *self = malloc(sizeof(*self));
96 97
@@ -130,7 +131,8 @@ static struct message *mesage__find(const char *msg)
130 return m; 131 return m;
131} 132}
132 133
133static int message__add_file_line(struct message *self, char *file, int lineno) 134static int message__add_file_line(struct message *self, const char *file,
135 int lineno)
134{ 136{
135 int rc = -1; 137 int rc = -1;
136 struct file_line *fl = file_line__new(file, lineno); 138 struct file_line *fl = file_line__new(file, lineno);
@@ -145,7 +147,8 @@ out:
145 return rc; 147 return rc;
146} 148}
147 149
148static int message__add(const char *msg, char *option, char *file, int lineno) 150static int message__add(const char *msg, char *option, const char *file,
151 int lineno)
149{ 152{
150 int rc = 0; 153 int rc = 0;
151 char bf[16384]; 154 char bf[16384];
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index fdc7113b08d1..6eb039718259 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -2373,9 +2373,10 @@ void zconf_nextfile(const char *name)
2373 memset(buf, 0, sizeof(*buf)); 2373 memset(buf, 0, sizeof(*buf));
2374 2374
2375 current_buf->state = YY_CURRENT_BUFFER; 2375 current_buf->state = YY_CURRENT_BUFFER;
2376 zconfin = zconf_fopen(name); 2376 zconfin = zconf_fopen(file->name);
2377 if (!zconfin) { 2377 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);
2379 exit(1); 2380 exit(1);
2380 } 2381 }
2381 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); 2382 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
@@ -2422,7 +2423,7 @@ int zconf_lineno(void)
2422 return current_pos.lineno; 2423 return current_pos.lineno;
2423} 2424}
2424 2425
2425char *zconf_curname(void) 2426const char *zconf_curname(void)
2426{ 2427{
2427 return current_pos.file ? current_pos.file->name : "<none>"; 2428 return current_pos.file ? current_pos.file->name : "<none>";
2428} 2429}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 76db065ed72c..3f7240df0f3b 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -31,12 +31,18 @@ extern "C" {
31 31
32#define SRCTREE "srctree" 32#define SRCTREE "srctree"
33 33
34#ifndef PACKAGE
34#define PACKAGE "linux" 35#define PACKAGE "linux"
36#endif
37
35#define LOCALEDIR "/usr/share/locale" 38#define LOCALEDIR "/usr/share/locale"
36 39
37#define _(text) gettext(text) 40#define _(text) gettext(text)
38#define N_(text) (text) 41#define N_(text) (text)
39 42
43#ifndef CONFIG_
44#define CONFIG_ "CONFIG_"
45#endif
40 46
41#define TF_COMMAND 0x0001 47#define TF_COMMAND 0x0001
42#define TF_PARAM 0x0002 48#define TF_PARAM 0x0002
@@ -70,7 +76,10 @@ FILE *zconf_fopen(const char *name);
70void zconf_initscan(const char *name); 76void zconf_initscan(const char *name);
71void zconf_nextfile(const char *name); 77void zconf_nextfile(const char *name);
72int zconf_lineno(void); 78int zconf_lineno(void);
73char *zconf_curname(void); 79const char *zconf_curname(void);
80
81/* conf.c */
82void xfgets(char *str, int size, FILE *in);
74 83
75/* confdata.c */ 84/* confdata.c */
76const char *conf_get_configname(void); 85const char *conf_get_configname(void);
@@ -80,6 +89,13 @@ void sym_set_change_count(int count);
80void sym_add_change_count(int count); 89void sym_add_change_count(int count);
81void conf_set_all_new_symbols(enum conf_def_mode mode); 90void conf_set_all_new_symbols(enum conf_def_mode mode);
82 91
92/* confdata.c and expr.c */
93static 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
83/* kconfig_load.c */ 99/* kconfig_load.c */
84void kconfig_load(void); 100void kconfig_load(void);
85 101
@@ -91,6 +107,7 @@ void menu_end_menu(void);
91void menu_add_entry(struct symbol *sym); 107void menu_add_entry(struct symbol *sym);
92void menu_end_entry(void); 108void menu_end_entry(void);
93void menu_add_dep(struct expr *dep); 109void menu_add_dep(struct expr *dep);
110void menu_add_visibility(struct expr *dep);
94struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); 111struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
95struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); 112struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
96void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); 113void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 9a948c9ce44e..17342fef38b9 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,3 +1,4 @@
1#include <stdarg.h>
1 2
2/* confdata.c */ 3/* confdata.c */
3P(conf_parse,void,(const char *name)); 4P(conf_parse,void,(const char *name));
@@ -8,6 +9,7 @@ P(conf_write,int,(const char *name));
8P(conf_write_autoconf,int,(void)); 9P(conf_write_autoconf,int,(void));
9P(conf_get_changed,bool,(void)); 10P(conf_get_changed,bool,(void));
10P(conf_set_changed_callback, void,(void (*fn)(void))); 11P(conf_set_changed_callback, void,(void (*fn)(void)));
12P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap)));
11 13
12/* menu.c */ 14/* menu.c */
13P(rootmenu,struct menu,); 15P(rootmenu,struct menu,);
@@ -28,6 +30,7 @@ P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
28 30
29P(sym_lookup,struct symbol *,(const char *name, int flags)); 31P(sym_lookup,struct symbol *,(const char *name, int flags));
30P(sym_find,struct symbol *,(const char *name)); 32P(sym_find,struct symbol *,(const char *name));
33P(sym_expand_string_value,const char *,(const char *in));
31P(sym_re_search,struct symbol **,(const char *pattern)); 34P(sym_re_search,struct symbol **,(const char *pattern));
32P(sym_type_name,const char *,(enum symbol_type type)); 35P(sym_type_name,const char *,(enum symbol_type type));
33P(sym_calc_value,void,(struct symbol *sym)); 36P(sym_calc_value,void,(struct symbol *sym));
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index fcef0f59d553..82cc3a85e7f8 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -23,6 +23,8 @@ ccflags()
23 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' 23 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
24 elif [ -f /usr/include/ncurses/curses.h ]; then 24 elif [ -f /usr/include/ncurses/curses.h ]; then
25 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' 25 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>"'
26 elif [ -f /usr/include/ncurses.h ]; then 28 elif [ -f /usr/include/ncurses.h ]; then
27 echo '-DCURSES_LOC="<ncurses.h>"' 29 echo '-DCURSES_LOC="<ncurses.h>"'
28 else 30 else
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index d2f6e056c058..d433c7a24745 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -25,11 +25,9 @@
25static const char mconf_readme[] = N_( 25static const char mconf_readme[] = N_(
26"Overview\n" 26"Overview\n"
27"--------\n" 27"--------\n"
28"Some kernel features may be built directly into the kernel.\n" 28"This interface let you select features and parameters for the build.\n"
29"Some may be made into loadable runtime modules. Some features\n" 29"Features can either be built-in, modularized, or ignored. Parameters\n"
30"may be completely removed altogether. There are also certain\n" 30"must be entered in as decimal or hexadecimal numbers or text.\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"
33"\n" 31"\n"
34"Menu items beginning with following braces represent features that\n" 32"Menu items beginning with following braces represent features that\n"
35" [ ] can be built in or removed\n" 33" [ ] can be built in or removed\n"
@@ -117,7 +115,7 @@ static const char mconf_readme[] = N_(
117"-----------------------------\n" 115"-----------------------------\n"
118"Menuconfig supports the use of alternate configuration files for\n" 116"Menuconfig supports the use of alternate configuration files for\n"
119"those who, for various reasons, find it necessary to switch\n" 117"those who, for various reasons, find it necessary to switch\n"
120"between different kernel configurations.\n" 118"between different configurations.\n"
121"\n" 119"\n"
122"At the end of the main menu you will find two options. One is\n" 120"At the end of the main menu you will find two options. One is\n"
123"for saving the current configuration to a file of your choosing.\n" 121"for saving the current configuration to a file of your choosing.\n"
@@ -150,9 +148,9 @@ static const char mconf_readme[] = N_(
150"\n" 148"\n"
151"Optional personality available\n" 149"Optional personality available\n"
152"------------------------------\n" 150"------------------------------\n"
153"If you prefer to have all of the kernel options listed in a single\n" 151"If you prefer to have all of the options listed in a single menu, rather\n"
154"menu, rather than the default multimenu hierarchy, run the menuconfig\n" 152"than the default multimenu hierarchy, run the menuconfig with\n"
155"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" 153"MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
156"\n" 154"\n"
157"make MENUCONFIG_MODE=single_menu menuconfig\n" 155"make MENUCONFIG_MODE=single_menu menuconfig\n"
158"\n" 156"\n"
@@ -207,12 +205,12 @@ load_config_text[] = N_(
207 "last retrieved. Leave blank to abort."), 205 "last retrieved. Leave blank to abort."),
208load_config_help[] = N_( 206load_config_help[] = N_(
209 "\n" 207 "\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"
211 "configurations available on a single machine.\n" 209 "configurations available on a single machine.\n"
212 "\n" 210 "\n"
213 "If you have saved a previous configuration in a file other than the\n" 211 "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" 212 "default one, entering its name here will allow you to modify that\n"
215 "to modify that configuration.\n" 213 "configuration.\n"
216 "\n" 214 "\n"
217 "If you are uncertain, then you have probably never used alternate\n" 215 "If you are uncertain, then you have probably never used alternate\n"
218 "configuration files. You should therefore leave this blank to abort.\n"), 216 "configuration files. You should therefore leave this blank to abort.\n"),
@@ -221,8 +219,8 @@ save_config_text[] = N_(
221 "as an alternate. Leave blank to abort."), 219 "as an alternate. Leave blank to abort."),
222save_config_help[] = N_( 220save_config_help[] = N_(
223 "\n" 221 "\n"
224 "For various reasons, one may wish to keep different kernel\n" 222 "For various reasons, one may wish to keep different configurations\n"
225 "configurations available on a single machine.\n" 223 "available on a single machine.\n"
226 "\n" 224 "\n"
227 "Entering a file name here will allow you to later retrieve, modify\n" 225 "Entering a file name here will allow you to later retrieve, modify\n"
228 "and use the current configuration as an alternate to whatever\n" 226 "and use the current configuration as an alternate to whatever\n"
@@ -232,7 +230,7 @@ save_config_help[] = N_(
232 "leave this blank.\n"), 230 "leave this blank.\n"),
233search_help[] = N_( 231search_help[] = N_(
234 "\n" 232 "\n"
235 "Search for CONFIG_ symbols and display their relations.\n" 233 "Search for symbols and display their relations.\n"
236 "Regular expressions are allowed.\n" 234 "Regular expressions are allowed.\n"
237 "Example: search for \"^FOO\"\n" 235 "Example: search for \"^FOO\"\n"
238 "Result:\n" 236 "Result:\n"
@@ -249,7 +247,7 @@ search_help[] = N_(
249 "Selected by: BAR\n" 247 "Selected by: BAR\n"
250 "-----------------------------------------------------------------\n" 248 "-----------------------------------------------------------------\n"
251 "o The line 'Prompt:' shows the text used in the menu structure for\n" 249 "o The line 'Prompt:' shows the text used in the menu structure for\n"
252 " this CONFIG_ symbol\n" 250 " this symbol\n"
253 "o The 'Defined at' line tell at what file / line number the symbol\n" 251 "o The 'Defined at' line tell at what file / line number the symbol\n"
254 " is defined\n" 252 " is defined\n"
255 "o The 'Depends on:' line tell what symbols needs to be defined for\n" 253 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
@@ -265,9 +263,9 @@ search_help[] = N_(
265 "Only relevant lines are shown.\n" 263 "Only relevant lines are shown.\n"
266 "\n\n" 264 "\n\n"
267 "Search examples:\n" 265 "Search examples:\n"
268 "Examples: USB => find all CONFIG_ symbols containing USB\n" 266 "Examples: USB => find all symbols containing USB\n"
269 " ^USB => find all CONFIG_ symbols starting with USB\n" 267 " ^USB => find all symbols starting with USB\n"
270 " USB$ => find all CONFIG_ symbols ending with USB\n" 268 " USB$ => find all symbols ending with USB\n"
271 "\n"); 269 "\n");
272 270
273static int indent; 271static int indent;
@@ -290,13 +288,9 @@ static void set_config_filename(const char *config_filename)
290{ 288{
291 static char menu_backtitle[PATH_MAX+128]; 289 static char menu_backtitle[PATH_MAX+128];
292 int size; 290 int size;
293 struct symbol *sym;
294 291
295 sym = sym_lookup("KERNELVERSION", 0);
296 sym_calc_value(sym);
297 size = snprintf(menu_backtitle, sizeof(menu_backtitle), 292 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
298 _("%s - Linux Kernel v%s Configuration"), 293 "%s - %s", config_filename, rootmenu.prompt->text);
299 config_filename, sym_get_string_value(sym));
300 if (size >= sizeof(menu_backtitle)) 294 if (size >= sizeof(menu_backtitle))
301 menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; 295 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
302 set_dialog_backtitle(menu_backtitle); 296 set_dialog_backtitle(menu_backtitle);
@@ -316,8 +310,8 @@ static void search_conf(void)
316again: 310again:
317 dialog_clear(); 311 dialog_clear();
318 dres = dialog_inputbox(_("Search Configuration Parameter"), 312 dres = dialog_inputbox(_("Search Configuration Parameter"),
319 _("Enter CONFIG_ (sub)string to search for " 313 _("Enter " CONFIG_ " (sub)string to search for "
320 "(with or without \"CONFIG\")"), 314 "(with or without \"" CONFIG_ "\")"),
321 10, 75, ""); 315 10, 75, "");
322 switch (dres) { 316 switch (dres) {
323 case 0: 317 case 0:
@@ -329,10 +323,10 @@ again:
329 return; 323 return;
330 } 324 }
331 325
332 /* strip CONFIG_ if necessary */ 326 /* strip the prefix if necessary */
333 dialog_input = dialog_input_result; 327 dialog_input = dialog_input_result;
334 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) 328 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
335 dialog_input += 7; 329 dialog_input += strlen(CONFIG_);
336 330
337 sym_arr = sym_re_search(dialog_input); 331 sym_arr = sym_re_search(dialog_input);
338 res = get_relations_str(sym_arr); 332 res = get_relations_str(sym_arr);
@@ -834,7 +828,7 @@ int main(int ac, char **av)
834 if (conf_get_changed()) 828 if (conf_get_changed())
835 res = dialog_yesno(NULL, 829 res = dialog_yesno(NULL,
836 _("Do you wish to save your " 830 _("Do you wish to save your "
837 "new kernel configuration?\n" 831 "new configuration?\n"
838 "<ESC><ESC> to continue."), 832 "<ESC><ESC> to continue."),
839 6, 60); 833 6, 60);
840 else 834 else
@@ -846,20 +840,20 @@ int main(int ac, char **av)
846 case 0: 840 case 0:
847 if (conf_write(filename)) { 841 if (conf_write(filename)) {
848 fprintf(stderr, _("\n\n" 842 fprintf(stderr, _("\n\n"
849 "Error during writing of the kernel configuration.\n" 843 "Error while writing of the configuration.\n"
850 "Your kernel configuration changes were NOT saved." 844 "Your configuration changes were NOT saved."
851 "\n\n")); 845 "\n\n"));
852 return 1; 846 return 1;
853 } 847 }
854 case -1: 848 case -1:
855 printf(_("\n\n" 849 printf(_("\n\n"
856 "*** End of Linux kernel configuration.\n" 850 "*** End of the configuration.\n"
857 "*** Execute 'make' to build the kernel or try 'make help'." 851 "*** Execute 'make' to start the build or try 'make help'."
858 "\n\n")); 852 "\n\n"));
859 break; 853 break;
860 default: 854 default:
861 fprintf(stderr, _("\n\n" 855 fprintf(stderr, _("\n\n"
862 "Your kernel configuration changes were NOT saved." 856 "Your configuration changes were NOT saved."
863 "\n\n")); 857 "\n\n"));
864 } 858 }
865 859
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 4fb590247f33..b9d9aa18e6d6 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -10,7 +10,7 @@
10#include "lkc.h" 10#include "lkc.h"
11 11
12static const char nohelp_text[] = N_( 12static 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");
14 14
15struct menu rootmenu; 15struct menu rootmenu;
16static struct menu **last_entry_ptr; 16static struct menu **last_entry_ptr;
@@ -107,7 +107,6 @@ static struct expr *menu_check_dep(struct expr *e)
107void menu_add_dep(struct expr *dep) 107void menu_add_dep(struct expr *dep)
108{ 108{
109 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); 109 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
110 current_entry->dir_dep = current_entry->dep;
111} 110}
112 111
113void menu_set_type(int type) 112void menu_set_type(int type)
@@ -139,7 +138,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
139 while (isspace(*prompt)) 138 while (isspace(*prompt))
140 prompt++; 139 prompt++;
141 } 140 }
142 if (current_entry->prompt) 141 if (current_entry->prompt && current_entry != &rootmenu)
143 prop_warn(prop, "prompt redefined"); 142 prop_warn(prop, "prompt redefined");
144 current_entry->prompt = prop; 143 current_entry->prompt = prop;
145 } 144 }
@@ -153,6 +152,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
153 return menu_add_prop(type, prompt, NULL, dep); 152 return menu_add_prop(type, prompt, NULL, dep);
154} 153}
155 154
155void menu_add_visibility(struct expr *expr)
156{
157 current_entry->visibility = expr_alloc_and(current_entry->visibility,
158 expr);
159}
160
156void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) 161void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
157{ 162{
158 menu_add_prop(type, NULL, expr, dep); 163 menu_add_prop(type, NULL, expr, dep);
@@ -291,10 +296,6 @@ void menu_finalize(struct menu *parent)
291 for (menu = parent->list; menu; menu = menu->next) 296 for (menu = parent->list; menu; menu = menu->next)
292 menu_finalize(menu); 297 menu_finalize(menu);
293 } else if (sym) { 298 } else if (sym) {
294 /* ignore inherited dependencies for dir_dep */
295 sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
296 sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
297
298 basedep = parent->prompt ? parent->prompt->visible.expr : NULL; 299 basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
299 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); 300 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
300 basedep = expr_eliminate_dups(expr_transform(basedep)); 301 basedep = expr_eliminate_dups(expr_transform(basedep));
@@ -325,6 +326,8 @@ void menu_finalize(struct menu *parent)
325 parent->next = last_menu->next; 326 parent->next = last_menu->next;
326 last_menu->next = NULL; 327 last_menu->next = NULL;
327 } 328 }
329
330 sym->dir_dep.expr = parent->dep;
328 } 331 }
329 for (menu = parent->list; menu; menu = menu->next) { 332 for (menu = parent->list; menu; menu = menu->next) {
330 if (sym && sym_is_choice(sym) && 333 if (sym && sym_is_choice(sym) &&
@@ -413,6 +416,11 @@ bool menu_is_visible(struct menu *menu)
413 if (!menu->prompt) 416 if (!menu->prompt)
414 return false; 417 return false;
415 418
419 if (menu->visibility) {
420 if (expr_calc_value(menu->visibility) == no)
421 return no;
422 }
423
416 sym = menu->sym; 424 sym = menu->sym;
417 if (sym) { 425 if (sym) {
418 sym_calc_value(sym); 426 sym_calc_value(sym);
@@ -566,7 +574,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
566 574
567 if (menu_has_help(menu)) { 575 if (menu_has_help(menu)) {
568 if (sym->name) { 576 if (sym->name) {
569 str_printf(help, "CONFIG_%s:\n\n", sym->name); 577 str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
570 str_append(help, _(menu_get_help(menu))); 578 str_append(help, _(menu_get_help(menu)));
571 str_append(help, "\n"); 579 str_append(help, "\n");
572 } 580 }
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 762caf80ce37..272a987f23e0 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -5,25 +5,26 @@
5 * Derived from menuconfig. 5 * Derived from menuconfig.
6 * 6 *
7 */ 7 */
8#define _GNU_SOURCE
9#include <string.h>
8#define LKC_DIRECT_LINK 10#define LKC_DIRECT_LINK
9#include "lkc.h" 11#include "lkc.h"
10#include "nconf.h" 12#include "nconf.h"
13#include <ctype.h>
11 14
12static const char nconf_readme[] = N_( 15static const char nconf_readme[] = N_(
13"Overview\n" 16"Overview\n"
14"--------\n" 17"--------\n"
15"Some kernel features may be built directly into the kernel.\n" 18"This interface let you select features and parameters for the build.\n"
16"Some may be made into loadable runtime modules. Some features\n" 19"Features can either be built-in, modularized, or ignored. Parameters\n"
17"may be completely removed altogether. There are also certain\n" 20"must be entered in as decimal or hexadecimal numbers or text.\n"
18"kernel parameters which are not really features, but must be\n"
19"entered in as decimal or hexadecimal numbers or possibly text.\n"
20"\n" 21"\n"
21"Menu items beginning with following braces represent features that\n" 22"Menu items beginning with following braces represent features that\n"
22" [ ] can be built in or removed\n" 23" [ ] can be built in or removed\n"
23" < > can be built in, modularized or removed\n" 24" < > can be built in, modularized or removed\n"
24" { } can be built in or modularized (selected by other feature)\n" 25" { } can be built in or modularized (selected by other feature)\n"
25" - - are selected by other feature,\n" 26" - - 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"
27"while *, M or whitespace inside braces means to build in, build as\n" 28"while *, M or whitespace inside braces means to build in, build as\n"
28"a module or to exclude the feature respectively.\n" 29"a module or to exclude the feature respectively.\n"
29"\n" 30"\n"
@@ -41,9 +42,13 @@ static const char nconf_readme[] = N_(
41" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" 42" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
42" Submenus are designated by \"--->\".\n" 43" Submenus are designated by \"--->\".\n"
43"\n" 44"\n"
44" Shortcut: Press the option's highlighted letter (hotkey).\n" 45" Searching: pressing '/' triggers interactive search mode.\n"
45" Pressing a hotkey more than once will sequence\n" 46" nconfig performs a case insensitive search for the string\n"
46" through all visible items which use that hotkey.\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"
47"\n" 52"\n"
48" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" 53" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
49" unseen options into view.\n" 54" unseen options into view.\n"
@@ -88,7 +93,7 @@ static const char nconf_readme[] = N_(
88"-----------------------------\n" 93"-----------------------------\n"
89"nconfig supports the use of alternate configuration files for\n" 94"nconfig supports the use of alternate configuration files for\n"
90"those who, for various reasons, find it necessary to switch\n" 95"those who, for various reasons, find it necessary to switch\n"
91"between different kernel configurations.\n" 96"between different configurations.\n"
92"\n" 97"\n"
93"At the end of the main menu you will find two options. One is\n" 98"At the end of the main menu you will find two options. One is\n"
94"for saving the current configuration to a file of your choosing.\n" 99"for saving the current configuration to a file of your choosing.\n"
@@ -121,9 +126,9 @@ static const char nconf_readme[] = N_(
121"\n" 126"\n"
122"Optional personality available\n" 127"Optional personality available\n"
123"------------------------------\n" 128"------------------------------\n"
124"If you prefer to have all of the kernel options listed in a single\n" 129"If you prefer to have all of the options listed in a single menu, rather\n"
125"menu, rather than the default multimenu hierarchy, run the nconfig\n" 130"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
126"with NCONFIG_MODE environment variable set to single_menu. Example:\n" 131"environment variable set to single_menu. Example:\n"
127"\n" 132"\n"
128"make NCONFIG_MODE=single_menu nconfig\n" 133"make NCONFIG_MODE=single_menu nconfig\n"
129"\n" 134"\n"
@@ -141,21 +146,21 @@ menu_no_f_instructions[] = N_(
141" <Enter> or <right-arrow> selects submenus --->.\n" 146" <Enter> or <right-arrow> selects submenus --->.\n"
142" Capital Letters are hotkeys.\n" 147" Capital Letters are hotkeys.\n"
143" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 148" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
144" Pressing SpaceBar toggles between the above options\n" 149" Pressing SpaceBar toggles between the above options.\n"
145" Press <Esc> or <left-arrow> to go back one menu, \n" 150" Press <Esc> or <left-arrow> to go back one menu,\n"
146" <?> or <h> for Help, </> for Search.\n" 151" <?> 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"
148" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 153" 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"),
150menu_instructions[] = N_( 155menu_instructions[] = N_(
151" Arrow keys navigate the menu.\n" 156" Arrow keys navigate the menu.\n"
152" <Enter> or <right-arrow> selects submenus --->.\n" 157" <Enter> or <right-arrow> selects submenus --->.\n"
153" Capital Letters are hotkeys.\n" 158" Capital Letters are hotkeys.\n"
154" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 159" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
155" Pressing SpaceBar toggles between the above options\n" 160" 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"
157" <?>, <F1> or <h> for Help, </> for Search.\n" 162" <?>, <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"
159" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 164" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
160" <Esc> always leaves the current window\n"), 165" <Esc> always leaves the current window\n"),
161radiolist_instructions[] = N_( 166radiolist_instructions[] = N_(
@@ -178,19 +183,19 @@ setmod_text[] = N_(
178"has been configured as a module.\n" 183"has been configured as a module.\n"
179"As a result, this feature will be built as a module."), 184"As a result, this feature will be built as a module."),
180nohelp_text[] = N_( 185nohelp_text[] = N_(
181"There is no help available for this kernel option.\n"), 186"There is no help available for this option.\n"),
182load_config_text[] = N_( 187load_config_text[] = N_(
183"Enter the name of the configuration file you wish to load.\n" 188"Enter the name of the configuration file you wish to load.\n"
184"Accept the name shown to restore the configuration you\n" 189"Accept the name shown to restore the configuration you\n"
185"last retrieved. Leave blank to abort."), 190"last retrieved. Leave blank to abort."),
186load_config_help[] = N_( 191load_config_help[] = N_(
187"\n" 192"\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"
189"configurations available on a single machine.\n" 194"configurations available on a single machine.\n"
190"\n" 195"\n"
191"If you have saved a previous configuration in a file other than the\n" 196"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" 197"default one, entering its name here will allow you to modify that\n"
193"to modify that configuration.\n" 198"configuration.\n"
194"\n" 199"\n"
195"If you are uncertain, then you have probably never used alternate\n" 200"If you are uncertain, then you have probably never used alternate\n"
196"configuration files. You should therefor leave this blank to abort.\n"), 201"configuration files. You should therefor leave this blank to abort.\n"),
@@ -199,8 +204,8 @@ save_config_text[] = N_(
199"as an alternate. Leave blank to abort."), 204"as an alternate. Leave blank to abort."),
200save_config_help[] = N_( 205save_config_help[] = N_(
201"\n" 206"\n"
202"For various reasons, one may wish to keep different kernel\n" 207"For various reasons, one may wish to keep different configurations\n"
203"configurations available on a single machine.\n" 208"available on a single machine.\n"
204"\n" 209"\n"
205"Entering a file name here will allow you to later retrieve, modify\n" 210"Entering a file name here will allow you to later retrieve, modify\n"
206"and use the current configuration as an alternate to whatever\n" 211"and use the current configuration as an alternate to whatever\n"
@@ -210,8 +215,8 @@ save_config_help[] = N_(
210"leave this blank.\n"), 215"leave this blank.\n"),
211search_help[] = N_( 216search_help[] = N_(
212"\n" 217"\n"
213"Search for CONFIG_ symbols and display their relations.\n" 218"Search for symbols and display their relations. Regular expressions\n"
214"Regular expressions are allowed.\n" 219"are allowed.\n"
215"Example: search for \"^FOO\"\n" 220"Example: search for \"^FOO\"\n"
216"Result:\n" 221"Result:\n"
217"-----------------------------------------------------------------\n" 222"-----------------------------------------------------------------\n"
@@ -227,7 +232,7 @@ search_help[] = N_(
227"Selected by: BAR\n" 232"Selected by: BAR\n"
228"-----------------------------------------------------------------\n" 233"-----------------------------------------------------------------\n"
229"o The line 'Prompt:' shows the text used in the menu structure for\n" 234"o The line 'Prompt:' shows the text used in the menu structure for\n"
230" this CONFIG_ symbol\n" 235" this symbol\n"
231"o The 'Defined at' line tell at what file / line number the symbol\n" 236"o The 'Defined at' line tell at what file / line number the symbol\n"
232" is defined\n" 237" is defined\n"
233"o The 'Depends on:' line tell what symbols needs to be defined for\n" 238"o The 'Depends on:' line tell what symbols needs to be defined for\n"
@@ -243,16 +248,15 @@ search_help[] = N_(
243"Only relevant lines are shown.\n" 248"Only relevant lines are shown.\n"
244"\n\n" 249"\n\n"
245"Search examples:\n" 250"Search examples:\n"
246"Examples: USB = > find all CONFIG_ symbols containing USB\n" 251"Examples: USB = > find all symbols containing USB\n"
247" ^USB => find all CONFIG_ symbols starting with USB\n" 252" ^USB => find all symbols starting with USB\n"
248" USB$ => find all CONFIG_ symbols ending with USB\n" 253" USB$ => find all symbols ending with USB\n"
249"\n"); 254"\n");
250 255
251struct mitem { 256struct mitem {
252 char str[256]; 257 char str[256];
253 char tag; 258 char tag;
254 void *usrptr; 259 void *usrptr;
255 int is_hot;
256 int is_visible; 260 int is_visible;
257}; 261};
258 262
@@ -275,14 +279,6 @@ static int items_num;
275static int global_exit; 279static int global_exit;
276/* the currently selected button */ 280/* the currently selected button */
277const char *current_instructions = menu_instructions; 281const char *current_instructions = menu_instructions;
278/* this array is used to implement hot keys. it is updated in item_make and
279 * resetted in clean_items. It would be better to use a hash, but lets keep it
280 * simple... */
281#define MAX_SAME_KEY MAX_MENU_ITEMS
282struct {
283 int count;
284 int ptrs[MAX_MENU_ITEMS];
285} hotkeys[1<<(sizeof(char)*8)];
286 282
287static void conf(struct menu *menu); 283static void conf(struct menu *menu);
288static void conf_choice(struct menu *menu); 284static void conf_choice(struct menu *menu);
@@ -292,6 +288,7 @@ static void conf_save(void);
292static void show_help(struct menu *menu); 288static void show_help(struct menu *menu);
293static int do_exit(void); 289static int do_exit(void);
294static void setup_windows(void); 290static void setup_windows(void);
291static void search_conf(void);
295 292
296typedef void (*function_key_handler_t)(int *key, struct menu *menu); 293typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297static void handle_f1(int *key, struct menu *current_item); 294static void handle_f1(int *key, struct menu *current_item);
@@ -302,6 +299,7 @@ static void handle_f5(int *key, struct menu *current_item);
302static void handle_f6(int *key, struct menu *current_item); 299static void handle_f6(int *key, struct menu *current_item);
303static void handle_f7(int *key, struct menu *current_item); 300static void handle_f7(int *key, struct menu *current_item);
304static void handle_f8(int *key, struct menu *current_item); 301static void handle_f8(int *key, struct menu *current_item);
302static void handle_f9(int *key, struct menu *current_item);
305 303
306struct function_keys { 304struct function_keys {
307 const char *key_str; 305 const char *key_str;
@@ -310,7 +308,7 @@ struct function_keys {
310 function_key_handler_t handler; 308 function_key_handler_t handler;
311}; 309};
312 310
313static const int function_keys_num = 8; 311static const int function_keys_num = 9;
314struct function_keys function_keys[] = { 312struct function_keys function_keys[] = {
315 { 313 {
316 .key_str = "F1", 314 .key_str = "F1",
@@ -320,13 +318,13 @@ struct function_keys function_keys[] = {
320 }, 318 },
321 { 319 {
322 .key_str = "F2", 320 .key_str = "F2",
323 .func = "Symbol Info", 321 .func = "Sym Info",
324 .key = F_SYMBOL, 322 .key = F_SYMBOL,
325 .handler = handle_f2, 323 .handler = handle_f2,
326 }, 324 },
327 { 325 {
328 .key_str = "F3", 326 .key_str = "F3",
329 .func = "Instructions", 327 .func = "Insts",
330 .key = F_INSTS, 328 .key = F_INSTS,
331 .handler = handle_f3, 329 .handler = handle_f3,
332 }, 330 },
@@ -356,9 +354,15 @@ struct function_keys function_keys[] = {
356 }, 354 },
357 { 355 {
358 .key_str = "F8", 356 .key_str = "F8",
357 .func = "Sym Search",
358 .key = F_SEARCH,
359 .handler = handle_f8,
360 },
361 {
362 .key_str = "F9",
359 .func = "Exit", 363 .func = "Exit",
360 .key = F_EXIT, 364 .key = F_EXIT,
361 .handler = handle_f8, 365 .handler = handle_f9,
362 }, 366 },
363}; 367};
364 368
@@ -444,9 +448,16 @@ static void handle_f7(int *key, struct menu *current_item)
444 return; 448 return;
445} 449}
446 450
447/* exit */ 451/* search */
448static void handle_f8(int *key, struct menu *current_item) 452static void handle_f8(int *key, struct menu *current_item)
449{ 453{
454 search_conf();
455 return;
456}
457
458/* exit */
459static void handle_f9(int *key, struct menu *current_item)
460{
450 do_exit(); 461 do_exit();
451 return; 462 return;
452} 463}
@@ -479,110 +490,44 @@ static void clean_items(void)
479 free_item(curses_menu_items[i]); 490 free_item(curses_menu_items[i]);
480 bzero(curses_menu_items, sizeof(curses_menu_items)); 491 bzero(curses_menu_items, sizeof(curses_menu_items));
481 bzero(k_menu_items, sizeof(k_menu_items)); 492 bzero(k_menu_items, sizeof(k_menu_items));
482 bzero(hotkeys, sizeof(hotkeys));
483 items_num = 0; 493 items_num = 0;
484} 494}
485 495
486/* return the index of the next hot item, or -1 if no such item exists */ 496typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
487static int get_next_hot(int c) 497 FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
488{
489 static int hot_index;
490 static int hot_char;
491
492 if (c < 0 || c > 255 || hotkeys[c].count <= 0)
493 return -1;
494
495 if (hot_char == c) {
496 hot_index = (hot_index+1)%hotkeys[c].count;
497 return hotkeys[c].ptrs[hot_index];
498 } else {
499 hot_char = c;
500 hot_index = 0;
501 return hotkeys[c].ptrs[0];
502 }
503}
504
505/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
506static int canbhot(char c)
507{
508 c = tolower(c);
509 return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
510 c != 'n' && c != '?';
511}
512
513/* check if str already contains a hot key. */
514static int is_hot(int index)
515{
516 return k_menu_items[index].is_hot;
517}
518 498
519/* find the first possible hot key, and mark it. 499/* return the index of the matched item, or -1 if no such item exists */
520 * index is the index of the item in the menu 500static int get_mext_match(const char *match_str, match_f flag)
521 * return 0 on success*/
522static int make_hot(char *dest, int len, const char *org, int index)
523{ 501{
524 int position = -1; 502 int match_start = item_index(current_item(curses_menu));
525 int i; 503 int index;
526 int tmp; 504
527 int c; 505 if (flag == FIND_NEXT_MATCH_DOWN)
528 int org_len = strlen(org); 506 ++match_start;
529 507 else if (flag == FIND_NEXT_MATCH_UP)
530 if (org == NULL || is_hot(index)) 508 --match_start;
531 return 1; 509
532 510 index = match_start;
533 /* make sure not to make hot keys out of markers. 511 index = (index + items_num) % items_num;
534 * find where to start looking for a hot key 512 while (true) {
535 */ 513 char *str = k_menu_items[index].str;
536 i = 0; 514 if (strcasestr(str, match_str) != 0)
537 /* skip white space */ 515 return index;
538 while (i < org_len && org[i] == ' ') 516 if (flag == FIND_NEXT_MATCH_UP ||
539 i++; 517 flag == MATCH_TINKER_PATTERN_UP)
540 if (i == org_len) 518 --index;
541 return -1; 519 else
542 /* if encountering '(' or '<' or '[', find the match and look from there 520 ++index;
543 **/ 521 index = (index + items_num) % items_num;
544 if (org[i] == '[' || org[i] == '<' || org[i] == '(') { 522 if (index == match_start)
545 i++; 523 return -1;
546 for (; i < org_len; i++)
547 if (org[i] == ']' || org[i] == '>' || org[i] == ')')
548 break;
549 }
550 if (i == org_len)
551 return -1;
552 for (; i < org_len; i++) {
553 if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
554 position = i;
555 break;
556 }
557 } 524 }
558 if (position == -1)
559 return 1;
560
561 /* ok, char at org[position] should be a hot key to this item */
562 c = tolower(org[position]);
563 tmp = hotkeys[c].count;
564 hotkeys[c].ptrs[tmp] = index;
565 hotkeys[c].count++;
566 /*
567 snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
568 &org[position+1]);
569 */
570 /* make org[position] uppercase, and all leading letter small case */
571 strncpy(dest, org, len);
572 for (i = 0; i < position; i++)
573 dest[i] = tolower(dest[i]);
574 dest[position] = toupper(dest[position]);
575 k_menu_items[index].is_hot = 1;
576 return 0;
577} 525}
578 526
579/* Make a new item. Add a hotkey mark in the first possible letter. 527/* Make a new item. */
580 * As ncurses does not allow any attributes inside menue item, we mark the
581 * hot key as the first capitalized letter in the string */
582static void item_make(struct menu *menu, char tag, const char *fmt, ...) 528static void item_make(struct menu *menu, char tag, const char *fmt, ...)
583{ 529{
584 va_list ap; 530 va_list ap;
585 char tmp_str[256];
586 531
587 if (items_num > MAX_MENU_ITEMS-1) 532 if (items_num > MAX_MENU_ITEMS-1)
588 return; 533 return;
@@ -597,16 +542,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...)
597 k_menu_items[items_num].is_visible = 1; 542 k_menu_items[items_num].is_visible = 1;
598 543
599 va_start(ap, fmt); 544 va_start(ap, fmt);
600 vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); 545 vsnprintf(k_menu_items[items_num].str,
601 if (!k_menu_items[items_num].is_visible) 546 sizeof(k_menu_items[items_num].str),
602 memcpy(tmp_str, "XXX", 3); 547 fmt, ap);
603 va_end(ap); 548 va_end(ap);
604 if (make_hot( 549
605 k_menu_items[items_num].str, 550 if (!k_menu_items[items_num].is_visible)
606 sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) 551 memcpy(k_menu_items[items_num].str, "XXX", 3);
607 strncpy(k_menu_items[items_num].str,
608 tmp_str,
609 sizeof(k_menu_items[items_num].str));
610 552
611 curses_menu_items[items_num] = new_item( 553 curses_menu_items[items_num] = new_item(
612 k_menu_items[items_num].str, 554 k_menu_items[items_num].str,
@@ -638,11 +580,9 @@ static void item_add_str(const char *fmt, ...)
638 va_end(ap); 580 va_end(ap);
639 snprintf(tmp_str, sizeof(tmp_str), "%s%s", 581 snprintf(tmp_str, sizeof(tmp_str), "%s%s",
640 k_menu_items[index].str, new_str); 582 k_menu_items[index].str, new_str);
641 if (make_hot(k_menu_items[index].str, 583 strncpy(k_menu_items[index].str,
642 sizeof(k_menu_items[index].str), tmp_str, index) != 0) 584 tmp_str,
643 strncpy(k_menu_items[index].str, 585 sizeof(k_menu_items[index].str));
644 tmp_str,
645 sizeof(k_menu_items[index].str));
646 586
647 free_item(curses_menu_items[index]); 587 free_item(curses_menu_items[index]);
648 curses_menu_items[index] = new_item( 588 curses_menu_items[index] = new_item(
@@ -676,6 +616,8 @@ static void *item_data(void)
676 struct mitem *mcur; 616 struct mitem *mcur;
677 617
678 cur = current_item(curses_menu); 618 cur = current_item(curses_menu);
619 if (!cur)
620 return NULL;
679 mcur = (struct mitem *) item_userptr(cur); 621 mcur = (struct mitem *) item_userptr(cur);
680 return mcur->usrptr; 622 return mcur->usrptr;
681 623
@@ -691,13 +633,9 @@ static char menu_backtitle[PATH_MAX+128];
691static const char *set_config_filename(const char *config_filename) 633static const char *set_config_filename(const char *config_filename)
692{ 634{
693 int size; 635 int size;
694 struct symbol *sym;
695 636
696 sym = sym_lookup("KERNELVERSION", 0);
697 sym_calc_value(sym);
698 size = snprintf(menu_backtitle, sizeof(menu_backtitle), 637 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
699 _("%s - Linux Kernel v%s Configuration"), 638 "%s - %s", config_filename, rootmenu.prompt->text);
700 config_filename, sym_get_string_value(sym));
701 if (size >= sizeof(menu_backtitle)) 639 if (size >= sizeof(menu_backtitle))
702 menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; 640 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
703 641
@@ -707,25 +645,6 @@ static const char *set_config_filename(const char *config_filename)
707 return menu_backtitle; 645 return menu_backtitle;
708} 646}
709 647
710/* command = 0 is supress, 1 is restore */
711static void supress_stdout(int command)
712{
713 static FILE *org_stdout;
714 static FILE *org_stderr;
715
716 if (command == 0) {
717 org_stdout = stdout;
718 org_stderr = stderr;
719 stdout = fopen("/dev/null", "a");
720 stderr = fopen("/dev/null", "a");
721 } else {
722 fclose(stdout);
723 fclose(stderr);
724 stdout = org_stdout;
725 stderr = org_stderr;
726 }
727}
728
729/* return = 0 means we are successful. 648/* return = 0 means we are successful.
730 * -1 means go on doing what you were doing 649 * -1 means go on doing what you were doing
731 */ 650 */
@@ -737,8 +656,7 @@ static int do_exit(void)
737 return 0; 656 return 0;
738 } 657 }
739 res = btn_dialog(main_window, 658 res = btn_dialog(main_window,
740 _("Do you wish to save your " 659 _("Do you wish to save your new configuration?\n"
741 "new kernel configuration?\n"
742 "<ESC> to cancel and resume nconfig."), 660 "<ESC> to cancel and resume nconfig."),
743 2, 661 2,
744 " <save> ", 662 " <save> ",
@@ -751,36 +669,19 @@ static int do_exit(void)
751 /* if we got here, the user really wants to exit */ 669 /* if we got here, the user really wants to exit */
752 switch (res) { 670 switch (res) {
753 case 0: 671 case 0:
754 supress_stdout(0);
755 res = conf_write(filename); 672 res = conf_write(filename);
756 supress_stdout(1);
757 if (res) 673 if (res)
758 btn_dialog( 674 btn_dialog(
759 main_window, 675 main_window,
760 _("Error during writing of the kernel " 676 _("Error during writing of configuration.\n"
761 "configuration.\n" 677 "Your configuration changes were NOT saved."),
762 "Your kernel configuration "
763 "changes were NOT saved."),
764 1, 678 1,
765 "<OK>"); 679 "<OK>");
766 else {
767 char buf[1024];
768 snprintf(buf, 1024,
769 _("Configuration written to %s\n"
770 "End of Linux kernel configuration.\n"
771 "Execute 'make' to build the kernel or try"
772 " 'make help'."), filename);
773 btn_dialog(
774 main_window,
775 buf,
776 1,
777 "<OK>");
778 }
779 break; 680 break;
780 default: 681 default:
781 btn_dialog( 682 btn_dialog(
782 main_window, 683 main_window,
783 _("Your kernel configuration changes were NOT saved."), 684 _("Your configuration changes were NOT saved."),
784 1, 685 1,
785 "<OK>"); 686 "<OK>");
786 break; 687 break;
@@ -800,8 +701,8 @@ static void search_conf(void)
800again: 701again:
801 dres = dialog_inputbox(main_window, 702 dres = dialog_inputbox(main_window,
802 _("Search Configuration Parameter"), 703 _("Search Configuration Parameter"),
803 _("Enter CONFIG_ (sub)string to search for " 704 _("Enter " CONFIG_ " (sub)string to search for "
804 "(with or without \"CONFIG\")"), 705 "(with or without \"" CONFIG_ "\")"),
805 "", dialog_input_result, 99); 706 "", dialog_input_result, 99);
806 switch (dres) { 707 switch (dres) {
807 case 0: 708 case 0:
@@ -814,10 +715,10 @@ again:
814 return; 715 return;
815 } 716 }
816 717
817 /* strip CONFIG_ if necessary */ 718 /* strip the prefix if necessary */
818 dialog_input = dialog_input_result; 719 dialog_input = dialog_input_result;
819 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) 720 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
820 dialog_input += 7; 721 dialog_input += strlen(CONFIG_);
821 722
822 sym_arr = sym_re_search(dialog_input); 723 sym_arr = sym_re_search(dialog_input);
823 res = get_relations_str(sym_arr); 724 res = get_relations_str(sym_arr);
@@ -1025,23 +926,18 @@ static void reset_menu(void)
1025static void center_item(int selected_index, int *last_top_row) 926static void center_item(int selected_index, int *last_top_row)
1026{ 927{
1027 int toprow; 928 int toprow;
1028 int maxy, maxx;
1029 929
1030 scale_menu(curses_menu, &maxy, &maxx);
1031 set_top_row(curses_menu, *last_top_row); 930 set_top_row(curses_menu, *last_top_row);
1032 toprow = top_row(curses_menu); 931 toprow = top_row(curses_menu);
1033 if (selected_index >= toprow && selected_index < toprow+maxy) { 932 if (selected_index < toprow ||
1034 /* we can only move the selected item. no need to scroll */ 933 selected_index >= toprow+mwin_max_lines) {
1035 set_current_item(curses_menu, 934 toprow = max(selected_index-mwin_max_lines/2, 0);
1036 curses_menu_items[selected_index]); 935 if (toprow >= item_count(curses_menu)-mwin_max_lines)
1037 } else {
1038 toprow = max(selected_index-maxy/2, 0);
1039 if (toprow >= item_count(curses_menu)-maxy)
1040 toprow = item_count(curses_menu)-mwin_max_lines; 936 toprow = item_count(curses_menu)-mwin_max_lines;
1041 set_top_row(curses_menu, toprow); 937 set_top_row(curses_menu, toprow);
1042 set_current_item(curses_menu,
1043 curses_menu_items[selected_index]);
1044 } 938 }
939 set_current_item(curses_menu,
940 curses_menu_items[selected_index]);
1045 *last_top_row = toprow; 941 *last_top_row = toprow;
1046 post_menu(curses_menu); 942 post_menu(curses_menu);
1047 refresh_all_windows(main_window); 943 refresh_all_windows(main_window);
@@ -1073,7 +969,7 @@ static void show_menu(const char *prompt, const char *instructions,
1073 /* position the menu at the middle of the screen */ 969 /* position the menu at the middle of the screen */
1074 scale_menu(curses_menu, &maxy, &maxx); 970 scale_menu(curses_menu, &maxy, &maxx);
1075 maxx = min(maxx, mwin_max_cols-2); 971 maxx = min(maxx, mwin_max_cols-2);
1076 maxy = mwin_max_lines-2; 972 maxy = mwin_max_lines;
1077 menu_window = derwin(main_window, 973 menu_window = derwin(main_window,
1078 maxy, 974 maxy,
1079 maxx, 975 maxx,
@@ -1097,10 +993,77 @@ static void show_menu(const char *prompt, const char *instructions,
1097 refresh_all_windows(main_window); 993 refresh_all_windows(main_window);
1098} 994}
1099 995
996static 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}
1100 1006
1101static void conf(struct menu *menu) 1007struct match_state
1102{ 1008{
1009 int in_search;
1010 match_f match_direction;
1103 char pattern[256]; 1011 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 */
1018static 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
1065static void conf(struct menu *menu)
1066{
1104 struct menu *submenu = 0; 1067 struct menu *submenu = 0;
1105 const char *prompt = menu_get_prompt(menu); 1068 const char *prompt = menu_get_prompt(menu);
1106 struct symbol *sym; 1069 struct symbol *sym;
@@ -1108,8 +1071,11 @@ static void conf(struct menu *menu)
1108 int res; 1071 int res;
1109 int current_index = 0; 1072 int current_index = 0;
1110 int last_top_row = 0; 1073 int last_top_row = 0;
1111 1074 struct match_state match_state = {
1112 bzero(pattern, sizeof(pattern)); 1075 .in_search = 0,
1076 .match_direction = MATCH_TINKER_PATTERN_DOWN,
1077 .pattern = "",
1078 };
1113 1079
1114 while (!global_exit) { 1080 while (!global_exit) {
1115 reset_menu(); 1081 reset_menu();
@@ -1122,7 +1088,22 @@ static void conf(struct menu *menu)
1122 _(menu_instructions), 1088 _(menu_instructions),
1123 current_index, &last_top_row); 1089 current_index, &last_top_row);
1124 keypad((menu_win(curses_menu)), TRUE); 1090 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 }
1126 if (process_special_keys(&res, 1107 if (process_special_keys(&res,
1127 (struct menu *) item_data())) 1108 (struct menu *) item_data()))
1128 break; 1109 break;
@@ -1153,19 +1134,13 @@ static void conf(struct menu *menu)
1153 if (res == 10 || res == 27 || 1134 if (res == 10 || res == 27 ||
1154 res == 32 || res == 'n' || res == 'y' || 1135 res == 32 || res == 'n' || res == 'y' ||
1155 res == KEY_LEFT || res == KEY_RIGHT || 1136 res == KEY_LEFT || res == KEY_RIGHT ||
1156 res == 'm' || res == '/') 1137 res == 'm')
1157 break; 1138 break;
1158 else if (canbhot(res)) {
1159 /* check for hot keys: */
1160 int tmp = get_next_hot(res);
1161 if (tmp != -1)
1162 center_item(tmp, &last_top_row);
1163 }
1164 refresh_all_windows(main_window); 1139 refresh_all_windows(main_window);
1165 } 1140 }
1166 1141
1167 refresh_all_windows(main_window); 1142 refresh_all_windows(main_window);
1168 /* if ESC or left*/ 1143 /* if ESC or left*/
1169 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) 1144 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1170 break; 1145 break;
1171 1146
@@ -1233,23 +1208,30 @@ static void conf(struct menu *menu)
1233 if (item_is_tag('t')) 1208 if (item_is_tag('t'))
1234 sym_set_tristate_value(sym, mod); 1209 sym_set_tristate_value(sym, mod);
1235 break; 1210 break;
1236 case '/':
1237 search_conf();
1238 break;
1239 } 1211 }
1240 } 1212 }
1241} 1213}
1242 1214
1215static 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
1243static void show_help(struct menu *menu) 1223static void show_help(struct menu *menu)
1244{ 1224{
1245 struct gstr help = str_new(); 1225 struct gstr help = str_new();
1246 1226
1247 if (menu && menu->sym && menu_has_help(menu)) { 1227 if (menu && menu->sym && menu_has_help(menu)) {
1248 if (menu->sym->name) { 1228 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);
1250 str_append(&help, _(menu_get_help(menu))); 1230 str_append(&help, _(menu_get_help(menu)));
1251 str_append(&help, "\n"); 1231 str_append(&help, "\n");
1252 get_symbol_str(&help, menu->sym); 1232 get_symbol_str(&help, menu->sym);
1233 } else {
1234 str_append(&help, _(menu_get_help(menu)));
1253 } 1235 }
1254 } else { 1236 } else {
1255 str_append(&help, nohelp_text); 1237 str_append(&help, nohelp_text);
@@ -1266,6 +1248,11 @@ static void conf_choice(struct menu *menu)
1266 int selected_index = 0; 1248 int selected_index = 0;
1267 int last_top_row = 0; 1249 int last_top_row = 0;
1268 int res, i = 0; 1250 int res, i = 0;
1251 struct match_state match_state = {
1252 .in_search = 0,
1253 .match_direction = MATCH_TINKER_PATTERN_DOWN,
1254 .pattern = "",
1255 };
1269 1256
1270 active = sym_get_choice_value(menu->sym); 1257 active = sym_get_choice_value(menu->sym);
1271 /* this is mostly duplicated from the conf() function. */ 1258 /* this is mostly duplicated from the conf() function. */
@@ -1292,7 +1279,22 @@ static void conf_choice(struct menu *menu)
1292 _(radiolist_instructions), 1279 _(radiolist_instructions),
1293 selected_index, 1280 selected_index,
1294 &last_top_row); 1281 &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 }
1296 if (process_special_keys( 1298 if (process_special_keys(
1297 &res, 1299 &res,
1298 (struct menu *) item_data())) 1300 (struct menu *) item_data()))
@@ -1322,13 +1324,8 @@ static void conf_choice(struct menu *menu)
1322 break; 1324 break;
1323 } 1325 }
1324 if (res == 10 || res == 27 || res == ' ' || 1326 if (res == 10 || res == 27 || res == ' ' ||
1325 res == KEY_LEFT) 1327 res == KEY_LEFT){
1326 break; 1328 break;
1327 else if (canbhot(res)) {
1328 /* check for hot keys: */
1329 int tmp = get_next_hot(res);
1330 if (tmp != -1)
1331 center_item(tmp, &last_top_row);
1332 } 1329 }
1333 refresh_all_windows(main_window); 1330 refresh_all_windows(main_window);
1334 } 1331 }
@@ -1447,16 +1444,8 @@ static void conf_save(void)
1447 case 0: 1444 case 0:
1448 if (!dialog_input_result[0]) 1445 if (!dialog_input_result[0])
1449 return; 1446 return;
1450 supress_stdout(0);
1451 res = conf_write(dialog_input_result); 1447 res = conf_write(dialog_input_result);
1452 supress_stdout(1);
1453 if (!res) { 1448 if (!res) {
1454 char buf[1024];
1455 sprintf(buf, "%s %s",
1456 _("configuration file saved to: "),
1457 dialog_input_result);
1458 btn_dialog(main_window,
1459 buf, 1, "<OK>");
1460 set_config_filename(dialog_input_result); 1449 set_config_filename(dialog_input_result);
1461 return; 1450 return;
1462 } 1451 }
@@ -1483,7 +1472,7 @@ void setup_windows(void)
1483 /* set up the menu and menu window */ 1472 /* set up the menu and menu window */
1484 main_window = newwin(LINES-2, COLS-2, 2, 1); 1473 main_window = newwin(LINES-2, COLS-2, 2, 1);
1485 keypad(main_window, TRUE); 1474 keypad(main_window, TRUE);
1486 mwin_max_lines = LINES-6; 1475 mwin_max_lines = LINES-7;
1487 mwin_max_cols = COLS-6; 1476 mwin_max_cols = COLS-6;
1488 1477
1489 /* panels order is from bottom to top */ 1478 /* panels order is from bottom to top */
@@ -1530,9 +1519,10 @@ int main(int ac, char **av)
1530 /* set btns menu */ 1519 /* set btns menu */
1531 curses_menu = new_menu(curses_menu_items); 1520 curses_menu = new_menu(curses_menu_items);
1532 menu_opts_off(curses_menu, O_SHOWDESC); 1521 menu_opts_off(curses_menu, O_SHOWDESC);
1533 menu_opts_off(curses_menu, O_SHOWMATCH); 1522 menu_opts_on(curses_menu, O_SHOWMATCH);
1534 menu_opts_on(curses_menu, O_ONEVALUE); 1523 menu_opts_on(curses_menu, O_ONEVALUE);
1535 menu_opts_on(curses_menu, O_NONCYCLIC); 1524 menu_opts_on(curses_menu, O_NONCYCLIC);
1525 menu_opts_on(curses_menu, O_IGNORECASE);
1536 set_menu_mark(curses_menu, " "); 1526 set_menu_mark(curses_menu, " ");
1537 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); 1527 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1538 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); 1528 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
@@ -1548,8 +1538,7 @@ int main(int ac, char **av)
1548 _(menu_no_f_instructions)); 1538 _(menu_no_f_instructions));
1549 } 1539 }
1550 1540
1551 1541 conf_set_message_callback(conf_message_callback);
1552
1553 /* do the work */ 1542 /* do the work */
1554 while (!global_exit) { 1543 while (!global_exit) {
1555 conf(&rootmenu); 1544 conf(&rootmenu);
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index a9d9344e1365..f8137b3a5382 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -137,7 +137,7 @@ void set_colors()
137 if (has_colors()) { 137 if (has_colors()) {
138 normal_color_theme(); 138 normal_color_theme();
139 } else { 139 } else {
140 /* give deafults */ 140 /* give defaults */
141 no_colors_theme(); 141 no_colors_theme();
142 } 142 }
143} 143}
@@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win,
167 length = strlen(string); 167 length = strlen(string);
168 temp = (width - length) / 2; 168 temp = (width - length) / 2;
169 x = startx + (int)temp; 169 x = startx + (int)temp;
170 wattrset(win, color); 170 (void) wattrset(win, color);
171 mvwprintw(win, y, x, "%s", string); 171 mvwprintw(win, y, x, "%s", string);
172 refresh(); 172 refresh();
173} 173}
@@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); 297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]); 298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
299 299
300 wattrset(win, attributes[DIALOG_BOX]); 300 (void) wattrset(win, attributes[DIALOG_BOX]);
301 box(win, 0, 0); 301 box(win, 0, 0);
302 302
303 /* print message */ 303 /* print message */
304 wattrset(msg_win, attributes[DIALOG_TEXT]); 304 (void) wattrset(msg_win, attributes[DIALOG_TEXT]);
305 fill_window(msg_win, msg); 305 fill_window(msg_win, msg);
306 306
307 set_menu_win(menu, win); 307 set_menu_win(menu, win);
@@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window,
392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); 392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
393 keypad(form_win, TRUE); 393 keypad(form_win, TRUE);
394 394
395 wattrset(form_win, attributes[INPUT_FIELD]); 395 (void) wattrset(form_win, attributes[INPUT_FIELD]);
396 396
397 wattrset(win, attributes[INPUT_BOX]); 397 (void) wattrset(win, attributes[INPUT_BOX]);
398 box(win, 0, 0); 398 box(win, 0, 0);
399 wattrset(win, attributes[INPUT_HEADING]); 399 (void) wattrset(win, attributes[INPUT_HEADING]);
400 if (title) 400 if (title)
401 mvwprintw(win, 0, 3, "%s", title); 401 mvwprintw(win, 0, 3, "%s", title);
402 402
403 /* print message */ 403 /* print message */
404 wattrset(prompt_win, attributes[INPUT_TEXT]); 404 (void) wattrset(prompt_win, attributes[INPUT_TEXT]);
405 fill_window(prompt_win, prompt); 405 fill_window(prompt_win, prompt);
406 406
407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); 407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
@@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window,
531 531
532 /* create the pad */ 532 /* create the pad */
533 pad = newpad(total_lines+10, total_cols+10); 533 pad = newpad(total_lines+10, total_cols+10);
534 wattrset(pad, attributes[SCROLLWIN_TEXT]); 534 (void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
535 fill_window(pad, text); 535 fill_window(pad, text);
536 536
537 win_lines = min(total_lines+4, LINES-2); 537 win_lines = min(total_lines+4, LINES-2);
@@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window,
546 win = newwin(win_lines, win_cols, y, x); 546 win = newwin(win_lines, win_cols, y, x);
547 keypad(win, TRUE); 547 keypad(win, TRUE);
548 /* show the help in the help window, and show the help panel */ 548 /* 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]);
550 box(win, 0, 0); 550 box(win, 0, 0);
551 wattrset(win, attributes[SCROLLWIN_HEADING]); 551 (void) wattrset(win, attributes[SCROLLWIN_HEADING]);
552 mvwprintw(win, 0, 3, " %s ", title); 552 mvwprintw(win, 0, 3, " %s ", title);
553 panel = new_panel(win); 553 panel = new_panel(win);
554 554
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
index fb4296666004..58fbda8fc0dc 100644
--- a/scripts/kconfig/nconf.h
+++ b/scripts/kconfig/nconf.h
@@ -69,7 +69,8 @@ typedef enum {
69 F_BACK = 5, 69 F_BACK = 5,
70 F_SAVE = 6, 70 F_SAVE = 6,
71 F_LOAD = 7, 71 F_LOAD = 7,
72 F_EXIT = 8 72 F_SEARCH = 8,
73 F_EXIT = 9,
73} function_key; 74} function_key;
74 75
75void set_colors(void); 76void set_colors(void);
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 820df2d1217b..06dd2e33581d 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -3,25 +3,42 @@
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <qapplication.h> 6#include <qglobal.h>
7
8#if QT_VERSION < 0x040000
7#include <qmainwindow.h> 9#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>
8#include <qdesktopwidget.h> 31#include <qdesktopwidget.h>
9#include <qtoolbar.h> 32#include <qtoolbar.h>
10#include <qlayout.h> 33#include <qlayout.h>
11#include <qvbox.h>
12#include <qsplitter.h> 34#include <qsplitter.h>
13#include <qlistview.h>
14#include <qtextbrowser.h>
15#include <qlineedit.h> 35#include <qlineedit.h>
16#include <qlabel.h> 36#include <qlabel.h>
17#include <qpushbutton.h> 37#include <qpushbutton.h>
18#include <qmenubar.h> 38#include <qmenubar.h>
19#include <qmessagebox.h> 39#include <qmessagebox.h>
20#include <qaction.h>
21#include <qheader.h>
22#include <qfiledialog.h>
23#include <qdragobject.h>
24#include <qregexp.h> 40#include <qregexp.h>
41#include <qevent.h>
25 42
26#include <stdlib.h> 43#include <stdlib.h>
27 44
@@ -39,7 +56,7 @@
39static QApplication *configApp; 56static QApplication *configApp;
40static ConfigSettings *configSettings; 57static ConfigSettings *configSettings;
41 58
42QAction *ConfigMainWindow::saveAction; 59Q3Action *ConfigMainWindow::saveAction;
43 60
44static inline QString qgettext(const char* str) 61static inline QString qgettext(const char* str)
45{ 62{
@@ -54,9 +71,9 @@ static inline QString qgettext(const QString& str)
54/** 71/**
55 * Reads a list of integer values from the application settings. 72 * Reads a list of integer values from the application settings.
56 */ 73 */
57QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok) 74Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58{ 75{
59 QValueList<int> result; 76 Q3ValueList<int> result;
60 QStringList entryList = readListEntry(key, ok); 77 QStringList entryList = readListEntry(key, ok);
61 QStringList::Iterator it; 78 QStringList::Iterator it;
62 79
@@ -69,10 +86,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
69/** 86/**
70 * Writes a list of integer values to the application settings. 87 * Writes a list of integer values to the application settings.
71 */ 88 */
72bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value) 89bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
73{ 90{
74 QStringList stringList; 91 QStringList stringList;
75 QValueList<int>::ConstIterator it; 92 Q3ValueList<int>::ConstIterator it;
76 93
77 for (it = value.begin(); it != value.end(); ++it) 94 for (it = value.begin(); it != value.end(); ++it)
78 stringList.push_back(QString::number(*it)); 95 stringList.push_back(QString::number(*it));
@@ -80,7 +97,6 @@ bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value
80} 97}
81 98
82 99
83#if QT_VERSION >= 300
84/* 100/*
85 * set the new data 101 * set the new data
86 * TODO check the value 102 * TODO check the value
@@ -91,7 +107,6 @@ void ConfigItem::okRename(int col)
91 sym_set_string_value(menu->sym, text(dataColIdx).latin1()); 107 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
92 listView()->updateList(this); 108 listView()->updateList(this);
93} 109}
94#endif
95 110
96/* 111/*
97 * update the displayed of a menu entry 112 * update the displayed of a menu entry
@@ -195,11 +210,9 @@ void ConfigItem::updateMenu(void)
195 210
196 data = sym_get_string_value(sym); 211 data = sym_get_string_value(sym);
197 212
198#if QT_VERSION >= 300
199 int i = list->mapIdx(dataColIdx); 213 int i = list->mapIdx(dataColIdx);
200 if (i >= 0) 214 if (i >= 0)
201 setRenameEnabled(i, TRUE); 215 setRenameEnabled(i, TRUE);
202#endif
203 setText(dataColIdx, data); 216 setText(dataColIdx, data);
204 if (type == S_STRING) 217 if (type == S_STRING)
205 prompt = QString("%1: %2").arg(prompt).arg(data); 218 prompt = QString("%1: %2").arg(prompt).arg(data);
@@ -432,7 +445,7 @@ void ConfigList::updateList(ConfigItem* item)
432 if (!rootEntry) { 445 if (!rootEntry) {
433 if (mode != listMode) 446 if (mode != listMode)
434 goto update; 447 goto update;
435 QListViewItemIterator it(this); 448 Q3ListViewItemIterator it(this);
436 ConfigItem* item; 449 ConfigItem* item;
437 450
438 for (; it.current(); ++it) { 451 for (; it.current(); ++it) {
@@ -527,11 +540,9 @@ void ConfigList::changeValue(ConfigItem* item)
527 case S_INT: 540 case S_INT:
528 case S_HEX: 541 case S_HEX:
529 case S_STRING: 542 case S_STRING:
530#if QT_VERSION >= 300
531 if (colMap[dataColIdx] >= 0) 543 if (colMap[dataColIdx] >= 0)
532 item->startRename(colMap[dataColIdx]); 544 item->startRename(colMap[dataColIdx]);
533 else 545 else
534#endif
535 parent()->lineEdit->show(item); 546 parent()->lineEdit->show(item);
536 break; 547 break;
537 } 548 }
@@ -563,7 +574,7 @@ void ConfigList::setParentMenu(void)
563 return; 574 return;
564 setRootMenu(menu_get_parent_menu(rootEntry->parent)); 575 setRootMenu(menu_get_parent_menu(rootEntry->parent));
565 576
566 QListViewItemIterator it(this); 577 Q3ListViewItemIterator it(this);
567 for (; (item = (ConfigItem*)it.current()); it++) { 578 for (; (item = (ConfigItem*)it.current()); it++) {
568 if (item->menu == oldroot) { 579 if (item->menu == oldroot) {
569 setCurrentItem(item); 580 setCurrentItem(item);
@@ -645,7 +656,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
645 656
646void ConfigList::keyPressEvent(QKeyEvent* ev) 657void ConfigList::keyPressEvent(QKeyEvent* ev)
647{ 658{
648 QListViewItem* i = currentItem(); 659 Q3ListViewItem* i = currentItem();
649 ConfigItem* item; 660 ConfigItem* item;
650 struct menu *menu; 661 struct menu *menu;
651 enum prop_type type; 662 enum prop_type type;
@@ -811,10 +822,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
811{ 822{
812 if (e->y() <= header()->geometry().bottom()) { 823 if (e->y() <= header()->geometry().bottom()) {
813 if (!headerPopup) { 824 if (!headerPopup) {
814 QAction *action; 825 Q3Action *action;
815 826
816 headerPopup = new QPopupMenu(this); 827 headerPopup = new Q3PopupMenu(this);
817 action = new QAction(NULL, _("Show Name"), 0, this); 828 action = new Q3Action(NULL, _("Show Name"), 0, this);
818 action->setToggleAction(TRUE); 829 action->setToggleAction(TRUE);
819 connect(action, SIGNAL(toggled(bool)), 830 connect(action, SIGNAL(toggled(bool)),
820 parent(), SLOT(setShowName(bool))); 831 parent(), SLOT(setShowName(bool)));
@@ -822,7 +833,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
822 action, SLOT(setOn(bool))); 833 action, SLOT(setOn(bool)));
823 action->setOn(showName); 834 action->setOn(showName);
824 action->addTo(headerPopup); 835 action->addTo(headerPopup);
825 action = new QAction(NULL, _("Show Range"), 0, this); 836 action = new Q3Action(NULL, _("Show Range"), 0, this);
826 action->setToggleAction(TRUE); 837 action->setToggleAction(TRUE);
827 connect(action, SIGNAL(toggled(bool)), 838 connect(action, SIGNAL(toggled(bool)),
828 parent(), SLOT(setShowRange(bool))); 839 parent(), SLOT(setShowRange(bool)));
@@ -830,7 +841,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
830 action, SLOT(setOn(bool))); 841 action, SLOT(setOn(bool)));
831 action->setOn(showRange); 842 action->setOn(showRange);
832 action->addTo(headerPopup); 843 action->addTo(headerPopup);
833 action = new QAction(NULL, _("Show Data"), 0, this); 844 action = new Q3Action(NULL, _("Show Data"), 0, this);
834 action->setToggleAction(TRUE); 845 action->setToggleAction(TRUE);
835 connect(action, SIGNAL(toggled(bool)), 846 connect(action, SIGNAL(toggled(bool)),
836 parent(), SLOT(setShowData(bool))); 847 parent(), SLOT(setShowData(bool)));
@@ -914,7 +925,7 @@ void ConfigView::setShowData(bool b)
914 925
915void ConfigList::setAllOpen(bool open) 926void ConfigList::setAllOpen(bool open)
916{ 927{
917 QListViewItemIterator it(this); 928 Q3ListViewItemIterator it(this);
918 929
919 for (; it.current(); it++) 930 for (; it.current(); it++)
920 it.current()->setOpen(open); 931 it.current()->setOpen(open);
@@ -937,7 +948,7 @@ void ConfigView::updateListAll(void)
937} 948}
938 949
939ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) 950ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
940 : Parent(parent, name), sym(0), menu(0) 951 : Parent(parent, name), sym(0), _menu(0)
941{ 952{
942 if (name) { 953 if (name) {
943 configSettings->beginGroup(name); 954 configSettings->beginGroup(name);
@@ -960,7 +971,7 @@ void ConfigInfoView::setShowDebug(bool b)
960{ 971{
961 if (_showDebug != b) { 972 if (_showDebug != b) {
962 _showDebug = b; 973 _showDebug = b;
963 if (menu) 974 if (_menu)
964 menuInfo(); 975 menuInfo();
965 else if (sym) 976 else if (sym)
966 symbolInfo(); 977 symbolInfo();
@@ -970,11 +981,11 @@ void ConfigInfoView::setShowDebug(bool b)
970 981
971void ConfigInfoView::setInfo(struct menu *m) 982void ConfigInfoView::setInfo(struct menu *m)
972{ 983{
973 if (menu == m) 984 if (_menu == m)
974 return; 985 return;
975 menu = m; 986 _menu = m;
976 sym = NULL; 987 sym = NULL;
977 if (!menu) 988 if (!_menu)
978 clear(); 989 clear();
979 else 990 else
980 menuInfo(); 991 menuInfo();
@@ -1001,11 +1012,11 @@ void ConfigInfoView::menuInfo(void)
1001 struct symbol* sym; 1012 struct symbol* sym;
1002 QString head, debug, help; 1013 QString head, debug, help;
1003 1014
1004 sym = menu->sym; 1015 sym = _menu->sym;
1005 if (sym) { 1016 if (sym) {
1006 if (menu->prompt) { 1017 if (_menu->prompt) {
1007 head += "<big><b>"; 1018 head += "<big><b>";
1008 head += print_filter(_(menu->prompt->text)); 1019 head += print_filter(_(_menu->prompt->text));
1009 head += "</b></big>"; 1020 head += "</b></big>";
1010 if (sym->name) { 1021 if (sym->name) {
1011 head += " ("; 1022 head += " (";
@@ -1031,23 +1042,23 @@ void ConfigInfoView::menuInfo(void)
1031 debug = debug_info(sym); 1042 debug = debug_info(sym);
1032 1043
1033 struct gstr help_gstr = str_new(); 1044 struct gstr help_gstr = str_new();
1034 menu_get_ext_help(menu, &help_gstr); 1045 menu_get_ext_help(_menu, &help_gstr);
1035 help = print_filter(str_get(&help_gstr)); 1046 help = print_filter(str_get(&help_gstr));
1036 str_free(&help_gstr); 1047 str_free(&help_gstr);
1037 } else if (menu->prompt) { 1048 } else if (_menu->prompt) {
1038 head += "<big><b>"; 1049 head += "<big><b>";
1039 head += print_filter(_(menu->prompt->text)); 1050 head += print_filter(_(_menu->prompt->text));
1040 head += "</b></big><br><br>"; 1051 head += "</b></big><br><br>";
1041 if (showDebug()) { 1052 if (showDebug()) {
1042 if (menu->prompt->visible.expr) { 1053 if (_menu->prompt->visible.expr) {
1043 debug += "&nbsp;&nbsp;dep: "; 1054 debug += "&nbsp;&nbsp;dep: ";
1044 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);
1045 debug += "<br><br>"; 1056 debug += "<br><br>";
1046 } 1057 }
1047 } 1058 }
1048 } 1059 }
1049 if (showDebug()) 1060 if (showDebug())
1050 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);
1051 1062
1052 setText(head + debug + help); 1063 setText(head + debug + help);
1053} 1064}
@@ -1150,10 +1161,10 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
1150 *text += str2; 1161 *text += str2;
1151} 1162}
1152 1163
1153QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) 1164Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1154{ 1165{
1155 QPopupMenu* popup = Parent::createPopupMenu(pos); 1166 Q3PopupMenu* popup = Parent::createPopupMenu(pos);
1156 QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup); 1167 Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
1157 action->setToggleAction(TRUE); 1168 action->setToggleAction(TRUE);
1158 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); 1169 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1159 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); 1170 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1210,7 +1221,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
1210 y = configSettings->readNumEntry("/window y", 0, &ok); 1221 y = configSettings->readNumEntry("/window y", 0, &ok);
1211 if (ok) 1222 if (ok)
1212 move(x, y); 1223 move(x, y);
1213 QValueList<int> sizes = configSettings->readSizes("/split", &ok); 1224 Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
1214 if (ok) 1225 if (ok)
1215 split->setSizes(sizes); 1226 split->setSizes(sizes);
1216 configSettings->endGroup(); 1227 configSettings->endGroup();
@@ -1263,8 +1274,14 @@ ConfigMainWindow::ConfigMainWindow(void)
1263 char title[256]; 1274 char title[256];
1264 1275
1265 QDesktopWidget *d = configApp->desktop(); 1276 QDesktopWidget *d = configApp->desktop();
1266 snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"), 1277 snprintf(title, sizeof(title), "%s%s",
1267 getenv("KERNELVERSION")); 1278 rootmenu.prompt->text,
1279#if QT_VERSION < 0x040000
1280 " (Qt3)"
1281#else
1282 ""
1283#endif
1284 );
1268 setCaption(title); 1285 setCaption(title);
1269 1286
1270 width = configSettings->readNumEntry("/window width", d->width() - 64); 1287 width = configSettings->readNumEntry("/window width", d->width() - 64);
@@ -1297,42 +1314,42 @@ ConfigMainWindow::ConfigMainWindow(void)
1297 configList->setFocus(); 1314 configList->setFocus();
1298 1315
1299 menu = menuBar(); 1316 menu = menuBar();
1300 toolBar = new QToolBar("Tools", this); 1317 toolBar = new Q3ToolBar("Tools", this);
1301 1318
1302 backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this); 1319 backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
1303 connect(backAction, SIGNAL(activated()), SLOT(goBack())); 1320 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1304 backAction->setEnabled(FALSE); 1321 backAction->setEnabled(FALSE);
1305 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);
1306 connect(quitAction, SIGNAL(activated()), SLOT(close())); 1323 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1307 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);
1308 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); 1325 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1309 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);
1310 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); 1327 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1311 conf_set_changed_callback(conf_changed); 1328 conf_set_changed_callback(conf_changed);
1312 // Set saveAction's initial state 1329 // Set saveAction's initial state
1313 conf_changed(); 1330 conf_changed();
1314 QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this); 1331 Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
1315 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); 1332 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1316 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);
1317 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig())); 1334 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1318 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);
1319 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); 1336 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1320 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);
1321 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); 1338 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1322 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);
1323 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); 1340 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1324 1341
1325 QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this); 1342 Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
1326 showNameAction->setToggleAction(TRUE); 1343 showNameAction->setToggleAction(TRUE);
1327 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); 1344 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1328 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool))); 1345 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1329 showNameAction->setOn(configView->showName()); 1346 showNameAction->setOn(configView->showName());
1330 QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this); 1347 Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
1331 showRangeAction->setToggleAction(TRUE); 1348 showRangeAction->setToggleAction(TRUE);
1332 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); 1349 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1333 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool))); 1350 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1334 showRangeAction->setOn(configList->showRange); 1351 showRangeAction->setOn(configList->showRange);
1335 QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this); 1352 Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
1336 showDataAction->setToggleAction(TRUE); 1353 showDataAction->setToggleAction(TRUE);
1337 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); 1354 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1338 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); 1355 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
@@ -1345,9 +1362,15 @@ ConfigMainWindow::ConfigMainWindow(void)
1345 connect(optGroup, SIGNAL(selected(QAction *)), menuView, 1362 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1346 SLOT(setOptionMode(QAction *))); 1363 SLOT(setOptionMode(QAction *)));
1347 1364
1348 configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup); 1365#if QT_VERSION >= 0x040000
1349 configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup); 1366 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1350 configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, 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
1351 configView->showNormalAction->setToggleAction(TRUE); 1374 configView->showNormalAction->setToggleAction(TRUE);
1352 configView->showNormalAction->setOn(configList->optMode == normalOpt); 1375 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1353 configView->showAllAction->setToggleAction(TRUE); 1376 configView->showAllAction->setToggleAction(TRUE);
@@ -1355,15 +1378,15 @@ ConfigMainWindow::ConfigMainWindow(void)
1355 configView->showPromptAction->setToggleAction(TRUE); 1378 configView->showPromptAction->setToggleAction(TRUE);
1356 configView->showPromptAction->setOn(configList->optMode == promptOpt); 1379 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1357 1380
1358 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); 1381 Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
1359 showDebugAction->setToggleAction(TRUE); 1382 showDebugAction->setToggleAction(TRUE);
1360 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); 1383 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1361 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); 1384 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1362 showDebugAction->setOn(helpText->showDebug()); 1385 showDebugAction->setOn(helpText->showDebug());
1363 1386
1364 QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this); 1387 Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
1365 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); 1388 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1366 QAction *showAboutAction = new QAction(NULL, _("About"), 0, this); 1389 Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
1367 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); 1390 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1368 1391
1369 // init tool bar 1392 // init tool bar
@@ -1377,7 +1400,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1377 fullViewAction->addTo(toolBar); 1400 fullViewAction->addTo(toolBar);
1378 1401
1379 // create config menu 1402 // create config menu
1380 QPopupMenu* config = new QPopupMenu(this); 1403 Q3PopupMenu* config = new Q3PopupMenu(this);
1381 menu->insertItem(_("&File"), config); 1404 menu->insertItem(_("&File"), config);
1382 loadAction->addTo(config); 1405 loadAction->addTo(config);
1383 saveAction->addTo(config); 1406 saveAction->addTo(config);
@@ -1386,12 +1409,12 @@ ConfigMainWindow::ConfigMainWindow(void)
1386 quitAction->addTo(config); 1409 quitAction->addTo(config);
1387 1410
1388 // create edit menu 1411 // create edit menu
1389 QPopupMenu* editMenu = new QPopupMenu(this); 1412 Q3PopupMenu* editMenu = new Q3PopupMenu(this);
1390 menu->insertItem(_("&Edit"), editMenu); 1413 menu->insertItem(_("&Edit"), editMenu);
1391 searchAction->addTo(editMenu); 1414 searchAction->addTo(editMenu);
1392 1415
1393 // create options menu 1416 // create options menu
1394 QPopupMenu* optionMenu = new QPopupMenu(this); 1417 Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
1395 menu->insertItem(_("&Option"), optionMenu); 1418 menu->insertItem(_("&Option"), optionMenu);
1396 showNameAction->addTo(optionMenu); 1419 showNameAction->addTo(optionMenu);
1397 showRangeAction->addTo(optionMenu); 1420 showRangeAction->addTo(optionMenu);
@@ -1399,10 +1422,9 @@ ConfigMainWindow::ConfigMainWindow(void)
1399 optionMenu->insertSeparator(); 1422 optionMenu->insertSeparator();
1400 optGroup->addTo(optionMenu); 1423 optGroup->addTo(optionMenu);
1401 optionMenu->insertSeparator(); 1424 optionMenu->insertSeparator();
1402 showDebugAction->addTo(optionMenu);
1403 1425
1404 // create help menu 1426 // create help menu
1405 QPopupMenu* helpMenu = new QPopupMenu(this); 1427 Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
1406 menu->insertSeparator(); 1428 menu->insertSeparator();
1407 menu->insertItem(_("&Help"), helpMenu); 1429 menu->insertItem(_("&Help"), helpMenu);
1408 showIntroAction->addTo(helpMenu); 1430 showIntroAction->addTo(helpMenu);
@@ -1437,7 +1459,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1437 showSplitView(); 1459 showSplitView();
1438 1460
1439 // UI setup done, restore splitter positions 1461 // UI setup done, restore splitter positions
1440 QValueList<int> sizes = configSettings->readSizes("/split1", &ok); 1462 Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1441 if (ok) 1463 if (ok)
1442 split1->setSizes(sizes); 1464 split1->setSizes(sizes);
1443 1465
@@ -1448,7 +1470,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1448 1470
1449void ConfigMainWindow::loadConfig(void) 1471void ConfigMainWindow::loadConfig(void)
1450{ 1472{
1451 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this); 1473 QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1452 if (s.isNull()) 1474 if (s.isNull())
1453 return; 1475 return;
1454 if (conf_read(QFile::encodeName(s))) 1476 if (conf_read(QFile::encodeName(s)))
@@ -1464,7 +1486,7 @@ void ConfigMainWindow::saveConfig(void)
1464 1486
1465void ConfigMainWindow::saveConfigAs(void) 1487void ConfigMainWindow::saveConfigAs(void)
1466{ 1488{
1467 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this); 1489 QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1468 if (s.isNull()) 1490 if (s.isNull())
1469 return; 1491 return;
1470 if (conf_write(QFile::encodeName(s))) 1492 if (conf_write(QFile::encodeName(s)))
@@ -1633,7 +1655,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
1633 1655
1634void ConfigMainWindow::showIntro(void) 1656void ConfigMainWindow::showIntro(void)
1635{ 1657{
1636 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"
1637 "For each option, a blank box indicates the feature is disabled, a check\n" 1659 "For each option, a blank box indicates the feature is disabled, a check\n"
1638 "indicates it is enabled, and a dot indicates that it is to be compiled\n" 1660 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1639 "as a module. Clicking on the box will cycle through the three states.\n\n" 1661 "as a module. Clicking on the box will cycle through the three states.\n\n"
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 636a74b23bf9..91677d900dbd 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -3,26 +3,25 @@
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#if QT_VERSION < 0x040000
6#include <qlistview.h> 7#include <qlistview.h>
7#if QT_VERSION >= 300
8#include <qsettings.h>
9#else 8#else
10class QSettings { 9#include <q3listview.h>
11public: 10#endif
12 void beginGroup(const QString& group) { } 11#include <qsettings.h>
13 void endGroup(void) { } 12
14 bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const 13#if QT_VERSION < 0x040000
15 { if (ok) *ok = FALSE; return def; } 14#define Q3ValueList QValueList
16 int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const 15#define Q3PopupMenu QPopupMenu
17 { if (ok) *ok = FALSE; return def; } 16#define Q3ListView QListView
18 QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const 17#define Q3ListViewItem QListViewItem
19 { if (ok) *ok = FALSE; return def; } 18#define Q3VBox QVBox
20 QStringList readListEntry(const QString& key, bool* ok = 0) const 19#define Q3TextBrowser QTextBrowser
21 { if (ok) *ok = FALSE; return QStringList(); } 20#define Q3MainWindow QMainWindow
22 template <class t> 21#define Q3Action QAction
23 bool writeEntry(const QString& key, t value) 22#define Q3ToolBar QToolBar
24 { return TRUE; } 23#define Q3ListViewItemIterator QListViewItemIterator
25}; 24#define Q3FileDialog QFileDialog
26#endif 25#endif
27 26
28class ConfigView; 27class ConfigView;
@@ -31,11 +30,10 @@ class ConfigItem;
31class ConfigLineEdit; 30class ConfigLineEdit;
32class ConfigMainWindow; 31class ConfigMainWindow;
33 32
34
35class ConfigSettings : public QSettings { 33class ConfigSettings : public QSettings {
36public: 34public:
37 QValueList<int> readSizes(const QString& key, bool *ok); 35 Q3ValueList<int> readSizes(const QString& key, bool *ok);
38 bool writeSizes(const QString& key, const QValueList<int>& value); 36 bool writeSizes(const QString& key, const Q3ValueList<int>& value);
39}; 37};
40 38
41enum colIdx { 39enum colIdx {
@@ -48,9 +46,9 @@ enum optionMode {
48 normalOpt = 0, allOpt, promptOpt 46 normalOpt = 0, allOpt, promptOpt
49}; 47};
50 48
51class ConfigList : public QListView { 49class ConfigList : public Q3ListView {
52 Q_OBJECT 50 Q_OBJECT
53 typedef class QListView Parent; 51 typedef class Q3ListView Parent;
54public: 52public:
55 ConfigList(ConfigView* p, const char *name = 0); 53 ConfigList(ConfigView* p, const char *name = 0);
56 void reinit(void); 54 void reinit(void);
@@ -135,17 +133,17 @@ public:
135 struct menu *rootEntry; 133 struct menu *rootEntry;
136 QColorGroup disabledColorGroup; 134 QColorGroup disabledColorGroup;
137 QColorGroup inactivedColorGroup; 135 QColorGroup inactivedColorGroup;
138 QPopupMenu* headerPopup; 136 Q3PopupMenu* headerPopup;
139 137
140private: 138private:
141 int colMap[colNr]; 139 int colMap[colNr];
142 int colRevMap[colNr]; 140 int colRevMap[colNr];
143}; 141};
144 142
145class ConfigItem : public QListViewItem { 143class ConfigItem : public Q3ListViewItem {
146 typedef class QListViewItem Parent; 144 typedef class Q3ListViewItem Parent;
147public: 145public:
148 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) 146 ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v)
149 : Parent(parent, after), menu(m), visible(v), goParent(false) 147 : Parent(parent, after), menu(m), visible(v), goParent(false)
150 { 148 {
151 init(); 149 init();
@@ -155,16 +153,14 @@ public:
155 { 153 {
156 init(); 154 init();
157 } 155 }
158 ConfigItem(QListView *parent, ConfigItem *after, bool v) 156 ConfigItem(Q3ListView *parent, ConfigItem *after, bool v)
159 : Parent(parent, after), menu(0), visible(v), goParent(true) 157 : Parent(parent, after), menu(0), visible(v), goParent(true)
160 { 158 {
161 init(); 159 init();
162 } 160 }
163 ~ConfigItem(void); 161 ~ConfigItem(void);
164 void init(void); 162 void init(void);
165#if QT_VERSION >= 300
166 void okRename(int col); 163 void okRename(int col);
167#endif
168 void updateMenu(void); 164 void updateMenu(void);
169 void testUpdateMenu(bool v); 165 void testUpdateMenu(bool v);
170 ConfigList* listView() const 166 ConfigList* listView() const
@@ -219,9 +215,9 @@ public:
219 ConfigItem *item; 215 ConfigItem *item;
220}; 216};
221 217
222class ConfigView : public QVBox { 218class ConfigView : public Q3VBox {
223 Q_OBJECT 219 Q_OBJECT
224 typedef class QVBox Parent; 220 typedef class Q3VBox Parent;
225public: 221public:
226 ConfigView(QWidget* parent, const char *name = 0); 222 ConfigView(QWidget* parent, const char *name = 0);
227 ~ConfigView(void); 223 ~ConfigView(void);
@@ -252,9 +248,9 @@ public:
252 static QAction *showPromptAction; 248 static QAction *showPromptAction;
253}; 249};
254 250
255class ConfigInfoView : public QTextBrowser { 251class ConfigInfoView : public Q3TextBrowser {
256 Q_OBJECT 252 Q_OBJECT
257 typedef class QTextBrowser Parent; 253 typedef class Q3TextBrowser Parent;
258public: 254public:
259 ConfigInfoView(QWidget* parent, const char *name = 0); 255 ConfigInfoView(QWidget* parent, const char *name = 0);
260 bool showDebug(void) const { return _showDebug; } 256 bool showDebug(void) const { return _showDebug; }
@@ -274,11 +270,11 @@ protected:
274 QString debug_info(struct symbol *sym); 270 QString debug_info(struct symbol *sym);
275 static QString print_filter(const QString &str); 271 static QString print_filter(const QString &str);
276 static void expr_print_help(void *data, struct symbol *sym, const char *str); 272 static void expr_print_help(void *data, struct symbol *sym, const char *str);
277 QPopupMenu* createPopupMenu(const QPoint& pos); 273 Q3PopupMenu* createPopupMenu(const QPoint& pos);
278 void contentsContextMenuEvent(QContextMenuEvent *e); 274 void contentsContextMenuEvent(QContextMenuEvent *e);
279 275
280 struct symbol *sym; 276 struct symbol *sym;
281 struct menu *menu; 277 struct menu *_menu;
282 bool _showDebug; 278 bool _showDebug;
283}; 279};
284 280
@@ -302,10 +298,10 @@ protected:
302 struct symbol **result; 298 struct symbol **result;
303}; 299};
304 300
305class ConfigMainWindow : public QMainWindow { 301class ConfigMainWindow : public Q3MainWindow {
306 Q_OBJECT 302 Q_OBJECT
307 303
308 static QAction *saveAction; 304 static Q3Action *saveAction;
309 static void conf_changed(void); 305 static void conf_changed(void);
310public: 306public:
311 ConfigMainWindow(void); 307 ConfigMainWindow(void);
@@ -334,8 +330,8 @@ protected:
334 ConfigView *configView; 330 ConfigView *configView;
335 ConfigList *configList; 331 ConfigList *configList;
336 ConfigInfoView *helpText; 332 ConfigInfoView *helpText;
337 QToolBar *toolBar; 333 Q3ToolBar *toolBar;
338 QAction *backAction; 334 Q3Action *backAction;
339 QSplitter* split1; 335 QSplitter* split1;
340 QSplitter* split2; 336 QSplitter* split2;
341}; 337};
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index c70a27d924f0..fd81fc33d633 100644
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -42,6 +42,8 @@
42# mv config_strip .config 42# mv config_strip .config
43# make oldconfig 43# make oldconfig
44# 44#
45use strict;
46
45my $config = ".config"; 47my $config = ".config";
46 48
47my $uname = `uname -r`; 49my $uname = `uname -r`;
@@ -123,7 +125,6 @@ my %selects;
123my %prompts; 125my %prompts;
124my %objects; 126my %objects;
125my $var; 127my $var;
126my $cont = 0;
127my $iflevel = 0; 128my $iflevel = 0;
128my @ifdeps; 129my @ifdeps;
129 130
@@ -137,19 +138,45 @@ sub read_kconfig {
137 my $config; 138 my $config;
138 my @kconfigs; 139 my @kconfigs;
139 140
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";
141 while (<KIN>) { 155 while (<KIN>) {
142 chomp; 156 chomp;
143 157
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
144 # collect any Kconfig sources 171 # collect any Kconfig sources
145 if (/^source\s*"(.*)"/) { 172 if (/^source\s*"(.*)"/) {
146 $kconfigs[$#kconfigs+1] = $1; 173 $kconfigs[$#kconfigs+1] = $1;
147 } 174 }
148 175
149 # configs found 176 # configs found
150 if (/^\s*config\s+(\S+)\s*$/) { 177 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
151 $state = "NEW"; 178 $state = "NEW";
152 $config = $1; 179 $config = $2;
153 180
154 for (my $i = 0; $i < $iflevel; $i++) { 181 for (my $i = 0; $i < $iflevel; $i++) {
155 if ($i) { 182 if ($i) {
@@ -178,7 +205,7 @@ sub read_kconfig {
178 # configs without prompts must be selected 205 # configs without prompts must be selected
179 } elsif ($state ne "NONE" && /^\s*tristate\s\S/) { 206 } elsif ($state ne "NONE" && /^\s*tristate\s\S/) {
180 # note if the config has a prompt 207 # note if the config has a prompt
181 $prompt{$config} = 1; 208 $prompts{$config} = 1;
182 209
183 # Check for if statements 210 # Check for if statements
184 } elsif (/^if\s+(.*\S)\s*$/) { 211 } elsif (/^if\s+(.*\S)\s*$/) {
@@ -218,6 +245,8 @@ if ($kconfig) {
218# Read all Makefiles to map the configs to the objects 245# Read all Makefiles to map the configs to the objects
219foreach my $makefile (@makefiles) { 246foreach my $makefile (@makefiles) {
220 247
248 my $cont = 0;
249
221 open(MIN,$makefile) || die "Can't open $makefile"; 250 open(MIN,$makefile) || die "Can't open $makefile";
222 while (<MIN>) { 251 while (<MIN>) {
223 my $objs; 252 my $objs;
@@ -281,7 +310,7 @@ if (defined($lsmod_file)) {
281 # see what modules are loaded on this system 310 # see what modules are loaded on this system
282 my $lsmod; 311 my $lsmod;
283 312
284 foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { 313 foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
285 if ( -x "$dir/lsmod" ) { 314 if ( -x "$dir/lsmod" ) {
286 $lsmod = "$dir/lsmod"; 315 $lsmod = "$dir/lsmod";
287 last; 316 last;
@@ -363,7 +392,7 @@ while ($repeat) {
363 parse_config_dep_select $depends{$config}; 392 parse_config_dep_select $depends{$config};
364 } 393 }
365 394
366 if (defined($prompt{$config}) || !defined($selects{$config})) { 395 if (defined($prompts{$config}) || !defined($selects{$config})) {
367 next; 396 next;
368 } 397 }
369 398
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index e95718fea355..af6e9f3de950 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -840,6 +840,55 @@ struct symbol *sym_find(const char *name)
840 return symbol; 840 return symbol;
841} 841}
842 842
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 */
848const 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) + 1;
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
843struct symbol **sym_re_search(const char *pattern) 892struct symbol **sym_re_search(const char *pattern)
844{ 893{
845 struct symbol *sym, **sym_arr = NULL; 894 struct symbol *sym, **sym_arr = NULL;
@@ -937,6 +986,8 @@ static void sym_check_print_recursive(struct symbol *last_sym)
937 sym = stack->sym; 986 sym = stack->sym;
938 next_sym = stack->next ? stack->next->sym : last_sym; 987 next_sym = stack->next ? stack->next->sym : last_sym;
939 prop = stack->prop; 988 prop = stack->prop;
989 if (prop == NULL)
990 prop = stack->sym->prop;
940 991
941 /* for choice values find the menu entry (used below) */ 992 /* for choice values find the menu entry (used below) */
942 if (sym_is_choice(sym) || sym_is_choice_value(sym)) { 993 if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 78b5c04e736b..6330cc871a47 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -12,15 +12,18 @@
12struct file *file_lookup(const char *name) 12struct file *file_lookup(const char *name)
13{ 13{
14 struct file *file; 14 struct file *file;
15 const char *file_name = sym_expand_string_value(name);
15 16
16 for (file = file_list; file; file = file->next) { 17 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);
18 return file; 20 return file;
21 }
19 } 22 }
20 23
21 file = malloc(sizeof(*file)); 24 file = malloc(sizeof(*file));
22 memset(file, 0, sizeof(*file)); 25 memset(file, 0, sizeof(*file));
23 file->name = strdup(name); 26 file->name = file_name;
24 file->next = file_list; 27 file->next = file_list;
25 file_list = file; 28 file_list = file;
26 return file; 29 return file;
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index d8bc74249622..c9e690eb7545 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -38,6 +38,7 @@ hex, T_TYPE, TF_COMMAND, S_HEX
38string, T_TYPE, TF_COMMAND, S_STRING 38string, T_TYPE, TF_COMMAND, S_STRING
39select, T_SELECT, TF_COMMAND 39select, T_SELECT, TF_COMMAND
40range, T_RANGE, TF_COMMAND 40range, T_RANGE, TF_COMMAND
41visible, T_VISIBLE, TF_COMMAND
41option, T_OPTION, TF_COMMAND 42option, T_OPTION, TF_COMMAND
42on, T_ON, TF_PARAM 43on, T_ON, TF_PARAM
43modules, T_OPT_MODULES, TF_OPTION 44modules, T_OPT_MODULES, TF_OPTION
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index c1748faf4634..4055d5de1750 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -32,7 +32,7 @@
32struct kconf_id; 32struct kconf_id;
33 33
34static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len); 34static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
35/* maximum key range = 47, duplicates = 0 */ 35/* maximum key range = 50, duplicates = 0 */
36 36
37#ifdef __GNUC__ 37#ifdef __GNUC__
38__inline 38__inline
@@ -46,32 +46,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
46{ 46{
47 static unsigned char asso_values[] = 47 static unsigned char asso_values[] =
48 { 48 {
49 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
50 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
51 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 51 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
52 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 52 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
53 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
54 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
55 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 55 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
56 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 56 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
57 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 57 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
58 49, 49, 49, 49, 49, 49, 49, 49, 11, 5, 58 52, 52, 52, 52, 52, 52, 52, 52, 40, 5,
59 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, 59 0, 0, 5, 52, 0, 20, 52, 52, 10, 20,
60 5, 0, 30, 49, 0, 15, 0, 10, 0, 49, 60 5, 0, 35, 52, 0, 30, 0, 15, 0, 52,
61 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, 61 15, 52, 52, 52, 52, 52, 52, 52, 52, 52,
62 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 62 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
63 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 63 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
64 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 64 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
65 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 65 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
66 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 66 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
67 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 67 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
68 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 68 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
69 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 69 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
70 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 70 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
71 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 71 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
72 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 72 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
73 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 73 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
74 49, 49, 49, 49, 49, 49 74 52, 52, 52, 52, 52, 52
75 }; 75 };
76 register int hval = len; 76 register int hval = len;
77 77
@@ -102,25 +102,26 @@ struct kconf_id_strings_t
102 char kconf_id_strings_str12[sizeof("default")]; 102 char kconf_id_strings_str12[sizeof("default")];
103 char kconf_id_strings_str13[sizeof("def_bool")]; 103 char kconf_id_strings_str13[sizeof("def_bool")];
104 char kconf_id_strings_str14[sizeof("help")]; 104 char kconf_id_strings_str14[sizeof("help")];
105 char kconf_id_strings_str15[sizeof("bool")];
106 char kconf_id_strings_str16[sizeof("config")]; 105 char kconf_id_strings_str16[sizeof("config")];
107 char kconf_id_strings_str17[sizeof("def_tristate")]; 106 char kconf_id_strings_str17[sizeof("def_tristate")];
108 char kconf_id_strings_str18[sizeof("boolean")]; 107 char kconf_id_strings_str18[sizeof("hex")];
109 char kconf_id_strings_str19[sizeof("defconfig_list")]; 108 char kconf_id_strings_str19[sizeof("defconfig_list")];
110 char kconf_id_strings_str21[sizeof("string")];
111 char kconf_id_strings_str22[sizeof("if")]; 109 char kconf_id_strings_str22[sizeof("if")];
112 char kconf_id_strings_str23[sizeof("int")]; 110 char kconf_id_strings_str23[sizeof("int")];
113 char kconf_id_strings_str26[sizeof("select")];
114 char kconf_id_strings_str27[sizeof("modules")]; 111 char kconf_id_strings_str27[sizeof("modules")];
115 char kconf_id_strings_str28[sizeof("tristate")]; 112 char kconf_id_strings_str28[sizeof("tristate")];
116 char kconf_id_strings_str29[sizeof("menu")]; 113 char kconf_id_strings_str29[sizeof("menu")];
117 char kconf_id_strings_str31[sizeof("source")];
118 char kconf_id_strings_str32[sizeof("comment")]; 114 char kconf_id_strings_str32[sizeof("comment")];
119 char kconf_id_strings_str33[sizeof("hex")];
120 char kconf_id_strings_str35[sizeof("menuconfig")]; 115 char kconf_id_strings_str35[sizeof("menuconfig")];
121 char kconf_id_strings_str36[sizeof("prompt")]; 116 char kconf_id_strings_str36[sizeof("string")];
122 char kconf_id_strings_str37[sizeof("depends")]; 117 char kconf_id_strings_str37[sizeof("visible")];
118 char kconf_id_strings_str41[sizeof("prompt")];
119 char kconf_id_strings_str42[sizeof("depends")];
120 char kconf_id_strings_str44[sizeof("bool")];
121 char kconf_id_strings_str46[sizeof("select")];
122 char kconf_id_strings_str47[sizeof("boolean")];
123 char kconf_id_strings_str48[sizeof("mainmenu")]; 123 char kconf_id_strings_str48[sizeof("mainmenu")];
124 char kconf_id_strings_str51[sizeof("source")];
124 }; 125 };
125static struct kconf_id_strings_t kconf_id_strings_contents = 126static struct kconf_id_strings_t kconf_id_strings_contents =
126 { 127 {
@@ -136,25 +137,26 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
136 "default", 137 "default",
137 "def_bool", 138 "def_bool",
138 "help", 139 "help",
139 "bool",
140 "config", 140 "config",
141 "def_tristate", 141 "def_tristate",
142 "boolean", 142 "hex",
143 "defconfig_list", 143 "defconfig_list",
144 "string",
145 "if", 144 "if",
146 "int", 145 "int",
147 "select",
148 "modules", 146 "modules",
149 "tristate", 147 "tristate",
150 "menu", 148 "menu",
151 "source",
152 "comment", 149 "comment",
153 "hex",
154 "menuconfig", 150 "menuconfig",
151 "string",
152 "visible",
155 "prompt", 153 "prompt",
156 "depends", 154 "depends",
157 "mainmenu" 155 "bool",
156 "select",
157 "boolean",
158 "mainmenu",
159 "source"
158 }; 160 };
159#define kconf_id_strings ((const char *) &kconf_id_strings_contents) 161#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
160#ifdef __GNUC__ 162#ifdef __GNUC__
@@ -168,11 +170,11 @@ kconf_id_lookup (register const char *str, register unsigned int len)
168{ 170{
169 enum 171 enum
170 { 172 {
171 TOTAL_KEYWORDS = 31, 173 TOTAL_KEYWORDS = 32,
172 MIN_WORD_LENGTH = 2, 174 MIN_WORD_LENGTH = 2,
173 MAX_WORD_LENGTH = 14, 175 MAX_WORD_LENGTH = 14,
174 MIN_HASH_VALUE = 2, 176 MIN_HASH_VALUE = 2,
175 MAX_HASH_VALUE = 48 177 MAX_HASH_VALUE = 51
176 }; 178 };
177 179
178 static struct kconf_id wordlist[] = 180 static struct kconf_id wordlist[] =
@@ -191,31 +193,35 @@ kconf_id_lookup (register const char *str, register unsigned int len)
191 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, 193 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
192 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, 194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
193 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND}, 195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND},
194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN}, 196 {-1},
195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND}, 197 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND},
196 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, 198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
197 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN}, 199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_HEX},
198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION}, 200 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION},
199 {-1}, 201 {-1}, {-1},
200 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
201 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, 202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, 203 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
203 {-1}, {-1}, 204 {-1}, {-1}, {-1},
204 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
205 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, 205 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
206 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, 206 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
207 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, 207 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
208 {-1}, 208 {-1}, {-1},
209 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND},
210 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, 209 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
211 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX}, 210 {-1}, {-1},
212 {-1},
213 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, 211 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
214 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND}, 212 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_TYPE, TF_COMMAND, S_STRING},
215 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND}, 213 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_VISIBLE, TF_COMMAND},
216 {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, 214 {-1}, {-1}, {-1},
215 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_PROMPT, TF_COMMAND},
216 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_DEPENDS, TF_COMMAND},
217 {-1}, 217 {-1},
218 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND} 218 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44, T_TYPE, TF_COMMAND, S_BOOLEAN},
219 {-1},
220 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND},
221 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
222 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND},
223 {-1}, {-1},
224 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_SOURCE, TF_COMMAND}
219 }; 225 };
220 226
221 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 227 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index d8f7236cb0a3..3dbaec185cc4 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -304,9 +304,10 @@ void zconf_nextfile(const char *name)
304 memset(buf, 0, sizeof(*buf)); 304 memset(buf, 0, sizeof(*buf));
305 305
306 current_buf->state = YY_CURRENT_BUFFER; 306 current_buf->state = YY_CURRENT_BUFFER;
307 yyin = zconf_fopen(name); 307 yyin = zconf_fopen(file->name);
308 if (!yyin) { 308 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);
310 exit(1); 311 exit(1);
311 } 312 }
312 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 313 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
@@ -353,7 +354,7 @@ int zconf_lineno(void)
353 return current_pos.lineno; 354 return current_pos.lineno;
354} 355}
355 356
356char *zconf_curname(void) 357const char *zconf_curname(void)
357{ 358{
358 return current_pos.file ? current_pos.file->name : "<none>"; 359 return current_pos.file ? current_pos.file->name : "<none>";
359} 360}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 32a9eefd842c..4c5495ea205e 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -160,18 +160,19 @@ static struct menu *current_menu, *current_entry;
160 T_DEFAULT = 275, 160 T_DEFAULT = 275,
161 T_SELECT = 276, 161 T_SELECT = 276,
162 T_RANGE = 277, 162 T_RANGE = 277,
163 T_OPTION = 278, 163 T_VISIBLE = 278,
164 T_ON = 279, 164 T_OPTION = 279,
165 T_WORD = 280, 165 T_ON = 280,
166 T_WORD_QUOTE = 281, 166 T_WORD = 281,
167 T_UNEQUAL = 282, 167 T_WORD_QUOTE = 282,
168 T_CLOSE_PAREN = 283, 168 T_UNEQUAL = 283,
169 T_OPEN_PAREN = 284, 169 T_CLOSE_PAREN = 284,
170 T_EOL = 285, 170 T_OPEN_PAREN = 285,
171 T_OR = 286, 171 T_EOL = 286,
172 T_AND = 287, 172 T_OR = 287,
173 T_EQUAL = 288, 173 T_AND = 288,
174 T_NOT = 289 174 T_EQUAL = 289,
175 T_NOT = 290
175 }; 176 };
176#endif 177#endif
177 178
@@ -417,22 +418,22 @@ union yyalloc
417#endif 418#endif
418 419
419/* YYFINAL -- State number of the termination state. */ 420/* YYFINAL -- State number of the termination state. */
420#define YYFINAL 3 421#define YYFINAL 11
421/* YYLAST -- Last index in YYTABLE. */ 422/* YYLAST -- Last index in YYTABLE. */
422#define YYLAST 259 423#define YYLAST 290
423 424
424/* YYNTOKENS -- Number of terminals. */ 425/* YYNTOKENS -- Number of terminals. */
425#define YYNTOKENS 35 426#define YYNTOKENS 36
426/* YYNNTS -- Number of nonterminals. */ 427/* YYNNTS -- Number of nonterminals. */
427#define YYNNTS 46 428#define YYNNTS 50
428/* YYNRULES -- Number of rules. */ 429/* YYNRULES -- Number of rules. */
429#define YYNRULES 110 430#define YYNRULES 118
430/* YYNRULES -- Number of states. */ 431/* YYNRULES -- Number of states. */
431#define YYNSTATES 180 432#define YYNSTATES 191
432 433
433/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 434/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
434#define YYUNDEFTOK 2 435#define YYUNDEFTOK 2
435#define YYMAXUTOK 289 436#define YYMAXUTOK 290
436 437
437#define YYTRANSLATE(YYX) \ 438#define YYTRANSLATE(YYX) \
438 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 439 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -468,7 +469,8 @@ static const yytype_uint8 yytranslate[] =
468 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 469 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
469 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 470 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
470 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 471 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
471 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 472 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
473 35
472}; 474};
473 475
474#if YYDEBUG 476#if YYDEBUG
@@ -476,73 +478,75 @@ static const yytype_uint8 yytranslate[] =
476 YYRHS. */ 478 YYRHS. */
477static const yytype_uint16 yyprhs[] = 479static const yytype_uint16 yyprhs[] =
478{ 480{
479 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, 481 0, 0, 3, 6, 8, 11, 13, 14, 17, 20,
480 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, 482 23, 26, 31, 36, 40, 42, 44, 46, 48, 50,
481 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, 483 52, 54, 56, 58, 60, 62, 64, 66, 68, 72,
482 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, 484 75, 79, 82, 86, 89, 90, 93, 96, 99, 102,
483 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, 485 105, 108, 112, 117, 122, 127, 133, 137, 138, 142,
484 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, 486 143, 146, 150, 153, 155, 159, 160, 163, 166, 169,
485 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, 487 172, 175, 180, 184, 187, 192, 193, 196, 200, 202,
486 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, 488 206, 207, 210, 213, 216, 220, 224, 228, 230, 234,
487 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, 489 235, 238, 241, 244, 248, 252, 255, 258, 261, 262,
488 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, 490 265, 268, 271, 276, 277, 280, 283, 286, 287, 290,
489 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, 491 292, 294, 297, 300, 303, 305, 308, 309, 312, 314,
490 322 492 318, 322, 326, 329, 333, 337, 339, 341, 342
491}; 493};
492 494
493/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 495/* YYRHS -- A `-1'-separated list of the rules' RHS. */
494static const yytype_int8 yyrhs[] = 496static const yytype_int8 yyrhs[] =
495{ 497{
496 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, 498 37, 0, -1, 81, 38, -1, 38, -1, 63, 39,
497 53, -1, 37, 64, -1, 37, 3, 74, 76, -1, 499 -1, 39, -1, -1, 39, 41, -1, 39, 55, -1,
498 37, 75, -1, 37, 25, 1, 30, -1, 37, 38, 500 39, 67, -1, 39, 80, -1, 39, 26, 1, 31,
499 1, 30, -1, 37, 1, 30, -1, 16, -1, 18, 501 -1, 39, 40, 1, 31, -1, 39, 1, 31, -1,
500 -1, 19, -1, 21, -1, 17, -1, 22, -1, 20, 502 16, -1, 18, -1, 19, -1, 21, -1, 17, -1,
501 -1, 30, -1, 59, -1, 68, -1, 42, -1, 44, 503 22, -1, 20, -1, 23, -1, 31, -1, 61, -1,
502 -1, 66, -1, 25, 1, 30, -1, 1, 30, -1, 504 71, -1, 44, -1, 46, -1, 69, -1, 26, 1,
503 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, 505 31, -1, 1, 31, -1, 10, 26, 31, -1, 43,
504 -1, 43, 45, -1, -1, 45, 46, -1, 45, 47, 506 47, -1, 11, 26, 31, -1, 45, 47, -1, -1,
505 -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, 507 47, 48, -1, 47, 49, -1, 47, 75, -1, 47,
506 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, 508 73, -1, 47, 42, -1, 47, 31, -1, 19, 78,
507 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, 509 31, -1, 18, 79, 82, 31, -1, 20, 83, 82,
508 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, 510 31, -1, 21, 26, 82, 31, -1, 22, 84, 84,
509 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, 511 82, 31, -1, 24, 50, 31, -1, -1, 50, 26,
510 -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, 512 51, -1, -1, 34, 79, -1, 7, 85, 31, -1,
511 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, 513 52, 56, -1, 80, -1, 53, 58, 54, -1, -1,
512 -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, 514 56, 57, -1, 56, 75, -1, 56, 73, -1, 56,
513 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, 515 31, -1, 56, 42, -1, 18, 79, 82, 31, -1,
514 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, 516 19, 78, 31, -1, 17, 31, -1, 20, 26, 82,
515 -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, 517 31, -1, -1, 58, 41, -1, 14, 83, 81, -1,
516 -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, 518 80, -1, 59, 62, 60, -1, -1, 62, 41, -1,
517 -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, 519 62, 67, -1, 62, 55, -1, 3, 79, 81, -1,
518 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, 520 4, 79, 31, -1, 64, 76, 74, -1, 80, -1,
519 -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, 521 65, 68, 66, -1, -1, 68, 41, -1, 68, 67,
520 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, 522 -1, 68, 55, -1, 6, 79, 31, -1, 9, 79,
521 -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, 523 31, -1, 70, 74, -1, 12, 31, -1, 72, 13,
522 -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, 524 -1, -1, 74, 75, -1, 74, 31, -1, 74, 42,
523 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, 525 -1, 16, 25, 83, 31, -1, -1, 76, 77, -1,
524 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, 526 76, 31, -1, 23, 82, -1, -1, 79, 82, -1,
525 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, 527 26, -1, 27, -1, 5, 31, -1, 8, 31, -1,
526 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, 528 15, 31, -1, 31, -1, 81, 31, -1, -1, 14,
527 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, 529 83, -1, 84, -1, 84, 34, 84, -1, 84, 28,
528 -1, -1, 25, -1 530 84, -1, 30, 83, 29, -1, 35, 83, -1, 83,
531 32, 83, -1, 83, 33, 83, -1, 26, -1, 27,
532 -1, -1, 26, -1
529}; 533};
530 534
531/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 535/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
532static const yytype_uint16 yyrline[] = 536static const yytype_uint16 yyrline[] =
533{ 537{
534 0, 107, 107, 109, 111, 112, 113, 114, 115, 116, 538 0, 108, 108, 108, 110, 110, 112, 114, 115, 116,
535 117, 121, 125, 125, 125, 125, 125, 125, 125, 129, 539 117, 118, 119, 123, 127, 127, 127, 127, 127, 127,
536 130, 131, 132, 133, 134, 138, 139, 145, 153, 159, 540 127, 127, 131, 132, 133, 134, 135, 136, 140, 141,
537 167, 177, 179, 180, 181, 182, 183, 184, 187, 195, 541 147, 155, 161, 169, 179, 181, 182, 183, 184, 185,
538 201, 211, 217, 223, 226, 228, 239, 240, 245, 254, 542 186, 189, 197, 203, 213, 219, 225, 228, 230, 241,
539 259, 267, 270, 272, 273, 274, 275, 276, 279, 285, 543 242, 247, 256, 261, 269, 272, 274, 275, 276, 277,
540 296, 302, 312, 314, 319, 327, 335, 338, 340, 341, 544 278, 281, 287, 298, 304, 314, 316, 321, 329, 337,
541 342, 347, 354, 359, 367, 370, 372, 373, 374, 377, 545 340, 342, 343, 344, 349, 356, 363, 368, 376, 379,
542 385, 392, 399, 405, 412, 414, 415, 416, 419, 427, 546 381, 382, 383, 386, 394, 401, 408, 414, 421, 423,
543 429, 434, 435, 438, 439, 440, 444, 445, 448, 449, 547 424, 425, 428, 436, 438, 439, 442, 449, 451, 456,
544 452, 453, 454, 455, 456, 457, 458, 461, 462, 465, 548 457, 460, 461, 462, 466, 467, 470, 471, 474, 475,
545 466 549 476, 477, 478, 479, 480, 483, 484, 487, 488
546}; 550};
547#endif 551#endif
548 552
@@ -555,19 +559,19 @@ static const char *const yytname[] =
555 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", 559 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
556 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", 560 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
557 "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", 561 "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
558 "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", 562 "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
559 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", 563 "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", 564 "T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
561 "option_error", "config_entry_start", "config_stmt", 565 "common_stmt", "option_error", "config_entry_start", "config_stmt",
562 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", 566 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
563 "config_option", "symbol_option", "symbol_option_list", 567 "config_option", "symbol_option", "symbol_option_list",
564 "symbol_option_arg", "choice", "choice_entry", "choice_end", 568 "symbol_option_arg", "choice", "choice_entry", "choice_end",
565 "choice_stmt", "choice_option_list", "choice_option", "choice_block", 569 "choice_stmt", "choice_option_list", "choice_option", "choice_block",
566 "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", 570 "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
567 "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", 571 "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
568 "comment_stmt", "help_start", "help", "depends_list", "depends", 572 "comment", "comment_stmt", "help_start", "help", "depends_list",
569 "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 573 "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt",
570 "word_opt", 0 574 "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0
571}; 575};
572#endif 576#endif
573 577
@@ -579,42 +583,42 @@ static const yytype_uint16 yytoknum[] =
579 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 583 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
580 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 584 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
581 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 585 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
582 285, 286, 287, 288, 289 586 285, 286, 287, 288, 289, 290
583}; 587};
584# endif 588# endif
585 589
586/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 590/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
587static const yytype_uint8 yyr1[] = 591static const yytype_uint8 yyr1[] =
588{ 592{
589 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, 593 0, 36, 37, 37, 38, 38, 39, 39, 39, 39,
590 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, 594 39, 39, 39, 39, 40, 40, 40, 40, 40, 40,
591 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, 595 40, 40, 41, 41, 41, 41, 41, 41, 42, 42,
592 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, 596 43, 44, 45, 46, 47, 47, 47, 47, 47, 47,
593 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, 597 47, 48, 48, 48, 48, 48, 49, 50, 50, 51,
594 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, 598 51, 52, 53, 54, 55, 56, 56, 56, 56, 56,
595 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, 599 56, 57, 57, 57, 57, 58, 58, 59, 60, 61,
596 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, 600 62, 62, 62, 62, 63, 64, 65, 66, 67, 68,
597 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, 601 68, 68, 68, 69, 70, 71, 72, 73, 74, 74,
598 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, 602 74, 74, 75, 76, 76, 76, 77, 78, 78, 79,
599 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, 603 79, 80, 80, 80, 81, 81, 82, 82, 83, 83,
600 80 604 83, 83, 83, 83, 83, 84, 84, 85, 85
601}; 605};
602 606
603/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 607/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
604static const yytype_uint8 yyr2[] = 608static const yytype_uint8 yyr2[] =
605{ 609{
606 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, 610 0, 2, 2, 1, 2, 1, 0, 2, 2, 2,
607 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 611 2, 4, 4, 3, 1, 1, 1, 1, 1, 1,
608 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, 612 1, 1, 1, 1, 1, 1, 1, 1, 3, 2,
609 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, 613 3, 2, 3, 2, 0, 2, 2, 2, 2, 2,
610 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, 614 2, 3, 4, 4, 4, 5, 3, 0, 3, 0,
611 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, 615 2, 3, 2, 1, 3, 0, 2, 2, 2, 2,
612 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, 616 2, 4, 3, 2, 4, 0, 2, 3, 1, 3,
613 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, 617 0, 2, 2, 2, 3, 3, 3, 1, 3, 0,
614 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, 618 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
615 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, 619 2, 2, 4, 0, 2, 2, 2, 0, 2, 1,
616 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, 620 1, 2, 2, 2, 1, 2, 0, 2, 1, 3,
617 1 621 3, 3, 2, 3, 3, 1, 1, 0, 1
618}; 622};
619 623
620/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 624/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -622,158 +626,172 @@ static const yytype_uint8 yyr2[] =
622 means the default is an error. */ 626 means the default is an error. */
623static const yytype_uint8 yydefact[] = 627static const yytype_uint8 yydefact[] =
624{ 628{
625 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, 629 6, 0, 104, 0, 3, 0, 6, 6, 99, 100,
626 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, 630 0, 1, 0, 0, 0, 0, 117, 0, 0, 0,
627 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, 631 0, 0, 0, 14, 18, 15, 16, 20, 17, 19,
628 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, 632 21, 0, 22, 0, 7, 34, 25, 34, 26, 55,
629 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, 633 65, 8, 70, 23, 93, 79, 9, 27, 88, 24,
630 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, 634 10, 0, 105, 2, 74, 13, 0, 101, 0, 118,
631 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, 635 0, 102, 0, 0, 0, 115, 116, 0, 0, 0,
632 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, 636 108, 103, 0, 0, 0, 0, 0, 0, 0, 88,
633 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, 637 0, 0, 75, 83, 51, 84, 30, 32, 0, 112,
634 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, 638 0, 0, 67, 0, 0, 11, 12, 0, 0, 0,
635 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, 639 0, 97, 0, 0, 0, 47, 0, 40, 39, 35,
636 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, 640 36, 0, 38, 37, 0, 0, 97, 0, 59, 60,
637 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, 641 56, 58, 57, 66, 54, 53, 71, 73, 69, 72,
638 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, 642 68, 106, 95, 0, 94, 80, 82, 78, 81, 77,
639 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, 643 90, 91, 89, 111, 113, 114, 110, 109, 29, 86,
640 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, 644 0, 106, 0, 106, 106, 106, 0, 0, 0, 87,
641 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, 645 63, 106, 0, 106, 0, 96, 0, 0, 41, 98,
642 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 646 0, 0, 106, 49, 46, 28, 0, 62, 0, 107,
647 92, 42, 43, 44, 0, 0, 48, 61, 64, 45,
648 50
643}; 649};
644 650
645/* YYDEFGOTO[NTERM-NUM]. */ 651/* YYDEFGOTO[NTERM-NUM]. */
646static const yytype_int16 yydefgoto[] = 652static const yytype_int16 yydefgoto[] =
647{ 653{
648 -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, 654 -1, 3, 4, 5, 33, 34, 108, 35, 36, 37,
649 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, 655 38, 74, 109, 110, 157, 186, 39, 40, 124, 41,
650 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, 656 76, 120, 77, 42, 128, 43, 78, 6, 44, 45,
651 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, 657 137, 46, 80, 47, 48, 49, 111, 112, 81, 113,
652 42, 74, 156, 60, 61, 51 658 79, 134, 152, 153, 50, 7, 165, 69, 70, 60
653}; 659};
654 660
655/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 661/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
656 STATE-NUM. */ 662 STATE-NUM. */
657#define YYPACT_NINF -80 663#define YYPACT_NINF -90
658static const yytype_int16 yypact[] = 664static const yytype_int16 yypact[] =
659{ 665{
660 -80, 2, 132, -80, -13, -1, -1, -2, -1, 9, 666 4, 42, -90, 96, -90, 111, -90, 15, -90, -90,
661 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, 667 75, -90, 82, 42, 104, 42, 110, 107, 42, 115,
662 -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, 668 125, -4, 121, -90, -90, -90, -90, -90, -90, -90,
663 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 669 -90, 162, -90, 163, -90, -90, -90, -90, -90, -90,
664 -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, 670 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
665 -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, 671 -90, 139, -90, -90, 138, -90, 142, -90, 143, -90,
666 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, 672 152, -90, 164, 167, 168, -90, -90, -4, -4, 77,
667 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, 673 -18, -90, 177, 185, 33, 71, 195, 247, 236, -2,
668 -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, 674 236, 171, -90, -90, -90, -90, -90, -90, 41, -90,
669 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, 675 -4, -4, 138, 97, 97, -90, -90, 186, 187, 194,
670 -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, 676 42, 42, -4, 196, 97, -90, 219, -90, -90, -90,
671 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, 677 -90, 210, -90, -90, 204, 42, 42, 199, -90, -90,
672 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 678 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
673 -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, 679 -90, 222, -90, 223, -90, -90, -90, -90, -90, -90,
674 -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, 680 -90, -90, -90, -90, 215, -90, -90, -90, -90, -90,
675 -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, 681 -4, 222, 228, 222, -5, 222, 97, 35, 229, -90,
676 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, 682 -90, 222, 232, 222, -4, -90, 135, 233, -90, -90,
677 -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 683 234, 235, 222, 240, -90, -90, 237, -90, 239, -13,
684 -90, -90, -90, -90, 244, 42, -90, -90, -90, -90,
685 -90
678}; 686};
679 687
680/* YYPGOTO[NTERM-NUM]. */ 688/* YYPGOTO[NTERM-NUM]. */
681static const yytype_int16 yypgoto[] = 689static const yytype_int16 yypgoto[] =
682{ 690{
683 -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, 691 -90, -90, 269, 271, -90, 23, -70, -90, -90, -90,
684 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, 692 -90, 243, -90, -90, -90, -90, -90, -90, -90, -48,
685 -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, 693 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
686 -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, 694 -90, -20, -90, -90, -90, -90, -90, 206, 205, -68,
687 147, 192, 69, -54, -79, -80 695 -90, -90, 169, -1, 27, -7, 118, -66, -89, -90
688}; 696};
689 697
690/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 698/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
691 positive, shift that token. If negative, reduce the rule which 699 positive, shift that token. If negative, reduce the rule which
692 number is the opposite. If zero, do what YYDEFACT says. 700 number is the opposite. If zero, do what YYDEFACT says.
693 If YYTABLE_NINF, syntax error. */ 701 If YYTABLE_NINF, syntax error. */
694#define YYTABLE_NINF -82 702#define YYTABLE_NINF -86
695static const yytype_int16 yytable[] = 703static const yytype_int16 yytable[] =
696{ 704{
697 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, 705 10, 88, 89, 54, 146, 147, 119, 1, 122, 164,
698 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, 706 93, 141, 56, 142, 58, 156, 94, 62, 1, 90,
699 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, 707 91, 131, 65, 66, 144, 145, 67, 90, 91, 132,
700 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, 708 127, 68, 136, -31, 97, 2, 154, -31, -31, -31,
701 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, 709 -31, -31, -31, -31, -31, 98, 52, -31, -31, 99,
702 -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, 710 -31, 100, 101, 102, 103, 104, -31, 105, 129, 106,
703 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, 711 138, 173, 92, 141, 107, 142, 174, 172, 8, 9,
704 -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, 712 143, -33, 97, 90, 91, -33, -33, -33, -33, -33,
705 -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, 713 -33, -33, -33, 98, 166, -33, -33, 99, -33, 100,
706 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, 714 101, 102, 103, 104, -33, 105, 11, 106, 179, 151,
707 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, 715 123, 126, 107, 135, 125, 130, 2, 139, 2, 90,
708 -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, 716 91, -5, 12, 55, 161, 13, 14, 15, 16, 17,
709 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, 717 18, 19, 20, 65, 66, 21, 22, 23, 24, 25,
710 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, 718 26, 27, 28, 29, 30, 57, 59, 31, 61, -4,
711 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, 719 12, 63, 32, 13, 14, 15, 16, 17, 18, 19,
712 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, 720 20, 64, 71, 21, 22, 23, 24, 25, 26, 27,
713 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, 721 28, 29, 30, 72, 73, 31, 180, 90, 91, 52,
714 -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, 722 32, -85, 97, 82, 83, -85, -85, -85, -85, -85,
715 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, 723 -85, -85, -85, 84, 190, -85, -85, 99, -85, -85,
716 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, 724 -85, -85, -85, -85, -85, 85, 97, 106, 86, 87,
717 -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, 725 -52, -52, 140, -52, -52, -52, -52, 98, 95, -52,
718 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, 726 -52, 99, 114, 115, 116, 117, 96, 148, 149, 150,
719 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, 727 158, 106, 155, 159, 97, 163, 118, -76, -76, -76,
720 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, 728 -76, -76, -76, -76, -76, 160, 164, -76, -76, 99,
721 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, 729 13, 14, 15, 16, 17, 18, 19, 20, 91, 106,
722 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 730 21, 22, 14, 15, 140, 17, 18, 19, 20, 168,
731 175, 21, 22, 177, 181, 182, 183, 32, 187, 167,
732 188, 169, 170, 171, 185, 189, 53, 51, 32, 176,
733 75, 178, 121, 0, 133, 162, 0, 0, 0, 0,
734 184
723}; 735};
724 736
725static const yytype_int16 yycheck[] = 737static const yytype_int16 yycheck[] =
726{ 738{
727 5, 6, 0, 8, 58, 59, 11, 86, 87, 4, 739 1, 67, 68, 10, 93, 94, 76, 3, 76, 14,
728 5, 6, 7, 8, 9, 10, 11, 30, 97, 14, 740 28, 81, 13, 81, 15, 104, 34, 18, 3, 32,
729 15, 27, 25, 26, 25, 26, 29, 33, 30, 83, 741 33, 23, 26, 27, 90, 91, 30, 32, 33, 31,
730 84, 34, 25, 67, 25, 30, 70, 30, 72, 0, 742 78, 35, 80, 0, 1, 31, 102, 4, 5, 6,
731 1, 95, 3, 4, 5, 6, 7, 8, 9, 10, 743 7, 8, 9, 10, 11, 12, 31, 14, 15, 16,
732 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, 744 17, 18, 19, 20, 21, 22, 23, 24, 78, 26,
733 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, 745 80, 26, 69, 133, 31, 133, 31, 156, 26, 27,
734 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, 746 29, 0, 1, 32, 33, 4, 5, 6, 7, 8,
735 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, 747 9, 10, 11, 12, 150, 14, 15, 16, 17, 18,
736 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, 748 19, 20, 21, 22, 23, 24, 0, 26, 164, 100,
737 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, 749 77, 78, 31, 80, 77, 78, 31, 80, 31, 32,
738 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, 750 33, 0, 1, 31, 115, 4, 5, 6, 7, 8,
739 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, 751 9, 10, 11, 26, 27, 14, 15, 16, 17, 18,
740 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, 752 19, 20, 21, 22, 23, 31, 26, 26, 31, 0,
741 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, 753 1, 26, 31, 4, 5, 6, 7, 8, 9, 10,
742 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, 754 11, 26, 31, 14, 15, 16, 17, 18, 19, 20,
743 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, 755 21, 22, 23, 1, 1, 26, 31, 32, 33, 31,
744 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, 756 31, 0, 1, 31, 31, 4, 5, 6, 7, 8,
745 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, 757 9, 10, 11, 31, 185, 14, 15, 16, 17, 18,
746 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, 758 19, 20, 21, 22, 23, 31, 1, 26, 31, 31,
747 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, 759 5, 6, 31, 8, 9, 10, 11, 12, 31, 14,
748 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, 760 15, 16, 17, 18, 19, 20, 31, 31, 31, 25,
749 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, 761 1, 26, 26, 13, 1, 26, 31, 4, 5, 6,
750 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, 762 7, 8, 9, 10, 11, 31, 14, 14, 15, 16,
751 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, 763 4, 5, 6, 7, 8, 9, 10, 11, 33, 26,
752 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 764 14, 15, 5, 6, 31, 8, 9, 10, 11, 31,
765 31, 14, 15, 31, 31, 31, 31, 31, 31, 151,
766 31, 153, 154, 155, 34, 31, 7, 6, 31, 161,
767 37, 163, 76, -1, 79, 116, -1, -1, -1, -1,
768 172
753}; 769};
754 770
755/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 771/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
756 symbol of state STATE-NUM. */ 772 symbol of state STATE-NUM. */
757static const yytype_uint8 yystos[] = 773static const yytype_uint8 yystos[] =
758{ 774{
759 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, 775 0, 3, 31, 37, 38, 39, 63, 81, 26, 27,
760 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 776 79, 0, 1, 4, 5, 6, 7, 8, 9, 10,
761 20, 21, 22, 25, 30, 38, 39, 41, 42, 43, 777 11, 14, 15, 16, 17, 18, 19, 20, 21, 22,
762 44, 50, 51, 53, 57, 59, 61, 62, 64, 66, 778 23, 26, 31, 40, 41, 43, 44, 45, 46, 52,
763 67, 68, 75, 30, 25, 26, 74, 74, 30, 74, 779 53, 55, 59, 61, 64, 65, 67, 69, 70, 71,
764 25, 80, 30, 74, 25, 25, 25, 26, 29, 34, 780 80, 39, 31, 38, 81, 31, 79, 31, 79, 26,
765 78, 79, 30, 1, 1, 45, 45, 54, 56, 60, 781 85, 31, 79, 26, 26, 26, 27, 30, 35, 83,
766 71, 65, 71, 30, 76, 30, 30, 30, 30, 30, 782 84, 31, 1, 1, 47, 47, 56, 58, 62, 76,
767 30, 78, 78, 31, 32, 76, 27, 33, 30, 30, 783 68, 74, 31, 31, 31, 31, 31, 31, 83, 83,
768 1, 12, 16, 18, 19, 20, 21, 22, 23, 25, 784 32, 33, 81, 28, 34, 31, 31, 1, 12, 16,
769 30, 40, 46, 47, 69, 70, 72, 17, 18, 19, 785 18, 19, 20, 21, 22, 24, 26, 31, 42, 48,
770 20, 30, 40, 55, 70, 72, 39, 52, 75, 39, 786 49, 72, 73, 75, 17, 18, 19, 20, 31, 42,
771 53, 58, 64, 75, 30, 40, 72, 39, 53, 63, 787 57, 73, 75, 41, 54, 80, 41, 55, 60, 67,
772 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, 788 80, 23, 31, 74, 77, 41, 55, 66, 67, 80,
773 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, 789 31, 42, 75, 29, 83, 83, 84, 84, 31, 31,
774 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, 790 25, 79, 78, 79, 83, 26, 84, 50, 1, 13,
775 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, 791 31, 79, 78, 26, 14, 82, 83, 82, 31, 82,
776 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 792 82, 82, 84, 26, 31, 31, 82, 31, 82, 83,
793 31, 31, 31, 31, 82, 34, 51, 31, 31, 31,
794 79
777}; 795};
778 796
779#define yyerrok (yyerrstatus = 0) 797#define yyerrok (yyerrstatus = 0)
@@ -1284,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep)
1284 1302
1285 switch (yytype) 1303 switch (yytype)
1286 { 1304 {
1287 case 51: /* "choice_entry" */ 1305 case 53: /* "choice_entry" */
1288 1306
1289 { 1307 {
1290 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1308 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1294,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep)
1294}; 1312};
1295 1313
1296 break; 1314 break;
1297 case 57: /* "if_entry" */ 1315 case 59: /* "if_entry" */
1298 1316
1299 { 1317 {
1300 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1318 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1304,7 +1322,7 @@ yydestruct (yymsg, yytype, yyvaluep)
1304}; 1322};
1305 1323
1306 break; 1324 break;
1307 case 62: /* "menu_entry" */ 1325 case 65: /* "menu_entry" */
1308 1326
1309 { 1327 {
1310 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1328 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1614,39 +1632,39 @@ yyreduce:
1614 YY_REDUCE_PRINT (yyn); 1632 YY_REDUCE_PRINT (yyn);
1615 switch (yyn) 1633 switch (yyn)
1616 { 1634 {
1617 case 8: 1635 case 10:
1618 1636
1619 { zconf_error("unexpected end statement"); ;} 1637 { zconf_error("unexpected end statement"); ;}
1620 break; 1638 break;
1621 1639
1622 case 9: 1640 case 11:
1623 1641
1624 { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;} 1642 { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;}
1625 break; 1643 break;
1626 1644
1627 case 10: 1645 case 12:
1628 1646
1629 { 1647 {
1630 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); 1648 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name);
1631;} 1649;}
1632 break; 1650 break;
1633 1651
1634 case 11: 1652 case 13:
1635 1653
1636 { zconf_error("invalid statement"); ;} 1654 { zconf_error("invalid statement"); ;}
1637 break; 1655 break;
1638 1656
1639 case 25: 1657 case 28:
1640 1658
1641 { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} 1659 { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
1642 break; 1660 break;
1643 1661
1644 case 26: 1662 case 29:
1645 1663
1646 { zconf_error("invalid option"); ;} 1664 { zconf_error("invalid option"); ;}
1647 break; 1665 break;
1648 1666
1649 case 27: 1667 case 30:
1650 1668
1651 { 1669 {
1652 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); 1670 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1656,7 +1674,7 @@ yyreduce:
1656;} 1674;}
1657 break; 1675 break;
1658 1676
1659 case 28: 1677 case 31:
1660 1678
1661 { 1679 {
1662 menu_end_entry(); 1680 menu_end_entry();
@@ -1664,7 +1682,7 @@ yyreduce:
1664;} 1682;}
1665 break; 1683 break;
1666 1684
1667 case 29: 1685 case 32:
1668 1686
1669 { 1687 {
1670 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); 1688 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1674,7 +1692,7 @@ yyreduce:
1674;} 1692;}
1675 break; 1693 break;
1676 1694
1677 case 30: 1695 case 33:
1678 1696
1679 { 1697 {
1680 if (current_entry->prompt) 1698 if (current_entry->prompt)
@@ -1686,7 +1704,7 @@ yyreduce:
1686;} 1704;}
1687 break; 1705 break;
1688 1706
1689 case 38: 1707 case 41:
1690 1708
1691 { 1709 {
1692 menu_set_type((yyvsp[(1) - (3)].id)->stype); 1710 menu_set_type((yyvsp[(1) - (3)].id)->stype);
@@ -1696,7 +1714,7 @@ yyreduce:
1696;} 1714;}
1697 break; 1715 break;
1698 1716
1699 case 39: 1717 case 42:
1700 1718
1701 { 1719 {
1702 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); 1720 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1704,7 +1722,7 @@ yyreduce:
1704;} 1722;}
1705 break; 1723 break;
1706 1724
1707 case 40: 1725 case 43:
1708 1726
1709 { 1727 {
1710 menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); 1728 menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
@@ -1716,7 +1734,7 @@ yyreduce:
1716;} 1734;}
1717 break; 1735 break;
1718 1736
1719 case 41: 1737 case 44:
1720 1738
1721 { 1739 {
1722 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); 1740 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
@@ -1724,7 +1742,7 @@ yyreduce:
1724;} 1742;}
1725 break; 1743 break;
1726 1744
1727 case 42: 1745 case 45:
1728 1746
1729 { 1747 {
1730 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); 1748 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
@@ -1732,7 +1750,7 @@ yyreduce:
1732;} 1750;}
1733 break; 1751 break;
1734 1752
1735 case 45: 1753 case 48:
1736 1754
1737 { 1755 {
1738 struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); 1756 struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
@@ -1744,17 +1762,17 @@ yyreduce:
1744;} 1762;}
1745 break; 1763 break;
1746 1764
1747 case 46: 1765 case 49:
1748 1766
1749 { (yyval.string) = NULL; ;} 1767 { (yyval.string) = NULL; ;}
1750 break; 1768 break;
1751 1769
1752 case 47: 1770 case 50:
1753 1771
1754 { (yyval.string) = (yyvsp[(2) - (2)].string); ;} 1772 { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
1755 break; 1773 break;
1756 1774
1757 case 48: 1775 case 51:
1758 1776
1759 { 1777 {
1760 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); 1778 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
@@ -1765,14 +1783,14 @@ yyreduce:
1765;} 1783;}
1766 break; 1784 break;
1767 1785
1768 case 49: 1786 case 52:
1769 1787
1770 { 1788 {
1771 (yyval.menu) = menu_add_menu(); 1789 (yyval.menu) = menu_add_menu();
1772;} 1790;}
1773 break; 1791 break;
1774 1792
1775 case 50: 1793 case 53:
1776 1794
1777 { 1795 {
1778 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { 1796 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
@@ -1782,7 +1800,7 @@ yyreduce:
1782;} 1800;}
1783 break; 1801 break;
1784 1802
1785 case 58: 1803 case 61:
1786 1804
1787 { 1805 {
1788 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); 1806 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1790,7 +1808,7 @@ yyreduce:
1790;} 1808;}
1791 break; 1809 break;
1792 1810
1793 case 59: 1811 case 62:
1794 1812
1795 { 1813 {
1796 if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { 1814 if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
@@ -1803,7 +1821,7 @@ yyreduce:
1803;} 1821;}
1804 break; 1822 break;
1805 1823
1806 case 60: 1824 case 63:
1807 1825
1808 { 1826 {
1809 current_entry->sym->flags |= SYMBOL_OPTIONAL; 1827 current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1811,7 +1829,7 @@ yyreduce:
1811;} 1829;}
1812 break; 1830 break;
1813 1831
1814 case 61: 1832 case 64:
1815 1833
1816 { 1834 {
1817 if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { 1835 if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
@@ -1823,7 +1841,7 @@ yyreduce:
1823;} 1841;}
1824 break; 1842 break;
1825 1843
1826 case 64: 1844 case 67:
1827 1845
1828 { 1846 {
1829 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 1847 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
@@ -1833,7 +1851,7 @@ yyreduce:
1833;} 1851;}
1834 break; 1852 break;
1835 1853
1836 case 65: 1854 case 68:
1837 1855
1838 { 1856 {
1839 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { 1857 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
@@ -1843,7 +1861,14 @@ yyreduce:
1843;} 1861;}
1844 break; 1862 break;
1845 1863
1846 case 71: 1864 case 74:
1865
1866 {
1867 menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
1868;}
1869 break;
1870
1871 case 75:
1847 1872
1848 { 1873 {
1849 menu_add_entry(NULL); 1874 menu_add_entry(NULL);
@@ -1852,14 +1877,14 @@ yyreduce:
1852;} 1877;}
1853 break; 1878 break;
1854 1879
1855 case 72: 1880 case 76:
1856 1881
1857 { 1882 {
1858 (yyval.menu) = menu_add_menu(); 1883 (yyval.menu) = menu_add_menu();
1859;} 1884;}
1860 break; 1885 break;
1861 1886
1862 case 73: 1887 case 77:
1863 1888
1864 { 1889 {
1865 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { 1890 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
@@ -1869,7 +1894,7 @@ yyreduce:
1869;} 1894;}
1870 break; 1895 break;
1871 1896
1872 case 79: 1897 case 83:
1873 1898
1874 { 1899 {
1875 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); 1900 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
@@ -1877,7 +1902,7 @@ yyreduce:
1877;} 1902;}
1878 break; 1903 break;
1879 1904
1880 case 80: 1905 case 84:
1881 1906
1882 { 1907 {
1883 menu_add_entry(NULL); 1908 menu_add_entry(NULL);
@@ -1886,14 +1911,14 @@ yyreduce:
1886;} 1911;}
1887 break; 1912 break;
1888 1913
1889 case 81: 1914 case 85:
1890 1915
1891 { 1916 {
1892 menu_end_entry(); 1917 menu_end_entry();
1893;} 1918;}
1894 break; 1919 break;
1895 1920
1896 case 82: 1921 case 86:
1897 1922
1898 { 1923 {
1899 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 1924 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1901,14 +1926,14 @@ yyreduce:
1901;} 1926;}
1902 break; 1927 break;
1903 1928
1904 case 83: 1929 case 87:
1905 1930
1906 { 1931 {
1907 current_entry->help = (yyvsp[(2) - (2)].string); 1932 current_entry->help = (yyvsp[(2) - (2)].string);
1908;} 1933;}
1909 break; 1934 break;
1910 1935
1911 case 88: 1936 case 92:
1912 1937
1913 { 1938 {
1914 menu_add_dep((yyvsp[(3) - (4)].expr)); 1939 menu_add_dep((yyvsp[(3) - (4)].expr));
@@ -1916,84 +1941,91 @@ yyreduce:
1916;} 1941;}
1917 break; 1942 break;
1918 1943
1919 case 90: 1944 case 96:
1945
1946 {
1947 menu_add_visibility((yyvsp[(2) - (2)].expr));
1948;}
1949 break;
1950
1951 case 98:
1920 1952
1921 { 1953 {
1922 menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); 1954 menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
1923;} 1955;}
1924 break; 1956 break;
1925 1957
1926 case 93: 1958 case 101:
1927 1959
1928 { (yyval.id) = (yyvsp[(1) - (2)].id); ;} 1960 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
1929 break; 1961 break;
1930 1962
1931 case 94: 1963 case 102:
1932 1964
1933 { (yyval.id) = (yyvsp[(1) - (2)].id); ;} 1965 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
1934 break; 1966 break;
1935 1967
1936 case 95: 1968 case 103:
1937 1969
1938 { (yyval.id) = (yyvsp[(1) - (2)].id); ;} 1970 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
1939 break; 1971 break;
1940 1972
1941 case 98: 1973 case 106:
1942 1974
1943 { (yyval.expr) = NULL; ;} 1975 { (yyval.expr) = NULL; ;}
1944 break; 1976 break;
1945 1977
1946 case 99: 1978 case 107:
1947 1979
1948 { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} 1980 { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
1949 break; 1981 break;
1950 1982
1951 case 100: 1983 case 108:
1952 1984
1953 { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} 1985 { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
1954 break; 1986 break;
1955 1987
1956 case 101: 1988 case 109:
1957 1989
1958 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} 1990 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
1959 break; 1991 break;
1960 1992
1961 case 102: 1993 case 110:
1962 1994
1963 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} 1995 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
1964 break; 1996 break;
1965 1997
1966 case 103: 1998 case 111:
1967 1999
1968 { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} 2000 { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
1969 break; 2001 break;
1970 2002
1971 case 104: 2003 case 112:
1972 2004
1973 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} 2005 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
1974 break; 2006 break;
1975 2007
1976 case 105: 2008 case 113:
1977 2009
1978 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} 2010 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
1979 break; 2011 break;
1980 2012
1981 case 106: 2013 case 114:
1982 2014
1983 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} 2015 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
1984 break; 2016 break;
1985 2017
1986 case 107: 2018 case 115:
1987 2019
1988 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} 2020 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
1989 break; 2021 break;
1990 2022
1991 case 108: 2023 case 116:
1992 2024
1993 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} 2025 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
1994 break; 2026 break;
1995 2027
1996 case 109: 2028 case 117:
1997 2029
1998 { (yyval.string) = NULL; ;} 2030 { (yyval.string) = NULL; ;}
1999 break; 2031 break;
@@ -2239,6 +2271,10 @@ void conf_parse(const char *name)
2239 prop = prop_alloc(P_DEFAULT, modules_sym); 2271 prop = prop_alloc(P_DEFAULT, modules_sym);
2240 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); 2272 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
2241 } 2273 }
2274
2275 rootmenu.prompt->text = _(rootmenu.prompt->text);
2276 rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
2277
2242 menu_finalize(&rootmenu); 2278 menu_finalize(&rootmenu);
2243 for_all_symbols(i, sym) { 2279 for_all_symbols(i, sym) {
2244 if (sym_check_deps(sym)) 2280 if (sym_check_deps(sym))
@@ -2259,6 +2295,7 @@ static const char *zconf_tokenname(int token)
2259 case T_IF: return "if"; 2295 case T_IF: return "if";
2260 case T_ENDIF: return "endif"; 2296 case T_ENDIF: return "endif";
2261 case T_DEPENDS: return "depends"; 2297 case T_DEPENDS: return "depends";
2298 case T_VISIBLE: return "visible";
2262 } 2299 }
2263 return "<token>"; 2300 return "<token>";
2264} 2301}
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 23dfd3baa7a1..49fb4ab664c3 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry;
36#define YYERROR_VERBOSE 36#define YYERROR_VERBOSE
37#endif 37#endif
38%} 38%}
39%expect 26 39%expect 30
40 40
41%union 41%union
42{ 42{
@@ -68,6 +68,7 @@ static struct menu *current_menu, *current_entry;
68%token <id>T_DEFAULT 68%token <id>T_DEFAULT
69%token <id>T_SELECT 69%token <id>T_SELECT
70%token <id>T_RANGE 70%token <id>T_RANGE
71%token <id>T_VISIBLE
71%token <id>T_OPTION 72%token <id>T_OPTION
72%token <id>T_ON 73%token <id>T_ON
73%token <string> T_WORD 74%token <string> T_WORD
@@ -104,14 +105,15 @@ static struct menu *current_menu, *current_entry;
104%} 105%}
105 106
106%% 107%%
107input: stmt_list; 108input: nl start | start;
109
110start: mainmenu_stmt stmt_list | stmt_list;
108 111
109stmt_list: 112stmt_list:
110 /* empty */ 113 /* empty */
111 | stmt_list common_stmt 114 | stmt_list common_stmt
112 | stmt_list choice_stmt 115 | stmt_list choice_stmt
113 | stmt_list menu_stmt 116 | stmt_list menu_stmt
114 | stmt_list T_MAINMENU prompt nl
115 | stmt_list end { zconf_error("unexpected end statement"); } 117 | stmt_list end { zconf_error("unexpected end statement"); }
116 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } 118 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
117 | stmt_list option_name error T_EOL 119 | stmt_list option_name error T_EOL
@@ -122,7 +124,7 @@ stmt_list:
122; 124;
123 125
124option_name: 126option_name:
125 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT 127 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
126; 128;
127 129
128common_stmt: 130common_stmt:
@@ -342,6 +344,13 @@ if_block:
342 | if_block choice_stmt 344 | if_block choice_stmt
343; 345;
344 346
347/* mainmenu entry */
348
349mainmenu_stmt: T_MAINMENU prompt nl
350{
351 menu_add_prompt(P_MENU, $2, NULL);
352};
353
345/* menu entry */ 354/* menu entry */
346 355
347menu: T_MENU prompt T_EOL 356menu: T_MENU prompt T_EOL
@@ -351,7 +360,7 @@ menu: T_MENU prompt T_EOL
351 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 360 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
352}; 361};
353 362
354menu_entry: menu depends_list 363menu_entry: menu visibility_list depends_list
355{ 364{
356 $$ = menu_add_menu(); 365 $$ = menu_add_menu();
357}; 366};
@@ -422,6 +431,19 @@ depends: T_DEPENDS T_ON expr T_EOL
422 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 431 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
423}; 432};
424 433
434/* visibility option */
435
436visibility_list:
437 /* empty */
438 | visibility_list visible
439 | visibility_list T_EOL
440;
441
442visible: T_VISIBLE if_expr
443{
444 menu_add_visibility($2);
445};
446
425/* prompt statement */ 447/* prompt statement */
426 448
427prompt_stmt_opt: 449prompt_stmt_opt:
@@ -494,6 +516,10 @@ void conf_parse(const char *name)
494 prop = prop_alloc(P_DEFAULT, modules_sym); 516 prop = prop_alloc(P_DEFAULT, modules_sym);
495 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); 517 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
496 } 518 }
519
520 rootmenu.prompt->text = _(rootmenu.prompt->text);
521 rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
522
497 menu_finalize(&rootmenu); 523 menu_finalize(&rootmenu);
498 for_all_symbols(i, sym) { 524 for_all_symbols(i, sym) {
499 if (sym_check_deps(sym)) 525 if (sym_check_deps(sym))
@@ -514,6 +540,7 @@ static const char *zconf_tokenname(int token)
514 case T_IF: return "if"; 540 case T_IF: return "if";
515 case T_ENDIF: return "endif"; 541 case T_ENDIF: return "endif";
516 case T_DEPENDS: return "depends"; 542 case T_DEPENDS: return "depends";
543 case T_VISIBLE: return "visible";
517 } 544 }
518 return "<token>"; 545 return "<token>";
519} 546}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index fcdfb245a575..39580a5dc5df 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -5,7 +5,7 @@ use strict;
5## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## 5## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
6## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## 6## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
7## Copyright (C) 2001 Simon Huggins ## 7## Copyright (C) 2001 Simon Huggins ##
8## Copyright (C) 2005-2009 Randy Dunlap ## 8## Copyright (C) 2005-2010 Randy Dunlap ##
9## ## 9## ##
10## #define enhancements by Armin Kuster <akuster@mvista.com> ## 10## #define enhancements by Armin Kuster <akuster@mvista.com> ##
11## Copyright (c) 2000 MontaVista Software, Inc. ## 11## Copyright (c) 2000 MontaVista Software, Inc. ##
@@ -44,12 +44,13 @@ use strict;
44# Note: This only supports 'c'. 44# Note: This only supports 'c'.
45 45
46# usage: 46# usage:
47# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ] 47# kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ]
48# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile 48# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
49# or 49# or
50# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile 50# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
51# 51#
52# Set output format using one of -docbook -html -text or -man. Default is man. 52# Set output format using one of -docbook -html -text or -man. Default is man.
53# The -list format is for internal use by docproc.
53# 54#
54# -no-doc-sections 55# -no-doc-sections
55# Do not output DOC: sections 56# Do not output DOC: sections
@@ -210,9 +211,16 @@ my %highlights_text = ( $type_constant, "\$1",
210 $type_param, "\$1" ); 211 $type_param, "\$1" );
211my $blankline_text = ""; 212my $blankline_text = "";
212 213
214# list mode
215my %highlights_list = ( $type_constant, "\$1",
216 $type_func, "\$1",
217 $type_struct, "\$1",
218 $type_param, "\$1" );
219my $blankline_list = "";
213 220
214sub usage { 221sub 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";
216 print " [ -function funcname [ -function funcname ...] ]\n"; 224 print " [ -function funcname [ -function funcname ...] ]\n";
217 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; 225 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
218 print " c source file(s) > outputfile\n"; 226 print " c source file(s) > outputfile\n";
@@ -318,6 +326,10 @@ while ($ARGV[0] =~ m/^-(.*)/) {
318 $output_mode = "xml"; 326 $output_mode = "xml";
319 %highlights = %highlights_xml; 327 %highlights = %highlights_xml;
320 $blankline = $blankline_xml; 328 $blankline = $blankline_xml;
329 } elsif ($cmd eq "-list") {
330 $output_mode = "list";
331 %highlights = %highlights_list;
332 $blankline = $blankline_list;
321 } elsif ($cmd eq "-gnome") { 333 } elsif ($cmd eq "-gnome") {
322 $output_mode = "gnome"; 334 $output_mode = "gnome";
323 %highlights = %highlights_gnome; 335 %highlights = %highlights_gnome;
@@ -441,7 +453,7 @@ sub output_highlight {
441 if ($output_mode eq "html" || $output_mode eq "xml") { 453 if ($output_mode eq "html" || $output_mode eq "xml") {
442 $contents = local_unescape($contents); 454 $contents = local_unescape($contents);
443 # convert data read & converted thru xml_escape() into &xyz; format: 455 # convert data read & converted thru xml_escape() into &xyz; format:
444 $contents =~ s/\\\\\\/&/g; 456 $contents =~ s/\\\\\\/\&/g;
445 } 457 }
446# print STDERR "contents b4:$contents\n"; 458# print STDERR "contents b4:$contents\n";
447 eval $dohighlight; 459 eval $dohighlight;
@@ -758,7 +770,11 @@ sub output_struct_xml(%) {
758 print $args{'type'} . " " . $args{'struct'} . " {\n"; 770 print $args{'type'} . " " . $args{'struct'} . " {\n";
759 foreach $parameter (@{$args{'parameterlist'}}) { 771 foreach $parameter (@{$args{'parameterlist'}}) {
760 if ($parameter =~ /^#/) { 772 if ($parameter =~ /^#/) {
761 print "$parameter\n"; 773 my $prm = $parameter;
774 # convert data read & converted thru xml_escape() into &xyz; format:
775 # This allows us to have #define macros interspersed in a struct.
776 $prm =~ s/\\\\\\/\&/g;
777 print "$prm\n";
762 next; 778 next;
763 } 779 }
764 780
@@ -1361,6 +1377,42 @@ sub output_blockhead_text(%) {
1361 } 1377 }
1362} 1378}
1363 1379
1380## list mode output functions
1381
1382sub output_function_list(%) {
1383 my %args = %{$_[0]};
1384
1385 print $args{'function'} . "\n";
1386}
1387
1388# output enum in list
1389sub output_enum_list(%) {
1390 my %args = %{$_[0]};
1391 print $args{'enum'} . "\n";
1392}
1393
1394# output typedef in list
1395sub output_typedef_list(%) {
1396 my %args = %{$_[0]};
1397 print $args{'typedef'} . "\n";
1398}
1399
1400# output struct as list
1401sub output_struct_list(%) {
1402 my %args = %{$_[0]};
1403
1404 print $args{'struct'} . "\n";
1405}
1406
1407sub output_blockhead_list(%) {
1408 my %args = %{$_[0]};
1409 my ($parameter, $section);
1410
1411 foreach $section (@{$args{'sectionlist'}}) {
1412 print "DOC: $section\n";
1413 }
1414}
1415
1364## 1416##
1365# generic output function for all types (function, struct/union, typedef, enum); 1417# generic output function for all types (function, struct/union, typedef, enum);
1366# calls the generated, variable output_ function name based on 1418# calls the generated, variable output_ function name based on
@@ -1454,6 +1506,8 @@ sub dump_enum($$) {
1454 my $file = shift; 1506 my $file = shift;
1455 1507
1456 $x =~ s@/\*.*?\*/@@gos; # strip comments. 1508 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1509 $x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums
1510
1457 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { 1511 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
1458 $declaration_name = $1; 1512 $declaration_name = $1;
1459 my $members = $2; 1513 my $members = $2;
@@ -1651,6 +1705,8 @@ sub push_parameter($$$) {
1651 } 1705 }
1652 } 1706 }
1653 1707
1708 $param = xml_escape($param);
1709
1654 # strip spaces from $param so that it is one continous string 1710 # strip spaces from $param so that it is one continous string
1655 # on @parameterlist; 1711 # on @parameterlist;
1656 # this fixes a problem where check_sections() cannot find 1712 # this fixes a problem where check_sections() cannot find
@@ -1677,7 +1733,7 @@ sub check_sections($$$$$$) {
1677 foreach $px (0 .. $#prms) { 1733 foreach $px (0 .. $#prms) {
1678 $prm_clean = $prms[$px]; 1734 $prm_clean = $prms[$px];
1679 $prm_clean =~ s/\[.*\]//; 1735 $prm_clean =~ s/\[.*\]//;
1680 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//; 1736 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
1681 # ignore array size in a parameter string; 1737 # ignore array size in a parameter string;
1682 # however, the original param string may contain 1738 # however, the original param string may contain
1683 # spaces, e.g.: addr[6 + 2] 1739 # spaces, e.g.: addr[6 + 2]
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index 67d59c7a18dc..5325423ceab4 100644
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -44,7 +44,9 @@ all:
44 44
45Makefile:; 45Makefile:;
46 46
47\$(all) %/: all 47\$(all): all
48 @: 48 @:
49 49
50%/: all
51 @:
50EOF 52EOF
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 1ce655dde99e..33122ca04e7c 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -14,6 +14,7 @@
14#define _GNU_SOURCE 14#define _GNU_SOURCE
15#include <stdio.h> 15#include <stdio.h>
16#include <ctype.h> 16#include <ctype.h>
17#include <string.h>
17#include "modpost.h" 18#include "modpost.h"
18#include "../../include/generated/autoconf.h" 19#include "../../include/generated/autoconf.h"
19#include "../../include/linux/license.h" 20#include "../../include/linux/license.h"
@@ -789,6 +790,7 @@ static const char *section_white_list[] =
789{ 790{
790 ".comment*", 791 ".comment*",
791 ".debug*", 792 ".debug*",
793 ".GCC-command-line", /* mn10300 */
792 ".mdebug*", /* alpha, score, mips etc. */ 794 ".mdebug*", /* alpha, score, mips etc. */
793 ".pdr", /* alpha, score, mips etc. */ 795 ".pdr", /* alpha, score, mips etc. */
794 ".stab*", 796 ".stab*",
@@ -1033,6 +1035,13 @@ static const struct sectioncheck *section_mismatch(
1033 * fromsec = .data* 1035 * fromsec = .data*
1034 * atsym =__param* 1036 * atsym =__param*
1035 * 1037 *
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 *
1036 * Pattern 2: 1045 * Pattern 2:
1037 * Many drivers utilise a *driver container with references to 1046 * Many drivers utilise a *driver container with references to
1038 * add, remove, probe functions etc. 1047 * add, remove, probe functions etc.
@@ -1067,6 +1076,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
1067 (strncmp(fromsym, "__param", strlen("__param")) == 0)) 1076 (strncmp(fromsym, "__param", strlen("__param")) == 0))
1068 return 0; 1077 return 0;
1069 1078
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
1070 /* Check for pattern 2 */ 1085 /* Check for pattern 2 */
1071 if (match(tosec, init_exit_sections) && 1086 if (match(tosec, init_exit_sections) &&
1072 match(fromsec, data_sections) && 1087 match(fromsec, data_sections) &&
@@ -1193,6 +1208,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1193 * .cpuinit.data => __cpudata 1208 * .cpuinit.data => __cpudata
1194 * .memexitconst => __memconst 1209 * .memexitconst => __memconst
1195 * etc. 1210 * etc.
1211 *
1212 * The memory of returned value has been allocated on a heap. The user of this
1213 * method should free it after usage.
1196*/ 1214*/
1197static char *sec2annotation(const char *s) 1215static char *sec2annotation(const char *s)
1198{ 1216{
@@ -1215,9 +1233,9 @@ static char *sec2annotation(const char *s)
1215 strcat(p, "data "); 1233 strcat(p, "data ");
1216 else 1234 else
1217 strcat(p, " "); 1235 strcat(p, " ");
1218 return r; /* we leak her but we do not care */ 1236 return r;
1219 } else { 1237 } else {
1220 return ""; 1238 return strdup("");
1221 } 1239 }
1222} 1240}
1223 1241
@@ -1352,7 +1370,7 @@ static void report_sec_mismatch(const char *modname,
1352 "%s%s so it may be used outside an exit section.\n", 1370 "%s%s so it may be used outside an exit section.\n",
1353 from, prl_from, fromsym, from_p, 1371 from, prl_from, fromsym, from_p,
1354 to, prl_to, tosym, to_p, 1372 to, prl_to, tosym, to_p,
1355 sec2annotation(tosec), tosym, to_p); 1373 prl_to, tosym, to_p);
1356 free(prl_from); 1374 free(prl_from);
1357 free(prl_to); 1375 free(prl_to);
1358 break; 1376 break;
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index 361d0f71184b..a71be6b7cdec 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_
84my %ref = (); # $ref{$name} exists if there is a true external reference to $name 84my %ref = (); # $ref{$name} exists if there is a true external reference to $name
85my %export = (); # $export{$name} exists if there is an EXPORT_... of $name 85my %export = (); # $export{$name} exists if there is an EXPORT_... of $name
86 86
87my %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
111my %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
87&find(\&linux_objects, '.'); # find the objects and do_nm on them 145&find(\&linux_objects, '.'); # find the objects and do_nm on them
88&list_multiply_defined(); 146&list_multiply_defined();
89&resolve_external_references(); 147&resolve_external_references();
@@ -105,7 +163,8 @@ sub linux_objects
105 if (/.*\.o$/ && 163 if (/.*\.o$/ &&
106 ! ( 164 ! (
107 m:/built-in.o$: 165 m:/built-in.o$:
108 || m:arch/x86/kernel/vsyscall-syms.o$: 166 || m:arch/x86/vdso/:
167 || m:arch/x86/boot/:
109 || m:arch/ia64/ia32/ia32.o$: 168 || m:arch/ia64/ia32/ia32.o$:
110 || m:arch/ia64/kernel/gate-syms.o$: 169 || m:arch/ia64/kernel/gate-syms.o$:
111 || m:arch/ia64/lib/__divdi3.o$: 170 || m:arch/ia64/lib/__divdi3.o$:
@@ -148,6 +207,7 @@ sub linux_objects
148 || m:^.*/\.tmp_: 207 || m:^.*/\.tmp_:
149 || m:^\.tmp_: 208 || m:^\.tmp_:
150 || m:/vmlinux-obj.o$: 209 || m:/vmlinux-obj.o$:
210 || m:^tools/:
151 ) 211 )
152 ) { 212 ) {
153 do_nm($basename, $_); 213 do_nm($basename, $_);
@@ -167,11 +227,11 @@ sub do_nm
167 printf STDERR "$fullname is not an object file\n"; 227 printf STDERR "$fullname is not an object file\n";
168 return; 228 return;
169 } 229 }
170 ($source = $fullname) =~ s/\.o$//; 230 ($source = $basename) =~ s/\.o$//;
171 if (-e "$objtree$source.c" || -e "$objtree$source.S") { 231 if (-e "$source.c" || -e "$source.S") {
172 $source = "$objtree$source"; 232 $source = "$objtree$File::Find::dir/$source";
173 } else { 233 } else {
174 $source = "$srctree$source"; 234 $source = "$srctree$File::Find::dir/$source";
175 } 235 }
176 if (! -e "$source.c" && ! -e "$source.S") { 236 if (! -e "$source.c" && ! -e "$source.S") {
177 # No obvious source, exclude the object if it is conglomerate 237 # No obvious source, exclude the object if it is conglomerate
@@ -214,6 +274,7 @@ sub do_nm
214 # T global label/procedure 274 # T global label/procedure
215 # U external reference 275 # U external reference
216 # W weak external reference to text that has been resolved 276 # 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.
217 # a assembler equate 278 # a assembler equate
218 # b static variable, uninitialised 279 # b static variable, uninitialised
219 # d static variable, initialised 280 # d static variable, initialised
@@ -222,8 +283,9 @@ sub do_nm
222 # s static variable, uninitialised, small bss 283 # s static variable, uninitialised, small bss
223 # t static label/procedures 284 # t static label/procedures
224 # w weak external reference to text that has not been resolved 285 # w weak external reference to text that has not been resolved
286 # v similar to w
225 # ? undefined type, used a lot by modules 287 # ? undefined type, used a lot by modules
226 if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) { 288 if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) {
227 printf STDERR "nm output for $fullname contains unknown type '$_'\n"; 289 printf STDERR "nm output for $fullname contains unknown type '$_'\n";
228 } 290 }
229 elsif ($name =~ /\./) { 291 elsif ($name =~ /\./) {
@@ -234,7 +296,7 @@ sub do_nm
234 # binutils keeps changing the type for exported symbols, force it to R 296 # binutils keeps changing the type for exported symbols, force it to R
235 $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); 297 $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
236 $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this 298 $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this
237 if ($type =~ /[ABCDGRSTW]/ && 299 if ($type =~ /[ABCDGRSTWV]/ &&
238 $name ne 'init_module' && 300 $name ne 'init_module' &&
239 $name ne 'cleanup_module' && 301 $name ne 'cleanup_module' &&
240 $name ne 'Using_Versions' && 302 $name ne 'Using_Versions' &&
@@ -270,27 +332,9 @@ sub do_nm
270 close($nmdata); 332 close($nmdata);
271 333
272 if ($#nmdata < 0) { 334 if ($#nmdata < 0) {
273 if ( 335 printf "No nm data for $fullname\n"
274 $fullname ne "lib/brlock.o" 336 unless $nmexception{$fullname};
275 && $fullname ne "lib/dec_and_lock.o" 337 return;
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;
294 } 338 }
295 $nmdata{$fullname} = \@nmdata; 339 $nmdata{$fullname} = \@nmdata;
296} 340}
@@ -319,18 +363,14 @@ sub list_multiply_defined
319 foreach my $name (keys(%def)) { 363 foreach my $name (keys(%def)) {
320 if ($#{$def{$name}} > 0) { 364 if ($#{$def{$name}} > 0) {
321 # Special case for cond_syscall 365 # Special case for cond_syscall
322 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && 366 if ($#{$def{$name}} == 1 &&
323 ($def{$name}[0] eq "kernel/sys.o" || 367 ($name =~ /^sys_/ || $name =~ /^compat_sys_/ ||
324 $def{$name}[1] eq "kernel/sys.o")) { 368 $name =~ /^sys32_/)) {
325 &drop_def("kernel/sys.o", $name); 369 if($def{$name}[0] eq "kernel/sys_ni.o" ||
326 next; 370 $def{$name}[1] eq "kernel/sys_ni.o") {
327 } 371 &drop_def("kernel/sys_ni.o", $name);
328 # Special case for i386 entry code 372 next;
329 if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && 373 }
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;
334 } 374 }
335 375
336 printf "$name is multiply defined in :-\n"; 376 printf "$name is multiply defined in :-\n";
@@ -372,31 +412,7 @@ sub resolve_external_references
372 $ref{$name} = "" 412 $ref{$name} = ""
373 } 413 }
374 } 414 }
375 elsif ( $name ne "mod_use_count_" 415 elsif ( ! $nameexception{$name}
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"
400 && $name !~ /^__sched_text_/ 416 && $name !~ /^__sched_text_/
401 && $name !~ /^__start_/ 417 && $name !~ /^__start_/
402 && $name !~ /^__end_/ 418 && $name !~ /^__end_/
@@ -407,7 +423,6 @@ sub resolve_external_references
407 && $name !~ /^__.*per_cpu_end/ 423 && $name !~ /^__.*per_cpu_end/
408 && $name !~ /^__alt_instructions/ 424 && $name !~ /^__alt_instructions/
409 && $name !~ /^__setup_/ 425 && $name !~ /^__setup_/
410 && $name !~ /^jiffies/
411 && $name !~ /^__mod_timer/ 426 && $name !~ /^__mod_timer/
412 && $name !~ /^__mod_page_state/ 427 && $name !~ /^__mod_page_state/
413 && $name !~ /^init_module/ 428 && $name !~ /^init_module/
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 5f1e2fc7f171..49b74e1ee12d 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -66,7 +66,9 @@ else
66 cp System.map "$tmpdir/boot/System.map-$version" 66 cp System.map "$tmpdir/boot/System.map-$version"
67 cp .config "$tmpdir/boot/config-$version" 67 cp .config "$tmpdir/boot/config-$version"
68 # Not all arches include the boot path in KBUILD_IMAGE 68 # 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
70 cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version" 72 cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
71 fi 73 fi
72fi 74fi
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 15440f55aef6..e1c1d5b8ca70 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -70,7 +70,7 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware' 70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
71echo "%endif" 71echo "%endif"
72 72
73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} KBUILD_SRC= modules_install' 73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install'
74echo "%ifarch ia64" 74echo "%ifarch ia64"
75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" 75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" 76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
new file mode 100644
index 000000000000..f2f32eee2c5b
--- /dev/null
+++ b/scripts/recordmcount.c
@@ -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
35static int fd_map; /* File descriptor for file being modified. */
36static int mmap_failed; /* Boolean flag. */
37static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
38static char gpfx; /* prefix for global symbol name (sometimes '_') */
39static struct stat sb; /* Remember .st_size, etc. */
40static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
41
42/* setjmp() return values */
43enum {
44 SJ_SETJMP = 0, /* hardwired first return */
45 SJ_FAIL,
46 SJ_SUCCEED
47};
48
49/* Per-file resource cleanup when multiple files. */
50static void
51cleanup(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
60static void __attribute__((noreturn))
61fail_file(void)
62{
63 cleanup();
64 longjmp(jmpenv, SJ_FAIL);
65}
66
67static void __attribute__((noreturn))
68succeed_file(void)
69{
70 cleanup();
71 longjmp(jmpenv, SJ_SUCCEED);
72}
73
74/* ulseek, uread, ...: Check return value for errors. */
75
76static off_t
77ulseek(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
87static size_t
88uread(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
98static size_t
99uwrite(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
109static void *
110umalloc(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 */
133static 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
159static 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
171static 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
179static 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
185static uint64_t w8nat(uint64_t const x)
186{
187 return x;
188}
189
190static uint32_t w4nat(uint32_t const x)
191{
192 return x;
193}
194
195static uint32_t w2nat(uint16_t const x)
196{
197 return x;
198}
199
200static uint64_t (*w8)(uint64_t);
201static uint32_t (*w)(uint32_t);
202static uint32_t (*w2)(uint16_t);
203
204/* Names of the sections that could contain calls to mcount. */
205static int
206is_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
228typedef uint8_t myElf64_Byte; /* Type for a 8-bit quantity. */
229
230union 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
241static 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
246static 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
253static void
254do_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
357int
358main(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
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
new file mode 100644
index 000000000000..39667174971d
--- /dev/null
+++ b/scripts/recordmcount.h
@@ -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. */
108static int fn_is_fake_mcount(Elf_Rel const *rp)
109{
110 return 0;
111}
112static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount;
113
114static uint_t fn_ELF_R_SYM(Elf_Rel const *rp)
115{
116 return ELF_R_SYM(_w(rp->r_info));
117}
118static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
119
120static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
121{
122 rp->r_info = _w(ELF_R_INFO(sym, type));
123}
124static 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
147static 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. */
161static 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 */
242static 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 */
317static 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. */
346static 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
367static 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
378static 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. */
395static void
396do_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}
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 0171060b5fd6..1d7963f4ee79 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section
159my $function_regex; # Find the name of a function 159my $function_regex; # Find the name of a function
160 # (return offset and func name) 160 # (return offset and func name)
161my $mcount_regex; # Find the call site to mcount (return offset) 161my $mcount_regex; # Find the call site to mcount (return offset)
162my $mcount_adjust; # Address adjustment to mcount offset
162my $alignment; # The .align value to use for $mcount_section 163my $alignment; # The .align value to use for $mcount_section
163my $section_type; # Section header plus possible alignment command 164my $section_type; # Section header plus possible alignment command
164my $can_use_local = 0; # If we can use local function references 165my $can_use_local = 0; # If we can use local function references
@@ -213,6 +214,7 @@ $section_regex = "Disassembly of section\\s+(\\S+):";
213$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; 214$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
214$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; 215$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
215$section_type = '@progbits'; 216$section_type = '@progbits';
217$mcount_adjust = 0;
216$type = ".long"; 218$type = ".long";
217 219
218if ($arch eq "x86_64") { 220if ($arch eq "x86_64") {
@@ -268,6 +270,8 @@ if ($arch eq "x86_64") {
268} elsif ($arch eq "arm") { 270} elsif ($arch eq "arm") {
269 $alignment = 2; 271 $alignment = 2;
270 $section_type = '%progbits'; 272 $section_type = '%progbits';
273 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" .
274 "\\s+(__gnu_mcount_nc|mcount)\$";
271 275
272} elsif ($arch eq "ia64") { 276} elsif ($arch eq "ia64") {
273 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; 277 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
@@ -351,6 +355,9 @@ if ($arch eq "x86_64") {
351} elsif ($arch eq "microblaze") { 355} elsif ($arch eq "microblaze") {
352 # Microblaze calls '_mcount' instead of plain 'mcount'. 356 # Microblaze calls '_mcount' instead of plain 'mcount'.
353 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; 357 $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;
354} else { 361} else {
355 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 362 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
356} 363}
@@ -511,7 +518,7 @@ while (<IN>) {
511 } 518 }
512 # is this a call site to mcount? If so, record it to print later 519 # is this a call site to mcount? If so, record it to print later
513 if ($text_found && /$mcount_regex/) { 520 if ($text_found && /$mcount_regex/) {
514 push(@offsets, hex $1); 521 push(@offsets, (hex $1) + $mcount_adjust);
515 } 522 }
516} 523}
517 524
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 64a9cb5556cd..ef8729f48586 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -43,7 +43,7 @@ scm_version()
43 fi 43 fi
44 44
45 # Check for git and a git repo. 45 # 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
47 47
48 # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore 48 # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
49 # it, because this version is defined in the top level Makefile. 49 # it, because this version is defined in the top level Makefile.
@@ -85,8 +85,8 @@ scm_version()
85 fi 85 fi
86 86
87 # Check for mercurial and a mercurial repo. 87 # 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
89 tag=`printf '%s' "$hgid" | cut -d' ' -f2` 89 tag=`printf '%s' "$hgid" | cut -s -d' ' -f2`
90 90
91 # Do we have an untagged version? 91 # Do we have an untagged version?
92 if [ -z "$tag" -o "$tag" = tip ]; then 92 if [ -z "$tag" -o "$tag" = tip ]; then
@@ -160,8 +160,10 @@ if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
160 # full scm version string 160 # full scm version string
161 res="$res$(scm_version)" 161 res="$res$(scm_version)"
162else 162else
163 # apped a plus sign if the repository is not in a clean tagged 163 # append a plus sign if the repository is not in a clean
164 # state and LOCALVERSION= is not specified 164 # annotated or signed tagged state (as git describe only
165 # looks at signed or annotated tags - git tag -a/-s) and
166 # LOCALVERSION= is not specified
165 if test "${LOCALVERSION+set}" != "set"; then 167 if test "${LOCALVERSION+set}" != "set"; then
166 scm=$(scm_version --short) 168 scm=$(scm_version --short)
167 res="$res${scm:++}" 169 res="$res${scm:++}"
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 8509bb512935..bbbe584d4494 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -125,7 +125,9 @@ exuberant()
125 -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ 125 -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
126 --extra=+f --c-kinds=-px \ 126 --extra=+f --c-kinds=-px \
127 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ 127 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \
128 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' 128 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
129 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
130 --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/'
129 131
130 all_kconfigs | xargs $1 -a \ 132 all_kconfigs | xargs $1 -a \
131 --langdef=kconfig --language-force=kconfig \ 133 --langdef=kconfig --language-force=kconfig \