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