aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
commitf43dc23d5ea91fca257be02138a255f02d98e806 (patch)
treeb29722f6e965316e90ac97abf79923ced250dc21 /scripts
parentf8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff)
parent4162cf64973df51fc885825bc9ca4d055891c49f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts: arch/sh/kernel/cpu/sh2/setup-sh7619.c arch/sh/kernel/cpu/sh2a/setup-mxg.c arch/sh/kernel/cpu/sh2a/setup-sh7201.c arch/sh/kernel/cpu/sh2a/setup-sh7203.c arch/sh/kernel/cpu/sh2a/setup-sh7206.c arch/sh/kernel/cpu/sh3/setup-sh7705.c arch/sh/kernel/cpu/sh3/setup-sh770x.c arch/sh/kernel/cpu/sh3/setup-sh7710.c arch/sh/kernel/cpu/sh3/setup-sh7720.c arch/sh/kernel/cpu/sh4/setup-sh4-202.c arch/sh/kernel/cpu/sh4/setup-sh7750.c arch/sh/kernel/cpu/sh4/setup-sh7760.c arch/sh/kernel/cpu/sh4a/setup-sh7343.c arch/sh/kernel/cpu/sh4a/setup-sh7366.c arch/sh/kernel/cpu/sh4a/setup-sh7722.c arch/sh/kernel/cpu/sh4a/setup-sh7723.c arch/sh/kernel/cpu/sh4a/setup-sh7724.c arch/sh/kernel/cpu/sh4a/setup-sh7763.c arch/sh/kernel/cpu/sh4a/setup-sh7770.c arch/sh/kernel/cpu/sh4a/setup-sh7780.c arch/sh/kernel/cpu/sh4a/setup-sh7785.c arch/sh/kernel/cpu/sh4a/setup-sh7786.c arch/sh/kernel/cpu/sh4a/setup-shx3.c arch/sh/kernel/cpu/sh5/setup-sh5.c drivers/serial/sh-sci.c drivers/serial/sh-sci.h include/linux/serial_sci.h
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore3
-rw-r--r--scripts/Kbuild.include24
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.build64
-rw-r--r--scripts/Makefile.clean2
-rw-r--r--scripts/Makefile.headersinst3
-rw-r--r--scripts/Makefile.help3
-rw-r--r--scripts/Makefile.lib61
-rw-r--r--scripts/Makefile.modbuiltin60
-rw-r--r--scripts/Makefile.modpost21
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/docproc.c166
-rw-r--r--scripts/basic/fixdep.c145
-rw-r--r--scripts/basic/hash.c64
-rw-r--r--scripts/binoffset.c163
-rwxr-xr-xscripts/checkincludes.pl83
-rwxr-xr-xscripts/checkkconfigsymbols.sh6
-rwxr-xr-xscripts/checkpatch.pl473
-rwxr-xr-xscripts/checkstack.pl16
-rwxr-xr-xscripts/checksyscalls.sh5
-rwxr-xr-xscripts/checkversion.pl23
-rwxr-xr-xscripts/coccicheck106
-rw-r--r--scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci67
-rw-r--r--scripts/coccinelle/api/alloc/kzalloc-simple.cocci86
-rw-r--r--scripts/coccinelle/api/err_cast.cocci56
-rw-r--r--scripts/coccinelle/api/kstrdup.cocci39
-rw-r--r--scripts/coccinelle/api/memdup.cocci40
-rw-r--r--scripts/coccinelle/api/memdup_user.cocci35
-rw-r--r--scripts/coccinelle/api/resource_size.cocci93
-rw-r--r--scripts/coccinelle/free/kfree.cocci117
-rw-r--r--scripts/coccinelle/iterators/fen.cocci64
-rw-r--r--scripts/coccinelle/iterators/itnull.cocci58
-rw-r--r--scripts/coccinelle/iterators/list_entry_update.cocci62
-rw-r--r--scripts/coccinelle/locks/call_kern.cocci74
-rw-r--r--scripts/coccinelle/locks/double_lock.cocci92
-rw-r--r--scripts/coccinelle/locks/flags.cocci80
-rw-r--r--scripts/coccinelle/locks/mini_lock.cocci95
-rw-r--r--scripts/coccinelle/misc/doubleinit.cocci53
-rw-r--r--scripts/coccinelle/misc/ifcol.cocci48
-rw-r--r--scripts/coccinelle/null/deref_null.cocci282
-rw-r--r--scripts/coccinelle/null/eno.cocci20
-rw-r--r--scripts/coccinelle/null/kmerr.cocci72
-rw-r--r--scripts/coccinelle/tests/doublebitand.cocci54
-rw-r--r--scripts/coccinelle/tests/doubletest.cocci40
-rwxr-xr-xscripts/config13
-rw-r--r--scripts/conmakehash.c6
-rwxr-xr-xscripts/decodecode48
-rw-r--r--scripts/dtc/.gitignore5
-rw-r--r--scripts/dtc/Makefile3
-rw-r--r--scripts/dtc/checks.c105
-rw-r--r--scripts/dtc/data.c2
-rw-r--r--scripts/dtc/dtc-lexer.l175
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped614
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped892
-rw-r--r--scripts/dtc/dtc-parser.tab.h_shipped82
-rw-r--r--scripts/dtc/dtc-parser.y160
-rw-r--r--scripts/dtc/dtc.c57
-rw-r--r--scripts/dtc/dtc.h77
-rw-r--r--scripts/dtc/flattree.c192
-rw-r--r--scripts/dtc/fstree.c13
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c2
-rw-r--r--scripts/dtc/livetree.c345
-rw-r--r--scripts/dtc/srcpos.c258
-rw-r--r--scripts/dtc/srcpos.h99
-rw-r--r--scripts/dtc/treesource.c50
-rw-r--r--scripts/dtc/util.c59
-rw-r--r--scripts/dtc/util.h56
-rw-r--r--scripts/dtc/version_gen.h2
-rw-r--r--scripts/export_report.pl37
-rwxr-xr-xscripts/extract-ikconfig116
-rw-r--r--scripts/gcc-goto.sh5
-rw-r--r--scripts/gen_initramfs_list.sh4
-rw-r--r--scripts/genksyms/genksyms.c10
-rw-r--r--scripts/genksyms/keywords.c_shipped192
-rw-r--r--scripts/genksyms/keywords.gperf4
-rw-r--r--scripts/genksyms/parse.c_shipped2
-rw-r--r--scripts/genksyms/parse.y2
-rwxr-xr-xscripts/get_maintainer.pl1888
-rw-r--r--scripts/gfp-translate9
-rwxr-xr-xscripts/headerdep.pl3
-rwxr-xr-xscripts/headers.sh4
-rw-r--r--scripts/headers_check.pl17
-rw-r--r--scripts/headers_install.pl28
-rw-r--r--scripts/kallsyms.c8
-rw-r--r--scripts/kconfig/.gitignore1
-rw-r--r--scripts/kconfig/Makefile189
-rw-r--r--scripts/kconfig/conf.c229
-rw-r--r--scripts/kconfig/confdata.c467
-rw-r--r--scripts/kconfig/expr.c77
-rw-r--r--scripts/kconfig/expr.h13
-rw-r--r--scripts/kconfig/gconf.c157
-rw-r--r--scripts/kconfig/gconf.glade31
-rw-r--r--scripts/kconfig/kxgettext.c19
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped32
-rw-r--r--scripts/kconfig/lkc.h35
-rw-r--r--scripts/kconfig/lkc_proto.h10
-rw-r--r--scripts/kconfig/lxdialog/check-lxdialog.sh2
-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/lxdialog/util.c2
-rw-r--r--scripts/kconfig/mconf.c182
-rw-r--r--scripts/kconfig/menu.c176
-rw-r--r--scripts/kconfig/nconf.c1561
-rw-r--r--scripts/kconfig/nconf.gui.c617
-rw-r--r--scripts/kconfig/nconf.h96
-rw-r--r--scripts/kconfig/qconf.cc282
-rw-r--r--scripts/kconfig/qconf.h93
-rw-r--r--scripts/kconfig/streamline_config.pl451
-rw-r--r--scripts/kconfig/symbol.c383
-rw-r--r--scripts/kconfig/util.c11
-rw-r--r--scripts/kconfig/zconf.gperf3
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped124
-rw-r--r--scripts/kconfig/zconf.l13
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped959
-rw-r--r--scripts/kconfig/zconf.y75
-rwxr-xr-xscripts/kernel-doc227
-rw-r--r--scripts/markup_oops.pl66
-rwxr-xr-xscripts/mkcompile_h17
-rw-r--r--scripts/mkmakefile4
-rwxr-xr-xscripts/mkuboot.sh2
-rw-r--r--scripts/mod/Makefile2
-rw-r--r--scripts/mod/file2alias.c173
-rw-r--r--scripts/mod/mk_elfconfig.c9
-rw-r--r--scripts/mod/modpost.c521
-rw-r--r--scripts/mod/modpost.h46
-rw-r--r--scripts/mod/sumversion.c2
-rw-r--r--scripts/module-common.lds8
-rwxr-xr-xscripts/namespace.pl212
-rw-r--r--scripts/package/Makefile70
-rw-r--r--scripts/package/builddeb108
-rw-r--r--scripts/package/buildtar6
-rwxr-xr-xscripts/package/mkspec6
-rw-r--r--scripts/pnmtologo.c4
-rw-r--r--scripts/profile2linkerlist.pl8
-rw-r--r--scripts/recordmcount.c410
-rw-r--r--scripts/recordmcount.h443
-rwxr-xr-xscripts/recordmcount.pl335
-rw-r--r--scripts/rt-tester/rt-tester.py2
-rw-r--r--scripts/selinux/Makefile4
-rw-r--r--scripts/selinux/genheaders/.gitignore1
-rw-r--r--scripts/selinux/genheaders/Makefile5
-rw-r--r--scripts/selinux/genheaders/genheaders.c118
-rw-r--r--scripts/selinux/mdp/mdp.c153
-rwxr-xr-xscripts/setlocalversion185
-rwxr-xr-xscripts/show_delta2
-rwxr-xr-xscripts/tags.sh42
-rw-r--r--scripts/tracing/power.pl108
-rw-r--r--scripts/unifdef.c341
149 files changed, 13852 insertions, 4880 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index b939fbd01195..e2741d23bab8 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -6,4 +6,5 @@ kallsyms
6pnmtologo 6pnmtologo
7bin2c 7bin2c
8unifdef 8unifdef
9binoffset 9ihex2fw
10recordmcount
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index c29be8f90248..ed2773edfe71 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -83,11 +83,12 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
83# is automatically cleaned up. 83# is automatically cleaned up.
84try-run = $(shell set -e; \ 84try-run = $(shell set -e; \
85 TMP="$(TMPOUT).$$$$.tmp"; \ 85 TMP="$(TMPOUT).$$$$.tmp"; \
86 TMPO="$(TMPOUT).$$$$.o"; \
86 if ($(1)) >/dev/null 2>&1; \ 87 if ($(1)) >/dev/null 2>&1; \
87 then echo "$(2)"; \ 88 then echo "$(2)"; \
88 else echo "$(3)"; \ 89 else echo "$(3)"; \
89 fi; \ 90 fi; \
90 rm -f "$$TMP") 91 rm -f "$$TMP" "$$TMPO")
91 92
92# as-option 93# as-option
93# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) 94# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
@@ -99,18 +100,18 @@ as-option = $(call try-run,\
99# Usage: cflags-y += $(call as-instr,instr,option1,option2) 100# Usage: cflags-y += $(call as-instr,instr,option1,option2)
100 101
101as-instr = $(call try-run,\ 102as-instr = $(call try-run,\
102 echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) 103 /bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
103 104
104# cc-option 105# cc-option
105# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) 106# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
106 107
107cc-option = $(call try-run,\ 108cc-option = $(call try-run,\
108 $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2)) 109 $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
109 110
110# cc-option-yn 111# cc-option-yn
111# Usage: flag := $(call cc-option-yn,-march=winchip-c6) 112# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
112cc-option-yn = $(call try-run,\ 113cc-option-yn = $(call try-run,\
113 $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n) 114 $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
114 115
115# cc-option-align 116# cc-option-align
116# Prefix align with either -falign or -malign 117# Prefix align with either -falign or -malign
@@ -130,10 +131,15 @@ cc-fullversion = $(shell $(CONFIG_SHELL) \
130# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) 131# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
131cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) 132cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3))
132 133
134# cc-ldoption
135# Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
136cc-ldoption = $(call try-run,\
137 $(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2))
138
133# ld-option 139# ld-option
134# Usage: ldflags += $(call ld-option, -Wl$(comma)--hash-style=both) 140# Usage: LDFLAGS += $(call ld-option, -X)
135ld-option = $(call try-run,\ 141ld-option = $(call try-run,\
136 $(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2)) 142 $(CC) /dev/null -c -o "$$TMPO" ; $(LD) $(1) "$$TMPO" -o "$$TMP",$(1),$(2))
137 143
138###### 144######
139 145
@@ -143,6 +149,12 @@ ld-option = $(call try-run,\
143# $(Q)$(MAKE) $(build)=dir 149# $(Q)$(MAKE) $(build)=dir
144build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj 150build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
145 151
152###
153# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj=
154# Usage:
155# $(Q)$(MAKE) $(modbuiltin)=dir
156modbuiltin := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.modbuiltin obj
157
146# Prefix -I with $(srctree) if it is not an absolute path. 158# Prefix -I with $(srctree) if it is not an absolute path.
147# skip if -I has no parameter 159# skip if -I has no parameter
148addtree = $(if $(patsubst -I%,%,$(1)), \ 160addtree = $(if $(patsubst -I%,%,$(1)), \
diff --git a/scripts/Makefile b/scripts/Makefile
index 9dd5b25a1d53..2e088109fbd5 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -10,8 +10,8 @@
10hostprogs-$(CONFIG_KALLSYMS) += kallsyms 10hostprogs-$(CONFIG_KALLSYMS) += kallsyms
11hostprogs-$(CONFIG_LOGO) += pnmtologo 11hostprogs-$(CONFIG_LOGO) += pnmtologo
12hostprogs-$(CONFIG_VT) += conmakehash 12hostprogs-$(CONFIG_VT) += conmakehash
13hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
14hostprogs-$(CONFIG_IKCONFIG) += bin2c 13hostprogs-$(CONFIG_IKCONFIG) += bin2c
14hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
15 15
16always := $(hostprogs-y) $(hostprogs-m) 16always := $(hostprogs-y) $(hostprogs-m)
17 17
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 5c4b7a400c18..4eb99ab34053 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,30 +195,48 @@ 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
208ifdef CONFIG_FTRACE_MCOUNT_RECORD 211ifdef CONFIG_FTRACE_MCOUNT_RECORD
209cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ 212ifdef BUILD_C_RECORDMCOUNT
213# Due to recursion, we must skip empty.o.
214# The empty.o file is created in the make process in order to determine
215# the target endianness and word size. It is made before all other C
216# files, including recordmcount.
217sub_cmd_record_mcount = \
218 if [ $(@) != "scripts/mod/empty.o" ]; then \
219 $(objtree)/scripts/recordmcount "$(@)"; \
220 fi;
221else
222sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
223 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
210 "$(if $(CONFIG_64BIT),64,32)" \ 224 "$(if $(CONFIG_64BIT),64,32)" \
211 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ 225 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
226 "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
212 "$(if $(part-of-module),1,0)" "$(@)"; 227 "$(if $(part-of-module),1,0)" "$(@)";
213endif 228endif
229cmd_record_mcount = \
230 if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \
231 $(sub_cmd_record_mcount) \
232 fi;
233endif
214 234
215define rule_cc_o_c 235define rule_cc_o_c
216 $(call echo-cmd,checksrc) $(cmd_checksrc) \ 236 $(call echo-cmd,checksrc) $(cmd_checksrc) \
217 $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ 237 $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
218 $(cmd_modversions) \ 238 $(cmd_modversions) \
239 $(call echo-cmd,record_mcount) \
219 $(cmd_record_mcount) \ 240 $(cmd_record_mcount) \
220 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ 241 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
221 $(dot-target).tmp; \ 242 $(dot-target).tmp; \
@@ -246,10 +267,10 @@ $(obj)/%.lst: $(src)/%.c FORCE
246# Compile assembler sources (.S) 267# Compile assembler sources (.S)
247# --------------------------------------------------------------------------- 268# ---------------------------------------------------------------------------
248 269
249modkern_aflags := $(AFLAGS_KERNEL) 270modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
250 271
251$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE) 272$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
252$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE) 273$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
253 274
254quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ 275quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
255cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< 276cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
@@ -269,7 +290,8 @@ targets += $(extra-y) $(MAKECMDGOALS) $(always)
269# Linker scripts preprocessor (.lds.S -> .lds) 290# Linker scripts preprocessor (.lds.S -> .lds)
270# --------------------------------------------------------------------------- 291# ---------------------------------------------------------------------------
271quiet_cmd_cpp_lds_S = LDS $@ 292quiet_cmd_cpp_lds_S = LDS $@
272 cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $< 293 cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
294 -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
273 295
274$(obj)/%.lds: $(src)/%.lds.S FORCE 296$(obj)/%.lds: $(src)/%.lds.S FORCE
275 $(call if_changed_dep,cpp_lds_S) 297 $(call if_changed_dep,cpp_lds_S)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 6f89fbb56256..686cb0d31c7c 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -45,6 +45,8 @@ __clean-files := $(extra-y) $(always) \
45 $(host-progs) \ 45 $(host-progs) \
46 $(hostprogs-y) $(hostprogs-m) $(hostprogs-) 46 $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
47 47
48__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
49
48# as clean-files is given relative to the current directory, this adds 50# as clean-files is given relative to the current directory, this adds
49# a $(obj) prefix, except for absolute paths 51# a $(obj) prefix, except for absolute paths
50 52
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 0fcd83838771..f89cb87f5c01 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -3,7 +3,6 @@
3# 3#
4# header-y - list files to be installed. They are preprocessed 4# header-y - list files to be installed. They are preprocessed
5# to remove __KERNEL__ section of the file 5# to remove __KERNEL__ section of the file
6# unifdef-y - Same as header-y. Obsolete
7# objhdr-y - Same as header-y but for generated files 6# objhdr-y - Same as header-y but for generated files
8# 7#
9# ========================================================================== 8# ==========================================================================
@@ -20,7 +19,7 @@ include scripts/Kbuild.include
20 19
21install := $(INSTALL_HDR_PATH)/$(_dst) 20install := $(INSTALL_HDR_PATH)/$(_dst)
22 21
23header-y := $(sort $(header-y) $(unifdef-y)) 22header-y := $(sort $(header-y))
24subdirs := $(patsubst %/,%,$(filter %/, $(header-y))) 23subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
25header-y := $(filter-out %/, $(header-y)) 24header-y := $(filter-out %/, $(header-y))
26 25
diff --git a/scripts/Makefile.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 7a7778746ea6..396da16aabf8 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -101,14 +101,6 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
101modname_flags = $(if $(filter 1,$(words $(modname))),\ 101modname_flags = $(if $(filter 1,$(words $(modname))),\
102 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") 102 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
103 103
104#hash values
105ifdef CONFIG_DYNAMIC_DEBUG
106debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
107 -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
108else
109debug_flags =
110endif
111
112orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ 104orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
113 $(ccflags-y) $(CFLAGS_$(basetarget).o) 105 $(ccflags-y) $(CFLAGS_$(basetarget).o)
114_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) 106_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
@@ -127,6 +119,13 @@ _c_flags += $(if $(patsubst n%,, \
127 $(CFLAGS_GCOV)) 119 $(CFLAGS_GCOV))
128endif 120endif
129 121
122ifdef CONFIG_SYMBOL_PREFIX
123_sym_flags = -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))
124_cpp_flags += $(_sym_flags)
125_a_flags += $(_sym_flags)
126endif
127
128
130# If building the kernel in a separate objtree expand all occurrences 129# If building the kernel in a separate objtree expand all occurrences
131# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). 130# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
132 131
@@ -147,8 +146,7 @@ endif
147 146
148c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 147c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
149 $(__c_flags) $(modkern_cflags) \ 148 $(__c_flags) $(modkern_cflags) \
150 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ 149 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
151 $(debug_flags)
152 150
153a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 151a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
154 $(__a_flags) $(modkern_aflags) 152 $(__a_flags) $(modkern_aflags)
@@ -202,20 +200,48 @@ quiet_cmd_gzip = GZIP $@
202cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ 200cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \
203 (rm -f $@ ; false) 201 (rm -f $@ ; false)
204 202
203# DTC
204# ---------------------------------------------------------------------------
205
206# Generate an assembly file to wrap the output of the device tree compiler
207quiet_cmd_dt_S_dtb= DTB $@
208cmd_dt_S_dtb= \
209( \
210 echo '\#include <asm-generic/vmlinux.lds.h>'; \
211 echo '.section .dtb.init.rodata,"a"'; \
212 echo '.balign STRUCT_ALIGNMENT'; \
213 echo '.global __dtb_$(*F)_begin'; \
214 echo '__dtb_$(*F)_begin:'; \
215 echo '.incbin "$<" '; \
216 echo '__dtb_$(*F)_end:'; \
217 echo '.global __dtb_$(*F)_end'; \
218 echo '.balign STRUCT_ALIGNMENT'; \
219) > $@
220
221$(obj)/%.dtb.S: $(obj)/%.dtb
222 $(call cmd,dt_S_dtb)
223
224quiet_cmd_dtc = DTC $@
225cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $<
205 226
206# Bzip2 227# Bzip2
207# --------------------------------------------------------------------------- 228# ---------------------------------------------------------------------------
208 229
209# Bzip2 and LZMA do not include size in file... so we have to fake that; 230# Bzip2 and LZMA do not include size in file... so we have to fake that;
210# append the size as a 32-bit littleendian number as gzip does. 231# append the size as a 32-bit littleendian number as gzip does.
211size_append = echo -ne $(shell \ 232size_append = printf $(shell \
212dec_size=0; \ 233dec_size=0; \
213for F in $1; do \ 234for F in $1; do \
214 fsize=$$(stat -c "%s" $$F); \ 235 fsize=$$(stat -c "%s" $$F); \
215 dec_size=$$(expr $$dec_size + $$fsize); \ 236 dec_size=$$(expr $$dec_size + $$fsize); \
216done; \ 237done; \
217printf "%08x" $$dec_size | \ 238printf "%08x\n" $$dec_size | \
218 sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g' \ 239 sed 's/\(..\)/\1 /g' | { \
240 read ch0 ch1 ch2 ch3; \
241 for ch in $$ch3 $$ch2 $$ch1 $$ch0; do \
242 printf '%s%03o' '\\' $$((0x$$ch)); \
243 done; \
244 } \
219) 245)
220 246
221quiet_cmd_bzip2 = BZIP2 $@ 247quiet_cmd_bzip2 = BZIP2 $@
@@ -230,3 +256,12 @@ quiet_cmd_lzma = LZMA $@
230cmd_lzma = (cat $(filter-out FORCE,$^) | \ 256cmd_lzma = (cat $(filter-out FORCE,$^) | \
231 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 257 lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
232 (rm -f $@ ; false) 258 (rm -f $@ ; false)
259
260quiet_cmd_lzo = LZO $@
261cmd_lzo = (cat $(filter-out FORCE,$^) | \
262 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
263 (rm -f $@ ; false)
264
265# misc stuff
266# ---------------------------------------------------------------------------
267quote:="
diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin
new file mode 100644
index 000000000000..1adb974e6950
--- /dev/null
+++ b/scripts/Makefile.modbuiltin
@@ -0,0 +1,60 @@
1# ==========================================================================
2# Generating modules.builtin
3# ==========================================================================
4
5src := $(obj)
6
7PHONY := __modbuiltin
8__modbuiltin:
9
10-include include/config/auto.conf
11# tristate.conf sets tristate variables to uppercase 'Y' or 'M'
12# That way, we get the list of built-in modules in obj-Y
13-include include/config/tristate.conf
14
15include scripts/Kbuild.include
16
17ifneq ($(KBUILD_SRC),)
18# Create output directory if not already present
19_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
20endif
21
22# The filename Kbuild has precedence over Makefile
23kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
24kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
25include $(kbuild-file)
26
27include scripts/Makefile.lib
28__subdir-Y := $(patsubst %/,%,$(filter %/, $(obj-Y)))
29subdir-Y += $(__subdir-Y)
30subdir-ym := $(sort $(subdir-y) $(subdir-Y) $(subdir-m))
31subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
32obj-Y := $(addprefix $(obj)/,$(obj-Y))
33
34modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym))
35modbuiltin-mods := $(filter %.ko, $(obj-Y:.o=.ko))
36modbuiltin-target := $(obj)/modules.builtin
37
38__modbuiltin: $(modbuiltin-target) $(subdir-ym)
39 @:
40
41$(modbuiltin-target): $(subdir-ym) FORCE
42 $(Q)(for m in $(modbuiltin-mods); do echo kernel/$$m; done; \
43 cat /dev/null $(modbuiltin-subdirs)) > $@
44
45PHONY += FORCE
46
47FORCE:
48
49# Descending
50# ---------------------------------------------------------------------------
51
52PHONY += $(subdir-ym)
53$(subdir-ym):
54 $(Q)$(MAKE) $(modbuiltin)=$@
55
56
57# Declare the contents of the .PHONY variable as phony. We keep that
58# information in a variable se we can use it in if_changed and friends.
59
60.PHONY: $(PHONY)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index f4053dc7b5d6..7d22056582c1 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -13,7 +13,6 @@
13# 2) modpost is then used to 13# 2) modpost is then used to
14# 3) create one <module>.mod.c file pr. module 14# 3) create one <module>.mod.c file pr. module
15# 4) create one Module.symvers file with CRC for all exported symbols 15# 4) create one Module.symvers file with CRC for all exported symbols
16# 4a) [CONFIG_MARKERS] create one Module.markers file listing defined markers
17# 5) compile all <module>.mod.c files 16# 5) compile all <module>.mod.c files
18# 6) final link of the module to a <module.ko> file 17# 6) final link of the module to a <module.ko> file
19 18
@@ -31,7 +30,7 @@
31# - See include/linux/module.h for more details 30# - See include/linux/module.h for more details
32 31
33# 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,
34# 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.
35 34
36# 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
37# symbols in the final module linking stage 36# symbols in the final module linking stage
@@ -59,10 +58,6 @@ include scripts/Makefile.lib
59 58
60kernelsymfile := $(objtree)/Module.symvers 59kernelsymfile := $(objtree)/Module.symvers
61modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers 60modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
62kernelmarkersfile := $(objtree)/Module.markers
63modulemarkersfile := $(firstword $(KBUILD_EXTMOD))/Module.markers
64
65markersfile = $(if $(KBUILD_EXTMOD),$(modulemarkersfile),$(kernelmarkersfile))
66 61
67# Step 1), find all modules listed in $(MODVERDIR)/ 62# Step 1), find all modules listed in $(MODVERDIR)/
68__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) 63__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
@@ -85,8 +80,6 @@ modpost = scripts/mod/modpost \
85 $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \ 80 $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \
86 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ 81 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
87 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ 82 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
88 $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
89 $(if $(CONFIG_MARKERS),-M $(markersfile)) \
90 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \ 83 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
91 $(if $(cross_build),-c) 84 $(if $(cross_build),-c)
92 85
@@ -101,17 +94,12 @@ quiet_cmd_kernel-mod = MODPOST $@
101 cmd_kernel-mod = $(modpost) $@ 94 cmd_kernel-mod = $(modpost) $@
102 95
103vmlinux.o: FORCE 96vmlinux.o: FORCE
104 @rm -fr $(kernelmarkersfile)
105 $(call cmd,kernel-mod) 97 $(call cmd,kernel-mod)
106 98
107# Declare generated files as targets for modpost 99# Declare generated files as targets for modpost
108$(symverfile): __modpost ; 100$(symverfile): __modpost ;
109$(modules:.ko=.mod.c): __modpost ; 101$(modules:.ko=.mod.c): __modpost ;
110 102
111ifdef CONFIG_MARKERS
112$(markersfile): __modpost ;
113endif
114
115 103
116# Step 5), compile all *.mod.c files 104# Step 5), compile all *.mod.c files
117 105
@@ -119,7 +107,7 @@ endif
119modname = $(notdir $(@:.mod.o=)) 107modname = $(notdir $(@:.mod.o=))
120 108
121quiet_cmd_cc_o_c = CC $@ 109quiet_cmd_cc_o_c = CC $@
122 cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ 110 cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \
123 -c -o $@ $< 111 -c -o $@ $<
124 112
125$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE 113$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
@@ -129,8 +117,9 @@ targets += $(modules:.ko=.mod.o)
129 117
130# Step 6), final link of the modules 118# Step 6), final link of the modules
131quiet_cmd_ld_ko_o = LD [M] $@ 119quiet_cmd_ld_ko_o = LD [M] $@
132 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ 120 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
133 $(filter-out FORCE,$^) 121 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
122 -o $@ $(filter-out FORCE,$^)
134 123
135$(modules): %.ko :%.o %.mod.o FORCE 124$(modules): %.ko :%.o %.mod.o FORCE
136 $(call if_changed,ld_ko_o) 125 $(call if_changed,ld_ko_o)
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 09559951df12..4c324a1f1e0e 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,7 @@
9# fixdep: Used to generate dependency information during build process 9# fixdep: Used to generate dependency information during build process
10# docproc: Used in Documentation/DocBook 10# docproc: Used in Documentation/DocBook
11 11
12hostprogs-y := fixdep docproc hash 12hostprogs-y := fixdep docproc
13always := $(hostprogs-y) 13always := $(hostprogs-y)
14 14
15# fixdep is needed to compile other host programs 15# fixdep is needed to compile other host programs
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 99ca7a698687..98dec87974d0 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -34,12 +34,14 @@
34 * 34 *
35 */ 35 */
36 36
37#define _GNU_SOURCE
37#include <stdio.h> 38#include <stdio.h>
38#include <stdlib.h> 39#include <stdlib.h>
39#include <string.h> 40#include <string.h>
40#include <ctype.h> 41#include <ctype.h>
41#include <unistd.h> 42#include <unistd.h>
42#include <limits.h> 43#include <limits.h>
44#include <errno.h>
43#include <sys/types.h> 45#include <sys/types.h>
44#include <sys/wait.h> 46#include <sys/wait.h>
45 47
@@ -54,6 +56,7 @@ typedef void FILEONLY(char * file);
54FILEONLY *internalfunctions; 56FILEONLY *internalfunctions;
55FILEONLY *externalfunctions; 57FILEONLY *externalfunctions;
56FILEONLY *symbolsonly; 58FILEONLY *symbolsonly;
59FILEONLY *findall;
57 60
58typedef void FILELINE(char * file, char * line); 61typedef void FILELINE(char * file, char * line);
59FILELINE * singlefunctions; 62FILELINE * singlefunctions;
@@ -65,13 +68,31 @@ 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
74void usage (void) 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
95static void usage (void)
75{ 96{
76 fprintf(stderr, "Usage: docproc {doc|depend} file\n"); 97 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
77 fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n"); 98 fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
@@ -84,7 +105,7 @@ void usage (void)
84/* 105/*
85 * Execute kernel-doc with parameters given in svec 106 * Execute kernel-doc with parameters given in svec
86 */ 107 */
87void exec_kernel_doc(char **svec) 108static void exec_kernel_doc(char **svec)
88{ 109{
89 pid_t pid; 110 pid_t pid;
90 int ret; 111 int ret;
@@ -129,7 +150,7 @@ struct symfile
129struct symfile symfilelist[MAXFILES]; 150struct symfile symfilelist[MAXFILES];
130int symfilecnt = 0; 151int symfilecnt = 0;
131 152
132void add_new_symbol(struct symfile *sym, char * symname) 153static void add_new_symbol(struct symfile *sym, char * symname)
133{ 154{
134 sym->symbollist = 155 sym->symbollist =
135 realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *)); 156 realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
@@ -137,14 +158,14 @@ void add_new_symbol(struct symfile *sym, char * symname)
137} 158}
138 159
139/* Add a filename to the list */ 160/* Add a filename to the list */
140struct symfile * add_new_file(char * filename) 161static struct symfile * add_new_file(char * filename)
141{ 162{
142 symfilelist[symfilecnt++].filename = strdup(filename); 163 symfilelist[symfilecnt++].filename = strdup(filename);
143 return &symfilelist[symfilecnt - 1]; 164 return &symfilelist[symfilecnt - 1];
144} 165}
145 166
146/* Check if file already are present in the list */ 167/* Check if file already are present in the list */
147struct symfile * filename_exist(char * filename) 168static struct symfile * filename_exist(char * filename)
148{ 169{
149 int i; 170 int i;
150 for (i=0; i < symfilecnt; i++) 171 for (i=0; i < symfilecnt; i++)
@@ -157,20 +178,20 @@ struct symfile * filename_exist(char * filename)
157 * List all files referenced within the template file. 178 * List all files referenced within the template file.
158 * Files are separated by tabs. 179 * Files are separated by tabs.
159 */ 180 */
160void adddep(char * file) { printf("\t%s", file); } 181static void adddep(char * file) { printf("\t%s", file); }
161void adddep2(char * file, char * line) { line = line; adddep(file); } 182static void adddep2(char * file, char * line) { line = line; adddep(file); }
162void noaction(char * line) { line = line; } 183static void noaction(char * line) { line = line; }
163void noaction2(char * file, char * line) { file = file; line = line; } 184static void noaction2(char * file, char * line) { file = file; line = line; }
164 185
165/* Echo the line without further action */ 186/* Echo the line without further action */
166void printline(char * line) { printf("%s", line); } 187static void printline(char * line) { printf("%s", line); }
167 188
168/* 189/*
169 * Find all symbols in filename that are exported with EXPORT_SYMBOL & 190 * Find all symbols in filename that are exported with EXPORT_SYMBOL &
170 * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly). 191 * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly).
171 * All symbols located are stored in symfilelist. 192 * All symbols located are stored in symfilelist.
172 */ 193 */
173void find_export_symbols(char * filename) 194static void find_export_symbols(char * filename)
174{ 195{
175 FILE * fp; 196 FILE * fp;
176 struct symfile *sym; 197 struct symfile *sym;
@@ -227,7 +248,7 @@ void find_export_symbols(char * filename)
227 * intfunc uses -nofunction 248 * intfunc uses -nofunction
228 * extfunc uses -function 249 * extfunc uses -function
229 */ 250 */
230void docfunctions(char * filename, char * type) 251static void docfunctions(char * filename, char * type)
231{ 252{
232 int i,j; 253 int i,j;
233 int symcnt = 0; 254 int symcnt = 0;
@@ -248,6 +269,7 @@ 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 }
@@ -258,15 +280,15 @@ void docfunctions(char * filename, char * type)
258 fflush(stdout); 280 fflush(stdout);
259 free(vec); 281 free(vec);
260} 282}
261void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } 283static void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
262void extfunc(char * filename) { docfunctions(filename, FUNCTION); } 284static void extfunc(char * filename) { docfunctions(filename, FUNCTION); }
263 285
264/* 286/*
265 * Document specific function(s) in a file. 287 * Document specific function(s) in a file.
266 * Call kernel-doc with the following parameters: 288 * Call kernel-doc with the following parameters:
267 * kernel-doc -docbook -function function1 [-function function2] 289 * kernel-doc -docbook -function function1 [-function function2]
268 */ 290 */
269void singfunc(char * filename, char * line) 291static void singfunc(char * filename, char * line)
270{ 292{
271 char *vec[200]; /* Enough for specific functions */ 293 char *vec[200]; /* Enough for specific functions */
272 int i, idx = 0; 294 int i, idx = 0;
@@ -287,6 +309,11 @@ 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);
@@ -297,7 +324,7 @@ void singfunc(char * filename, char * line)
297 * Call kernel-doc with the following parameters: 324 * Call kernel-doc with the following parameters:
298 * kernel-doc -docbook -function "doc section" filename 325 * kernel-doc -docbook -function "doc section" filename
299 */ 326 */
300void docsect(char *filename, char *line) 327static void docsect(char *filename, char *line)
301{ 328{
302 char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */ 329 char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */
303 char *s; 330 char *s;
@@ -306,6 +333,13 @@ void docsect(char *filename, char *line)
306 if (*s == '\n') 333 if (*s == '\n')
307 *s = '\0'; 334 *s = '\0';
308 335
336 if (asprintf(&s, "DOC: %s", line) < 0) {
337 perror("asprintf");
338 exit(1);
339 }
340 consume_symbol(s);
341 free(s);
342
309 vec[0] = KERNELDOC; 343 vec[0] = KERNELDOC;
310 vec[1] = DOCBOOK; 344 vec[1] = DOCBOOK;
311 vec[2] = FUNCTION; 345 vec[2] = FUNCTION;
@@ -315,6 +349,84 @@ void docsect(char *filename, char *line)
315 exec_kernel_doc(vec); 349 exec_kernel_doc(vec);
316} 350}
317 351
352static void find_all_symbols(char *filename)
353{
354 char *vec[4]; /* kerneldoc -list file NULL */
355 pid_t pid;
356 int ret, i, count, start;
357 char real_filename[PATH_MAX + 1];
358 int pipefd[2];
359 char *data, *str;
360 size_t data_len = 0;
361
362 vec[0] = KERNELDOC;
363 vec[1] = LIST;
364 vec[2] = filename;
365 vec[3] = NULL;
366
367 if (pipe(pipefd)) {
368 perror("pipe");
369 exit(1);
370 }
371
372 switch (pid=fork()) {
373 case -1:
374 perror("fork");
375 exit(1);
376 case 0:
377 close(pipefd[0]);
378 dup2(pipefd[1], 1);
379 memset(real_filename, 0, sizeof(real_filename));
380 strncat(real_filename, kernsrctree, PATH_MAX);
381 strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
382 PATH_MAX - strlen(real_filename));
383 execvp(real_filename, vec);
384 fprintf(stderr, "exec ");
385 perror(real_filename);
386 exit(1);
387 default:
388 close(pipefd[1]);
389 data = malloc(4096);
390 do {
391 while ((ret = read(pipefd[0],
392 data + data_len,
393 4096)) > 0) {
394 data_len += ret;
395 data = realloc(data, data_len + 4096);
396 }
397 } while (ret == -EAGAIN);
398 if (ret != 0) {
399 perror("read");
400 exit(1);
401 }
402 waitpid(pid, &ret ,0);
403 }
404 if (WIFEXITED(ret))
405 exitstatus |= WEXITSTATUS(ret);
406 else
407 exitstatus = 0xff;
408
409 count = 0;
410 /* poor man's strtok, but with counting */
411 for (i = 0; i < data_len; i++) {
412 if (data[i] == '\n') {
413 count++;
414 data[i] = '\0';
415 }
416 }
417 start = all_list_len;
418 all_list_len += count;
419 all_list = realloc(all_list, sizeof(char *) * all_list_len);
420 str = data;
421 for (i = 0; i < data_len && start != all_list_len; i++) {
422 if (data[i] == '\0') {
423 all_list[start] = str;
424 str = data + i + 1;
425 start++;
426 }
427 }
428}
429
318/* 430/*
319 * Parse file, calling action specific functions for: 431 * Parse file, calling action specific functions for:
320 * 1) Lines containing !E 432 * 1) Lines containing !E
@@ -322,9 +434,10 @@ void docsect(char *filename, char *line)
322 * 3) Lines containing !D 434 * 3) Lines containing !D
323 * 4) Lines containing !F 435 * 4) Lines containing !F
324 * 5) Lines containing !P 436 * 5) Lines containing !P
325 * 6) Default lines - lines not matching the above 437 * 6) Lines containing !C
438 * 7) Default lines - lines not matching the above
326 */ 439 */
327void parse_file(FILE *infile) 440static void parse_file(FILE *infile)
328{ 441{
329 char line[MAXLINESZ]; 442 char line[MAXLINESZ];
330 char * s; 443 char * s;
@@ -365,6 +478,12 @@ void parse_file(FILE *infile)
365 s++; 478 s++;
366 docsection(line + 2, s); 479 docsection(line + 2, s);
367 break; 480 break;
481 case 'C':
482 while (*s && !isspace(*s)) s++;
483 *s = '\0';
484 if (findall)
485 findall(line+2);
486 break;
368 default: 487 default:
369 defaultline(line); 488 defaultline(line);
370 } 489 }
@@ -380,6 +499,7 @@ void parse_file(FILE *infile)
380int main(int argc, char *argv[]) 499int main(int argc, char *argv[])
381{ 500{
382 FILE * infile; 501 FILE * infile;
502 int i;
383 503
384 srctree = getenv("SRCTREE"); 504 srctree = getenv("SRCTREE");
385 if (!srctree) 505 if (!srctree)
@@ -415,6 +535,7 @@ int main(int argc, char *argv[])
415 symbolsonly = find_export_symbols; 535 symbolsonly = find_export_symbols;
416 singlefunctions = noaction2; 536 singlefunctions = noaction2;
417 docsection = noaction2; 537 docsection = noaction2;
538 findall = find_all_symbols;
418 parse_file(infile); 539 parse_file(infile);
419 540
420 /* Rewind to start from beginning of file again */ 541 /* Rewind to start from beginning of file again */
@@ -425,8 +546,16 @@ int main(int argc, char *argv[])
425 symbolsonly = printline; 546 symbolsonly = printline;
426 singlefunctions = singfunc; 547 singlefunctions = singfunc;
427 docsection = docsect; 548 docsection = docsect;
549 findall = NULL;
428 550
429 parse_file(infile); 551 parse_file(infile);
552
553 for (i = 0; i < all_list_len; i++) {
554 if (!all_list[i])
555 continue;
556 fprintf(stderr, "Warning: didn't use docs for %s\n",
557 all_list[i]);
558 }
430 } 559 }
431 else if (strcmp("depend", argv[1]) == 0) 560 else if (strcmp("depend", argv[1]) == 0)
432 { 561 {
@@ -439,6 +568,7 @@ int main(int argc, char *argv[])
439 symbolsonly = adddep; 568 symbolsonly = adddep;
440 singlefunctions = adddep2; 569 singlefunctions = adddep2;
441 docsection = adddep2; 570 docsection = adddep2;
571 findall = adddep;
442 parse_file(infile); 572 parse_file(infile);
443 printf("\n"); 573 printf("\n");
444 } 574 }
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 72c15205bb2b..c9a16abacab4 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -16,16 +16,15 @@
16 * tells make when to remake a file. 16 * tells make when to remake a file.
17 * 17 *
18 * To use this list as-is however has the drawback that virtually 18 * To use this list as-is however has the drawback that virtually
19 * every file in the kernel includes <linux/config.h> which then again 19 * every file in the kernel includes autoconf.h.
20 * includes <linux/autoconf.h>
21 * 20 *
22 * If the user re-runs make *config, linux/autoconf.h will be 21 * If the user re-runs make *config, autoconf.h will be
23 * regenerated. make notices that and will rebuild every file which 22 * regenerated. make notices that and will rebuild every file which
24 * includes autoconf.h, i.e. basically all files. This is extremely 23 * includes autoconf.h, i.e. basically all files. This is extremely
25 * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. 24 * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
26 * 25 *
27 * So we play the same trick that "mkdep" played before. We replace 26 * So we play the same trick that "mkdep" played before. We replace
28 * the dependency on linux/autoconf.h by a dependency on every config 27 * the dependency on autoconf.h by a dependency on every config
29 * option which is mentioned in any of the listed prequisites. 28 * option which is mentioned in any of the listed prequisites.
30 * 29 *
31 * kconfig populates a tree in include/config/ with an empty file 30 * kconfig populates a tree in include/config/ with an empty file
@@ -74,7 +73,7 @@
74 * cmd_<target> = <cmdline> 73 * cmd_<target> = <cmdline>
75 * 74 *
76 * and then basically copies the .<target>.d file to stdout, in the 75 * and then basically copies the .<target>.d file to stdout, in the
77 * process filtering out the dependency on linux/autoconf.h and adding 76 * process filtering out the dependency on autoconf.h and adding
78 * dependencies on include/config/my/option.h for every 77 * dependencies on include/config/my/option.h for every
79 * CONFIG_MY_OPTION encountered in any of the prequisites. 78 * CONFIG_MY_OPTION encountered in any of the prequisites.
80 * 79 *
@@ -125,8 +124,7 @@ char *target;
125char *depfile; 124char *depfile;
126char *cmdline; 125char *cmdline;
127 126
128void usage(void) 127static void usage(void)
129
130{ 128{
131 fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); 129 fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
132 exit(1); 130 exit(1);
@@ -135,43 +133,41 @@ void usage(void)
135/* 133/*
136 * Print out the commandline prefixed with cmd_<target filename> := 134 * Print out the commandline prefixed with cmd_<target filename> :=
137 */ 135 */
138void print_cmdline(void) 136static void print_cmdline(void)
139{ 137{
140 printf("cmd_%s := %s\n\n", target, cmdline); 138 printf("cmd_%s := %s\n\n", target, cmdline);
141} 139}
142 140
143char * str_config = NULL; 141struct item {
144int size_config = 0; 142 struct item *next;
145int len_config = 0; 143 unsigned int len;
144 unsigned int hash;
145 char name[0];
146};
146 147
147/* 148#define HASHSZ 256
148 * Grow the configuration string to a desired length. 149static struct item *hashtab[HASHSZ];
149 * Usually the first growth is plenty.
150 */
151void grow_config(int len)
152{
153 while (len_config + len > size_config) {
154 if (size_config == 0)
155 size_config = 2048;
156 str_config = realloc(str_config, size_config *= 2);
157 if (str_config == NULL)
158 { perror("fixdep:malloc"); exit(1); }
159 }
160}
161 150
151static unsigned int strhash(const char *str, unsigned int sz)
152{
153 /* fnv32 hash */
154 unsigned int i, hash = 2166136261U;
162 155
156 for (i = 0; i < sz; i++)
157 hash = (hash ^ str[i]) * 0x01000193;
158 return hash;
159}
163 160
164/* 161/*
165 * Lookup a value in the configuration string. 162 * Lookup a value in the configuration string.
166 */ 163 */
167int is_defined_config(const char * name, int len) 164static int is_defined_config(const char *name, int len, unsigned int hash)
168{ 165{
169 const char * pconfig; 166 struct item *aux;
170 const char * plast = str_config + len_config - len; 167
171 for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { 168 for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) {
172 if (pconfig[ -1] == '\n' 169 if (aux->hash == hash && aux->len == len &&
173 && pconfig[len] == '\n' 170 memcmp(aux->name, name, len) == 0)
174 && !memcmp(pconfig, name, len))
175 return 1; 171 return 1;
176 } 172 }
177 return 0; 173 return 0;
@@ -180,54 +176,69 @@ int is_defined_config(const char * name, int len)
180/* 176/*
181 * Add a new value to the configuration string. 177 * Add a new value to the configuration string.
182 */ 178 */
183void define_config(const char * name, int len) 179static void define_config(const char *name, int len, unsigned int hash)
184{ 180{
185 grow_config(len + 1); 181 struct item *aux = malloc(sizeof(*aux) + len);
186 182
187 memcpy(str_config+len_config, name, len); 183 if (!aux) {
188 len_config += len; 184 perror("fixdep:malloc");
189 str_config[len_config++] = '\n'; 185 exit(1);
186 }
187 memcpy(aux->name, name, len);
188 aux->len = len;
189 aux->hash = hash;
190 aux->next = hashtab[hash % HASHSZ];
191 hashtab[hash % HASHSZ] = aux;
190} 192}
191 193
192/* 194/*
193 * Clear the set of configuration strings. 195 * Clear the set of configuration strings.
194 */ 196 */
195void clear_config(void) 197static void clear_config(void)
196{ 198{
197 len_config = 0; 199 struct item *aux, *next;
198 define_config("", 0); 200 unsigned int i;
201
202 for (i = 0; i < HASHSZ; i++) {
203 for (aux = hashtab[i]; aux; aux = next) {
204 next = aux->next;
205 free(aux);
206 }
207 hashtab[i] = NULL;
208 }
199} 209}
200 210
201/* 211/*
202 * Record the use of a CONFIG_* word. 212 * Record the use of a CONFIG_* word.
203 */ 213 */
204void use_config(char *m, int slen) 214static void use_config(const char *m, int slen)
205{ 215{
206 char s[PATH_MAX]; 216 unsigned int hash = strhash(m, slen);
207 char *p; 217 int c, i;
208 218
209 if (is_defined_config(m, slen)) 219 if (is_defined_config(m, slen, hash))
210 return; 220 return;
211 221
212 define_config(m, slen); 222 define_config(m, slen, hash);
213 223
214 memcpy(s, m, slen); s[slen] = 0; 224 printf(" $(wildcard include/config/");
215 225 for (i = 0; i < slen; i++) {
216 for (p = s; p < s + slen; p++) { 226 c = m[i];
217 if (*p == '_') 227 if (c == '_')
218 *p = '/'; 228 c = '/';
219 else 229 else
220 *p = tolower((int)*p); 230 c = tolower(c);
231 putchar(c);
221 } 232 }
222 printf(" $(wildcard include/config/%s.h) \\\n", s); 233 printf(".h) \\\n");
223} 234}
224 235
225void parse_config_file(char *map, size_t len) 236static void parse_config_file(const char *map, size_t len)
226{ 237{
227 int *end = (int *) (map + len); 238 const int *end = (const int *) (map + len);
228 /* start at +1, so that p can never be < map */ 239 /* start at +1, so that p can never be < map */
229 int *m = (int *) map + 1; 240 const int *m = (const int *) map + 1;
230 char *p, *q; 241 const char *p, *q;
231 242
232 for (; m < end; m++) { 243 for (; m < end; m++) {
233 if (*m == INT_CONF) { p = (char *) m ; goto conf; } 244 if (*m == INT_CONF) { p = (char *) m ; goto conf; }
@@ -256,7 +267,7 @@ void parse_config_file(char *map, size_t len)
256} 267}
257 268
258/* test is s ends in sub */ 269/* test is s ends in sub */
259int strrcmp(char *s, char *sub) 270static int strrcmp(char *s, char *sub)
260{ 271{
261 int slen = strlen(s); 272 int slen = strlen(s);
262 int sublen = strlen(sub); 273 int sublen = strlen(sub);
@@ -267,7 +278,7 @@ int strrcmp(char *s, char *sub)
267 return memcmp(s + slen - sublen, sub, sublen); 278 return memcmp(s + slen - sublen, sub, sublen);
268} 279}
269 280
270void do_config_file(char *filename) 281static void do_config_file(const char *filename)
271{ 282{
272 struct stat st; 283 struct stat st;
273 int fd; 284 int fd;
@@ -275,7 +286,7 @@ void do_config_file(char *filename)
275 286
276 fd = open(filename, O_RDONLY); 287 fd = open(filename, O_RDONLY);
277 if (fd < 0) { 288 if (fd < 0) {
278 fprintf(stderr, "fixdep: "); 289 fprintf(stderr, "fixdep: error opening config file: ");
279 perror(filename); 290 perror(filename);
280 exit(2); 291 exit(2);
281 } 292 }
@@ -298,7 +309,7 @@ void do_config_file(char *filename)
298 close(fd); 309 close(fd);
299} 310}
300 311
301void parse_dep_file(void *map, size_t len) 312static void parse_dep_file(void *map, size_t len)
302{ 313{
303 char *m = map; 314 char *m = map;
304 char *end = m + len; 315 char *end = m + len;
@@ -326,7 +337,7 @@ void parse_dep_file(void *map, size_t len)
326 p++; 337 p++;
327 } 338 }
328 memcpy(s, m, p-m); s[p-m] = 0; 339 memcpy(s, m, p-m); s[p-m] = 0;
329 if (strrcmp(s, "include/linux/autoconf.h") && 340 if (strrcmp(s, "include/generated/autoconf.h") &&
330 strrcmp(s, "arch/um/include/uml-config.h") && 341 strrcmp(s, "arch/um/include/uml-config.h") &&
331 strrcmp(s, ".ver")) { 342 strrcmp(s, ".ver")) {
332 printf(" %s \\\n", s); 343 printf(" %s \\\n", s);
@@ -338,7 +349,7 @@ void parse_dep_file(void *map, size_t len)
338 printf("$(deps_%s):\n", target); 349 printf("$(deps_%s):\n", target);
339} 350}
340 351
341void print_deps(void) 352static void print_deps(void)
342{ 353{
343 struct stat st; 354 struct stat st;
344 int fd; 355 int fd;
@@ -346,11 +357,15 @@ void print_deps(void)
346 357
347 fd = open(depfile, O_RDONLY); 358 fd = open(depfile, O_RDONLY);
348 if (fd < 0) { 359 if (fd < 0) {
349 fprintf(stderr, "fixdep: "); 360 fprintf(stderr, "fixdep: error opening depfile: ");
350 perror(depfile); 361 perror(depfile);
351 exit(2); 362 exit(2);
352 } 363 }
353 fstat(fd, &st); 364 if (fstat(fd, &st) < 0) {
365 fprintf(stderr, "fixdep: error fstat'ing depfile: ");
366 perror(depfile);
367 exit(2);
368 }
354 if (st.st_size == 0) { 369 if (st.st_size == 0) {
355 fprintf(stderr,"fixdep: %s is empty\n",depfile); 370 fprintf(stderr,"fixdep: %s is empty\n",depfile);
356 close(fd); 371 close(fd);
@@ -370,7 +385,7 @@ void print_deps(void)
370 close(fd); 385 close(fd);
371} 386}
372 387
373void traps(void) 388static void traps(void)
374{ 389{
375 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; 390 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
376 int *p = (int *)test; 391 int *p = (int *)test;
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
deleted file mode 100644
index 3299ad7fc8c0..000000000000
--- a/scripts/basic/hash.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
3 *
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#define DYNAMIC_DEBUG_HASH_BITS 6
11
12static const char *program;
13
14static void usage(void)
15{
16 printf("Usage: %s <djb2|r5> <modname>\n", program);
17 exit(1);
18}
19
20/* djb2 hashing algorithm by Dan Bernstein. From:
21 * http://www.cse.yorku.ca/~oz/hash.html
22 */
23
24unsigned int djb2_hash(char *str)
25{
26 unsigned long hash = 5381;
27 int c;
28
29 c = *str;
30 while (c) {
31 hash = ((hash << 5) + hash) + c;
32 c = *++str;
33 }
34 return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
35}
36
37unsigned int r5_hash(char *str)
38{
39 unsigned long hash = 0;
40 int c;
41
42 c = *str;
43 while (c) {
44 hash = (hash + (c << 4) + (c >> 4)) * 11;
45 c = *++str;
46 }
47 return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
48}
49
50int main(int argc, char *argv[])
51{
52 program = argv[0];
53
54 if (argc != 3)
55 usage();
56 if (!strcmp(argv[1], "djb2"))
57 printf("%d\n", djb2_hash(argv[2]));
58 else if (!strcmp(argv[1], "r5"))
59 printf("%d\n", r5_hash(argv[2]));
60 else
61 usage();
62 exit(0);
63}
64
diff --git a/scripts/binoffset.c b/scripts/binoffset.c
deleted file mode 100644
index 1a2e39b8e3e5..000000000000
--- a/scripts/binoffset.c
+++ /dev/null
@@ -1,163 +0,0 @@
1/***************************************************************************
2 * binoffset.c
3 * (C) 2002 Randy Dunlap <rdunlap@xenotime.net>
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19# binoffset.c:
20# - searches a (binary) file for a specified (binary) pattern
21# - returns the offset of the located pattern or ~0 if not found
22# - exits with exit status 0 normally or non-0 if pattern is not found
23# or any other error occurs.
24
25****************************************************************/
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <errno.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/mman.h>
36
37#define VERSION "0.1"
38#define BUF_SIZE (16 * 1024)
39#define PAT_SIZE 100
40
41char *progname;
42char *inputname;
43int inputfd;
44unsigned int bix; /* buf index */
45unsigned char patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */
46int pat_len; /* actual number of pattern bytes */
47unsigned char *madr; /* mmap address */
48size_t filesize;
49int num_matches = 0;
50off_t firstloc = 0;
51
52void usage (void)
53{
54 fprintf (stderr, "%s ver. %s\n", progname, VERSION);
55 fprintf (stderr, "usage: %s filename pattern_bytes\n",
56 progname);
57 fprintf (stderr, " [prints location of pattern_bytes in file]\n");
58 exit (1);
59}
60
61void get_pattern (int pat_count, char *pats [])
62{
63 int ix, err, tmp;
64
65#ifdef DEBUG
66 fprintf (stderr,"get_pattern: count = %d\n", pat_count);
67 for (ix = 0; ix < pat_count; ix++)
68 fprintf (stderr, " pat # %d: [%s]\n", ix, pats[ix]);
69#endif
70
71 for (ix = 0; ix < pat_count; ix++) {
72 tmp = 0;
73 err = sscanf (pats[ix], "%5i", &tmp);
74 if (err != 1 || tmp > 0xff) {
75 fprintf (stderr, "pattern or value error in pattern # %d [%s]\n",
76 ix, pats[ix]);
77 usage ();
78 }
79 patterns [ix] = tmp;
80 }
81 pat_len = pat_count;
82}
83
84void search_pattern (void)
85{
86 for (bix = 0; bix < filesize; bix++) {
87 if (madr[bix] == patterns[0]) {
88 if (memcmp (&madr[bix], patterns, pat_len) == 0) {
89 if (num_matches == 0)
90 firstloc = bix;
91 num_matches++;
92 }
93 }
94 }
95}
96
97#ifdef NOTDEF
98size_t get_filesize (int fd)
99{
100 off_t end_off = lseek (fd, 0, SEEK_END);
101 lseek (fd, 0, SEEK_SET);
102 return (size_t) end_off;
103}
104#endif
105
106size_t get_filesize (int fd)
107{
108 int err;
109 struct stat stat;
110
111 err = fstat (fd, &stat);
112 fprintf (stderr, "filesize: %ld\n", err < 0 ? (long)err : stat.st_size);
113 if (err < 0)
114 return err;
115 return (size_t) stat.st_size;
116}
117
118int main (int argc, char *argv [])
119{
120 progname = argv[0];
121
122 if (argc < 3)
123 usage ();
124
125 get_pattern (argc - 2, argv + 2);
126
127 inputname = argv[1];
128
129 inputfd = open (inputname, O_RDONLY);
130 if (inputfd == -1) {
131 fprintf (stderr, "%s: cannot open '%s'\n",
132 progname, inputname);
133 exit (3);
134 }
135
136 filesize = get_filesize (inputfd);
137
138 madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0);
139 if (madr == MAP_FAILED) {
140 fprintf (stderr, "mmap error = %d\n", errno);
141 close (inputfd);
142 exit (4);
143 }
144
145 search_pattern ();
146
147 if (munmap (madr, filesize))
148 fprintf (stderr, "munmap error = %d\n", errno);
149
150 if (close (inputfd))
151 fprintf (stderr, "%s: error %d closing '%s'\n",
152 progname, errno, inputname);
153
154 fprintf (stderr, "number of pattern matches = %d\n", num_matches);
155 if (num_matches == 0)
156 firstloc = ~0;
157 printf ("%ld\n", firstloc);
158 fprintf (stderr, "%ld\n", firstloc);
159
160 exit (num_matches ? 0 : 2);
161}
162
163/* end binoffset.c */
diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl
index 8e6b716c191c..97b2c6143fe4 100755
--- a/scripts/checkincludes.pl
+++ b/scripts/checkincludes.pl
@@ -1,24 +1,89 @@
1#!/usr/bin/perl 1#!/usr/bin/perl
2# 2#
3# checkincludes: Find files included more than once in (other) files. 3# checkincludes: find/remove files included more than once
4#
4# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. 5# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>.
6# Copyright 2009 Luis R. Rodriguez <mcgrof@gmail.com>
7#
8# This script checks for duplicate includes. It also has support
9# to remove them in place. Note that this will not take into
10# consideration macros so you should run this only if you know
11# you do have real dups and do not have them under #ifdef's. You
12# could also just review the results.
13
14use strict;
15
16sub usage {
17 print "Usage: checkincludes.pl [-r]\n";
18 print "By default we just warn of duplicates\n";
19 print "To remove duplicated includes in place use -r\n";
20 exit 1;
21}
5 22
6foreach $file (@ARGV) { 23my $remove = 0;
7 open(FILE, $file) or die "Cannot open $file: $!.\n"; 24
25if ($#ARGV < 0) {
26 usage();
27}
28
29if ($#ARGV >= 1) {
30 if ($ARGV[0] =~ /^-/) {
31 if ($ARGV[0] eq "-r") {
32 $remove = 1;
33 shift;
34 } else {
35 usage();
36 }
37 }
38}
39
40foreach my $file (@ARGV) {
41 open(my $f, '<', $file)
42 or die "Cannot open $file: $!.\n";
8 43
9 my %includedfiles = (); 44 my %includedfiles = ();
45 my @file_lines = ();
10 46
11 while (<FILE>) { 47 while (<$f>) {
12 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 48 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
13 ++$includedfiles{$1}; 49 ++$includedfiles{$1};
14 } 50 }
51 push(@file_lines, $_);
15 } 52 }
16 53
17 foreach $filename (keys %includedfiles) { 54 close($f);
18 if ($includedfiles{$filename} > 1) { 55
19 print "$file: $filename is included more than once.\n"; 56 if (!$remove) {
57 foreach my $filename (keys %includedfiles) {
58 if ($includedfiles{$filename} > 1) {
59 print "$file: $filename is included more than once.\n";
60 }
20 } 61 }
62 next;
21 } 63 }
22 64
23 close(FILE); 65 open($f, '>', $file)
66 or die("Cannot write to $file: $!");
67
68 my $dups = 0;
69 foreach (@file_lines) {
70 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
71 foreach my $filename (keys %includedfiles) {
72 if ($1 eq $filename) {
73 if ($includedfiles{$filename} > 1) {
74 $includedfiles{$filename}--;
75 $dups++;
76 } else {
77 print {$f} $_;
78 }
79 }
80 }
81 } else {
82 print {$f} $_;
83 }
84 }
85 if ($dups > 0) {
86 print "$file: removed $dups duplicate includes\n";
87 }
88 close($f);
24} 89}
diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh
index 39677c82747a..2ca49bb31efc 100755
--- a/scripts/checkkconfigsymbols.sh
+++ b/scripts/checkkconfigsymbols.sh
@@ -9,12 +9,12 @@ paths="$@"
9# Doing this once at the beginning saves a lot of time, on a cache-hot tree. 9# Doing this once at the beginning saves a lot of time, on a cache-hot tree.
10Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`" 10Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`"
11 11
12echo -e "File list \tundefined symbol used" 12/bin/echo -e "File list \tundefined symbol used"
13find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i 13find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i
14do 14do
15 # Output the bare Kconfig variable and the filename; the _MODULE part at 15 # Output the bare Kconfig variable and the filename; the _MODULE part at
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
@@ -54,6 +54,6 @@ while read symb files; do
54 # beyond the purpose of this script. 54 # beyond the purpose of this script.
55 symb_bare=`echo $symb | sed -e 's/_MODULE//'` 55 symb_bare=`echo $symb | sed -e 's/_MODULE//'`
56 if ! grep -q "\<$symb_bare\>" $Kconfigs; then 56 if ! grep -q "\<$symb_bare\>" $Kconfigs; then
57 echo -e "$files: \t$symb" 57 /bin/echo -e "$files: \t$symb"
58 fi 58 fi
59done|sort 59done|sort
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 2d5ece798c4c..e3c7fc0dca38 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,8 +1,8 @@
1#!/usr/bin/perl -w 1#!/usr/bin/perl -w
2# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit) 2# (c) 2001, Dave Jones. (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5# (c) 2008, Andy Whitcroft <apw@canonical.com> 5# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
6# Licensed under the terms of the GNU GPL License version 2 6# Licensed under the terms of the GNU GPL License version 2
7 7
8use strict; 8use strict;
@@ -10,7 +10,7 @@ use strict;
10my $P = $0; 10my $P = $0;
11$P =~ s@.*/@@g; 11$P =~ s@.*/@@g;
12 12
13my $V = '0.28'; 13my $V = '0.31';
14 14
15use Getopt::Long qw(:config no_auto_abbrev); 15use Getopt::Long qw(:config no_auto_abbrev);
16 16
@@ -28,6 +28,41 @@ my $mailback = 0;
28my $summary_file = 0; 28my $summary_file = 0;
29my $root; 29my $root;
30my %debug; 30my %debug;
31my $help = 0;
32
33sub help {
34 my ($exitcode) = @_;
35
36 print << "EOM";
37Usage: $P [OPTION]... [FILE]...
38Version: $V
39
40Options:
41 -q, --quiet quiet
42 --no-tree run without a kernel tree
43 --no-signoff do not check for 'Signed-off-by' line
44 --patch treat FILE as patchfile (default)
45 --emacs emacs compile window format
46 --terse one line per report
47 -f, --file treat FILE as regular source file
48 --subjective, --strict enable more subjective tests
49 --root=PATH PATH to the kernel tree root
50 --no-summary suppress the per-file summary
51 --mailback only produce a report in case of warnings/errors
52 --summary-file include the filename in summary
53 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
54 'values', 'possible', 'type', and 'attr' (default
55 is all off)
56 --test-only=WORD report only warnings/errors containing WORD
57 literally
58 -h, --help, --version display this help and exit
59
60When FILE is - read standard input.
61EOM
62
63 exit($exitcode);
64}
65
31GetOptions( 66GetOptions(
32 'q|quiet+' => \$quiet, 67 'q|quiet+' => \$quiet,
33 'tree!' => \$tree, 68 'tree!' => \$tree,
@@ -35,7 +70,7 @@ GetOptions(
35 'patch!' => \$chk_patch, 70 'patch!' => \$chk_patch,
36 'emacs!' => \$emacs, 71 'emacs!' => \$emacs,
37 'terse!' => \$terse, 72 'terse!' => \$terse,
38 'file!' => \$file, 73 'f|file!' => \$file,
39 'subjective!' => \$check, 74 'subjective!' => \$check,
40 'strict!' => \$check, 75 'strict!' => \$check,
41 'root=s' => \$root, 76 'root=s' => \$root,
@@ -45,22 +80,16 @@ GetOptions(
45 80
46 'debug=s' => \%debug, 81 'debug=s' => \%debug,
47 'test-only=s' => \$tst_only, 82 'test-only=s' => \$tst_only,
48) or exit; 83 'h|help' => \$help,
84 'version' => \$help
85) or help(1);
86
87help(0) if ($help);
49 88
50my $exit = 0; 89my $exit = 0;
51 90
52if ($#ARGV < 0) { 91if ($#ARGV < 0) {
53 print "usage: $P [options] patchfile\n"; 92 print "$P: no input files\n";
54 print "version: $V\n";
55 print "options: -q => quiet\n";
56 print " --no-tree => run without a kernel tree\n";
57 print " --terse => one line per report\n";
58 print " --emacs => emacs compile window format\n";
59 print " --file => check a source file\n";
60 print " --strict => enable more subjective tests\n";
61 print " --root => path to the kernel tree root\n";
62 print " --no-summary => suppress the per-file summary\n";
63 print " --summary-file => include the filename in summary\n";
64 exit(1); 93 exit(1);
65} 94}
66 95
@@ -74,6 +103,8 @@ for my $key (keys %debug) {
74 die "$@" if ($@); 103 die "$@" if ($@);
75} 104}
76 105
106my $rpt_cleaners = 0;
107
77if ($terse) { 108if ($terse) {
78 $emacs = 1; 109 $emacs = 1;
79 $quiet++; 110 $quiet++;
@@ -101,7 +132,10 @@ if ($tree) {
101 132
102my $emitted_corrupt = 0; 133my $emitted_corrupt = 0;
103 134
104our $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; 135our $Ident = qr{
136 [A-Za-z_][A-Za-z\d_]*
137 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
138 }x;
105our $Storage = qr{extern|static|asmlinkage}; 139our $Storage = qr{extern|static|asmlinkage};
106our $Sparse = qr{ 140our $Sparse = qr{
107 __user| 141 __user|
@@ -113,11 +147,28 @@ our $Sparse = qr{
113 __kprobes| 147 __kprobes|
114 __ref 148 __ref
115 }x; 149 }x;
150
151# Notes to $Attribute:
152# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
116our $Attribute = qr{ 153our $Attribute = qr{
117 const| 154 const|
155 __percpu|
156 __nocast|
157 __safe|
158 __bitwise__|
159 __packed__|
160 __packed2__|
161 __naked|
162 __maybe_unused|
163 __always_unused|
164 __noreturn|
165 __used|
166 __cold|
167 __noclone|
168 __deprecated|
118 __read_mostly| 169 __read_mostly|
119 __kprobes| 170 __kprobes|
120 __(?:mem|cpu|dev|)(?:initdata|init)| 171 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
121 ____cacheline_aligned| 172 ____cacheline_aligned|
122 ____cacheline_aligned_in_smp| 173 ____cacheline_aligned_in_smp|
123 ____cacheline_internodealigned_in_smp| 174 ____cacheline_internodealigned_in_smp|
@@ -153,10 +204,18 @@ our $UTF8 = qr {
153}x; 204}x;
154 205
155our $typeTypedefs = qr{(?x: 206our $typeTypedefs = qr{(?x:
156 (?:__)?(?:u|s|be|le)(?:\d|\d\d)| 207 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
157 atomic_t 208 atomic_t
158)}; 209)};
159 210
211our $logFunctions = qr{(?x:
212 printk|
213 pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
214 (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
215 WARN|
216 panic
217)};
218
160our @typeList = ( 219our @typeList = (
161 qr{void}, 220 qr{void},
162 qr{(?:unsigned\s+)?char}, 221 qr{(?:unsigned\s+)?char},
@@ -181,6 +240,12 @@ our @modifierList = (
181 qr{fastcall}, 240 qr{fastcall},
182); 241);
183 242
243our $allowed_asm_includes = qr{(?x:
244 irq|
245 memory
246)};
247# memory.h: ARM has a custom one
248
184sub build_types { 249sub build_types {
185 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 250 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
186 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 251 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
@@ -356,6 +421,13 @@ sub sanitise_line {
356 $off++; 421 $off++;
357 next; 422 next;
358 } 423 }
424 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
425 $sanitise_quote = '//';
426
427 substr($res, $off, 2, $sanitise_quote);
428 $off++;
429 next;
430 }
359 431
360 # A \ in a string means ignore the next character. 432 # A \ in a string means ignore the next character.
361 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 433 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
@@ -379,6 +451,8 @@ sub sanitise_line {
379 #print "c<$c> SQ<$sanitise_quote>\n"; 451 #print "c<$c> SQ<$sanitise_quote>\n";
380 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 452 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
381 substr($res, $off, 1, $;); 453 substr($res, $off, 1, $;);
454 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
455 substr($res, $off, 1, $;);
382 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 456 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
383 substr($res, $off, 1, 'X'); 457 substr($res, $off, 1, 'X');
384 } else { 458 } else {
@@ -386,6 +460,10 @@ sub sanitise_line {
386 } 460 }
387 } 461 }
388 462
463 if ($sanitise_quote eq '//') {
464 $sanitise_quote = '';
465 }
466
389 # The pathname on a #include may be surrounded by '<' and '>'. 467 # The pathname on a #include may be surrounded by '<' and '>'.
390 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 468 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
391 my $clean = 'X' x length($1); 469 my $clean = 'X' x length($1);
@@ -496,6 +574,9 @@ sub ctx_statement_block {
496 $type = ($level != 0)? '{' : ''; 574 $type = ($level != 0)? '{' : '';
497 575
498 if ($level == 0) { 576 if ($level == 0) {
577 if (substr($blk, $off + 1, 1) eq ';') {
578 $off++;
579 }
499 last; 580 last;
500 } 581 }
501 } 582 }
@@ -610,15 +691,15 @@ sub ctx_block_get {
610 $blk .= $rawlines[$line]; 691 $blk .= $rawlines[$line];
611 692
612 # Handle nested #if/#else. 693 # Handle nested #if/#else.
613 if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 694 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
614 push(@stack, $level); 695 push(@stack, $level);
615 } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 696 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
616 $level = $stack[$#stack - 1]; 697 $level = $stack[$#stack - 1];
617 } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) { 698 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
618 $level = pop(@stack); 699 $level = pop(@stack);
619 } 700 }
620 701
621 foreach my $c (split(//, $rawlines[$line])) { 702 foreach my $c (split(//, $lines[$line])) {
622 ##print "C<$c>L<$level><$open$close>O<$off>\n"; 703 ##print "C<$c>L<$level><$open$close>O<$off>\n";
623 if ($off > 0) { 704 if ($off > 0) {
624 $off--; 705 $off--;
@@ -778,7 +859,12 @@ sub annotate_values {
778 $av_preprocessor = 0; 859 $av_preprocessor = 0;
779 } 860 }
780 861
781 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\()/) { 862 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) {
863 print "CAST($1)\n" if ($dbg_values > 1);
864 push(@av_paren_type, $type);
865 $type = 'C';
866
867 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
782 print "DECLARE($1)\n" if ($dbg_values > 1); 868 print "DECLARE($1)\n" if ($dbg_values > 1);
783 $type = 'T'; 869 $type = 'T';
784 870
@@ -955,23 +1041,25 @@ sub annotate_values {
955 1041
956sub possible { 1042sub possible {
957 my ($possible, $line) = @_; 1043 my ($possible, $line) = @_;
958 1044 my $notPermitted = qr{(?:
959 print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
960 if ($possible !~ /(?:
961 ^(?: 1045 ^(?:
962 $Modifier| 1046 $Modifier|
963 $Storage| 1047 $Storage|
964 $Type| 1048 $Type|
965 DEFINE_\S+| 1049 DEFINE_\S+
1050 )$|
1051 ^(?:
966 goto| 1052 goto|
967 return| 1053 return|
968 case| 1054 case|
969 else| 1055 else|
970 asm|__asm__| 1056 asm|__asm__|
971 do 1057 do
972 )$| 1058 )(?:\s|$)|
973 ^(?:typedef|struct|enum)\b 1059 ^(?:typedef|struct|enum)\b
974 )/x) { 1060 )}x;
1061 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1062 if ($possible !~ $notPermitted) {
975 # Check for modifiers. 1063 # Check for modifiers.
976 $possible =~ s/\s*$Storage\s*//g; 1064 $possible =~ s/\s*$Storage\s*//g;
977 $possible =~ s/\s*$Sparse\s*//g; 1065 $possible =~ s/\s*$Sparse\s*//g;
@@ -980,8 +1068,10 @@ sub possible {
980 } elsif ($possible =~ /\s/) { 1068 } elsif ($possible =~ /\s/) {
981 $possible =~ s/\s*$Type\s*//g; 1069 $possible =~ s/\s*$Type\s*//g;
982 for my $modifier (split(' ', $possible)) { 1070 for my $modifier (split(' ', $possible)) {
983 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1071 if ($modifier !~ $notPermitted) {
984 push(@modifierList, $modifier); 1072 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1073 push(@modifierList, $modifier);
1074 }
985 } 1075 }
986 1076
987 } else { 1077 } else {
@@ -1096,6 +1186,7 @@ sub process {
1096 # suppression flags 1186 # suppression flags
1097 my %suppress_ifbraces; 1187 my %suppress_ifbraces;
1098 my %suppress_whiletrailers; 1188 my %suppress_whiletrailers;
1189 my %suppress_export;
1099 1190
1100 # Pre-scan the patch sanitizing the lines. 1191 # Pre-scan the patch sanitizing the lines.
1101 # Pre-scan the patch looking for any __setup documentation. 1192 # Pre-scan the patch looking for any __setup documentation.
@@ -1188,7 +1279,6 @@ sub process {
1188 $linenr++; 1279 $linenr++;
1189 1280
1190 my $rawline = $rawlines[$linenr - 1]; 1281 my $rawline = $rawlines[$linenr - 1];
1191 my $hunk_line = ($realcnt != 0);
1192 1282
1193#extract the line range in the file after the patch is applied 1283#extract the line range in the file after the patch is applied
1194 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1284 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1205,6 +1295,7 @@ sub process {
1205 1295
1206 %suppress_ifbraces = (); 1296 %suppress_ifbraces = ();
1207 %suppress_whiletrailers = (); 1297 %suppress_whiletrailers = ();
1298 %suppress_export = ();
1208 next; 1299 next;
1209 1300
1210# track the line number as we move through the hunk, note that 1301# track the line number as we move through the hunk, note that
@@ -1228,6 +1319,8 @@ sub process {
1228 $realcnt--; 1319 $realcnt--;
1229 } 1320 }
1230 1321
1322 my $hunk_line = ($realcnt != 0);
1323
1231#make up the handle for any error we report on this line 1324#make up the handle for any error we report on this line
1232 $prefix = "$filename:$realline: " if ($emacs && $file); 1325 $prefix = "$filename:$realline: " if ($emacs && $file);
1233 $prefix = "$filename:$linenr: " if ($emacs && !$file); 1326 $prefix = "$filename:$linenr: " if ($emacs && !$file);
@@ -1236,7 +1329,11 @@ sub process {
1236 $here = "#$realline: " if ($file); 1329 $here = "#$realline: " if ($file);
1237 1330
1238 # extract the filename as it passes 1331 # extract the filename as it passes
1239 if ($line=~/^\+\+\+\s+(\S+)/) { 1332 if ($line =~ /^diff --git.*?(\S+)$/) {
1333 $realfile = $1;
1334 $realfile =~ s@^([^/]*)/@@;
1335
1336 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1240 $realfile = $1; 1337 $realfile = $1;
1241 $realfile =~ s@^([^/]*)/@@; 1338 $realfile =~ s@^([^/]*)/@@;
1242 1339
@@ -1260,6 +1357,14 @@ sub process {
1260 1357
1261 $cnt_lines++ if ($realcnt != 0); 1358 $cnt_lines++ if ($realcnt != 0);
1262 1359
1360# Check for incorrect file permissions
1361 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
1362 my $permhere = $here . "FILE: $realfile\n";
1363 if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) {
1364 ERROR("do not set execute permissions for source files\n" . $permhere);
1365 }
1366 }
1367
1263#check the patch for a signoff: 1368#check the patch for a signoff:
1264 if ($line =~ /^\s*signed-off-by:/i) { 1369 if ($line =~ /^\s*signed-off-by:/i) {
1265 # This is a signoff, if ugly, so do not double report. 1370 # This is a signoff, if ugly, so do not double report.
@@ -1317,6 +1422,38 @@ sub process {
1317 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1422 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1318 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1423 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1319 ERROR("trailing whitespace\n" . $herevet); 1424 ERROR("trailing whitespace\n" . $herevet);
1425 $rpt_cleaners = 1;
1426 }
1427
1428# check for Kconfig help text having a real description
1429# Only applies when adding the entry originally, after that we do not have
1430# sufficient context to determine whether it is indeed long enough.
1431 if ($realfile =~ /Kconfig/ &&
1432 $line =~ /\+\s*(?:---)?help(?:---)?$/) {
1433 my $length = 0;
1434 my $cnt = $realcnt;
1435 my $ln = $linenr + 1;
1436 my $f;
1437 my $is_end = 0;
1438 while ($cnt > 0 && defined $lines[$ln - 1]) {
1439 $f = $lines[$ln - 1];
1440 $cnt-- if ($lines[$ln - 1] !~ /^-/);
1441 $is_end = $lines[$ln - 1] =~ /^\+/;
1442 $ln++;
1443
1444 next if ($f =~ /^-/);
1445 $f =~ s/^.//;
1446 $f =~ s/#.*//;
1447 $f =~ s/^\s+//;
1448 next if ($f =~ /^$/);
1449 if ($f =~ /^\s*config\s/) {
1450 $is_end = 1;
1451 last;
1452 }
1453 $length++;
1454 }
1455 WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4);
1456 #print "is_end<$is_end> length<$length>\n";
1320 } 1457 }
1321 1458
1322# check we are in a valid source file if not then ignore this hunk 1459# check we are in a valid source file if not then ignore this hunk
@@ -1325,17 +1462,35 @@ sub process {
1325#80 column limit 1462#80 column limit
1326 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1463 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1327 $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 1464 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
1328 $line !~ /^\+\s*printk\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ && 1465 !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ ||
1466 $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
1329 $length > 80) 1467 $length > 80)
1330 { 1468 {
1331 WARN("line over 80 characters\n" . $herecurr); 1469 WARN("line over 80 characters\n" . $herecurr);
1332 } 1470 }
1333 1471
1472# check for spaces before a quoted newline
1473 if ($rawline =~ /^.*\".*\s\\n/) {
1474 WARN("unnecessary whitespace before a quoted newline\n" . $herecurr);
1475 }
1476
1334# check for adding lines without a newline. 1477# check for adding lines without a newline.
1335 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1478 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1336 WARN("adding a line without newline at end of file\n" . $herecurr); 1479 WARN("adding a line without newline at end of file\n" . $herecurr);
1337 } 1480 }
1338 1481
1482# Blackfin: use hi/lo macros
1483 if ($realfile =~ m@arch/blackfin/.*\.S$@) {
1484 if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
1485 my $herevet = "$here\n" . cat_vet($line) . "\n";
1486 ERROR("use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
1487 }
1488 if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
1489 my $herevet = "$here\n" . cat_vet($line) . "\n";
1490 ERROR("use the HI() macro, not (... >> 16)\n" . $herevet);
1491 }
1492 }
1493
1339# check we are in a valid source file C or perl if not then ignore this hunk 1494# check we are in a valid source file C or perl if not then ignore this hunk
1340 next if ($realfile !~ /\.(h|c|pl)$/); 1495 next if ($realfile !~ /\.(h|c|pl)$/);
1341 1496
@@ -1345,6 +1500,23 @@ sub process {
1345 $rawline =~ /^\+\s* \s*/) { 1500 $rawline =~ /^\+\s* \s*/) {
1346 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1501 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1347 ERROR("code indent should use tabs where possible\n" . $herevet); 1502 ERROR("code indent should use tabs where possible\n" . $herevet);
1503 $rpt_cleaners = 1;
1504 }
1505
1506# check for space before tabs.
1507 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
1508 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1509 WARN("please, no space before tabs\n" . $herevet);
1510 }
1511
1512# check for spaces at the beginning of a line.
1513# Exceptions:
1514# 1) within comments
1515# 2) indented preprocessor commands
1516# 3) hanging labels
1517 if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) {
1518 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1519 WARN("please, no spaces at the start of a line\n" . $herevet);
1348 } 1520 }
1349 1521
1350# check we are in a valid C source file if not then ignore this hunk 1522# check we are in a valid C source file if not then ignore this hunk
@@ -1355,14 +1527,33 @@ sub process {
1355 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); 1527 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
1356 } 1528 }
1357 1529
1530# Blackfin: don't use __builtin_bfin_[cs]sync
1531 if ($line =~ /__builtin_bfin_csync/) {
1532 my $herevet = "$here\n" . cat_vet($line) . "\n";
1533 ERROR("use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
1534 }
1535 if ($line =~ /__builtin_bfin_ssync/) {
1536 my $herevet = "$here\n" . cat_vet($line) . "\n";
1537 ERROR("use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
1538 }
1539
1358# Check for potential 'bare' types 1540# Check for potential 'bare' types
1359 my ($stat, $cond, $line_nr_next, $remain_next, $off_next); 1541 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
1542 $realline_next);
1360 if ($realcnt && $line =~ /.\s*\S/) { 1543 if ($realcnt && $line =~ /.\s*\S/) {
1361 ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 1544 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
1362 ctx_statement_block($linenr, $realcnt, 0); 1545 ctx_statement_block($linenr, $realcnt, 0);
1363 $stat =~ s/\n./\n /g; 1546 $stat =~ s/\n./\n /g;
1364 $cond =~ s/\n./\n /g; 1547 $cond =~ s/\n./\n /g;
1365 1548
1549 # Find the real next line.
1550 $realline_next = $line_nr_next;
1551 if (defined $realline_next &&
1552 (!defined $lines[$realline_next - 1] ||
1553 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
1554 $realline_next++;
1555 }
1556
1366 my $s = $stat; 1557 my $s = $stat;
1367 $s =~ s/{.*$//s; 1558 $s =~ s/{.*$//s;
1368 1559
@@ -1372,6 +1563,8 @@ sub process {
1372 # Ignore functions being called 1563 # Ignore functions being called
1373 } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 1564 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
1374 1565
1566 } elsif ($s =~ /^.\s*else\b/s) {
1567
1375 # declarations always start with types 1568 # declarations always start with types
1376 } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { 1569 } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) {
1377 my $type = $1; 1570 my $type = $1;
@@ -1459,7 +1652,7 @@ sub process {
1459 1652
1460 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 1653 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
1461 ERROR("that open brace { should be on the previous line\n" . 1654 ERROR("that open brace { should be on the previous line\n" .
1462 "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); 1655 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
1463 } 1656 }
1464 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 1657 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
1465 $ctx =~ /\)\s*\;\s*$/ && 1658 $ctx =~ /\)\s*\;\s*$/ &&
@@ -1468,7 +1661,7 @@ sub process {
1468 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 1661 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
1469 if ($nindent > $indent) { 1662 if ($nindent > $indent) {
1470 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . 1663 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
1471 "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); 1664 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
1472 } 1665 }
1473 } 1666 }
1474 } 1667 }
@@ -1532,8 +1725,9 @@ sub process {
1532 $s =~ /^\s*#\s*?/ || 1725 $s =~ /^\s*#\s*?/ ||
1533 $s =~ /^\s*$Ident\s*:/) { 1726 $s =~ /^\s*$Ident\s*:/) {
1534 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 1727 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
1535 $s =~ s/^.*?\n//; 1728 if ($s =~ s/^.*?\n//) {
1536 $cond_lines++; 1729 $cond_lines++;
1730 }
1537 } 1731 }
1538 } 1732 }
1539 1733
@@ -1594,8 +1788,8 @@ sub process {
1594 } 1788 }
1595 1789
1596# check for initialisation to aggregates open brace on the next line 1790# check for initialisation to aggregates open brace on the next line
1597 if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && 1791 if ($line =~ /^.\s*{/ &&
1598 $line =~ /^.\s*{/) { 1792 $prevline =~ /(?:^|[^=])=\s*$/) {
1599 ERROR("that open brace { should be on the previous line\n" . $hereprev); 1793 ERROR("that open brace { should be on the previous line\n" . $hereprev);
1600 } 1794 }
1601 1795
@@ -1620,25 +1814,53 @@ sub process {
1620 $line =~ s@//.*@@; 1814 $line =~ s@//.*@@;
1621 $opline =~ s@//.*@@; 1815 $opline =~ s@//.*@@;
1622 1816
1623#EXPORT_SYMBOL should immediately follow its function closing }. 1817# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
1624 if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || 1818# the whole statement.
1625 ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1819#print "APW <$lines[$realline_next - 1]>\n";
1820 if (defined $realline_next &&
1821 exists $lines[$realline_next - 1] &&
1822 !defined $suppress_export{$realline_next} &&
1823 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1824 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1825 # Handle definitions which produce identifiers with
1826 # a prefix:
1827 # XXX(foo);
1828 # EXPORT_SYMBOL(something_foo);
1626 my $name = $1; 1829 my $name = $1;
1627 if ($prevline !~ /(?: 1830 if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ &&
1628 ^.}| 1831 $name =~ /^${Ident}_$2/) {
1832#print "FOO C name<$name>\n";
1833 $suppress_export{$realline_next} = 1;
1834
1835 } elsif ($stat !~ /(?:
1836 \n.}\s*$|
1629 ^.DEFINE_$Ident\(\Q$name\E\)| 1837 ^.DEFINE_$Ident\(\Q$name\E\)|
1630 ^.DECLARE_$Ident\(\Q$name\E\)| 1838 ^.DECLARE_$Ident\(\Q$name\E\)|
1631 ^.LIST_HEAD\(\Q$name\E\)| 1839 ^.LIST_HEAD\(\Q$name\E\)|
1632 ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 1840 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
1633 \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[) 1841 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
1634 )/x) { 1842 )/x) {
1635 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 1843#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
1844 $suppress_export{$realline_next} = 2;
1845 } else {
1846 $suppress_export{$realline_next} = 1;
1636 } 1847 }
1637 } 1848 }
1849 if (!defined $suppress_export{$linenr} &&
1850 $prevline =~ /^.\s*$/ &&
1851 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1852 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1853#print "FOO B <$lines[$linenr - 1]>\n";
1854 $suppress_export{$linenr} = 2;
1855 }
1856 if (defined $suppress_export{$linenr} &&
1857 $suppress_export{$linenr} == 2) {
1858 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
1859 }
1638 1860
1639# check for external initialisers. 1861# check for global initialisers.
1640 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { 1862 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
1641 ERROR("do not initialise externals to 0 or NULL\n" . 1863 ERROR("do not initialise globals to 0 or NULL\n" .
1642 $herecurr); 1864 $herecurr);
1643 } 1865 }
1644# check for static initialisers. 1866# check for static initialisers.
@@ -1647,6 +1869,23 @@ sub process {
1647 $herecurr); 1869 $herecurr);
1648 } 1870 }
1649 1871
1872# check for static const char * arrays.
1873 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
1874 WARN("static const char * array should probably be static const char * const\n" .
1875 $herecurr);
1876 }
1877
1878# check for static char foo[] = "bar" declarations.
1879 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
1880 WARN("static char array declaration should probably be static const char\n" .
1881 $herecurr);
1882 }
1883
1884# check for declarations of struct pci_device_id
1885 if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
1886 WARN("Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
1887 }
1888
1650# check for new typedefs, only function parameters and sparse annotations 1889# check for new typedefs, only function parameters and sparse annotations
1651# make sense. 1890# make sense.
1652 if ($line =~ /\btypedef\s/ && 1891 if ($line =~ /\btypedef\s/ &&
@@ -1740,6 +1979,11 @@ sub process {
1740 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); 1979 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
1741 } 1980 }
1742 1981
1982# missing space after union, struct or enum definition
1983 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {
1984 WARN("missing space after $1 definition\n" . $herecurr);
1985 }
1986
1743# check for spacing round square brackets; allowed: 1987# check for spacing round square brackets; allowed:
1744# 1. with a type on the left -- int [] a; 1988# 1. with a type on the left -- int [] a;
1745# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 1989# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
@@ -1891,7 +2135,7 @@ sub process {
1891 # A unary '*' may be const 2135 # A unary '*' may be const
1892 2136
1893 } elsif ($ctx =~ /.xW/) { 2137 } elsif ($ctx =~ /.xW/) {
1894 ERROR("Aspace prohibited after that '$op' $at\n" . $hereptr); 2138 ERROR("space prohibited after that '$op' $at\n" . $hereptr);
1895 } 2139 }
1896 2140
1897 # unary ++ and unary -- are allowed no space on one side. 2141 # unary ++ and unary -- are allowed no space on one side.
@@ -2017,21 +2261,29 @@ sub process {
2017 my $value = $2; 2261 my $value = $2;
2018 2262
2019 # Flatten any parentheses 2263 # Flatten any parentheses
2020 $value =~ s/\)\(/\) \(/g; 2264 $value =~ s/\(/ \(/g;
2265 $value =~ s/\)/\) /g;
2021 while ($value =~ s/\[[^\{\}]*\]/1/ || 2266 while ($value =~ s/\[[^\{\}]*\]/1/ ||
2022 $value !~ /(?:$Ident|-?$Constant)\s* 2267 $value !~ /(?:$Ident|-?$Constant)\s*
2023 $Compare\s* 2268 $Compare\s*
2024 (?:$Ident|-?$Constant)/x && 2269 (?:$Ident|-?$Constant)/x &&
2025 $value =~ s/\([^\(\)]*\)/1/) { 2270 $value =~ s/\([^\(\)]*\)/1/) {
2026 } 2271 }
2027 2272#print "value<$value>\n";
2028 if ($value =~ /^(?:$Ident|-?$Constant)$/) { 2273 if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
2029 ERROR("return is not a function, parentheses are not required\n" . $herecurr); 2274 ERROR("return is not a function, parentheses are not required\n" . $herecurr);
2030 2275
2031 } elsif ($spacing !~ /\s+/) { 2276 } elsif ($spacing !~ /\s+/) {
2032 ERROR("space required before the open parenthesis '('\n" . $herecurr); 2277 ERROR("space required before the open parenthesis '('\n" . $herecurr);
2033 } 2278 }
2034 } 2279 }
2280# Return of what appears to be an errno should normally be -'ve
2281 if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
2282 my $name = $1;
2283 if ($name ne 'EOF' && $name ne 'ERROR') {
2284 WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr);
2285 }
2286 }
2035 2287
2036# Need a space before open parenthesis after if, while etc 2288# Need a space before open parenthesis after if, while etc
2037 if ($line=~/\b(if|while|for|switch)\(/) { 2289 if ($line=~/\b(if|while|for|switch)\(/) {
@@ -2077,8 +2329,10 @@ sub process {
2077 # Find out how long the conditional actually is. 2329 # Find out how long the conditional actually is.
2078 my @newlines = ($c =~ /\n/gs); 2330 my @newlines = ($c =~ /\n/gs);
2079 my $cond_lines = 1 + $#newlines; 2331 my $cond_lines = 1 + $#newlines;
2332 my $stat_real = '';
2080 2333
2081 my $stat_real = raw_line($linenr, $cond_lines); 2334 $stat_real = raw_line($linenr, $cond_lines)
2335 . "\n" if ($cond_lines);
2082 if (defined($stat_real) && $cond_lines > 1) { 2336 if (defined($stat_real) && $cond_lines > 1) {
2083 $stat_real = "[...]\n$stat_real"; 2337 $stat_real = "[...]\n$stat_real";
2084 } 2338 }
@@ -2164,7 +2418,7 @@ sub process {
2164 my $checkfile = "include/linux/$file"; 2418 my $checkfile = "include/linux/$file";
2165 if (-f "$root/$checkfile" && 2419 if (-f "$root/$checkfile" &&
2166 $realfile ne $checkfile && 2420 $realfile ne $checkfile &&
2167 $1 ne 'irq') 2421 $1 !~ /$allowed_asm_includes/)
2168 { 2422 {
2169 if ($realfile =~ m{^arch/}) { 2423 if ($realfile =~ m{^arch/}) {
2170 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 2424 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
@@ -2243,10 +2497,13 @@ sub process {
2243 DECLARE_PER_CPU| 2497 DECLARE_PER_CPU|
2244 DEFINE_PER_CPU| 2498 DEFINE_PER_CPU|
2245 __typeof__\(| 2499 __typeof__\(|
2246 \.$Ident\s*=\s* 2500 union|
2501 struct|
2502 \.$Ident\s*=\s*|
2503 ^\"|\"$
2247 }x; 2504 }x;
2248 #print "REST<$rest> dstat<$dstat>\n"; 2505 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
2249 if ($rest ne '') { 2506 if ($rest ne '' && $rest ne ',') {
2250 if ($rest !~ /while\s*\(/ && 2507 if ($rest !~ /while\s*\(/ &&
2251 $dstat !~ /$exceptions/) 2508 $dstat !~ /$exceptions/)
2252 { 2509 {
@@ -2423,6 +2680,21 @@ sub process {
2423 } 2680 }
2424 } 2681 }
2425 2682
2683# prefer usleep_range over udelay
2684 if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
2685 # ignore udelay's < 10, however
2686 if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
2687 CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
2688 }
2689 }
2690
2691# warn about unexpectedly long msleep's
2692 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
2693 if ($1 < 20) {
2694 WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
2695 }
2696 }
2697
2426# warn about #ifdefs in C files 2698# warn about #ifdefs in C files
2427# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 2699# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
2428# print "#ifdef in C files should be avoided\n"; 2700# print "#ifdef in C files should be avoided\n";
@@ -2454,6 +2726,11 @@ sub process {
2454 CHK("architecture specific defines should be avoided\n" . $herecurr); 2726 CHK("architecture specific defines should be avoided\n" . $herecurr);
2455 } 2727 }
2456 2728
2729# Check that the storage class is at the beginning of a declaration
2730 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
2731 WARN("storage class should be at the beginning of the declaration\n" . $herecurr)
2732 }
2733
2457# check the location of the inline attribute, that it is between 2734# check the location of the inline attribute, that it is between
2458# storage class and type. 2735# storage class and type.
2459 if ($line =~ /\b$Type\s+$Inline\b/ || 2736 if ($line =~ /\b$Type\s+$Inline\b/ ||
@@ -2466,6 +2743,11 @@ sub process {
2466 WARN("plain inline is preferred over $1\n" . $herecurr); 2743 WARN("plain inline is preferred over $1\n" . $herecurr);
2467 } 2744 }
2468 2745
2746# check for sizeof(&)
2747 if ($line =~ /\bsizeof\s*\(\s*\&/) {
2748 WARN("sizeof(& should be avoided\n" . $herecurr);
2749 }
2750
2469# check for new externs in .c files. 2751# check for new externs in .c files.
2470 if ($realfile =~ /\.c$/ && defined $stat && 2752 if ($realfile =~ /\.c$/ && defined $stat &&
2471 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 2753 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
@@ -2512,13 +2794,10 @@ sub process {
2512 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); 2794 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
2513 } 2795 }
2514 2796
2515# check for semaphores used as mutexes 2797# check for semaphores initialized locked
2516 if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) { 2798 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
2517 WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
2518 }
2519# check for semaphores used as mutexes
2520 if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
2521 WARN("consider using a completion\n" . $herecurr); 2799 WARN("consider using a completion\n" . $herecurr);
2800
2522 } 2801 }
2523# recommend strict_strto* over simple_strto* 2802# recommend strict_strto* over simple_strto*
2524 if ($line =~ /\bsimple_(strto.*?)\s*\(/) { 2803 if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
@@ -2528,9 +2807,46 @@ sub process {
2528 if ($line =~ /^.\s*__initcall\s*\(/) { 2807 if ($line =~ /^.\s*__initcall\s*\(/) {
2529 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr); 2808 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
2530 } 2809 }
2531# check for struct file_operations, ensure they are const. 2810# check for various ops structs, ensure they are const.
2811 my $struct_ops = qr{acpi_dock_ops|
2812 address_space_operations|
2813 backlight_ops|
2814 block_device_operations|
2815 dentry_operations|
2816 dev_pm_ops|
2817 dma_map_ops|
2818 extent_io_ops|
2819 file_lock_operations|
2820 file_operations|
2821 hv_ops|
2822 ide_dma_ops|
2823 intel_dvo_dev_ops|
2824 item_operations|
2825 iwl_ops|
2826 kgdb_arch|
2827 kgdb_io|
2828 kset_uevent_ops|
2829 lock_manager_operations|
2830 microcode_ops|
2831 mtrr_ops|
2832 neigh_ops|
2833 nlmsvc_binding|
2834 pci_raw_ops|
2835 pipe_buf_operations|
2836 platform_hibernation_ops|
2837 platform_suspend_ops|
2838 proto_ops|
2839 rpc_pipe_ops|
2840 seq_operations|
2841 snd_ac97_build_ops|
2842 soc_pcmcia_socket_ops|
2843 stacktrace_ops|
2844 sysfs_ops|
2845 tty_operations|
2846 usb_mon_operations|
2847 wd_ops}x;
2532 if ($line !~ /\bconst\b/ && 2848 if ($line !~ /\bconst\b/ &&
2533 $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) { 2849 $line =~ /\bstruct\s+($struct_ops)\b/) {
2534 WARN("struct $1 should normally be const\n" . 2850 WARN("struct $1 should normally be const\n" .
2535 $herecurr); 2851 $herecurr);
2536 } 2852 }
@@ -2566,6 +2882,16 @@ sub process {
2566 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 2882 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
2567 } 2883 }
2568 } 2884 }
2885
2886# check for lockdep_set_novalidate_class
2887 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
2888 $line =~ /__lockdep_no_validate__\s*\)/ ) {
2889 if ($realfile !~ m@^kernel/lockdep@ &&
2890 $realfile !~ m@^include/linux/lockdep@ &&
2891 $realfile !~ m@^drivers/base/core@) {
2892 ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
2893 }
2894 }
2569 } 2895 }
2570 2896
2571 # If we have no input at all, then there is nothing to report on 2897 # If we have no input at all, then there is nothing to report on
@@ -2602,6 +2928,15 @@ sub process {
2602 print "\n" if ($quiet == 0); 2928 print "\n" if ($quiet == 0);
2603 } 2929 }
2604 2930
2931 if ($quiet == 0) {
2932 # If there were whitespace errors which cleanpatch can fix
2933 # then suggest that.
2934 if ($rpt_cleaners) {
2935 print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
2936 print " scripts/cleanfile\n\n";
2937 }
2938 }
2939
2605 if ($clean == 1 && $quiet == 0) { 2940 if ($clean == 1 && $quiet == 0) {
2606 print "$vname has no obvious style problems and is ready for submission.\n" 2941 print "$vname has no obvious style problems and is ready for submission.\n"
2607 } 2942 }
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..3ab316e52313 100755
--- a/scripts/checksyscalls.sh
+++ b/scripts/checksyscalls.sh
@@ -6,7 +6,7 @@
6# and listed below so they are ignored. 6# and listed below so they are ignored.
7# 7#
8# Usage: 8# Usage:
9# syscallchk gcc gcc-options 9# checksyscalls.sh gcc gcc-options
10# 10#
11 11
12ignore_list() { 12ignore_list() {
@@ -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
@@ -205,5 +204,5 @@ sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\
205\#endif/p' $1 204\#endif/p' $1
206} 205}
207 206
208(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ 207(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \
209$* -E -x c - > /dev/null 208$* -E -x c - > /dev/null
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..1bb1a1bd2daa
--- /dev/null
+++ b/scripts/coccicheck
@@ -0,0 +1,106 @@
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"
19 OPTIONS="-dir $srctree"
20fi
21
22if [ ! -x "$SPATCH" ]; then
23 echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
24 exit 1
25fi
26
27if [ "$MODE" = "" ] ; then
28 if [ "$ONLINE" = "0" ] ; then
29 echo 'You have not explicitly specified the mode to use. Using default "chain" mode.'
30 echo 'All available modes will be tried (in that order): patch, report, context, org'
31 echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
32 fi
33 MODE="chain"
34elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
35 FLAGS="$FLAGS -no_show_diff"
36fi
37
38if [ "$ONLINE" = "0" ] ; then
39 echo ''
40 echo 'Please check for false positives in the output before submitting a patch.'
41 echo 'When using "patch" mode, carefully review the patch before submitting it.'
42 echo ''
43fi
44
45coccinelle () {
46 COCCI="$1"
47
48 OPT=`grep "Option" $COCCI | cut -d':' -f2`
49
50# The option '-parse_cocci' can be used to syntactically check the SmPL files.
51#
52# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
53
54 if [ "$ONLINE" = "0" ] ; then
55
56 FILE=`echo $COCCI | sed "s|$srctree/||"`
57
58 echo "Processing `basename $COCCI`"
59 echo "with option(s) \"$OPT\""
60 echo ''
61 echo 'Message example to submit a patch:'
62
63 sed -ne 's|^///||p' $COCCI
64
65 if [ "$MODE" = "patch" ] ; then
66 echo ' The semantic patch that makes this change is available'
67 elif [ "$MODE" = "report" ] ; then
68 echo ' The semantic patch that makes this report is available'
69 elif [ "$MODE" = "context" ] ; then
70 echo ' The semantic patch that spots this code is available'
71 elif [ "$MODE" = "org" ] ; then
72 echo ' The semantic patch that makes this Org report is available'
73 else
74 echo ' The semantic patch that makes this output is available'
75 fi
76 echo " in $FILE."
77 echo ''
78 echo ' More information about semantic patching is available at'
79 echo ' http://coccinelle.lip6.fr/'
80 echo ''
81
82 if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
83 echo 'Semantic patch information:'
84 sed -ne 's|^//#||p' $COCCI
85 echo ''
86 fi
87 fi
88
89 if [ "$MODE" = "chain" ] ; then
90 $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
91 $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \
92 $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
93 $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1
94 else
95 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
96 fi
97
98}
99
100if [ "$COCCI" = "" ] ; then
101 for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
102 coccinelle $f
103 done
104else
105 coccinelle $COCCI
106fi
diff --git a/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci
new file mode 100644
index 000000000000..7d4771d449c3
--- /dev/null
+++ b/scripts/coccinelle/api/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/api/alloc/kzalloc-simple.cocci b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci
new file mode 100644
index 000000000000..046b9b16f8f9
--- /dev/null
+++ b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci
@@ -0,0 +1,86 @@
1///
2/// Use kzalloc rather than kmalloc followed by memset with 0
3///
4/// This considers some simple cases that are common and easy to validate
5/// Note in particular that there are no ...s in the rule, so all of the
6/// matched code has to be contiguous
7///
8// Confidence: High
9// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
10// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
11// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
12// Options: -no_includes -include_headers
13//
14// Keywords: kmalloc, kzalloc
15// Version min: < 2.6.12 kmalloc
16// Version min: 2.6.14 kzalloc
17//
18
19virtual context
20virtual patch
21virtual org
22virtual report
23
24//----------------------------------------------------------
25// For context mode
26//----------------------------------------------------------
27
28@depends on context@
29type T, T2;
30expression x;
31expression E1,E2;
32statement S;
33@@
34
35* x = (T)kmalloc(E1,E2);
36 if ((x==NULL) || ...) S
37* memset((T2)x,0,E1);
38
39//----------------------------------------------------------
40// For patch mode
41//----------------------------------------------------------
42
43@depends on patch@
44type T, T2;
45expression x;
46expression E1,E2;
47statement S;
48@@
49
50- x = (T)kmalloc(E1,E2);
51+ x = kzalloc(E1,E2);
52 if ((x==NULL) || ...) S
53- memset((T2)x,0,E1);
54
55//----------------------------------------------------------
56// For org mode
57//----------------------------------------------------------
58
59@r depends on org || report@
60type T, T2;
61expression x;
62expression E1,E2;
63statement S;
64position p;
65@@
66
67 x = (T)kmalloc@p(E1,E2);
68 if ((x==NULL) || ...) S
69 memset((T2)x,0,E1);
70
71@script:python depends on org@
72p << r.p;
73x << r.x;
74@@
75
76msg="%s" % (x)
77msg_safe=msg.replace("[","@(").replace("]",")")
78coccilib.org.print_todo(p[0], msg_safe)
79
80@script:python depends on report@
81p << r.p;
82x << r.x;
83@@
84
85msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
86coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci
new file mode 100644
index 000000000000..2ce115000af6
--- /dev/null
+++ b/scripts/coccinelle/api/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/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci
new file mode 100644
index 000000000000..e0805ad08d39
--- /dev/null
+++ b/scripts/coccinelle/api/kstrdup.cocci
@@ -0,0 +1,39 @@
1/// Use kstrdup rather than duplicating its implementation
2///
3// Confidence: High
4// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7// URL: http://coccinelle.lip6.fr/
8// Comments:
9// Options: -no_includes -include_headers
10
11virtual patch
12
13@@
14expression from,to;
15expression flag,E1,E2;
16statement S;
17@@
18
19- to = kmalloc(strlen(from) + 1,flag);
20+ to = kstrdup(from, flag);
21 ... when != \(from = E1 \| to = E1 \)
22 if (to==NULL || ...) S
23 ... when != \(from = E2 \| to = E2 \)
24- strcpy(to, from);
25
26@@
27expression x,from,to;
28expression flag,E1,E2,E3;
29statement S;
30@@
31
32- x = strlen(from) + 1;
33 ... when != \( x = E1 \| from = E1 \)
34- to = \(kmalloc\|kzalloc\)(x,flag);
35+ to = kstrdup(from, flag);
36 ... when != \(x = E2 \| from = E2 \| to = E2 \)
37 if (to==NULL || ...) S
38 ... when != \(x = E3 \| from = E3 \| to = E3 \)
39- memcpy(to, from, x);
diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci
new file mode 100644
index 000000000000..b5d722077dc1
--- /dev/null
+++ b/scripts/coccinelle/api/memdup.cocci
@@ -0,0 +1,40 @@
1/// Use kmemdup rather than duplicating its implementation
2///
3// Confidence: High
4// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7// URL: http://coccinelle.lip6.fr/
8// Comments:
9// Options: -no_includes -include_headers
10
11virtual patch
12
13@r1@
14expression from,to;
15expression flag;
16position p;
17@@
18
19 to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
20
21@r2@
22expression x,from,to;
23expression flag,E1;
24position p;
25@@
26
27 x = strlen(from) + 1;
28 ... when != \( x = E1 \| from = E1 \)
29 to = \(kmalloc@p\|kzalloc@p\)(x,flag);
30
31@@
32expression from,to,size,flag;
33position p != {r1.p,r2.p};
34statement S;
35@@
36
37- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
38+ to = kmemdup(from,size,flag);
39 if (to==NULL || ...) S
40- memcpy(to, from, size);
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci
new file mode 100644
index 000000000000..72ce012e878a
--- /dev/null
+++ b/scripts/coccinelle/api/memdup_user.cocci
@@ -0,0 +1,35 @@
1/// Use kmemdup_user rather than duplicating its implementation
2/// This is a little bit restricted to reduce false positives
3///
4// Confidence: High
5// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
6// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
7// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
8// URL: http://coccinelle.lip6.fr/
9// Comments:
10// Options: -no_includes -include_headers
11
12virtual patch
13
14@@
15expression from,to,size,flag;
16position p;
17identifier l1,l2;
18@@
19
20- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
21+ to = memdup_user(from,size);
22 if (
23- to==NULL
24+ IS_ERR(to)
25 || ...) {
26 <+... when != goto l1;
27- -ENOMEM
28+ PTR_ERR(to)
29 ...+>
30 }
31- if (copy_from_user(to, from, size) != 0) {
32- <+... when != goto l2;
33- -EFAULT
34- ...+>
35- }
diff --git a/scripts/coccinelle/api/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci
new file mode 100644
index 000000000000..1935a58b39d9
--- /dev/null
+++ b/scripts/coccinelle/api/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/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci
new file mode 100644
index 000000000000..f9f79d9245ee
--- /dev/null
+++ b/scripts/coccinelle/free/kfree.cocci
@@ -0,0 +1,117 @@
1/// Find a use after free.
2//# Values of variables may imply that some
3//# execution paths are not possible, resulting in false positives.
4//# Another source of false positives are macros such as
5//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
6///
7// Confidence: Moderate
8// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11// URL: http://coccinelle.lip6.fr/
12// Comments:
13// Options: -no_includes -include_headers
14
15virtual org
16virtual report
17
18@free@
19expression E;
20position p1;
21@@
22
23kfree@p1(E)
24
25@print expression@
26constant char *c;
27expression free.E,E2;
28type T;
29position p;
30identifier f;
31@@
32
33(
34 f(...,c,...,(T)E@p,...)
35|
36 E@p == E2
37|
38 E@p != E2
39|
40 !E@p
41|
42 E@p || ...
43)
44
45@sz@
46expression free.E;
47position p;
48@@
49
50 sizeof(<+...E@p...+>)
51
52@loop exists@
53expression E;
54identifier l;
55position ok;
56@@
57
58while (1) { ...
59 kfree@ok(E)
60 ... when != break;
61 when != goto l;
62 when forall
63}
64
65@r exists@
66expression free.E, subE<=free.E, E2;
67expression E1;
68iterator iter;
69statement S;
70position free.p1!=loop.ok,p2!={print.p,sz.p};
71@@
72
73kfree@p1(E,...)
74...
75(
76 iter(...,subE,...) S // no use
77|
78 list_remove_head(E1,subE,...)
79|
80 subE = E2
81|
82 subE++
83|
84 ++subE
85|
86 --subE
87|
88 subE--
89|
90 &subE
91|
92 BUG(...)
93|
94 BUG_ON(...)
95|
96 return_VALUE(...)
97|
98 return_ACPI_STATUS(...)
99|
100 E@p2 // bad use
101)
102
103@script:python depends on org@
104p1 << free.p1;
105p2 << r.p2;
106@@
107
108cocci.print_main("kfree",p1)
109cocci.print_secs("ref",p2)
110
111@script:python depends on report@
112p1 << free.p1;
113p2 << r.p2;
114@@
115
116msg = "reference preceded by free on line %s" % (p1[0].line)
117coccilib.report.print_report(p2[0],msg)
diff --git a/scripts/coccinelle/iterators/fen.cocci b/scripts/coccinelle/iterators/fen.cocci
new file mode 100644
index 000000000000..77bc108c3f59
--- /dev/null
+++ b/scripts/coccinelle/iterators/fen.cocci
@@ -0,0 +1,64 @@
1/// These iterators only exit normally when the loop cursor is NULL, so there
2/// is no point to call of_node_put on the final value.
3///
4// Confidence: High
5// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
6// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
7// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
8// URL: http://coccinelle.lip6.fr/
9// Comments:
10// Options: -no_includes -include_headers
11
12virtual patch
13
14@@
15iterator name for_each_node_by_name;
16expression np,E;
17identifier l;
18@@
19
20for_each_node_by_name(np,...) {
21 ... when != break;
22 when != goto l;
23}
24... when != np = E
25- of_node_put(np);
26
27@@
28iterator name for_each_node_by_type;
29expression np,E;
30identifier l;
31@@
32
33for_each_node_by_type(np,...) {
34 ... when != break;
35 when != goto l;
36}
37... when != np = E
38- of_node_put(np);
39
40@@
41iterator name for_each_compatible_node;
42expression np,E;
43identifier l;
44@@
45
46for_each_compatible_node(np,...) {
47 ... when != break;
48 when != goto l;
49}
50... when != np = E
51- of_node_put(np);
52
53@@
54iterator name for_each_matching_node;
55expression np,E;
56identifier l;
57@@
58
59for_each_matching_node(np,...) {
60 ... when != break;
61 when != goto l;
62}
63... when != np = E
64- of_node_put(np);
diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci
new file mode 100644
index 000000000000..baa4297a4ed1
--- /dev/null
+++ b/scripts/coccinelle/iterators/itnull.cocci
@@ -0,0 +1,58 @@
1/// Many iterators have the property that the first argument is always bound
2/// to a real list element, never NULL. False positives arise for some
3/// iterators that do not have this property, or in cases when the loop
4/// cursor is reassigned. The latter should only happen when the matched
5/// code is on the way to a loop exit (break, goto, or return).
6///
7// Confidence: Moderate
8// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11// URL: http://coccinelle.lip6.fr/
12// Comments:
13// Options: -no_includes -include_headers
14
15virtual patch
16
17@@
18iterator I;
19expression x,E,E1,E2;
20statement S,S1,S2;
21@@
22
23I(x,...) { <...
24(
25- if (x == NULL && ...) S
26|
27- if (x != NULL || ...)
28 S
29|
30- (x == NULL) ||
31 E
32|
33- (x != NULL) &&
34 E
35|
36- (x == NULL && ...) ? E1 :
37 E2
38|
39- (x != NULL || ...) ?
40 E1
41- : E2
42|
43- if (x == NULL && ...) S1 else
44 S2
45|
46- if (x != NULL || ...)
47 S1
48- else S2
49|
50+ BAD(
51 x == NULL
52+ )
53|
54+ BAD(
55 x != NULL
56+ )
57)
58 ...> } \ No newline at end of file
diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci
new file mode 100644
index 000000000000..b2967475679b
--- /dev/null
+++ b/scripts/coccinelle/iterators/list_entry_update.cocci
@@ -0,0 +1,62 @@
1/// list_for_each_entry uses its first argument to get from one element of
2/// the list to the next, so it is usually not a good idea to reassign it.
3/// The first rule finds such a reassignment and the second rule checks
4/// that there is a path from the reassignment back to the top of the loop.
5///
6// Confidence: High
7// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
8// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
9// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
10// URL: http://coccinelle.lip6.fr/
11// Comments:
12// Options: -no_includes -include_headers
13
14virtual context
15virtual org
16virtual report
17
18@r@
19iterator name list_for_each_entry;
20expression x,E;
21position p1,p2;
22@@
23
24list_for_each_entry@p1(x,...) { <... x =@p2 E ...> }
25
26@depends on context && !org && !report@
27expression x,E;
28position r.p1,r.p2;
29statement S;
30@@
31
32*x =@p2 E
33...
34list_for_each_entry@p1(x,...) S
35
36// ------------------------------------------------------------------------
37
38@back depends on (org || report) && !context exists@
39expression x,E;
40position r.p1,r.p2;
41statement S;
42@@
43
44x =@p2 E
45...
46list_for_each_entry@p1(x,...) S
47
48@script:python depends on back && org@
49p1 << r.p1;
50p2 << r.p2;
51@@
52
53cocci.print_main("iterator",p1)
54cocci.print_secs("update",p2)
55
56@script:python depends on back && report@
57p1 << r.p1;
58p2 << r.p2;
59@@
60
61msg = "iterator with update on line %s" % (p2[0].line)
62coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci
new file mode 100644
index 000000000000..00af5344a68f
--- /dev/null
+++ b/scripts/coccinelle/locks/call_kern.cocci
@@ -0,0 +1,74 @@
1/// Find functions that refer to GFP_KERNEL but are called with locks held.
2/// The proposed change of converting the GFP_KERNEL is not necessarily the
3/// correct one. It may be desired to unlock the lock, or to not call the
4/// function under the lock in the first place.
5///
6// Confidence: Moderate
7// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
8// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
9// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
10// URL: http://coccinelle.lip6.fr/
11// Comments:
12// Options: -no_includes -include_headers
13
14virtual patch
15
16@gfp exists@
17identifier fn;
18position p;
19@@
20
21fn(...) {
22 ... when != read_unlock_irq(...)
23 when != write_unlock_irq(...)
24 when != read_unlock_irqrestore(...)
25 when != write_unlock_irqrestore(...)
26 when != spin_unlock(...)
27 when != spin_unlock_irq(...)
28 when != spin_unlock_irqrestore(...)
29 when != local_irq_enable(...)
30 when any
31 GFP_KERNEL@p
32 ... when any
33}
34
35@locked@
36identifier gfp.fn;
37@@
38
39(
40read_lock_irq
41|
42write_lock_irq
43|
44read_lock_irqsave
45|
46write_lock_irqsave
47|
48spin_lock
49|
50spin_trylock
51|
52spin_lock_irq
53|
54spin_lock_irqsave
55|
56local_irq_disable
57)
58 (...)
59... when != read_unlock_irq(...)
60 when != write_unlock_irq(...)
61 when != read_unlock_irqrestore(...)
62 when != write_unlock_irqrestore(...)
63 when != spin_unlock(...)
64 when != spin_unlock_irq(...)
65 when != spin_unlock_irqrestore(...)
66 when != local_irq_enable(...)
67fn(...)
68
69@depends on locked@
70position gfp.p;
71@@
72
73- GFP_KERNEL@p
74+ GFP_ATOMIC
diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci
new file mode 100644
index 000000000000..63b24e682fad
--- /dev/null
+++ b/scripts/coccinelle/locks/double_lock.cocci
@@ -0,0 +1,92 @@
1/// Find double locks. False positives may occur when some paths cannot
2/// occur at execution, due to the values of variables, and when there is
3/// an intervening function call that releases the lock.
4///
5// Confidence: Moderate
6// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
7// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
8// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
9// URL: http://coccinelle.lip6.fr/
10// Comments:
11// Options: -no_includes -include_headers
12
13virtual org
14virtual report
15
16@locked@
17position p1;
18expression E1;
19position p;
20@@
21
22(
23mutex_lock@p1
24|
25mutex_trylock@p1
26|
27spin_lock@p1
28|
29spin_trylock@p1
30|
31read_lock@p1
32|
33read_trylock@p1
34|
35write_lock@p1
36|
37write_trylock@p1
38) (E1@p,...);
39
40@balanced@
41position p1 != locked.p1;
42position locked.p;
43identifier lock,unlock;
44expression x <= locked.E1;
45expression E,locked.E1;
46expression E2;
47@@
48
49if (E) {
50 <+... when != E1
51 lock(E1@p,...)
52 ...+>
53}
54... when != E1
55 when != \(x = E2\|&x\)
56 when forall
57if (E) {
58 <+... when != E1
59 unlock@p1(E1,...)
60 ...+>
61}
62
63@r depends on !balanced exists@
64expression x <= locked.E1;
65expression locked.E1;
66expression E2;
67identifier lock;
68position locked.p,p1,p2;
69@@
70
71lock@p1 (E1@p,...);
72... when != E1
73 when != \(x = E2\|&x\)
74lock@p2 (E1,...);
75
76@script:python depends on org@
77p1 << r.p1;
78p2 << r.p2;
79lock << r.lock;
80@@
81
82cocci.print_main(lock,p1)
83cocci.print_secs("second lock",p2)
84
85@script:python depends on report@
86p1 << r.p1;
87p2 << r.p2;
88lock << r.lock;
89@@
90
91msg = "second lock on line %s" % (p2[0].line)
92coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci
new file mode 100644
index 000000000000..b4344d838097
--- /dev/null
+++ b/scripts/coccinelle/locks/flags.cocci
@@ -0,0 +1,80 @@
1/// Find nested lock+irqsave functions that use the same flags variables
2///
3// Confidence: High
4// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7// URL: http://coccinelle.lip6.fr/
8// Comments:
9// Options: -no_includes -include_headers
10
11virtual context
12virtual org
13virtual report
14
15@r@
16expression lock1,lock2,flags;
17position p1,p2;
18@@
19
20(
21spin_lock_irqsave@p1(lock1,flags)
22|
23read_lock_irqsave@p1(lock1,flags)
24|
25write_lock_irqsave@p1(lock1,flags)
26)
27... when != flags
28(
29spin_lock_irqsave(lock1,flags)
30|
31read_lock_irqsave(lock1,flags)
32|
33write_lock_irqsave(lock1,flags)
34|
35spin_lock_irqsave@p2(lock2,flags)
36|
37read_lock_irqsave@p2(lock2,flags)
38|
39write_lock_irqsave@p2(lock2,flags)
40)
41
42@d@
43expression f <= r.flags;
44expression lock1,lock2,flags;
45position r.p1, r.p2;
46@@
47
48(
49*spin_lock_irqsave@p1(lock1,flags)
50|
51*read_lock_irqsave@p1(lock1,flags)
52|
53*write_lock_irqsave@p1(lock1,flags)
54)
55... when != f
56(
57*spin_lock_irqsave@p2(lock2,flags)
58|
59*read_lock_irqsave@p2(lock2,flags)
60|
61*write_lock_irqsave@p2(lock2,flags)
62)
63
64// ----------------------------------------------------------------------
65
66@script:python depends on d && org@
67p1 << r.p1;
68p2 << r.p2;
69@@
70
71cocci.print_main("original lock",p1)
72cocci.print_secs("nested lock+irqsave that reuses flags",p2)
73
74@script:python depends on d && report@
75p1 << r.p1;
76p2 << r.p2;
77@@
78
79msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line)
80coccilib.report.print_report(p2[0], msg)
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci
new file mode 100644
index 000000000000..7641a2925434
--- /dev/null
+++ b/scripts/coccinelle/locks/mini_lock.cocci
@@ -0,0 +1,95 @@
1/// Find missing unlocks. This semantic match considers the specific case
2/// where the unlock is missing from an if branch, and there is a lock
3/// before the if and an unlock after the if. False positives are due to
4/// cases where the if branch represents a case where the function is
5/// supposed to exit with the lock held, or where there is some preceding
6/// function call that releases the lock.
7///
8// Confidence: Moderate
9// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
10// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
11// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
12// URL: http://coccinelle.lip6.fr/
13// Comments:
14// Options: -no_includes -include_headers
15
16virtual org
17virtual report
18
19@prelocked@
20position p1,p;
21expression E1;
22@@
23
24(
25mutex_lock@p1
26|
27mutex_trylock@p1
28|
29spin_lock@p1
30|
31spin_trylock@p1
32|
33read_lock@p1
34|
35read_trylock@p1
36|
37write_lock@p1
38|
39write_trylock@p1
40|
41read_lock_irq@p1
42|
43write_lock_irq@p1
44|
45read_lock_irqsave@p1
46|
47write_lock_irqsave@p1
48|
49spin_lock_irq@p1
50|
51spin_lock_irqsave@p1
52) (E1@p,...);
53
54@looped@
55position r;
56@@
57
58for(...;...;...) { <+... return@r ...; ...+> }
59
60@err@
61expression E1;
62position prelocked.p;
63position up != prelocked.p1;
64position r!=looped.r;
65identifier lock,unlock;
66@@
67
68lock(E1@p,...);
69<+... when != E1
70if (...) {
71 ... when != E1
72 return@r ...;
73}
74...+>
75unlock@up(E1,...);
76
77@script:python depends on org@
78p << prelocked.p1;
79lock << err.lock;
80unlock << err.unlock;
81p2 << err.r;
82@@
83
84cocci.print_main(lock,p)
85cocci.print_secs(unlock,p2)
86
87@script:python depends on report@
88p << prelocked.p1;
89lock << err.lock;
90unlock << err.unlock;
91p2 << err.r;
92@@
93
94msg = "preceding lock on line %s" % (p[0].line)
95coccilib.report.print_report(p2[0],msg)
diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci
new file mode 100644
index 000000000000..156b20adb351
--- /dev/null
+++ b/scripts/coccinelle/misc/doubleinit.cocci
@@ -0,0 +1,53 @@
1/// Find duplicate field initializations. This has a high rate of false
2/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
3/// initialization.
4///
5// Confidence: Low
6// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
7// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
8// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
9// URL: http://coccinelle.lip6.fr/
10// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
11// Options: -no_includes -include_headers
12
13virtual org
14virtual report
15
16@r@
17identifier I, s, fld;
18position p0,p;
19expression E;
20@@
21
22struct I s =@p0 { ..., .fld@p = E, ...};
23
24@s@
25identifier I, s, r.fld;
26position r.p0,p;
27expression E;
28@@
29
30struct I s =@p0 { ..., .fld@p = E, ...};
31
32@script:python depends on org@
33p0 << r.p0;
34fld << r.fld;
35ps << s.p;
36pr << r.p;
37@@
38
39if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
40 cocci.print_main(fld,p0)
41 cocci.print_secs("s",ps)
42 cocci.print_secs("r",pr)
43
44@script:python depends on report@
45p0 << r.p0;
46fld << r.fld;
47ps << s.p;
48pr << r.p;
49@@
50
51if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
52 msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line)
53 coccilib.report.print_report(p0[0],msg)
diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci
new file mode 100644
index 000000000000..b7ed91dbeb95
--- /dev/null
+++ b/scripts/coccinelle/misc/ifcol.cocci
@@ -0,0 +1,48 @@
1/// Find confusingly indented code in or after an if. An if branch should
2/// be indented. The code following an if should not be indented.
3/// Sometimes, code after an if that is indented is actually intended to be
4/// part of the if branch.
5///
6/// This has a high rate of false positives, because Coccinelle's column
7/// calculation does not distinguish between spaces and tabs, so code that
8/// is not visually aligned may be considered to be in the same column.
9///
10// Confidence: Low
11// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
12// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
13// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
14// URL: http://coccinelle.lip6.fr/
15// Comments:
16// Options: -no_includes -include_headers
17
18virtual org
19virtual report
20
21@r disable braces4@
22position p1,p2;
23statement S1,S2;
24@@
25
26(
27if (...) { ... }
28|
29if (...) S1@p1 S2@p2
30)
31
32@script:python depends on org@
33p1 << r.p1;
34p2 << r.p2;
35@@
36
37if (p1[0].column == p2[0].column):
38 cocci.print_main("branch",p1)
39 cocci.print_secs("after",p2)
40
41@script:python depends on report@
42p1 << r.p1;
43p2 << r.p2;
44@@
45
46if (p1[0].column == p2[0].column):
47 msg = "code aligned with following code on line %s" % (p2[0].line)
48 coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci
new file mode 100644
index 000000000000..cdac6cfcce92
--- /dev/null
+++ b/scripts/coccinelle/null/deref_null.cocci
@@ -0,0 +1,282 @@
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 org
15virtual report
16
17@ifm@
18expression *E;
19statement S1,S2;
20position p1;
21@@
22
23if@p1 ((E == NULL && ...) || ...) S1 else S2
24
25// The following two rules are separate, because both can match a single
26// expression in different ways
27@pr1 expression@
28expression *ifm.E;
29identifier f;
30position p1;
31@@
32
33 (E != NULL && ...) ? <+...E->f@p1...+> : ...
34
35@pr2 expression@
36expression *ifm.E;
37identifier f;
38position p2;
39@@
40
41(
42 (E != NULL) && ... && <+...E->f@p2...+>
43|
44 (E == NULL) || ... || <+...E->f@p2...+>
45|
46 sizeof(<+...E->f@p2...+>)
47)
48
49// For org and report modes
50
51@r depends on !context && (org || report) exists@
52expression subE <= ifm.E;
53expression *ifm.E;
54expression E1,E2;
55identifier f;
56statement S1,S2,S3,S4;
57iterator iter;
58position p!={pr1.p1,pr2.p2};
59position ifm.p1;
60@@
61
62if@p1 ((E == NULL && ...) || ...)
63{
64 ... when != if (...) S1 else S2
65(
66 iter(subE,...) S4 // no use
67|
68 list_remove_head(E2,subE,...)
69|
70 subE = E1
71|
72 for(subE = E1;...;...) S4
73|
74 subE++
75|
76 ++subE
77|
78 --subE
79|
80 subE--
81|
82 &subE
83|
84 E->f@p // bad use
85)
86 ... when any
87 return ...;
88}
89else S3
90
91@script:python depends on !context && !org && report@
92p << r.p;
93p1 << ifm.p1;
94x << ifm.E;
95@@
96
97msg="ERROR: %s is NULL but dereferenced." % (x)
98coccilib.report.print_report(p[0], msg)
99cocci.include_match(False)
100
101@script:python depends on !context && org && !report@
102p << r.p;
103p1 << ifm.p1;
104x << ifm.E;
105@@
106
107msg="ERROR: %s is NULL but dereferenced." % (x)
108msg_safe=msg.replace("[","@(").replace("]",")")
109cocci.print_main(msg_safe,p)
110cocci.include_match(False)
111
112@s depends on !context && (org || report) exists@
113expression subE <= ifm.E;
114expression *ifm.E;
115expression E1,E2;
116identifier f;
117statement S1,S2,S3,S4;
118iterator iter;
119position p!={pr1.p1,pr2.p2};
120position ifm.p1;
121@@
122
123if@p1 ((E == NULL && ...) || ...)
124{
125 ... when != if (...) S1 else S2
126(
127 iter(subE,...) S4 // no use
128|
129 list_remove_head(E2,subE,...)
130|
131 subE = E1
132|
133 for(subE = E1;...;...) S4
134|
135 subE++
136|
137 ++subE
138|
139 --subE
140|
141 subE--
142|
143 &subE
144|
145 E->f@p // bad use
146)
147 ... when any
148}
149else S3
150
151@script:python depends on !context && !org && report@
152p << s.p;
153p1 << ifm.p1;
154x << ifm.E;
155@@
156
157msg="ERROR: %s is NULL but dereferenced." % (x)
158coccilib.report.print_report(p[0], msg)
159
160@script:python depends on !context && org && !report@
161p << s.p;
162p1 << ifm.p1;
163x << ifm.E;
164@@
165
166msg="ERROR: %s is NULL but dereferenced." % (x)
167msg_safe=msg.replace("[","@(").replace("]",")")
168cocci.print_main(msg_safe,p)
169
170// For context mode
171
172@depends on context && !org && !report exists@
173expression subE <= ifm.E;
174expression *ifm.E;
175expression E1,E2;
176identifier f;
177statement S1,S2,S3,S4;
178iterator iter;
179position p!={pr1.p1,pr2.p2};
180position ifm.p1;
181@@
182
183if@p1 ((E == NULL && ...) || ...)
184{
185 ... when != if (...) S1 else S2
186(
187 iter(subE,...) S4 // no use
188|
189 list_remove_head(E2,subE,...)
190|
191 subE = E1
192|
193 for(subE = E1;...;...) S4
194|
195 subE++
196|
197 ++subE
198|
199 --subE
200|
201 subE--
202|
203 &subE
204|
205* E->f@p // bad use
206)
207 ... when any
208 return ...;
209}
210else S3
211
212// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
213// It is need because the previous rule as already made a "change".
214
215@ifm1@
216expression *E;
217statement S1,S2;
218position p1;
219@@
220
221if@p1 ((E == NULL && ...) || ...) S1 else S2
222
223@pr11 expression@
224expression *ifm1.E;
225identifier f;
226position p1;
227@@
228
229 (E != NULL && ...) ? <+...E->f@p1...+> : ...
230
231@pr12 expression@
232expression *ifm1.E;
233identifier f;
234position p2;
235@@
236
237(
238 (E != NULL) && ... && <+...E->f@p2...+>
239|
240 (E == NULL) || ... || <+...E->f@p2...+>
241|
242 sizeof(<+...E->f@p2...+>)
243)
244
245@depends on context && !org && !report exists@
246expression subE <= ifm1.E;
247expression *ifm1.E;
248expression E1,E2;
249identifier f;
250statement S1,S2,S3,S4;
251iterator iter;
252position p!={pr11.p1,pr12.p2};
253position ifm1.p1;
254@@
255
256if@p1 ((E == NULL && ...) || ...)
257{
258 ... when != if (...) S1 else S2
259(
260 iter(subE,...) S4 // no use
261|
262 list_remove_head(E2,subE,...)
263|
264 subE = E1
265|
266 for(subE = E1;...;...) S4
267|
268 subE++
269|
270 ++subE
271|
272 --subE
273|
274 subE--
275|
276 &subE
277|
278* E->f@p // bad use
279)
280 ... when any
281}
282else S3
diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci
new file mode 100644
index 000000000000..4c9c52b9c413
--- /dev/null
+++ b/scripts/coccinelle/null/eno.cocci
@@ -0,0 +1,20 @@
1/// The various basic memory allocation functions don't return ERR_PTR
2///
3// Confidence: High
4// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
7// URL: http://coccinelle.lip6.fr/
8// Comments:
9// Options: -no_includes -include_headers
10
11virtual patch
12
13@@
14expression x,E;
15@@
16
17x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
18... when != x = E
19- IS_ERR(x)
20+ !x
diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci
new file mode 100644
index 000000000000..949bf656c64c
--- /dev/null
+++ b/scripts/coccinelle/null/kmerr.cocci
@@ -0,0 +1,72 @@
1/// This semantic patch looks for kmalloc etc that are not followed by a
2/// NULL check. It only gives a report in the case where there is some
3/// error handling code later in the function, which may be helpful
4/// in determining what the error handling code for the call to kmalloc etc
5/// should be.
6///
7// Confidence: High
8// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11// URL: http://coccinelle.lip6.fr/
12// Comments:
13// Options: -no_includes -include_headers
14
15virtual context
16virtual org
17virtual report
18
19@withtest@
20expression x;
21position p;
22identifier f,fld;
23@@
24
25x@p = f(...);
26... when != x->fld
27\(x == NULL \| x != NULL\)
28
29@fixed depends on context && !org && !report@
30expression x,x1;
31position p1 != withtest.p;
32statement S;
33position any withtest.p;
34identifier f;
35@@
36
37*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
38...
39*x1@p = f(...);
40if (!x1) S
41
42// ------------------------------------------------------------------------
43
44@rfixed depends on (org || report) && !context exists@
45expression x,x1;
46position p1 != withtest.p;
47position p2;
48statement S;
49position any withtest.p;
50identifier f;
51@@
52
53x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
54...
55x1@p = f@p2(...);
56if (!x1) S
57
58@script:python depends on org@
59p1 << rfixed.p1;
60p2 << rfixed.p2;
61@@
62
63cocci.print_main("alloc call",p1)
64cocci.print_secs("possible model",p2)
65
66@script:python depends on report@
67p1 << rfixed.p1;
68p2 << rfixed.p2;
69@@
70
71msg = "alloc with no test, possible model on line %s" % (p2[0].line)
72coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/tests/doublebitand.cocci b/scripts/coccinelle/tests/doublebitand.cocci
new file mode 100644
index 000000000000..9ba73d05a77e
--- /dev/null
+++ b/scripts/coccinelle/tests/doublebitand.cocci
@@ -0,0 +1,54 @@
1/// Find bit operations that include the same argument more than once
2//# One source of false positives is when the argument performs a side
3//# effect. Another source of false positives is when a neutral value
4//# such as 0 for | is used to indicate no information, to maintain the
5//# same structure as other similar expressions
6///
7// Confidence: Moderate
8// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
11// URL: http://coccinelle.lip6.fr/
12// Comments:
13// Options: -no_includes -include_headers
14
15virtual context
16virtual org
17virtual report
18
19@r expression@
20expression E;
21position p;
22@@
23
24(
25* E@p
26 & ... & E
27|
28* E@p
29 | ... | E
30|
31* E@p
32 & ... & !E
33|
34* E@p
35 | ... | !E
36|
37* !E@p
38 & ... & E
39|
40* !E@p
41 | ... | E
42)
43
44@script:python depends on org@
45p << r.p;
46@@
47
48cocci.print_main("duplicated argument to & or |",p)
49
50@script:python depends on report@
51p << r.p;
52@@
53
54coccilib.report.print_report(p[0],"duplicated argument to & or |")
diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci
new file mode 100644
index 000000000000..13a2c0e8a4bf
--- /dev/null
+++ b/scripts/coccinelle/tests/doubletest.cocci
@@ -0,0 +1,40 @@
1/// Find &&/|| operations that include the same argument more than once
2//# A common source of false positives is when the argument performs a side
3//# effect.
4///
5// Confidence: Moderate
6// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
7// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
8// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
9// URL: http://coccinelle.lip6.fr/
10// Comments:
11// Options: -no_includes -include_headers
12
13virtual context
14virtual org
15virtual report
16
17@r expression@
18expression E;
19position p;
20@@
21
22(
23* E@p
24 || ... || E
25|
26* E@p
27 && ... && E
28)
29
30@script:python depends on org@
31p << r.p;
32@@
33
34cocci.print_main("duplicated argument to && or ||",p)
35
36@script:python depends on report@
37p << r.p;
38@@
39
40coccilib.report.print_report(p[0],"duplicated argument to && or ||")
diff --git a/scripts/config b/scripts/config
index 608d7fdb13e8..a7c7c4b8e957 100755
--- a/scripts/config
+++ b/scripts/config
@@ -10,8 +10,10 @@ commands:
10 --enable|-e option Enable option 10 --enable|-e option Enable option
11 --disable|-d option Disable option 11 --disable|-d option Disable option
12 --module|-m option Turn option into a module 12 --module|-m option Turn option into a module
13 --set-str option value 13 --set-str option string
14 Set option to "value" 14 Set option to "string"
15 --set-val option value
16 Set option to value
15 --state|-s option Print state of option (n,y,m,undef) 17 --state|-s option Print state of option (n,y,m,undef)
16 18
17 --enable-after|-E beforeopt option 19 --enable-after|-E beforeopt option
@@ -86,7 +88,7 @@ while [ "$1" != "" ] ; do
86 B=$ARG 88 B=$ARG
87 shift 2 89 shift 2
88 ;; 90 ;;
89 --*) 91 -*)
90 checkarg "$1" 92 checkarg "$1"
91 shift 93 shift
92 ;; 94 ;;
@@ -109,6 +111,11 @@ while [ "$1" != "" ] ; do
109 shift 111 shift
110 ;; 112 ;;
111 113
114 --set-val)
115 set_var "CONFIG_$ARG" "CONFIG_$ARG=$1"
116 shift
117 ;;
118
112 --state|-s) 119 --state|-s)
113 if grep -q "# CONFIG_$ARG is not set" $FN ; then 120 if grep -q "# CONFIG_$ARG is not set" $FN ; then
114 echo n 121 echo n
diff --git a/scripts/conmakehash.c b/scripts/conmakehash.c
index e0c6891a9ad4..263a44d57fa9 100644
--- a/scripts/conmakehash.c
+++ b/scripts/conmakehash.c
@@ -24,14 +24,14 @@
24 24
25typedef unsigned short unicode; 25typedef unsigned short unicode;
26 26
27void usage(char *argv0) 27static void usage(char *argv0)
28{ 28{
29 fprintf(stderr, "Usage: \n" 29 fprintf(stderr, "Usage: \n"
30 " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0); 30 " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
31 exit(EX_USAGE); 31 exit(EX_USAGE);
32} 32}
33 33
34int getunicode(char **p0) 34static int getunicode(char **p0)
35{ 35{
36 char *p = *p0; 36 char *p = *p0;
37 37
@@ -49,7 +49,7 @@ unicode unitable[MAX_FONTLEN][255];
49 /* Massive overkill, but who cares? */ 49 /* Massive overkill, but who cares? */
50int unicount[MAX_FONTLEN]; 50int unicount[MAX_FONTLEN];
51 51
52void addpair(int fp, int un) 52static void addpair(int fp, int un)
53{ 53{
54 int i; 54 int i;
55 55
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/.gitignore b/scripts/dtc/.gitignore
new file mode 100644
index 000000000000..095acb49a374
--- /dev/null
+++ b/scripts/dtc/.gitignore
@@ -0,0 +1,5 @@
1dtc
2dtc-lexer.lex.c
3dtc-parser.tab.c
4dtc-parser.tab.h
5
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 01cdb36fc583..04a31c17639f 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -4,7 +4,7 @@ hostprogs-y := dtc
4always := $(hostprogs-y) 4always := $(hostprogs-y)
5 5
6dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ 6dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
7 srcpos.o checks.o 7 srcpos.o checks.o util.o
8dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o 8dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
9 9
10# Source files need to get at the userspace version of libfdt_env.h to compile 10# Source files need to get at the userspace version of libfdt_env.h to compile
@@ -19,6 +19,7 @@ HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
19HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC) 19HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC)
20HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC) 20HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
21HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC) 21HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
22HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
22 23
23HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC) 24HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
24HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) 25HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 95485796f253..a662a0044798 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -278,32 +278,112 @@ static void check_property_name_chars(struct check *c, struct node *dt,
278} 278}
279PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); 279PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
280 280
281#define DESCLABEL_FMT "%s%s%s%s%s"
282#define DESCLABEL_ARGS(node,prop,mark) \
283 ((mark) ? "value of " : ""), \
284 ((prop) ? "'" : ""), \
285 ((prop) ? (prop)->name : ""), \
286 ((prop) ? "' in " : ""), (node)->fullpath
287
288static void check_duplicate_label(struct check *c, struct node *dt,
289 const char *label, struct node *node,
290 struct property *prop, struct marker *mark)
291{
292 struct node *othernode = NULL;
293 struct property *otherprop = NULL;
294 struct marker *othermark = NULL;
295
296 othernode = get_node_by_label(dt, label);
297
298 if (!othernode)
299 otherprop = get_property_by_label(dt, label, &othernode);
300 if (!othernode)
301 othermark = get_marker_label(dt, label, &othernode,
302 &otherprop);
303
304 if (!othernode)
305 return;
306
307 if ((othernode != node) || (otherprop != prop) || (othermark != mark))
308 FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
309 " and " DESCLABEL_FMT,
310 label, DESCLABEL_ARGS(node, prop, mark),
311 DESCLABEL_ARGS(othernode, otherprop, othermark));
312}
313
314static void check_duplicate_label_node(struct check *c, struct node *dt,
315 struct node *node)
316{
317 struct label *l;
318
319 for_each_label(node->labels, l)
320 check_duplicate_label(c, dt, l->label, node, NULL, NULL);
321}
322static void check_duplicate_label_prop(struct check *c, struct node *dt,
323 struct node *node, struct property *prop)
324{
325 struct marker *m = prop->val.markers;
326 struct label *l;
327
328 for_each_label(prop->labels, l)
329 check_duplicate_label(c, dt, l->label, node, prop, NULL);
330
331 for_each_marker_of_type(m, LABEL)
332 check_duplicate_label(c, dt, m->ref, node, prop, m);
333}
334CHECK(duplicate_label, NULL, check_duplicate_label_node,
335 check_duplicate_label_prop, NULL, ERROR);
336
281static void check_explicit_phandles(struct check *c, struct node *root, 337static void check_explicit_phandles(struct check *c, struct node *root,
282 struct node *node) 338 struct node *node, struct property *prop)
283{ 339{
284 struct property *prop; 340 struct marker *m;
285 struct node *other; 341 struct node *other;
286 cell_t phandle; 342 cell_t phandle;
287 343
288 prop = get_property(node, "linux,phandle"); 344 if (!streq(prop->name, "phandle")
289 if (! prop) 345 && !streq(prop->name, "linux,phandle"))
290 return; /* No phandle, that's fine */ 346 return;
291 347
292 if (prop->val.len != sizeof(cell_t)) { 348 if (prop->val.len != sizeof(cell_t)) {
293 FAIL(c, "%s has bad length (%d) linux,phandle property", 349 FAIL(c, "%s has bad length (%d) %s property",
294 node->fullpath, prop->val.len); 350 node->fullpath, prop->val.len, prop->name);
351 return;
352 }
353
354 m = prop->val.markers;
355 for_each_marker_of_type(m, REF_PHANDLE) {
356 assert(m->offset == 0);
357 if (node != get_node_by_ref(root, m->ref))
358 /* "Set this node's phandle equal to some
359 * other node's phandle". That's nonsensical
360 * by construction. */ {
361 FAIL(c, "%s in %s is a reference to another node",
362 prop->name, node->fullpath);
363 return;
364 }
365 /* But setting this node's phandle equal to its own
366 * phandle is allowed - that means allocate a unique
367 * phandle for this node, even if it's not otherwise
368 * referenced. The value will be filled in later, so
369 * no further checking for now. */
295 return; 370 return;
296 } 371 }
297 372
298 phandle = propval_cell(prop); 373 phandle = propval_cell(prop);
374
299 if ((phandle == 0) || (phandle == -1)) { 375 if ((phandle == 0) || (phandle == -1)) {
300 FAIL(c, "%s has invalid linux,phandle value 0x%x", 376 FAIL(c, "%s has bad value (0x%x) in %s property",
301 node->fullpath, phandle); 377 node->fullpath, phandle, prop->name);
302 return; 378 return;
303 } 379 }
304 380
381 if (node->phandle && (node->phandle != phandle))
382 FAIL(c, "%s has %s property which replaces existing phandle information",
383 node->fullpath, prop->name);
384
305 other = get_node_by_phandle(root, phandle); 385 other = get_node_by_phandle(root, phandle);
306 if (other) { 386 if (other && (other != node)) {
307 FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", 387 FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
308 node->fullpath, phandle, other->fullpath); 388 node->fullpath, phandle, other->fullpath);
309 return; 389 return;
@@ -311,7 +391,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
311 391
312 node->phandle = phandle; 392 node->phandle = phandle;
313} 393}
314NODE_CHECK(explicit_phandles, NULL, ERROR); 394PROP_CHECK(explicit_phandles, NULL, ERROR);
315 395
316static void check_name_properties(struct check *c, struct node *root, 396static void check_name_properties(struct check *c, struct node *root,
317 struct node *node) 397 struct node *node)
@@ -549,6 +629,9 @@ static struct check *check_table[] = {
549 &duplicate_node_names, &duplicate_property_names, 629 &duplicate_node_names, &duplicate_property_names,
550 &node_name_chars, &node_name_format, &property_name_chars, 630 &node_name_chars, &node_name_format, &property_name_chars,
551 &name_is_string, &name_properties, 631 &name_is_string, &name_properties,
632
633 &duplicate_label,
634
552 &explicit_phandles, 635 &explicit_phandles,
553 &phandle_references, &path_references, 636 &phandle_references, &path_references,
554 637
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index dd2e3d39d4c1..fe555e819bf8 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -217,7 +217,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
217 return d; 217 return d;
218} 218}
219 219
220struct data data_append_markers(struct data d, struct marker *m) 220static struct data data_append_markers(struct data d, struct marker *m)
221{ 221{
222 struct marker **mp = &d.markers; 222 struct marker **mp = &d.markers;
223 223
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 44dbfd3f0976..e866ea5166ac 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -18,7 +18,7 @@
18 * USA 18 * USA
19 */ 19 */
20 20
21%option noyywrap nounput yylineno 21%option noyywrap nounput noinput never-interactive
22 22
23%x INCLUDE 23%x INCLUDE
24%x BYTESTRING 24%x BYTESTRING
@@ -38,6 +38,13 @@ LINECOMMENT "//".*\n
38#include "srcpos.h" 38#include "srcpos.h"
39#include "dtc-parser.tab.h" 39#include "dtc-parser.tab.h"
40 40
41YYLTYPE yylloc;
42
43/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
44#define YY_USER_ACTION \
45 { \
46 srcpos_update(&yylloc, yytext, yyleng); \
47 }
41 48
42/*#define LEXDEBUG 1*/ 49/*#define LEXDEBUG 1*/
43 50
@@ -47,15 +54,10 @@ LINECOMMENT "//".*\n
47#define DPRINT(fmt, ...) do { } while (0) 54#define DPRINT(fmt, ...) do { } while (0)
48#endif 55#endif
49 56
50static int dts_version; /* = 0 */ 57static int dts_version = 1;
51 58
52#define BEGIN_DEFAULT() if (dts_version == 0) { \ 59#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
53 DPRINT("<INITIAL>\n"); \
54 BEGIN(INITIAL); \
55 } else { \
56 DPRINT("<V1>\n"); \
57 BEGIN(V1); \ 60 BEGIN(V1); \
58 }
59 61
60static void push_input_file(const char *filename); 62static void push_input_file(const char *filename);
61static int pop_input_file(void); 63static int pop_input_file(void);
@@ -75,18 +77,13 @@ static int pop_input_file(void);
75 } 77 }
76 78
77<*>{STRING} { 79<*>{STRING} {
78 yylloc.file = srcpos_file;
79 yylloc.first_line = yylineno;
80 DPRINT("String: %s\n", yytext); 80 DPRINT("String: %s\n", yytext);
81 yylval.data = data_copy_escape_string(yytext+1, 81 yylval.data = data_copy_escape_string(yytext+1,
82 yyleng-2); 82 yyleng-2);
83 yylloc.first_line = yylineno;
84 return DT_STRING; 83 return DT_STRING;
85 } 84 }
86 85
87<*>"/dts-v1/" { 86<*>"/dts-v1/" {
88 yylloc.file = srcpos_file;
89 yylloc.first_line = yylineno;
90 DPRINT("Keyword: /dts-v1/\n"); 87 DPRINT("Keyword: /dts-v1/\n");
91 dts_version = 1; 88 dts_version = 1;
92 BEGIN_DEFAULT(); 89 BEGIN_DEFAULT();
@@ -94,106 +91,57 @@ static int pop_input_file(void);
94 } 91 }
95 92
96<*>"/memreserve/" { 93<*>"/memreserve/" {
97 yylloc.file = srcpos_file;
98 yylloc.first_line = yylineno;
99 DPRINT("Keyword: /memreserve/\n"); 94 DPRINT("Keyword: /memreserve/\n");
100 BEGIN_DEFAULT(); 95 BEGIN_DEFAULT();
101 return DT_MEMRESERVE; 96 return DT_MEMRESERVE;
102 } 97 }
103 98
104<*>{LABEL}: { 99<*>{LABEL}: {
105 yylloc.file = srcpos_file;
106 yylloc.first_line = yylineno;
107 DPRINT("Label: %s\n", yytext); 100 DPRINT("Label: %s\n", yytext);
108 yylval.labelref = strdup(yytext); 101 yylval.labelref = xstrdup(yytext);
109 yylval.labelref[yyleng-1] = '\0'; 102 yylval.labelref[yyleng-1] = '\0';
110 return DT_LABEL; 103 return DT_LABEL;
111 } 104 }
112 105
113<INITIAL>[bodh]# {
114 yylloc.file = srcpos_file;
115 yylloc.first_line = yylineno;
116 if (*yytext == 'b')
117 yylval.cbase = 2;
118 else if (*yytext == 'o')
119 yylval.cbase = 8;
120 else if (*yytext == 'd')
121 yylval.cbase = 10;
122 else
123 yylval.cbase = 16;
124 DPRINT("Base: %d\n", yylval.cbase);
125 return DT_BASE;
126 }
127
128<INITIAL>[0-9a-fA-F]+ {
129 yylloc.file = srcpos_file;
130 yylloc.first_line = yylineno;
131 yylval.literal = strdup(yytext);
132 DPRINT("Literal: '%s'\n", yylval.literal);
133 return DT_LEGACYLITERAL;
134 }
135
136<V1>[0-9]+|0[xX][0-9a-fA-F]+ { 106<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
137 yylloc.file = srcpos_file; 107 yylval.literal = xstrdup(yytext);
138 yylloc.first_line = yylineno;
139 yylval.literal = strdup(yytext);
140 DPRINT("Literal: '%s'\n", yylval.literal); 108 DPRINT("Literal: '%s'\n", yylval.literal);
141 return DT_LITERAL; 109 return DT_LITERAL;
142 } 110 }
143 111
144\&{LABEL} { /* label reference */ 112<*>\&{LABEL} { /* label reference */
145 yylloc.file = srcpos_file;
146 yylloc.first_line = yylineno;
147 DPRINT("Ref: %s\n", yytext+1); 113 DPRINT("Ref: %s\n", yytext+1);
148 yylval.labelref = strdup(yytext+1); 114 yylval.labelref = xstrdup(yytext+1);
149 return DT_REF; 115 return DT_REF;
150 } 116 }
151 117
152"&{/"{PATHCHAR}+\} { /* new-style path reference */ 118<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */
153 yylloc.file = srcpos_file;
154 yylloc.first_line = yylineno;
155 yytext[yyleng-1] = '\0'; 119 yytext[yyleng-1] = '\0';
156 DPRINT("Ref: %s\n", yytext+2); 120 DPRINT("Ref: %s\n", yytext+2);
157 yylval.labelref = strdup(yytext+2); 121 yylval.labelref = xstrdup(yytext+2);
158 return DT_REF;
159 }
160
161<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
162 yylloc.file = srcpos_file;
163 yylloc.first_line = yylineno;
164 DPRINT("Ref: %s\n", yytext+1);
165 yylval.labelref = strdup(yytext+1);
166 return DT_REF; 122 return DT_REF;
167 } 123 }
168 124
169<BYTESTRING>[0-9a-fA-F]{2} { 125<BYTESTRING>[0-9a-fA-F]{2} {
170 yylloc.file = srcpos_file;
171 yylloc.first_line = yylineno;
172 yylval.byte = strtol(yytext, NULL, 16); 126 yylval.byte = strtol(yytext, NULL, 16);
173 DPRINT("Byte: %02x\n", (int)yylval.byte); 127 DPRINT("Byte: %02x\n", (int)yylval.byte);
174 return DT_BYTE; 128 return DT_BYTE;
175 } 129 }
176 130
177<BYTESTRING>"]" { 131<BYTESTRING>"]" {
178 yylloc.file = srcpos_file;
179 yylloc.first_line = yylineno;
180 DPRINT("/BYTESTRING\n"); 132 DPRINT("/BYTESTRING\n");
181 BEGIN_DEFAULT(); 133 BEGIN_DEFAULT();
182 return ']'; 134 return ']';
183 } 135 }
184 136
185<PROPNODENAME>{PROPNODECHAR}+ { 137<PROPNODENAME>{PROPNODECHAR}+ {
186 yylloc.file = srcpos_file;
187 yylloc.first_line = yylineno;
188 DPRINT("PropNodeName: %s\n", yytext); 138 DPRINT("PropNodeName: %s\n", yytext);
189 yylval.propnodename = strdup(yytext); 139 yylval.propnodename = xstrdup(yytext);
190 BEGIN_DEFAULT(); 140 BEGIN_DEFAULT();
191 return DT_PROPNODENAME; 141 return DT_PROPNODENAME;
192 } 142 }
193 143
194"/incbin/" { 144"/incbin/" {
195 yylloc.file = srcpos_file;
196 yylloc.first_line = yylineno;
197 DPRINT("Binary Include\n"); 145 DPRINT("Binary Include\n");
198 return DT_INCBIN; 146 return DT_INCBIN;
199 } 147 }
@@ -203,8 +151,6 @@ static int pop_input_file(void);
203<*>{LINECOMMENT}+ /* eat C++-style comments */ 151<*>{LINECOMMENT}+ /* eat C++-style comments */
204 152
205<*>. { 153<*>. {
206 yylloc.file = srcpos_file;
207 yylloc.first_line = yylineno;
208 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 154 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
209 (unsigned)yytext[0]); 155 (unsigned)yytext[0]);
210 if (yytext[0] == '[') { 156 if (yytext[0] == '[') {
@@ -221,100 +167,25 @@ static int pop_input_file(void);
221 167
222%% 168%%
223 169
224
225/*
226 * Stack of nested include file contexts.
227 */
228
229struct incl_file {
230 struct dtc_file *file;
231 YY_BUFFER_STATE yy_prev_buf;
232 int yy_prev_lineno;
233 struct incl_file *prev;
234};
235
236static struct incl_file *incl_file_stack;
237
238
239/*
240 * Detect infinite include recursion.
241 */
242#define MAX_INCLUDE_DEPTH (100)
243
244static int incl_depth = 0;
245
246
247static void push_input_file(const char *filename) 170static void push_input_file(const char *filename)
248{ 171{
249 struct incl_file *incl_file;
250 struct dtc_file *newfile;
251 struct search_path search, *searchptr = NULL;
252
253 assert(filename); 172 assert(filename);
254 173
255 if (incl_depth++ >= MAX_INCLUDE_DEPTH) 174 srcfile_push(filename);
256 die("Includes nested too deeply");
257
258 if (srcpos_file) {
259 search.dir = srcpos_file->dir;
260 search.next = NULL;
261 search.prev = NULL;
262 searchptr = &search;
263 }
264
265 newfile = dtc_open_file(filename, searchptr);
266 175
267 incl_file = xmalloc(sizeof(struct incl_file)); 176 yyin = current_srcfile->f;
268 177
269 /* 178 yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
270 * Save current context.
271 */
272 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
273 incl_file->yy_prev_lineno = yylineno;
274 incl_file->file = srcpos_file;
275 incl_file->prev = incl_file_stack;
276
277 incl_file_stack = incl_file;
278
279 /*
280 * Establish new context.
281 */
282 srcpos_file = newfile;
283 yylineno = 1;
284 yyin = newfile->file;
285 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
286} 179}
287 180
288 181
289static int pop_input_file(void) 182static int pop_input_file(void)
290{ 183{
291 struct incl_file *incl_file; 184 if (srcfile_pop() == 0)
292
293 if (incl_file_stack == 0)
294 return 0; 185 return 0;
295 186
296 dtc_close_file(srcpos_file); 187 yypop_buffer_state();
297 188 yyin = current_srcfile->f;
298 /*
299 * Pop.
300 */
301 --incl_depth;
302 incl_file = incl_file_stack;
303 incl_file_stack = incl_file->prev;
304
305 /*
306 * Recover old context.
307 */
308 yy_delete_buffer(YY_CURRENT_BUFFER);
309 yy_switch_to_buffer(incl_file->yy_prev_buf);
310 yylineno = incl_file->yy_prev_lineno;
311 srcpos_file = incl_file->file;
312 yyin = incl_file->file ? incl_file->file->file : NULL;
313
314 /*
315 * Free old state.
316 */
317 free(incl_file);
318 189
319 return 1; 190 return 1;
320} 191}
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index ac392cb040f6..50c4420b4b2c 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -9,7 +9,7 @@
9#define FLEX_SCANNER 9#define FLEX_SCANNER
10#define YY_FLEX_MAJOR_VERSION 2 10#define YY_FLEX_MAJOR_VERSION 2
11#define YY_FLEX_MINOR_VERSION 5 11#define YY_FLEX_MINOR_VERSION 5
12#define YY_FLEX_SUBMINOR_VERSION 34 12#define YY_FLEX_SUBMINOR_VERSION 35
13#if YY_FLEX_SUBMINOR_VERSION > 0 13#if YY_FLEX_SUBMINOR_VERSION > 0
14#define FLEX_BETA 14#define FLEX_BETA
15#endif 15#endif
@@ -54,7 +54,6 @@ typedef int flex_int32_t;
54typedef unsigned char flex_uint8_t; 54typedef unsigned char flex_uint8_t;
55typedef unsigned short int flex_uint16_t; 55typedef unsigned short int flex_uint16_t;
56typedef unsigned int flex_uint32_t; 56typedef unsigned int flex_uint32_t;
57#endif /* ! C99 */
58 57
59/* Limits of integral types. */ 58/* Limits of integral types. */
60#ifndef INT8_MIN 59#ifndef INT8_MIN
@@ -85,6 +84,8 @@ typedef unsigned int flex_uint32_t;
85#define UINT32_MAX (4294967295U) 84#define UINT32_MAX (4294967295U)
86#endif 85#endif
87 86
87#endif /* ! C99 */
88
88#endif /* ! FLEXINT_H */ 89#endif /* ! FLEXINT_H */
89 90
90#ifdef __cplusplus 91#ifdef __cplusplus
@@ -141,7 +142,15 @@ typedef unsigned int flex_uint32_t;
141 142
142/* Size of default input buffer. */ 143/* Size of default input buffer. */
143#ifndef YY_BUF_SIZE 144#ifndef YY_BUF_SIZE
145#ifdef __ia64__
146/* On IA-64, the buffer size is 16k, not 8k.
147 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
148 * Ditto for the __ia64__ case accordingly.
149 */
150#define YY_BUF_SIZE 32768
151#else
144#define YY_BUF_SIZE 16384 152#define YY_BUF_SIZE 16384
153#endif /* __ia64__ */
145#endif 154#endif
146 155
147/* The state buf must be large enough to hold one state per character in the main buffer. 156/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -161,20 +170,7 @@ extern FILE *yyin, *yyout;
161#define EOB_ACT_END_OF_FILE 1 170#define EOB_ACT_END_OF_FILE 1
162#define EOB_ACT_LAST_MATCH 2 171#define EOB_ACT_LAST_MATCH 2
163 172
164 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires 173 #define YY_LESS_LINENO(n)
165 * access to the local variable yy_act. Since yyless() is a macro, it would break
166 * existing scanners that call yyless() from OUTSIDE yylex.
167 * One obvious solution it to make yy_act a global. I tried that, and saw
168 * a 5% performance hit in a non-yylineno scanner, because yy_act is
169 * normally declared as a register variable-- so it is not worth it.
170 */
171 #define YY_LESS_LINENO(n) \
172 do { \
173 int yyl;\
174 for ( yyl = n; yyl < yyleng; ++yyl )\
175 if ( yytext[yyl] == '\n' )\
176 --yylineno;\
177 }while(0)
178 174
179/* Return all but the first "n" matched characters back to the input stream. */ 175/* Return all but the first "n" matched characters back to the input stream. */
180#define yyless(n) \ 176#define yyless(n) \
@@ -192,13 +188,6 @@ extern FILE *yyin, *yyout;
192 188
193#define unput(c) yyunput( c, (yytext_ptr) ) 189#define unput(c) yyunput( c, (yytext_ptr) )
194 190
195/* The following is because we cannot portably get our hands on size_t
196 * (without autoconf's help, which isn't available because we want
197 * flex-generated scanners to compile on their own).
198 * Given that the standard has decreed that size_t exists since 1989,
199 * I guess we can afford to depend on it. Manoj.
200 */
201
202#ifndef YY_TYPEDEF_YY_SIZE_T 191#ifndef YY_TYPEDEF_YY_SIZE_T
203#define YY_TYPEDEF_YY_SIZE_T 192#define YY_TYPEDEF_YY_SIZE_T
204typedef size_t yy_size_t; 193typedef size_t yy_size_t;
@@ -383,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] );
383 *yy_cp = '\0'; \ 372 *yy_cp = '\0'; \
384 (yy_c_buf_p) = yy_cp; 373 (yy_c_buf_p) = yy_cp;
385 374
386#define YY_NUM_RULES 20 375#define YY_NUM_RULES 17
387#define YY_END_OF_BUFFER 21 376#define YY_END_OF_BUFFER 18
388/* This struct is not used in this scanner, 377/* This struct is not used in this scanner,
389 but its presence is necessary. */ 378 but its presence is necessary. */
390struct yy_trans_info 379struct yy_trans_info
@@ -392,20 +381,19 @@ struct yy_trans_info
392 flex_int32_t yy_verify; 381 flex_int32_t yy_verify;
393 flex_int32_t yy_nxt; 382 flex_int32_t yy_nxt;
394 }; 383 };
395static yyconst flex_int16_t yy_accept[104] = 384static yyconst flex_int16_t yy_accept[94] =
396 { 0, 385 { 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 21, 19, 16, 16, 19, 19, 19, 7, 7, 19, 387 18, 16, 13, 13, 16, 16, 16, 16, 16, 16,
399 7, 19, 19, 19, 19, 13, 14, 14, 19, 8, 388 16, 10, 11, 11, 6, 6, 13, 0, 2, 0,
400 8, 16, 0, 2, 0, 0, 9, 0, 0, 0, 389 7, 0, 0, 0, 0, 0, 0, 0, 5, 0,
401 0, 0, 0, 7, 7, 5, 0, 6, 0, 12, 390 9, 9, 11, 11, 6, 0, 7, 0, 0, 0,
402 12, 14, 14, 8, 0, 11, 9, 0, 0, 0, 391 0, 15, 0, 0, 0, 0, 6, 0, 14, 0,
403 0, 18, 0, 0, 0, 0, 8, 0, 17, 0, 392 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,
404 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 393 0, 0, 0, 0, 0, 0, 0, 0, 3, 12,
405 0, 0, 0, 0, 0, 0, 0, 0, 3, 15,
406 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 394 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
407
408 0, 4, 0 395 0, 4, 0
396
409 } ; 397 } ;
410 398
411static yyconst flex_int32_t yy_ec[256] = 399static yyconst flex_int32_t yy_ec[256] =
@@ -414,16 +402,16 @@ static yyconst flex_int32_t yy_ec[256] =
414 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 402 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
415 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 403 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
416 1, 2, 1, 4, 5, 1, 1, 6, 1, 1, 404 1, 2, 1, 4, 5, 1, 1, 6, 1, 1,
417 1, 7, 8, 8, 9, 8, 10, 11, 12, 13, 405 1, 7, 5, 5, 8, 5, 9, 10, 11, 12,
418 13, 13, 13, 13, 13, 13, 13, 14, 1, 1, 406 12, 12, 12, 12, 12, 12, 12, 13, 1, 1,
419 1, 1, 8, 8, 15, 15, 15, 15, 15, 15, 407 1, 1, 5, 5, 14, 14, 14, 14, 14, 14,
420 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 408 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
421 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 409 15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
422 1, 18, 19, 1, 16, 1, 15, 20, 21, 22, 410 1, 17, 18, 1, 15, 1, 14, 19, 20, 21,
423 411
424 23, 15, 16, 24, 25, 16, 16, 26, 27, 28, 412 22, 14, 15, 15, 23, 15, 15, 24, 25, 26,
425 24, 16, 16, 29, 30, 31, 32, 33, 16, 17, 413 15, 15, 15, 27, 28, 29, 30, 31, 15, 16,
426 16, 16, 34, 1, 35, 1, 1, 1, 1, 1, 414 15, 15, 32, 1, 33, 1, 1, 1, 1, 1,
427 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 415 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
428 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 416 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
429 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 417 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -440,136 +428,114 @@ static yyconst flex_int32_t yy_ec[256] =
440 1, 1, 1, 1, 1 428 1, 1, 1, 1, 1
441 } ; 429 } ;
442 430
443static yyconst flex_int32_t yy_meta[36] = 431static yyconst flex_int32_t yy_meta[34] =
444 { 0, 432 { 0,
445 1, 1, 1, 1, 2, 1, 2, 2, 2, 3, 433 1, 1, 1, 1, 2, 1, 2, 2, 3, 4,
446 4, 4, 4, 5, 6, 7, 7, 1, 1, 6, 434 4, 4, 5, 6, 7, 7, 1, 1, 6, 6,
447 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 435 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
448 7, 7, 7, 8, 1 436 7, 8, 1
449 } ; 437 } ;
450 438
451static yyconst flex_int16_t yy_base[117] = 439static yyconst flex_int16_t yy_base[106] =
452 { 0, 440 { 0,
453 0, 0, 30, 0, 44, 0, 67, 0, 97, 105, 441 0, 0, 237, 236, 25, 0, 47, 0, 30, 71,
454 302, 303, 35, 44, 40, 94, 112, 0, 129, 152, 442 244, 247, 82, 84, 84, 211, 95, 229, 218, 0,
455 296, 295, 159, 0, 176, 303, 0, 116, 95, 165, 443 111, 247, 0, 84, 83, 95, 106, 86, 247, 237,
456 49, 46, 102, 303, 296, 0, 0, 288, 290, 293, 444 0, 230, 231, 234, 207, 209, 212, 220, 247, 206,
457 264, 266, 270, 0, 0, 303, 0, 303, 264, 303, 445 247, 218, 0, 106, 116, 0, 0, 0, 223, 89,
458 0, 0, 195, 101, 0, 0, 0, 0, 284, 125, 446 226, 219, 199, 206, 200, 204, 0, 190, 213, 212,
459 277, 265, 225, 230, 216, 218, 0, 202, 224, 221, 447 202, 91, 178, 161, 247, 172, 144, 150, 140, 130,
460 217, 107, 196, 188, 303, 206, 179, 186, 178, 185, 448 140, 124, 128, 120, 138, 137, 123, 122, 247, 247,
461 183, 162, 161, 150, 169, 160, 145, 125, 303, 303, 449 134, 114, 132, 86, 135, 125, 90, 136, 247, 97,
462 137, 109, 190, 103, 203, 167, 108, 197, 303, 123, 450 29, 247, 247, 153, 156, 161, 165, 170, 176, 180,
463 451
464 29, 303, 303, 215, 221, 226, 229, 234, 240, 246, 452 187, 195, 200, 205, 212
465 250, 257, 265, 270, 275, 282
466 } ; 453 } ;
467 454
468static yyconst flex_int16_t yy_def[117] = 455static yyconst flex_int16_t yy_def[106] =
469 { 0, 456 { 0,
470 103, 1, 1, 3, 3, 5, 103, 7, 3, 3, 457 93, 1, 1, 1, 1, 5, 93, 7, 1, 1,
471 103, 103, 103, 103, 104, 105, 103, 106, 103, 19, 458 93, 93, 93, 93, 94, 95, 93, 96, 17, 97,
472 19, 20, 103, 107, 20, 103, 108, 109, 105, 103, 459 96, 93, 98, 99, 93, 93, 93, 94, 93, 94,
473 103, 103, 104, 103, 104, 110, 111, 103, 112, 113, 460 100, 93, 101, 102, 93, 93, 93, 96, 93, 93,
474 103, 103, 103, 106, 19, 103, 20, 103, 103, 103, 461 93, 96, 98, 99, 93, 103, 100, 104, 101, 101,
475 20, 108, 109, 103, 114, 110, 111, 115, 112, 112, 462 102, 93, 93, 93, 93, 93, 103, 104, 93, 93,
476 113, 103, 103, 103, 103, 103, 114, 115, 103, 103, 463 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
477 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 464 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
478 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 465 93, 93, 93, 93, 93, 105, 93, 105, 93, 105,
479 103, 103, 103, 103, 103, 116, 103, 116, 103, 116, 466 93, 93, 0, 93, 93, 93, 93, 93, 93, 93,
480 467
481 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, 468 93, 93, 93, 93, 93
482 103, 103, 103, 103, 103, 103
483 } ; 469 } ;
484 470
485static yyconst flex_int16_t yy_nxt[339] = 471static yyconst flex_int16_t yy_nxt[281] =
486 { 0, 472 { 0,
487 12, 13, 14, 15, 12, 16, 12, 12, 12, 17, 473 12, 13, 14, 15, 12, 16, 12, 12, 17, 12,
488 18, 18, 18, 12, 19, 20, 20, 12, 12, 21, 474 12, 12, 12, 18, 18, 18, 12, 12, 18, 18,
489 19, 21, 19, 22, 20, 20, 20, 20, 20, 20, 475 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
490 20, 20, 20, 12, 12, 12, 32, 32, 102, 23, 476 18, 12, 12, 19, 20, 20, 20, 92, 21, 25,
491 12, 12, 12, 34, 20, 32, 32, 32, 32, 20, 477 26, 26, 22, 21, 21, 21, 21, 12, 13, 14,
492 20, 20, 20, 20, 24, 24, 24, 35, 25, 54, 478 15, 23, 16, 23, 23, 19, 23, 23, 23, 12,
493 54, 54, 26, 25, 25, 25, 25, 12, 13, 14, 479 24, 24, 24, 12, 12, 24, 24, 24, 24, 24,
494 15, 27, 12, 27, 27, 27, 23, 27, 27, 27, 480 24, 24, 24, 24, 24, 24, 24, 24, 12, 12,
495 12, 28, 28, 28, 12, 12, 28, 28, 28, 28, 481 25, 26, 26, 27, 27, 27, 27, 29, 43, 29,
496 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 482 43, 43, 45, 45, 45, 50, 39, 59, 46, 93,
497 483
498 12, 12, 29, 36, 103, 34, 17, 30, 31, 31, 484 30, 33, 30, 34, 45, 45, 45, 27, 27, 68,
499 29, 54, 54, 54, 17, 30, 31, 31, 39, 35, 485 43, 91, 43, 43, 69, 35, 87, 36, 39, 37,
500 52, 40, 52, 52, 52, 103, 78, 38, 38, 46, 486 42, 42, 42, 39, 42, 45, 45, 45, 89, 42,
501 101, 60, 79, 41, 69, 97, 42, 94, 43, 45, 487 42, 42, 42, 85, 85, 86, 85, 85, 86, 89,
502 45, 45, 46, 45, 47, 47, 93, 92, 45, 45, 488 84, 90, 83, 82, 81, 80, 79, 78, 77, 76,
503 45, 45, 47, 47, 47, 47, 47, 47, 47, 47, 489 75, 74, 90, 28, 28, 28, 28, 28, 28, 28,
504 47, 47, 47, 47, 47, 39, 47, 91, 40, 90, 490 28, 31, 31, 31, 38, 38, 38, 38, 41, 73,
505 99, 47, 47, 47, 47, 54, 54, 54, 89, 88, 491 41, 43, 72, 43, 71, 43, 43, 44, 33, 44,
506 41, 55, 87, 49, 100, 43, 51, 51, 51, 86, 492 44, 44, 44, 47, 69, 47, 47, 49, 49, 49,
507 51, 95, 95, 96, 85, 51, 51, 51, 51, 52, 493 49, 49, 49, 49, 49, 51, 51, 51, 51, 51,
508 494
509 99, 52, 52, 52, 95, 95, 96, 84, 46, 83, 495 51, 51, 51, 57, 70, 57, 58, 58, 58, 67,
510 82, 81, 39, 79, 100, 33, 33, 33, 33, 33, 496 58, 58, 88, 88, 88, 88, 88, 88, 88, 88,
511 33, 33, 33, 37, 80, 77, 37, 37, 37, 44, 497 34, 66, 65, 64, 63, 62, 61, 60, 52, 50,
512 40, 44, 50, 76, 50, 52, 75, 52, 74, 52, 498 39, 56, 39, 55, 54, 53, 52, 50, 48, 93,
513 52, 53, 73, 53, 53, 53, 53, 56, 56, 56, 499 40, 39, 32, 93, 19, 19, 11, 93, 93, 93,
514 72, 56, 56, 57, 71, 57, 57, 59, 59, 59, 500 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
515 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, 501 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
516 61, 61, 61, 67, 70, 67, 68, 68, 68, 62, 502 93, 93, 93, 93, 93, 93, 93, 93, 93, 93
517 68, 68, 98, 98, 98, 98, 98, 98, 98, 98,
518 60, 66, 65, 64, 63, 62, 60, 58, 103, 48,
519
520 48, 103, 11, 103, 103, 103, 103, 103, 103, 103,
521 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
522 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
523 103, 103, 103, 103, 103, 103, 103, 103
524 } ; 503 } ;
525 504
526static yyconst flex_int16_t yy_chk[339] = 505static yyconst flex_int16_t yy_chk[281] =
527 { 0, 506 { 0,
528 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 507 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
529 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 508 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
530 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 509 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
531 1, 1, 1, 1, 1, 3, 13, 13, 101, 3, 510 1, 1, 1, 5, 5, 5, 5, 91, 5, 9,
532 3, 3, 3, 15, 3, 14, 14, 32, 32, 3, 511 9, 9, 5, 5, 5, 5, 5, 7, 7, 7,
533 3, 3, 3, 3, 5, 5, 5, 15, 5, 31,
534 31, 31, 5, 5, 5, 5, 5, 7, 7, 7,
535 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 512 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
536 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 513 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
537 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 514 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
538 515 10, 10, 10, 13, 13, 14, 14, 15, 24, 28,
539 7, 7, 9, 16, 29, 33, 9, 9, 9, 9, 516 24, 24, 25, 25, 25, 50, 24, 50, 25, 90,
540 10, 54, 54, 54, 10, 10, 10, 10, 17, 33, 517
541 28, 17, 28, 28, 28, 100, 72, 16, 29, 28, 518 15, 17, 28, 17, 26, 26, 26, 27, 27, 62,
542 97, 60, 72, 17, 60, 94, 17, 92, 17, 19, 519 44, 87, 44, 44, 62, 17, 84, 17, 44, 17,
543 19, 19, 19, 19, 19, 19, 91, 88, 19, 19, 520 21, 21, 21, 21, 21, 45, 45, 45, 86, 21,
544 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 521 21, 21, 21, 83, 83, 83, 85, 85, 85, 88,
545 19, 19, 20, 20, 20, 23, 20, 87, 23, 86, 522 82, 86, 81, 78, 77, 76, 75, 74, 73, 72,
546 96, 20, 20, 20, 20, 30, 30, 30, 85, 84, 523 71, 70, 88, 94, 94, 94, 94, 94, 94, 94,
547 23, 30, 83, 23, 96, 23, 25, 25, 25, 82, 524 94, 95, 95, 95, 96, 96, 96, 96, 97, 69,
548 25, 93, 93, 93, 81, 25, 25, 25, 25, 53, 525 97, 98, 68, 98, 67, 98, 98, 99, 66, 99,
549 526 99, 99, 99, 100, 64, 100, 100, 101, 101, 101,
550 98, 53, 53, 53, 95, 95, 95, 80, 53, 79, 527 101, 101, 101, 101, 101, 102, 102, 102, 102, 102,
551 78, 77, 76, 74, 98, 104, 104, 104, 104, 104, 528
552 104, 104, 104, 105, 73, 71, 105, 105, 105, 106, 529 102, 102, 102, 103, 63, 103, 104, 104, 104, 61,
553 70, 106, 107, 69, 107, 108, 68, 108, 66, 108, 530 104, 104, 105, 105, 105, 105, 105, 105, 105, 105,
554 108, 109, 65, 109, 109, 109, 109, 110, 110, 110, 531 60, 59, 58, 56, 55, 54, 53, 52, 51, 49,
555 64, 110, 110, 111, 63, 111, 111, 112, 112, 112, 532 42, 40, 38, 37, 36, 35, 34, 33, 32, 30,
556 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 533 19, 18, 16, 11, 4, 3, 93, 93, 93, 93,
557 113, 113, 113, 114, 62, 114, 115, 115, 115, 61, 534 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
558 115, 115, 116, 116, 116, 116, 116, 116, 116, 116, 535 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
559 59, 49, 43, 42, 41, 40, 39, 38, 35, 22, 536 93, 93, 93, 93, 93, 93, 93, 93, 93, 93
560
561 21, 11, 103, 103, 103, 103, 103, 103, 103, 103,
562 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
563 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
564 103, 103, 103, 103, 103, 103, 103, 103
565 } ; 537 } ;
566 538
567/* Table of booleans, true if rule could match eol. */
568static yyconst flex_int32_t yy_rule_can_match_eol[21] =
569 { 0,
5701, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
571 0, };
572
573static yy_state_type yy_last_accepting_state; 539static yy_state_type yy_last_accepting_state;
574static char *yy_last_accepting_cpos; 540static char *yy_last_accepting_cpos;
575 541
@@ -604,6 +570,7 @@ char *yytext;
604 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 570 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
605 * USA 571 * USA
606 */ 572 */
573#define YY_NO_INPUT 1
607 574
608 575
609 576
@@ -613,6 +580,13 @@ char *yytext;
613#include "srcpos.h" 580#include "srcpos.h"
614#include "dtc-parser.tab.h" 581#include "dtc-parser.tab.h"
615 582
583YYLTYPE yylloc;
584
585/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
586#define YY_USER_ACTION \
587 { \
588 srcpos_update(&yylloc, yytext, yyleng); \
589 }
616 590
617/*#define LEXDEBUG 1*/ 591/*#define LEXDEBUG 1*/
618 592
@@ -622,19 +596,14 @@ char *yytext;
622#define DPRINT(fmt, ...) do { } while (0) 596#define DPRINT(fmt, ...) do { } while (0)
623#endif 597#endif
624 598
625static int dts_version; /* = 0 */ 599static int dts_version = 1;
626 600
627#define BEGIN_DEFAULT() if (dts_version == 0) { \ 601#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
628 DPRINT("<INITIAL>\n"); \
629 BEGIN(INITIAL); \
630 } else { \
631 DPRINT("<V1>\n"); \
632 BEGIN(V1); \ 602 BEGIN(V1); \
633 }
634 603
635static void push_input_file(const char *filename); 604static void push_input_file(const char *filename);
636static int pop_input_file(void); 605static int pop_input_file(void);
637#line 638 "dtc-lexer.lex.c" 606#line 607 "dtc-lexer.lex.c"
638 607
639#define INITIAL 0 608#define INITIAL 0
640#define INCLUDE 1 609#define INCLUDE 1
@@ -656,6 +625,35 @@ static int pop_input_file(void);
656 625
657static int yy_init_globals (void ); 626static int yy_init_globals (void );
658 627
628/* Accessor methods to globals.
629 These are made visible to non-reentrant scanners for convenience. */
630
631int yylex_destroy (void );
632
633int yyget_debug (void );
634
635void yyset_debug (int debug_flag );
636
637YY_EXTRA_TYPE yyget_extra (void );
638
639void yyset_extra (YY_EXTRA_TYPE user_defined );
640
641FILE *yyget_in (void );
642
643void yyset_in (FILE * in_str );
644
645FILE *yyget_out (void );
646
647void yyset_out (FILE * out_str );
648
649int yyget_leng (void );
650
651char *yyget_text (void );
652
653int yyget_lineno (void );
654
655void yyset_lineno (int line_number );
656
659/* Macros after this point can all be overridden by user definitions in 657/* Macros after this point can all be overridden by user definitions in
660 * section 1. 658 * section 1.
661 */ 659 */
@@ -688,7 +686,12 @@ static int input (void );
688 686
689/* Amount of stuff to slurp up with each read. */ 687/* Amount of stuff to slurp up with each read. */
690#ifndef YY_READ_BUF_SIZE 688#ifndef YY_READ_BUF_SIZE
689#ifdef __ia64__
690/* On IA-64, the buffer size is 16k, not 8k */
691#define YY_READ_BUF_SIZE 16384
692#else
691#define YY_READ_BUF_SIZE 8192 693#define YY_READ_BUF_SIZE 8192
694#endif /* __ia64__ */
692#endif 695#endif
693 696
694/* Copy whatever the last rule matched to the standard output. */ 697/* Copy whatever the last rule matched to the standard output. */
@@ -696,7 +699,7 @@ static int input (void );
696/* This used to be an fputs(), but since the string might contain NUL's, 699/* This used to be an fputs(), but since the string might contain NUL's,
697 * we now use fwrite(). 700 * we now use fwrite().
698 */ 701 */
699#define ECHO fwrite( yytext, yyleng, 1, yyout ) 702#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
700#endif 703#endif
701 704
702/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 705/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -707,7 +710,7 @@ static int input (void );
707 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ 710 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
708 { \ 711 { \
709 int c = '*'; \ 712 int c = '*'; \
710 int n; \ 713 size_t n; \
711 for ( n = 0; n < max_size && \ 714 for ( n = 0; n < max_size && \
712 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 715 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
713 buf[n] = (char) c; \ 716 buf[n] = (char) c; \
@@ -789,9 +792,9 @@ YY_DECL
789 register char *yy_cp, *yy_bp; 792 register char *yy_cp, *yy_bp;
790 register int yy_act; 793 register int yy_act;
791 794
792#line 64 "dtc-lexer.l" 795#line 66 "dtc-lexer.l"
793 796
794#line 795 "dtc-lexer.lex.c" 797#line 798 "dtc-lexer.lex.c"
795 798
796 if ( !(yy_init) ) 799 if ( !(yy_init) )
797 { 800 {
@@ -844,35 +847,21 @@ yy_match:
844 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 847 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
845 { 848 {
846 yy_current_state = (int) yy_def[yy_current_state]; 849 yy_current_state = (int) yy_def[yy_current_state];
847 if ( yy_current_state >= 104 ) 850 if ( yy_current_state >= 94 )
848 yy_c = yy_meta[(unsigned int) yy_c]; 851 yy_c = yy_meta[(unsigned int) yy_c];
849 } 852 }
850 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 853 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
851 ++yy_cp; 854 ++yy_cp;
852 } 855 }
853 while ( yy_base[yy_current_state] != 303 ); 856 while ( yy_current_state != 93 );
857 yy_cp = (yy_last_accepting_cpos);
858 yy_current_state = (yy_last_accepting_state);
854 859
855yy_find_action: 860yy_find_action:
856 yy_act = yy_accept[yy_current_state]; 861 yy_act = yy_accept[yy_current_state];
857 if ( yy_act == 0 )
858 { /* have to back up */
859 yy_cp = (yy_last_accepting_cpos);
860 yy_current_state = (yy_last_accepting_state);
861 yy_act = yy_accept[yy_current_state];
862 }
863 862
864 YY_DO_BEFORE_ACTION; 863 YY_DO_BEFORE_ACTION;
865 864
866 if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
867 {
868 int yyl;
869 for ( yyl = 0; yyl < yyleng; ++yyl )
870 if ( yytext[yyl] == '\n' )
871
872 yylineno++;
873;
874 }
875
876do_action: /* This label is used only to access EOF actions. */ 865do_action: /* This label is used only to access EOF actions. */
877 866
878 switch ( yy_act ) 867 switch ( yy_act )
@@ -887,7 +876,7 @@ do_action: /* This label is used only to access EOF actions. */
887case 1: 876case 1:
888/* rule 1 can match eol */ 877/* rule 1 can match eol */
889YY_RULE_SETUP 878YY_RULE_SETUP
890#line 65 "dtc-lexer.l" 879#line 67 "dtc-lexer.l"
891{ 880{
892 char *name = strchr(yytext, '\"') + 1; 881 char *name = strchr(yytext, '\"') + 1;
893 yytext[yyleng-1] = '\0'; 882 yytext[yyleng-1] = '\0';
@@ -899,7 +888,7 @@ case YY_STATE_EOF(INCLUDE):
899case YY_STATE_EOF(BYTESTRING): 888case YY_STATE_EOF(BYTESTRING):
900case YY_STATE_EOF(PROPNODENAME): 889case YY_STATE_EOF(PROPNODENAME):
901case YY_STATE_EOF(V1): 890case YY_STATE_EOF(V1):
902#line 71 "dtc-lexer.l" 891#line 73 "dtc-lexer.l"
903{ 892{
904 if (!pop_input_file()) { 893 if (!pop_input_file()) {
905 yyterminate(); 894 yyterminate();
@@ -909,23 +898,18 @@ case YY_STATE_EOF(V1):
909case 2: 898case 2:
910/* rule 2 can match eol */ 899/* rule 2 can match eol */
911YY_RULE_SETUP 900YY_RULE_SETUP
912#line 77 "dtc-lexer.l" 901#line 79 "dtc-lexer.l"
913{ 902{
914 yylloc.file = srcpos_file;
915 yylloc.first_line = yylineno;
916 DPRINT("String: %s\n", yytext); 903 DPRINT("String: %s\n", yytext);
917 yylval.data = data_copy_escape_string(yytext+1, 904 yylval.data = data_copy_escape_string(yytext+1,
918 yyleng-2); 905 yyleng-2);
919 yylloc.first_line = yylineno;
920 return DT_STRING; 906 return DT_STRING;
921 } 907 }
922 YY_BREAK 908 YY_BREAK
923case 3: 909case 3:
924YY_RULE_SETUP 910YY_RULE_SETUP
925#line 87 "dtc-lexer.l" 911#line 86 "dtc-lexer.l"
926{ 912{
927 yylloc.file = srcpos_file;
928 yylloc.first_line = yylineno;
929 DPRINT("Keyword: /dts-v1/\n"); 913 DPRINT("Keyword: /dts-v1/\n");
930 dts_version = 1; 914 dts_version = 1;
931 BEGIN_DEFAULT(); 915 BEGIN_DEFAULT();
@@ -934,10 +918,8 @@ YY_RULE_SETUP
934 YY_BREAK 918 YY_BREAK
935case 4: 919case 4:
936YY_RULE_SETUP 920YY_RULE_SETUP
937#line 96 "dtc-lexer.l" 921#line 93 "dtc-lexer.l"
938{ 922{
939 yylloc.file = srcpos_file;
940 yylloc.first_line = yylineno;
941 DPRINT("Keyword: /memreserve/\n"); 923 DPRINT("Keyword: /memreserve/\n");
942 BEGIN_DEFAULT(); 924 BEGIN_DEFAULT();
943 return DT_MEMRESERVE; 925 return DT_MEMRESERVE;
@@ -945,158 +927,100 @@ YY_RULE_SETUP
945 YY_BREAK 927 YY_BREAK
946case 5: 928case 5:
947YY_RULE_SETUP 929YY_RULE_SETUP
948#line 104 "dtc-lexer.l" 930#line 99 "dtc-lexer.l"
949{ 931{
950 yylloc.file = srcpos_file;
951 yylloc.first_line = yylineno;
952 DPRINT("Label: %s\n", yytext); 932 DPRINT("Label: %s\n", yytext);
953 yylval.labelref = strdup(yytext); 933 yylval.labelref = xstrdup(yytext);
954 yylval.labelref[yyleng-1] = '\0'; 934 yylval.labelref[yyleng-1] = '\0';
955 return DT_LABEL; 935 return DT_LABEL;
956 } 936 }
957 YY_BREAK 937 YY_BREAK
958case 6: 938case 6:
959YY_RULE_SETUP 939YY_RULE_SETUP
960#line 113 "dtc-lexer.l" 940#line 106 "dtc-lexer.l"
961{ 941{
962 yylloc.file = srcpos_file; 942 yylval.literal = xstrdup(yytext);
963 yylloc.first_line = yylineno;
964 if (*yytext == 'b')
965 yylval.cbase = 2;
966 else if (*yytext == 'o')
967 yylval.cbase = 8;
968 else if (*yytext == 'd')
969 yylval.cbase = 10;
970 else
971 yylval.cbase = 16;
972 DPRINT("Base: %d\n", yylval.cbase);
973 return DT_BASE;
974 }
975 YY_BREAK
976case 7:
977YY_RULE_SETUP
978#line 128 "dtc-lexer.l"
979{
980 yylloc.file = srcpos_file;
981 yylloc.first_line = yylineno;
982 yylval.literal = strdup(yytext);
983 DPRINT("Literal: '%s'\n", yylval.literal);
984 return DT_LEGACYLITERAL;
985 }
986 YY_BREAK
987case 8:
988YY_RULE_SETUP
989#line 136 "dtc-lexer.l"
990{
991 yylloc.file = srcpos_file;
992 yylloc.first_line = yylineno;
993 yylval.literal = strdup(yytext);
994 DPRINT("Literal: '%s'\n", yylval.literal); 943 DPRINT("Literal: '%s'\n", yylval.literal);
995 return DT_LITERAL; 944 return DT_LITERAL;
996 } 945 }
997 YY_BREAK 946 YY_BREAK
998case 9: 947case 7:
999YY_RULE_SETUP 948YY_RULE_SETUP
1000#line 144 "dtc-lexer.l" 949#line 112 "dtc-lexer.l"
1001{ /* label reference */ 950{ /* label reference */
1002 yylloc.file = srcpos_file;
1003 yylloc.first_line = yylineno;
1004 DPRINT("Ref: %s\n", yytext+1); 951 DPRINT("Ref: %s\n", yytext+1);
1005 yylval.labelref = strdup(yytext+1); 952 yylval.labelref = xstrdup(yytext+1);
1006 return DT_REF; 953 return DT_REF;
1007 } 954 }
1008 YY_BREAK 955 YY_BREAK
1009case 10: 956case 8:
1010YY_RULE_SETUP 957YY_RULE_SETUP
1011#line 152 "dtc-lexer.l" 958#line 118 "dtc-lexer.l"
1012{ /* new-style path reference */ 959{ /* new-style path reference */
1013 yylloc.file = srcpos_file;
1014 yylloc.first_line = yylineno;
1015 yytext[yyleng-1] = '\0'; 960 yytext[yyleng-1] = '\0';
1016 DPRINT("Ref: %s\n", yytext+2); 961 DPRINT("Ref: %s\n", yytext+2);
1017 yylval.labelref = strdup(yytext+2); 962 yylval.labelref = xstrdup(yytext+2);
1018 return DT_REF;
1019 }
1020 YY_BREAK
1021case 11:
1022YY_RULE_SETUP
1023#line 161 "dtc-lexer.l"
1024{ /* old-style path reference */
1025 yylloc.file = srcpos_file;
1026 yylloc.first_line = yylineno;
1027 DPRINT("Ref: %s\n", yytext+1);
1028 yylval.labelref = strdup(yytext+1);
1029 return DT_REF; 963 return DT_REF;
1030 } 964 }
1031 YY_BREAK 965 YY_BREAK
1032case 12: 966case 9:
1033YY_RULE_SETUP 967YY_RULE_SETUP
1034#line 169 "dtc-lexer.l" 968#line 125 "dtc-lexer.l"
1035{ 969{
1036 yylloc.file = srcpos_file;
1037 yylloc.first_line = yylineno;
1038 yylval.byte = strtol(yytext, NULL, 16); 970 yylval.byte = strtol(yytext, NULL, 16);
1039 DPRINT("Byte: %02x\n", (int)yylval.byte); 971 DPRINT("Byte: %02x\n", (int)yylval.byte);
1040 return DT_BYTE; 972 return DT_BYTE;
1041 } 973 }
1042 YY_BREAK 974 YY_BREAK
1043case 13: 975case 10:
1044YY_RULE_SETUP 976YY_RULE_SETUP
1045#line 177 "dtc-lexer.l" 977#line 131 "dtc-lexer.l"
1046{ 978{
1047 yylloc.file = srcpos_file;
1048 yylloc.first_line = yylineno;
1049 DPRINT("/BYTESTRING\n"); 979 DPRINT("/BYTESTRING\n");
1050 BEGIN_DEFAULT(); 980 BEGIN_DEFAULT();
1051 return ']'; 981 return ']';
1052 } 982 }
1053 YY_BREAK 983 YY_BREAK
1054case 14: 984case 11:
1055YY_RULE_SETUP 985YY_RULE_SETUP
1056#line 185 "dtc-lexer.l" 986#line 137 "dtc-lexer.l"
1057{ 987{
1058 yylloc.file = srcpos_file;
1059 yylloc.first_line = yylineno;
1060 DPRINT("PropNodeName: %s\n", yytext); 988 DPRINT("PropNodeName: %s\n", yytext);
1061 yylval.propnodename = strdup(yytext); 989 yylval.propnodename = xstrdup(yytext);
1062 BEGIN_DEFAULT(); 990 BEGIN_DEFAULT();
1063 return DT_PROPNODENAME; 991 return DT_PROPNODENAME;
1064 } 992 }
1065 YY_BREAK 993 YY_BREAK
1066case 15: 994case 12:
1067YY_RULE_SETUP 995YY_RULE_SETUP
1068#line 194 "dtc-lexer.l" 996#line 144 "dtc-lexer.l"
1069{ 997{
1070 yylloc.file = srcpos_file;
1071 yylloc.first_line = yylineno;
1072 DPRINT("Binary Include\n"); 998 DPRINT("Binary Include\n");
1073 return DT_INCBIN; 999 return DT_INCBIN;
1074 } 1000 }
1075 YY_BREAK 1001 YY_BREAK
1076case 16: 1002case 13:
1077/* rule 16 can match eol */ 1003/* rule 13 can match eol */
1078YY_RULE_SETUP 1004YY_RULE_SETUP
1079#line 201 "dtc-lexer.l" 1005#line 149 "dtc-lexer.l"
1080/* eat whitespace */ 1006/* eat whitespace */
1081 YY_BREAK 1007 YY_BREAK
1082case 17: 1008case 14:
1083/* rule 17 can match eol */ 1009/* rule 14 can match eol */
1084YY_RULE_SETUP 1010YY_RULE_SETUP
1085#line 202 "dtc-lexer.l" 1011#line 150 "dtc-lexer.l"
1086/* eat C-style comments */ 1012/* eat C-style comments */
1087 YY_BREAK 1013 YY_BREAK
1088case 18: 1014case 15:
1089/* rule 18 can match eol */ 1015/* rule 15 can match eol */
1090YY_RULE_SETUP 1016YY_RULE_SETUP
1091#line 203 "dtc-lexer.l" 1017#line 151 "dtc-lexer.l"
1092/* eat C++-style comments */ 1018/* eat C++-style comments */
1093 YY_BREAK 1019 YY_BREAK
1094case 19: 1020case 16:
1095YY_RULE_SETUP 1021YY_RULE_SETUP
1096#line 205 "dtc-lexer.l" 1022#line 153 "dtc-lexer.l"
1097{ 1023{
1098 yylloc.file = srcpos_file;
1099 yylloc.first_line = yylineno;
1100 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 1024 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
1101 (unsigned)yytext[0]); 1025 (unsigned)yytext[0]);
1102 if (yytext[0] == '[') { 1026 if (yytext[0] == '[') {
@@ -1111,12 +1035,12 @@ YY_RULE_SETUP
1111 return yytext[0]; 1035 return yytext[0];
1112 } 1036 }
1113 YY_BREAK 1037 YY_BREAK
1114case 20: 1038case 17:
1115YY_RULE_SETUP 1039YY_RULE_SETUP
1116#line 222 "dtc-lexer.l" 1040#line 168 "dtc-lexer.l"
1117ECHO; 1041ECHO;
1118 YY_BREAK 1042 YY_BREAK
1119#line 1120 "dtc-lexer.lex.c" 1043#line 1044 "dtc-lexer.lex.c"
1120 1044
1121 case YY_END_OF_BUFFER: 1045 case YY_END_OF_BUFFER:
1122 { 1046 {
@@ -1181,7 +1105,8 @@ ECHO;
1181 1105
1182 else 1106 else
1183 { 1107 {
1184 yy_cp = (yy_c_buf_p); 1108 yy_cp = (yy_last_accepting_cpos);
1109 yy_current_state = (yy_last_accepting_state);
1185 goto yy_find_action; 1110 goto yy_find_action;
1186 } 1111 }
1187 } 1112 }
@@ -1406,7 +1331,7 @@ static int yy_get_next_buffer (void)
1406 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1331 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1407 { 1332 {
1408 yy_current_state = (int) yy_def[yy_current_state]; 1333 yy_current_state = (int) yy_def[yy_current_state];
1409 if ( yy_current_state >= 104 ) 1334 if ( yy_current_state >= 94 )
1410 yy_c = yy_meta[(unsigned int) yy_c]; 1335 yy_c = yy_meta[(unsigned int) yy_c];
1411 } 1336 }
1412 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1337 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1434,11 +1359,11 @@ static int yy_get_next_buffer (void)
1434 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1359 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1435 { 1360 {
1436 yy_current_state = (int) yy_def[yy_current_state]; 1361 yy_current_state = (int) yy_def[yy_current_state];
1437 if ( yy_current_state >= 104 ) 1362 if ( yy_current_state >= 94 )
1438 yy_c = yy_meta[(unsigned int) yy_c]; 1363 yy_c = yy_meta[(unsigned int) yy_c];
1439 } 1364 }
1440 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1365 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1441 yy_is_jam = (yy_current_state == 103); 1366 yy_is_jam = (yy_current_state == 93);
1442 1367
1443 return yy_is_jam ? 0 : yy_current_state; 1368 return yy_is_jam ? 0 : yy_current_state;
1444} 1369}
@@ -1513,11 +1438,6 @@ static int yy_get_next_buffer (void)
1513 *(yy_c_buf_p) = '\0'; /* preserve yytext */ 1438 *(yy_c_buf_p) = '\0'; /* preserve yytext */
1514 (yy_hold_char) = *++(yy_c_buf_p); 1439 (yy_hold_char) = *++(yy_c_buf_p);
1515 1440
1516 if ( c == '\n' )
1517
1518 yylineno++;
1519;
1520
1521 return c; 1441 return c;
1522} 1442}
1523#endif /* ifndef YY_NO_INPUT */ 1443#endif /* ifndef YY_NO_INPUT */
@@ -1632,10 +1552,6 @@ static void yy_load_buffer_state (void)
1632 yyfree((void *) b ); 1552 yyfree((void *) b );
1633} 1553}
1634 1554
1635#ifndef __cplusplus
1636extern int isatty (int );
1637#endif /* __cplusplus */
1638
1639/* Initializes or reinitializes a buffer. 1555/* Initializes or reinitializes a buffer.
1640 * This function is sometimes called more than once on the same buffer, 1556 * This function is sometimes called more than once on the same buffer,
1641 * such as during a yyrestart() or at EOF. 1557 * such as during a yyrestart() or at EOF.
@@ -1659,7 +1575,7 @@ extern int isatty (int );
1659 b->yy_bs_column = 0; 1575 b->yy_bs_column = 0;
1660 } 1576 }
1661 1577
1662 b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; 1578 b->yy_is_interactive = 0;
1663 1579
1664 errno = oerrno; 1580 errno = oerrno;
1665} 1581}
@@ -1840,8 +1756,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1840 1756
1841/** Setup the input buffer state to scan the given bytes. The next call to yylex() will 1757/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1842 * scan from a @e copy of @a bytes. 1758 * scan from a @e copy of @a bytes.
1843 * @param bytes the byte buffer to scan 1759 * @param yybytes the byte buffer to scan
1844 * @param len the number of bytes in the buffer pointed to by @a bytes. 1760 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
1845 * 1761 *
1846 * @return the newly allocated buffer state object. 1762 * @return the newly allocated buffer state object.
1847 */ 1763 */
@@ -1988,9 +1904,6 @@ static int yy_init_globals (void)
1988 * This function is called from yylex_destroy(), so don't allocate here. 1904 * This function is called from yylex_destroy(), so don't allocate here.
1989 */ 1905 */
1990 1906
1991 /* We do not touch yylineno unless the option is enabled. */
1992 yylineno = 1;
1993
1994 (yy_buffer_stack) = 0; 1907 (yy_buffer_stack) = 0;
1995 (yy_buffer_stack_top) = 0; 1908 (yy_buffer_stack_top) = 0;
1996 (yy_buffer_stack_max) = 0; 1909 (yy_buffer_stack_max) = 0;
@@ -2083,104 +1996,29 @@ void yyfree (void * ptr )
2083 1996
2084#define YYTABLES_NAME "yytables" 1997#define YYTABLES_NAME "yytables"
2085 1998
2086#line 222 "dtc-lexer.l" 1999#line 168 "dtc-lexer.l"
2087 2000
2088 2001
2089 2002
2090
2091/*
2092 * Stack of nested include file contexts.
2093 */
2094
2095struct incl_file {
2096 struct dtc_file *file;
2097 YY_BUFFER_STATE yy_prev_buf;
2098 int yy_prev_lineno;
2099 struct incl_file *prev;
2100};
2101
2102static struct incl_file *incl_file_stack;
2103
2104
2105/*
2106 * Detect infinite include recursion.
2107 */
2108#define MAX_INCLUDE_DEPTH (100)
2109
2110static int incl_depth = 0;
2111
2112
2113static void push_input_file(const char *filename) 2003static void push_input_file(const char *filename)
2114{ 2004{
2115 struct incl_file *incl_file;
2116 struct dtc_file *newfile;
2117 struct search_path search, *searchptr = NULL;
2118
2119 assert(filename); 2005 assert(filename);
2120 2006
2121 if (incl_depth++ >= MAX_INCLUDE_DEPTH) 2007 srcfile_push(filename);
2122 die("Includes nested too deeply");
2123 2008
2124 if (srcpos_file) { 2009 yyin = current_srcfile->f;
2125 search.dir = srcpos_file->dir;
2126 search.next = NULL;
2127 search.prev = NULL;
2128 searchptr = &search;
2129 }
2130
2131 newfile = dtc_open_file(filename, searchptr);
2132 2010
2133 incl_file = xmalloc(sizeof(struct incl_file)); 2011 yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
2134
2135 /*
2136 * Save current context.
2137 */
2138 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
2139 incl_file->yy_prev_lineno = yylineno;
2140 incl_file->file = srcpos_file;
2141 incl_file->prev = incl_file_stack;
2142
2143 incl_file_stack = incl_file;
2144
2145 /*
2146 * Establish new context.
2147 */
2148 srcpos_file = newfile;
2149 yylineno = 1;
2150 yyin = newfile->file;
2151 yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
2152} 2012}
2153 2013
2154 2014
2155static int pop_input_file(void) 2015static int pop_input_file(void)
2156{ 2016{
2157 struct incl_file *incl_file; 2017 if (srcfile_pop() == 0)
2158
2159 if (incl_file_stack == 0)
2160 return 0; 2018 return 0;
2161 2019
2162 dtc_close_file(srcpos_file); 2020 yypop_buffer_state();
2163 2021 yyin = current_srcfile->f;
2164 /*
2165 * Pop.
2166 */
2167 --incl_depth;
2168 incl_file = incl_file_stack;
2169 incl_file_stack = incl_file->prev;
2170
2171 /*
2172 * Recover old context.
2173 */
2174 yy_delete_buffer(YY_CURRENT_BUFFER);
2175 yy_switch_to_buffer(incl_file->yy_prev_buf);
2176 yylineno = incl_file->yy_prev_lineno;
2177 srcpos_file = incl_file->file;
2178 yyin = incl_file->file ? incl_file->file->file : NULL;
2179
2180 /*
2181 * Free old state.
2182 */
2183 free(incl_file);
2184 2022
2185 return 1; 2023 return 1;
2186} 2024}
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index 27129377e5d2..9be2eea18a30 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -1,24 +1,23 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2 1
3/* Skeleton implementation for Bison's Yacc-like parsers in C 2/* A Bison parser, made by GNU Bison 2.4.1. */
4 3
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4/* Skeleton implementation for Bison's Yacc-like parsers in C
5
6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc. 7 Free Software Foundation, Inc.
7 8
8 This program is free software; you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option) 11 the Free Software Foundation, either version 3 of the License, or
11 any later version. 12 (at your option) any later version.
12 13
13 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 17 GNU General Public License for more details.
17 18
18 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22 21
23/* As a special exception, you may create a larger work that contains 22/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work 23 part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +28,7 @@
29 special exception, which will cause the skeleton and the resulting 28 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public 29 Bison output files to be licensed under the GNU General Public
31 License without this special exception. 30 License without this special exception.
32 31
33 This special exception was added by the Free Software Foundation in 32 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */ 33 version 2.2 of Bison. */
35 34
@@ -47,7 +46,7 @@
47#define YYBISON 1 46#define YYBISON 1
48 47
49/* Bison version. */ 48/* Bison version. */
50#define YYBISON_VERSION "2.3" 49#define YYBISON_VERSION "2.4.1"
51 50
52/* Skeleton name. */ 51/* Skeleton name. */
53#define YYSKELETON_NAME "yacc.c" 52#define YYSKELETON_NAME "yacc.c"
@@ -55,55 +54,32 @@
55/* Pure parsers. */ 54/* Pure parsers. */
56#define YYPURE 0 55#define YYPURE 0
57 56
58/* Using locations. */ 57/* Push parsers. */
59#define YYLSP_NEEDED 1 58#define YYPUSH 0
60
61 59
60/* Pull parsers. */
61#define YYPULL 1
62 62
63/* Tokens. */ 63/* Using locations. */
64#ifndef YYTOKENTYPE 64#define YYLSP_NEEDED 0
65# define YYTOKENTYPE
66 /* Put the tokens into the symbol table, so that GDB and other debuggers
67 know about them. */
68 enum yytokentype {
69 DT_V1 = 258,
70 DT_MEMRESERVE = 259,
71 DT_PROPNODENAME = 260,
72 DT_LITERAL = 261,
73 DT_LEGACYLITERAL = 262,
74 DT_BASE = 263,
75 DT_BYTE = 264,
76 DT_STRING = 265,
77 DT_LABEL = 266,
78 DT_REF = 267,
79 DT_INCBIN = 268
80 };
81#endif
82/* Tokens. */
83#define DT_V1 258
84#define DT_MEMRESERVE 259
85#define DT_PROPNODENAME 260
86#define DT_LITERAL 261
87#define DT_LEGACYLITERAL 262
88#define DT_BASE 263
89#define DT_BYTE 264
90#define DT_STRING 265
91#define DT_LABEL 266
92#define DT_REF 267
93#define DT_INCBIN 268
94
95 65
96 66
97 67
98/* Copy the first part of user declarations. */ 68/* Copy the first part of user declarations. */
99#line 23 "dtc-parser.y" 69
70/* Line 189 of yacc.c */
71#line 21 "dtc-parser.y"
100 72
101#include <stdio.h> 73#include <stdio.h>
102 74
103#include "dtc.h" 75#include "dtc.h"
104#include "srcpos.h" 76#include "srcpos.h"
105 77
78YYLTYPE yylloc;
79
106extern int yylex(void); 80extern int yylex(void);
81extern void print_error(char const *fmt, ...);
82extern void yyerror(char const *s);
107 83
108extern struct boot_info *the_boot_info; 84extern struct boot_info *the_boot_info;
109extern int treesource_error; 85extern int treesource_error;
@@ -111,6 +87,9 @@ extern int treesource_error;
111static unsigned long long eval_literal(const char *s, int base, int bits); 87static unsigned long long eval_literal(const char *s, int base, int bits);
112 88
113 89
90/* Line 189 of yacc.c */
91#line 92 "dtc-parser.tab.c"
92
114/* Enabling traces. */ 93/* Enabling traces. */
115#ifndef YYDEBUG 94#ifndef YYDEBUG
116# define YYDEBUG 0 95# define YYDEBUG 0
@@ -129,10 +108,35 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
129# define YYTOKEN_TABLE 0 108# define YYTOKEN_TABLE 0
130#endif 109#endif
131 110
111
112/* Tokens. */
113#ifndef YYTOKENTYPE
114# define YYTOKENTYPE
115 /* Put the tokens into the symbol table, so that GDB and other debuggers
116 know about them. */
117 enum yytokentype {
118 DT_V1 = 258,
119 DT_MEMRESERVE = 259,
120 DT_PROPNODENAME = 260,
121 DT_LITERAL = 261,
122 DT_BASE = 262,
123 DT_BYTE = 263,
124 DT_STRING = 264,
125 DT_LABEL = 265,
126 DT_REF = 266,
127 DT_INCBIN = 267
128 };
129#endif
130
131
132
132#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 133#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
133typedef union YYSTYPE 134typedef union YYSTYPE
134#line 37 "dtc-parser.y"
135{ 135{
136
137/* Line 214 of yacc.c */
138#line 39 "dtc-parser.y"
139
136 char *propnodename; 140 char *propnodename;
137 char *literal; 141 char *literal;
138 char *labelref; 142 char *labelref;
@@ -147,34 +151,23 @@ typedef union YYSTYPE
147 struct node *node; 151 struct node *node;
148 struct node *nodelist; 152 struct node *nodelist;
149 struct reserve_info *re; 153 struct reserve_info *re;
150} 154
151/* Line 187 of yacc.c. */ 155
152#line 153 "dtc-parser.tab.c" 156
153 YYSTYPE; 157/* Line 214 of yacc.c */
158#line 159 "dtc-parser.tab.c"
159} YYSTYPE;
160# define YYSTYPE_IS_TRIVIAL 1
154# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 161# define yystype YYSTYPE /* obsolescent; will be withdrawn */
155# define YYSTYPE_IS_DECLARED 1 162# define YYSTYPE_IS_DECLARED 1
156# define YYSTYPE_IS_TRIVIAL 1
157#endif
158
159#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
160typedef struct YYLTYPE
161{
162 int first_line;
163 int first_column;
164 int last_line;
165 int last_column;
166} YYLTYPE;
167# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
168# define YYLTYPE_IS_DECLARED 1
169# define YYLTYPE_IS_TRIVIAL 1
170#endif 163#endif
171 164
172 165
173/* Copy the second part of user declarations. */ 166/* Copy the second part of user declarations. */
174 167
175 168
176/* Line 216 of yacc.c. */ 169/* Line 264 of yacc.c */
177#line 178 "dtc-parser.tab.c" 170#line 171 "dtc-parser.tab.c"
178 171
179#ifdef short 172#ifdef short
180# undef short 173# undef short
@@ -249,14 +242,14 @@ typedef short int yytype_int16;
249#if (defined __STDC__ || defined __C99__FUNC__ \ 242#if (defined __STDC__ || defined __C99__FUNC__ \
250 || defined __cplusplus || defined _MSC_VER) 243 || defined __cplusplus || defined _MSC_VER)
251static int 244static int
252YYID (int i) 245YYID (int yyi)
253#else 246#else
254static int 247static int
255YYID (i) 248YYID (yyi)
256 int i; 249 int yyi;
257#endif 250#endif
258{ 251{
259 return i; 252 return yyi;
260} 253}
261#endif 254#endif
262 255
@@ -332,15 +325,13 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
332 325
333#if (! defined yyoverflow \ 326#if (! defined yyoverflow \
334 && (! defined __cplusplus \ 327 && (! defined __cplusplus \
335 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ 328 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
336 && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
337 329
338/* A type that is properly aligned for any stack member. */ 330/* A type that is properly aligned for any stack member. */
339union yyalloc 331union yyalloc
340{ 332{
341 yytype_int16 yyss; 333 yytype_int16 yyss_alloc;
342 YYSTYPE yyvs; 334 YYSTYPE yyvs_alloc;
343 YYLTYPE yyls;
344}; 335};
345 336
346/* The size of the maximum gap between one aligned stack and the next. */ 337/* The size of the maximum gap between one aligned stack and the next. */
@@ -349,8 +340,8 @@ union yyalloc
349/* The size of an array large to enough to hold all stacks, each with 340/* The size of an array large to enough to hold all stacks, each with
350 N elements. */ 341 N elements. */
351# define YYSTACK_BYTES(N) \ 342# define YYSTACK_BYTES(N) \
352 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ 343 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
353 + 2 * YYSTACK_GAP_MAXIMUM) 344 + YYSTACK_GAP_MAXIMUM)
354 345
355/* Copy COUNT objects from FROM to TO. The source and destination do 346/* Copy COUNT objects from FROM to TO. The source and destination do
356 not overlap. */ 347 not overlap. */
@@ -375,12 +366,12 @@ union yyalloc
375 elements in the stack, and YYPTR gives the new location of the 366 elements in the stack, and YYPTR gives the new location of the
376 stack. Advance YYPTR to a properly aligned location for the next 367 stack. Advance YYPTR to a properly aligned location for the next
377 stack. */ 368 stack. */
378# define YYSTACK_RELOCATE(Stack) \ 369# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
379 do \ 370 do \
380 { \ 371 { \
381 YYSIZE_T yynewbytes; \ 372 YYSIZE_T yynewbytes; \
382 YYCOPY (&yyptr->Stack, Stack, yysize); \ 373 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
383 Stack = &yyptr->Stack; \ 374 Stack = &yyptr->Stack_alloc; \
384 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ 375 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
385 yyptr += yynewbytes / sizeof (*yyptr); \ 376 yyptr += yynewbytes / sizeof (*yyptr); \
386 } \ 377 } \
@@ -389,22 +380,22 @@ union yyalloc
389#endif 380#endif
390 381
391/* YYFINAL -- State number of the termination state. */ 382/* YYFINAL -- State number of the termination state. */
392#define YYFINAL 9 383#define YYFINAL 4
393/* YYLAST -- Last index in YYTABLE. */ 384/* YYLAST -- Last index in YYTABLE. */
394#define YYLAST 73 385#define YYLAST 56
395 386
396/* YYNTOKENS -- Number of terminals. */ 387/* YYNTOKENS -- Number of terminals. */
397#define YYNTOKENS 27 388#define YYNTOKENS 25
398/* YYNNTS -- Number of nonterminals. */ 389/* YYNNTS -- Number of nonterminals. */
399#define YYNNTS 20 390#define YYNNTS 16
400/* YYNRULES -- Number of rules. */ 391/* YYNRULES -- Number of rules. */
401#define YYNRULES 45 392#define YYNRULES 39
402/* YYNRULES -- Number of states. */ 393/* YYNRULES -- Number of states. */
403#define YYNSTATES 76 394#define YYNSTATES 67
404 395
405/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 396/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
406#define YYUNDEFTOK 2 397#define YYUNDEFTOK 2
407#define YYMAXUTOK 268 398#define YYMAXUTOK 267
408 399
409#define YYTRANSLATE(YYX) \ 400#define YYTRANSLATE(YYX) \
410 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 401 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -416,15 +407,15 @@ static const yytype_uint8 yytranslate[] =
416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 407 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 408 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 409 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 24, 26, 2, 2, 25, 15, 2, 16, 2, 2, 410 22, 24, 2, 2, 23, 2, 2, 14, 2, 2,
420 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 411 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
421 20, 19, 21, 2, 2, 2, 2, 2, 2, 2, 412 18, 17, 19, 2, 2, 2, 2, 2, 2, 2,
422 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 414 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424 2, 22, 2, 23, 2, 2, 2, 2, 2, 2, 415 2, 20, 2, 21, 2, 2, 2, 2, 2, 2,
425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427 2, 2, 2, 17, 2, 18, 2, 2, 2, 2, 418 2, 2, 2, 15, 2, 16, 2, 2, 2, 2,
428 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 419 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 420 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 421 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -438,7 +429,7 @@ static const yytype_uint8 yytranslate[] =
438 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
439 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
440 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 431 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
441 5, 6, 7, 8, 9, 10, 11, 12, 13 432 5, 6, 7, 8, 9, 10, 11, 12
442}; 433};
443 434
444#if YYDEBUG 435#if YYDEBUG
@@ -446,41 +437,37 @@ static const yytype_uint8 yytranslate[] =
446 YYRHS. */ 437 YYRHS. */
447static const yytype_uint8 yyprhs[] = 438static const yytype_uint8 yyprhs[] =
448{ 439{
449 0, 0, 3, 8, 11, 12, 15, 21, 22, 25, 440 0, 0, 3, 8, 9, 12, 17, 20, 22, 25,
450 27, 34, 36, 38, 41, 47, 48, 51, 57, 61, 441 29, 33, 39, 40, 43, 48, 51, 54, 57, 62,
451 64, 69, 74, 77, 87, 93, 96, 97, 100, 103, 442 67, 70, 80, 86, 89, 90, 93, 96, 97, 100,
452 104, 107, 110, 113, 114, 116, 118, 121, 122, 125, 443 103, 106, 108, 109, 112, 115, 116, 119, 122, 125
453 128, 129, 132, 135, 139, 140
454}; 444};
455 445
456/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 446/* YYRHS -- A `-1'-separated list of the rules' RHS. */
457static const yytype_int8 yyrhs[] = 447static const yytype_int8 yyrhs[] =
458{ 448{
459 28, 0, -1, 3, 14, 29, 34, -1, 31, 34, 449 26, 0, -1, 3, 13, 27, 30, -1, -1, 28,
460 -1, -1, 30, 29, -1, 46, 4, 33, 33, 14, 450 27, -1, 4, 29, 29, 13, -1, 10, 28, -1,
461 -1, -1, 32, 31, -1, 30, -1, 46, 4, 33, 451 6, -1, 14, 31, -1, 30, 14, 31, -1, 30,
462 15, 33, 14, -1, 6, -1, 7, -1, 16, 35, 452 11, 31, -1, 15, 32, 39, 16, 13, -1, -1,
463 -1, 17, 36, 44, 18, 14, -1, -1, 36, 37, 453 32, 33, -1, 5, 17, 34, 13, -1, 5, 13,
464 -1, 46, 5, 19, 38, 14, -1, 46, 5, 14, 454 -1, 10, 33, -1, 35, 9, -1, 35, 18, 36,
465 -1, 39, 10, -1, 39, 20, 40, 21, -1, 39, 455 19, -1, 35, 20, 38, 21, -1, 35, 11, -1,
466 22, 43, 23, -1, 39, 12, -1, 39, 13, 24, 456 35, 12, 22, 9, 23, 29, 23, 29, 24, -1,
467 10, 25, 33, 25, 33, 26, -1, 39, 13, 24, 457 35, 12, 22, 9, 24, -1, 34, 10, -1, -1,
468 10, 26, -1, 38, 11, -1, -1, 38, 25, -1, 458 34, 23, -1, 35, 10, -1, -1, 36, 37, -1,
469 39, 11, -1, -1, 40, 42, -1, 40, 12, -1, 459 36, 11, -1, 36, 10, -1, 6, -1, -1, 38,
470 40, 11, -1, -1, 8, -1, 6, -1, 41, 7, 460 8, -1, 38, 10, -1, -1, 40, 39, -1, 40,
471 -1, -1, 43, 9, -1, 43, 11, -1, -1, 45, 461 33, -1, 5, 31, -1, 10, 40, -1
472 44, -1, 45, 37, -1, 46, 5, 35, -1, -1,
473 11, -1
474}; 462};
475 463
476/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 464/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
477static const yytype_uint16 yyrline[] = 465static const yytype_uint16 yyrline[] =
478{ 466{
479 0, 89, 89, 93, 101, 104, 111, 119, 122, 129, 467 0, 86, 86, 95, 98, 105, 109, 117, 124, 128,
480 133, 140, 144, 151, 158, 166, 169, 176, 180, 187, 468 132, 145, 153, 156, 163, 167, 171, 179, 183, 187,
481 191, 195, 199, 203, 220, 231, 239, 242, 246, 254, 469 191, 195, 212, 222, 230, 233, 237, 245, 248, 252,
482 257, 261, 266, 274, 277, 281, 285, 293, 296, 300, 470 257, 264, 272, 275, 279, 287, 290, 294, 302, 306
483 308, 311, 315, 323, 331, 334
484}; 471};
485#endif 472#endif
486 473
@@ -490,13 +477,12 @@ static const yytype_uint16 yyrline[] =
490static const char *const yytname[] = 477static const char *const yytname[] =
491{ 478{
492 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", 479 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
493 "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE", 480 "DT_PROPNODENAME", "DT_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING",
494 "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'", 481 "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='",
495 "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','", 482 "'<'", "'>'", "'['", "']'", "'('", "','", "')'", "$accept", "sourcefile",
496 "')'", "$accept", "sourcefile", "memreserves", "memreserve", 483 "memreserves", "memreserve", "addr", "devicetree", "nodedef", "proplist",
497 "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef", 484 "propdef", "propdata", "propdataprefix", "celllist", "cellval",
498 "proplist", "propdef", "propdata", "propdataprefix", "celllist", 485 "bytestring", "subnodes", "subnode", 0
499 "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0
500}; 486};
501#endif 487#endif
502 488
@@ -506,29 +492,27 @@ static const char *const yytname[] =
506static const yytype_uint16 yytoknum[] = 492static const yytype_uint16 yytoknum[] =
507{ 493{
508 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 494 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
509 265, 266, 267, 268, 59, 45, 47, 123, 125, 61, 495 265, 266, 267, 59, 47, 123, 125, 61, 60, 62,
510 60, 62, 91, 93, 40, 44, 41 496 91, 93, 40, 44, 41
511}; 497};
512# endif 498# endif
513 499
514/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 500/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
515static const yytype_uint8 yyr1[] = 501static const yytype_uint8 yyr1[] =
516{ 502{
517 0, 27, 28, 28, 29, 29, 30, 31, 31, 32, 503 0, 25, 26, 27, 27, 28, 28, 29, 30, 30,
518 32, 33, 33, 34, 35, 36, 36, 37, 37, 38, 504 30, 31, 32, 32, 33, 33, 33, 34, 34, 34,
519 38, 38, 38, 38, 38, 38, 39, 39, 39, 40, 505 34, 34, 34, 34, 35, 35, 35, 36, 36, 36,
520 40, 40, 40, 41, 41, 42, 42, 43, 43, 43, 506 36, 37, 38, 38, 38, 39, 39, 39, 40, 40
521 44, 44, 44, 45, 46, 46
522}; 507};
523 508
524/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 509/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
525static const yytype_uint8 yyr2[] = 510static const yytype_uint8 yyr2[] =
526{ 511{
527 0, 2, 4, 2, 0, 2, 5, 0, 2, 1, 512 0, 2, 4, 0, 2, 4, 2, 1, 2, 3,
528 6, 1, 1, 2, 5, 0, 2, 5, 3, 2, 513 3, 5, 0, 2, 4, 2, 2, 2, 4, 4,
529 4, 4, 2, 9, 5, 2, 0, 2, 2, 0, 514 2, 9, 5, 2, 0, 2, 2, 0, 2, 2,
530 2, 2, 2, 0, 1, 1, 2, 0, 2, 2, 515 2, 1, 0, 2, 2, 0, 2, 2, 2, 2
531 0, 2, 2, 3, 0, 1
532}; 516};
533 517
534/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 518/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -536,86 +520,79 @@ static const yytype_uint8 yyr2[] =
536 means the default is an error. */ 520 means the default is an error. */
537static const yytype_uint8 yydefact[] = 521static const yytype_uint8 yydefact[] =
538{ 522{
539 7, 0, 45, 0, 9, 0, 7, 0, 4, 1, 523 0, 0, 0, 3, 1, 0, 0, 0, 3, 7,
540 0, 3, 8, 0, 0, 4, 0, 15, 13, 11, 524 0, 6, 0, 2, 4, 0, 12, 8, 0, 0,
541 12, 0, 2, 5, 0, 40, 0, 0, 0, 16, 525 5, 35, 10, 9, 0, 0, 13, 0, 35, 15,
542 0, 40, 0, 0, 6, 0, 42, 41, 0, 10, 526 24, 38, 16, 39, 0, 37, 36, 0, 0, 11,
543 14, 18, 26, 43, 0, 0, 25, 17, 27, 19, 527 23, 14, 25, 17, 26, 20, 0, 27, 32, 0,
544 28, 22, 0, 29, 37, 0, 33, 0, 0, 35, 528 0, 0, 0, 31, 30, 29, 18, 28, 33, 34,
545 34, 32, 31, 20, 0, 30, 38, 39, 21, 0, 529 19, 0, 22, 0, 0, 0, 21
546 24, 36, 0, 0, 0, 23
547}; 530};
548 531
549/* YYDEFGOTO[NTERM-NUM]. */ 532/* YYDEFGOTO[NTERM-NUM]. */
550static const yytype_int8 yydefgoto[] = 533static const yytype_int8 yydefgoto[] =
551{ 534{
552 -1, 3, 14, 4, 5, 6, 27, 11, 18, 25, 535 -1, 2, 7, 8, 10, 13, 17, 21, 26, 37,
553 29, 44, 45, 56, 64, 65, 57, 30, 31, 7 536 38, 50, 57, 51, 27, 28
554}; 537};
555 538
556/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 539/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
557 STATE-NUM. */ 540 STATE-NUM. */
558#define YYPACT_NINF -14 541#define YYPACT_NINF -12
559static const yytype_int8 yypact[] = 542static const yytype_int8 yypact[] =
560{ 543{
561 30, -11, -14, 7, -14, -1, 27, 13, 27, -14, 544 10, -11, 18, -1, -12, 22, -1, 15, -1, -12,
562 8, -14, -14, 40, -1, 27, 35, -14, -14, -14, 545 22, -12, 20, 1, -12, 17, -12, -12, 20, 20,
563 -14, 21, -14, -14, 40, 24, 40, 28, 40, -14, 546 -12, 6, -12, -12, 21, 6, -12, 23, 6, -12,
564 32, 24, 46, 38, -14, 39, -14, -14, 26, -14, 547 -12, -12, -12, -12, 28, -12, -12, -6, 13, -12,
565 -14, -14, -14, -14, -9, 10, -14, -14, -14, -14, 548 -12, -12, -12, -12, -12, -12, 24, -12, -12, 33,
566 -14, -14, 31, -14, -14, 44, -2, 3, 23, -14, 549 -5, 0, -4, -12, -12, -12, -12, -12, -12, -12,
567 -14, -14, -14, -14, 50, -14, -14, -14, -14, 40, 550 -12, 22, -12, 25, 22, 19, -12
568 -14, -14, 33, 40, 36, -14
569}; 551};
570 552
571/* YYPGOTO[NTERM-NUM]. */ 553/* YYPGOTO[NTERM-NUM]. */
572static const yytype_int8 yypgoto[] = 554static const yytype_int8 yypgoto[] =
573{ 555{
574 -14, -14, 48, 29, 53, -14, -13, 47, 34, -14, 556 -12, -12, 36, 39, -10, -12, 8, -12, 12, -12,
575 37, -14, -14, -14, -14, -14, -14, 42, -14, -7 557 -12, -12, -12, -12, 27, 31
576}; 558};
577 559
578/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 560/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
579 positive, shift that token. If negative, reduce the rule which 561 positive, shift that token. If negative, reduce the rule which
580 number is the opposite. If zero, do what YYDEFACT says. 562 number is the opposite. If zero, do what YYDEFACT says.
581 If YYTABLE_NINF, syntax error. */ 563 If YYTABLE_NINF, syntax error. */
582#define YYTABLE_NINF -45 564#define YYTABLE_NINF -1
583static const yytype_int8 yytable[] = 565static const yytype_uint8 yytable[] =
584{ 566{
585 21, 16, 46, 8, 59, 47, 60, 9, 16, 61, 567 15, 53, 3, 5, 40, 54, 55, 41, 58, 6,
586 62, 28, 66, 33, 67, 10, 48, 13, 32, 63, 568 59, 24, 18, 1, 56, 19, 25, 42, 4, 61,
587 49, 50, 51, 52, 32, 17, 68, 19, 20, -44, 569 62, 60, 43, 44, 45, 46, 22, 23, 9, 12,
588 53, -44, 54, 1, -44, 2, 26, 15, 2, 24, 570 20, 47, 31, 48, 29, 16, 16, 32, 30, 34,
589 41, 2, 34, 17, 15, 42, 19, 20, 69, 70, 571 35, 39, 52, 66, 14, 11, 49, 0, 64, 0,
590 35, 38, 39, 40, 58, 55, 72, 71, 73, 12, 572 0, 63, 0, 0, 65, 36, 33
591 74, 22, 75, 23, 0, 0, 0, 0, 36, 0,
592 0, 0, 43, 37
593}; 573};
594 574
595static const yytype_int8 yycheck[] = 575static const yytype_int8 yycheck[] =
596{ 576{
597 13, 8, 11, 14, 6, 14, 8, 0, 15, 11, 577 10, 6, 13, 4, 10, 10, 11, 13, 8, 10,
598 12, 24, 9, 26, 11, 16, 25, 4, 25, 21, 578 10, 5, 11, 3, 19, 14, 10, 23, 0, 23,
599 10, 11, 12, 13, 31, 17, 23, 6, 7, 5, 579 24, 21, 9, 10, 11, 12, 18, 19, 6, 14,
600 20, 4, 22, 3, 4, 11, 15, 8, 11, 4, 580 13, 18, 24, 20, 13, 15, 15, 25, 17, 16,
601 14, 11, 14, 17, 15, 19, 6, 7, 25, 26, 581 28, 13, 9, 24, 8, 6, 22, -1, 23, -1,
602 18, 5, 14, 14, 10, 24, 69, 7, 25, 6, 582 -1, 61, -1, -1, 64, 28, 25
603 73, 14, 26, 15, -1, -1, -1, -1, 31, -1,
604 -1, -1, 38, 31
605}; 583};
606 584
607/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 585/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
608 symbol of state STATE-NUM. */ 586 symbol of state STATE-NUM. */
609static const yytype_uint8 yystos[] = 587static const yytype_uint8 yystos[] =
610{ 588{
611 0, 3, 11, 28, 30, 31, 32, 46, 14, 0, 589 0, 3, 26, 13, 0, 4, 10, 27, 28, 6,
612 16, 34, 31, 4, 29, 30, 46, 17, 35, 6, 590 29, 28, 14, 30, 27, 29, 15, 31, 11, 14,
613 7, 33, 34, 29, 4, 36, 15, 33, 33, 37, 591 13, 32, 31, 31, 5, 10, 33, 39, 40, 13,
614 44, 45, 46, 33, 14, 18, 37, 44, 5, 14, 592 17, 31, 33, 40, 16, 33, 39, 34, 35, 13,
615 14, 14, 19, 35, 38, 39, 11, 14, 25, 10, 593 10, 13, 23, 9, 10, 11, 12, 18, 20, 22,
616 11, 12, 13, 20, 22, 24, 40, 43, 10, 6, 594 36, 38, 9, 6, 10, 11, 19, 37, 8, 10,
617 8, 11, 12, 21, 41, 42, 9, 11, 23, 25, 595 21, 23, 24, 29, 23, 29, 24
618 26, 7, 33, 25, 33, 26
619}; 596};
620 597
621#define yyerrok (yyerrstatus = 0) 598#define yyerrok (yyerrstatus = 0)
@@ -728,7 +705,7 @@ do { \
728 { \ 705 { \
729 YYFPRINTF (stderr, "%s ", Title); \ 706 YYFPRINTF (stderr, "%s ", Title); \
730 yy_symbol_print (stderr, \ 707 yy_symbol_print (stderr, \
731 Type, Value, Location); \ 708 Type, Value); \
732 YYFPRINTF (stderr, "\n"); \ 709 YYFPRINTF (stderr, "\n"); \
733 } \ 710 } \
734} while (YYID (0)) 711} while (YYID (0))
@@ -742,19 +719,17 @@ do { \
742#if (defined __STDC__ || defined __C99__FUNC__ \ 719#if (defined __STDC__ || defined __C99__FUNC__ \
743 || defined __cplusplus || defined _MSC_VER) 720 || defined __cplusplus || defined _MSC_VER)
744static void 721static void
745yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) 722yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
746#else 723#else
747static void 724static void
748yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) 725yy_symbol_value_print (yyoutput, yytype, yyvaluep)
749 FILE *yyoutput; 726 FILE *yyoutput;
750 int yytype; 727 int yytype;
751 YYSTYPE const * const yyvaluep; 728 YYSTYPE const * const yyvaluep;
752 YYLTYPE const * const yylocationp;
753#endif 729#endif
754{ 730{
755 if (!yyvaluep) 731 if (!yyvaluep)
756 return; 732 return;
757 YYUSE (yylocationp);
758# ifdef YYPRINT 733# ifdef YYPRINT
759 if (yytype < YYNTOKENS) 734 if (yytype < YYNTOKENS)
760 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); 735 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
@@ -776,14 +751,13 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
776#if (defined __STDC__ || defined __C99__FUNC__ \ 751#if (defined __STDC__ || defined __C99__FUNC__ \
777 || defined __cplusplus || defined _MSC_VER) 752 || defined __cplusplus || defined _MSC_VER)
778static void 753static void
779yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) 754yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
780#else 755#else
781static void 756static void
782yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) 757yy_symbol_print (yyoutput, yytype, yyvaluep)
783 FILE *yyoutput; 758 FILE *yyoutput;
784 int yytype; 759 int yytype;
785 YYSTYPE const * const yyvaluep; 760 YYSTYPE const * const yyvaluep;
786 YYLTYPE const * const yylocationp;
787#endif 761#endif
788{ 762{
789 if (yytype < YYNTOKENS) 763 if (yytype < YYNTOKENS)
@@ -791,9 +765,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
791 else 765 else
792 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); 766 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
793 767
794 YY_LOCATION_PRINT (yyoutput, *yylocationp); 768 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
795 YYFPRINTF (yyoutput, ": ");
796 yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
797 YYFPRINTF (yyoutput, ")"); 769 YYFPRINTF (yyoutput, ")");
798} 770}
799 771
@@ -805,17 +777,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
805#if (defined __STDC__ || defined __C99__FUNC__ \ 777#if (defined __STDC__ || defined __C99__FUNC__ \
806 || defined __cplusplus || defined _MSC_VER) 778 || defined __cplusplus || defined _MSC_VER)
807static void 779static void
808yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) 780yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
809#else 781#else
810static void 782static void
811yy_stack_print (bottom, top) 783yy_stack_print (yybottom, yytop)
812 yytype_int16 *bottom; 784 yytype_int16 *yybottom;
813 yytype_int16 *top; 785 yytype_int16 *yytop;
814#endif 786#endif
815{ 787{
816 YYFPRINTF (stderr, "Stack now"); 788 YYFPRINTF (stderr, "Stack now");
817 for (; bottom <= top; ++bottom) 789 for (; yybottom <= yytop; yybottom++)
818 YYFPRINTF (stderr, " %d", *bottom); 790 {
791 int yybot = *yybottom;
792 YYFPRINTF (stderr, " %d", yybot);
793 }
819 YYFPRINTF (stderr, "\n"); 794 YYFPRINTF (stderr, "\n");
820} 795}
821 796
@@ -833,12 +808,11 @@ do { \
833#if (defined __STDC__ || defined __C99__FUNC__ \ 808#if (defined __STDC__ || defined __C99__FUNC__ \
834 || defined __cplusplus || defined _MSC_VER) 809 || defined __cplusplus || defined _MSC_VER)
835static void 810static void
836yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) 811yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
837#else 812#else
838static void 813static void
839yy_reduce_print (yyvsp, yylsp, yyrule) 814yy_reduce_print (yyvsp, yyrule)
840 YYSTYPE *yyvsp; 815 YYSTYPE *yyvsp;
841 YYLTYPE *yylsp;
842 int yyrule; 816 int yyrule;
843#endif 817#endif
844{ 818{
@@ -850,18 +824,18 @@ yy_reduce_print (yyvsp, yylsp, yyrule)
850 /* The symbols being reduced. */ 824 /* The symbols being reduced. */
851 for (yyi = 0; yyi < yynrhs; yyi++) 825 for (yyi = 0; yyi < yynrhs; yyi++)
852 { 826 {
853 fprintf (stderr, " $%d = ", yyi + 1); 827 YYFPRINTF (stderr, " $%d = ", yyi + 1);
854 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], 828 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
855 &(yyvsp[(yyi + 1) - (yynrhs)]) 829 &(yyvsp[(yyi + 1) - (yynrhs)])
856 , &(yylsp[(yyi + 1) - (yynrhs)]) ); 830 );
857 fprintf (stderr, "\n"); 831 YYFPRINTF (stderr, "\n");
858 } 832 }
859} 833}
860 834
861# define YY_REDUCE_PRINT(Rule) \ 835# define YY_REDUCE_PRINT(Rule) \
862do { \ 836do { \
863 if (yydebug) \ 837 if (yydebug) \
864 yy_reduce_print (yyvsp, yylsp, Rule); \ 838 yy_reduce_print (yyvsp, Rule); \
865} while (YYID (0)) 839} while (YYID (0))
866 840
867/* Nonzero means print parse trace. It is left uninitialized so that 841/* Nonzero means print parse trace. It is left uninitialized so that
@@ -1112,18 +1086,16 @@ yysyntax_error (char *yyresult, int yystate, int yychar)
1112#if (defined __STDC__ || defined __C99__FUNC__ \ 1086#if (defined __STDC__ || defined __C99__FUNC__ \
1113 || defined __cplusplus || defined _MSC_VER) 1087 || defined __cplusplus || defined _MSC_VER)
1114static void 1088static void
1115yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) 1089yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1116#else 1090#else
1117static void 1091static void
1118yydestruct (yymsg, yytype, yyvaluep, yylocationp) 1092yydestruct (yymsg, yytype, yyvaluep)
1119 const char *yymsg; 1093 const char *yymsg;
1120 int yytype; 1094 int yytype;
1121 YYSTYPE *yyvaluep; 1095 YYSTYPE *yyvaluep;
1122 YYLTYPE *yylocationp;
1123#endif 1096#endif
1124{ 1097{
1125 YYUSE (yyvaluep); 1098 YYUSE (yyvaluep);
1126 YYUSE (yylocationp);
1127 1099
1128 if (!yymsg) 1100 if (!yymsg)
1129 yymsg = "Deleting"; 1101 yymsg = "Deleting";
@@ -1136,10 +1108,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp)
1136 break; 1108 break;
1137 } 1109 }
1138} 1110}
1139
1140 1111
1141/* Prevent warnings from -Wmissing-prototypes. */ 1112/* Prevent warnings from -Wmissing-prototypes. */
1142
1143#ifdef YYPARSE_PARAM 1113#ifdef YYPARSE_PARAM
1144#if defined __STDC__ || defined __cplusplus 1114#if defined __STDC__ || defined __cplusplus
1145int yyparse (void *YYPARSE_PARAM); 1115int yyparse (void *YYPARSE_PARAM);
@@ -1155,23 +1125,20 @@ int yyparse ();
1155#endif /* ! YYPARSE_PARAM */ 1125#endif /* ! YYPARSE_PARAM */
1156 1126
1157 1127
1158 1128/* The lookahead symbol. */
1159/* The look-ahead symbol. */
1160int yychar; 1129int yychar;
1161 1130
1162/* The semantic value of the look-ahead symbol. */ 1131/* The semantic value of the lookahead symbol. */
1163YYSTYPE yylval; 1132YYSTYPE yylval;
1164 1133
1165/* Number of syntax errors so far. */ 1134/* Number of syntax errors so far. */
1166int yynerrs; 1135int yynerrs;
1167/* Location data for the look-ahead symbol. */
1168YYLTYPE yylloc;
1169 1136
1170 1137
1171 1138
1172/*----------. 1139/*-------------------------.
1173| yyparse. | 1140| yyparse or yypush_parse. |
1174`----------*/ 1141`-------------------------*/
1175 1142
1176#ifdef YYPARSE_PARAM 1143#ifdef YYPARSE_PARAM
1177#if (defined __STDC__ || defined __C99__FUNC__ \ 1144#if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1195,79 +1162,70 @@ yyparse ()
1195#endif 1162#endif
1196#endif 1163#endif
1197{ 1164{
1198
1199 int yystate;
1200 int yyn;
1201 int yyresult;
1202 /* Number of tokens to shift before error messages enabled. */
1203 int yyerrstatus;
1204 /* Look-ahead token as an internal (translated) token number. */
1205 int yytoken = 0;
1206#if YYERROR_VERBOSE
1207 /* Buffer for error messages, and its allocated size. */
1208 char yymsgbuf[128];
1209 char *yymsg = yymsgbuf;
1210 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1211#endif
1212 1165
1213 /* Three stacks and their tools:
1214 `yyss': related to states,
1215 `yyvs': related to semantic values,
1216 `yyls': related to locations.
1217 1166
1218 Refer to the stacks thru separate pointers, to allow yyoverflow 1167 int yystate;
1219 to reallocate them elsewhere. */ 1168 /* Number of tokens to shift before error messages enabled. */
1169 int yyerrstatus;
1220 1170
1221 /* The state stack. */ 1171 /* The stacks and their tools:
1222 yytype_int16 yyssa[YYINITDEPTH]; 1172 `yyss': related to states.
1223 yytype_int16 *yyss = yyssa; 1173 `yyvs': related to semantic values.
1224 yytype_int16 *yyssp;
1225 1174
1226 /* The semantic value stack. */ 1175 Refer to the stacks thru separate pointers, to allow yyoverflow
1227 YYSTYPE yyvsa[YYINITDEPTH]; 1176 to reallocate them elsewhere. */
1228 YYSTYPE *yyvs = yyvsa;
1229 YYSTYPE *yyvsp;
1230 1177
1231 /* The location stack. */ 1178 /* The state stack. */
1232 YYLTYPE yylsa[YYINITDEPTH]; 1179 yytype_int16 yyssa[YYINITDEPTH];
1233 YYLTYPE *yyls = yylsa; 1180 yytype_int16 *yyss;
1234 YYLTYPE *yylsp; 1181 yytype_int16 *yyssp;
1235 /* The locations where the error started and ended. */
1236 YYLTYPE yyerror_range[2];
1237 1182
1238#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) 1183 /* The semantic value stack. */
1184 YYSTYPE yyvsa[YYINITDEPTH];
1185 YYSTYPE *yyvs;
1186 YYSTYPE *yyvsp;
1239 1187
1240 YYSIZE_T yystacksize = YYINITDEPTH; 1188 YYSIZE_T yystacksize;
1241 1189
1190 int yyn;
1191 int yyresult;
1192 /* Lookahead token as an internal (translated) token number. */
1193 int yytoken;
1242 /* The variables used to return semantic value and location from the 1194 /* The variables used to return semantic value and location from the
1243 action routines. */ 1195 action routines. */
1244 YYSTYPE yyval; 1196 YYSTYPE yyval;
1245 YYLTYPE yyloc; 1197
1198#if YYERROR_VERBOSE
1199 /* Buffer for error messages, and its allocated size. */
1200 char yymsgbuf[128];
1201 char *yymsg = yymsgbuf;
1202 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1203#endif
1204
1205#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1246 1206
1247 /* The number of symbols on the RHS of the reduced rule. 1207 /* The number of symbols on the RHS of the reduced rule.
1248 Keep to zero when no symbol should be popped. */ 1208 Keep to zero when no symbol should be popped. */
1249 int yylen = 0; 1209 int yylen = 0;
1250 1210
1211 yytoken = 0;
1212 yyss = yyssa;
1213 yyvs = yyvsa;
1214 yystacksize = YYINITDEPTH;
1215
1251 YYDPRINTF ((stderr, "Starting parse\n")); 1216 YYDPRINTF ((stderr, "Starting parse\n"));
1252 1217
1253 yystate = 0; 1218 yystate = 0;
1254 yyerrstatus = 0; 1219 yyerrstatus = 0;
1255 yynerrs = 0; 1220 yynerrs = 0;
1256 yychar = YYEMPTY; /* Cause a token to be read. */ 1221 yychar = YYEMPTY; /* Cause a token to be read. */
1257 1222
1258 /* Initialize stack pointers. 1223 /* Initialize stack pointers.
1259 Waste one element of value and location stack 1224 Waste one element of value and location stack
1260 so that they stay on the same level as the state stack. 1225 so that they stay on the same level as the state stack.
1261 The wasted elements are never initialized. */ 1226 The wasted elements are never initialized. */
1262
1263 yyssp = yyss; 1227 yyssp = yyss;
1264 yyvsp = yyvs; 1228 yyvsp = yyvs;
1265 yylsp = yyls;
1266#if YYLTYPE_IS_TRIVIAL
1267 /* Initialize the default location before parsing starts. */
1268 yylloc.first_line = yylloc.last_line = 1;
1269 yylloc.first_column = yylloc.last_column = 0;
1270#endif
1271 1229
1272 goto yysetstate; 1230 goto yysetstate;
1273 1231
@@ -1294,7 +1252,6 @@ yyparse ()
1294 memory. */ 1252 memory. */
1295 YYSTYPE *yyvs1 = yyvs; 1253 YYSTYPE *yyvs1 = yyvs;
1296 yytype_int16 *yyss1 = yyss; 1254 yytype_int16 *yyss1 = yyss;
1297 YYLTYPE *yyls1 = yyls;
1298 1255
1299 /* Each stack pointer address is followed by the size of the 1256 /* Each stack pointer address is followed by the size of the
1300 data in use in that stack, in bytes. This used to be a 1257 data in use in that stack, in bytes. This used to be a
@@ -1303,9 +1260,8 @@ yyparse ()
1303 yyoverflow (YY_("memory exhausted"), 1260 yyoverflow (YY_("memory exhausted"),
1304 &yyss1, yysize * sizeof (*yyssp), 1261 &yyss1, yysize * sizeof (*yyssp),
1305 &yyvs1, yysize * sizeof (*yyvsp), 1262 &yyvs1, yysize * sizeof (*yyvsp),
1306 &yyls1, yysize * sizeof (*yylsp),
1307 &yystacksize); 1263 &yystacksize);
1308 yyls = yyls1; 1264
1309 yyss = yyss1; 1265 yyss = yyss1;
1310 yyvs = yyvs1; 1266 yyvs = yyvs1;
1311 } 1267 }
@@ -1326,9 +1282,8 @@ yyparse ()
1326 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1282 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1327 if (! yyptr) 1283 if (! yyptr)
1328 goto yyexhaustedlab; 1284 goto yyexhaustedlab;
1329 YYSTACK_RELOCATE (yyss); 1285 YYSTACK_RELOCATE (yyss_alloc, yyss);
1330 YYSTACK_RELOCATE (yyvs); 1286 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1331 YYSTACK_RELOCATE (yyls);
1332# undef YYSTACK_RELOCATE 1287# undef YYSTACK_RELOCATE
1333 if (yyss1 != yyssa) 1288 if (yyss1 != yyssa)
1334 YYSTACK_FREE (yyss1); 1289 YYSTACK_FREE (yyss1);
@@ -1338,7 +1293,6 @@ yyparse ()
1338 1293
1339 yyssp = yyss + yysize - 1; 1294 yyssp = yyss + yysize - 1;
1340 yyvsp = yyvs + yysize - 1; 1295 yyvsp = yyvs + yysize - 1;
1341 yylsp = yyls + yysize - 1;
1342 1296
1343 YYDPRINTF ((stderr, "Stack size increased to %lu\n", 1297 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1344 (unsigned long int) yystacksize)); 1298 (unsigned long int) yystacksize));
@@ -1349,6 +1303,9 @@ yyparse ()
1349 1303
1350 YYDPRINTF ((stderr, "Entering state %d\n", yystate)); 1304 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1351 1305
1306 if (yystate == YYFINAL)
1307 YYACCEPT;
1308
1352 goto yybackup; 1309 goto yybackup;
1353 1310
1354/*-----------. 1311/*-----------.
@@ -1357,16 +1314,16 @@ yyparse ()
1357yybackup: 1314yybackup:
1358 1315
1359 /* Do appropriate processing given the current state. Read a 1316 /* Do appropriate processing given the current state. Read a
1360 look-ahead token if we need one and don't already have one. */ 1317 lookahead token if we need one and don't already have one. */
1361 1318
1362 /* First try to decide what to do without reference to look-ahead token. */ 1319 /* First try to decide what to do without reference to lookahead token. */
1363 yyn = yypact[yystate]; 1320 yyn = yypact[yystate];
1364 if (yyn == YYPACT_NINF) 1321 if (yyn == YYPACT_NINF)
1365 goto yydefault; 1322 goto yydefault;
1366 1323
1367 /* Not known => get a look-ahead token if don't already have one. */ 1324 /* Not known => get a lookahead token if don't already have one. */
1368 1325
1369 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ 1326 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1370 if (yychar == YYEMPTY) 1327 if (yychar == YYEMPTY)
1371 { 1328 {
1372 YYDPRINTF ((stderr, "Reading a token: ")); 1329 YYDPRINTF ((stderr, "Reading a token: "));
@@ -1398,24 +1355,20 @@ yybackup:
1398 goto yyreduce; 1355 goto yyreduce;
1399 } 1356 }
1400 1357
1401 if (yyn == YYFINAL)
1402 YYACCEPT;
1403
1404 /* Count tokens shifted since error; after three, turn off error 1358 /* Count tokens shifted since error; after three, turn off error
1405 status. */ 1359 status. */
1406 if (yyerrstatus) 1360 if (yyerrstatus)
1407 yyerrstatus--; 1361 yyerrstatus--;
1408 1362
1409 /* Shift the look-ahead token. */ 1363 /* Shift the lookahead token. */
1410 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); 1364 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1411 1365
1412 /* Discard the shifted token unless it is eof. */ 1366 /* Discard the shifted token. */
1413 if (yychar != YYEOF) 1367 yychar = YYEMPTY;
1414 yychar = YYEMPTY;
1415 1368
1416 yystate = yyn; 1369 yystate = yyn;
1417 *++yyvsp = yylval; 1370 *++yyvsp = yylval;
1418 *++yylsp = yylloc; 1371
1419 goto yynewstate; 1372 goto yynewstate;
1420 1373
1421 1374
@@ -1446,337 +1399,387 @@ yyreduce:
1446 GCC warning that YYVAL may be used uninitialized. */ 1399 GCC warning that YYVAL may be used uninitialized. */
1447 yyval = yyvsp[1-yylen]; 1400 yyval = yyvsp[1-yylen];
1448 1401
1449 /* Default location. */ 1402
1450 YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
1451 YY_REDUCE_PRINT (yyn); 1403 YY_REDUCE_PRINT (yyn);
1452 switch (yyn) 1404 switch (yyn)
1453 { 1405 {
1454 case 2: 1406 case 2:
1455#line 90 "dtc-parser.y" 1407
1408/* Line 1455 of yacc.c */
1409#line 87 "dtc-parser.y"
1456 { 1410 {
1457 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0); 1411 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node),
1412 guess_boot_cpuid((yyvsp[(4) - (4)].node)));
1458 ;} 1413 ;}
1459 break; 1414 break;
1460 1415
1461 case 3: 1416 case 3:
1462#line 94 "dtc-parser.y" 1417
1418/* Line 1455 of yacc.c */
1419#line 95 "dtc-parser.y"
1463 { 1420 {
1464 the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0); 1421 (yyval.re) = NULL;
1465 ;} 1422 ;}
1466 break; 1423 break;
1467 1424
1468 case 4: 1425 case 4:
1469#line 101 "dtc-parser.y" 1426
1427/* Line 1455 of yacc.c */
1428#line 99 "dtc-parser.y"
1470 { 1429 {
1471 (yyval.re) = NULL; 1430 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1472 ;} 1431 ;}
1473 break; 1432 break;
1474 1433
1475 case 5: 1434 case 5:
1476#line 105 "dtc-parser.y" 1435
1436/* Line 1455 of yacc.c */
1437#line 106 "dtc-parser.y"
1477 { 1438 {
1478 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); 1439 (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].addr), (yyvsp[(3) - (4)].addr));
1479 ;} 1440 ;}
1480 break; 1441 break;
1481 1442
1482 case 6: 1443 case 6:
1483#line 112 "dtc-parser.y" 1444
1445/* Line 1455 of yacc.c */
1446#line 110 "dtc-parser.y"
1484 { 1447 {
1485 (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref)); 1448 add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref));
1449 (yyval.re) = (yyvsp[(2) - (2)].re);
1486 ;} 1450 ;}
1487 break; 1451 break;
1488 1452
1489 case 7: 1453 case 7:
1490#line 119 "dtc-parser.y" 1454
1455/* Line 1455 of yacc.c */
1456#line 118 "dtc-parser.y"
1491 { 1457 {
1492 (yyval.re) = NULL; 1458 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
1493 ;} 1459 ;}
1494 break; 1460 break;
1495 1461
1496 case 8: 1462 case 8:
1497#line 123 "dtc-parser.y" 1463
1464/* Line 1455 of yacc.c */
1465#line 125 "dtc-parser.y"
1498 { 1466 {
1499 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); 1467 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "");
1500 ;} 1468 ;}
1501 break; 1469 break;
1502 1470
1503 case 9: 1471 case 9:
1504#line 130 "dtc-parser.y" 1472
1473/* Line 1455 of yacc.c */
1474#line 129 "dtc-parser.y"
1505 { 1475 {
1506 (yyval.re) = (yyvsp[(1) - (1)].re); 1476 (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
1507 ;} 1477 ;}
1508 break; 1478 break;
1509 1479
1510 case 10: 1480 case 10:
1511#line 134 "dtc-parser.y" 1481
1482/* Line 1455 of yacc.c */
1483#line 133 "dtc-parser.y"
1512 { 1484 {
1513 (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref)); 1485 struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref));
1486
1487 if (target)
1488 merge_nodes(target, (yyvsp[(3) - (3)].node));
1489 else
1490 print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref));
1491 (yyval.node) = (yyvsp[(1) - (3)].node);
1514 ;} 1492 ;}
1515 break; 1493 break;
1516 1494
1517 case 11: 1495 case 11:
1518#line 141 "dtc-parser.y" 1496
1497/* Line 1455 of yacc.c */
1498#line 146 "dtc-parser.y"
1519 { 1499 {
1520 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); 1500 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
1521 ;} 1501 ;}
1522 break; 1502 break;
1523 1503
1524 case 12: 1504 case 12:
1525#line 145 "dtc-parser.y" 1505
1506/* Line 1455 of yacc.c */
1507#line 153 "dtc-parser.y"
1526 { 1508 {
1527 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64); 1509 (yyval.proplist) = NULL;
1528 ;} 1510 ;}
1529 break; 1511 break;
1530 1512
1531 case 13: 1513 case 13:
1532#line 152 "dtc-parser.y" 1514
1515/* Line 1455 of yacc.c */
1516#line 157 "dtc-parser.y"
1533 { 1517 {
1534 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL); 1518 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
1535 ;} 1519 ;}
1536 break; 1520 break;
1537 1521
1538 case 14: 1522 case 14:
1539#line 159 "dtc-parser.y" 1523
1524/* Line 1455 of yacc.c */
1525#line 164 "dtc-parser.y"
1540 { 1526 {
1541 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); 1527 (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data));
1542 ;} 1528 ;}
1543 break; 1529 break;
1544 1530
1545 case 15: 1531 case 15:
1546#line 166 "dtc-parser.y" 1532
1533/* Line 1455 of yacc.c */
1534#line 168 "dtc-parser.y"
1547 { 1535 {
1548 (yyval.proplist) = NULL; 1536 (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data);
1549 ;} 1537 ;}
1550 break; 1538 break;
1551 1539
1552 case 16: 1540 case 16:
1553#line 170 "dtc-parser.y" 1541
1542/* Line 1455 of yacc.c */
1543#line 172 "dtc-parser.y"
1554 { 1544 {
1555 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); 1545 add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref));
1546 (yyval.prop) = (yyvsp[(2) - (2)].prop);
1556 ;} 1547 ;}
1557 break; 1548 break;
1558 1549
1559 case 17: 1550 case 17:
1560#line 177 "dtc-parser.y" 1551
1552/* Line 1455 of yacc.c */
1553#line 180 "dtc-parser.y"
1561 { 1554 {
1562 (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref)); 1555 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
1563 ;} 1556 ;}
1564 break; 1557 break;
1565 1558
1566 case 18: 1559 case 18:
1567#line 181 "dtc-parser.y" 1560
1561/* Line 1455 of yacc.c */
1562#line 184 "dtc-parser.y"
1568 { 1563 {
1569 (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref)); 1564 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1570 ;} 1565 ;}
1571 break; 1566 break;
1572 1567
1573 case 19: 1568 case 19:
1569
1570/* Line 1455 of yacc.c */
1574#line 188 "dtc-parser.y" 1571#line 188 "dtc-parser.y"
1575 { 1572 {
1576 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); 1573 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1577 ;} 1574 ;}
1578 break; 1575 break;
1579 1576
1580 case 20: 1577 case 20:
1578
1579/* Line 1455 of yacc.c */
1581#line 192 "dtc-parser.y" 1580#line 192 "dtc-parser.y"
1582 { 1581 {
1583 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); 1582 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
1584 ;} 1583 ;}
1585 break; 1584 break;
1586 1585
1587 case 21: 1586 case 21:
1588#line 196 "dtc-parser.y"
1589 {
1590 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1591 ;}
1592 break;
1593
1594 case 22:
1595#line 200 "dtc-parser.y"
1596 {
1597 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
1598 ;}
1599 break;
1600 1587
1601 case 23: 1588/* Line 1455 of yacc.c */
1602#line 204 "dtc-parser.y" 1589#line 196 "dtc-parser.y"
1603 { 1590 {
1604 struct search_path path = { srcpos_file->dir, NULL, NULL }; 1591 FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL);
1605 struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path); 1592 struct data d;
1606 struct data d = empty_data;
1607 1593
1608 if ((yyvsp[(6) - (9)].addr) != 0) 1594 if ((yyvsp[(6) - (9)].addr) != 0)
1609 if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) 1595 if (fseek(f, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
1610 yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", 1596 print_error("Couldn't seek to offset %llu in \"%s\": %s",
1611 (unsigned long long)(yyvsp[(6) - (9)].addr), 1597 (unsigned long long)(yyvsp[(6) - (9)].addr),
1612 (yyvsp[(4) - (9)].data).val, strerror(errno)); 1598 (yyvsp[(4) - (9)].data).val,
1599 strerror(errno));
1613 1600
1614 d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr)); 1601 d = data_copy_file(f, (yyvsp[(8) - (9)].addr));
1615 1602
1616 (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); 1603 (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
1617 dtc_close_file(file); 1604 fclose(f);
1618 ;} 1605 ;}
1619 break; 1606 break;
1620 1607
1621 case 24: 1608 case 22:
1622#line 221 "dtc-parser.y" 1609
1610/* Line 1455 of yacc.c */
1611#line 213 "dtc-parser.y"
1623 { 1612 {
1624 struct search_path path = { srcpos_file->dir, NULL, NULL }; 1613 FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL);
1625 struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path);
1626 struct data d = empty_data; 1614 struct data d = empty_data;
1627 1615
1628 d = data_copy_file(file->file, -1); 1616 d = data_copy_file(f, -1);
1629 1617
1630 (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); 1618 (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d);
1631 dtc_close_file(file); 1619 fclose(f);
1632 ;} 1620 ;}
1633 break; 1621 break;
1634 1622
1635 case 25: 1623 case 23:
1636#line 232 "dtc-parser.y" 1624
1625/* Line 1455 of yacc.c */
1626#line 223 "dtc-parser.y"
1637 { 1627 {
1638 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1628 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1639 ;} 1629 ;}
1640 break; 1630 break;
1641 1631
1642 case 26: 1632 case 24:
1643#line 239 "dtc-parser.y" 1633
1634/* Line 1455 of yacc.c */
1635#line 230 "dtc-parser.y"
1644 { 1636 {
1645 (yyval.data) = empty_data; 1637 (yyval.data) = empty_data;
1646 ;} 1638 ;}
1647 break; 1639 break;
1648 1640
1649 case 27: 1641 case 25:
1650#line 243 "dtc-parser.y" 1642
1643/* Line 1455 of yacc.c */
1644#line 234 "dtc-parser.y"
1651 { 1645 {
1652 (yyval.data) = (yyvsp[(1) - (2)].data); 1646 (yyval.data) = (yyvsp[(1) - (2)].data);
1653 ;} 1647 ;}
1654 break; 1648 break;
1655 1649
1656 case 28: 1650 case 26:
1657#line 247 "dtc-parser.y" 1651
1652/* Line 1455 of yacc.c */
1653#line 238 "dtc-parser.y"
1658 { 1654 {
1659 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1655 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1660 ;} 1656 ;}
1661 break; 1657 break;
1662 1658
1663 case 29: 1659 case 27:
1664#line 254 "dtc-parser.y" 1660
1661/* Line 1455 of yacc.c */
1662#line 245 "dtc-parser.y"
1665 { 1663 {
1666 (yyval.data) = empty_data; 1664 (yyval.data) = empty_data;
1667 ;} 1665 ;}
1668 break; 1666 break;
1669 1667
1670 case 30: 1668 case 28:
1671#line 258 "dtc-parser.y" 1669
1670/* Line 1455 of yacc.c */
1671#line 249 "dtc-parser.y"
1672 { 1672 {
1673 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); 1673 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
1674 ;} 1674 ;}
1675 break; 1675 break;
1676 1676
1677 case 31: 1677 case 29:
1678#line 262 "dtc-parser.y" 1678
1679/* Line 1455 of yacc.c */
1680#line 253 "dtc-parser.y"
1679 { 1681 {
1680 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, 1682 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
1681 (yyvsp[(2) - (2)].labelref)), -1); 1683 (yyvsp[(2) - (2)].labelref)), -1);
1682 ;} 1684 ;}
1683 break; 1685 break;
1684 1686
1685 case 32: 1687 case 30:
1686#line 267 "dtc-parser.y" 1688
1689/* Line 1455 of yacc.c */
1690#line 258 "dtc-parser.y"
1687 { 1691 {
1688 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1692 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1689 ;} 1693 ;}
1690 break; 1694 break;
1691 1695
1692 case 33: 1696 case 31:
1693#line 274 "dtc-parser.y"
1694 {
1695 (yyval.cbase) = 16;
1696 ;}
1697 break;
1698 1697
1699 case 35: 1698/* Line 1455 of yacc.c */
1700#line 282 "dtc-parser.y" 1699#line 265 "dtc-parser.y"
1701 { 1700 {
1702 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); 1701 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
1703 ;} 1702 ;}
1704 break; 1703 break;
1705 1704
1706 case 36: 1705 case 32:
1707#line 286 "dtc-parser.y"
1708 {
1709 (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
1710 ;}
1711 break;
1712 1706
1713 case 37: 1707/* Line 1455 of yacc.c */
1714#line 293 "dtc-parser.y" 1708#line 272 "dtc-parser.y"
1715 { 1709 {
1716 (yyval.data) = empty_data; 1710 (yyval.data) = empty_data;
1717 ;} 1711 ;}
1718 break; 1712 break;
1719 1713
1720 case 38: 1714 case 33:
1721#line 297 "dtc-parser.y" 1715
1716/* Line 1455 of yacc.c */
1717#line 276 "dtc-parser.y"
1722 { 1718 {
1723 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); 1719 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
1724 ;} 1720 ;}
1725 break; 1721 break;
1726 1722
1727 case 39: 1723 case 34:
1728#line 301 "dtc-parser.y" 1724
1725/* Line 1455 of yacc.c */
1726#line 280 "dtc-parser.y"
1729 { 1727 {
1730 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1728 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1731 ;} 1729 ;}
1732 break; 1730 break;
1733 1731
1734 case 40: 1732 case 35:
1735#line 308 "dtc-parser.y" 1733
1734/* Line 1455 of yacc.c */
1735#line 287 "dtc-parser.y"
1736 { 1736 {
1737 (yyval.nodelist) = NULL; 1737 (yyval.nodelist) = NULL;
1738 ;} 1738 ;}
1739 break; 1739 break;
1740 1740
1741 case 41: 1741 case 36:
1742#line 312 "dtc-parser.y" 1742
1743/* Line 1455 of yacc.c */
1744#line 291 "dtc-parser.y"
1743 { 1745 {
1744 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); 1746 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
1745 ;} 1747 ;}
1746 break; 1748 break;
1747 1749
1748 case 42: 1750 case 37:
1749#line 316 "dtc-parser.y" 1751
1752/* Line 1455 of yacc.c */
1753#line 295 "dtc-parser.y"
1750 { 1754 {
1751 yyerror("syntax error: properties must precede subnodes"); 1755 print_error("syntax error: properties must precede subnodes");
1752 YYERROR; 1756 YYERROR;
1753 ;} 1757 ;}
1754 break; 1758 break;
1755 1759
1756 case 43: 1760 case 38:
1757#line 324 "dtc-parser.y"
1758 {
1759 (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
1760 ;}
1761 break;
1762 1761
1763 case 44: 1762/* Line 1455 of yacc.c */
1764#line 331 "dtc-parser.y" 1763#line 303 "dtc-parser.y"
1765 { 1764 {
1766 (yyval.labelref) = NULL; 1765 (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename));
1767 ;} 1766 ;}
1768 break; 1767 break;
1769 1768
1770 case 45: 1769 case 39:
1771#line 335 "dtc-parser.y" 1770
1771/* Line 1455 of yacc.c */
1772#line 307 "dtc-parser.y"
1772 { 1773 {
1773 (yyval.labelref) = (yyvsp[(1) - (1)].labelref); 1774 add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref));
1775 (yyval.node) = (yyvsp[(2) - (2)].node);
1774 ;} 1776 ;}
1775 break; 1777 break;
1776 1778
1777 1779
1778/* Line 1267 of yacc.c. */ 1780
1779#line 1780 "dtc-parser.tab.c" 1781/* Line 1455 of yacc.c */
1782#line 1783 "dtc-parser.tab.c"
1780 default: break; 1783 default: break;
1781 } 1784 }
1782 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); 1785 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1786,7 +1789,6 @@ yyreduce:
1786 YY_STACK_PRINT (yyss, yyssp); 1789 YY_STACK_PRINT (yyss, yyssp);
1787 1790
1788 *++yyvsp = yyval; 1791 *++yyvsp = yyval;
1789 *++yylsp = yyloc;
1790 1792
1791 /* Now `shift' the result of the reduction. Determine what state 1793 /* Now `shift' the result of the reduction. Determine what state
1792 that goes to, based on the state we popped back to and the rule 1794 that goes to, based on the state we popped back to and the rule
@@ -1848,11 +1850,11 @@ yyerrlab:
1848#endif 1850#endif
1849 } 1851 }
1850 1852
1851 yyerror_range[0] = yylloc; 1853
1852 1854
1853 if (yyerrstatus == 3) 1855 if (yyerrstatus == 3)
1854 { 1856 {
1855 /* If just tried and failed to reuse look-ahead token after an 1857 /* If just tried and failed to reuse lookahead token after an
1856 error, discard it. */ 1858 error, discard it. */
1857 1859
1858 if (yychar <= YYEOF) 1860 if (yychar <= YYEOF)
@@ -1864,12 +1866,12 @@ yyerrlab:
1864 else 1866 else
1865 { 1867 {
1866 yydestruct ("Error: discarding", 1868 yydestruct ("Error: discarding",
1867 yytoken, &yylval, &yylloc); 1869 yytoken, &yylval);
1868 yychar = YYEMPTY; 1870 yychar = YYEMPTY;
1869 } 1871 }
1870 } 1872 }
1871 1873
1872 /* Else will try to reuse look-ahead token after shifting the error 1874 /* Else will try to reuse lookahead token after shifting the error
1873 token. */ 1875 token. */
1874 goto yyerrlab1; 1876 goto yyerrlab1;
1875 1877
@@ -1885,7 +1887,6 @@ yyerrorlab:
1885 if (/*CONSTCOND*/ 0) 1887 if (/*CONSTCOND*/ 0)
1886 goto yyerrorlab; 1888 goto yyerrorlab;
1887 1889
1888 yyerror_range[0] = yylsp[1-yylen];
1889 /* Do not reclaim the symbols of the rule which action triggered 1890 /* Do not reclaim the symbols of the rule which action triggered
1890 this YYERROR. */ 1891 this YYERROR. */
1891 YYPOPSTACK (yylen); 1892 YYPOPSTACK (yylen);
@@ -1919,24 +1920,16 @@ yyerrlab1:
1919 if (yyssp == yyss) 1920 if (yyssp == yyss)
1920 YYABORT; 1921 YYABORT;
1921 1922
1922 yyerror_range[0] = *yylsp; 1923
1923 yydestruct ("Error: popping", 1924 yydestruct ("Error: popping",
1924 yystos[yystate], yyvsp, yylsp); 1925 yystos[yystate], yyvsp);
1925 YYPOPSTACK (1); 1926 YYPOPSTACK (1);
1926 yystate = *yyssp; 1927 yystate = *yyssp;
1927 YY_STACK_PRINT (yyss, yyssp); 1928 YY_STACK_PRINT (yyss, yyssp);
1928 } 1929 }
1929 1930
1930 if (yyn == YYFINAL)
1931 YYACCEPT;
1932
1933 *++yyvsp = yylval; 1931 *++yyvsp = yylval;
1934 1932
1935 yyerror_range[1] = yylloc;
1936 /* Using YYLLOC is tempting, but would change the location of
1937 the look-ahead. YYLOC is available though. */
1938 YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
1939 *++yylsp = yyloc;
1940 1933
1941 /* Shift the error token. */ 1934 /* Shift the error token. */
1942 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); 1935 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
@@ -1959,7 +1952,7 @@ yyabortlab:
1959 yyresult = 1; 1952 yyresult = 1;
1960 goto yyreturn; 1953 goto yyreturn;
1961 1954
1962#ifndef yyoverflow 1955#if !defined(yyoverflow) || YYERROR_VERBOSE
1963/*-------------------------------------------------. 1956/*-------------------------------------------------.
1964| yyexhaustedlab -- memory exhaustion comes here. | 1957| yyexhaustedlab -- memory exhaustion comes here. |
1965`-------------------------------------------------*/ 1958`-------------------------------------------------*/
@@ -1970,9 +1963,9 @@ yyexhaustedlab:
1970#endif 1963#endif
1971 1964
1972yyreturn: 1965yyreturn:
1973 if (yychar != YYEOF && yychar != YYEMPTY) 1966 if (yychar != YYEMPTY)
1974 yydestruct ("Cleanup: discarding lookahead", 1967 yydestruct ("Cleanup: discarding lookahead",
1975 yytoken, &yylval, &yylloc); 1968 yytoken, &yylval);
1976 /* Do not reclaim the symbols of the rule which action triggered 1969 /* Do not reclaim the symbols of the rule which action triggered
1977 this YYABORT or YYACCEPT. */ 1970 this YYABORT or YYACCEPT. */
1978 YYPOPSTACK (yylen); 1971 YYPOPSTACK (yylen);
@@ -1980,7 +1973,7 @@ yyreturn:
1980 while (yyssp != yyss) 1973 while (yyssp != yyss)
1981 { 1974 {
1982 yydestruct ("Cleanup: popping", 1975 yydestruct ("Cleanup: popping",
1983 yystos[*yyssp], yyvsp, yylsp); 1976 yystos[*yyssp], yyvsp);
1984 YYPOPSTACK (1); 1977 YYPOPSTACK (1);
1985 } 1978 }
1986#ifndef yyoverflow 1979#ifndef yyoverflow
@@ -1996,29 +1989,24 @@ yyreturn:
1996} 1989}
1997 1990
1998 1991
1999#line 340 "dtc-parser.y" 1992
1993/* Line 1675 of yacc.c */
1994#line 313 "dtc-parser.y"
2000 1995
2001 1996
2002void yyerrorf(char const *s, ...) 1997void print_error(char const *fmt, ...)
2003{ 1998{
2004 const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
2005 va_list va; 1999 va_list va;
2006 va_start(va, s);
2007
2008 if (strcmp(fname, "-") == 0)
2009 fname = "stdin";
2010 2000
2011 fprintf(stderr, "%s:%d ", fname, yylloc.first_line); 2001 va_start(va, fmt);
2012 vfprintf(stderr, s, va); 2002 srcpos_verror(&yylloc, fmt, va);
2013 fprintf(stderr, "\n"); 2003 va_end(va);
2014 2004
2015 treesource_error = 1; 2005 treesource_error = 1;
2016 va_end(va);
2017} 2006}
2018 2007
2019void yyerror (char const *s) 2008void yyerror(char const *s) {
2020{ 2009 print_error("%s", s);
2021 yyerrorf("%s", s);
2022} 2010}
2023 2011
2024static unsigned long long eval_literal(const char *s, int base, int bits) 2012static unsigned long long eval_literal(const char *s, int base, int bits)
@@ -2029,12 +2017,12 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
2029 errno = 0; 2017 errno = 0;
2030 val = strtoull(s, &e, base); 2018 val = strtoull(s, &e, base);
2031 if (*e) 2019 if (*e)
2032 yyerror("bad characters in literal"); 2020 print_error("bad characters in literal");
2033 else if ((errno == ERANGE) 2021 else if ((errno == ERANGE)
2034 || ((bits < 64) && (val >= (1ULL << bits)))) 2022 || ((bits < 64) && (val >= (1ULL << bits))))
2035 yyerror("literal out of range"); 2023 print_error("literal out of range");
2036 else if (errno != 0) 2024 else if (errno != 0)
2037 yyerror("bad literal"); 2025 print_error("bad literal");
2038 return val; 2026 return val;
2039} 2027}
2040 2028
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
index ba99100d55c9..95c9547adea5 100644
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ b/scripts/dtc/dtc-parser.tab.h_shipped
@@ -1,24 +1,23 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2 1
3/* Skeleton interface for Bison's Yacc-like parsers in C 2/* A Bison parser, made by GNU Bison 2.4.1. */
4 3
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4/* Skeleton interface for Bison's Yacc-like parsers in C
5
6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc. 7 Free Software Foundation, Inc.
7 8
8 This program is free software; you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option) 11 the Free Software Foundation, either version 3 of the License, or
11 any later version. 12 (at your option) any later version.
12 13
13 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 17 GNU General Public License for more details.
17 18
18 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22 21
23/* As a special exception, you may create a larger work that contains 22/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work 23 part or all of the Bison parser skeleton and distribute that work
@@ -29,10 +28,11 @@
29 special exception, which will cause the skeleton and the resulting 28 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public 29 Bison output files to be licensed under the GNU General Public
31 License without this special exception. 30 License without this special exception.
32 31
33 This special exception was added by the Free Software Foundation in 32 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */ 33 version 2.2 of Bison. */
35 34
35
36/* Tokens. */ 36/* Tokens. */
37#ifndef YYTOKENTYPE 37#ifndef YYTOKENTYPE
38# define YYTOKENTYPE 38# define YYTOKENTYPE
@@ -43,35 +43,24 @@
43 DT_MEMRESERVE = 259, 43 DT_MEMRESERVE = 259,
44 DT_PROPNODENAME = 260, 44 DT_PROPNODENAME = 260,
45 DT_LITERAL = 261, 45 DT_LITERAL = 261,
46 DT_LEGACYLITERAL = 262, 46 DT_BASE = 262,
47 DT_BASE = 263, 47 DT_BYTE = 263,
48 DT_BYTE = 264, 48 DT_STRING = 264,
49 DT_STRING = 265, 49 DT_LABEL = 265,
50 DT_LABEL = 266, 50 DT_REF = 266,
51 DT_REF = 267, 51 DT_INCBIN = 267
52 DT_INCBIN = 268
53 }; 52 };
54#endif 53#endif
55/* Tokens. */
56#define DT_V1 258
57#define DT_MEMRESERVE 259
58#define DT_PROPNODENAME 260
59#define DT_LITERAL 261
60#define DT_LEGACYLITERAL 262
61#define DT_BASE 263
62#define DT_BYTE 264
63#define DT_STRING 265
64#define DT_LABEL 266
65#define DT_REF 267
66#define DT_INCBIN 268
67
68 54
69 55
70 56
71#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 57#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
72typedef union YYSTYPE 58typedef union YYSTYPE
73#line 37 "dtc-parser.y"
74{ 59{
60
61/* Line 1676 of yacc.c */
62#line 39 "dtc-parser.y"
63
75 char *propnodename; 64 char *propnodename;
76 char *literal; 65 char *literal;
77 char *labelref; 66 char *labelref;
@@ -86,28 +75,17 @@ typedef union YYSTYPE
86 struct node *node; 75 struct node *node;
87 struct node *nodelist; 76 struct node *nodelist;
88 struct reserve_info *re; 77 struct reserve_info *re;
89} 78
90/* Line 1489 of yacc.c. */ 79
91#line 92 "dtc-parser.tab.h" 80
92 YYSTYPE; 81/* Line 1676 of yacc.c */
82#line 83 "dtc-parser.tab.h"
83} YYSTYPE;
84# define YYSTYPE_IS_TRIVIAL 1
93# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 85# define yystype YYSTYPE /* obsolescent; will be withdrawn */
94# define YYSTYPE_IS_DECLARED 1 86# define YYSTYPE_IS_DECLARED 1
95# define YYSTYPE_IS_TRIVIAL 1
96#endif 87#endif
97 88
98extern YYSTYPE yylval; 89extern YYSTYPE yylval;
99 90
100#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
101typedef struct YYLTYPE
102{
103 int first_line;
104 int first_column;
105 int last_line;
106 int last_column;
107} YYLTYPE;
108# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
109# define YYLTYPE_IS_DECLARED 1
110# define YYLTYPE_IS_TRIVIAL 1
111#endif
112 91
113extern YYLTYPE yylloc;
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index b2ab562420ea..5e84a67fc1d2 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -18,15 +18,17 @@
18 * USA 18 * USA
19 */ 19 */
20 20
21%locations
22
23%{ 21%{
24#include <stdio.h> 22#include <stdio.h>
25 23
26#include "dtc.h" 24#include "dtc.h"
27#include "srcpos.h" 25#include "srcpos.h"
28 26
27YYLTYPE yylloc;
28
29extern int yylex(void); 29extern int yylex(void);
30extern void print_error(char const *fmt, ...);
31extern void yyerror(char const *s);
30 32
31extern struct boot_info *the_boot_info; 33extern struct boot_info *the_boot_info;
32extern int treesource_error; 34extern int treesource_error;
@@ -55,7 +57,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
55%token DT_MEMRESERVE 57%token DT_MEMRESERVE
56%token <propnodename> DT_PROPNODENAME 58%token <propnodename> DT_PROPNODENAME
57%token <literal> DT_LITERAL 59%token <literal> DT_LITERAL
58%token <literal> DT_LEGACYLITERAL
59%token <cbase> DT_BASE 60%token <cbase> DT_BASE
60%token <byte> DT_BYTE 61%token <byte> DT_BYTE
61%token <data> DT_STRING 62%token <data> DT_STRING
@@ -67,11 +68,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
67%type <data> propdataprefix 68%type <data> propdataprefix
68%type <re> memreserve 69%type <re> memreserve
69%type <re> memreserves 70%type <re> memreserves
70%type <re> v0_memreserve
71%type <re> v0_memreserves
72%type <addr> addr 71%type <addr> addr
73%type <data> celllist 72%type <data> celllist
74%type <cbase> cellbase
75%type <cell> cellval 73%type <cell> cellval
76%type <data> bytestring 74%type <data> bytestring
77%type <prop> propdef 75%type <prop> propdef
@@ -81,18 +79,14 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
81%type <node> nodedef 79%type <node> nodedef
82%type <node> subnode 80%type <node> subnode
83%type <nodelist> subnodes 81%type <nodelist> subnodes
84%type <labelref> label
85 82
86%% 83%%
87 84
88sourcefile: 85sourcefile:
89 DT_V1 ';' memreserves devicetree 86 DT_V1 ';' memreserves devicetree
90 { 87 {
91 the_boot_info = build_boot_info($3, $4, 0); 88 the_boot_info = build_boot_info($3, $4,
92 } 89 guess_boot_cpuid($4));
93 | v0_memreserves devicetree
94 {
95 the_boot_info = build_boot_info($1, $2, 0);
96 } 90 }
97 ; 91 ;
98 92
@@ -108,31 +102,14 @@ memreserves:
108 ; 102 ;
109 103
110memreserve: 104memreserve:
111 label DT_MEMRESERVE addr addr ';' 105 DT_MEMRESERVE addr addr ';'
112 { 106 {
113 $$ = build_reserve_entry($3, $4, $1); 107 $$ = build_reserve_entry($2, $3);
114 } 108 }
115 ; 109 | DT_LABEL memreserve
116
117v0_memreserves:
118 /* empty */
119 { 110 {
120 $$ = NULL; 111 add_label(&$2->labels, $1);
121 } 112 $$ = $2;
122 | v0_memreserve v0_memreserves
123 {
124 $$ = chain_reserve_entry($1, $2);
125 };
126 ;
127
128v0_memreserve:
129 memreserve
130 {
131 $$ = $1;
132 }
133 | label DT_MEMRESERVE addr '-' addr ';'
134 {
135 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
136 } 113 }
137 ; 114 ;
138 115
@@ -141,16 +118,26 @@ addr:
141 { 118 {
142 $$ = eval_literal($1, 0, 64); 119 $$ = eval_literal($1, 0, 64);
143 } 120 }
144 | DT_LEGACYLITERAL
145 {
146 $$ = eval_literal($1, 16, 64);
147 }
148 ; 121 ;
149 122
150devicetree: 123devicetree:
151 '/' nodedef 124 '/' nodedef
152 { 125 {
153 $$ = name_node($2, "", NULL); 126 $$ = name_node($2, "");
127 }
128 | devicetree '/' nodedef
129 {
130 $$ = merge_nodes($1, $3);
131 }
132 | devicetree DT_REF nodedef
133 {
134 struct node *target = get_node_by_ref($1, $2);
135
136 if (target)
137 merge_nodes(target, $3);
138 else
139 print_error("label or path, '%s', not found", $2);
140 $$ = $1;
154 } 141 }
155 ; 142 ;
156 143
@@ -173,13 +160,18 @@ proplist:
173 ; 160 ;
174 161
175propdef: 162propdef:
176 label DT_PROPNODENAME '=' propdata ';' 163 DT_PROPNODENAME '=' propdata ';'
164 {
165 $$ = build_property($1, $3);
166 }
167 | DT_PROPNODENAME ';'
177 { 168 {
178 $$ = build_property($2, $4, $1); 169 $$ = build_property($1, empty_data);
179 } 170 }
180 | label DT_PROPNODENAME ';' 171 | DT_LABEL propdef
181 { 172 {
182 $$ = build_property($2, empty_data, $1); 173 add_label(&$2->labels, $1);
174 $$ = $2;
183 } 175 }
184 ; 176 ;
185 177
@@ -202,31 +194,30 @@ propdata:
202 } 194 }
203 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' 195 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
204 { 196 {
205 struct search_path path = { srcpos_file->dir, NULL, NULL }; 197 FILE *f = srcfile_relative_open($4.val, NULL);
206 struct dtc_file *file = dtc_open_file($4.val, &path); 198 struct data d;
207 struct data d = empty_data;
208 199
209 if ($6 != 0) 200 if ($6 != 0)
210 if (fseek(file->file, $6, SEEK_SET) != 0) 201 if (fseek(f, $6, SEEK_SET) != 0)
211 yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", 202 print_error("Couldn't seek to offset %llu in \"%s\": %s",
212 (unsigned long long)$6, 203 (unsigned long long)$6,
213 $4.val, strerror(errno)); 204 $4.val,
205 strerror(errno));
214 206
215 d = data_copy_file(file->file, $8); 207 d = data_copy_file(f, $8);
216 208
217 $$ = data_merge($1, d); 209 $$ = data_merge($1, d);
218 dtc_close_file(file); 210 fclose(f);
219 } 211 }
220 | propdataprefix DT_INCBIN '(' DT_STRING ')' 212 | propdataprefix DT_INCBIN '(' DT_STRING ')'
221 { 213 {
222 struct search_path path = { srcpos_file->dir, NULL, NULL }; 214 FILE *f = srcfile_relative_open($4.val, NULL);
223 struct dtc_file *file = dtc_open_file($4.val, &path);
224 struct data d = empty_data; 215 struct data d = empty_data;
225 216
226 d = data_copy_file(file->file, -1); 217 d = data_copy_file(f, -1);
227 218
228 $$ = data_merge($1, d); 219 $$ = data_merge($1, d);
229 dtc_close_file(file); 220 fclose(f);
230 } 221 }
231 | propdata DT_LABEL 222 | propdata DT_LABEL
232 { 223 {
@@ -269,23 +260,11 @@ celllist:
269 } 260 }
270 ; 261 ;
271 262
272cellbase:
273 /* empty */
274 {
275 $$ = 16;
276 }
277 | DT_BASE
278 ;
279
280cellval: 263cellval:
281 DT_LITERAL 264 DT_LITERAL
282 { 265 {
283 $$ = eval_literal($1, 0, 32); 266 $$ = eval_literal($1, 0, 32);
284 } 267 }
285 | cellbase DT_LEGACYLITERAL
286 {
287 $$ = eval_literal($2, $1, 32);
288 }
289 ; 268 ;
290 269
291bytestring: 270bytestring:
@@ -308,57 +287,44 @@ subnodes:
308 { 287 {
309 $$ = NULL; 288 $$ = NULL;
310 } 289 }
311 | subnode subnodes 290 | subnode subnodes
312 { 291 {
313 $$ = chain_node($1, $2); 292 $$ = chain_node($1, $2);
314 } 293 }
315 | subnode propdef 294 | subnode propdef
316 { 295 {
317 yyerror("syntax error: properties must precede subnodes"); 296 print_error("syntax error: properties must precede subnodes");
318 YYERROR; 297 YYERROR;
319 } 298 }
320 ; 299 ;
321 300
322subnode: 301subnode:
323 label DT_PROPNODENAME nodedef 302 DT_PROPNODENAME nodedef
324 { 303 {
325 $$ = name_node($3, $2, $1); 304 $$ = name_node($2, $1);
326 } 305 }
327 ; 306 | DT_LABEL subnode
328
329label:
330 /* empty */
331 { 307 {
332 $$ = NULL; 308 add_label(&$2->labels, $1);
333 } 309 $$ = $2;
334 | DT_LABEL
335 {
336 $$ = $1;
337 } 310 }
338 ; 311 ;
339 312
340%% 313%%
341 314
342void yyerrorf(char const *s, ...) 315void print_error(char const *fmt, ...)
343{ 316{
344 const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
345 va_list va; 317 va_list va;
346 va_start(va, s);
347
348 if (strcmp(fname, "-") == 0)
349 fname = "stdin";
350 318
351 fprintf(stderr, "%s:%d ", fname, yylloc.first_line); 319 va_start(va, fmt);
352 vfprintf(stderr, s, va); 320 srcpos_verror(&yylloc, fmt, va);
353 fprintf(stderr, "\n"); 321 va_end(va);
354 322
355 treesource_error = 1; 323 treesource_error = 1;
356 va_end(va);
357} 324}
358 325
359void yyerror (char const *s) 326void yyerror(char const *s) {
360{ 327 print_error("%s", s);
361 yyerrorf("%s", s);
362} 328}
363 329
364static unsigned long long eval_literal(const char *s, int base, int bits) 330static unsigned long long eval_literal(const char *s, int base, int bits)
@@ -369,11 +335,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
369 errno = 0; 335 errno = 0;
370 val = strtoull(s, &e, base); 336 val = strtoull(s, &e, base);
371 if (*e) 337 if (*e)
372 yyerror("bad characters in literal"); 338 print_error("bad characters in literal");
373 else if ((errno == ERANGE) 339 else if ((errno == ERANGE)
374 || ((bits < 64) && (val >= (1ULL << bits)))) 340 || ((bits < 64) && (val >= (1ULL << bits))))
375 yyerror("literal out of range"); 341 print_error("literal out of range");
376 else if (errno != 0) 342 else if (errno != 0)
377 yyerror("bad literal"); 343 print_error("bad literal");
378 return val; 344 return val;
379} 345}
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index d8fd43b4ac1a..cbc0193098e4 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -30,30 +30,7 @@ int quiet; /* Level of quietness */
30int reservenum; /* Number of memory reservation slots */ 30int reservenum; /* Number of memory reservation slots */
31int minsize; /* Minimum blob size */ 31int minsize; /* Minimum blob size */
32int padsize; /* Additional padding to blob */ 32int padsize; /* Additional padding to blob */
33 33int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
34char *join_path(const char *path, const char *name)
35{
36 int lenp = strlen(path);
37 int lenn = strlen(name);
38 int len;
39 int needslash = 1;
40 char *str;
41
42 len = lenp + lenn + 2;
43 if ((lenp > 0) && (path[lenp-1] == '/')) {
44 needslash = 0;
45 len--;
46 }
47
48 str = xmalloc(len);
49 memcpy(str, path, lenp);
50 if (needslash) {
51 str[lenp] = '/';
52 lenp++;
53 }
54 memcpy(str+lenp, name, lenn+1);
55 return str;
56}
57 34
58static void fill_fullpaths(struct node *tree, const char *prefix) 35static void fill_fullpaths(struct node *tree, const char *prefix)
59{ 36{
@@ -104,8 +81,15 @@ static void __attribute__ ((noreturn)) usage(void)
104 fprintf(stderr, "\t\tSet the physical boot cpu\n"); 81 fprintf(stderr, "\t\tSet the physical boot cpu\n");
105 fprintf(stderr, "\t-f\n"); 82 fprintf(stderr, "\t-f\n");
106 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); 83 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
84 fprintf(stderr, "\t-s\n");
85 fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n");
107 fprintf(stderr, "\t-v\n"); 86 fprintf(stderr, "\t-v\n");
108 fprintf(stderr, "\t\tPrint DTC version and exit\n"); 87 fprintf(stderr, "\t\tPrint DTC version and exit\n");
88 fprintf(stderr, "\t-H <phandle format>\n");
89 fprintf(stderr, "\t\tphandle formats are:\n");
90 fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n");
91 fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n");
92 fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n");
109 exit(3); 93 exit(3);
110} 94}
111 95
@@ -115,7 +99,7 @@ int main(int argc, char *argv[])
115 const char *inform = "dts"; 99 const char *inform = "dts";
116 const char *outform = "dts"; 100 const char *outform = "dts";
117 const char *outname = "-"; 101 const char *outname = "-";
118 int force = 0, check = 0; 102 int force = 0, check = 0, sort = 0;
119 const char *arg; 103 const char *arg;
120 int opt; 104 int opt;
121 FILE *outf = NULL; 105 FILE *outf = NULL;
@@ -127,7 +111,7 @@ int main(int argc, char *argv[])
127 minsize = 0; 111 minsize = 0;
128 padsize = 0; 112 padsize = 0;
129 113
130 while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) { 114 while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) {
131 switch (opt) { 115 switch (opt) {
132 case 'I': 116 case 'I':
133 inform = optarg; 117 inform = optarg;
@@ -165,6 +149,22 @@ int main(int argc, char *argv[])
165 case 'v': 149 case 'v':
166 printf("Version: %s\n", DTC_VERSION); 150 printf("Version: %s\n", DTC_VERSION);
167 exit(0); 151 exit(0);
152 case 'H':
153 if (streq(optarg, "legacy"))
154 phandle_format = PHANDLE_LEGACY;
155 else if (streq(optarg, "epapr"))
156 phandle_format = PHANDLE_EPAPR;
157 else if (streq(optarg, "both"))
158 phandle_format = PHANDLE_BOTH;
159 else
160 die("Invalid argument \"%s\" to -H option\n",
161 optarg);
162 break;
163
164 case 's':
165 sort = 1;
166 break;
167
168 case 'h': 168 case 'h':
169 default: 169 default:
170 usage(); 170 usage();
@@ -182,6 +182,9 @@ int main(int argc, char *argv[])
182 if (minsize && padsize) 182 if (minsize && padsize)
183 die("Can't set both -p and -S\n"); 183 die("Can't set both -p and -S\n");
184 184
185 if (minsize)
186 fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n");
187
185 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", 188 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
186 inform, outform, arg); 189 inform, outform, arg);
187 190
@@ -200,6 +203,8 @@ int main(int argc, char *argv[])
200 fill_fullpaths(bi->dt, ""); 203 fill_fullpaths(bi->dt, "");
201 process_checks(force, bi); 204 process_checks(force, bi);
202 205
206 if (sort)
207 sort_tree(bi);
203 208
204 if (streq(outname, "-")) { 209 if (streq(outname, "-")) {
205 outf = stdout; 210 outf = stdout;
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 08d54c870086..f37c97eb3dfc 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -34,7 +34,17 @@
34#include <libfdt_env.h> 34#include <libfdt_env.h>
35#include <fdt.h> 35#include <fdt.h>
36 36
37#include "util.h"
38
39#ifdef DEBUG
40#define debug(fmt,args...) printf(fmt, ##args)
41#else
42#define debug(fmt,args...)
43#endif
44
45
37#define DEFAULT_FDT_VERSION 17 46#define DEFAULT_FDT_VERSION 17
47
38/* 48/*
39 * Command line options 49 * Command line options
40 */ 50 */
@@ -42,36 +52,11 @@ extern int quiet; /* Level of quietness */
42extern int reservenum; /* Number of memory reservation slots */ 52extern int reservenum; /* Number of memory reservation slots */
43extern int minsize; /* Minimum blob size */ 53extern int minsize; /* Minimum blob size */
44extern int padsize; /* Additional padding to blob */ 54extern int padsize; /* Additional padding to blob */
55extern int phandle_format; /* Use linux,phandle or phandle properties */
45 56
46static inline void __attribute__((noreturn)) die(char * str, ...) 57#define PHANDLE_LEGACY 0x1
47{ 58#define PHANDLE_EPAPR 0x2
48 va_list ap; 59#define PHANDLE_BOTH 0x3
49
50 va_start(ap, str);
51 fprintf(stderr, "FATAL ERROR: ");
52 vfprintf(stderr, str, ap);
53 exit(1);
54}
55
56static inline void *xmalloc(size_t len)
57{
58 void *new = malloc(len);
59
60 if (! new)
61 die("malloc() failed\n");
62
63 return new;
64}
65
66static inline void *xrealloc(void *p, size_t len)
67{
68 void *new = realloc(p, len);
69
70 if (! new)
71 die("realloc() failed (len=%d)\n", len);
72
73 return new;
74}
75 60
76typedef uint32_t cell_t; 61typedef uint32_t cell_t;
77 62
@@ -140,13 +125,18 @@ int data_is_one_string(struct data d);
140#define MAX_NODENAME_LEN 31 125#define MAX_NODENAME_LEN 31
141 126
142/* Live trees */ 127/* Live trees */
128struct label {
129 char *label;
130 struct label *next;
131};
132
143struct property { 133struct property {
144 char *name; 134 char *name;
145 struct data val; 135 struct data val;
146 136
147 struct property *next; 137 struct property *next;
148 138
149 char *label; 139 struct label *labels;
150}; 140};
151 141
152struct node { 142struct node {
@@ -163,22 +153,28 @@ struct node {
163 cell_t phandle; 153 cell_t phandle;
164 int addr_cells, size_cells; 154 int addr_cells, size_cells;
165 155
166 char *label; 156 struct label *labels;
167}; 157};
168 158
159#define for_each_label(l0, l) \
160 for ((l) = (l0); (l); (l) = (l)->next)
161
169#define for_each_property(n, p) \ 162#define for_each_property(n, p) \
170 for ((p) = (n)->proplist; (p); (p) = (p)->next) 163 for ((p) = (n)->proplist; (p); (p) = (p)->next)
171 164
172#define for_each_child(n, c) \ 165#define for_each_child(n, c) \
173 for ((c) = (n)->children; (c); (c) = (c)->next_sibling) 166 for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
174 167
175struct property *build_property(char *name, struct data val, char *label); 168void add_label(struct label **labels, char *label);
169
170struct property *build_property(char *name, struct data val);
176struct property *chain_property(struct property *first, struct property *list); 171struct property *chain_property(struct property *first, struct property *list);
177struct property *reverse_properties(struct property *first); 172struct property *reverse_properties(struct property *first);
178 173
179struct node *build_node(struct property *proplist, struct node *children); 174struct node *build_node(struct property *proplist, struct node *children);
180struct node *name_node(struct node *node, char *name, char *label); 175struct node *name_node(struct node *node, char *name);
181struct node *chain_node(struct node *first, struct node *list); 176struct node *chain_node(struct node *first, struct node *list);
177struct node *merge_nodes(struct node *old_node, struct node *new_node);
182 178
183void add_property(struct node *node, struct property *prop); 179void add_property(struct node *node, struct property *prop);
184void add_child(struct node *parent, struct node *child); 180void add_child(struct node *parent, struct node *child);
@@ -186,6 +182,10 @@ void add_child(struct node *parent, struct node *child);
186const char *get_unitname(struct node *node); 182const char *get_unitname(struct node *node);
187struct property *get_property(struct node *node, const char *propname); 183struct property *get_property(struct node *node, const char *propname);
188cell_t propval_cell(struct property *prop); 184cell_t propval_cell(struct property *prop);
185struct property *get_property_by_label(struct node *tree, const char *label,
186 struct node **node);
187struct marker *get_marker_label(struct node *tree, const char *label,
188 struct node **node, struct property **prop);
189struct node *get_subnode(struct node *node, const char *nodename); 189struct node *get_subnode(struct node *node, const char *nodename);
190struct node *get_node_by_path(struct node *tree, const char *path); 190struct node *get_node_by_path(struct node *tree, const char *path);
191struct node *get_node_by_label(struct node *tree, const char *label); 191struct node *get_node_by_label(struct node *tree, const char *label);
@@ -193,6 +193,8 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
193struct node *get_node_by_ref(struct node *tree, const char *ref); 193struct node *get_node_by_ref(struct node *tree, const char *ref);
194cell_t get_node_phandle(struct node *root, struct node *node); 194cell_t get_node_phandle(struct node *root, struct node *node);
195 195
196uint32_t guess_boot_cpuid(struct node *tree);
197
196/* Boot info (tree plus memreserve information */ 198/* Boot info (tree plus memreserve information */
197 199
198struct reserve_info { 200struct reserve_info {
@@ -200,10 +202,10 @@ struct reserve_info {
200 202
201 struct reserve_info *next; 203 struct reserve_info *next;
202 204
203 char *label; 205 struct label *labels;
204}; 206};
205 207
206struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label); 208struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
207struct reserve_info *chain_reserve_entry(struct reserve_info *first, 209struct reserve_info *chain_reserve_entry(struct reserve_info *first,
208 struct reserve_info *list); 210 struct reserve_info *list);
209struct reserve_info *add_reserve_entry(struct reserve_info *list, 211struct reserve_info *add_reserve_entry(struct reserve_info *list,
@@ -218,6 +220,7 @@ struct boot_info {
218 220
219struct boot_info *build_boot_info(struct reserve_info *reservelist, 221struct boot_info *build_boot_info(struct reserve_info *reservelist,
220 struct node *tree, uint32_t boot_cpuid_phys); 222 struct node *tree, uint32_t boot_cpuid_phys);
223void sort_tree(struct boot_info *bi);
221 224
222/* Checks */ 225/* Checks */
223 226
@@ -239,8 +242,4 @@ struct boot_info *dt_from_source(const char *f);
239 242
240struct boot_info *dt_from_fs(const char *dirname); 243struct boot_info *dt_from_fs(const char *dirname);
241 244
242/* misc */
243
244char *join_path(const char *path, const char *name);
245
246#endif /* _DTC_H */ 245#endif /* _DTC_H */
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 76acd28c068d..ead0332c87e1 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -52,9 +52,9 @@ struct emitter {
52 void (*string)(void *, char *, int); 52 void (*string)(void *, char *, int);
53 void (*align)(void *, int); 53 void (*align)(void *, int);
54 void (*data)(void *, struct data); 54 void (*data)(void *, struct data);
55 void (*beginnode)(void *, const char *); 55 void (*beginnode)(void *, struct label *labels);
56 void (*endnode)(void *, const char *); 56 void (*endnode)(void *, struct label *labels);
57 void (*property)(void *, const char *); 57 void (*property)(void *, struct label *labels);
58}; 58};
59 59
60static void bin_emit_cell(void *e, cell_t val) 60static void bin_emit_cell(void *e, cell_t val)
@@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struct data d)
89 *dtbuf = data_append_data(*dtbuf, d.val, d.len); 89 *dtbuf = data_append_data(*dtbuf, d.val, d.len);
90} 90}
91 91
92static void bin_emit_beginnode(void *e, const char *label) 92static void bin_emit_beginnode(void *e, struct label *labels)
93{ 93{
94 bin_emit_cell(e, FDT_BEGIN_NODE); 94 bin_emit_cell(e, FDT_BEGIN_NODE);
95} 95}
96 96
97static void bin_emit_endnode(void *e, const char *label) 97static void bin_emit_endnode(void *e, struct label *labels)
98{ 98{
99 bin_emit_cell(e, FDT_END_NODE); 99 bin_emit_cell(e, FDT_END_NODE);
100} 100}
101 101
102static void bin_emit_property(void *e, const char *label) 102static void bin_emit_property(void *e, struct label *labels)
103{ 103{
104 bin_emit_cell(e, FDT_PROP); 104 bin_emit_cell(e, FDT_PROP);
105} 105}
@@ -127,11 +127,21 @@ static void emit_offset_label(FILE *f, const char *label, int offset)
127 fprintf(f, "%s\t= . + %d\n", label, offset); 127 fprintf(f, "%s\t= . + %d\n", label, offset);
128} 128}
129 129
130#define ASM_EMIT_BELONG(f, fmt, ...) \
131 { \
132 fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \
133 fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \
134 fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \
135 fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \
136 }
137
130static void asm_emit_cell(void *e, cell_t val) 138static void asm_emit_cell(void *e, cell_t val)
131{ 139{
132 FILE *f = e; 140 FILE *f = e;
133 141
134 fprintf(f, "\t.long\t0x%x\n", val); 142 fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
143 (val >> 24) & 0xff, (val >> 16) & 0xff,
144 (val >> 8) & 0xff, val & 0xff);
135} 145}
136 146
137static void asm_emit_string(void *e, char *str, int len) 147static void asm_emit_string(void *e, char *str, int len)
@@ -156,7 +166,7 @@ static void asm_emit_align(void *e, int a)
156{ 166{
157 FILE *f = e; 167 FILE *f = e;
158 168
159 fprintf(f, "\t.balign\t%d\n", a); 169 fprintf(f, "\t.balign\t%d, 0\n", a);
160} 170}
161 171
162static void asm_emit_data(void *e, struct data d) 172static void asm_emit_data(void *e, struct data d)
@@ -169,8 +179,7 @@ static void asm_emit_data(void *e, struct data d)
169 emit_offset_label(f, m->ref, m->offset); 179 emit_offset_label(f, m->ref, m->offset);
170 180
171 while ((d.len - off) >= sizeof(uint32_t)) { 181 while ((d.len - off) >= sizeof(uint32_t)) {
172 fprintf(f, "\t.long\t0x%x\n", 182 asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off))));
173 fdt32_to_cpu(*((uint32_t *)(d.val+off))));
174 off += sizeof(uint32_t); 183 off += sizeof(uint32_t);
175 } 184 }
176 185
@@ -182,37 +191,43 @@ static void asm_emit_data(void *e, struct data d)
182 assert(off == d.len); 191 assert(off == d.len);
183} 192}
184 193
185static void asm_emit_beginnode(void *e, const char *label) 194static void asm_emit_beginnode(void *e, struct label *labels)
186{ 195{
187 FILE *f = e; 196 FILE *f = e;
197 struct label *l;
188 198
189 if (label) { 199 for_each_label(labels, l) {
190 fprintf(f, "\t.globl\t%s\n", label); 200 fprintf(f, "\t.globl\t%s\n", l->label);
191 fprintf(f, "%s:\n", label); 201 fprintf(f, "%s:\n", l->label);
192 } 202 }
193 fprintf(f, "\t.long\tFDT_BEGIN_NODE\n"); 203 fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
204 asm_emit_cell(e, FDT_BEGIN_NODE);
194} 205}
195 206
196static void asm_emit_endnode(void *e, const char *label) 207static void asm_emit_endnode(void *e, struct label *labels)
197{ 208{
198 FILE *f = e; 209 FILE *f = e;
210 struct label *l;
199 211
200 fprintf(f, "\t.long\tFDT_END_NODE\n"); 212 fprintf(f, "\t/* FDT_END_NODE */\n");
201 if (label) { 213 asm_emit_cell(e, FDT_END_NODE);
202 fprintf(f, "\t.globl\t%s_end\n", label); 214 for_each_label(labels, l) {
203 fprintf(f, "%s_end:\n", label); 215 fprintf(f, "\t.globl\t%s_end\n", l->label);
216 fprintf(f, "%s_end:\n", l->label);
204 } 217 }
205} 218}
206 219
207static void asm_emit_property(void *e, const char *label) 220static void asm_emit_property(void *e, struct label *labels)
208{ 221{
209 FILE *f = e; 222 FILE *f = e;
223 struct label *l;
210 224
211 if (label) { 225 for_each_label(labels, l) {
212 fprintf(f, "\t.globl\t%s\n", label); 226 fprintf(f, "\t.globl\t%s\n", l->label);
213 fprintf(f, "%s:\n", label); 227 fprintf(f, "%s:\n", l->label);
214 } 228 }
215 fprintf(f, "\t.long\tFDT_PROP\n"); 229 fprintf(f, "\t/* FDT_PROP */\n");
230 asm_emit_cell(e, FDT_PROP);
216} 231}
217 232
218static struct emitter asm_emitter = { 233static struct emitter asm_emitter = {
@@ -248,7 +263,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
248 struct node *child; 263 struct node *child;
249 int seen_name_prop = 0; 264 int seen_name_prop = 0;
250 265
251 emit->beginnode(etarget, tree->label); 266 emit->beginnode(etarget, tree->labels);
252 267
253 if (vi->flags & FTF_FULLPATH) 268 if (vi->flags & FTF_FULLPATH)
254 emit->string(etarget, tree->fullpath, 0); 269 emit->string(etarget, tree->fullpath, 0);
@@ -265,7 +280,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
265 280
266 nameoff = stringtable_insert(strbuf, prop->name); 281 nameoff = stringtable_insert(strbuf, prop->name);
267 282
268 emit->property(etarget, prop->label); 283 emit->property(etarget, prop->labels);
269 emit->cell(etarget, prop->val.len); 284 emit->cell(etarget, prop->val.len);
270 emit->cell(etarget, nameoff); 285 emit->cell(etarget, nameoff);
271 286
@@ -292,7 +307,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
292 flatten_tree(child, emit, etarget, strbuf, vi); 307 flatten_tree(child, emit, etarget, strbuf, vi);
293 } 308 }
294 309
295 emit->endnode(etarget, tree->label); 310 emit->endnode(etarget, tree->labels);
296} 311}
297 312
298static struct data flatten_reserve_list(struct reserve_info *reservelist, 313static struct data flatten_reserve_list(struct reserve_info *reservelist,
@@ -413,10 +428,13 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version)
413 if (padlen > 0) 428 if (padlen > 0)
414 blob = data_append_zeroes(blob, padlen); 429 blob = data_append_zeroes(blob, padlen);
415 430
416 fwrite(blob.val, blob.len, 1, f); 431 if (fwrite(blob.val, blob.len, 1, f) != 1) {
417 432 if (ferror(f))
418 if (ferror(f)) 433 die("Error writing device tree blob: %s\n",
419 die("Error writing device tree blob: %s\n", strerror(errno)); 434 strerror(errno));
435 else
436 die("Short write on device tree blob\n");
437 }
420 438
421 /* 439 /*
422 * data_merge() frees the right-hand element so only the blob 440 * data_merge() frees the right-hand element so only the blob
@@ -455,39 +473,44 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
455 die("Unknown device tree blob version %d\n", version); 473 die("Unknown device tree blob version %d\n", version);
456 474
457 fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); 475 fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
458 fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
459 fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
460 fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
461 fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
462 fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
463 fprintf(f, "\n");
464 476
465 emit_label(f, symprefix, "blob_start"); 477 emit_label(f, symprefix, "blob_start");
466 emit_label(f, symprefix, "header"); 478 emit_label(f, symprefix, "header");
467 fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n"); 479 fprintf(f, "\t/* magic */\n");
468 fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n", 480 asm_emit_cell(f, FDT_MAGIC);
469 symprefix, symprefix); 481 fprintf(f, "\t/* totalsize */\n");
470 fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n", 482 ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start",
483 symprefix, symprefix);
484 fprintf(f, "\t/* off_dt_struct */\n");
485 ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start",
471 symprefix, symprefix); 486 symprefix, symprefix);
472 fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n", 487 fprintf(f, "\t/* off_dt_strings */\n");
488 ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start",
473 symprefix, symprefix); 489 symprefix, symprefix);
474 fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n", 490 fprintf(f, "\t/* off_mem_rsvmap */\n");
491 ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start",
475 symprefix, symprefix); 492 symprefix, symprefix);
476 fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version); 493 fprintf(f, "\t/* version */\n");
477 fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n", 494 asm_emit_cell(f, vi->version);
478 vi->last_comp_version); 495 fprintf(f, "\t/* last_comp_version */\n");
479 496 asm_emit_cell(f, vi->last_comp_version);
480 if (vi->flags & FTF_BOOTCPUID) 497
481 fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", 498 if (vi->flags & FTF_BOOTCPUID) {
482 bi->boot_cpuid_phys); 499 fprintf(f, "\t/* boot_cpuid_phys */\n");
500 asm_emit_cell(f, bi->boot_cpuid_phys);
501 }
483 502
484 if (vi->flags & FTF_STRTABSIZE) 503 if (vi->flags & FTF_STRTABSIZE) {
485 fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", 504 fprintf(f, "\t/* size_dt_strings */\n");
486 symprefix, symprefix); 505 ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start",
506 symprefix, symprefix);
507 }
487 508
488 if (vi->flags & FTF_STRUCTSIZE) 509 if (vi->flags & FTF_STRUCTSIZE) {
489 fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n", 510 fprintf(f, "\t/* size_dt_struct */\n");
511 ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start",
490 symprefix, symprefix); 512 symprefix, symprefix);
513 }
491 514
492 /* 515 /*
493 * Reserve map entries. 516 * Reserve map entries.
@@ -505,16 +528,17 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
505 * as it appears .quad isn't available in some assemblers. 528 * as it appears .quad isn't available in some assemblers.
506 */ 529 */
507 for (re = bi->reservelist; re; re = re->next) { 530 for (re = bi->reservelist; re; re = re->next) {
508 if (re->label) { 531 struct label *l;
509 fprintf(f, "\t.globl\t%s\n", re->label); 532
510 fprintf(f, "%s:\n", re->label); 533 for_each_label(re->labels, l) {
534 fprintf(f, "\t.globl\t%s\n", l->label);
535 fprintf(f, "%s:\n", l->label);
511 } 536 }
512 fprintf(f, "\t.long\t0x%08x, 0x%08x\n", 537 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32));
513 (unsigned int)(re->re.address >> 32), 538 ASM_EMIT_BELONG(f, "0x%08x",
514 (unsigned int)(re->re.address & 0xffffffff)); 539 (unsigned int)(re->re.address & 0xffffffff));
515 fprintf(f, "\t.long\t0x%08x, 0x%08x\n", 540 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32));
516 (unsigned int)(re->re.size >> 32), 541 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff));
517 (unsigned int)(re->re.size & 0xffffffff));
518 } 542 }
519 for (i = 0; i < reservenum; i++) { 543 for (i = 0; i < reservenum; i++) {
520 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); 544 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
@@ -524,7 +548,9 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
524 548
525 emit_label(f, symprefix, "struct_start"); 549 emit_label(f, symprefix, "struct_start");
526 flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); 550 flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
527 fprintf(f, "\t.long\tFDT_END\n"); 551
552 fprintf(f, "\t/* FDT_END */\n");
553 asm_emit_cell(f, FDT_END);
528 emit_label(f, symprefix, "struct_end"); 554 emit_label(f, symprefix, "struct_end");
529 555
530 emit_label(f, symprefix, "strings_start"); 556 emit_label(f, symprefix, "strings_start");
@@ -601,7 +627,7 @@ static char *flat_read_string(struct inbuf *inb)
601 len++; 627 len++;
602 } while ((*p++) != '\0'); 628 } while ((*p++) != '\0');
603 629
604 str = strdup(inb->ptr); 630 str = xstrdup(inb->ptr);
605 631
606 inb->ptr += len; 632 inb->ptr += len;
607 633
@@ -643,7 +669,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
643 p++; 669 p++;
644 } 670 }
645 671
646 return strdup(inb->base + offset); 672 return xstrdup(inb->base + offset);
647} 673}
648 674
649static struct property *flat_read_property(struct inbuf *dtbuf, 675static struct property *flat_read_property(struct inbuf *dtbuf,
@@ -663,7 +689,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
663 689
664 val = flat_read_data(dtbuf, proplen); 690 val = flat_read_data(dtbuf, proplen);
665 691
666 return build_property(name, val, NULL); 692 return build_property(name, val);
667} 693}
668 694
669 695
@@ -688,7 +714,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
688 if (re.size == 0) 714 if (re.size == 0)
689 break; 715 break;
690 716
691 new = build_reserve_entry(re.address, re.size, NULL); 717 new = build_reserve_entry(re.address, re.size);
692 reservelist = add_reserve_entry(reservelist, new); 718 reservelist = add_reserve_entry(reservelist, new);
693 } 719 }
694 720
@@ -710,7 +736,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
710 if (!streq(ppath, "/")) 736 if (!streq(ppath, "/"))
711 plen++; 737 plen++;
712 738
713 return strdup(cpath + plen); 739 return xstrdup(cpath + plen);
714} 740}
715 741
716static struct node *unflatten_tree(struct inbuf *dtbuf, 742static struct node *unflatten_tree(struct inbuf *dtbuf,
@@ -776,7 +802,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
776 802
777struct boot_info *dt_from_blob(const char *fname) 803struct boot_info *dt_from_blob(const char *fname)
778{ 804{
779 struct dtc_file *dtcf; 805 FILE *f;
780 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; 806 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
781 uint32_t off_dt, off_str, off_mem_rsvmap; 807 uint32_t off_dt, off_str, off_mem_rsvmap;
782 int rc; 808 int rc;
@@ -791,14 +817,14 @@ struct boot_info *dt_from_blob(const char *fname)
791 uint32_t val; 817 uint32_t val;
792 int flags = 0; 818 int flags = 0;
793 819
794 dtcf = dtc_open_file(fname, NULL); 820 f = srcfile_relative_open(fname, NULL);
795 821
796 rc = fread(&magic, sizeof(magic), 1, dtcf->file); 822 rc = fread(&magic, sizeof(magic), 1, f);
797 if (ferror(dtcf->file)) 823 if (ferror(f))
798 die("Error reading DT blob magic number: %s\n", 824 die("Error reading DT blob magic number: %s\n",
799 strerror(errno)); 825 strerror(errno));
800 if (rc < 1) { 826 if (rc < 1) {
801 if (feof(dtcf->file)) 827 if (feof(f))
802 die("EOF reading DT blob magic number\n"); 828 die("EOF reading DT blob magic number\n");
803 else 829 else
804 die("Mysterious short read reading magic number\n"); 830 die("Mysterious short read reading magic number\n");
@@ -808,11 +834,11 @@ struct boot_info *dt_from_blob(const char *fname)
808 if (magic != FDT_MAGIC) 834 if (magic != FDT_MAGIC)
809 die("Blob has incorrect magic number\n"); 835 die("Blob has incorrect magic number\n");
810 836
811 rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file); 837 rc = fread(&totalsize, sizeof(totalsize), 1, f);
812 if (ferror(dtcf->file)) 838 if (ferror(f))
813 die("Error reading DT blob size: %s\n", strerror(errno)); 839 die("Error reading DT blob size: %s\n", strerror(errno));
814 if (rc < 1) { 840 if (rc < 1) {
815 if (feof(dtcf->file)) 841 if (feof(f))
816 die("EOF reading DT blob size\n"); 842 die("EOF reading DT blob size\n");
817 else 843 else
818 die("Mysterious short read reading blob size\n"); 844 die("Mysterious short read reading blob size\n");
@@ -832,12 +858,12 @@ struct boot_info *dt_from_blob(const char *fname)
832 p = blob + sizeof(magic) + sizeof(totalsize); 858 p = blob + sizeof(magic) + sizeof(totalsize);
833 859
834 while (sizeleft) { 860 while (sizeleft) {
835 if (feof(dtcf->file)) 861 if (feof(f))
836 die("EOF before reading %d bytes of DT blob\n", 862 die("EOF before reading %d bytes of DT blob\n",
837 totalsize); 863 totalsize);
838 864
839 rc = fread(p, 1, sizeleft, dtcf->file); 865 rc = fread(p, 1, sizeleft, f);
840 if (ferror(dtcf->file)) 866 if (ferror(f))
841 die("Error reading DT blob: %s\n", 867 die("Error reading DT blob: %s\n",
842 strerror(errno)); 868 strerror(errno));
843 869
@@ -900,7 +926,7 @@ struct boot_info *dt_from_blob(const char *fname)
900 926
901 free(blob); 927 free(blob);
902 928
903 dtc_close_file(dtcf); 929 fclose(f);
904 930
905 return build_boot_info(reservelist, tree, boot_cpuid_phys); 931 return build_boot_info(reservelist, tree, boot_cpuid_phys);
906} 932}
diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
index 766b2694d935..f3774530170a 100644
--- a/scripts/dtc/fstree.c
+++ b/scripts/dtc/fstree.c
@@ -58,10 +58,9 @@ static struct node *read_fstree(const char *dirname)
58 "WARNING: Cannot open %s: %s\n", 58 "WARNING: Cannot open %s: %s\n",
59 tmpnam, strerror(errno)); 59 tmpnam, strerror(errno));
60 } else { 60 } else {
61 prop = build_property(strdup(de->d_name), 61 prop = build_property(xstrdup(de->d_name),
62 data_copy_file(pfile, 62 data_copy_file(pfile,
63 st.st_size), 63 st.st_size));
64 NULL);
65 add_property(tree, prop); 64 add_property(tree, prop);
66 fclose(pfile); 65 fclose(pfile);
67 } 66 }
@@ -69,14 +68,14 @@ static struct node *read_fstree(const char *dirname)
69 struct node *newchild; 68 struct node *newchild;
70 69
71 newchild = read_fstree(tmpnam); 70 newchild = read_fstree(tmpnam);
72 newchild = name_node(newchild, strdup(de->d_name), 71 newchild = name_node(newchild, xstrdup(de->d_name));
73 NULL);
74 add_child(tree, newchild); 72 add_child(tree, newchild);
75 } 73 }
76 74
77 free(tmpnam); 75 free(tmpnam);
78 } 76 }
79 77
78 closedir(d);
80 return tree; 79 return tree;
81} 80}
82 81
@@ -85,8 +84,8 @@ struct boot_info *dt_from_fs(const char *dirname)
85 struct node *tree; 84 struct node *tree;
86 85
87 tree = read_fstree(dirname); 86 tree = read_fstree(dirname);
88 tree = name_node(tree, "", NULL); 87 tree = name_node(tree, "");
89 88
90 return build_boot_info(NULL, tree, 0); 89 return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
91} 90}
92 91
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index fbbba44fcd0d..22e692919ff9 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -411,7 +411,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
411 &phandle, sizeof(phandle)); 411 &phandle, sizeof(phandle));
412} 412}
413 413
414int _stringlist_contains(const char *strlist, int listlen, const char *str) 414static int _stringlist_contains(const char *strlist, int listlen, const char *str)
415{ 415{
416 int len = strlen(str); 416 int len = strlen(str);
417 const char *p; 417 const char *p;
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 0ca3de550b3f..c9209d5c999e 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -24,17 +24,30 @@
24 * Tree building functions 24 * Tree building functions
25 */ 25 */
26 26
27struct property *build_property(char *name, struct data val, char *label) 27void add_label(struct label **labels, char *label)
28{
29 struct label *new;
30
31 /* Make sure the label isn't already there */
32 for_each_label(*labels, new)
33 if (streq(new->label, label))
34 return;
35
36 new = xmalloc(sizeof(*new));
37 new->label = label;
38 new->next = *labels;
39 *labels = new;
40}
41
42struct property *build_property(char *name, struct data val)
28{ 43{
29 struct property *new = xmalloc(sizeof(*new)); 44 struct property *new = xmalloc(sizeof(*new));
30 45
46 memset(new, 0, sizeof(*new));
47
31 new->name = name; 48 new->name = name;
32 new->val = val; 49 new->val = val;
33 50
34 new->next = NULL;
35
36 new->label = label;
37
38 return new; 51 return new;
39} 52}
40 53
@@ -78,17 +91,82 @@ struct node *build_node(struct property *proplist, struct node *children)
78 return new; 91 return new;
79} 92}
80 93
81struct node *name_node(struct node *node, char *name, char * label) 94struct node *name_node(struct node *node, char *name)
82{ 95{
83 assert(node->name == NULL); 96 assert(node->name == NULL);
84 97
85 node->name = name; 98 node->name = name;
86 99
87 node->label = label;
88
89 return node; 100 return node;
90} 101}
91 102
103struct node *merge_nodes(struct node *old_node, struct node *new_node)
104{
105 struct property *new_prop, *old_prop;
106 struct node *new_child, *old_child;
107 struct label *l;
108
109 /* Add new node labels to old node */
110 for_each_label(new_node->labels, l)
111 add_label(&old_node->labels, l->label);
112
113 /* Move properties from the new node to the old node. If there
114 * is a collision, replace the old value with the new */
115 while (new_node->proplist) {
116 /* Pop the property off the list */
117 new_prop = new_node->proplist;
118 new_node->proplist = new_prop->next;
119 new_prop->next = NULL;
120
121 /* Look for a collision, set new value if there is */
122 for_each_property(old_node, old_prop) {
123 if (streq(old_prop->name, new_prop->name)) {
124 /* Add new labels to old property */
125 for_each_label(new_prop->labels, l)
126 add_label(&old_prop->labels, l->label);
127
128 old_prop->val = new_prop->val;
129 free(new_prop);
130 new_prop = NULL;
131 break;
132 }
133 }
134
135 /* if no collision occurred, add property to the old node. */
136 if (new_prop)
137 add_property(old_node, new_prop);
138 }
139
140 /* Move the override child nodes into the primary node. If
141 * there is a collision, then merge the nodes. */
142 while (new_node->children) {
143 /* Pop the child node off the list */
144 new_child = new_node->children;
145 new_node->children = new_child->next_sibling;
146 new_child->parent = NULL;
147 new_child->next_sibling = NULL;
148
149 /* Search for a collision. Merge if there is */
150 for_each_child(old_node, old_child) {
151 if (streq(old_child->name, new_child->name)) {
152 merge_nodes(old_child, new_child);
153 new_child = NULL;
154 break;
155 }
156 }
157
158 /* if no collision occured, add child to the old node. */
159 if (new_child)
160 add_child(old_node, new_child);
161 }
162
163 /* The new node contents are now merged into the old node. Free
164 * the new node. */
165 free(new_node);
166
167 return old_node;
168}
169
92struct node *chain_node(struct node *first, struct node *list) 170struct node *chain_node(struct node *first, struct node *list)
93{ 171{
94 assert(first->next_sibling == NULL); 172 assert(first->next_sibling == NULL);
@@ -124,18 +202,15 @@ void add_child(struct node *parent, struct node *child)
124 *p = child; 202 *p = child;
125} 203}
126 204
127struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size, 205struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
128 char *label)
129{ 206{
130 struct reserve_info *new = xmalloc(sizeof(*new)); 207 struct reserve_info *new = xmalloc(sizeof(*new));
131 208
209 memset(new, 0, sizeof(*new));
210
132 new->re.address = address; 211 new->re.address = address;
133 new->re.size = size; 212 new->re.size = size;
134 213
135 new->next = NULL;
136
137 new->label = label;
138
139 return new; 214 return new;
140} 215}
141 216
@@ -208,6 +283,60 @@ cell_t propval_cell(struct property *prop)
208 return fdt32_to_cpu(*((cell_t *)prop->val.val)); 283 return fdt32_to_cpu(*((cell_t *)prop->val.val));
209} 284}
210 285
286struct property *get_property_by_label(struct node *tree, const char *label,
287 struct node **node)
288{
289 struct property *prop;
290 struct node *c;
291
292 *node = tree;
293
294 for_each_property(tree, prop) {
295 struct label *l;
296
297 for_each_label(prop->labels, l)
298 if (streq(l->label, label))
299 return prop;
300 }
301
302 for_each_child(tree, c) {
303 prop = get_property_by_label(c, label, node);
304 if (prop)
305 return prop;
306 }
307
308 *node = NULL;
309 return NULL;
310}
311
312struct marker *get_marker_label(struct node *tree, const char *label,
313 struct node **node, struct property **prop)
314{
315 struct marker *m;
316 struct property *p;
317 struct node *c;
318
319 *node = tree;
320
321 for_each_property(tree, p) {
322 *prop = p;
323 m = p->val.markers;
324 for_each_marker_of_type(m, LABEL)
325 if (streq(m->ref, label))
326 return m;
327 }
328
329 for_each_child(tree, c) {
330 m = get_marker_label(c, label, node, prop);
331 if (m)
332 return m;
333 }
334
335 *prop = NULL;
336 *node = NULL;
337 return NULL;
338}
339
211struct node *get_subnode(struct node *node, const char *nodename) 340struct node *get_subnode(struct node *node, const char *nodename)
212{ 341{
213 struct node *child; 342 struct node *child;
@@ -245,11 +374,13 @@ struct node *get_node_by_path(struct node *tree, const char *path)
245struct node *get_node_by_label(struct node *tree, const char *label) 374struct node *get_node_by_label(struct node *tree, const char *label)
246{ 375{
247 struct node *child, *node; 376 struct node *child, *node;
377 struct label *l;
248 378
249 assert(label && (strlen(label) > 0)); 379 assert(label && (strlen(label) > 0));
250 380
251 if (tree->label && streq(tree->label, label)) 381 for_each_label(tree->labels, l)
252 return tree; 382 if (streq(l->label, label))
383 return tree;
253 384
254 for_each_child(tree, child) { 385 for_each_child(tree, child) {
255 node = get_node_by_label(child, label); 386 node = get_node_by_label(child, label);
@@ -293,16 +424,186 @@ cell_t get_node_phandle(struct node *root, struct node *node)
293 if ((node->phandle != 0) && (node->phandle != -1)) 424 if ((node->phandle != 0) && (node->phandle != -1))
294 return node->phandle; 425 return node->phandle;
295 426
296 assert(! get_property(node, "linux,phandle"));
297
298 while (get_node_by_phandle(root, phandle)) 427 while (get_node_by_phandle(root, phandle))
299 phandle++; 428 phandle++;
300 429
301 node->phandle = phandle; 430 node->phandle = phandle;
302 add_property(node, 431
303 build_property("linux,phandle", 432 if (!get_property(node, "linux,phandle")
304 data_append_cell(empty_data, phandle), 433 && (phandle_format & PHANDLE_LEGACY))
305 NULL)); 434 add_property(node,
435 build_property("linux,phandle",
436 data_append_cell(empty_data, phandle)));
437
438 if (!get_property(node, "phandle")
439 && (phandle_format & PHANDLE_EPAPR))
440 add_property(node,
441 build_property("phandle",
442 data_append_cell(empty_data, phandle)));
443
444 /* If the node *does* have a phandle property, we must
445 * be dealing with a self-referencing phandle, which will be
446 * fixed up momentarily in the caller */
306 447
307 return node->phandle; 448 return node->phandle;
308} 449}
450
451uint32_t guess_boot_cpuid(struct node *tree)
452{
453 struct node *cpus, *bootcpu;
454 struct property *reg;
455
456 cpus = get_node_by_path(tree, "/cpus");
457 if (!cpus)
458 return 0;
459
460
461 bootcpu = cpus->children;
462 if (!bootcpu)
463 return 0;
464
465 reg = get_property(bootcpu, "reg");
466 if (!reg || (reg->val.len != sizeof(uint32_t)))
467 return 0;
468
469 /* FIXME: Sanity check node? */
470
471 return propval_cell(reg);
472}
473
474static int cmp_reserve_info(const void *ax, const void *bx)
475{
476 const struct reserve_info *a, *b;
477
478 a = *((const struct reserve_info * const *)ax);
479 b = *((const struct reserve_info * const *)bx);
480
481 if (a->re.address < b->re.address)
482 return -1;
483 else if (a->re.address > b->re.address)
484 return 1;
485 else if (a->re.size < b->re.size)
486 return -1;
487 else if (a->re.size > b->re.size)
488 return 1;
489 else
490 return 0;
491}
492
493static void sort_reserve_entries(struct boot_info *bi)
494{
495 struct reserve_info *ri, **tbl;
496 int n = 0, i = 0;
497
498 for (ri = bi->reservelist;
499 ri;
500 ri = ri->next)
501 n++;
502
503 if (n == 0)
504 return;
505
506 tbl = xmalloc(n * sizeof(*tbl));
507
508 for (ri = bi->reservelist;
509 ri;
510 ri = ri->next)
511 tbl[i++] = ri;
512
513 qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
514
515 bi->reservelist = tbl[0];
516 for (i = 0; i < (n-1); i++)
517 tbl[i]->next = tbl[i+1];
518 tbl[n-1]->next = NULL;
519
520 free(tbl);
521}
522
523static int cmp_prop(const void *ax, const void *bx)
524{
525 const struct property *a, *b;
526
527 a = *((const struct property * const *)ax);
528 b = *((const struct property * const *)bx);
529
530 return strcmp(a->name, b->name);
531}
532
533static void sort_properties(struct node *node)
534{
535 int n = 0, i = 0;
536 struct property *prop, **tbl;
537
538 for_each_property(node, prop)
539 n++;
540
541 if (n == 0)
542 return;
543
544 tbl = xmalloc(n * sizeof(*tbl));
545
546 for_each_property(node, prop)
547 tbl[i++] = prop;
548
549 qsort(tbl, n, sizeof(*tbl), cmp_prop);
550
551 node->proplist = tbl[0];
552 for (i = 0; i < (n-1); i++)
553 tbl[i]->next = tbl[i+1];
554 tbl[n-1]->next = NULL;
555
556 free(tbl);
557}
558
559static int cmp_subnode(const void *ax, const void *bx)
560{
561 const struct node *a, *b;
562
563 a = *((const struct node * const *)ax);
564 b = *((const struct node * const *)bx);
565
566 return strcmp(a->name, b->name);
567}
568
569static void sort_subnodes(struct node *node)
570{
571 int n = 0, i = 0;
572 struct node *subnode, **tbl;
573
574 for_each_child(node, subnode)
575 n++;
576
577 if (n == 0)
578 return;
579
580 tbl = xmalloc(n * sizeof(*tbl));
581
582 for_each_child(node, subnode)
583 tbl[i++] = subnode;
584
585 qsort(tbl, n, sizeof(*tbl), cmp_subnode);
586
587 node->children = tbl[0];
588 for (i = 0; i < (n-1); i++)
589 tbl[i]->next_sibling = tbl[i+1];
590 tbl[n-1]->next_sibling = NULL;
591
592 free(tbl);
593}
594
595static void sort_node(struct node *node)
596{
597 struct node *c;
598
599 sort_properties(node);
600 sort_subnodes(node);
601 for_each_child(node, c)
602 sort_node(c);
603}
604
605void sort_tree(struct boot_info *bi)
606{
607 sort_reserve_entries(bi);
608 sort_node(bi->dt);
609}
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 9641b7628b4d..2dbc874288ca 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -17,100 +17,232 @@
17 * USA 17 * USA
18 */ 18 */
19 19
20#define _GNU_SOURCE
21
22#include <stdio.h>
23
20#include "dtc.h" 24#include "dtc.h"
21#include "srcpos.h" 25#include "srcpos.h"
22 26
23/*
24 * Like yylineno, this is the current open file pos.
25 */
26 27
27struct dtc_file *srcpos_file; 28static char *dirname(const char *path)
29{
30 const char *slash = strrchr(path, '/');
31
32 if (slash) {
33 int len = slash - path;
34 char *dir = xmalloc(len + 1);
35
36 memcpy(dir, path, len);
37 dir[len] = '\0';
38 return dir;
39 }
40 return NULL;
41}
42
43struct srcfile_state *current_srcfile; /* = NULL */
28 44
29static int dtc_open_one(struct dtc_file *file, 45/* Detect infinite include recursion. */
30 const char *search, 46#define MAX_SRCFILE_DEPTH (100)
31 const char *fname) 47static int srcfile_depth; /* = 0 */
48
49FILE *srcfile_relative_open(const char *fname, char **fullnamep)
32{ 50{
51 FILE *f;
33 char *fullname; 52 char *fullname;
34 53
35 if (search) { 54 if (streq(fname, "-")) {
36 fullname = xmalloc(strlen(search) + strlen(fname) + 2); 55 f = stdin;
37 56 fullname = xstrdup("<stdin>");
38 strcpy(fullname, search);
39 strcat(fullname, "/");
40 strcat(fullname, fname);
41 } else { 57 } else {
42 fullname = strdup(fname); 58 if (!current_srcfile || !current_srcfile->dir
59 || (fname[0] == '/'))
60 fullname = xstrdup(fname);
61 else
62 fullname = join_path(current_srcfile->dir, fname);
63
64 f = fopen(fullname, "r");
65 if (!f)
66 die("Couldn't open \"%s\": %s\n", fname,
67 strerror(errno));
43 } 68 }
44 69
45 file->file = fopen(fullname, "r"); 70 if (fullnamep)
46 if (!file->file) { 71 *fullnamep = fullname;
72 else
47 free(fullname); 73 free(fullname);
48 return 0;
49 }
50 74
51 file->name = fullname; 75 return f;
52 return 1;
53} 76}
54 77
78void srcfile_push(const char *fname)
79{
80 struct srcfile_state *srcfile;
81
82 if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
83 die("Includes nested too deeply");
84
85 srcfile = xmalloc(sizeof(*srcfile));
86
87 srcfile->f = srcfile_relative_open(fname, &srcfile->name);
88 srcfile->dir = dirname(srcfile->name);
89 srcfile->prev = current_srcfile;
90
91 srcfile->lineno = 1;
92 srcfile->colno = 1;
93
94 current_srcfile = srcfile;
95}
55 96
56struct dtc_file *dtc_open_file(const char *fname, 97int srcfile_pop(void)
57 const struct search_path *search)
58{ 98{
59 static const struct search_path default_search = { NULL, NULL, NULL }; 99 struct srcfile_state *srcfile = current_srcfile;
60 100
61 struct dtc_file *file; 101 assert(srcfile);
62 const char *slash;
63 102
64 file = xmalloc(sizeof(struct dtc_file)); 103 current_srcfile = srcfile->prev;
65 104
66 slash = strrchr(fname, '/'); 105 if (fclose(srcfile->f))
67 if (slash) { 106 die("Error closing \"%s\": %s\n", srcfile->name,
68 char *dir = xmalloc(slash - fname + 1); 107 strerror(errno));
69 108
70 memcpy(dir, fname, slash - fname); 109 /* FIXME: We allow the srcfile_state structure to leak,
71 dir[slash - fname] = 0; 110 * because it could still be referenced from a location
72 file->dir = dir; 111 * variable being carried through the parser somewhere. To
73 } else { 112 * fix this we could either allocate all the files from a
74 file->dir = NULL; 113 * table, or use a pool allocator. */
75 }
76 114
77 if (streq(fname, "-")) { 115 return current_srcfile ? 1 : 0;
78 file->name = "stdin"; 116}
79 file->file = stdin;
80 return file;
81 }
82 117
83 if (fname[0] == '/') { 118/*
84 file->file = fopen(fname, "r"); 119 * The empty source position.
85 if (!file->file) 120 */
86 goto fail;
87 121
88 file->name = strdup(fname); 122struct srcpos srcpos_empty = {
89 return file; 123 .first_line = 0,
90 } 124 .first_column = 0,
125 .last_line = 0,
126 .last_column = 0,
127 .file = NULL,
128};
91 129
92 if (!search) 130#define TAB_SIZE 8
93 search = &default_search;
94 131
95 while (search) { 132void srcpos_update(struct srcpos *pos, const char *text, int len)
96 if (dtc_open_one(file, search->dir, fname)) 133{
97 return file; 134 int i;
135
136 pos->file = current_srcfile;
137
138 pos->first_line = current_srcfile->lineno;
139 pos->first_column = current_srcfile->colno;
140
141 for (i = 0; i < len; i++)
142 if (text[i] == '\n') {
143 current_srcfile->lineno++;
144 current_srcfile->colno = 1;
145 } else if (text[i] == '\t') {
146 current_srcfile->colno =
147 ALIGN(current_srcfile->colno, TAB_SIZE);
148 } else {
149 current_srcfile->colno++;
150 }
151
152 pos->last_line = current_srcfile->lineno;
153 pos->last_column = current_srcfile->colno;
154}
98 155
99 if (errno != ENOENT) 156struct srcpos *
100 goto fail; 157srcpos_copy(struct srcpos *pos)
158{
159 struct srcpos *pos_new;
101 160
102 search = search->next; 161 pos_new = xmalloc(sizeof(struct srcpos));
103 } 162 memcpy(pos_new, pos, sizeof(struct srcpos));
163
164 return pos_new;
165}
166
167
168
169void
170srcpos_dump(struct srcpos *pos)
171{
172 printf("file : \"%s\"\n",
173 pos->file ? (char *) pos->file : "<no file>");
174 printf("first_line : %d\n", pos->first_line);
175 printf("first_column: %d\n", pos->first_column);
176 printf("last_line : %d\n", pos->last_line);
177 printf("last_column : %d\n", pos->last_column);
178 printf("file : %s\n", pos->file->name);
179}
104 180
105fail: 181
106 die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); 182char *
183srcpos_string(struct srcpos *pos)
184{
185 const char *fname = "<no-file>";
186 char *pos_str;
187 int rc;
188
189 if (pos)
190 fname = pos->file->name;
191
192
193 if (pos->first_line != pos->last_line)
194 rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
195 pos->first_line, pos->first_column,
196 pos->last_line, pos->last_column);
197 else if (pos->first_column != pos->last_column)
198 rc = asprintf(&pos_str, "%s:%d.%d-%d", fname,
199 pos->first_line, pos->first_column,
200 pos->last_column);
201 else
202 rc = asprintf(&pos_str, "%s:%d.%d", fname,
203 pos->first_line, pos->first_column);
204
205 if (rc == -1)
206 die("Couldn't allocate in srcpos string");
207
208 return pos_str;
209}
210
211void
212srcpos_verror(struct srcpos *pos, char const *fmt, va_list va)
213{
214 const char *srcstr;
215
216 srcstr = srcpos_string(pos);
217
218 fprintf(stdout, "Error: %s ", srcstr);
219 vfprintf(stdout, fmt, va);
220 fprintf(stdout, "\n");
107} 221}
108 222
109void dtc_close_file(struct dtc_file *file) 223void
224srcpos_error(struct srcpos *pos, char const *fmt, ...)
110{ 225{
111 if (fclose(file->file)) 226 va_list va;
112 die("Error closing \"%s\": %s\n", file->name, strerror(errno)); 227
228 va_start(va, fmt);
229 srcpos_verror(pos, fmt, va);
230 va_end(va);
231}
232
233
234void
235srcpos_warn(struct srcpos *pos, char const *fmt, ...)
236{
237 const char *srcstr;
238 va_list va;
239 va_start(va, fmt);
240
241 srcstr = srcpos_string(pos);
242
243 fprintf(stderr, "Warning: %s ", srcstr);
244 vfprintf(stderr, fmt, va);
245 fprintf(stderr, "\n");
113 246
114 free(file->dir); 247 va_end(va);
115 free(file);
116} 248}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index e17c7c04db8e..bd7966e56a53 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -17,69 +17,70 @@
17 * USA 17 * USA
18 */ 18 */
19 19
20/* 20#ifndef _SRCPOS_H_
21 * Augment the standard YYLTYPE with a filenum index into an 21#define _SRCPOS_H_
22 * array of all opened filenames.
23 */
24 22
25#include <stdio.h> 23#include <stdio.h>
26 24
27struct dtc_file { 25struct srcfile_state {
26 FILE *f;
27 char *name;
28 char *dir; 28 char *dir;
29 const char *name; 29 int lineno, colno;
30 FILE *file; 30 struct srcfile_state *prev;
31}; 31};
32 32
33#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED) 33extern struct srcfile_state *current_srcfile; /* = NULL */
34typedef struct YYLTYPE { 34
35FILE *srcfile_relative_open(const char *fname, char **fullnamep);
36void srcfile_push(const char *fname);
37int srcfile_pop(void);
38
39struct srcpos {
35 int first_line; 40 int first_line;
36 int first_column; 41 int first_column;
37 int last_line; 42 int last_line;
38 int last_column; 43 int last_column;
39 struct dtc_file *file; 44 struct srcfile_state *file;
40} YYLTYPE; 45};
41
42#define YYLTYPE_IS_DECLARED 1
43#define YYLTYPE_IS_TRIVIAL 1
44#endif
45
46/* Cater to old parser templates. */
47#ifndef YYID
48#define YYID(n) (n)
49#endif
50 46
51#define YYLLOC_DEFAULT(Current, Rhs, N) \ 47#define YYLTYPE struct srcpos
52 do \
53 if (YYID (N)) \
54 { \
55 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
56 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
57 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
58 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
59 (Current).file = YYRHSLOC (Rhs, N).file; \
60 } \
61 else \
62 { \
63 (Current).first_line = (Current).last_line = \
64 YYRHSLOC (Rhs, 0).last_line; \
65 (Current).first_column = (Current).last_column = \
66 YYRHSLOC (Rhs, 0).last_column; \
67 (Current).file = YYRHSLOC (Rhs, 0).file; \
68 } \
69 while (YYID (0))
70 48
49#define YYLLOC_DEFAULT(Current, Rhs, N) \
50 do { \
51 if (N) { \
52 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
53 (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
54 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
55 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
56 (Current).file = YYRHSLOC(Rhs, N).file; \
57 } else { \
58 (Current).first_line = (Current).last_line = \
59 YYRHSLOC(Rhs, 0).last_line; \
60 (Current).first_column = (Current).last_column = \
61 YYRHSLOC(Rhs, 0).last_column; \
62 (Current).file = YYRHSLOC (Rhs, 0).file; \
63 } \
64 } while (0)
71 65
72 66
73extern void yyerror(char const *); 67/*
74extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2))); 68 * Fictional source position used for IR nodes that are
69 * created without otherwise knowing a true source position.
70 * For example,constant definitions from the command line.
71 */
72extern struct srcpos srcpos_empty;
75 73
76extern struct dtc_file *srcpos_file; 74extern void srcpos_update(struct srcpos *pos, const char *text, int len);
75extern struct srcpos *srcpos_copy(struct srcpos *pos);
76extern char *srcpos_string(struct srcpos *pos);
77extern void srcpos_dump(struct srcpos *pos);
77 78
78struct search_path { 79extern void srcpos_verror(struct srcpos *pos, char const *, va_list va)
79 const char *dir; /* NULL for current directory */ 80 __attribute__((format(printf, 2, 0)));
80 struct search_path *prev, *next; 81extern void srcpos_error(struct srcpos *pos, char const *, ...)
81}; 82 __attribute__((format(printf, 2, 3)));
83extern void srcpos_warn(struct srcpos *pos, char const *, ...)
84 __attribute__((format(printf, 2, 3)));
82 85
83extern struct dtc_file *dtc_open_file(const char *fname, 86#endif /* _SRCPOS_H_ */
84 const struct search_path *search);
85extern void dtc_close_file(struct dtc_file *file);
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index ebeb6eb27907..c09aafade313 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -32,8 +32,8 @@ struct boot_info *dt_from_source(const char *fname)
32 the_boot_info = NULL; 32 the_boot_info = NULL;
33 treesource_error = 0; 33 treesource_error = 0;
34 34
35 srcpos_file = dtc_open_file(fname, NULL); 35 srcfile_push(fname);
36 yyin = srcpos_file->file; 36 yyin = current_srcfile->f;
37 37
38 if (yyparse() != 0) 38 if (yyparse() != 0)
39 die("Unable to parse input tree\n"); 39 die("Unable to parse input tree\n");
@@ -52,7 +52,7 @@ static void write_prefix(FILE *f, int level)
52 fputc('\t', f); 52 fputc('\t', f);
53} 53}
54 54
55int isstring(char c) 55static int isstring(char c)
56{ 56{
57 return (isprint(c) 57 return (isprint(c)
58 || (c == '\0') 58 || (c == '\0')
@@ -63,26 +63,20 @@ static void write_propval_string(FILE *f, struct data val)
63{ 63{
64 const char *str = val.val; 64 const char *str = val.val;
65 int i; 65 int i;
66 int newchunk = 1;
67 struct marker *m = val.markers; 66 struct marker *m = val.markers;
68 67
69 assert(str[val.len-1] == '\0'); 68 assert(str[val.len-1] == '\0');
70 69
70 while (m && (m->offset == 0)) {
71 if (m->type == LABEL)
72 fprintf(f, "%s: ", m->ref);
73 m = m->next;
74 }
75 fprintf(f, "\"");
76
71 for (i = 0; i < (val.len-1); i++) { 77 for (i = 0; i < (val.len-1); i++) {
72 char c = str[i]; 78 char c = str[i];
73 79
74 if (newchunk) {
75 while (m && (m->offset <= i)) {
76 if (m->type == LABEL) {
77 assert(m->offset == i);
78 fprintf(f, "%s: ", m->ref);
79 }
80 m = m->next;
81 }
82 fprintf(f, "\"");
83 newchunk = 0;
84 }
85
86 switch (c) { 80 switch (c) {
87 case '\a': 81 case '\a':
88 fprintf(f, "\\a"); 82 fprintf(f, "\\a");
@@ -113,7 +107,14 @@ static void write_propval_string(FILE *f, struct data val)
113 break; 107 break;
114 case '\0': 108 case '\0':
115 fprintf(f, "\", "); 109 fprintf(f, "\", ");
116 newchunk = 1; 110 while (m && (m->offset < i)) {
111 if (m->type == LABEL) {
112 assert(m->offset == (i+1));
113 fprintf(f, "%s: ", m->ref);
114 }
115 m = m->next;
116 }
117 fprintf(f, "\"");
117 break; 118 break;
118 default: 119 default:
119 if (isprint(c)) 120 if (isprint(c))
@@ -234,10 +235,11 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
234{ 235{
235 struct property *prop; 236 struct property *prop;
236 struct node *child; 237 struct node *child;
238 struct label *l;
237 239
238 write_prefix(f, level); 240 write_prefix(f, level);
239 if (tree->label) 241 for_each_label(tree->labels, l)
240 fprintf(f, "%s: ", tree->label); 242 fprintf(f, "%s: ", l->label);
241 if (tree->name && (*tree->name)) 243 if (tree->name && (*tree->name))
242 fprintf(f, "%s {\n", tree->name); 244 fprintf(f, "%s {\n", tree->name);
243 else 245 else
@@ -245,8 +247,8 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
245 247
246 for_each_property(tree, prop) { 248 for_each_property(tree, prop) {
247 write_prefix(f, level+1); 249 write_prefix(f, level+1);
248 if (prop->label) 250 for_each_label(prop->labels, l)
249 fprintf(f, "%s: ", prop->label); 251 fprintf(f, "%s: ", l->label);
250 fprintf(f, "%s", prop->name); 252 fprintf(f, "%s", prop->name);
251 write_propval(f, prop); 253 write_propval(f, prop);
252 } 254 }
@@ -266,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_info *bi)
266 fprintf(f, "/dts-v1/;\n\n"); 268 fprintf(f, "/dts-v1/;\n\n");
267 269
268 for (re = bi->reservelist; re; re = re->next) { 270 for (re = bi->reservelist; re; re = re->next) {
269 if (re->label) 271 struct label *l;
270 fprintf(f, "%s: ", re->label); 272
273 for_each_label(re->labels, l)
274 fprintf(f, "%s: ", l->label);
271 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", 275 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
272 (unsigned long long)re->re.address, 276 (unsigned long long)re->re.address,
273 (unsigned long long)re->re.size); 277 (unsigned long long)re->re.size);
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
new file mode 100644
index 000000000000..d7ac27d2ae15
--- /dev/null
+++ b/scripts/dtc/util.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <string.h>
24
25#include "util.h"
26
27char *xstrdup(const char *s)
28{
29 int len = strlen(s) + 1;
30 char *dup = xmalloc(len);
31
32 memcpy(dup, s, len);
33
34 return dup;
35}
36
37char *join_path(const char *path, const char *name)
38{
39 int lenp = strlen(path);
40 int lenn = strlen(name);
41 int len;
42 int needslash = 1;
43 char *str;
44
45 len = lenp + lenn + 2;
46 if ((lenp > 0) && (path[lenp-1] == '/')) {
47 needslash = 0;
48 len--;
49 }
50
51 str = xmalloc(len);
52 memcpy(str, path, lenp);
53 if (needslash) {
54 str[lenp] = '/';
55 lenp++;
56 }
57 memcpy(str+lenp, name, lenn+1);
58 return str;
59}
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
new file mode 100644
index 000000000000..9cead842c11e
--- /dev/null
+++ b/scripts/dtc/util.h
@@ -0,0 +1,56 @@
1#ifndef _UTIL_H
2#define _UTIL_H
3
4/*
5 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 */
22
23static inline void __attribute__((noreturn)) die(char * str, ...)
24{
25 va_list ap;
26
27 va_start(ap, str);
28 fprintf(stderr, "FATAL ERROR: ");
29 vfprintf(stderr, str, ap);
30 exit(1);
31}
32
33static inline void *xmalloc(size_t len)
34{
35 void *new = malloc(len);
36
37 if (!new)
38 die("malloc() failed\n");
39
40 return new;
41}
42
43static inline void *xrealloc(void *p, size_t len)
44{
45 void *new = realloc(p, len);
46
47 if (!new)
48 die("realloc() failed (len=%d)\n", len);
49
50 return new;
51}
52
53extern char *xstrdup(const char *s);
54extern char *join_path(const char *path, const char *name);
55
56#endif /* _UTIL_H */
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 658ff42429d6..6158b867df99 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
#define DTC_VERSION "DTC 1.2.0" #define DTC_VERSION "DTC 1.2.0-g37c0b6a0"
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/extract-ikconfig b/scripts/extract-ikconfig
index 72997c353cb3..1512c0a755ac 100755
--- a/scripts/extract-ikconfig
+++ b/scripts/extract-ikconfig
@@ -1,78 +1,66 @@
1#!/bin/sh 1#!/bin/sh
2# extracts .config info from a [b]zImage file 2# ----------------------------------------------------------------------
3# uses: binoffset (new), dd, zcat, strings, grep 3# extract-ikconfig - Extract the .config file from a kernel image
4# $arg1 is [b]zImage filename 4#
5 5# This will only work when the kernel was compiled with CONFIG_IKCONFIG.
6binoffset="./scripts/binoffset" 6#
7test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1 7# The obscure use of the "tr" filter is to work around older versions of
8 8# "grep" that report the byte offset of the line instead of the pattern.
9IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54" 9#
10IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44" 10# (c) 2009,2010 Dick Streefland <dick@streefland.net>
11dump_config() { 11# Licensed under the terms of the GNU General Public License.
12 file="$1" 12# ----------------------------------------------------------------------
13 13
14 start=`$binoffset $file $IKCFG_ST 2>/dev/null` 14cf1='IKCFG_ST\037\213\010'
15 [ "$?" != "0" ] && start="-1" 15cf2='0123456789'
16 if [ "$start" -eq "-1" ]; then 16
17 return 17dump_config()
18 fi
19 end=`$binoffset $file $IKCFG_ED 2>/dev/null`
20
21 start=`expr $start + 8`
22 size=`expr $end - $start`
23
24 dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat
25
26 clean_up
27 exit 0
28}
29
30
31usage()
32{ 18{
33 echo " usage: extract-ikconfig [b]zImage_filename" 19 if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
20 then
21 pos=${pos%%:*}
22 tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null
23 if [ $? != 1 ]
24 then # exit status must be 0 or 2 (trailing garbage warning)
25 cat $tmp1
26 exit 0
27 fi
28 fi
34} 29}
35 30
36clean_up() 31try_decompress()
37{ 32{
38 if [ "$TMPFILE" != "" ]; then 33 for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
39 rm -f $TMPFILE 34 do
40 fi 35 pos=${pos%%:*}
36 tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null
37 dump_config $tmp2
38 done
41} 39}
42 40
43if [ $# -lt 1 ] 41# Check invocation:
42me=${0##*/}
43img=$1
44if [ $# -ne 1 -o ! -s "$img" ]
44then 45then
45 usage 46 echo "Usage: $me <kernel-image>" >&2
46 exit 1 47 exit 2
47fi 48fi
48 49
49TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1 50# Prepare temp files:
50image="$1" 51tmp1=/tmp/ikconfig$$.1
51 52tmp2=/tmp/ikconfig$$.2
52# vmlinux: Attempt to dump the configuration from the file directly 53trap "rm -f $tmp1 $tmp2" 0
53dump_config "$image"
54 54
55GZHDR1="0x1f 0x8b 0x08 0x00" 55# Initial attempt for uncompressed images or objects:
56GZHDR2="0x1f 0x8b 0x08 0x08" 56dump_config "$img"
57
58# vmlinux.gz: Check for a compressed images
59off=`$binoffset "$image" $GZHDR1 2>/dev/null`
60[ "$?" != "0" ] && off="-1"
61if [ "$off" -eq "-1" ]; then
62 off=`$binoffset "$image" $GZHDR2 2>/dev/null`
63 [ "$?" != "0" ] && off="-1"
64fi
65if [ "$off" -eq "0" ]; then
66 zcat <"$image" >"$TMPFILE"
67 dump_config "$TMPFILE"
68elif [ "$off" -ne "-1" ]; then
69 (dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \
70 zcat >"$TMPFILE"
71 dump_config "$TMPFILE"
72fi
73 57
74echo "ERROR: Unable to extract kernel configuration information." 58# That didn't work, so retry after decompression.
75echo " This kernel image may not have the config info." 59try_decompress '\037\213\010' xy gunzip
60try_decompress 'BZh' xy bunzip2
61try_decompress '\135\0\0\0' xxx unlzma
62try_decompress '\211\114\132' xy 'lzop -d'
76 63
77clean_up 64# Bail out:
65echo "$me: Cannot find kernel config." >&2
78exit 1 66exit 1
diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh
new file mode 100644
index 000000000000..520d16b1ffaf
--- /dev/null
+++ b/scripts/gcc-goto.sh
@@ -0,0 +1,5 @@
1#!/bin/sh
2# Test for gcc 'asm goto' suport
3# Copyright (C) 2010, Jason Baron <jbaron@redhat.com>
4
5echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y"
diff --git a/scripts/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 3a8297b5184c..f99115ebe925 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -176,7 +176,7 @@ static int is_unknown_symbol(struct symbol *sym)
176 strcmp(defn->string, "{") == 0); 176 strcmp(defn->string, "{") == 0);
177} 177}
178 178
179struct symbol *__add_symbol(const char *name, enum symbol_type type, 179static struct symbol *__add_symbol(const char *name, enum symbol_type type,
180 struct string_list *defn, int is_extern, 180 struct string_list *defn, int is_extern,
181 int is_reference) 181 int is_reference)
182{ 182{
@@ -265,7 +265,7 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
265 return __add_symbol(name, type, defn, is_extern, 0); 265 return __add_symbol(name, type, defn, is_extern, 0);
266} 266}
267 267
268struct symbol *add_reference_symbol(const char *name, enum symbol_type type, 268static struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
269 struct string_list *defn, int is_extern) 269 struct string_list *defn, int is_extern)
270{ 270{
271 return __add_symbol(name, type, defn, is_extern, 1); 271 return __add_symbol(name, type, defn, is_extern, 1);
@@ -313,7 +313,7 @@ static int equal_list(struct string_list *a, struct string_list *b)
313 313
314#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 314#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
315 315
316struct string_list *read_node(FILE *f) 316static struct string_list *read_node(FILE *f)
317{ 317{
318 char buffer[256]; 318 char buffer[256];
319 struct string_list node = { 319 struct string_list node = {
@@ -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/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index 971e0113ae7a..8060e06798b3 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -1,4 +1,4 @@
1/* ANSI-C code produced by gperf version 3.0.2 */ 1/* ANSI-C code produced by gperf version 3.0.4 */
2/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ 2/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */
3 3
4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -30,9 +30,11 @@
30 30
31#line 1 "scripts/genksyms/keywords.gperf" 31#line 1 "scripts/genksyms/keywords.gperf"
32 32
33#line 3 "scripts/genksyms/keywords.gperf" 33struct resword;
34static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
35#line 5 "scripts/genksyms/keywords.gperf"
34struct resword { const char *name; int token; }; 36struct resword { const char *name; int token; };
35/* maximum key range = 62, duplicates = 0 */ 37/* maximum key range = 64, duplicates = 0 */
36 38
37#ifdef __GNUC__ 39#ifdef __GNUC__
38__inline 40__inline
@@ -46,154 +48,160 @@ is_reserved_hash (register const char *str, register unsigned int len)
46{ 48{
47 static const unsigned char asso_values[] = 49 static const unsigned char asso_values[] =
48 { 50 {
49 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 51 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
50 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 52 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
51 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 53 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
52 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 54 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
53 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
54 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 56 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
55 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, 57 67, 67, 67, 67, 67, 67, 67, 67, 67, 0,
56 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, 58 67, 67, 67, 67, 67, 67, 15, 67, 67, 67,
57 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, 59 0, 67, 67, 67, 67, 67, 67, 67, 67, 67,
58 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, 60 67, 67, 67, 67, 67, 0, 67, 0, 67, 5,
59 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, 61 25, 20, 15, 30, 67, 15, 67, 67, 10, 0,
60 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, 62 10, 40, 20, 67, 10, 5, 0, 10, 15, 67,
61 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 63 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
62 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 64 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
63 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
64 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
65 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 67 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
66 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 68 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
67 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 69 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
68 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
69 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 71 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
70 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 72 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
71 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 73 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
72 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 74 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
73 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 75 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
74 65, 65, 65, 65, 65, 65 76 67, 67, 67, 67, 67, 67
75 }; 77 };
76 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; 78 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
77} 79}
78 80
79#ifdef __GNUC__ 81#ifdef __GNUC__
80__inline 82__inline
83#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
84__attribute__ ((__gnu_inline__))
85#endif
81#endif 86#endif
82const struct resword * 87const struct resword *
83is_reserved_word (register const char *str, register unsigned int len) 88is_reserved_word (register const char *str, register unsigned int len)
84{ 89{
85 enum 90 enum
86 { 91 {
87 TOTAL_KEYWORDS = 43, 92 TOTAL_KEYWORDS = 45,
88 MIN_WORD_LENGTH = 3, 93 MIN_WORD_LENGTH = 3,
89 MAX_WORD_LENGTH = 24, 94 MAX_WORD_LENGTH = 24,
90 MIN_HASH_VALUE = 3, 95 MIN_HASH_VALUE = 3,
91 MAX_HASH_VALUE = 64 96 MAX_HASH_VALUE = 66
92 }; 97 };
93 98
94 static const struct resword wordlist[] = 99 static const struct resword wordlist[] =
95 { 100 {
96 {""}, {""}, {""}, 101 {""}, {""}, {""},
97#line 26 "scripts/genksyms/keywords.gperf" 102#line 30 "scripts/genksyms/keywords.gperf"
98 {"asm", ASM_KEYW}, 103 {"asm", ASM_KEYW},
99 {""}, 104 {""},
100#line 8 "scripts/genksyms/keywords.gperf" 105#line 12 "scripts/genksyms/keywords.gperf"
101 {"__asm", ASM_KEYW}, 106 {"__asm", ASM_KEYW},
102 {""}, 107 {""},
103#line 9 "scripts/genksyms/keywords.gperf" 108#line 13 "scripts/genksyms/keywords.gperf"
104 {"__asm__", ASM_KEYW}, 109 {"__asm__", ASM_KEYW},
105 {""}, {""}, 110 {""}, {""},
106#line 52 "scripts/genksyms/keywords.gperf" 111#line 56 "scripts/genksyms/keywords.gperf"
107 {"__typeof__", TYPEOF_KEYW}, 112 {"__typeof__", TYPEOF_KEYW},
108 {""}, 113 {""},
109#line 12 "scripts/genksyms/keywords.gperf" 114#line 16 "scripts/genksyms/keywords.gperf"
110 {"__const", CONST_KEYW}, 115 {"__const", CONST_KEYW},
111#line 11 "scripts/genksyms/keywords.gperf" 116#line 15 "scripts/genksyms/keywords.gperf"
112 {"__attribute__", ATTRIBUTE_KEYW}, 117 {"__attribute__", ATTRIBUTE_KEYW},
113#line 13 "scripts/genksyms/keywords.gperf" 118#line 17 "scripts/genksyms/keywords.gperf"
114 {"__const__", CONST_KEYW}, 119 {"__const__", CONST_KEYW},
115#line 18 "scripts/genksyms/keywords.gperf" 120#line 22 "scripts/genksyms/keywords.gperf"
116 {"__signed__", SIGNED_KEYW}, 121 {"__signed__", SIGNED_KEYW},
117#line 44 "scripts/genksyms/keywords.gperf" 122#line 48 "scripts/genksyms/keywords.gperf"
118 {"static", STATIC_KEYW}, 123 {"static", STATIC_KEYW},
119#line 20 "scripts/genksyms/keywords.gperf" 124 {""},
120 {"__volatile__", VOLATILE_KEYW}, 125#line 43 "scripts/genksyms/keywords.gperf"
121#line 39 "scripts/genksyms/keywords.gperf"
122 {"int", INT_KEYW}, 126 {"int", INT_KEYW},
123#line 32 "scripts/genksyms/keywords.gperf" 127#line 36 "scripts/genksyms/keywords.gperf"
124 {"char", CHAR_KEYW}, 128 {"char", CHAR_KEYW},
125#line 33 "scripts/genksyms/keywords.gperf" 129#line 37 "scripts/genksyms/keywords.gperf"
126 {"const", CONST_KEYW}, 130 {"const", CONST_KEYW},
127#line 45 "scripts/genksyms/keywords.gperf" 131#line 49 "scripts/genksyms/keywords.gperf"
128 {"struct", STRUCT_KEYW}, 132 {"struct", STRUCT_KEYW},
129#line 24 "scripts/genksyms/keywords.gperf" 133#line 28 "scripts/genksyms/keywords.gperf"
130 {"__restrict__", RESTRICT_KEYW}, 134 {"__restrict__", RESTRICT_KEYW},
131#line 25 "scripts/genksyms/keywords.gperf" 135#line 29 "scripts/genksyms/keywords.gperf"
132 {"restrict", RESTRICT_KEYW}, 136 {"restrict", RESTRICT_KEYW},
133#line 23 "scripts/genksyms/keywords.gperf" 137#line 9 "scripts/genksyms/keywords.gperf"
134 {"_restrict", RESTRICT_KEYW}, 138 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
135#line 16 "scripts/genksyms/keywords.gperf" 139#line 20 "scripts/genksyms/keywords.gperf"
136 {"__inline__", INLINE_KEYW}, 140 {"__inline__", INLINE_KEYW},
137#line 10 "scripts/genksyms/keywords.gperf" 141 {""},
138 {"__attribute", ATTRIBUTE_KEYW}, 142#line 24 "scripts/genksyms/keywords.gperf"
143 {"__volatile__", VOLATILE_KEYW},
144#line 7 "scripts/genksyms/keywords.gperf"
145 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
146#line 27 "scripts/genksyms/keywords.gperf"
147 {"_restrict", RESTRICT_KEYW},
139 {""}, 148 {""},
140#line 14 "scripts/genksyms/keywords.gperf" 149#line 14 "scripts/genksyms/keywords.gperf"
150 {"__attribute", ATTRIBUTE_KEYW},
151#line 8 "scripts/genksyms/keywords.gperf"
152 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
153#line 18 "scripts/genksyms/keywords.gperf"
141 {"__extension__", EXTENSION_KEYW}, 154 {"__extension__", EXTENSION_KEYW},
142#line 35 "scripts/genksyms/keywords.gperf" 155#line 39 "scripts/genksyms/keywords.gperf"
143 {"enum", ENUM_KEYW}, 156 {"enum", ENUM_KEYW},
144#line 19 "scripts/genksyms/keywords.gperf" 157#line 10 "scripts/genksyms/keywords.gperf"
145 {"__volatile", VOLATILE_KEYW}, 158 {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
146#line 36 "scripts/genksyms/keywords.gperf" 159#line 40 "scripts/genksyms/keywords.gperf"
147 {"extern", EXTERN_KEYW}, 160 {"extern", EXTERN_KEYW},
148 {""}, 161 {""},
149#line 17 "scripts/genksyms/keywords.gperf" 162#line 21 "scripts/genksyms/keywords.gperf"
150 {"__signed", SIGNED_KEYW}, 163 {"__signed", SIGNED_KEYW},
151#line 7 "scripts/genksyms/keywords.gperf" 164#line 11 "scripts/genksyms/keywords.gperf"
152 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, 165 {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
153 {""},
154#line 51 "scripts/genksyms/keywords.gperf" 166#line 51 "scripts/genksyms/keywords.gperf"
167 {"union", UNION_KEYW},
168#line 55 "scripts/genksyms/keywords.gperf"
155 {"typeof", TYPEOF_KEYW}, 169 {"typeof", TYPEOF_KEYW},
156#line 46 "scripts/genksyms/keywords.gperf" 170#line 50 "scripts/genksyms/keywords.gperf"
157 {"typedef", TYPEDEF_KEYW}, 171 {"typedef", TYPEDEF_KEYW},
158#line 15 "scripts/genksyms/keywords.gperf" 172#line 19 "scripts/genksyms/keywords.gperf"
159 {"__inline", INLINE_KEYW}, 173 {"__inline", INLINE_KEYW},
160#line 31 "scripts/genksyms/keywords.gperf" 174#line 35 "scripts/genksyms/keywords.gperf"
161 {"auto", AUTO_KEYW}, 175 {"auto", AUTO_KEYW},
162#line 47 "scripts/genksyms/keywords.gperf" 176#line 23 "scripts/genksyms/keywords.gperf"
163 {"union", UNION_KEYW}, 177 {"__volatile", VOLATILE_KEYW},
164 {""}, {""}, 178 {""}, {""},
165#line 48 "scripts/genksyms/keywords.gperf" 179#line 52 "scripts/genksyms/keywords.gperf"
166 {"unsigned", UNSIGNED_KEYW}, 180 {"unsigned", UNSIGNED_KEYW},
167#line 49 "scripts/genksyms/keywords.gperf"
168 {"void", VOID_KEYW},
169#line 42 "scripts/genksyms/keywords.gperf"
170 {"short", SHORT_KEYW},
171 {""}, {""},
172#line 50 "scripts/genksyms/keywords.gperf"
173 {"volatile", VOLATILE_KEYW},
174 {""},
175#line 37 "scripts/genksyms/keywords.gperf"
176 {"float", FLOAT_KEYW},
177#line 34 "scripts/genksyms/keywords.gperf"
178 {"double", DOUBLE_KEYW},
179 {""}, 181 {""},
180#line 5 "scripts/genksyms/keywords.gperf" 182#line 46 "scripts/genksyms/keywords.gperf"
181 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, 183 {"short", SHORT_KEYW},
182 {""}, {""}, 184#line 42 "scripts/genksyms/keywords.gperf"
183#line 38 "scripts/genksyms/keywords.gperf"
184 {"inline", INLINE_KEYW}, 185 {"inline", INLINE_KEYW},
185#line 6 "scripts/genksyms/keywords.gperf"
186 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
187#line 41 "scripts/genksyms/keywords.gperf"
188 {"register", REGISTER_KEYW},
189 {""}, 186 {""},
190#line 22 "scripts/genksyms/keywords.gperf" 187#line 54 "scripts/genksyms/keywords.gperf"
188 {"volatile", VOLATILE_KEYW},
189#line 44 "scripts/genksyms/keywords.gperf"
190 {"long", LONG_KEYW},
191#line 26 "scripts/genksyms/keywords.gperf"
191 {"_Bool", BOOL_KEYW}, 192 {"_Bool", BOOL_KEYW},
192#line 43 "scripts/genksyms/keywords.gperf"
193 {"signed", SIGNED_KEYW},
194 {""}, {""}, 193 {""}, {""},
195#line 40 "scripts/genksyms/keywords.gperf" 194#line 45 "scripts/genksyms/keywords.gperf"
196 {"long", LONG_KEYW} 195 {"register", REGISTER_KEYW},
196#line 53 "scripts/genksyms/keywords.gperf"
197 {"void", VOID_KEYW},
198#line 41 "scripts/genksyms/keywords.gperf"
199 {"float", FLOAT_KEYW},
200#line 38 "scripts/genksyms/keywords.gperf"
201 {"double", DOUBLE_KEYW},
202 {""}, {""}, {""}, {""},
203#line 47 "scripts/genksyms/keywords.gperf"
204 {"signed", SIGNED_KEYW}
197 }; 205 };
198 206
199 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 207 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
index 5ef3733225fb..e6349acb6f2f 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -1,10 +1,14 @@
1%{ 1%{
2struct resword;
3static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
2%} 4%}
3struct resword { const char *name; int token; } 5struct resword { const char *name; int token; }
4%% 6%%
5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW 7EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW 8EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
7EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW 9EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
10EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW
11EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
8__asm, ASM_KEYW 12__asm, ASM_KEYW
9__asm__, ASM_KEYW 13__asm__, ASM_KEYW
10__attribute, ATTRIBUTE_KEYW 14__attribute, ATTRIBUTE_KEYW
diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped
index eaee44e66a43..809b949e495b 100644
--- a/scripts/genksyms/parse.c_shipped
+++ b/scripts/genksyms/parse.c_shipped
@@ -160,7 +160,7 @@
160 160
161 161
162#include <assert.h> 162#include <assert.h>
163#include <malloc.h> 163#include <stdlib.h>
164#include "genksyms.h" 164#include "genksyms.h"
165 165
166static int is_typedef; 166static int is_typedef;
diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y
index 10d7dc724b6d..09a265cd7193 100644
--- a/scripts/genksyms/parse.y
+++ b/scripts/genksyms/parse.y
@@ -24,7 +24,7 @@
24%{ 24%{
25 25
26#include <assert.h> 26#include <assert.h>
27#include <malloc.h> 27#include <stdlib.h>
28#include "genksyms.h" 28#include "genksyms.h"
29 29
30static int is_typedef; 30static int is_typedef;
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 3e733146cd51..d21ec3a89603 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -5,15 +5,15 @@
5# Print selected MAINTAINERS information for 5# Print selected MAINTAINERS information for
6# the files modified in a patch or for a file 6# the files modified in a patch or for a file
7# 7#
8# usage: perl scripts/get_maintainers.pl [OPTIONS] <patch> 8# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
9# perl scripts/get_maintainers.pl [OPTIONS] -f <file> 9# perl scripts/get_maintainer.pl [OPTIONS] -f <file>
10# 10#
11# Licensed under the terms of the GNU GPL License version 2 11# Licensed under the terms of the GNU GPL License version 2
12 12
13use strict; 13use strict;
14 14
15my $P = $0; 15my $P = $0;
16my $V = '0.16'; 16my $V = '0.26-beta6';
17 17
18use Getopt::Long qw(:config no_auto_abbrev); 18use Getopt::Long qw(:config no_auto_abbrev);
19 19
@@ -23,27 +23,47 @@ my $email_usename = 1;
23my $email_maintainer = 1; 23my $email_maintainer = 1;
24my $email_list = 1; 24my $email_list = 1;
25my $email_subscriber_list = 0; 25my $email_subscriber_list = 0;
26my $email_git = 1;
27my $email_git_penguin_chiefs = 0; 26my $email_git_penguin_chiefs = 0;
27my $email_git = 0;
28my $email_git_all_signature_types = 0;
29my $email_git_blame = 0;
30my $email_git_blame_signatures = 1;
31my $email_git_fallback = 1;
28my $email_git_min_signatures = 1; 32my $email_git_min_signatures = 1;
29my $email_git_max_maintainers = 5; 33my $email_git_max_maintainers = 5;
34my $email_git_min_percent = 5;
30my $email_git_since = "1-year-ago"; 35my $email_git_since = "1-year-ago";
36my $email_hg_since = "-365";
37my $interactive = 0;
38my $email_remove_duplicates = 1;
39my $email_use_mailmap = 1;
31my $output_multiline = 1; 40my $output_multiline = 1;
32my $output_separator = ", "; 41my $output_separator = ", ";
42my $output_roles = 0;
43my $output_rolestats = 0;
33my $scm = 0; 44my $scm = 0;
34my $web = 0; 45my $web = 0;
35my $subsystem = 0; 46my $subsystem = 0;
36my $status = 0; 47my $status = 0;
48my $keywords = 1;
49my $sections = 0;
50my $file_emails = 0;
37my $from_filename = 0; 51my $from_filename = 0;
52my $pattern_depth = 0;
38my $version = 0; 53my $version = 0;
39my $help = 0; 54my $help = 0;
40 55
56my $vcs_used = 0;
57
41my $exit = 0; 58my $exit = 0;
42 59
60my %commit_author_hash;
61my %commit_signer_hash;
62
43my @penguin_chief = (); 63my @penguin_chief = ();
44push(@penguin_chief,"Linus Torvalds:torvalds\@linux-foundation.org"); 64push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org");
45#Andrew wants in on most everything - 2009/01/14 65#Andrew wants in on most everything - 2009/01/14
46#push(@penguin_chief,"Andrew Morton:akpm\@linux-foundation.org"); 66#push(@penguin_chief, "Andrew Morton:akpm\@linux-foundation.org");
47 67
48my @penguin_chief_names = (); 68my @penguin_chief_names = ();
49foreach my $chief (@penguin_chief) { 69foreach my $chief (@penguin_chief) {
@@ -53,35 +73,148 @@ foreach my $chief (@penguin_chief) {
53 push(@penguin_chief_names, $chief_name); 73 push(@penguin_chief_names, $chief_name);
54 } 74 }
55} 75}
56my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)"; 76my $penguin_chiefs = "\(" . join("|", @penguin_chief_names) . "\)";
77
78# Signature types of people who are either
79# a) responsible for the code in question, or
80# b) familiar enough with it to give relevant feedback
81my @signature_tags = ();
82push(@signature_tags, "Signed-off-by:");
83push(@signature_tags, "Reviewed-by:");
84push(@signature_tags, "Acked-by:");
57 85
58# rfc822 email address - preloaded methods go here. 86# rfc822 email address - preloaded methods go here.
59my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])"; 87my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
60my $rfc822_char = '[\\000-\\377]'; 88my $rfc822_char = '[\\000-\\377]';
61 89
90# VCS command support: class-like functions and strings
91
92my %VCS_cmds;
93
94my %VCS_cmds_git = (
95 "execute_cmd" => \&git_execute_cmd,
96 "available" => '(which("git") ne "") && (-d ".git")',
97 "find_signers_cmd" =>
98 "git log --no-color --since=\$email_git_since " .
99 '--format="GitCommit: %H%n' .
100 'GitAuthor: %an <%ae>%n' .
101 'GitDate: %aD%n' .
102 'GitSubject: %s%n' .
103 '%b%n"' .
104 " -- \$file",
105 "find_commit_signers_cmd" =>
106 "git log --no-color " .
107 '--format="GitCommit: %H%n' .
108 'GitAuthor: %an <%ae>%n' .
109 'GitDate: %aD%n' .
110 'GitSubject: %s%n' .
111 '%b%n"' .
112 " -1 \$commit",
113 "find_commit_author_cmd" =>
114 "git log --no-color " .
115 '--format="GitCommit: %H%n' .
116 'GitAuthor: %an <%ae>%n' .
117 'GitDate: %aD%n' .
118 'GitSubject: %s%n"' .
119 " -1 \$commit",
120 "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file",
121 "blame_file_cmd" => "git blame -l \$file",
122 "commit_pattern" => "^GitCommit: ([0-9a-f]{40,40})",
123 "blame_commit_pattern" => "^([0-9a-f]+) ",
124 "author_pattern" => "^GitAuthor: (.*)",
125 "subject_pattern" => "^GitSubject: (.*)",
126);
127
128my %VCS_cmds_hg = (
129 "execute_cmd" => \&hg_execute_cmd,
130 "available" => '(which("hg") ne "") && (-d ".hg")',
131 "find_signers_cmd" =>
132 "hg log --date=\$email_hg_since " .
133 "--template='HgCommit: {node}\\n" .
134 "HgAuthor: {author}\\n" .
135 "HgSubject: {desc}\\n'" .
136 " -- \$file",
137 "find_commit_signers_cmd" =>
138 "hg log " .
139 "--template='HgSubject: {desc}\\n'" .
140 " -r \$commit",
141 "find_commit_author_cmd" =>
142 "hg log " .
143 "--template='HgCommit: {node}\\n" .
144 "HgAuthor: {author}\\n" .
145 "HgSubject: {desc|firstline}\\n'" .
146 " -r \$commit",
147 "blame_range_cmd" => "", # not supported
148 "blame_file_cmd" => "hg blame -n \$file",
149 "commit_pattern" => "^HgCommit: ([0-9a-f]{40,40})",
150 "blame_commit_pattern" => "^([ 0-9a-f]+):",
151 "author_pattern" => "^HgAuthor: (.*)",
152 "subject_pattern" => "^HgSubject: (.*)",
153);
154
155my $conf = which_conf(".get_maintainer.conf");
156if (-f $conf) {
157 my @conf_args;
158 open(my $conffile, '<', "$conf")
159 or warn "$P: Can't find a readable .get_maintainer.conf file $!\n";
160
161 while (<$conffile>) {
162 my $line = $_;
163
164 $line =~ s/\s*\n?$//g;
165 $line =~ s/^\s*//g;
166 $line =~ s/\s+/ /g;
167
168 next if ($line =~ m/^\s*#/);
169 next if ($line =~ m/^\s*$/);
170
171 my @words = split(" ", $line);
172 foreach my $word (@words) {
173 last if ($word =~ m/^#/);
174 push (@conf_args, $word);
175 }
176 }
177 close($conffile);
178 unshift(@ARGV, @conf_args) if @conf_args;
179}
180
62if (!GetOptions( 181if (!GetOptions(
63 'email!' => \$email, 182 'email!' => \$email,
64 'git!' => \$email_git, 183 'git!' => \$email_git,
184 'git-all-signature-types!' => \$email_git_all_signature_types,
185 'git-blame!' => \$email_git_blame,
186 'git-blame-signatures!' => \$email_git_blame_signatures,
187 'git-fallback!' => \$email_git_fallback,
65 'git-chief-penguins!' => \$email_git_penguin_chiefs, 188 'git-chief-penguins!' => \$email_git_penguin_chiefs,
66 'git-min-signatures=i' => \$email_git_min_signatures, 189 'git-min-signatures=i' => \$email_git_min_signatures,
67 'git-max-maintainers=i' => \$email_git_max_maintainers, 190 'git-max-maintainers=i' => \$email_git_max_maintainers,
191 'git-min-percent=i' => \$email_git_min_percent,
68 'git-since=s' => \$email_git_since, 192 'git-since=s' => \$email_git_since,
193 'hg-since=s' => \$email_hg_since,
194 'i|interactive!' => \$interactive,
195 'remove-duplicates!' => \$email_remove_duplicates,
196 'mailmap!' => \$email_use_mailmap,
69 'm!' => \$email_maintainer, 197 'm!' => \$email_maintainer,
70 'n!' => \$email_usename, 198 'n!' => \$email_usename,
71 'l!' => \$email_list, 199 'l!' => \$email_list,
72 's!' => \$email_subscriber_list, 200 's!' => \$email_subscriber_list,
73 'multiline!' => \$output_multiline, 201 'multiline!' => \$output_multiline,
202 'roles!' => \$output_roles,
203 'rolestats!' => \$output_rolestats,
74 'separator=s' => \$output_separator, 204 'separator=s' => \$output_separator,
75 'subsystem!' => \$subsystem, 205 'subsystem!' => \$subsystem,
76 'status!' => \$status, 206 'status!' => \$status,
77 'scm!' => \$scm, 207 'scm!' => \$scm,
78 'web!' => \$web, 208 'web!' => \$web,
209 'pattern-depth=i' => \$pattern_depth,
210 'k|keywords!' => \$keywords,
211 'sections!' => \$sections,
212 'fe|file-emails!' => \$file_emails,
79 'f|file' => \$from_filename, 213 'f|file' => \$from_filename,
80 'v|version' => \$version, 214 'v|version' => \$version,
81 'h|help' => \$help, 215 'h|help|usage' => \$help,
82 )) { 216 )) {
83 usage(); 217 die "$P: invalid argument - use --help if necessary\n";
84 die "$P: invalid argument\n";
85} 218}
86 219
87if ($help != 0) { 220if ($help != 0) {
@@ -94,20 +227,34 @@ if ($version != 0) {
94 exit 0; 227 exit 0;
95} 228}
96 229
97if ($#ARGV < 0) { 230if (-t STDIN && !@ARGV) {
98 usage(); 231 # We're talking to a terminal, but have no command line arguments.
99 die "$P: argument missing: patchfile or -f file please\n"; 232 die "$P: missing patchfile or -f file - use --help if necessary\n";
100} 233}
101 234
102my $selections = $email + $scm + $status + $subsystem + $web; 235$output_multiline = 0 if ($output_separator ne ", ");
103if ($selections == 0) { 236$output_rolestats = 1 if ($interactive);
104 usage(); 237$output_roles = 1 if ($output_rolestats);
105 die "$P: Missing required option: email, scm, status, subsystem or web\n"; 238
239if ($sections) {
240 $email = 0;
241 $email_list = 0;
242 $scm = 0;
243 $status = 0;
244 $subsystem = 0;
245 $web = 0;
246 $keywords = 0;
247 $interactive = 0;
248} else {
249 my $selections = $email + $scm + $status + $subsystem + $web;
250 if ($selections == 0) {
251 die "$P: Missing required option: email, scm, status, subsystem or web\n";
252 }
106} 253}
107 254
108if ($email && ($email_maintainer + $email_list + $email_subscriber_list 255if ($email &&
109 + $email_git + $email_git_penguin_chiefs) == 0) { 256 ($email_maintainer + $email_list + $email_subscriber_list +
110 usage(); 257 $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
111 die "$P: Please select at least 1 email option\n"; 258 die "$P: Please select at least 1 email option\n";
112} 259}
113 260
@@ -119,8 +266,11 @@ if (!top_of_kernel_tree($lk_path)) {
119## Read MAINTAINERS for type/value pairs 266## Read MAINTAINERS for type/value pairs
120 267
121my @typevalue = (); 268my @typevalue = ();
122open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n"; 269my %keyword_hash;
123while (<MAINT>) { 270
271open (my $maint, '<', "${lk_path}MAINTAINERS")
272 or die "$P: Can't open MAINTAINERS: $!\n";
273while (<$maint>) {
124 my $line = $_; 274 my $line = $_;
125 275
126 if ($line =~ m/^(\C):\s*(.*)/) { 276 if ($line =~ m/^(\C):\s*(.*)/) {
@@ -132,6 +282,12 @@ while (<MAINT>) {
132 $value =~ s@\.@\\\.@g; ##Convert . to \. 282 $value =~ s@\.@\\\.@g; ##Convert . to \.
133 $value =~ s/\*/\.\*/g; ##Convert * to .* 283 $value =~ s/\*/\.\*/g; ##Convert * to .*
134 $value =~ s/\?/\./g; ##Convert ? to . 284 $value =~ s/\?/\./g; ##Convert ? to .
285 ##if pattern is a directory and it lacks a trailing slash, add one
286 if ((-d $value)) {
287 $value =~ s@([^/])$@$1/@;
288 }
289 } elsif ($type eq "K") {
290 $keyword_hash{@typevalue} = $value;
135 } 291 }
136 push(@typevalue, "$type:$value"); 292 push(@typevalue, "$type:$value");
137 } elsif (!/^(\s)*$/) { 293 } elsif (!/^(\s)*$/) {
@@ -139,31 +295,153 @@ while (<MAINT>) {
139 push(@typevalue, $line); 295 push(@typevalue, $line);
140 } 296 }
141} 297}
142close(MAINT); 298close($maint);
299
300
301#
302# Read mail address map
303#
304
305my $mailmap;
306
307read_mailmap();
308
309sub read_mailmap {
310 $mailmap = {
311 names => {},
312 addresses => {}
313 };
314
315 return if (!$email_use_mailmap || !(-f "${lk_path}.mailmap"));
316
317 open(my $mailmap_file, '<', "${lk_path}.mailmap")
318 or warn "$P: Can't open .mailmap: $!\n";
319
320 while (<$mailmap_file>) {
321 s/#.*$//; #strip comments
322 s/^\s+|\s+$//g; #trim
323
324 next if (/^\s*$/); #skip empty lines
325 #entries have one of the following formats:
326 # name1 <mail1>
327 # <mail1> <mail2>
328 # name1 <mail1> <mail2>
329 # name1 <mail1> name2 <mail2>
330 # (see man git-shortlog)
331 if (/^(.+)<(.+)>$/) {
332 my $real_name = $1;
333 my $address = $2;
334
335 $real_name =~ s/\s+$//;
336 ($real_name, $address) = parse_email("$real_name <$address>");
337 $mailmap->{names}->{$address} = $real_name;
338
339 } elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) {
340 my $real_address = $1;
341 my $wrong_address = $2;
342
343 $mailmap->{addresses}->{$wrong_address} = $real_address;
344
345 } elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) {
346 my $real_name = $1;
347 my $real_address = $2;
348 my $wrong_address = $3;
349
350 $real_name =~ s/\s+$//;
351 ($real_name, $real_address) =
352 parse_email("$real_name <$real_address>");
353 $mailmap->{names}->{$wrong_address} = $real_name;
354 $mailmap->{addresses}->{$wrong_address} = $real_address;
355
356 } elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) {
357 my $real_name = $1;
358 my $real_address = $2;
359 my $wrong_name = $3;
360 my $wrong_address = $4;
361
362 $real_name =~ s/\s+$//;
363 ($real_name, $real_address) =
364 parse_email("$real_name <$real_address>");
365
366 $wrong_name =~ s/\s+$//;
367 ($wrong_name, $wrong_address) =
368 parse_email("$wrong_name <$wrong_address>");
369
370 my $wrong_email = format_email($wrong_name, $wrong_address, 1);
371 $mailmap->{names}->{$wrong_email} = $real_name;
372 $mailmap->{addresses}->{$wrong_email} = $real_address;
373 }
374 }
375 close($mailmap_file);
376}
143 377
144## use the filenames on the command line or find the filenames in the patchfiles 378## use the filenames on the command line or find the filenames in the patchfiles
145 379
146my @files = (); 380my @files = ();
381my @range = ();
382my @keyword_tvi = ();
383my @file_emails = ();
384
385if (!@ARGV) {
386 push(@ARGV, "&STDIN");
387}
147 388
148foreach my $file (@ARGV) { 389foreach my $file (@ARGV) {
149 next if ((-d $file)); 390 if ($file ne "&STDIN") {
150 if (!(-f $file)) { 391 ##if $file is a directory and it lacks a trailing slash, add one
151 die "$P: file '${file}' not found\n"; 392 if ((-d $file)) {
393 $file =~ s@([^/])$@$1/@;
394 } elsif (!(-f $file)) {
395 die "$P: file '${file}' not found\n";
396 }
152 } 397 }
153 if ($from_filename) { 398 if ($from_filename) {
154 push(@files, $file); 399 push(@files, $file);
400 if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
401 open(my $f, '<', $file)
402 or die "$P: Can't open $file: $!\n";
403 my $text = do { local($/) ; <$f> };
404 close($f);
405 if ($keywords) {
406 foreach my $line (keys %keyword_hash) {
407 if ($text =~ m/$keyword_hash{$line}/x) {
408 push(@keyword_tvi, $line);
409 }
410 }
411 }
412 if ($file_emails) {
413 my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
414 push(@file_emails, clean_file_emails(@poss_addr));
415 }
416 }
155 } else { 417 } else {
156 my $file_cnt = @files; 418 my $file_cnt = @files;
157 open(PATCH, "<$file") or die "$P: Can't open ${file}\n"; 419 my $lastfile;
158 while (<PATCH>) { 420
421 open(my $patch, "< $file")
422 or die "$P: Can't open $file: $!\n";
423 while (<$patch>) {
424 my $patch_line = $_;
159 if (m/^\+\+\+\s+(\S+)/) { 425 if (m/^\+\+\+\s+(\S+)/) {
160 my $filename = $1; 426 my $filename = $1;
161 $filename =~ s@^[^/]*/@@; 427 $filename =~ s@^[^/]*/@@;
162 $filename =~ s@\n@@; 428 $filename =~ s@\n@@;
429 $lastfile = $filename;
163 push(@files, $filename); 430 push(@files, $filename);
431 } elsif (m/^\@\@ -(\d+),(\d+)/) {
432 if ($email_git_blame) {
433 push(@range, "$lastfile:$1:$2");
434 }
435 } elsif ($keywords) {
436 foreach my $line (keys %keyword_hash) {
437 if ($patch_line =~ m/^[+-].*$keyword_hash{$line}/x) {
438 push(@keyword_tvi, $line);
439 }
440 }
164 } 441 }
165 } 442 }
166 close(PATCH); 443 close($patch);
444
167 if ($file_cnt == @files) { 445 if ($file_cnt == @files) {
168 warn "$P: file '${file}' doesn't appear to be a patch. " 446 warn "$P: file '${file}' doesn't appear to be a patch. "
169 . "Add -f to options?\n"; 447 . "Add -f to options?\n";
@@ -172,104 +450,210 @@ foreach my $file (@ARGV) {
172 } 450 }
173} 451}
174 452
453@file_emails = uniq(@file_emails);
454
455my %email_hash_name;
456my %email_hash_address;
175my @email_to = (); 457my @email_to = ();
458my %hash_list_to;
176my @list_to = (); 459my @list_to = ();
177my @scm = (); 460my @scm = ();
178my @web = (); 461my @web = ();
179my @subsystem = (); 462my @subsystem = ();
180my @status = (); 463my @status = ();
464my %deduplicate_name_hash = ();
465my %deduplicate_address_hash = ();
466my $signature_pattern;
467
468my @maintainers = get_maintainers();
469
470if (@maintainers) {
471 @maintainers = merge_email(@maintainers);
472 output(@maintainers);
473}
474
475if ($scm) {
476 @scm = uniq(@scm);
477 output(@scm);
478}
479
480if ($status) {
481 @status = uniq(@status);
482 output(@status);
483}
484
485if ($subsystem) {
486 @subsystem = uniq(@subsystem);
487 output(@subsystem);
488}
489
490if ($web) {
491 @web = uniq(@web);
492 output(@web);
493}
494
495exit($exit);
496
497sub get_maintainers {
498 %email_hash_name = ();
499 %email_hash_address = ();
500 %commit_author_hash = ();
501 %commit_signer_hash = ();
502 @email_to = ();
503 %hash_list_to = ();
504 @list_to = ();
505 @scm = ();
506 @web = ();
507 @subsystem = ();
508 @status = ();
509 %deduplicate_name_hash = ();
510 %deduplicate_address_hash = ();
511 if ($email_git_all_signature_types) {
512 $signature_pattern = "(.+?)[Bb][Yy]:";
513 } else {
514 $signature_pattern = "\(" . join("|", @signature_tags) . "\)";
515 }
516
517 # Find responsible parties
518
519 my %exact_pattern_match_hash = ();
181 520
182# Find responsible parties 521 foreach my $file (@files) {
183 522
184foreach my $file (@files) { 523 my %hash;
524 my $tvi = find_first_section();
525 while ($tvi < @typevalue) {
526 my $start = find_starting_index($tvi);
527 my $end = find_ending_index($tvi);
528 my $exclude = 0;
529 my $i;
185 530
186#Do not match excluded file patterns 531 #Do not match excluded file patterns
187 532
188 my $exclude = 0; 533 for ($i = $start; $i < $end; $i++) {
189 foreach my $line (@typevalue) { 534 my $line = $typevalue[$i];
190 if ($line =~ m/^(\C):\s*(.*)/) { 535 if ($line =~ m/^(\C):\s*(.*)/) {
191 my $type = $1; 536 my $type = $1;
192 my $value = $2; 537 my $value = $2;
193 if ($type eq 'X') { 538 if ($type eq 'X') {
194 if (file_match_pattern($file, $value)) { 539 if (file_match_pattern($file, $value)) {
195 $exclude = 1; 540 $exclude = 1;
541 last;
542 }
543 }
544 }
545 }
546
547 if (!$exclude) {
548 for ($i = $start; $i < $end; $i++) {
549 my $line = $typevalue[$i];
550 if ($line =~ m/^(\C):\s*(.*)/) {
551 my $type = $1;
552 my $value = $2;
553 if ($type eq 'F') {
554 if (file_match_pattern($file, $value)) {
555 my $value_pd = ($value =~ tr@/@@);
556 my $file_pd = ($file =~ tr@/@@);
557 $value_pd++ if (substr($value,-1,1) ne "/");
558 $value_pd = -1 if ($value =~ /^\.\*/);
559 if ($value_pd >= $file_pd) {
560 $exact_pattern_match_hash{$file} = 1;
561 }
562 if ($pattern_depth == 0 ||
563 (($file_pd - $value_pd) < $pattern_depth)) {
564 $hash{$tvi} = $value_pd;
565 }
566 }
567 }
568 }
196 } 569 }
197 } 570 }
571 $tvi = $end + 1;
198 } 572 }
199 }
200 573
201 if (!$exclude) { 574 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
202 my $tvi = 0; 575 add_categories($line);
203 foreach my $line (@typevalue) { 576 if ($sections) {
204 if ($line =~ m/^(\C):\s*(.*)/) { 577 my $i;
205 my $type = $1; 578 my $start = find_starting_index($line);
206 my $value = $2; 579 my $end = find_ending_index($line);
207 if ($type eq 'F') { 580 for ($i = $start; $i < $end; $i++) {
208 if (file_match_pattern($file, $value)) { 581 my $line = $typevalue[$i];
209 add_categories($tvi); 582 if ($line =~ /^[FX]:/) { ##Restore file patterns
583 $line =~ s/([^\\])\.([^\*])/$1\?$2/g;
584 $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ?
585 $line =~ s/\\\./\./g; ##Convert \. to .
586 $line =~ s/\.\*/\*/g; ##Convert .* to *
210 } 587 }
588 $line =~ s/^([A-Z]):/$1:\t/g;
589 print("$line\n");
211 } 590 }
591 print("\n");
212 } 592 }
213 $tvi++;
214 } 593 }
215 } 594 }
216 595
217 if ($email && $email_git) { 596 if ($keywords) {
218 recent_git_signoffs($file); 597 @keyword_tvi = sort_and_uniq(@keyword_tvi);
598 foreach my $line (@keyword_tvi) {
599 add_categories($line);
600 }
219 } 601 }
220 602
221} 603 foreach my $email (@email_to, @list_to) {
604 $email->[0] = deduplicate_email($email->[0]);
605 }
222 606
223if ($email) { 607 foreach my $file (@files) {
224 foreach my $chief (@penguin_chief) { 608 if ($email &&
225 if ($chief =~ m/^(.*):(.*)/) { 609 ($email_git || ($email_git_fallback &&
226 my $email_address; 610 !$exact_pattern_match_hash{$file}))) {
227 if ($email_usename) { 611 vcs_file_signoffs($file);
228 $email_address = format_email($1, $2); 612 }
229 } else { 613 if ($email && $email_git_blame) {
230 $email_address = $2; 614 vcs_file_blame($file);
231 }
232 if ($email_git_penguin_chiefs) {
233 push(@email_to, $email_address);
234 } else {
235 @email_to = grep(!/${email_address}/, @email_to);
236 }
237 } 615 }
238 } 616 }
239}
240 617
241if ($email || $email_list) {
242 my @to = ();
243 if ($email) { 618 if ($email) {
244 @to = (@to, @email_to); 619 foreach my $chief (@penguin_chief) {
245 } 620 if ($chief =~ m/^(.*):(.*)/) {
246 if ($email_list) { 621 my $email_address;
247 @to = (@to, @list_to);
248 }
249 output(uniq(@to));
250}
251 622
252if ($scm) { 623 $email_address = format_email($1, $2, $email_usename);
253 @scm = sort_and_uniq(@scm); 624 if ($email_git_penguin_chiefs) {
254 output(@scm); 625 push(@email_to, [$email_address, 'chief penguin']);
255} 626 } else {
627 @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
628 }
629 }
630 }
256 631
257if ($status) { 632 foreach my $email (@file_emails) {
258 @status = sort_and_uniq(@status); 633 my ($name, $address) = parse_email($email);
259 output(@status);
260}
261 634
262if ($subsystem) { 635 my $tmp_email = format_email($name, $address, $email_usename);
263 @subsystem = sort_and_uniq(@subsystem); 636 push_email_address($tmp_email, '');
264 output(@subsystem); 637 add_role($tmp_email, 'in file');
265} 638 }
639 }
266 640
267if ($web) { 641 my @to = ();
268 @web = sort_and_uniq(@web); 642 if ($email || $email_list) {
269 output(@web); 643 if ($email) {
270} 644 @to = (@to, @email_to);
645 }
646 if ($email_list) {
647 @to = (@to, @list_to);
648 }
649 }
271 650
272exit($exit); 651 if ($interactive) {
652 @to = interactive_get_maintainers(\@to);
653 }
654
655 return @to;
656}
273 657
274sub file_match_pattern { 658sub file_match_pattern {
275 my ($file, $pattern) = @_; 659 my ($file, $pattern) = @_;
@@ -292,20 +676,31 @@ sub file_match_pattern {
292sub usage { 676sub usage {
293 print <<EOT; 677 print <<EOT;
294usage: $P [options] patchfile 678usage: $P [options] patchfile
295 $P [options] -f file 679 $P [options] -f file|directory
296version: $V 680version: $V
297 681
298MAINTAINER field selection options: 682MAINTAINER field selection options:
299 --email => print email address(es) if any 683 --email => print email address(es) if any
300 --git => include recent git \*-by: signers 684 --git => include recent git \*-by: signers
685 --git-all-signature-types => include signers regardless of signature type
686 or use only ${signature_pattern} signers (default: $email_git_all_signature_types)
687 --git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback)
301 --git-chief-penguins => include ${penguin_chiefs} 688 --git-chief-penguins => include ${penguin_chiefs}
302 --git-min-signatures => number of signatures required (default: 1) 689 --git-min-signatures => number of signatures required (default: $email_git_min_signatures)
303 --git-max-maintainers => maximum maintainers to add (default: 5) 690 --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
304 --git-since => git history to use (default: 1-year-ago) 691 --git-min-percent => minimum percentage of commits required (default: $email_git_min_percent)
692 --git-blame => use git blame to find modified commits for patch or file
693 --git-since => git history to use (default: $email_git_since)
694 --hg-since => hg history to use (default: $email_hg_since)
695 --interactive => display a menu (mostly useful if used with the --git option)
305 --m => include maintainer(s) if any 696 --m => include maintainer(s) if any
306 --n => include name 'Full Name <addr\@domain.tld>' 697 --n => include name 'Full Name <addr\@domain.tld>'
307 --l => include list(s) if any 698 --l => include list(s) if any
308 --s => include subscriber only list(s) if any 699 --s => include subscriber only list(s) if any
700 --remove-duplicates => minimize duplicate email names/addresses
701 --roles => show roles (status:subsystem, git-signer, list, etc...)
702 --rolestats => show roles and statistics (commits/total_commits, %)
703 --file-emails => add email addresses found in -f file (default: 0 (off))
309 --scm => print SCM tree(s) if any 704 --scm => print SCM tree(s) if any
310 --status => print status if any 705 --status => print status if any
311 --subsystem => print subsystem name if any 706 --subsystem => print subsystem name if any
@@ -313,103 +708,299 @@ MAINTAINER field selection options:
313 708
314Output type options: 709Output type options:
315 --separator [, ] => separator for multiple entries on 1 line 710 --separator [, ] => separator for multiple entries on 1 line
711 using --separator also sets --nomultiline if --separator is not [, ]
316 --multiline => print 1 entry per line 712 --multiline => print 1 entry per line
317 713
318Default options:
319 [--email --git --m --n --l --multiline]
320
321Other options: 714Other options:
715 --pattern-depth => Number of pattern directory traversals (default: 0 (all))
716 --keywords => scan patch for keywords (default: $keywords)
717 --sections => print all of the subsystem sections with pattern matches
718 --mailmap => use .mailmap file (default: $email_use_mailmap)
322 --version => show version 719 --version => show version
323 --help => show this help information 720 --help => show this help information
324 721
722Default options:
723 [--email --git --m --n --l --multiline --pattern-depth=0 --remove-duplicates]
724
725Notes:
726 Using "-f directory" may give unexpected results:
727 Used with "--git", git signators for _all_ files in and below
728 directory are examined as git recurses directories.
729 Any specified X: (exclude) pattern matches are _not_ ignored.
730 Used with "--nogit", directory is used as a pattern match,
731 no individual file within the directory or subdirectory
732 is matched.
733 Used with "--git-blame", does not iterate all files in directory
734 Using "--git-blame" is slow and may add old committers and authors
735 that are no longer active maintainers to the output.
736 Using "--roles" or "--rolestats" with git send-email --cc-cmd or any
737 other automated tools that expect only ["name"] <email address>
738 may not work because of additional output after <email address>.
739 Using "--rolestats" and "--git-blame" shows the #/total=% commits,
740 not the percentage of the entire file authored. # of commits is
741 not a good measure of amount of code authored. 1 major commit may
742 contain a thousand lines, 5 trivial commits may modify a single line.
743 If git is not installed, but mercurial (hg) is installed and an .hg
744 repository exists, the following options apply to mercurial:
745 --git,
746 --git-min-signatures, --git-max-maintainers, --git-min-percent, and
747 --git-blame
748 Use --hg-since not --git-since to control date selection
749 File ".get_maintainer.conf", if it exists in the linux kernel source root
750 directory, can change whatever get_maintainer defaults are desired.
751 Entries in this file can be any command line argument.
752 This file is prepended to any additional command line arguments.
753 Multiple lines and # comments are allowed.
325EOT 754EOT
326} 755}
327 756
328sub top_of_kernel_tree { 757sub top_of_kernel_tree {
329 my ($lk_path) = @_; 758 my ($lk_path) = @_;
330 759
331 if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") { 760 if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
332 $lk_path .= "/"; 761 $lk_path .= "/";
333 } 762 }
334 if ( (-f "${lk_path}COPYING") 763 if ( (-f "${lk_path}COPYING")
335 && (-f "${lk_path}CREDITS") 764 && (-f "${lk_path}CREDITS")
336 && (-f "${lk_path}Kbuild") 765 && (-f "${lk_path}Kbuild")
337 && (-f "${lk_path}MAINTAINERS") 766 && (-f "${lk_path}MAINTAINERS")
338 && (-f "${lk_path}Makefile") 767 && (-f "${lk_path}Makefile")
339 && (-f "${lk_path}README") 768 && (-f "${lk_path}README")
340 && (-d "${lk_path}Documentation") 769 && (-d "${lk_path}Documentation")
341 && (-d "${lk_path}arch") 770 && (-d "${lk_path}arch")
342 && (-d "${lk_path}include") 771 && (-d "${lk_path}include")
343 && (-d "${lk_path}drivers") 772 && (-d "${lk_path}drivers")
344 && (-d "${lk_path}fs") 773 && (-d "${lk_path}fs")
345 && (-d "${lk_path}init") 774 && (-d "${lk_path}init")
346 && (-d "${lk_path}ipc") 775 && (-d "${lk_path}ipc")
347 && (-d "${lk_path}kernel") 776 && (-d "${lk_path}kernel")
348 && (-d "${lk_path}lib") 777 && (-d "${lk_path}lib")
349 && (-d "${lk_path}scripts")) { 778 && (-d "${lk_path}scripts")) {
350 return 1; 779 return 1;
351 } 780 }
352 return 0; 781 return 0;
353} 782}
354 783
355sub format_email { 784sub parse_email {
356 my ($name, $email) = @_; 785 my ($formatted_email) = @_;
786
787 my $name = "";
788 my $address = "";
789
790 if ($formatted_email =~ /^([^<]+)<(.+\@.*)>.*$/) {
791 $name = $1;
792 $address = $2;
793 } elsif ($formatted_email =~ /^\s*<(.+\@\S*)>.*$/) {
794 $address = $1;
795 } elsif ($formatted_email =~ /^(.+\@\S*).*$/) {
796 $address = $1;
797 }
357 798
358 $name =~ s/^\s+|\s+$//g; 799 $name =~ s/^\s+|\s+$//g;
359 $name =~ s/^\"|\"$//g; 800 $name =~ s/^\"|\"$//g;
360 $email =~ s/^\s+|\s+$//g; 801 $address =~ s/^\s+|\s+$//g;
361 802
362 my $formatted_email = ""; 803 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
804 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
805 $name = "\"$name\"";
806 }
807
808 return ($name, $address);
809}
810
811sub format_email {
812 my ($name, $address, $usename) = @_;
813
814 my $formatted_email;
815
816 $name =~ s/^\s+|\s+$//g;
817 $name =~ s/^\"|\"$//g;
818 $address =~ s/^\s+|\s+$//g;
363 819
364 if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars 820 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
365 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 821 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
366 $formatted_email = "\"${name}\"\ \<${email}\>"; 822 $name = "\"$name\"";
823 }
824
825 if ($usename) {
826 if ("$name" eq "") {
827 $formatted_email = "$address";
828 } else {
829 $formatted_email = "$name <$address>";
830 }
367 } else { 831 } else {
368 $formatted_email = "${name} \<${email}\>"; 832 $formatted_email = $address;
369 } 833 }
834
370 return $formatted_email; 835 return $formatted_email;
371} 836}
372 837
373sub add_categories { 838sub find_first_section {
839 my $index = 0;
840
841 while ($index < @typevalue) {
842 my $tv = $typevalue[$index];
843 if (($tv =~ m/^(\C):\s*(.*)/)) {
844 last;
845 }
846 $index++;
847 }
848
849 return $index;
850}
851
852sub find_starting_index {
853 my ($index) = @_;
854
855 while ($index > 0) {
856 my $tv = $typevalue[$index];
857 if (!($tv =~ m/^(\C):\s*(.*)/)) {
858 last;
859 }
860 $index--;
861 }
862
863 return $index;
864}
865
866sub find_ending_index {
374 my ($index) = @_; 867 my ($index) = @_;
375 868
376 $index = $index - 1; 869 while ($index < @typevalue) {
377 while ($index >= 0) {
378 my $tv = $typevalue[$index]; 870 my $tv = $typevalue[$index];
871 if (!($tv =~ m/^(\C):\s*(.*)/)) {
872 last;
873 }
874 $index++;
875 }
876
877 return $index;
878}
879
880sub get_maintainer_role {
881 my ($index) = @_;
882
883 my $i;
884 my $start = find_starting_index($index);
885 my $end = find_ending_index($index);
886
887 my $role;
888 my $subsystem = $typevalue[$start];
889 if (length($subsystem) > 20) {
890 $subsystem = substr($subsystem, 0, 17);
891 $subsystem =~ s/\s*$//;
892 $subsystem = $subsystem . "...";
893 }
894
895 for ($i = $start + 1; $i < $end; $i++) {
896 my $tv = $typevalue[$i];
897 if ($tv =~ m/^(\C):\s*(.*)/) {
898 my $ptype = $1;
899 my $pvalue = $2;
900 if ($ptype eq "S") {
901 $role = $pvalue;
902 }
903 }
904 }
905
906 $role = lc($role);
907 if ($role eq "supported") {
908 $role = "supporter";
909 } elsif ($role eq "maintained") {
910 $role = "maintainer";
911 } elsif ($role eq "odd fixes") {
912 $role = "odd fixer";
913 } elsif ($role eq "orphan") {
914 $role = "orphan minder";
915 } elsif ($role eq "obsolete") {
916 $role = "obsolete minder";
917 } elsif ($role eq "buried alive in reporters") {
918 $role = "chief penguin";
919 }
920
921 return $role . ":" . $subsystem;
922}
923
924sub get_list_role {
925 my ($index) = @_;
926
927 my $i;
928 my $start = find_starting_index($index);
929 my $end = find_ending_index($index);
930
931 my $subsystem = $typevalue[$start];
932 if (length($subsystem) > 20) {
933 $subsystem = substr($subsystem, 0, 17);
934 $subsystem =~ s/\s*$//;
935 $subsystem = $subsystem . "...";
936 }
937
938 if ($subsystem eq "THE REST") {
939 $subsystem = "";
940 }
941
942 return $subsystem;
943}
944
945sub add_categories {
946 my ($index) = @_;
947
948 my $i;
949 my $start = find_starting_index($index);
950 my $end = find_ending_index($index);
951
952 push(@subsystem, $typevalue[$start]);
953
954 for ($i = $start + 1; $i < $end; $i++) {
955 my $tv = $typevalue[$i];
379 if ($tv =~ m/^(\C):\s*(.*)/) { 956 if ($tv =~ m/^(\C):\s*(.*)/) {
380 my $ptype = $1; 957 my $ptype = $1;
381 my $pvalue = $2; 958 my $pvalue = $2;
382 if ($ptype eq "L") { 959 if ($ptype eq "L") {
383 my $list_address = $pvalue; 960 my $list_address = $pvalue;
384 my $list_additional = ""; 961 my $list_additional = "";
962 my $list_role = get_list_role($i);
963
964 if ($list_role ne "") {
965 $list_role = ":" . $list_role;
966 }
385 if ($list_address =~ m/([^\s]+)\s+(.*)$/) { 967 if ($list_address =~ m/([^\s]+)\s+(.*)$/) {
386 $list_address = $1; 968 $list_address = $1;
387 $list_additional = $2; 969 $list_additional = $2;
388 } 970 }
389 if ($list_additional =~ m/subscribers-only/) { 971 if ($list_additional =~ m/subscribers-only/) {
390 if ($email_subscriber_list) { 972 if ($email_subscriber_list) {
391 push(@list_to, $list_address); 973 if (!$hash_list_to{lc($list_address)}) {
974 $hash_list_to{lc($list_address)} = 1;
975 push(@list_to, [$list_address,
976 "subscriber list${list_role}"]);
977 }
392 } 978 }
393 } else { 979 } else {
394 if ($email_list) { 980 if ($email_list) {
395 push(@list_to, $list_address); 981 if (!$hash_list_to{lc($list_address)}) {
982 $hash_list_to{lc($list_address)} = 1;
983 push(@list_to, [$list_address,
984 "open list${list_role}"]);
985 }
396 } 986 }
397 } 987 }
398 } elsif ($ptype eq "M") { 988 } elsif ($ptype eq "M") {
399 my $p_used = 0; 989 my ($name, $address) = parse_email($pvalue);
400 if ($index >= 0) { 990 if ($name eq "") {
401 my $tv = $typevalue[$index - 1]; 991 if ($i > 0) {
402 if ($tv =~ m/^(\C):\s*(.*)/) { 992 my $tv = $typevalue[$i - 1];
403 if ($1 eq "P") { 993 if ($tv =~ m/^(\C):\s*(.*)/) {
404 if ($email_usename) { 994 if ($1 eq "P") {
405 push_email_address(format_email($2, $pvalue)); 995 $name = $2;
406 $p_used = 1; 996 $pvalue = format_email($name, $address, $email_usename);
407 } 997 }
408 } 998 }
409 } 999 }
410 } 1000 }
411 if (!$p_used) { 1001 if ($email_maintainer) {
412 push_email_addresses($pvalue); 1002 my $role = get_maintainer_role($i);
1003 push_email_addresses($pvalue, $role);
413 } 1004 }
414 } elsif ($ptype eq "T") { 1005 } elsif ($ptype eq "T") {
415 push(@scm, $pvalue); 1006 push(@scm, $pvalue);
@@ -418,47 +1009,88 @@ sub add_categories {
418 } elsif ($ptype eq "S") { 1009 } elsif ($ptype eq "S") {
419 push(@status, $pvalue); 1010 push(@status, $pvalue);
420 } 1011 }
421
422 $index--;
423 } else {
424 push(@subsystem,$tv);
425 $index = -1;
426 } 1012 }
427 } 1013 }
428} 1014}
429 1015
1016sub email_inuse {
1017 my ($name, $address) = @_;
1018
1019 return 1 if (($name eq "") && ($address eq ""));
1020 return 1 if (($name ne "") && exists($email_hash_name{lc($name)}));
1021 return 1 if (($address ne "") && exists($email_hash_address{lc($address)}));
1022
1023 return 0;
1024}
1025
430sub push_email_address { 1026sub push_email_address {
431 my ($email_address) = @_; 1027 my ($line, $role) = @_;
1028
1029 my ($name, $address) = parse_email($line);
432 1030
433 my $email_name = ""; 1031 if ($address eq "") {
434 if ($email_address =~ m/([^<]+)<(.*\@.*)>$/) { 1032 return 0;
435 $email_name = $1;
436 $email_address = $2;
437 } 1033 }
438 1034
439 if ($email_maintainer) { 1035 if (!$email_remove_duplicates) {
440 if ($email_usename && $email_name) { 1036 push(@email_to, [format_email($name, $address, $email_usename), $role]);
441 push(@email_to, format_email($email_name, $email_address)); 1037 } elsif (!email_inuse($name, $address)) {
442 } else { 1038 push(@email_to, [format_email($name, $address, $email_usename), $role]);
443 push(@email_to, $email_address); 1039 $email_hash_name{lc($name)}++ if ($name ne "");
444 } 1040 $email_hash_address{lc($address)}++;
445 } 1041 }
1042
1043 return 1;
446} 1044}
447 1045
448sub push_email_addresses { 1046sub push_email_addresses {
449 my ($address) = @_; 1047 my ($address, $role) = @_;
450 1048
451 my @address_list = (); 1049 my @address_list = ();
452 1050
453 if (rfc822_valid($address)) { 1051 if (rfc822_valid($address)) {
454 push_email_address($address); 1052 push_email_address($address, $role);
455 } elsif (@address_list = rfc822_validlist($address)) { 1053 } elsif (@address_list = rfc822_validlist($address)) {
456 my $array_count = shift(@address_list); 1054 my $array_count = shift(@address_list);
457 while (my $entry = shift(@address_list)) { 1055 while (my $entry = shift(@address_list)) {
458 push_email_address($entry); 1056 push_email_address($entry, $role);
459 } 1057 }
460 } else { 1058 } else {
461 warn("Invalid MAINTAINERS address: '" . $address . "'\n"); 1059 if (!push_email_address($address, $role)) {
1060 warn("Invalid MAINTAINERS address: '" . $address . "'\n");
1061 }
1062 }
1063}
1064
1065sub add_role {
1066 my ($line, $role) = @_;
1067
1068 my ($name, $address) = parse_email($line);
1069 my $email = format_email($name, $address, $email_usename);
1070
1071 foreach my $entry (@email_to) {
1072 if ($email_remove_duplicates) {
1073 my ($entry_name, $entry_address) = parse_email($entry->[0]);
1074 if (($name eq $entry_name || $address eq $entry_address)
1075 && ($role eq "" || !($entry->[1] =~ m/$role/))
1076 ) {
1077 if ($entry->[1] eq "") {
1078 $entry->[1] = "$role";
1079 } else {
1080 $entry->[1] = "$entry->[1],$role";
1081 }
1082 }
1083 } else {
1084 if ($email eq $entry->[0]
1085 && ($role eq "" || !($entry->[1] =~ m/$role/))
1086 ) {
1087 if ($entry->[1] eq "") {
1088 $entry->[1] = "$role";
1089 } else {
1090 $entry->[1] = "$entry->[1],$role";
1091 }
1092 }
1093 }
462 } 1094 }
463} 1095}
464 1096
@@ -474,68 +1106,828 @@ sub which {
474 return ""; 1106 return "";
475} 1107}
476 1108
477sub recent_git_signoffs { 1109sub which_conf {
478 my ($file) = @_; 1110 my ($conf) = @_;
479 1111
480 my $sign_offs = ""; 1112 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
481 my $cmd = ""; 1113 if (-e "$path/$conf") {
482 my $output = ""; 1114 return "$path/$conf";
483 my $count = 0; 1115 }
484 my @lines = (); 1116 }
485 1117
486 if (which("git") eq "") { 1118 return "";
487 warn("$P: git not found. Add --nogit to options?\n"); 1119}
488 return; 1120
1121sub mailmap_email {
1122 my ($line) = @_;
1123
1124 my ($name, $address) = parse_email($line);
1125 my $email = format_email($name, $address, 1);
1126 my $real_name = $name;
1127 my $real_address = $address;
1128
1129 if (exists $mailmap->{names}->{$email} ||
1130 exists $mailmap->{addresses}->{$email}) {
1131 if (exists $mailmap->{names}->{$email}) {
1132 $real_name = $mailmap->{names}->{$email};
1133 }
1134 if (exists $mailmap->{addresses}->{$email}) {
1135 $real_address = $mailmap->{addresses}->{$email};
1136 }
1137 } else {
1138 if (exists $mailmap->{names}->{$address}) {
1139 $real_name = $mailmap->{names}->{$address};
1140 }
1141 if (exists $mailmap->{addresses}->{$address}) {
1142 $real_address = $mailmap->{addresses}->{$address};
1143 }
489 } 1144 }
490 if (!(-d ".git")) { 1145 return format_email($real_name, $real_address, 1);
491 warn("$P: .git directory not found. Use a git repository for better results.\n"); 1146}
492 warn("$P: perhaps 'git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git'\n"); 1147
493 return; 1148sub mailmap {
1149 my (@addresses) = @_;
1150
1151 my @mapped_emails = ();
1152 foreach my $line (@addresses) {
1153 push(@mapped_emails, mailmap_email($line));
494 } 1154 }
1155 merge_by_realname(@mapped_emails) if ($email_use_mailmap);
1156 return @mapped_emails;
1157}
495 1158
496 $cmd = "git log --since=${email_git_since} -- ${file}"; 1159sub merge_by_realname {
497 $cmd .= " | grep -Ei \"^[-_ a-z]+by:.*\\\@.*\$\""; 1160 my %address_map;
498 if (!$email_git_penguin_chiefs) { 1161 my (@emails) = @_;
499 $cmd .= " | grep -Ev \"${penguin_chiefs}\""; 1162
1163 foreach my $email (@emails) {
1164 my ($name, $address) = parse_email($email);
1165 if (exists $address_map{$name}) {
1166 $address = $address_map{$name};
1167 $email = format_email($name, $address, 1);
1168 } else {
1169 $address_map{$name} = $address;
1170 }
500 } 1171 }
501 $cmd .= " | cut -f2- -d\":\""; 1172}
502 $cmd .= " | sort | uniq -c | sort -rn";
503 1173
504 $output = `${cmd}`; 1174sub git_execute_cmd {
1175 my ($cmd) = @_;
1176 my @lines = ();
1177
1178 my $output = `$cmd`;
505 $output =~ s/^\s*//gm; 1179 $output =~ s/^\s*//gm;
1180 @lines = split("\n", $output);
506 1181
1182 return @lines;
1183}
1184
1185sub hg_execute_cmd {
1186 my ($cmd) = @_;
1187 my @lines = ();
1188
1189 my $output = `$cmd`;
507 @lines = split("\n", $output); 1190 @lines = split("\n", $output);
1191
1192 return @lines;
1193}
1194
1195sub extract_formatted_signatures {
1196 my (@signature_lines) = @_;
1197
1198 my @type = @signature_lines;
1199
1200 s/\s*(.*):.*/$1/ for (@type);
1201
1202 # cut -f2- -d":"
1203 s/\s*.*:\s*(.+)\s*/$1/ for (@signature_lines);
1204
1205## Reformat email addresses (with names) to avoid badly written signatures
1206
1207 foreach my $signer (@signature_lines) {
1208 $signer = deduplicate_email($signer);
1209 }
1210
1211 return (\@type, \@signature_lines);
1212}
1213
1214sub vcs_find_signers {
1215 my ($cmd) = @_;
1216 my $commits;
1217 my @lines = ();
1218 my @signatures = ();
1219
1220 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1221
1222 my $pattern = $VCS_cmds{"commit_pattern"};
1223
1224 $commits = grep(/$pattern/, @lines); # of commits
1225
1226 @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines);
1227
1228 return (0, @signatures) if !@signatures;
1229
1230 save_commits_by_author(@lines) if ($interactive);
1231 save_commits_by_signer(@lines) if ($interactive);
1232
1233 if (!$email_git_penguin_chiefs) {
1234 @signatures = grep(!/${penguin_chiefs}/i, @signatures);
1235 }
1236
1237 my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
1238
1239 return ($commits, @$signers_ref);
1240}
1241
1242sub vcs_find_author {
1243 my ($cmd) = @_;
1244 my @lines = ();
1245
1246 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1247
1248 if (!$email_git_penguin_chiefs) {
1249 @lines = grep(!/${penguin_chiefs}/i, @lines);
1250 }
1251
1252 return @lines if !@lines;
1253
1254 my @authors = ();
508 foreach my $line (@lines) { 1255 foreach my $line (@lines) {
509 if ($line =~ m/([0-9]+)\s+(.*)/) { 1256 if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
510 my $sign_offs = $1; 1257 my $author = $1;
511 $line = $2; 1258 my ($name, $address) = parse_email($author);
512 $count++; 1259 $author = format_email($name, $address, 1);
513 if ($sign_offs < $email_git_min_signatures || 1260 push(@authors, $author);
514 $count > $email_git_max_maintainers) { 1261 }
515 last; 1262 }
1263
1264 save_commits_by_author(@lines) if ($interactive);
1265 save_commits_by_signer(@lines) if ($interactive);
1266
1267 return @authors;
1268}
1269
1270sub vcs_save_commits {
1271 my ($cmd) = @_;
1272 my @lines = ();
1273 my @commits = ();
1274
1275 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1276
1277 foreach my $line (@lines) {
1278 if ($line =~ m/$VCS_cmds{"blame_commit_pattern"}/) {
1279 push(@commits, $1);
1280 }
1281 }
1282
1283 return @commits;
1284}
1285
1286sub vcs_blame {
1287 my ($file) = @_;
1288 my $cmd;
1289 my @commits = ();
1290
1291 return @commits if (!(-f $file));
1292
1293 if (@range && $VCS_cmds{"blame_range_cmd"} eq "") {
1294 my @all_commits = ();
1295
1296 $cmd = $VCS_cmds{"blame_file_cmd"};
1297 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1298 @all_commits = vcs_save_commits($cmd);
1299
1300 foreach my $file_range_diff (@range) {
1301 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
1302 my $diff_file = $1;
1303 my $diff_start = $2;
1304 my $diff_length = $3;
1305 next if ("$file" ne "$diff_file");
1306 for (my $i = $diff_start; $i < $diff_start + $diff_length; $i++) {
1307 push(@commits, $all_commits[$i]);
516 } 1308 }
517 } else {
518 die("$P: Unexpected git output: ${line}\n");
519 } 1309 }
520 if ($line =~ m/(.+)<(.+)>/) { 1310 } elsif (@range) {
521 my $git_name = $1; 1311 foreach my $file_range_diff (@range) {
522 my $git_addr = $2; 1312 next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
523 if ($email_usename) { 1313 my $diff_file = $1;
524 push(@email_to, format_email($git_name, $git_addr)); 1314 my $diff_start = $2;
1315 my $diff_length = $3;
1316 next if ("$file" ne "$diff_file");
1317 $cmd = $VCS_cmds{"blame_range_cmd"};
1318 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1319 push(@commits, vcs_save_commits($cmd));
1320 }
1321 } else {
1322 $cmd = $VCS_cmds{"blame_file_cmd"};
1323 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1324 @commits = vcs_save_commits($cmd);
1325 }
1326
1327 foreach my $commit (@commits) {
1328 $commit =~ s/^\^//g;
1329 }
1330
1331 return @commits;
1332}
1333
1334my $printed_novcs = 0;
1335sub vcs_exists {
1336 %VCS_cmds = %VCS_cmds_git;
1337 return 1 if eval $VCS_cmds{"available"};
1338 %VCS_cmds = %VCS_cmds_hg;
1339 return 2 if eval $VCS_cmds{"available"};
1340 %VCS_cmds = ();
1341 if (!$printed_novcs) {
1342 warn("$P: No supported VCS found. Add --nogit to options?\n");
1343 warn("Using a git repository produces better results.\n");
1344 warn("Try Linus Torvalds' latest git repository using:\n");
1345 warn("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git\n");
1346 $printed_novcs = 1;
1347 }
1348 return 0;
1349}
1350
1351sub vcs_is_git {
1352 vcs_exists();
1353 return $vcs_used == 1;
1354}
1355
1356sub vcs_is_hg {
1357 return $vcs_used == 2;
1358}
1359
1360sub interactive_get_maintainers {
1361 my ($list_ref) = @_;
1362 my @list = @$list_ref;
1363
1364 vcs_exists();
1365
1366 my %selected;
1367 my %authored;
1368 my %signed;
1369 my $count = 0;
1370 my $maintained = 0;
1371 foreach my $entry (@list) {
1372 $maintained = 1 if ($entry->[1] =~ /^(maintainer|supporter)/i);
1373 $selected{$count} = 1;
1374 $authored{$count} = 0;
1375 $signed{$count} = 0;
1376 $count++;
1377 }
1378
1379 #menu loop
1380 my $done = 0;
1381 my $print_options = 0;
1382 my $redraw = 1;
1383 while (!$done) {
1384 $count = 0;
1385 if ($redraw) {
1386 printf STDERR "\n%1s %2s %-65s",
1387 "*", "#", "email/list and role:stats";
1388 if ($email_git ||
1389 ($email_git_fallback && !$maintained) ||
1390 $email_git_blame) {
1391 print STDERR "auth sign";
1392 }
1393 print STDERR "\n";
1394 foreach my $entry (@list) {
1395 my $email = $entry->[0];
1396 my $role = $entry->[1];
1397 my $sel = "";
1398 $sel = "*" if ($selected{$count});
1399 my $commit_author = $commit_author_hash{$email};
1400 my $commit_signer = $commit_signer_hash{$email};
1401 my $authored = 0;
1402 my $signed = 0;
1403 $authored++ for (@{$commit_author});
1404 $signed++ for (@{$commit_signer});
1405 printf STDERR "%1s %2d %-65s", $sel, $count + 1, $email;
1406 printf STDERR "%4d %4d", $authored, $signed
1407 if ($authored > 0 || $signed > 0);
1408 printf STDERR "\n %s\n", $role;
1409 if ($authored{$count}) {
1410 my $commit_author = $commit_author_hash{$email};
1411 foreach my $ref (@{$commit_author}) {
1412 print STDERR " Author: @{$ref}[1]\n";
1413 }
1414 }
1415 if ($signed{$count}) {
1416 my $commit_signer = $commit_signer_hash{$email};
1417 foreach my $ref (@{$commit_signer}) {
1418 print STDERR " @{$ref}[2]: @{$ref}[1]\n";
1419 }
1420 }
1421
1422 $count++;
1423 }
1424 }
1425 my $date_ref = \$email_git_since;
1426 $date_ref = \$email_hg_since if (vcs_is_hg());
1427 if ($print_options) {
1428 $print_options = 0;
1429 if (vcs_exists()) {
1430 print STDERR <<EOT
1431
1432Version Control options:
1433g use git history [$email_git]
1434gf use git-fallback [$email_git_fallback]
1435b use git blame [$email_git_blame]
1436bs use blame signatures [$email_git_blame_signatures]
1437c# minimum commits [$email_git_min_signatures]
1438%# min percent [$email_git_min_percent]
1439d# history to use [$$date_ref]
1440x# max maintainers [$email_git_max_maintainers]
1441t all signature types [$email_git_all_signature_types]
1442m use .mailmap [$email_use_mailmap]
1443EOT
1444 }
1445 print STDERR <<EOT
1446
1447Additional options:
14480 toggle all
1449tm toggle maintainers
1450tg toggle git entries
1451tl toggle open list entries
1452ts toggle subscriber list entries
1453f emails in file [$file_emails]
1454k keywords in file [$keywords]
1455r remove duplicates [$email_remove_duplicates]
1456p# pattern match depth [$pattern_depth]
1457EOT
1458 }
1459 print STDERR
1460"\n#(toggle), A#(author), S#(signed) *(all), ^(none), O(options), Y(approve): ";
1461
1462 my $input = <STDIN>;
1463 chomp($input);
1464
1465 $redraw = 1;
1466 my $rerun = 0;
1467 my @wish = split(/[, ]+/, $input);
1468 foreach my $nr (@wish) {
1469 $nr = lc($nr);
1470 my $sel = substr($nr, 0, 1);
1471 my $str = substr($nr, 1);
1472 my $val = 0;
1473 $val = $1 if $str =~ /^(\d+)$/;
1474
1475 if ($sel eq "y") {
1476 $interactive = 0;
1477 $done = 1;
1478 $output_rolestats = 0;
1479 $output_roles = 0;
1480 last;
1481 } elsif ($nr =~ /^\d+$/ && $nr > 0 && $nr <= $count) {
1482 $selected{$nr - 1} = !$selected{$nr - 1};
1483 } elsif ($sel eq "*" || $sel eq '^') {
1484 my $toggle = 0;
1485 $toggle = 1 if ($sel eq '*');
1486 for (my $i = 0; $i < $count; $i++) {
1487 $selected{$i} = $toggle;
1488 }
1489 } elsif ($sel eq "0") {
1490 for (my $i = 0; $i < $count; $i++) {
1491 $selected{$i} = !$selected{$i};
1492 }
1493 } elsif ($sel eq "t") {
1494 if (lc($str) eq "m") {
1495 for (my $i = 0; $i < $count; $i++) {
1496 $selected{$i} = !$selected{$i}
1497 if ($list[$i]->[1] =~ /^(maintainer|supporter)/i);
1498 }
1499 } elsif (lc($str) eq "g") {
1500 for (my $i = 0; $i < $count; $i++) {
1501 $selected{$i} = !$selected{$i}
1502 if ($list[$i]->[1] =~ /^(author|commit|signer)/i);
1503 }
1504 } elsif (lc($str) eq "l") {
1505 for (my $i = 0; $i < $count; $i++) {
1506 $selected{$i} = !$selected{$i}
1507 if ($list[$i]->[1] =~ /^(open list)/i);
1508 }
1509 } elsif (lc($str) eq "s") {
1510 for (my $i = 0; $i < $count; $i++) {
1511 $selected{$i} = !$selected{$i}
1512 if ($list[$i]->[1] =~ /^(subscriber list)/i);
1513 }
1514 }
1515 } elsif ($sel eq "a") {
1516 if ($val > 0 && $val <= $count) {
1517 $authored{$val - 1} = !$authored{$val - 1};
1518 } elsif ($str eq '*' || $str eq '^') {
1519 my $toggle = 0;
1520 $toggle = 1 if ($str eq '*');
1521 for (my $i = 0; $i < $count; $i++) {
1522 $authored{$i} = $toggle;
1523 }
1524 }
1525 } elsif ($sel eq "s") {
1526 if ($val > 0 && $val <= $count) {
1527 $signed{$val - 1} = !$signed{$val - 1};
1528 } elsif ($str eq '*' || $str eq '^') {
1529 my $toggle = 0;
1530 $toggle = 1 if ($str eq '*');
1531 for (my $i = 0; $i < $count; $i++) {
1532 $signed{$i} = $toggle;
1533 }
1534 }
1535 } elsif ($sel eq "o") {
1536 $print_options = 1;
1537 $redraw = 1;
1538 } elsif ($sel eq "g") {
1539 if ($str eq "f") {
1540 bool_invert(\$email_git_fallback);
1541 } else {
1542 bool_invert(\$email_git);
1543 }
1544 $rerun = 1;
1545 } elsif ($sel eq "b") {
1546 if ($str eq "s") {
1547 bool_invert(\$email_git_blame_signatures);
1548 } else {
1549 bool_invert(\$email_git_blame);
1550 }
1551 $rerun = 1;
1552 } elsif ($sel eq "c") {
1553 if ($val > 0) {
1554 $email_git_min_signatures = $val;
1555 $rerun = 1;
1556 }
1557 } elsif ($sel eq "x") {
1558 if ($val > 0) {
1559 $email_git_max_maintainers = $val;
1560 $rerun = 1;
1561 }
1562 } elsif ($sel eq "%") {
1563 if ($str ne "" && $val >= 0) {
1564 $email_git_min_percent = $val;
1565 $rerun = 1;
1566 }
1567 } elsif ($sel eq "d") {
1568 if (vcs_is_git()) {
1569 $email_git_since = $str;
1570 } elsif (vcs_is_hg()) {
1571 $email_hg_since = $str;
1572 }
1573 $rerun = 1;
1574 } elsif ($sel eq "t") {
1575 bool_invert(\$email_git_all_signature_types);
1576 $rerun = 1;
1577 } elsif ($sel eq "f") {
1578 bool_invert(\$file_emails);
1579 $rerun = 1;
1580 } elsif ($sel eq "r") {
1581 bool_invert(\$email_remove_duplicates);
1582 $rerun = 1;
1583 } elsif ($sel eq "m") {
1584 bool_invert(\$email_use_mailmap);
1585 read_mailmap();
1586 $rerun = 1;
1587 } elsif ($sel eq "k") {
1588 bool_invert(\$keywords);
1589 $rerun = 1;
1590 } elsif ($sel eq "p") {
1591 if ($str ne "" && $val >= 0) {
1592 $pattern_depth = $val;
1593 $rerun = 1;
1594 }
1595 } elsif ($sel eq "h" || $sel eq "?") {
1596 print STDERR <<EOT
1597
1598Interactive mode allows you to select the various maintainers, submitters,
1599commit signers and mailing lists that could be CC'd on a patch.
1600
1601Any *'d entry is selected.
1602
1603If you have git or hg installed, you can choose to summarize the commit
1604history of files in the patch. Also, each line of the current file can
1605be matched to its commit author and that commits signers with blame.
1606
1607Various knobs exist to control the length of time for active commit
1608tracking, the maximum number of commit authors and signers to add,
1609and such.
1610
1611Enter selections at the prompt until you are satisfied that the selected
1612maintainers are appropriate. You may enter multiple selections separated
1613by either commas or spaces.
1614
1615EOT
525 } else { 1616 } else {
526 push(@email_to, $git_addr); 1617 print STDERR "invalid option: '$nr'\n";
1618 $redraw = 0;
1619 }
1620 }
1621 if ($rerun) {
1622 print STDERR "git-blame can be very slow, please have patience..."
1623 if ($email_git_blame);
1624 goto &get_maintainers;
1625 }
1626 }
1627
1628 #drop not selected entries
1629 $count = 0;
1630 my @new_emailto = ();
1631 foreach my $entry (@list) {
1632 if ($selected{$count}) {
1633 push(@new_emailto, $list[$count]);
1634 }
1635 $count++;
1636 }
1637 return @new_emailto;
1638}
1639
1640sub bool_invert {
1641 my ($bool_ref) = @_;
1642
1643 if ($$bool_ref) {
1644 $$bool_ref = 0;
1645 } else {
1646 $$bool_ref = 1;
1647 }
1648}
1649
1650sub deduplicate_email {
1651 my ($email) = @_;
1652
1653 my $matched = 0;
1654 my ($name, $address) = parse_email($email);
1655 $email = format_email($name, $address, 1);
1656 $email = mailmap_email($email);
1657
1658 return $email if (!$email_remove_duplicates);
1659
1660 ($name, $address) = parse_email($email);
1661
1662 if ($name ne "" && $deduplicate_name_hash{lc($name)}) {
1663 $name = $deduplicate_name_hash{lc($name)}->[0];
1664 $address = $deduplicate_name_hash{lc($name)}->[1];
1665 $matched = 1;
1666 } elsif ($deduplicate_address_hash{lc($address)}) {
1667 $name = $deduplicate_address_hash{lc($address)}->[0];
1668 $address = $deduplicate_address_hash{lc($address)}->[1];
1669 $matched = 1;
1670 }
1671 if (!$matched) {
1672 $deduplicate_name_hash{lc($name)} = [ $name, $address ];
1673 $deduplicate_address_hash{lc($address)} = [ $name, $address ];
1674 }
1675 $email = format_email($name, $address, 1);
1676 $email = mailmap_email($email);
1677 return $email;
1678}
1679
1680sub save_commits_by_author {
1681 my (@lines) = @_;
1682
1683 my @authors = ();
1684 my @commits = ();
1685 my @subjects = ();
1686
1687 foreach my $line (@lines) {
1688 if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
1689 my $author = $1;
1690 $author = deduplicate_email($author);
1691 push(@authors, $author);
1692 }
1693 push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
1694 push(@subjects, $1) if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
1695 }
1696
1697 for (my $i = 0; $i < @authors; $i++) {
1698 my $exists = 0;
1699 foreach my $ref(@{$commit_author_hash{$authors[$i]}}) {
1700 if (@{$ref}[0] eq $commits[$i] &&
1701 @{$ref}[1] eq $subjects[$i]) {
1702 $exists = 1;
1703 last;
1704 }
1705 }
1706 if (!$exists) {
1707 push(@{$commit_author_hash{$authors[$i]}},
1708 [ ($commits[$i], $subjects[$i]) ]);
1709 }
1710 }
1711}
1712
1713sub save_commits_by_signer {
1714 my (@lines) = @_;
1715
1716 my $commit = "";
1717 my $subject = "";
1718
1719 foreach my $line (@lines) {
1720 $commit = $1 if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
1721 $subject = $1 if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
1722 if ($line =~ /^[ \t]*${signature_pattern}.*\@.*$/) {
1723 my @signatures = ($line);
1724 my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
1725 my @types = @$types_ref;
1726 my @signers = @$signers_ref;
1727
1728 my $type = $types[0];
1729 my $signer = $signers[0];
1730
1731 $signer = deduplicate_email($signer);
1732
1733 my $exists = 0;
1734 foreach my $ref(@{$commit_signer_hash{$signer}}) {
1735 if (@{$ref}[0] eq $commit &&
1736 @{$ref}[1] eq $subject &&
1737 @{$ref}[2] eq $type) {
1738 $exists = 1;
1739 last;
1740 }
1741 }
1742 if (!$exists) {
1743 push(@{$commit_signer_hash{$signer}},
1744 [ ($commit, $subject, $type) ]);
527 } 1745 }
528 } elsif ($line =~ m/<(.+)>/) { 1746 }
529 my $git_addr = $1; 1747 }
530 push(@email_to, $git_addr); 1748}
1749
1750sub vcs_assign {
1751 my ($role, $divisor, @lines) = @_;
1752
1753 my %hash;
1754 my $count = 0;
1755
1756 return if (@lines <= 0);
1757
1758 if ($divisor <= 0) {
1759 warn("Bad divisor in " . (caller(0))[3] . ": $divisor\n");
1760 $divisor = 1;
1761 }
1762
1763 @lines = mailmap(@lines);
1764
1765 return if (@lines <= 0);
1766
1767 @lines = sort(@lines);
1768
1769 # uniq -c
1770 $hash{$_}++ for @lines;
1771
1772 # sort -rn
1773 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
1774 my $sign_offs = $hash{$line};
1775 my $percent = $sign_offs * 100 / $divisor;
1776
1777 $percent = 100 if ($percent > 100);
1778 $count++;
1779 last if ($sign_offs < $email_git_min_signatures ||
1780 $count > $email_git_max_maintainers ||
1781 $percent < $email_git_min_percent);
1782 push_email_address($line, '');
1783 if ($output_rolestats) {
1784 my $fmt_percent = sprintf("%.0f", $percent);
1785 add_role($line, "$role:$sign_offs/$divisor=$fmt_percent%");
531 } else { 1786 } else {
532 push(@email_to, $line); 1787 add_role($line, $role);
533 } 1788 }
534 } 1789 }
535} 1790}
536 1791
1792sub vcs_file_signoffs {
1793 my ($file) = @_;
1794
1795 my @signers = ();
1796 my $commits;
1797
1798 $vcs_used = vcs_exists();
1799 return if (!$vcs_used);
1800
1801 my $cmd = $VCS_cmds{"find_signers_cmd"};
1802 $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
1803
1804 ($commits, @signers) = vcs_find_signers($cmd);
1805
1806 foreach my $signer (@signers) {
1807 $signer = deduplicate_email($signer);
1808 }
1809
1810 vcs_assign("commit_signer", $commits, @signers);
1811}
1812
1813sub vcs_file_blame {
1814 my ($file) = @_;
1815
1816 my @signers = ();
1817 my @all_commits = ();
1818 my @commits = ();
1819 my $total_commits;
1820 my $total_lines;
1821
1822 $vcs_used = vcs_exists();
1823 return if (!$vcs_used);
1824
1825 @all_commits = vcs_blame($file);
1826 @commits = uniq(@all_commits);
1827 $total_commits = @commits;
1828 $total_lines = @all_commits;
1829
1830 if ($email_git_blame_signatures) {
1831 if (vcs_is_hg()) {
1832 my $commit_count;
1833 my @commit_signers = ();
1834 my $commit = join(" -r ", @commits);
1835 my $cmd;
1836
1837 $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1838 $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
1839
1840 ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1841
1842 push(@signers, @commit_signers);
1843 } else {
1844 foreach my $commit (@commits) {
1845 my $commit_count;
1846 my @commit_signers = ();
1847 my $cmd;
1848
1849 $cmd = $VCS_cmds{"find_commit_signers_cmd"};
1850 $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
1851
1852 ($commit_count, @commit_signers) = vcs_find_signers($cmd);
1853
1854 push(@signers, @commit_signers);
1855 }
1856 }
1857 }
1858
1859 if ($from_filename) {
1860 if ($output_rolestats) {
1861 my @blame_signers;
1862 if (vcs_is_hg()) {{ # Double brace for last exit
1863 my $commit_count;
1864 my @commit_signers = ();
1865 @commits = uniq(@commits);
1866 @commits = sort(@commits);
1867 my $commit = join(" -r ", @commits);
1868 my $cmd;
1869
1870 $cmd = $VCS_cmds{"find_commit_author_cmd"};
1871 $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd
1872
1873 my @lines = ();
1874
1875 @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
1876
1877 if (!$email_git_penguin_chiefs) {
1878 @lines = grep(!/${penguin_chiefs}/i, @lines);
1879 }
1880
1881 last if !@lines;
1882
1883 my @authors = ();
1884 foreach my $line (@lines) {
1885 if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
1886 my $author = $1;
1887 $author = deduplicate_email($author);
1888 push(@authors, $author);
1889 }
1890 }
1891
1892 save_commits_by_author(@lines) if ($interactive);
1893 save_commits_by_signer(@lines) if ($interactive);
1894
1895 push(@signers, @authors);
1896 }}
1897 else {
1898 foreach my $commit (@commits) {
1899 my $i;
1900 my $cmd = $VCS_cmds{"find_commit_author_cmd"};
1901 $cmd =~ s/(\$\w+)/$1/eeg; #interpolate $cmd
1902 my @author = vcs_find_author($cmd);
1903 next if !@author;
1904
1905 my $formatted_author = deduplicate_email($author[0]);
1906
1907 my $count = grep(/$commit/, @all_commits);
1908 for ($i = 0; $i < $count ; $i++) {
1909 push(@blame_signers, $formatted_author);
1910 }
1911 }
1912 }
1913 if (@blame_signers) {
1914 vcs_assign("authored lines", $total_lines, @blame_signers);
1915 }
1916 }
1917 foreach my $signer (@signers) {
1918 $signer = deduplicate_email($signer);
1919 }
1920 vcs_assign("commits", $total_commits, @signers);
1921 } else {
1922 foreach my $signer (@signers) {
1923 $signer = deduplicate_email($signer);
1924 }
1925 vcs_assign("modified commits", $total_commits, @signers);
1926 }
1927}
1928
537sub uniq { 1929sub uniq {
538 my @parms = @_; 1930 my (@parms) = @_;
539 1931
540 my %saw; 1932 my %saw;
541 @parms = grep(!$saw{$_}++, @parms); 1933 @parms = grep(!$saw{$_}++, @parms);
@@ -543,7 +1935,7 @@ sub uniq {
543} 1935}
544 1936
545sub sort_and_uniq { 1937sub sort_and_uniq {
546 my @parms = @_; 1938 my (@parms) = @_;
547 1939
548 my %saw; 1940 my %saw;
549 @parms = sort @parms; 1941 @parms = sort @parms;
@@ -551,8 +1943,72 @@ sub sort_and_uniq {
551 return @parms; 1943 return @parms;
552} 1944}
553 1945
1946sub clean_file_emails {
1947 my (@file_emails) = @_;
1948 my @fmt_emails = ();
1949
1950 foreach my $email (@file_emails) {
1951 $email =~ s/[\(\<\{]{0,1}([A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+)[\)\>\}]{0,1}/\<$1\>/g;
1952 my ($name, $address) = parse_email($email);
1953 if ($name eq '"[,\.]"') {
1954 $name = "";
1955 }
1956
1957 my @nw = split(/[^A-Za-zÀ-ÿ\'\,\.\+-]/, $name);
1958 if (@nw > 2) {
1959 my $first = $nw[@nw - 3];
1960 my $middle = $nw[@nw - 2];
1961 my $last = $nw[@nw - 1];
1962
1963 if (((length($first) == 1 && $first =~ m/[A-Za-z]/) ||
1964 (length($first) == 2 && substr($first, -1) eq ".")) ||
1965 (length($middle) == 1 ||
1966 (length($middle) == 2 && substr($middle, -1) eq "."))) {
1967 $name = "$first $middle $last";
1968 } else {
1969 $name = "$middle $last";
1970 }
1971 }
1972
1973 if (substr($name, -1) =~ /[,\.]/) {
1974 $name = substr($name, 0, length($name) - 1);
1975 } elsif (substr($name, -2) =~ /[,\.]"/) {
1976 $name = substr($name, 0, length($name) - 2) . '"';
1977 }
1978
1979 if (substr($name, 0, 1) =~ /[,\.]/) {
1980 $name = substr($name, 1, length($name) - 1);
1981 } elsif (substr($name, 0, 2) =~ /"[,\.]/) {
1982 $name = '"' . substr($name, 2, length($name) - 2);
1983 }
1984
1985 my $fmt_email = format_email($name, $address, $email_usename);
1986 push(@fmt_emails, $fmt_email);
1987 }
1988 return @fmt_emails;
1989}
1990
1991sub merge_email {
1992 my @lines;
1993 my %saw;
1994
1995 for (@_) {
1996 my ($address, $role) = @$_;
1997 if (!$saw{$address}) {
1998 if ($output_roles) {
1999 push(@lines, "$address ($role)");
2000 } else {
2001 push(@lines, $address);
2002 }
2003 $saw{$address} = 1;
2004 }
2005 }
2006
2007 return @lines;
2008}
2009
554sub output { 2010sub output {
555 my @parms = @_; 2011 my (@parms) = @_;
556 2012
557 if ($output_multiline) { 2013 if ($output_multiline) {
558 foreach my $line (@parms) { 2014 foreach my $line (@parms) {
@@ -616,7 +2072,7 @@ sub rfc822_strip_comments {
616 2072
617# valid: returns true if the parameter is an RFC822 valid address 2073# valid: returns true if the parameter is an RFC822 valid address
618# 2074#
619sub rfc822_valid ($) { 2075sub rfc822_valid {
620 my $s = rfc822_strip_comments(shift); 2076 my $s = rfc822_strip_comments(shift);
621 2077
622 if (!$rfc822re) { 2078 if (!$rfc822re) {
@@ -636,7 +2092,7 @@ sub rfc822_valid ($) {
636# from success with no addresses found, because an empty string is 2092# from success with no addresses found, because an empty string is
637# a valid list. 2093# a valid list.
638 2094
639sub rfc822_validlist ($) { 2095sub rfc822_validlist {
640 my $s = rfc822_strip_comments(shift); 2096 my $s = rfc822_strip_comments(shift);
641 2097
642 if (!$rfc822re) { 2098 if (!$rfc822re) {
@@ -649,11 +2105,9 @@ sub rfc822_validlist ($) {
649 if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so && 2105 if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so &&
650 $s =~ m/^$rfc822_char*$/) { 2106 $s =~ m/^$rfc822_char*$/) {
651 while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) { 2107 while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) {
652 push @r, $1; 2108 push(@r, $1);
653 } 2109 }
654 return wantarray ? (scalar(@r), @r) : 1; 2110 return wantarray ? (scalar(@r), @r) : 1;
655 } 2111 }
656 else { 2112 return wantarray ? () : 0;
657 return wantarray ? () : 0;
658 }
659} 2113}
diff --git a/scripts/gfp-translate b/scripts/gfp-translate
index 073cb6d152a0..c9230e158a8f 100644
--- a/scripts/gfp-translate
+++ b/scripts/gfp-translate
@@ -19,7 +19,7 @@ usage() {
19 exit 0 19 exit 0
20} 20}
21 21
22# Parse command-line arguements 22# Parse command-line arguments
23while [ $# -gt 0 ]; do 23while [ $# -gt 0 ]; do
24 case $1 in 24 case $1 in
25 --source) 25 --source)
@@ -63,7 +63,12 @@ fi
63 63
64# Extract GFP flags from the kernel source 64# Extract GFP flags from the kernel source
65TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 65TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1
66grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE 66grep -q ___GFP $SOURCE/include/linux/gfp.h
67if [ $? -eq 0 ]; then
68 grep "^#define ___GFP" $SOURCE/include/linux/gfp.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE
69else
70 grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE
71fi
67 72
68# Parse the flags 73# Parse the flags
69IFS=" 74IFS="
diff --git a/scripts/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.sh b/scripts/headers.sh
index 0308ecc10d5b..978b42b3acd7 100755
--- a/scripts/headers.sh
+++ b/scripts/headers.sh
@@ -8,14 +8,12 @@ do_command()
8{ 8{
9 if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then 9 if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then
10 make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 10 make ARCH=$2 KBUILD_HEADERS=$1 headers_$1
11 elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then
12 make ARCH=$2 KBUILD_HEADERS=$1 headers_$1
13 else 11 else
14 printf "Ignoring arch: %s\n" ${arch} 12 printf "Ignoring arch: %s\n" ${arch}
15 fi 13 fi
16} 14}
17 15
18archs=$(ls ${srctree}/arch) 16archs=${HDR_ARCH_LIST:-$(ls ${srctree}/arch)}
19 17
20for arch in ${archs}; do 18for arch in ${archs}; do
21 case ${arch} in 19 case ${arch} in
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl
index db1dd7a549f2..7957e7a5166a 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
@@ -63,10 +64,10 @@ sub check_include
63 64
64sub check_declarations 65sub check_declarations
65{ 66{
66 if ($line =~m/^\s*extern\b/) { 67 if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) {
67 printf STDERR "$filename:$lineno: " . 68 printf STDERR "$filename:$lineno: " .
68 "userspace cannot call function or variable " . 69 "userspace cannot reference function or " .
69 "defined in the kernel\n"; 70 "variable defined in the kernel\n";
70 } 71 }
71} 72}
72 73
@@ -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 c6ae4052ab43..efb3be10d428 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -20,16 +20,16 @@ use strict;
20 20
21my ($readdir, $installdir, $arch, @files) = @ARGV; 21my ($readdir, $installdir, $arch, @files) = @ARGV;
22 22
23my $unifdef = "scripts/unifdef -U__KERNEL__"; 23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
24 24
25foreach my $file (@files) { 25foreach my $file (@files) {
26 local *INFILE;
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,11 +39,19 @@ 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";
48 # unifdef will exit 0 on success, and will exit 1 when the
49 # file was processed successfully but no changes were made,
50 # so abort only when it's higher than that.
51 my $e = $? >> 8;
52 if ($e > 1) {
53 die "$tmpfile: $!\n";
54 }
47 unlink $tmpfile; 55 unlink $tmpfile;
48} 56}
49exit 0; 57exit 0;
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 64343cc084b4..60dd3eb9366e 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -107,10 +107,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
107 107
108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); 108 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
109 if (rc != 3) { 109 if (rc != 3) {
110 if (rc != EOF) { 110 if (rc != EOF && fgets(str, 500, in) == NULL)
111 /* skip line */ 111 fprintf(stderr, "Read error or end of file.\n");
112 fgets(str, 500, in);
113 }
114 return -1; 112 return -1;
115 } 113 }
116 114
@@ -585,7 +583,7 @@ static int prefix_underscores_count(const char *str)
585{ 583{
586 const char *tail = str; 584 const char *tail = str;
587 585
588 while (*tail != '_') 586 while (*tail == '_')
589 tail++; 587 tail++;
590 588
591 return tail - str; 589 return tail - str;
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 5ddf8becd7a2..368ae306aee4 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -2,12 +2,13 @@
2# Kernel configuration targets 2# Kernel configuration targets
3# These targets are used from top-level makefile 3# These targets are used from top-level makefile
4 4
5PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config 5PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \
6 localmodconfig localyesconfig
6 7
7ifdef KBUILD_KCONFIG 8ifdef KBUILD_KCONFIG
8Kconfig := $(KBUILD_KCONFIG) 9Kconfig := $(KBUILD_KCONFIG)
9else 10else
10Kconfig := arch/$(SRCARCH)/Kconfig 11Kconfig := Kconfig
11endif 12endif
12 13
13xconfig: $(obj)/qconf 14xconfig: $(obj)/qconf
@@ -20,13 +21,56 @@ menuconfig: $(obj)/mconf
20 $< $(Kconfig) 21 $< $(Kconfig)
21 22
22config: $(obj)/conf 23config: $(obj)/conf
24 $< --oldaskconfig $(Kconfig)
25
26nconfig: $(obj)/nconf
23 $< $(Kconfig) 27 $< $(Kconfig)
24 28
25oldconfig: $(obj)/conf 29oldconfig: $(obj)/conf
26 $< -o $(Kconfig) 30 $< --$@ $(Kconfig)
27 31
28silentoldconfig: $(obj)/conf 32silentoldconfig: $(obj)/conf
29 $< -s $(Kconfig) 33 $(Q)mkdir -p include/generated
34 $< --$@ $(Kconfig)
35
36# if no path is given, then use src directory to find file
37ifdef LSMOD
38LSMOD_F := $(LSMOD)
39ifeq ($(findstring /,$(LSMOD)),)
40 LSMOD_F := $(objtree)/$(LSMOD)
41endif
42endif
43
44localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
45 $(Q)mkdir -p include/generated
46 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
47 $(Q)if [ -f .config ]; then \
48 cmp -s .tmp.config .config || \
49 (mv -f .config .config.old.1; \
50 mv -f .tmp.config .config; \
51 $(obj)/conf --silentoldconfig $(Kconfig); \
52 mv -f .config.old.1 .config.old) \
53 else \
54 mv -f .tmp.config .config; \
55 $(obj)/conf --silentoldconfig $(Kconfig); \
56 fi
57 $(Q)rm -f .tmp.config
58
59localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
60 $(Q)mkdir -p include/generated
61 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
62 $(Q)sed -i s/=m/=y/ .tmp.config
63 $(Q)if [ -f .config ]; then \
64 cmp -s .tmp.config .config || \
65 (mv -f .config .config.old.1; \
66 mv -f .tmp.config .config; \
67 $(obj)/conf --silentoldconfig $(Kconfig); \
68 mv -f .config.old.1 .config.old) \
69 else \
70 mv -f .tmp.config .config; \
71 $(obj)/conf --silentoldconfig $(Kconfig); \
72 fi
73 $(Q)rm -f .tmp.config
30 74
31# Create new linux.pot file 75# Create new linux.pot file
32# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files 76# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
@@ -51,59 +95,64 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
51 $(Q)rm -f arch/um/Kconfig.arch 95 $(Q)rm -f arch/um/Kconfig.arch
52 $(Q)rm -f $(obj)/config.pot 96 $(Q)rm -f $(obj)/config.pot
53 97
54PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig 98PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
55 99
56randconfig: $(obj)/conf 100allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
57 $< -r $(Kconfig) 101 $< --$@ $(Kconfig)
58 102
59allyesconfig: $(obj)/conf 103PHONY += listnewconfig oldnoconfig savedefconfig defconfig
60 $< -y $(Kconfig)
61 104
62allnoconfig: $(obj)/conf 105listnewconfig oldnoconfig: $(obj)/conf
63 $< -n $(Kconfig) 106 $< --$@ $(Kconfig)
64 107
65allmodconfig: $(obj)/conf 108savedefconfig: $(obj)/conf
66 $< -m $(Kconfig) 109 $< --$@=defconfig $(Kconfig)
67 110
68defconfig: $(obj)/conf 111defconfig: $(obj)/conf
69ifeq ($(KBUILD_DEFCONFIG),) 112ifeq ($(KBUILD_DEFCONFIG),)
70 $< -d $(Kconfig) 113 $< --defconfig $(Kconfig)
71else 114else
72 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" 115 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
73 $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) 116 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
74endif 117endif
75 118
76%_defconfig: $(obj)/conf 119%_defconfig: $(obj)/conf
77 $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) 120 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
78 121
79# Help text used by make help 122# Help text used by make help
80help: 123help:
81 @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'
82 @echo ' menuconfig - Update current config utilising a menu based program' 126 @echo ' menuconfig - Update current config utilising a menu based program'
83 @echo ' xconfig - Update current config utilising a QT based front-end' 127 @echo ' xconfig - Update current config utilising a QT based front-end'
84 @echo ' gconfig - Update current config utilising a GTK based front-end' 128 @echo ' gconfig - Update current config utilising a GTK based front-end'
85 @echo ' oldconfig - Update current config utilising a provided .config as base' 129 @echo ' oldconfig - Update current config utilising a provided .config as base'
130 @echo ' localmodconfig - Update current config disabling modules not loaded'
131 @echo ' localyesconfig - Update current config converting local mods to core'
86 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' 132 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
87 @echo ' randconfig - New config with random answer to all options' 133 @echo ' defconfig - New config with default from ARCH supplied defconfig'
88 @echo ' defconfig - New config with default answer to all options' 134 @echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
89 @echo ' allmodconfig - New config selecting modules when possible'
90 @echo ' allyesconfig - New config where all options are accepted with yes'
91 @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)'
92 142
93# lxdialog stuff 143# lxdialog stuff
94check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh 144check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
95 145
96# Use recursively expanded variables so we do not call gcc unless 146# Use recursively expanded variables so we do not call gcc unless
97# we really need to do so. (Do not call gcc as part of make mrproper) 147# we really need to do so. (Do not call gcc as part of make mrproper)
98HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) 148HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
99HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) 149 -DLOCALE
100
101HOST_EXTRACFLAGS += -DLOCALE
102
103 150
104# =========================================================================== 151# ===========================================================================
105# Shared Makefile for the various kconfig executables: 152# Shared Makefile for the various kconfig executables:
106# conf: Used for defconfig, oldconfig and related targets 153# conf: Used for defconfig, oldconfig and related targets
154# nconf: Used for the nconfig target.
155# Utilizes ncurses
107# mconf: Used for the menuconfig target 156# mconf: Used for the menuconfig target
108# Utilizes the lxdialog package 157# Utilizes the lxdialog package
109# qconf: Used for the xconfig target 158# qconf: Used for the xconfig target
@@ -116,11 +165,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
116lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o 165lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
117 166
118conf-objs := conf.o zconf.tab.o 167conf-objs := conf.o zconf.tab.o
119mconf-objs := mconf.o zconf.tab.o $(lxdialog) 168mconf-objs := mconf.o zconf.tab.o $(lxdialog)
169nconf-objs := nconf.o zconf.tab.o nconf.gui.o
120kxgettext-objs := kxgettext.o zconf.tab.o 170kxgettext-objs := kxgettext.o zconf.tab.o
121 171
122hostprogs-y := conf qconf gconf kxgettext 172hostprogs-y := conf qconf gconf kxgettext
123 173
174ifeq ($(MAKECMDGOALS),nconfig)
175 hostprogs-y += nconf
176endif
177
124ifeq ($(MAKECMDGOALS),menuconfig) 178ifeq ($(MAKECMDGOALS),menuconfig)
125 hostprogs-y += mconf 179 hostprogs-y += mconf
126endif 180endif
@@ -144,14 +198,14 @@ endif
144 198
145clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ 199clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
146 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h 200 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
147clean-files += mconf qconf gconf 201clean-files += mconf qconf gconf nconf
148clean-files += config.pot linux.pot 202clean-files += config.pot linux.pot
149 203
150# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) 204# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
151PHONY += $(obj)/dochecklxdialog 205PHONY += $(obj)/dochecklxdialog
152$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog 206$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
153$(obj)/dochecklxdialog: 207$(obj)/dochecklxdialog:
154 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) 208 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
155 209
156always := dochecklxdialog 210always := dochecklxdialog
157 211
@@ -165,10 +219,13 @@ HOSTCFLAGS_zconf.tab.o := -I$(src)
165HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl 219HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl
166HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK 220HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
167 221
168HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` 222HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
169HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ 223HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
170 -D LKC_DIRECT_LINK 224 -D LKC_DIRECT_LINK
171 225
226HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
227
228HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
172$(obj)/qconf.o: $(obj)/.tmp_qtcheck 229$(obj)/qconf.o: $(obj)/.tmp_qtcheck
173 230
174ifeq ($(qconf-target),1) 231ifeq ($(qconf-target),1)
@@ -178,40 +235,48 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile
178# QT needs some extra effort... 235# QT needs some extra effort...
179$(obj)/.tmp_qtcheck: 236$(obj)/.tmp_qtcheck:
180 @set -e; echo " CHECK qt"; dir=""; pkg=""; \ 237 @set -e; echo " CHECK qt"; dir=""; pkg=""; \
181 pkg-config --exists qt 2> /dev/null && pkg=qt; \ 238 if ! pkg-config --exists QtCore 2> /dev/null; then \
182 pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ 239 echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \
183 if [ -n "$$pkg" ]; then \ 240 pkg-config --exists qt 2> /dev/null && pkg=qt; \
184 cflags="\$$(shell pkg-config $$pkg --cflags)"; \ 241 pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
185 libs="\$$(shell pkg-config $$pkg --libs)"; \ 242 if [ -n "$$pkg" ]; then \
186 moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ 243 cflags="\$$(shell pkg-config $$pkg --cflags)"; \
187 dir="$$(pkg-config $$pkg --variable=prefix)"; \ 244 libs="\$$(shell pkg-config $$pkg --libs)"; \
245 moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
246 dir="$$(pkg-config $$pkg --variable=prefix)"; \
247 else \
248 for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
249 if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
250 done; \
251 if [ -z "$$dir" ]; then \
252 echo "*"; \
253 echo "* Unable to find any QT installation. Please make sure that"; \
254 echo "* the QT4 or QT3 development package is correctly installed and"; \
255 echo "* either qmake can be found or install pkg-config or set"; \
256 echo "* the QTDIR environment variable to the correct location."; \
257 echo "*"; \
258 false; \
259 fi; \
260 libpath=$$dir/lib; lib=qt; osdir=""; \
261 $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
262 osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
263 test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
264 test -f $$libpath/libqt-mt.so && lib=qt-mt; \
265 cflags="-I$$dir/include"; \
266 libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
267 moc="$$dir/bin/moc"; \
268 fi; \
269 if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
270 echo "*"; \
271 echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
272 echo "*"; \
273 moc="/usr/bin/moc"; \
274 fi; \
188 else \ 275 else \
189 for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ 276 cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \
190 if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ 277 libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \
191 done; \ 278 binpath="\$$(shell pkg-config QtCore --variable=prefix)"; \
192 if [ -z "$$dir" ]; then \ 279 moc="$$binpath/bin/moc"; \
193 echo "*"; \
194 echo "* Unable to find the QT3 installation. Please make sure that"; \
195 echo "* the QT3 development package is correctly installed and"; \
196 echo "* either install pkg-config or set the QTDIR environment"; \
197 echo "* variable to the correct location."; \
198 echo "*"; \
199 false; \
200 fi; \
201 libpath=$$dir/lib; lib=qt; osdir=""; \
202 $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
203 osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
204 test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
205 test -f $$libpath/libqt-mt.so && lib=qt-mt; \
206 cflags="-I$$dir/include"; \
207 libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
208 moc="$$dir/bin/moc"; \
209 fi; \
210 if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
211 echo "*"; \
212 echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
213 echo "*"; \
214 moc="/usr/bin/moc"; \
215 fi; \ 280 fi; \
216 echo "KC_QT_CFLAGS=$$cflags" > $@; \ 281 echo "KC_QT_CFLAGS=$$cflags" > $@; \
217 echo "KC_QT_LIBS=$$libs" >> $@; \ 282 echo "KC_QT_LIBS=$$libs" >> $@; \
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 3baaaecd6b13..659326c3e895 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;
@@ -38,14 +44,14 @@ static int conf_cnt;
38static char line[128]; 44static char line[128];
39static struct menu *rootEntry; 45static struct menu *rootEntry;
40 46
41static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); 47static void print_help(struct menu *menu)
42
43static const char *get_help(struct menu *menu)
44{ 48{
45 if (menu_has_help(menu)) 49 struct gstr help = str_new();
46 return _(menu_get_help(menu)); 50
47 else 51 menu_get_ext_help(menu, &help);
48 return nohelp_text; 52
53 printf("\n%s\n", str_get(&help));
54 str_free(&help);
49} 55}
50 56
51static void strip(char *str) 57static void strip(char *str)
@@ -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;
@@ -121,7 +127,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
121 return 1; 127 return 1;
122} 128}
123 129
124int conf_string(struct menu *menu) 130static int conf_string(struct menu *menu)
125{ 131{
126 struct symbol *sym = menu->sym; 132 struct symbol *sym = menu->sym;
127 const char *def; 133 const char *def;
@@ -140,7 +146,7 @@ int conf_string(struct menu *menu)
140 case '?': 146 case '?':
141 /* print help */ 147 /* print help */
142 if (line[1] == '\n') { 148 if (line[1] == '\n') {
143 printf("\n%s\n", get_help(menu)); 149 print_help(menu);
144 def = NULL; 150 def = NULL;
145 break; 151 break;
146 } 152 }
@@ -156,14 +162,12 @@ 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) {
@@ -220,7 +224,7 @@ static int conf_sym(struct menu *menu)
220 if (sym_set_tristate_value(sym, newval)) 224 if (sym_set_tristate_value(sym, newval))
221 return 0; 225 return 0;
222help: 226help:
223 printf("\n%s\n", get_help(menu)); 227 print_help(menu);
224 } 228 }
225} 229}
226 230
@@ -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,20 +296,20 @@ 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 printf("\n%s\n", get_help(menu)); 312 print_help(menu);
311 continue; 313 continue;
312 } 314 }
313 if (!line[0]) 315 if (!line[0])
@@ -331,7 +333,7 @@ static int conf_choice(struct menu *menu)
331 if (!child) 333 if (!child)
332 continue; 334 continue;
333 if (line[strlen(line) - 1] == '?') { 335 if (line[strlen(line) - 1] == '?') {
334 printf("\n%s\n", get_help(child)); 336 print_help(child);
335 continue; 337 continue;
336 } 338 }
337 sym_set_choice_value(sym, child->sym); 339 sym_set_choice_value(sym, child->sym);
@@ -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("%s%s\n", CONFIG_, 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(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) {
@@ -501,8 +508,7 @@ int main(int ac, char **av)
501 name = conf_get_configname(); 508 name = conf_get_configname();
502 if (stat(name, &tmpstat)) { 509 if (stat(name, &tmpstat)) {
503 fprintf(stderr, _("***\n" 510 fprintf(stderr, _("***\n"
504 "*** You have not yet configured your kernel!\n" 511 "*** Configuration file \"%s\" not found!\n"
505 "*** (missing kernel config file \"%s\")\n"
506 "***\n" 512 "***\n"
507 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 513 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
508 "*** \"make menuconfig\" or \"make xconfig\").\n" 514 "*** \"make menuconfig\" or \"make xconfig\").\n"
@@ -512,7 +518,7 @@ int main(int ac, char **av)
512 } 518 }
513 519
514 switch (input_mode) { 520 switch (input_mode) {
515 case set_default: 521 case defconfig:
516 if (!defconfig_file) 522 if (!defconfig_file)
517 defconfig_file = conf_get_default_confname(); 523 defconfig_file = conf_get_default_confname();
518 if (conf_read(defconfig_file)) { 524 if (conf_read(defconfig_file)) {
@@ -522,25 +528,30 @@ int main(int ac, char **av)
522 exit(1); 528 exit(1);
523 } 529 }
524 break; 530 break;
525 case ask_silent: 531 case savedefconfig:
526 case ask_all: 532 case silentoldconfig:
527 case ask_new: 533 case oldaskconfig:
534 case oldconfig:
535 case listnewconfig:
536 case oldnoconfig:
528 conf_read(NULL); 537 conf_read(NULL);
529 break; 538 break;
530 case set_no: 539 case allnoconfig:
531 case set_mod: 540 case allyesconfig:
532 case set_yes: 541 case allmodconfig:
533 case set_random: 542 case alldefconfig:
543 case randconfig:
534 name = getenv("KCONFIG_ALLCONFIG"); 544 name = getenv("KCONFIG_ALLCONFIG");
535 if (name && !stat(name, &tmpstat)) { 545 if (name && !stat(name, &tmpstat)) {
536 conf_read_simple(name, S_DEF_USER); 546 conf_read_simple(name, S_DEF_USER);
537 break; 547 break;
538 } 548 }
539 switch (input_mode) { 549 switch (input_mode) {
540 case set_no: name = "allno.config"; break; 550 case allnoconfig: name = "allno.config"; break;
541 case set_mod: name = "allmod.config"; break; 551 case allyesconfig: name = "allyes.config"; break;
542 case set_yes: name = "allyes.config"; break; 552 case allmodconfig: name = "allmod.config"; break;
543 case set_random: name = "allrandom.config"; break; 553 case alldefconfig: name = "alldef.config"; break;
554 case randconfig: name = "allrandom.config"; break;
544 default: break; 555 default: break;
545 } 556 }
546 if (!stat(name, &tmpstat)) 557 if (!stat(name, &tmpstat))
@@ -557,7 +568,7 @@ int main(int ac, char **av)
557 name = getenv("KCONFIG_NOSILENTUPDATE"); 568 name = getenv("KCONFIG_NOSILENTUPDATE");
558 if (name && *name) { 569 if (name && *name) {
559 fprintf(stderr, 570 fprintf(stderr,
560 _("\n*** Kernel configuration requires explicit update.\n\n")); 571 _("\n*** The configuration requires explicit update.\n\n"));
561 return 1; 572 return 1;
562 } 573 }
563 } 574 }
@@ -565,33 +576,42 @@ int main(int ac, char **av)
565 } 576 }
566 577
567 switch (input_mode) { 578 switch (input_mode) {
568 case set_no: 579 case allnoconfig:
569 conf_set_all_new_symbols(def_no); 580 conf_set_all_new_symbols(def_no);
570 break; 581 break;
571 case set_yes: 582 case allyesconfig:
572 conf_set_all_new_symbols(def_yes); 583 conf_set_all_new_symbols(def_yes);
573 break; 584 break;
574 case set_mod: 585 case allmodconfig:
575 conf_set_all_new_symbols(def_mod); 586 conf_set_all_new_symbols(def_mod);
576 break; 587 break;
577 case set_random: 588 case alldefconfig:
589 conf_set_all_new_symbols(def_default);
590 break;
591 case randconfig:
578 conf_set_all_new_symbols(def_random); 592 conf_set_all_new_symbols(def_random);
579 break; 593 break;
580 case set_default: 594 case defconfig:
581 conf_set_all_new_symbols(def_default); 595 conf_set_all_new_symbols(def_default);
582 break; 596 break;
583 case ask_new: 597 case savedefconfig:
584 case ask_all: 598 break;
599 case oldaskconfig:
585 rootEntry = &rootmenu; 600 rootEntry = &rootmenu;
586 conf(&rootmenu); 601 conf(&rootmenu);
587 input_mode = ask_silent; 602 input_mode = silentoldconfig;
588 /* fall through */ 603 /* fall through */
589 case ask_silent: 604 case oldconfig:
605 case listnewconfig:
606 case oldnoconfig:
607 case silentoldconfig:
590 /* Update until a loop caused no more changes */ 608 /* Update until a loop caused no more changes */
591 do { 609 do {
592 conf_cnt = 0; 610 conf_cnt = 0;
593 check_conf(&rootmenu); 611 check_conf(&rootmenu);
594 } while (conf_cnt); 612 } while (conf_cnt &&
613 (input_mode != listnewconfig &&
614 input_mode != oldnoconfig));
595 break; 615 break;
596 } 616 }
597 617
@@ -600,18 +620,35 @@ int main(int ac, char **av)
600 * All other commands are only used to generate a config. 620 * All other commands are only used to generate a config.
601 */ 621 */
602 if (conf_get_changed() && conf_write(NULL)) { 622 if (conf_get_changed() && conf_write(NULL)) {
603 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); 623 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
604 exit(1); 624 exit(1);
605 } 625 }
606 if (conf_write_autoconf()) { 626 if (conf_write_autoconf()) {
607 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); 627 fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
608 return 1; 628 return 1;
609 } 629 }
610 } else { 630 } else if (input_mode == savedefconfig) {
631 if (conf_write_defconfig(defconfig_file)) {
632 fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
633 defconfig_file);
634 return 1;
635 }
636 } else if (input_mode != listnewconfig) {
611 if (conf_write(NULL)) { 637 if (conf_write(NULL)) {
612 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); 638 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
613 exit(1); 639 exit(1);
614 } 640 }
615 } 641 }
616 return 0; 642 return 0;
617} 643}
644/*
645 * Helper function to facilitate fgets() by Jean Sacren.
646 */
647void xfgets(str, size, in)
648 char *str;
649 int size;
650 FILE *in;
651{
652 if (fgets(str, size, in) == NULL)
653 fprintf(stderr, "\nError in reading or end of file.\n");
654}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index a04da3459f0f..61c35bf2d9cb 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -5,6 +5,7 @@
5 5
6#include <sys/stat.h> 6#include <sys/stat.h>
7#include <ctype.h> 7#include <ctype.h>
8#include <errno.h>
8#include <fcntl.h> 9#include <fcntl.h>
9#include <stdio.h> 10#include <stdio.h>
10#include <stdlib.h> 11#include <stdlib.h>
@@ -18,6 +19,9 @@
18static void conf_warning(const char *fmt, ...) 19static void conf_warning(const char *fmt, ...)
19 __attribute__ ((format (printf, 1, 2))); 20 __attribute__ ((format (printf, 1, 2)));
20 21
22static void conf_message(const char *fmt, ...)
23 __attribute__ ((format (printf, 1, 2)));
24
21static const char *conf_filename; 25static const char *conf_filename;
22static int conf_lineno, conf_warnings, conf_unsaved; 26static int conf_lineno, conf_warnings, conf_unsaved;
23 27
@@ -34,6 +38,29 @@ static void conf_warning(const char *fmt, ...)
34 conf_warnings++; 38 conf_warnings++;
35} 39}
36 40
41static void conf_default_message_callback(const char *fmt, va_list ap)
42{
43 printf("#\n# ");
44 vprintf(fmt, ap);
45 printf("\n#\n");
46}
47
48static void (*conf_message_callback) (const char *fmt, va_list ap) =
49 conf_default_message_callback;
50void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
51{
52 conf_message_callback = fn;
53}
54
55static void conf_message(const char *fmt, ...)
56{
57 va_list ap;
58
59 va_start(ap, fmt);
60 if (conf_message_callback)
61 conf_message_callback(fmt, ap);
62}
63
37const char *conf_get_configname(void) 64const char *conf_get_configname(void)
38{ 65{
39 char *name = getenv("KCONFIG_CONFIG"); 66 char *name = getenv("KCONFIG_CONFIG");
@@ -170,8 +197,11 @@ int conf_read_simple(const char *name, int def)
170 if (in) 197 if (in)
171 goto load; 198 goto load;
172 sym_add_change_count(1); 199 sym_add_change_count(1);
173 if (!sym_defconfig_list) 200 if (!sym_defconfig_list) {
201 if (modules_sym)
202 sym_calc_value(modules_sym);
174 return 1; 203 return 1;
204 }
175 205
176 for_all_defaults(sym_defconfig_list, prop) { 206 for_all_defaults(sym_defconfig_list, prop) {
177 if (expr_calc_value(prop->visible.expr) == no || 207 if (expr_calc_value(prop->visible.expr) == no ||
@@ -180,9 +210,8 @@ int conf_read_simple(const char *name, int def)
180 name = conf_expand_value(prop->expr->left.sym->name); 210 name = conf_expand_value(prop->expr->left.sym->name);
181 in = zconf_fopen(name); 211 in = zconf_fopen(name);
182 if (in) { 212 if (in) {
183 printf(_("#\n" 213 conf_message(_("using defaults found in %s"),
184 "# using defaults found in %s\n" 214 name);
185 "#\n"), name);
186 goto load; 215 goto load;
187 } 216 }
188 } 217 }
@@ -217,24 +246,23 @@ load:
217 while (fgets(line, sizeof(line), in)) { 246 while (fgets(line, sizeof(line), in)) {
218 conf_lineno++; 247 conf_lineno++;
219 sym = NULL; 248 sym = NULL;
220 switch (line[0]) { 249 if (line[0] == '#') {
221 case '#': 250 if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
222 if (memcmp(line + 2, "CONFIG_", 7))
223 continue; 251 continue;
224 p = strchr(line + 9, ' '); 252 p = strchr(line + 2 + strlen(CONFIG_), ' ');
225 if (!p) 253 if (!p)
226 continue; 254 continue;
227 *p++ = 0; 255 *p++ = 0;
228 if (strncmp(p, "is not set", 10)) 256 if (strncmp(p, "is not set", 10))
229 continue; 257 continue;
230 if (def == S_DEF_USER) { 258 if (def == S_DEF_USER) {
231 sym = sym_find(line + 9); 259 sym = sym_find(line + 2 + strlen(CONFIG_));
232 if (!sym) { 260 if (!sym) {
233 sym_add_change_count(1); 261 sym_add_change_count(1);
234 break; 262 goto setsym;
235 } 263 }
236 } else { 264 } else {
237 sym = sym_lookup(line + 9, 0); 265 sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
238 if (sym->type == S_UNKNOWN) 266 if (sym->type == S_UNKNOWN)
239 sym->type = S_BOOLEAN; 267 sym->type = S_BOOLEAN;
240 } 268 }
@@ -250,13 +278,8 @@ load:
250 default: 278 default:
251 ; 279 ;
252 } 280 }
253 break; 281 } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
254 case 'C': 282 p = strchr(line + strlen(CONFIG_), '=');
255 if (memcmp(line, "CONFIG_", 7)) {
256 conf_warning("unexpected data");
257 continue;
258 }
259 p = strchr(line + 7, '=');
260 if (!p) 283 if (!p)
261 continue; 284 continue;
262 *p++ = 0; 285 *p++ = 0;
@@ -267,13 +290,13 @@ load:
267 *p2 = 0; 290 *p2 = 0;
268 } 291 }
269 if (def == S_DEF_USER) { 292 if (def == S_DEF_USER) {
270 sym = sym_find(line + 7); 293 sym = sym_find(line + strlen(CONFIG_));
271 if (!sym) { 294 if (!sym) {
272 sym_add_change_count(1); 295 sym_add_change_count(1);
273 break; 296 goto setsym;
274 } 297 }
275 } else { 298 } else {
276 sym = sym_lookup(line + 7, 0); 299 sym = sym_lookup(line + strlen(CONFIG_), 0);
277 if (sym->type == S_UNKNOWN) 300 if (sym->type == S_UNKNOWN)
278 sym->type = S_OTHER; 301 sym->type = S_OTHER;
279 } 302 }
@@ -282,14 +305,12 @@ load:
282 } 305 }
283 if (conf_set_sym_val(sym, def, def_flags, p)) 306 if (conf_set_sym_val(sym, def, def_flags, p))
284 continue; 307 continue;
285 break; 308 } else {
286 case '\r': 309 if (line[0] != '\r' && line[0] != '\n')
287 case '\n': 310 conf_warning("unexpected data");
288 break;
289 default:
290 conf_warning("unexpected data");
291 continue; 311 continue;
292 } 312 }
313setsym:
293 if (sym && sym_is_choice_value(sym)) { 314 if (sym && sym_is_choice_value(sym)) {
294 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 315 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
295 switch (sym->def[def].tri) { 316 switch (sym->def[def].tri) {
@@ -396,15 +417,149 @@ int conf_read(const char *name)
396 return 0; 417 return 0;
397} 418}
398 419
420/* Write a S_STRING */
421static void conf_write_string(bool headerfile, const char *name,
422 const char *str, FILE *out)
423{
424 int l;
425 if (headerfile)
426 fprintf(out, "#define %s%s \"", CONFIG_, name);
427 else
428 fprintf(out, "%s%s=\"", CONFIG_, name);
429
430 while (1) {
431 l = strcspn(str, "\"\\");
432 if (l) {
433 xfwrite(str, l, 1, out);
434 str += l;
435 }
436 if (!*str)
437 break;
438 fprintf(out, "\\%c", *str++);
439 }
440 fputs("\"\n", out);
441}
442
443static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
444{
445 const char *str;
446
447 switch (sym->type) {
448 case S_BOOLEAN:
449 case S_TRISTATE:
450 switch (sym_get_tristate_value(sym)) {
451 case no:
452 if (write_no)
453 fprintf(out, "# %s%s is not set\n",
454 CONFIG_, sym->name);
455 break;
456 case mod:
457 fprintf(out, "%s%s=m\n", CONFIG_, sym->name);
458 break;
459 case yes:
460 fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
461 break;
462 }
463 break;
464 case S_STRING:
465 conf_write_string(false, sym->name, sym_get_string_value(sym), out);
466 break;
467 case S_HEX:
468 case S_INT:
469 str = sym_get_string_value(sym);
470 fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str);
471 break;
472 case S_OTHER:
473 case S_UNKNOWN:
474 break;
475 }
476}
477
478/*
479 * Write out a minimal config.
480 * All values that has default values are skipped as this is redundant.
481 */
482int conf_write_defconfig(const char *filename)
483{
484 struct symbol *sym;
485 struct menu *menu;
486 FILE *out;
487
488 out = fopen(filename, "w");
489 if (!out)
490 return 1;
491
492 sym_clear_all_valid();
493
494 /* Traverse all menus to find all relevant symbols */
495 menu = rootmenu.list;
496
497 while (menu != NULL)
498 {
499 sym = menu->sym;
500 if (sym == NULL) {
501 if (!menu_is_visible(menu))
502 goto next_menu;
503 } else if (!sym_is_choice(sym)) {
504 sym_calc_value(sym);
505 if (!(sym->flags & SYMBOL_WRITE))
506 goto next_menu;
507 sym->flags &= ~SYMBOL_WRITE;
508 /* If we cannot change the symbol - skip */
509 if (!sym_is_changable(sym))
510 goto next_menu;
511 /* If symbol equals to default value - skip */
512 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
513 goto next_menu;
514
515 /*
516 * If symbol is a choice value and equals to the
517 * default for a choice - skip.
518 * But only if value is bool and equal to "y" and
519 * choice is not "optional".
520 * (If choice is "optional" then all values can be "n")
521 */
522 if (sym_is_choice_value(sym)) {
523 struct symbol *cs;
524 struct symbol *ds;
525
526 cs = prop_get_symbol(sym_get_choice_prop(sym));
527 ds = sym_choice_default(cs);
528 if (!sym_is_optional(cs) && sym == ds) {
529 if ((sym->type == S_BOOLEAN) &&
530 sym_get_tristate_value(sym) == yes)
531 goto next_menu;
532 }
533 }
534 conf_write_symbol(sym, out, true);
535 }
536next_menu:
537 if (menu->list != NULL) {
538 menu = menu->list;
539 }
540 else if (menu->next != NULL) {
541 menu = menu->next;
542 } else {
543 while ((menu = menu->parent)) {
544 if (menu->next != NULL) {
545 menu = menu->next;
546 break;
547 }
548 }
549 }
550 }
551 fclose(out);
552 return 0;
553}
554
399int conf_write(const char *name) 555int conf_write(const char *name)
400{ 556{
401 FILE *out; 557 FILE *out;
402 struct symbol *sym; 558 struct symbol *sym;
403 struct menu *menu; 559 struct menu *menu;
404 const char *basename; 560 const char *basename;
405 char dirname[128], tmpname[128], newname[128];
406 int type, l;
407 const char *str; 561 const char *str;
562 char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
408 time_t now; 563 time_t now;
409 int use_timestamp = 1; 564 int use_timestamp = 1;
410 char *env; 565 char *env;
@@ -443,8 +598,6 @@ int conf_write(const char *name)
443 if (!out) 598 if (!out)
444 return 1; 599 return 1;
445 600
446 sym = sym_lookup("KERNELVERSION", 0);
447 sym_calc_value(sym);
448 time(&now); 601 time(&now);
449 env = getenv("KCONFIG_NOTIMESTAMP"); 602 env = getenv("KCONFIG_NOTIMESTAMP");
450 if (env && *env) 603 if (env && *env)
@@ -452,10 +605,10 @@ int conf_write(const char *name)
452 605
453 fprintf(out, _("#\n" 606 fprintf(out, _("#\n"
454 "# Automatically generated make config: don't edit\n" 607 "# Automatically generated make config: don't edit\n"
455 "# Linux kernel version: %s\n" 608 "# %s\n"
456 "%s%s" 609 "%s%s"
457 "#\n"), 610 "#\n"),
458 sym_get_string_value(sym), 611 rootmenu.prompt->text,
459 use_timestamp ? "# " : "", 612 use_timestamp ? "# " : "",
460 use_timestamp ? ctime(&now) : ""); 613 use_timestamp ? ctime(&now) : "");
461 614
@@ -478,56 +631,11 @@ int conf_write(const char *name)
478 if (!(sym->flags & SYMBOL_WRITE)) 631 if (!(sym->flags & SYMBOL_WRITE))
479 goto next; 632 goto next;
480 sym->flags &= ~SYMBOL_WRITE; 633 sym->flags &= ~SYMBOL_WRITE;
481 type = sym->type; 634 /* Write config symbol to file */
482 if (type == S_TRISTATE) { 635 conf_write_symbol(sym, out, true);
483 sym_calc_value(modules_sym);
484 if (modules_sym->curr.tri == no)
485 type = S_BOOLEAN;
486 }
487 switch (type) {
488 case S_BOOLEAN:
489 case S_TRISTATE:
490 switch (sym_get_tristate_value(sym)) {
491 case no:
492 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
493 break;
494 case mod:
495 fprintf(out, "CONFIG_%s=m\n", sym->name);
496 break;
497 case yes:
498 fprintf(out, "CONFIG_%s=y\n", sym->name);
499 break;
500 }
501 break;
502 case S_STRING:
503 str = sym_get_string_value(sym);
504 fprintf(out, "CONFIG_%s=\"", sym->name);
505 while (1) {
506 l = strcspn(str, "\"\\");
507 if (l) {
508 fwrite(str, l, 1, out);
509 str += l;
510 }
511 if (!*str)
512 break;
513 fprintf(out, "\\%c", *str++);
514 }
515 fputs("\"\n", out);
516 break;
517 case S_HEX:
518 str = sym_get_string_value(sym);
519 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
520 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
521 break;
522 }
523 case S_INT:
524 str = sym_get_string_value(sym);
525 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
526 break;
527 }
528 } 636 }
529 637
530 next: 638next:
531 if (menu->list) { 639 if (menu->list) {
532 menu = menu->list; 640 menu = menu->list;
533 continue; 641 continue;
@@ -551,19 +659,17 @@ int conf_write(const char *name)
551 return 1; 659 return 1;
552 } 660 }
553 661
554 printf(_("#\n" 662 conf_message(_("configuration written to %s"), newname);
555 "# configuration written to %s\n"
556 "#\n"), newname);
557 663
558 sym_set_change_count(0); 664 sym_set_change_count(0);
559 665
560 return 0; 666 return 0;
561} 667}
562 668
563int conf_split_config(void) 669static int conf_split_config(void)
564{ 670{
565 const char *name; 671 const char *name;
566 char path[128]; 672 char path[PATH_MAX+1];
567 char *s, *d, c; 673 char *s, *d, c;
568 struct symbol *sym; 674 struct symbol *sym;
569 struct stat sb; 675 struct stat sb;
@@ -677,9 +783,9 @@ int conf_write_autoconf(void)
677 struct symbol *sym; 783 struct symbol *sym;
678 const char *str; 784 const char *str;
679 const char *name; 785 const char *name;
680 FILE *out, *out_h; 786 FILE *out, *tristate, *out_h;
681 time_t now; 787 time_t now;
682 int i, l; 788 int i;
683 789
684 sym_clear_all_valid(); 790 sym_clear_all_valid();
685 791
@@ -692,33 +798,45 @@ int conf_write_autoconf(void)
692 if (!out) 798 if (!out)
693 return 1; 799 return 1;
694 800
801 tristate = fopen(".tmpconfig_tristate", "w");
802 if (!tristate) {
803 fclose(out);
804 return 1;
805 }
806
695 out_h = fopen(".tmpconfig.h", "w"); 807 out_h = fopen(".tmpconfig.h", "w");
696 if (!out_h) { 808 if (!out_h) {
697 fclose(out); 809 fclose(out);
810 fclose(tristate);
698 return 1; 811 return 1;
699 } 812 }
700 813
701 sym = sym_lookup("KERNELVERSION", 0);
702 sym_calc_value(sym);
703 time(&now); 814 time(&now);
704 fprintf(out, "#\n" 815 fprintf(out, "#\n"
705 "# Automatically generated make config: don't edit\n" 816 "# Automatically generated make config: don't edit\n"
706 "# Linux kernel version: %s\n" 817 "# %s\n"
707 "# %s" 818 "# %s"
708 "#\n", 819 "#\n",
709 sym_get_string_value(sym), ctime(&now)); 820 rootmenu.prompt->text, ctime(&now));
821 fprintf(tristate, "#\n"
822 "# Automatically generated - do not edit\n"
823 "\n");
710 fprintf(out_h, "/*\n" 824 fprintf(out_h, "/*\n"
711 " * Automatically generated C config: don't edit\n" 825 " * Automatically generated C config: don't edit\n"
712 " * Linux kernel version: %s\n" 826 " * %s\n"
713 " * %s" 827 " * %s"
714 " */\n" 828 " */\n",
715 "#define AUTOCONF_INCLUDED\n", 829 rootmenu.prompt->text, ctime(&now));
716 sym_get_string_value(sym), ctime(&now));
717 830
718 for_all_symbols(i, sym) { 831 for_all_symbols(i, sym) {
719 sym_calc_value(sym); 832 sym_calc_value(sym);
720 if (!(sym->flags & SYMBOL_WRITE) || !sym->name) 833 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
721 continue; 834 continue;
835
836 /* write symbol to config file */
837 conf_write_symbol(sym, out, false);
838
839 /* update autoconf and tristate files */
722 switch (sym->type) { 840 switch (sym->type) {
723 case S_BOOLEAN: 841 case S_BOOLEAN:
724 case S_TRISTATE: 842 case S_TRISTATE:
@@ -726,59 +844,53 @@ int conf_write_autoconf(void)
726 case no: 844 case no:
727 break; 845 break;
728 case mod: 846 case mod:
729 fprintf(out, "CONFIG_%s=m\n", sym->name); 847 fprintf(tristate, "%s%s=M\n",
730 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 848 CONFIG_, sym->name);
849 fprintf(out_h, "#define %s%s_MODULE 1\n",
850 CONFIG_, sym->name);
731 break; 851 break;
732 case yes: 852 case yes:
733 fprintf(out, "CONFIG_%s=y\n", sym->name); 853 if (sym->type == S_TRISTATE)
734 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 854 fprintf(tristate,"%s%s=Y\n",
855 CONFIG_, sym->name);
856 fprintf(out_h, "#define %s%s 1\n",
857 CONFIG_, sym->name);
735 break; 858 break;
736 } 859 }
737 break; 860 break;
738 case S_STRING: 861 case S_STRING:
739 str = sym_get_string_value(sym); 862 conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
740 fprintf(out, "CONFIG_%s=\"", sym->name);
741 fprintf(out_h, "#define CONFIG_%s \"", sym->name);
742 while (1) {
743 l = strcspn(str, "\"\\");
744 if (l) {
745 fwrite(str, l, 1, out);
746 fwrite(str, l, 1, out_h);
747 str += l;
748 }
749 if (!*str)
750 break;
751 fprintf(out, "\\%c", *str);
752 fprintf(out_h, "\\%c", *str);
753 str++;
754 }
755 fputs("\"\n", out);
756 fputs("\"\n", out_h);
757 break; 863 break;
758 case S_HEX: 864 case S_HEX:
759 str = sym_get_string_value(sym); 865 str = sym_get_string_value(sym);
760 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 866 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
761 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 867 fprintf(out_h, "#define %s%s 0x%s\n",
762 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 868 CONFIG_, sym->name, str);
763 break; 869 break;
764 } 870 }
765 case S_INT: 871 case S_INT:
766 str = sym_get_string_value(sym); 872 str = sym_get_string_value(sym);
767 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 873 fprintf(out_h, "#define %s%s %s\n",
768 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 874 CONFIG_, sym->name, str);
769 break; 875 break;
770 default: 876 default:
771 break; 877 break;
772 } 878 }
773 } 879 }
774 fclose(out); 880 fclose(out);
881 fclose(tristate);
775 fclose(out_h); 882 fclose(out_h);
776 883
777 name = getenv("KCONFIG_AUTOHEADER"); 884 name = getenv("KCONFIG_AUTOHEADER");
778 if (!name) 885 if (!name)
779 name = "include/linux/autoconf.h"; 886 name = "include/generated/autoconf.h";
780 if (rename(".tmpconfig.h", name)) 887 if (rename(".tmpconfig.h", name))
781 return 1; 888 return 1;
889 name = getenv("KCONFIG_TRISTATE");
890 if (!name)
891 name = "include/config/tristate.conf";
892 if (rename(".tmpconfig_tristate", name))
893 return 1;
782 name = conf_get_autoconfig_name(); 894 name = conf_get_autoconfig_name();
783 /* 895 /*
784 * This must be the last step, kbuild has a dependency on auto.conf 896 * This must be the last step, kbuild has a dependency on auto.conf
@@ -817,13 +929,73 @@ void conf_set_changed_callback(void (*fn)(void))
817 conf_changed_callback = fn; 929 conf_changed_callback = fn;
818} 930}
819 931
932static void randomize_choice_values(struct symbol *csym)
933{
934 struct property *prop;
935 struct symbol *sym;
936 struct expr *e;
937 int cnt, def;
820 938
821void conf_set_all_new_symbols(enum conf_def_mode mode) 939 /*
940 * If choice is mod then we may have more items selected
941 * and if no then no-one.
942 * In both cases stop.
943 */
944 if (csym->curr.tri != yes)
945 return;
946
947 prop = sym_get_choice_prop(csym);
948
949 /* count entries in choice block */
950 cnt = 0;
951 expr_list_for_each_sym(prop->expr, e, sym)
952 cnt++;
953
954 /*
955 * find a random value and set it to yes,
956 * set the rest to no so we have only one set
957 */
958 def = (rand() % cnt);
959
960 cnt = 0;
961 expr_list_for_each_sym(prop->expr, e, sym) {
962 if (def == cnt++) {
963 sym->def[S_DEF_USER].tri = yes;
964 csym->def[S_DEF_USER].val = sym;
965 }
966 else {
967 sym->def[S_DEF_USER].tri = no;
968 }
969 }
970 csym->flags |= SYMBOL_DEF_USER;
971 /* clear VALID to get value calculated */
972 csym->flags &= ~(SYMBOL_VALID);
973}
974
975static void set_all_choice_values(struct symbol *csym)
822{ 976{
823 struct symbol *sym, *csym;
824 struct property *prop; 977 struct property *prop;
978 struct symbol *sym;
825 struct expr *e; 979 struct expr *e;
826 int i, cnt, def; 980
981 prop = sym_get_choice_prop(csym);
982
983 /*
984 * Set all non-assinged choice values to no
985 */
986 expr_list_for_each_sym(prop->expr, e, sym) {
987 if (!sym_has_value(sym))
988 sym->def[S_DEF_USER].tri = no;
989 }
990 csym->flags |= SYMBOL_DEF_USER;
991 /* clear VALID to get value calculated */
992 csym->flags &= ~(SYMBOL_VALID);
993}
994
995void conf_set_all_new_symbols(enum conf_def_mode mode)
996{
997 struct symbol *sym, *csym;
998 int i, cnt;
827 999
828 for_all_symbols(i, sym) { 1000 for_all_symbols(i, sym) {
829 if (sym_has_value(sym)) 1001 if (sym_has_value(sym))
@@ -842,7 +1014,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
842 sym->def[S_DEF_USER].tri = no; 1014 sym->def[S_DEF_USER].tri = no;
843 break; 1015 break;
844 case def_random: 1016 case def_random:
845 sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); 1017 cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
1018 sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
846 break; 1019 break;
847 default: 1020 default:
848 continue; 1021 continue;
@@ -858,14 +1031,12 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
858 1031
859 sym_clear_all_valid(); 1032 sym_clear_all_valid();
860 1033
861 if (mode != def_random)
862 return;
863 /* 1034 /*
864 * We have different type of choice blocks. 1035 * We have different type of choice blocks.
865 * If curr.tri equal to mod then we can select several 1036 * If curr.tri equals to mod then we can select several
866 * choice symbols in one block. 1037 * choice symbols in one block.
867 * In this case we do nothing. 1038 * In this case we do nothing.
868 * If curr.tri equal yes then only one symbol can be 1039 * If curr.tri equals yes then only one symbol can be
869 * selected in a choice block and we set it to yes, 1040 * selected in a choice block and we set it to yes,
870 * and the rest to no. 1041 * and the rest to no.
871 */ 1042 */
@@ -874,35 +1045,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
874 continue; 1045 continue;
875 1046
876 sym_calc_value(csym); 1047 sym_calc_value(csym);
877 1048 if (mode == def_random)
878 if (csym->curr.tri != yes) 1049 randomize_choice_values(csym);
879 continue; 1050 else
880 1051 set_all_choice_values(csym);
881 prop = sym_get_choice_prop(csym);
882
883 /* count entries in choice block */
884 cnt = 0;
885 expr_list_for_each_sym(prop->expr, e, sym)
886 cnt++;
887
888 /*
889 * find a random value and set it to yes,
890 * set the rest to no so we have only one set
891 */
892 def = (rand() % cnt);
893
894 cnt = 0;
895 expr_list_for_each_sym(prop->expr, e, sym) {
896 if (def == cnt++) {
897 sym->def[S_DEF_USER].tri = yes;
898 csym->def[S_DEF_USER].val = sym;
899 }
900 else {
901 sym->def[S_DEF_USER].tri = no;
902 }
903 }
904 csym->flags |= SYMBOL_DEF_USER;
905 /* clear VALID to get value calculated */
906 csym->flags &= ~(SYMBOL_VALID);
907 } 1052 }
908} 1053}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 579ece4fa584..001003452f68 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -64,7 +64,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
64 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; 64 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
65} 65}
66 66
67struct expr *expr_copy(struct expr *org) 67struct expr *expr_copy(const struct expr *org)
68{ 68{
69 struct expr *e; 69 struct expr *e;
70 70
@@ -348,7 +348,7 @@ struct expr *expr_trans_bool(struct expr *e)
348/* 348/*
349 * e1 || e2 -> ? 349 * e1 || e2 -> ?
350 */ 350 */
351struct expr *expr_join_or(struct expr *e1, struct expr *e2) 351static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
352{ 352{
353 struct expr *tmp; 353 struct expr *tmp;
354 struct symbol *sym1, *sym2; 354 struct symbol *sym1, *sym2;
@@ -412,7 +412,7 @@ struct expr *expr_join_or(struct expr *e1, struct expr *e2)
412 return NULL; 412 return NULL;
413} 413}
414 414
415struct expr *expr_join_and(struct expr *e1, struct expr *e2) 415static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
416{ 416{
417 struct expr *tmp; 417 struct expr *tmp;
418 struct symbol *sym1, *sym2; 418 struct symbol *sym1, *sym2;
@@ -1013,6 +1013,48 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
1013#endif 1013#endif
1014} 1014}
1015 1015
1016static inline struct expr *
1017expr_get_leftmost_symbol(const struct expr *e)
1018{
1019
1020 if (e == NULL)
1021 return NULL;
1022
1023 while (e->type != E_SYMBOL)
1024 e = e->left.expr;
1025
1026 return expr_copy(e);
1027}
1028
1029/*
1030 * Given expression `e1' and `e2', returns the leaf of the longest
1031 * sub-expression of `e1' not containing 'e2.
1032 */
1033struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1034{
1035 struct expr *ret;
1036
1037 switch (e1->type) {
1038 case E_OR:
1039 return expr_alloc_and(
1040 expr_simplify_unmet_dep(e1->left.expr, e2),
1041 expr_simplify_unmet_dep(e1->right.expr, e2));
1042 case E_AND: {
1043 struct expr *e;
1044 e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
1045 e = expr_eliminate_dups(e);
1046 ret = (!expr_eq(e, e1)) ? e1 : NULL;
1047 expr_free(e);
1048 break;
1049 }
1050 default:
1051 ret = e1;
1052 break;
1053 }
1054
1055 return expr_get_leftmost_symbol(ret);
1056}
1057
1016void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) 1058void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1017{ 1059{
1018 if (!e) { 1060 if (!e) {
@@ -1087,7 +1129,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
1087 1129
1088static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 1130static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1089{ 1131{
1090 fwrite(str, strlen(str), 1, data); 1132 xfwrite(str, strlen(str), 1, data);
1091} 1133}
1092 1134
1093void expr_fprint(struct expr *e, FILE *out) 1135void expr_fprint(struct expr *e, FILE *out)
@@ -1097,7 +1139,32 @@ void expr_fprint(struct expr *e, FILE *out)
1097 1139
1098static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) 1140static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1099{ 1141{
1100 str_append((struct gstr*)data, str); 1142 struct gstr *gs = (struct gstr*)data;
1143 const char *sym_str = NULL;
1144
1145 if (sym)
1146 sym_str = sym_get_string_value(sym);
1147
1148 if (gs->max_width) {
1149 unsigned extra_length = strlen(str);
1150 const char *last_cr = strrchr(gs->s, '\n');
1151 unsigned last_line_length;
1152
1153 if (sym_str)
1154 extra_length += 4 + strlen(sym_str);
1155
1156 if (!last_cr)
1157 last_cr = gs->s;
1158
1159 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1160
1161 if ((last_line_length + extra_length) > gs->max_width)
1162 str_append(gs, "\\\n");
1163 }
1164
1165 str_append(gs, str);
1166 if (sym && sym->type != S_UNKNOWN)
1167 str_printf(gs, " [=%s]", sym_str);
1101} 1168}
1102 1169
1103void expr_gstr_print(struct expr *e, struct gstr *gs) 1170void expr_gstr_print(struct expr *e, struct gstr *gs)
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 6408fefae083..3d238db49764 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -18,7 +18,7 @@ extern "C" {
18struct file { 18struct file {
19 struct file *next; 19 struct file *next;
20 struct file *parent; 20 struct file *parent;
21 char *name; 21 const char *name;
22 int lineno; 22 int lineno;
23 int flags; 23 int flags;
24}; 24};
@@ -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 {
@@ -163,6 +164,7 @@ struct menu {
163 struct menu *list; 164 struct menu *list;
164 struct symbol *sym; 165 struct symbol *sym;
165 struct property *prompt; 166 struct property *prompt;
167 struct expr *visibility;
166 struct expr *dep; 168 struct expr *dep;
167 unsigned int flags; 169 unsigned int flags;
168 char *help; 170 char *help;
@@ -190,7 +192,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e
190struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); 192struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
191struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); 193struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
192struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); 194struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
193struct expr *expr_copy(struct expr *org); 195struct expr *expr_copy(const struct expr *org);
194void expr_free(struct expr *e); 196void expr_free(struct expr *e);
195int expr_eq(struct expr *e1, struct expr *e2); 197int expr_eq(struct expr *e1, struct expr *e2);
196void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); 198void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
@@ -205,6 +207,7 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
205struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); 207struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
206void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); 208void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
207struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); 209struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
210struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
208 211
209void expr_fprint(struct expr *e, FILE *out); 212void expr_fprint(struct expr *e, FILE *out);
210struct gstr; /* forward */ 213struct gstr; /* forward */
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 199b22bb49e2..455896164d72 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{
@@ -189,7 +133,6 @@ void init_main_window(const gchar * glade_file)
189 GladeXML *xml; 133 GladeXML *xml;
190 GtkWidget *widget; 134 GtkWidget *widget;
191 GtkTextBuffer *txtbuf; 135 GtkTextBuffer *txtbuf;
192 char title[256];
193 GtkStyle *style; 136 GtkStyle *style;
194 137
195 xml = glade_xml_new(glade_file, "window1", NULL); 138 xml = glade_xml_new(glade_file, "window1", NULL);
@@ -266,9 +209,7 @@ void init_main_window(const gchar * glade_file)
266 /*"style", PANGO_STYLE_OBLIQUE, */ 209 /*"style", PANGO_STYLE_OBLIQUE, */
267 NULL); 210 NULL);
268 211
269 sprintf(title, _("Linux Kernel v%s Configuration"), 212 gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
270 getenv("KERNELVERSION"));
271 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
272 213
273 gtk_widget_show(main_wnd); 214 gtk_widget_show(main_wnd);
274} 215}
@@ -456,19 +397,9 @@ static void text_insert_help(struct menu *menu)
456 GtkTextBuffer *buffer; 397 GtkTextBuffer *buffer;
457 GtkTextIter start, end; 398 GtkTextIter start, end;
458 const char *prompt = _(menu_get_prompt(menu)); 399 const char *prompt = _(menu_get_prompt(menu));
459 gchar *name; 400 struct gstr help = str_new();
460 const char *help;
461
462 help = menu_get_help(menu);
463 401
464 /* Gettextize if the help text not empty */ 402 menu_get_ext_help(menu, &help);
465 if ((help != 0) && (help[0] != 0))
466 help = _(help);
467
468 if (menu->sym && menu->sym->name)
469 name = g_strdup_printf(menu->sym->name);
470 else
471 name = g_strdup("");
472 403
473 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); 404 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
474 gtk_text_buffer_get_bounds(buffer, &start, &end); 405 gtk_text_buffer_get_bounds(buffer, &start, &end);
@@ -478,14 +409,11 @@ static void text_insert_help(struct menu *menu)
478 gtk_text_buffer_get_end_iter(buffer, &end); 409 gtk_text_buffer_get_end_iter(buffer, &end);
479 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, 410 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
480 NULL); 411 NULL);
481 gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
482 gtk_text_buffer_get_end_iter(buffer, &end);
483 gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
484 NULL);
485 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); 412 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
486 gtk_text_buffer_get_end_iter(buffer, &end); 413 gtk_text_buffer_get_end_iter(buffer, &end);
487 gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2, 414 gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
488 NULL); 415 NULL);
416 str_free(&help);
489} 417}
490 418
491 419
@@ -710,20 +638,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
710 638
711 639
712void 640void
713on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) 641on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
714{ 642{
715 show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; 643 opt_mode = OPT_NORMAL;
644 gtk_tree_store_clear(tree2);
645 display_tree(&rootmenu); /* instead of update_tree to speed-up */
646}
716 647
648
649void
650on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
651{
652 opt_mode = OPT_ALL;
717 gtk_tree_store_clear(tree2); 653 gtk_tree_store_clear(tree2);
718 display_tree(&rootmenu); // instead of update_tree to speed-up 654 display_tree(&rootmenu); /* instead of update_tree to speed-up */
719} 655}
720 656
721 657
722void 658void
723on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) 659on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
724{ 660{
725 show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; 661 opt_mode = OPT_PROMPT;
726 update_tree(&rootmenu, NULL); 662 gtk_tree_store_clear(tree2);
663 display_tree(&rootmenu); /* instead of update_tree to speed-up */
727} 664}
728 665
729 666
@@ -731,8 +668,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
731{ 668{
732 GtkWidget *dialog; 669 GtkWidget *dialog;
733 const gchar *intro_text = _( 670 const gchar *intro_text = _(
734 "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" 671 "Welcome to gkc, the GTK+ graphical configuration tool\n"
735 "for Linux.\n"
736 "For each option, a blank box indicates the feature is disabled, a\n" 672 "For each option, a blank box indicates the feature is disabled, a\n"
737 "check indicates it is enabled, and a dot indicates that it is to\n" 673 "check indicates it is enabled, and a dot indicates that it is to\n"
738 "be compiled as a module. Clicking on the box will cycle through the three states.\n" 674 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
@@ -1174,9 +1110,12 @@ static gchar **fill_row(struct menu *menu)
1174 1110
1175 row[COL_OPTION] = 1111 row[COL_OPTION] =
1176 g_strdup_printf("%s %s", _(menu_get_prompt(menu)), 1112 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1177 sym && sym_has_value(sym) ? "(NEW)" : ""); 1113 sym && !sym_has_value(sym) ? "(NEW)" : "");
1178 1114
1179 if (show_all && !menu_is_visible(menu)) 1115 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1116 row[COL_COLOR] = g_strdup("DarkGray");
1117 else if (opt_mode == OPT_PROMPT &&
1118 menu_has_prompt(menu) && !menu_is_visible(menu))
1180 row[COL_COLOR] = g_strdup("DarkGray"); 1119 row[COL_COLOR] = g_strdup("DarkGray");
1181 else 1120 else
1182 row[COL_COLOR] = g_strdup("Black"); 1121 row[COL_COLOR] = g_strdup("Black");
@@ -1399,16 +1338,20 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
1399 menu2 ? menu_get_prompt(menu2) : "nil"); 1338 menu2 ? menu_get_prompt(menu2) : "nil");
1400#endif 1339#endif
1401 1340
1402 if (!menu_is_visible(child1) && !show_all) { // remove node 1341 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1342 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1343 (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
1344
1345 /* remove node */
1403 if (gtktree_iter_find_node(dst, menu1) != NULL) { 1346 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1404 memcpy(&tmp, child2, sizeof(GtkTreeIter)); 1347 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1405 valid = gtk_tree_model_iter_next(model2, 1348 valid = gtk_tree_model_iter_next(model2,
1406 child2); 1349 child2);
1407 gtk_tree_store_remove(tree2, &tmp); 1350 gtk_tree_store_remove(tree2, &tmp);
1408 if (!valid) 1351 if (!valid)
1409 return; // next parent 1352 return; /* next parent */
1410 else 1353 else
1411 goto reparse; // next child 1354 goto reparse; /* next child */
1412 } else 1355 } else
1413 continue; 1356 continue;
1414 } 1357 }
@@ -1477,17 +1420,19 @@ static void display_tree(struct menu *menu)
1477 && (tree == tree2)) 1420 && (tree == tree2))
1478 continue; 1421 continue;
1479 1422
1480 if (menu_is_visible(child) || show_all) 1423 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1424 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1425 (opt_mode == OPT_ALL && menu_get_prompt(child)))
1481 place_node(child, fill_row(child)); 1426 place_node(child, fill_row(child));
1482#ifdef DEBUG 1427#ifdef DEBUG
1483 printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); 1428 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1484 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); 1429 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1485 dbg_print_ptype(ptype); 1430 printf("%s", prop_get_type_name(ptype));
1486 printf(" | "); 1431 printf(" | ");
1487 if (sym) { 1432 if (sym) {
1488 dbg_print_stype(sym->type); 1433 printf("%s", sym_type_name(sym->type));
1489 printf(" | "); 1434 printf(" | ");
1490 dbg_print_flags(sym->flags); 1435 printf("%s", dbg_sym_flags(sym->flags));
1491 printf("\n"); 1436 printf("\n");
1492 } else 1437 } else
1493 printf("\n"); 1438 printf("\n");
@@ -1582,12 +1527,6 @@ int main(int ac, char *av[])
1582 else 1527 else
1583 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); 1528 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
1584 1529
1585 /* Load the interface and connect signals */
1586 init_main_window(glade_file);
1587 init_tree_model();
1588 init_left_tree();
1589 init_right_tree();
1590
1591 /* Conf stuffs */ 1530 /* Conf stuffs */
1592 if (ac > 1 && av[1][0] == '-') { 1531 if (ac > 1 && av[1][0] == '-') {
1593 switch (av[1][1]) { 1532 switch (av[1][1]) {
@@ -1607,6 +1546,12 @@ int main(int ac, char *av[])
1607 fixup_rootmenu(&rootmenu); 1546 fixup_rootmenu(&rootmenu);
1608 conf_read(NULL); 1547 conf_read(NULL);
1609 1548
1549 /* Load the interface and connect signals */
1550 init_main_window(glade_file);
1551 init_tree_model();
1552 init_left_tree();
1553 init_right_tree();
1554
1610 switch (view_mode) { 1555 switch (view_mode) {
1611 case SINGLE_VIEW: 1556 case SINGLE_VIEW:
1612 display_tree_part(); 1557 display_tree_part();
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index 803233fdd6dd..aa483cb32755 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -1,5 +1,4 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> 1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3 2
4<glade-interface> 3<glade-interface>
5 4
@@ -190,26 +189,40 @@
190 </child> 189 </child>
191 190
192 <child> 191 <child>
193 <widget class="GtkCheckMenuItem" id="show_all_options1"> 192 <widget class="GtkRadioMenuItem" id="set_option_mode1">
193 <property name="visible">True</property>
194 <property name="tooltip" translatable="yes">Show normal options</property>
195 <property name="label" translatable="yes">Show normal options</property>
196 <property name="use_underline">True</property>
197 <property name="active">True</property>
198 <signal name="activate" handler="on_set_option_mode1_activate"/>
199 </widget>
200 </child>
201
202 <child>
203 <widget class="GtkRadioMenuItem" id="set_option_mode2">
194 <property name="visible">True</property> 204 <property name="visible">True</property>
195 <property name="tooltip" translatable="yes">Show all options</property> 205 <property name="tooltip" translatable="yes">Show all options</property>
196 <property name="label" translatable="yes">Show all _options</property> 206 <property name="label" translatable="yes">Show all _options</property>
197 <property name="use_underline">True</property> 207 <property name="use_underline">True</property>
198 <property name="active">False</property> 208 <property name="active">False</property>
199 <signal name="activate" handler="on_show_all_options1_activate"/> 209 <property name="group">set_option_mode1</property>
210 <signal name="activate" handler="on_set_option_mode2_activate"/>
200 </widget> 211 </widget>
201 </child> 212 </child>
202 213
203 <child> 214 <child>
204 <widget class="GtkCheckMenuItem" id="show_debug_info1"> 215 <widget class="GtkRadioMenuItem" id="set_option_mode3">
205 <property name="visible">True</property> 216 <property name="visible">True</property>
206 <property name="tooltip" translatable="yes">Show masked options</property> 217 <property name="tooltip" translatable="yes">Show all options with prompts</property>
207 <property name="label" translatable="yes">Show _debug info</property> 218 <property name="label" translatable="yes">Show all prompt options</property>
208 <property name="use_underline">True</property> 219 <property name="use_underline">True</property>
209 <property name="active">False</property> 220 <property name="active">False</property>
210 <signal name="activate" handler="on_show_debug_info1_activate"/> 221 <property name="group">set_option_mode1</property>
222 <signal name="activate" handler="on_set_option_mode3_activate"/>
211 </widget> 223 </widget>
212 </child> 224 </child>
225
213 </widget> 226 </widget>
214 </child> 227 </child>
215 </widget> 228 </widget>
@@ -547,7 +560,7 @@
547 <property name="headers_visible">True</property> 560 <property name="headers_visible">True</property>
548 <property name="rules_hint">False</property> 561 <property name="rules_hint">False</property>
549 <property name="reorderable">False</property> 562 <property name="reorderable">False</property>
550 <property name="enable_search">True</property> 563 <property name="enable_search">False</property>
551 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/> 564 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
552 <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/> 565 <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
553 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/> 566 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/>
@@ -582,7 +595,7 @@
582 <property name="headers_visible">True</property> 595 <property name="headers_visible">True</property>
583 <property name="rules_hint">False</property> 596 <property name="rules_hint">False</property>
584 <property name="reorderable">False</property> 597 <property name="reorderable">False</property>
585 <property name="enable_search">True</property> 598 <property name="enable_search">False</property>
586 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/> 599 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
587 <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/> 600 <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
588 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/> 601 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
index 8d9ce22b0fc5..e9d8e791bf0d 100644
--- a/scripts/kconfig/kxgettext.c
+++ b/scripts/kconfig/kxgettext.c
@@ -63,11 +63,11 @@ next:
63 63
64struct file_line { 64struct file_line {
65 struct file_line *next; 65 struct file_line *next;
66 char* file; 66 const char *file;
67 int lineno; 67 int lineno;
68}; 68};
69 69
70static struct file_line *file_line__new(char *file, int lineno) 70static struct file_line *file_line__new(const char *file, int lineno)
71{ 71{
72 struct file_line *self = malloc(sizeof(*self)); 72 struct file_line *self = malloc(sizeof(*self));
73 73
@@ -90,7 +90,8 @@ struct message {
90 90
91static struct message *message__list; 91static struct message *message__list;
92 92
93static struct message *message__new(const char *msg, char *option, char *file, int lineno) 93static struct message *message__new(const char *msg, char *option,
94 const char *file, int lineno)
94{ 95{
95 struct message *self = malloc(sizeof(*self)); 96 struct message *self = malloc(sizeof(*self));
96 97
@@ -130,7 +131,8 @@ static struct message *mesage__find(const char *msg)
130 return m; 131 return m;
131} 132}
132 133
133static int message__add_file_line(struct message *self, char *file, int lineno) 134static int message__add_file_line(struct message *self, const char *file,
135 int lineno)
134{ 136{
135 int rc = -1; 137 int rc = -1;
136 struct file_line *fl = file_line__new(file, lineno); 138 struct file_line *fl = file_line__new(file, lineno);
@@ -145,7 +147,8 @@ out:
145 return rc; 147 return rc;
146} 148}
147 149
148static int message__add(const char *msg, char *option, char *file, int lineno) 150static int message__add(const char *msg, char *option, const char *file,
151 int lineno)
149{ 152{
150 int rc = 0; 153 int rc = 0;
151 char bf[16384]; 154 char bf[16384];
@@ -166,7 +169,7 @@ static int message__add(const char *msg, char *option, char *file, int lineno)
166 return rc; 169 return rc;
167} 170}
168 171
169void menu_build_message_list(struct menu *menu) 172static void menu_build_message_list(struct menu *menu)
170{ 173{
171 struct menu *child; 174 struct menu *child;
172 175
@@ -211,7 +214,7 @@ static void message__print_gettext_msgid_msgstr(struct message *self)
211 "msgstr \"\"\n", self->msg); 214 "msgstr \"\"\n", self->msg);
212} 215}
213 216
214void menu__xgettext(void) 217static void menu__xgettext(void)
215{ 218{
216 struct message *m = message__list; 219 struct message *m = message__list;
217 220
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index dc3e81807d13..6eb039718259 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -160,7 +160,15 @@ typedef unsigned int flex_uint32_t;
160 160
161/* Size of default input buffer. */ 161/* Size of default input buffer. */
162#ifndef YY_BUF_SIZE 162#ifndef YY_BUF_SIZE
163#ifdef __ia64__
164/* On IA-64, the buffer size is 16k, not 8k.
165 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
166 * Ditto for the __ia64__ case accordingly.
167 */
168#define YY_BUF_SIZE 32768
169#else
163#define YY_BUF_SIZE 16384 170#define YY_BUF_SIZE 16384
171#endif /* __ia64__ */
164#endif 172#endif
165 173
166/* The state buf must be large enough to hold one state per character in the main buffer. 174/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -802,7 +810,7 @@ static int last_ts, first_ts;
802static void zconf_endhelp(void); 810static void zconf_endhelp(void);
803static void zconf_endfile(void); 811static void zconf_endfile(void);
804 812
805void new_string(void) 813static void new_string(void)
806{ 814{
807 text = malloc(START_STRSIZE); 815 text = malloc(START_STRSIZE);
808 text_asize = START_STRSIZE; 816 text_asize = START_STRSIZE;
@@ -810,7 +818,7 @@ void new_string(void)
810 *text = 0; 818 *text = 0;
811} 819}
812 820
813void append_string(const char *str, int size) 821static void append_string(const char *str, int size)
814{ 822{
815 int new_size = text_size + size + 1; 823 int new_size = text_size + size + 1;
816 if (new_size > text_asize) { 824 if (new_size > text_asize) {
@@ -824,7 +832,7 @@ void append_string(const char *str, int size)
824 text[text_size] = 0; 832 text[text_size] = 0;
825} 833}
826 834
827void alloc_string(const char *str, int size) 835static void alloc_string(const char *str, int size)
828{ 836{
829 text = malloc(size + 1); 837 text = malloc(size + 1);
830 memcpy(text, str, size); 838 memcpy(text, str, size);
@@ -914,7 +922,12 @@ static int input (void );
914 922
915/* Amount of stuff to slurp up with each read. */ 923/* Amount of stuff to slurp up with each read. */
916#ifndef YY_READ_BUF_SIZE 924#ifndef YY_READ_BUF_SIZE
925#ifdef __ia64__
926/* On IA-64, the buffer size is 16k, not 8k */
927#define YY_READ_BUF_SIZE 16384
928#else
917#define YY_READ_BUF_SIZE 8192 929#define YY_READ_BUF_SIZE 8192
930#endif /* __ia64__ */
918#endif 931#endif
919 932
920/* Copy whatever the last rule matched to the standard output. */ 933/* Copy whatever the last rule matched to the standard output. */
@@ -922,7 +935,7 @@ static int input (void );
922/* This used to be an fputs(), but since the string might contain NUL's, 935/* This used to be an fputs(), but since the string might contain NUL's,
923 * we now use fwrite(). 936 * we now use fwrite().
924 */ 937 */
925#define ECHO fwrite( zconftext, zconfleng, 1, zconfout ) 938#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0)
926#endif 939#endif
927 940
928/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 941/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -2060,8 +2073,8 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
2060 2073
2061/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will 2074/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
2062 * scan from a @e copy of @a bytes. 2075 * scan from a @e copy of @a bytes.
2063 * @param bytes the byte buffer to scan 2076 * @param yybytes the byte buffer to scan
2064 * @param len the number of bytes in the buffer pointed to by @a bytes. 2077 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
2065 * 2078 *
2066 * @return the newly allocated buffer state object. 2079 * @return the newly allocated buffer state object.
2067 */ 2080 */
@@ -2360,9 +2373,10 @@ void zconf_nextfile(const char *name)
2360 memset(buf, 0, sizeof(*buf)); 2373 memset(buf, 0, sizeof(*buf));
2361 2374
2362 current_buf->state = YY_CURRENT_BUFFER; 2375 current_buf->state = YY_CURRENT_BUFFER;
2363 zconfin = zconf_fopen(name); 2376 zconfin = zconf_fopen(file->name);
2364 if (!zconfin) { 2377 if (!zconfin) {
2365 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); 2378 printf("%s:%d: can't open file \"%s\"\n",
2379 zconf_curname(), zconf_lineno(), file->name);
2366 exit(1); 2380 exit(1);
2367 } 2381 }
2368 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE)); 2382 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
@@ -2409,7 +2423,7 @@ int zconf_lineno(void)
2409 return current_pos.lineno; 2423 return current_pos.lineno;
2410} 2424}
2411 2425
2412char *zconf_curname(void) 2426const char *zconf_curname(void)
2413{ 2427{
2414 return current_pos.file ? current_pos.file->name : "<none>"; 2428 return current_pos.file ? current_pos.file->name : "<none>";
2415} 2429}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index f379b0bf8c9e..febf0c94d558 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -14,6 +14,7 @@
14static inline const char *gettext(const char *txt) { return txt; } 14static inline const char *gettext(const char *txt) { return txt; }
15static inline void textdomain(const char *domainname) {} 15static inline void textdomain(const char *domainname) {}
16static inline void bindtextdomain(const char *name, const char *dir) {} 16static inline void bindtextdomain(const char *name, const char *dir) {}
17static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
17#endif 18#endif
18 19
19#ifdef __cplusplus 20#ifdef __cplusplus
@@ -31,12 +32,18 @@ extern "C" {
31 32
32#define SRCTREE "srctree" 33#define SRCTREE "srctree"
33 34
35#ifndef PACKAGE
34#define PACKAGE "linux" 36#define PACKAGE "linux"
37#endif
38
35#define LOCALEDIR "/usr/share/locale" 39#define LOCALEDIR "/usr/share/locale"
36 40
37#define _(text) gettext(text) 41#define _(text) gettext(text)
38#define N_(text) (text) 42#define N_(text) (text)
39 43
44#ifndef CONFIG_
45#define CONFIG_ "CONFIG_"
46#endif
40 47
41#define TF_COMMAND 0x0001 48#define TF_COMMAND 0x0001
42#define TF_PARAM 0x0002 49#define TF_PARAM 0x0002
@@ -61,16 +68,21 @@ struct kconf_id {
61 enum symbol_type stype; 68 enum symbol_type stype;
62}; 69};
63 70
71#ifdef YYDEBUG
72extern int zconfdebug;
73#endif
74
64int zconfparse(void); 75int zconfparse(void);
65void zconfdump(FILE *out); 76void zconfdump(FILE *out);
66
67extern int zconfdebug;
68void zconf_starthelp(void); 77void zconf_starthelp(void);
69FILE *zconf_fopen(const char *name); 78FILE *zconf_fopen(const char *name);
70void zconf_initscan(const char *name); 79void zconf_initscan(const char *name);
71void zconf_nextfile(const char *name); 80void zconf_nextfile(const char *name);
72int zconf_lineno(void); 81int zconf_lineno(void);
73char *zconf_curname(void); 82const char *zconf_curname(void);
83
84/* conf.c */
85void xfgets(char *str, int size, FILE *in);
74 86
75/* confdata.c */ 87/* confdata.c */
76const char *conf_get_configname(void); 88const char *conf_get_configname(void);
@@ -80,17 +92,25 @@ void sym_set_change_count(int count);
80void sym_add_change_count(int count); 92void sym_add_change_count(int count);
81void conf_set_all_new_symbols(enum conf_def_mode mode); 93void conf_set_all_new_symbols(enum conf_def_mode mode);
82 94
95/* confdata.c and expr.c */
96static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
97{
98 if (fwrite(str, len, count, out) < count)
99 fprintf(stderr, "\nError in writing or end of file.\n");
100}
101
83/* kconfig_load.c */ 102/* kconfig_load.c */
84void kconfig_load(void); 103void kconfig_load(void);
85 104
86/* menu.c */ 105/* menu.c */
87void menu_init(void); 106void _menu_init(void);
88void menu_warn(struct menu *menu, const char *fmt, ...); 107void menu_warn(struct menu *menu, const char *fmt, ...);
89struct menu *menu_add_menu(void); 108struct menu *menu_add_menu(void);
90void menu_end_menu(void); 109void menu_end_menu(void);
91void menu_add_entry(struct symbol *sym); 110void menu_add_entry(struct symbol *sym);
92void menu_end_entry(void); 111void menu_end_entry(void);
93void menu_add_dep(struct expr *dep); 112void menu_add_dep(struct expr *dep);
113void menu_add_visibility(struct expr *dep);
94struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); 114struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
95struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); 115struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
96void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); 116void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
@@ -106,6 +126,11 @@ int file_write_dep(const char *name);
106struct gstr { 126struct gstr {
107 size_t len; 127 size_t len;
108 char *s; 128 char *s;
129 /*
130 * when max_width is not zero long lines in string s (if any) get
131 * wrapped not to exceed the max_width value
132 */
133 int max_width;
109}; 134};
110struct gstr str_new(void); 135struct gstr str_new(void);
111struct gstr str_assign(const char *s); 136struct gstr str_assign(const char *s);
@@ -121,6 +146,8 @@ void sym_init(void);
121void sym_clear_all_valid(void); 146void sym_clear_all_valid(void);
122void sym_set_all_changed(void); 147void sym_set_all_changed(void);
123void sym_set_changed(struct symbol *sym); 148void sym_set_changed(struct symbol *sym);
149struct symbol *sym_choice_default(struct symbol *sym);
150const char *sym_get_string_default(struct symbol *sym);
124struct symbol *sym_check_deps(struct symbol *sym); 151struct symbol *sym_check_deps(struct symbol *sym);
125struct property *prop_alloc(enum prop_type type, struct symbol *sym); 152struct property *prop_alloc(enum prop_type type, struct symbol *sym);
126struct symbol *prop_get_symbol(struct property *prop); 153struct symbol *prop_get_symbol(struct property *prop);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 8e69461313d1..17342fef38b9 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,28 +1,36 @@
1#include <stdarg.h>
1 2
2/* confdata.c */ 3/* confdata.c */
3P(conf_parse,void,(const char *name)); 4P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name)); 5P(conf_read,int,(const char *name));
5P(conf_read_simple,int,(const char *name, int)); 6P(conf_read_simple,int,(const char *name, int));
7P(conf_write_defconfig,int,(const char *name));
6P(conf_write,int,(const char *name)); 8P(conf_write,int,(const char *name));
7P(conf_write_autoconf,int,(void)); 9P(conf_write_autoconf,int,(void));
8P(conf_get_changed,bool,(void)); 10P(conf_get_changed,bool,(void));
9P(conf_set_changed_callback, void,(void (*fn)(void))); 11P(conf_set_changed_callback, void,(void (*fn)(void)));
12P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap)));
10 13
11/* menu.c */ 14/* menu.c */
12P(rootmenu,struct menu,); 15P(rootmenu,struct menu,);
13 16
14P(menu_is_visible,bool,(struct menu *menu)); 17P(menu_is_visible, bool, (struct menu *menu));
18P(menu_has_prompt, bool, (struct menu *menu));
15P(menu_get_prompt,const char *,(struct menu *menu)); 19P(menu_get_prompt,const char *,(struct menu *menu));
16P(menu_get_root_menu,struct menu *,(struct menu *menu)); 20P(menu_get_root_menu,struct menu *,(struct menu *menu));
17P(menu_get_parent_menu,struct menu *,(struct menu *menu)); 21P(menu_get_parent_menu,struct menu *,(struct menu *menu));
18P(menu_has_help,bool,(struct menu *menu)); 22P(menu_has_help,bool,(struct menu *menu));
19P(menu_get_help,const char *,(struct menu *menu)); 23P(menu_get_help,const char *,(struct menu *menu));
24P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
25P(get_relations_str, struct gstr, (struct symbol **sym_arr));
26P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
20 27
21/* symbol.c */ 28/* symbol.c */
22P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); 29P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
23 30
24P(sym_lookup,struct symbol *,(const char *name, int flags)); 31P(sym_lookup,struct symbol *,(const char *name, int flags));
25P(sym_find,struct symbol *,(const char *name)); 32P(sym_find,struct symbol *,(const char *name));
33P(sym_expand_string_value,const char *,(const char *in));
26P(sym_re_search,struct symbol **,(const char *pattern)); 34P(sym_re_search,struct symbol **,(const char *pattern));
27P(sym_type_name,const char *,(enum symbol_type type)); 35P(sym_type_name,const char *,(enum symbol_type type));
28P(sym_calc_value,void,(struct symbol *sym)); 36P(sym_calc_value,void,(struct symbol *sym));
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index fcef0f59d553..82cc3a85e7f8 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -23,6 +23,8 @@ ccflags()
23 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' 23 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
24 elif [ -f /usr/include/ncurses/curses.h ]; then 24 elif [ -f /usr/include/ncurses/curses.h ]; then
25 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' 25 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
26 elif [ -f /usr/include/ncursesw/curses.h ]; then
27 echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"'
26 elif [ -f /usr/include/ncurses.h ]; then 28 elif [ -f /usr/include/ncurses.h ]; then
27 echo '-DCURSES_LOC="<ncurses.h>"' 29 echo '-DCURSES_LOC="<ncurses.h>"'
28 else 30 else
diff --git a/scripts/kconfig/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/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index 86d95cca46a7..f2375ad7ebc9 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -19,6 +19,8 @@
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22#include <stdarg.h>
23
22#include "dialog.h" 24#include "dialog.h"
23 25
24struct dialog_info dlg; 26struct dialog_info dlg;
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 3bcacb4bfd3a..d433c7a24745 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -25,11 +25,9 @@
25static const char mconf_readme[] = N_( 25static const char mconf_readme[] = N_(
26"Overview\n" 26"Overview\n"
27"--------\n" 27"--------\n"
28"Some kernel features may be built directly into the kernel.\n" 28"This interface let you select features and parameters for the build.\n"
29"Some may be made into loadable runtime modules. Some features\n" 29"Features can either be built-in, modularized, or ignored. Parameters\n"
30"may be completely removed altogether. There are also certain\n" 30"must be entered in as decimal or hexadecimal numbers or text.\n"
31"kernel parameters which are not really features, but must be\n"
32"entered in as decimal or hexadecimal numbers or possibly text.\n"
33"\n" 31"\n"
34"Menu items beginning with following braces represent features that\n" 32"Menu items beginning with following braces represent features that\n"
35" [ ] can be built in or removed\n" 33" [ ] can be built in or removed\n"
@@ -67,13 +65,15 @@ static const char mconf_readme[] = N_(
67" there is a delayed response which you may find annoying.\n" 65" there is a delayed response which you may find annoying.\n"
68"\n" 66"\n"
69" Also, the <TAB> and cursor keys will cycle between <Select>,\n" 67" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
70" <Exit> and <Help>\n" 68" <Exit> and <Help>.\n"
71"\n" 69"\n"
72"o To get help with an item, use the cursor keys to highlight <Help>\n" 70"o To get help with an item, use the cursor keys to highlight <Help>\n"
73" and Press <ENTER>.\n" 71" and press <ENTER>.\n"
74"\n" 72"\n"
75" Shortcut: Press <H> or <?>.\n" 73" Shortcut: Press <H> or <?>.\n"
76"\n" 74"\n"
75"o To toggle the display of hidden options, press <Z>.\n"
76"\n"
77"\n" 77"\n"
78"Radiolists (Choice lists)\n" 78"Radiolists (Choice lists)\n"
79"-----------\n" 79"-----------\n"
@@ -115,7 +115,7 @@ static const char mconf_readme[] = N_(
115"-----------------------------\n" 115"-----------------------------\n"
116"Menuconfig supports the use of alternate configuration files for\n" 116"Menuconfig supports the use of alternate configuration files for\n"
117"those who, for various reasons, find it necessary to switch\n" 117"those who, for various reasons, find it necessary to switch\n"
118"between different kernel configurations.\n" 118"between different configurations.\n"
119"\n" 119"\n"
120"At the end of the main menu you will find two options. One is\n" 120"At the end of the main menu you will find two options. One is\n"
121"for saving the current configuration to a file of your choosing.\n" 121"for saving the current configuration to a file of your choosing.\n"
@@ -148,9 +148,9 @@ static const char mconf_readme[] = N_(
148"\n" 148"\n"
149"Optional personality available\n" 149"Optional personality available\n"
150"------------------------------\n" 150"------------------------------\n"
151"If you prefer to have all of the kernel options listed in a single\n" 151"If you prefer to have all of the options listed in a single menu, rather\n"
152"menu, rather than the default multimenu hierarchy, run the menuconfig\n" 152"than the default multimenu hierarchy, run the menuconfig with\n"
153"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" 153"MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
154"\n" 154"\n"
155"make MENUCONFIG_MODE=single_menu menuconfig\n" 155"make MENUCONFIG_MODE=single_menu menuconfig\n"
156"\n" 156"\n"
@@ -199,30 +199,28 @@ inputbox_instructions_string[] = N_(
199setmod_text[] = N_( 199setmod_text[] = N_(
200 "This feature depends on another which has been configured as a module.\n" 200 "This feature depends on another which has been configured as a module.\n"
201 "As a result, this feature will be built as a module."), 201 "As a result, this feature will be built as a module."),
202nohelp_text[] = N_(
203 "There is no help available for this kernel option.\n"),
204load_config_text[] = N_( 202load_config_text[] = N_(
205 "Enter the name of the configuration file you wish to load. " 203 "Enter the name of the configuration file you wish to load. "
206 "Accept the name shown to restore the configuration you " 204 "Accept the name shown to restore the configuration you "
207 "last retrieved. Leave blank to abort."), 205 "last retrieved. Leave blank to abort."),
208load_config_help[] = N_( 206load_config_help[] = N_(
209 "\n" 207 "\n"
210 "For various reasons, one may wish to keep several different kernel\n" 208 "For various reasons, one may wish to keep several different\n"
211 "configurations available on a single machine.\n" 209 "configurations available on a single machine.\n"
212 "\n" 210 "\n"
213 "If you have saved a previous configuration in a file other than the\n" 211 "If you have saved a previous configuration in a file other than the\n"
214 "kernel's default, entering the name of the file here will allow you\n" 212 "default one, entering its name here will allow you to modify that\n"
215 "to modify that configuration.\n" 213 "configuration.\n"
216 "\n" 214 "\n"
217 "If you are uncertain, then you have probably never used alternate\n" 215 "If you are uncertain, then you have probably never used alternate\n"
218 "configuration files. You should therefor leave this blank to abort.\n"), 216 "configuration files. You should therefore leave this blank to abort.\n"),
219save_config_text[] = N_( 217save_config_text[] = N_(
220 "Enter a filename to which this configuration should be saved " 218 "Enter a filename to which this configuration should be saved "
221 "as an alternate. Leave blank to abort."), 219 "as an alternate. Leave blank to abort."),
222save_config_help[] = N_( 220save_config_help[] = N_(
223 "\n" 221 "\n"
224 "For various reasons, one may wish to keep different kernel\n" 222 "For various reasons, one may wish to keep different configurations\n"
225 "configurations available on a single machine.\n" 223 "available on a single machine.\n"
226 "\n" 224 "\n"
227 "Entering a file name here will allow you to later retrieve, modify\n" 225 "Entering a file name here will allow you to later retrieve, modify\n"
228 "and use the current configuration as an alternate to whatever\n" 226 "and use the current configuration as an alternate to whatever\n"
@@ -232,7 +230,7 @@ save_config_help[] = N_(
232 "leave this blank.\n"), 230 "leave this blank.\n"),
233search_help[] = N_( 231search_help[] = N_(
234 "\n" 232 "\n"
235 "Search for CONFIG_ symbols and display their relations.\n" 233 "Search for symbols and display their relations.\n"
236 "Regular expressions are allowed.\n" 234 "Regular expressions are allowed.\n"
237 "Example: search for \"^FOO\"\n" 235 "Example: search for \"^FOO\"\n"
238 "Result:\n" 236 "Result:\n"
@@ -249,7 +247,7 @@ search_help[] = N_(
249 "Selected by: BAR\n" 247 "Selected by: BAR\n"
250 "-----------------------------------------------------------------\n" 248 "-----------------------------------------------------------------\n"
251 "o The line 'Prompt:' shows the text used in the menu structure for\n" 249 "o The line 'Prompt:' shows the text used in the menu structure for\n"
252 " this CONFIG_ symbol\n" 250 " this symbol\n"
253 "o The 'Defined at' line tell at what file / line number the symbol\n" 251 "o The 'Defined at' line tell at what file / line number the symbol\n"
254 " is defined\n" 252 " is defined\n"
255 "o The 'Depends on:' line tell what symbols needs to be defined for\n" 253 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
@@ -265,15 +263,16 @@ search_help[] = N_(
265 "Only relevant lines are shown.\n" 263 "Only relevant lines are shown.\n"
266 "\n\n" 264 "\n\n"
267 "Search examples:\n" 265 "Search examples:\n"
268 "Examples: USB => find all CONFIG_ symbols containing USB\n" 266 "Examples: USB => find all symbols containing USB\n"
269 " ^USB => find all CONFIG_ symbols starting with USB\n" 267 " ^USB => find all symbols starting with USB\n"
270 " USB$ => find all CONFIG_ symbols ending with USB\n" 268 " USB$ => find all symbols ending with USB\n"
271 "\n"); 269 "\n");
272 270
273static int indent; 271static int indent;
274static struct menu *current_menu; 272static struct menu *current_menu;
275static int child_count; 273static int child_count;
276static int single_menu_mode; 274static int single_menu_mode;
275static int show_all_options;
277 276
278static void conf(struct menu *menu); 277static void conf(struct menu *menu);
279static void conf_choice(struct menu *menu); 278static void conf_choice(struct menu *menu);
@@ -284,91 +283,14 @@ static void show_textbox(const char *title, const char *text, int r, int c);
284static void show_helptext(const char *title, const char *text); 283static void show_helptext(const char *title, const char *text);
285static void show_help(struct menu *menu); 284static void show_help(struct menu *menu);
286 285
287static void get_prompt_str(struct gstr *r, struct property *prop)
288{
289 int i, j;
290 struct menu *submenu[8], *menu;
291
292 str_printf(r, _("Prompt: %s\n"), _(prop->text));
293 str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
294 prop->menu->lineno);
295 if (!expr_is_yes(prop->visible.expr)) {
296 str_append(r, _(" Depends on: "));
297 expr_gstr_print(prop->visible.expr, r);
298 str_append(r, "\n");
299 }
300 menu = prop->menu->parent;
301 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
302 submenu[i++] = menu;
303 if (i > 0) {
304 str_printf(r, _(" Location:\n"));
305 for (j = 4; --i >= 0; j += 2) {
306 menu = submenu[i];
307 str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
308 if (menu->sym) {
309 str_printf(r, " (%s [=%s])", menu->sym->name ?
310 menu->sym->name : _("<choice>"),
311 sym_get_string_value(menu->sym));
312 }
313 str_append(r, "\n");
314 }
315 }
316}
317
318static void get_symbol_str(struct gstr *r, struct symbol *sym)
319{
320 bool hit;
321 struct property *prop;
322
323 if (sym && sym->name)
324 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
325 sym_get_string_value(sym));
326 for_all_prompts(sym, prop)
327 get_prompt_str(r, prop);
328 hit = false;
329 for_all_properties(sym, prop, P_SELECT) {
330 if (!hit) {
331 str_append(r, " Selects: ");
332 hit = true;
333 } else
334 str_printf(r, " && ");
335 expr_gstr_print(prop->expr, r);
336 }
337 if (hit)
338 str_append(r, "\n");
339 if (sym->rev_dep.expr) {
340 str_append(r, _(" Selected by: "));
341 expr_gstr_print(sym->rev_dep.expr, r);
342 str_append(r, "\n");
343 }
344 str_append(r, "\n\n");
345}
346
347static struct gstr get_relations_str(struct symbol **sym_arr)
348{
349 struct symbol *sym;
350 struct gstr res = str_new();
351 int i;
352
353 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
354 get_symbol_str(&res, sym);
355 if (!i)
356 str_append(&res, _("No matches found.\n"));
357 return res;
358}
359
360static char filename[PATH_MAX+1]; 286static char filename[PATH_MAX+1];
361static void set_config_filename(const char *config_filename) 287static void set_config_filename(const char *config_filename)
362{ 288{
363 static char menu_backtitle[PATH_MAX+128]; 289 static char menu_backtitle[PATH_MAX+128];
364 int size; 290 int size;
365 struct symbol *sym;
366 291
367 sym = sym_lookup("KERNELVERSION", 0);
368 sym_calc_value(sym);
369 size = snprintf(menu_backtitle, sizeof(menu_backtitle), 292 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
370 _("%s - Linux Kernel v%s Configuration"), 293 "%s - %s", config_filename, rootmenu.prompt->text);
371 config_filename, sym_get_string_value(sym));
372 if (size >= sizeof(menu_backtitle)) 294 if (size >= sizeof(menu_backtitle))
373 menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; 295 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
374 set_dialog_backtitle(menu_backtitle); 296 set_dialog_backtitle(menu_backtitle);
@@ -388,8 +310,8 @@ static void search_conf(void)
388again: 310again:
389 dialog_clear(); 311 dialog_clear();
390 dres = dialog_inputbox(_("Search Configuration Parameter"), 312 dres = dialog_inputbox(_("Search Configuration Parameter"),
391 _("Enter CONFIG_ (sub)string to search for " 313 _("Enter " CONFIG_ " (sub)string to search for "
392 "(with or without \"CONFIG\")"), 314 "(with or without \"" CONFIG_ "\")"),
393 10, 75, ""); 315 10, 75, "");
394 switch (dres) { 316 switch (dres) {
395 case 0: 317 case 0:
@@ -401,10 +323,10 @@ again:
401 return; 323 return;
402 } 324 }
403 325
404 /* strip CONFIG_ if necessary */ 326 /* strip the prefix if necessary */
405 dialog_input = dialog_input_result; 327 dialog_input = dialog_input_result;
406 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) 328 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
407 dialog_input += 7; 329 dialog_input += strlen(CONFIG_);
408 330
409 sym_arr = sym_re_search(dialog_input); 331 sym_arr = sym_re_search(dialog_input);
410 res = get_relations_str(sym_arr); 332 res = get_relations_str(sym_arr);
@@ -421,8 +343,16 @@ static void build_conf(struct menu *menu)
421 int type, tmp, doint = 2; 343 int type, tmp, doint = 2;
422 tristate val; 344 tristate val;
423 char ch; 345 char ch;
424 346 bool visible;
425 if (!menu_is_visible(menu)) 347
348 /*
349 * note: menu_is_visible() has side effect that it will
350 * recalc the value of the symbol.
351 */
352 visible = menu_is_visible(menu);
353 if (show_all_options && !menu_has_prompt(menu))
354 return;
355 else if (!show_all_options && !visible)
426 return; 356 return;
427 357
428 sym = menu->sym; 358 sym = menu->sym;
@@ -681,6 +611,9 @@ static void conf(struct menu *menu)
681 case 7: 611 case 7:
682 search_conf(); 612 search_conf();
683 break; 613 break;
614 case 8:
615 show_all_options = !show_all_options;
616 break;
684 } 617 }
685 } 618 }
686} 619}
@@ -699,19 +632,10 @@ static void show_helptext(const char *title, const char *text)
699static void show_help(struct menu *menu) 632static void show_help(struct menu *menu)
700{ 633{
701 struct gstr help = str_new(); 634 struct gstr help = str_new();
702 struct symbol *sym = menu->sym; 635
703 636 help.max_width = getmaxx(stdscr) - 10;
704 if (menu_has_help(menu)) 637 menu_get_ext_help(menu, &help);
705 { 638
706 if (sym->name) {
707 str_printf(&help, "CONFIG_%s:\n\n", sym->name);
708 str_append(&help, _(menu_get_help(menu)));
709 str_append(&help, "\n");
710 }
711 } else {
712 str_append(&help, nohelp_text);
713 }
714 get_symbol_str(&help, sym);
715 show_helptext(_(menu_get_prompt(menu)), str_get(&help)); 639 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
716 str_free(&help); 640 str_free(&help);
717} 641}
@@ -888,6 +812,8 @@ int main(int ac, char **av)
888 single_menu_mode = 1; 812 single_menu_mode = 1;
889 } 813 }
890 814
815 initscr();
816
891 getyx(stdscr, saved_y, saved_x); 817 getyx(stdscr, saved_y, saved_x);
892 if (init_dialog(NULL)) { 818 if (init_dialog(NULL)) {
893 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); 819 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
@@ -902,7 +828,7 @@ int main(int ac, char **av)
902 if (conf_get_changed()) 828 if (conf_get_changed())
903 res = dialog_yesno(NULL, 829 res = dialog_yesno(NULL,
904 _("Do you wish to save your " 830 _("Do you wish to save your "
905 "new kernel configuration?\n" 831 "new configuration?\n"
906 "<ESC><ESC> to continue."), 832 "<ESC><ESC> to continue."),
907 6, 60); 833 6, 60);
908 else 834 else
@@ -914,20 +840,20 @@ int main(int ac, char **av)
914 case 0: 840 case 0:
915 if (conf_write(filename)) { 841 if (conf_write(filename)) {
916 fprintf(stderr, _("\n\n" 842 fprintf(stderr, _("\n\n"
917 "Error during writing of the kernel configuration.\n" 843 "Error while writing of the configuration.\n"
918 "Your kernel configuration changes were NOT saved." 844 "Your configuration changes were NOT saved."
919 "\n\n")); 845 "\n\n"));
920 return 1; 846 return 1;
921 } 847 }
922 case -1: 848 case -1:
923 printf(_("\n\n" 849 printf(_("\n\n"
924 "*** End of Linux kernel configuration.\n" 850 "*** End of the configuration.\n"
925 "*** Execute 'make' to build the kernel or try 'make help'." 851 "*** Execute 'make' to start the build or try 'make help'."
926 "\n\n")); 852 "\n\n"));
927 break; 853 break;
928 default: 854 default:
929 fprintf(stderr, _("\n\n" 855 fprintf(stderr, _("\n\n"
930 "Your kernel configuration changes were NOT saved." 856 "Your configuration changes were NOT saved."
931 "\n\n")); 857 "\n\n"));
932 } 858 }
933 859
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 07ff8d105c9d..5fdf10dc1d8a 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -9,6 +9,9 @@
9#define LKC_DIRECT_LINK 9#define LKC_DIRECT_LINK
10#include "lkc.h" 10#include "lkc.h"
11 11
12static const char nohelp_text[] = N_(
13 "There is no help available for this option.\n");
14
12struct menu rootmenu; 15struct menu rootmenu;
13static struct menu **last_entry_ptr; 16static struct menu **last_entry_ptr;
14 17
@@ -35,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
35 va_end(ap); 38 va_end(ap);
36} 39}
37 40
38void menu_init(void) 41void _menu_init(void)
39{ 42{
40 current_entry = current_menu = &rootmenu; 43 current_entry = current_menu = &rootmenu;
41 last_entry_ptr = &rootmenu.list; 44 last_entry_ptr = &rootmenu.list;
@@ -55,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
55 *last_entry_ptr = menu; 58 *last_entry_ptr = menu;
56 last_entry_ptr = &menu->next; 59 last_entry_ptr = &menu->next;
57 current_entry = menu; 60 current_entry = menu;
61 if (sym)
62 menu_add_symbol(P_SYMBOL, sym, NULL);
58} 63}
59 64
60void menu_end_entry(void) 65void menu_end_entry(void)
@@ -74,7 +79,7 @@ void menu_end_menu(void)
74 current_menu = current_menu->parent; 79 current_menu = current_menu->parent;
75} 80}
76 81
77struct expr *menu_check_dep(struct expr *e) 82static struct expr *menu_check_dep(struct expr *e)
78{ 83{
79 if (!e) 84 if (!e)
80 return e; 85 return e;
@@ -133,8 +138,22 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
133 while (isspace(*prompt)) 138 while (isspace(*prompt))
134 prompt++; 139 prompt++;
135 } 140 }
136 if (current_entry->prompt) 141 if (current_entry->prompt && current_entry != &rootmenu)
137 prop_warn(prop, "prompt redefined"); 142 prop_warn(prop, "prompt redefined");
143
144 /* Apply all upper menus' visibilities to actual prompts. */
145 if(type == P_PROMPT) {
146 struct menu *menu = current_entry;
147
148 while ((menu = menu->parent) != NULL) {
149 if (!menu->visibility)
150 continue;
151 prop->visible.expr
152 = expr_alloc_and(prop->visible.expr,
153 menu->visibility);
154 }
155 }
156
138 current_entry->prompt = prop; 157 current_entry->prompt = prop;
139 } 158 }
140 prop->text = prompt; 159 prop->text = prompt;
@@ -147,6 +166,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
147 return menu_add_prop(type, prompt, NULL, dep); 166 return menu_add_prop(type, prompt, NULL, dep);
148} 167}
149 168
169void menu_add_visibility(struct expr *expr)
170{
171 current_entry->visibility = expr_alloc_and(current_entry->visibility,
172 expr);
173}
174
150void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) 175void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
151{ 176{
152 menu_add_prop(type, NULL, expr, dep); 177 menu_add_prop(type, NULL, expr, dep);
@@ -178,13 +203,13 @@ void menu_add_option(int token, char *arg)
178 } 203 }
179} 204}
180 205
181static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) 206static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
182{ 207{
183 return sym2->type == S_INT || sym2->type == S_HEX || 208 return sym2->type == S_INT || sym2->type == S_HEX ||
184 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); 209 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
185} 210}
186 211
187void sym_check_prop(struct symbol *sym) 212static void sym_check_prop(struct symbol *sym)
188{ 213{
189 struct property *prop; 214 struct property *prop;
190 struct symbol *sym2; 215 struct symbol *sym2;
@@ -194,8 +219,17 @@ void sym_check_prop(struct symbol *sym)
194 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && 219 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
195 prop->expr->type != E_SYMBOL) 220 prop->expr->type != E_SYMBOL)
196 prop_warn(prop, 221 prop_warn(prop,
197 "default for config symbol '%'" 222 "default for config symbol '%s'"
198 " must be a single symbol", sym->name); 223 " must be a single symbol", sym->name);
224 if (prop->expr->type != E_SYMBOL)
225 break;
226 sym2 = prop_get_symbol(prop);
227 if (sym->type == S_HEX || sym->type == S_INT) {
228 if (!menu_validate_number(sym, sym2))
229 prop_warn(prop,
230 "'%s': number is invalid",
231 sym->name);
232 }
199 break; 233 break;
200 case P_SELECT: 234 case P_SELECT:
201 sym2 = prop_get_symbol(prop); 235 sym2 = prop_get_symbol(prop);
@@ -215,8 +249,8 @@ void sym_check_prop(struct symbol *sym)
215 if (sym->type != S_INT && sym->type != S_HEX) 249 if (sym->type != S_INT && sym->type != S_HEX)
216 prop_warn(prop, "range is only allowed " 250 prop_warn(prop, "range is only allowed "
217 "for int or hex symbols"); 251 "for int or hex symbols");
218 if (!menu_range_valid_sym(sym, prop->expr->left.sym) || 252 if (!menu_validate_number(sym, prop->expr->left.sym) ||
219 !menu_range_valid_sym(sym, prop->expr->right.sym)) 253 !menu_validate_number(sym, prop->expr->right.sym))
220 prop_warn(prop, "range is invalid"); 254 prop_warn(prop, "range is invalid");
221 break; 255 break;
222 default: 256 default:
@@ -315,6 +349,8 @@ void menu_finalize(struct menu *parent)
315 parent->next = last_menu->next; 349 parent->next = last_menu->next;
316 last_menu->next = NULL; 350 last_menu->next = NULL;
317 } 351 }
352
353 sym->dir_dep.expr = parent->dep;
318 } 354 }
319 for (menu = parent->list; menu; menu = menu->next) { 355 for (menu = parent->list; menu; menu = menu->next) {
320 if (sym && sym_is_choice(sym) && 356 if (sym && sym_is_choice(sym) &&
@@ -387,6 +423,13 @@ void menu_finalize(struct menu *parent)
387 } 423 }
388} 424}
389 425
426bool menu_has_prompt(struct menu *menu)
427{
428 if (!menu->prompt)
429 return false;
430 return true;
431}
432
390bool menu_is_visible(struct menu *menu) 433bool menu_is_visible(struct menu *menu)
391{ 434{
392 struct menu *child; 435 struct menu *child;
@@ -395,6 +438,12 @@ bool menu_is_visible(struct menu *menu)
395 438
396 if (!menu->prompt) 439 if (!menu->prompt)
397 return false; 440 return false;
441
442 if (menu->visibility) {
443 if (expr_calc_value(menu->visibility) == no)
444 return no;
445 }
446
398 sym = menu->sym; 447 sym = menu->sym;
399 if (sym) { 448 if (sym) {
400 sym_calc_value(sym); 449 sym_calc_value(sym);
@@ -404,12 +453,18 @@ bool menu_is_visible(struct menu *menu)
404 453
405 if (visible != no) 454 if (visible != no)
406 return true; 455 return true;
456
407 if (!sym || sym_get_tristate_value(menu->sym) == no) 457 if (!sym || sym_get_tristate_value(menu->sym) == no)
408 return false; 458 return false;
409 459
410 for (child = menu->list; child; child = child->next) 460 for (child = menu->list; child; child = child->next) {
411 if (menu_is_visible(child)) 461 if (menu_is_visible(child)) {
462 if (sym)
463 sym->flags |= SYMBOL_DEF_USER;
412 return true; 464 return true;
465 }
466 }
467
413 return false; 468 return false;
414} 469}
415 470
@@ -451,3 +506,104 @@ const char *menu_get_help(struct menu *menu)
451 else 506 else
452 return ""; 507 return "";
453} 508}
509
510static void get_prompt_str(struct gstr *r, struct property *prop)
511{
512 int i, j;
513 struct menu *submenu[8], *menu;
514
515 str_printf(r, _("Prompt: %s\n"), _(prop->text));
516 str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
517 prop->menu->lineno);
518 if (!expr_is_yes(prop->visible.expr)) {
519 str_append(r, _(" Depends on: "));
520 expr_gstr_print(prop->visible.expr, r);
521 str_append(r, "\n");
522 }
523 menu = prop->menu->parent;
524 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
525 submenu[i++] = menu;
526 if (i > 0) {
527 str_printf(r, _(" Location:\n"));
528 for (j = 4; --i >= 0; j += 2) {
529 menu = submenu[i];
530 str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
531 if (menu->sym) {
532 str_printf(r, " (%s [=%s])", menu->sym->name ?
533 menu->sym->name : _("<choice>"),
534 sym_get_string_value(menu->sym));
535 }
536 str_append(r, "\n");
537 }
538 }
539}
540
541void get_symbol_str(struct gstr *r, struct symbol *sym)
542{
543 bool hit;
544 struct property *prop;
545
546 if (sym && sym->name) {
547 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
548 sym_get_string_value(sym));
549 str_printf(r, "Type : %s\n", sym_type_name(sym->type));
550 if (sym->type == S_INT || sym->type == S_HEX) {
551 prop = sym_get_range_prop(sym);
552 if (prop) {
553 str_printf(r, "Range : ");
554 expr_gstr_print(prop->expr, r);
555 str_append(r, "\n");
556 }
557 }
558 }
559 for_all_prompts(sym, prop)
560 get_prompt_str(r, prop);
561 hit = false;
562 for_all_properties(sym, prop, P_SELECT) {
563 if (!hit) {
564 str_append(r, " Selects: ");
565 hit = true;
566 } else
567 str_printf(r, " && ");
568 expr_gstr_print(prop->expr, r);
569 }
570 if (hit)
571 str_append(r, "\n");
572 if (sym->rev_dep.expr) {
573 str_append(r, _(" Selected by: "));
574 expr_gstr_print(sym->rev_dep.expr, r);
575 str_append(r, "\n");
576 }
577 str_append(r, "\n\n");
578}
579
580struct gstr get_relations_str(struct symbol **sym_arr)
581{
582 struct symbol *sym;
583 struct gstr res = str_new();
584 int i;
585
586 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
587 get_symbol_str(&res, sym);
588 if (!i)
589 str_append(&res, _("No matches found.\n"));
590 return res;
591}
592
593
594void menu_get_ext_help(struct menu *menu, struct gstr *help)
595{
596 struct symbol *sym = menu->sym;
597
598 if (menu_has_help(menu)) {
599 if (sym->name) {
600 str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
601 str_append(help, _(menu_get_help(menu)));
602 str_append(help, "\n");
603 }
604 } else {
605 str_append(help, nohelp_text);
606 }
607 if (sym)
608 get_symbol_str(help, sym);
609}
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
new file mode 100644
index 000000000000..db56377393d7
--- /dev/null
+++ b/scripts/kconfig/nconf.c
@@ -0,0 +1,1561 @@
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 _GNU_SOURCE
9#include <string.h>
10#define LKC_DIRECT_LINK
11#include "lkc.h"
12#include "nconf.h"
13#include <ctype.h>
14
15static const char nconf_readme[] = N_(
16"Overview\n"
17"--------\n"
18"This interface let you select features and parameters for the build.\n"
19"Features can either be built-in, modularized, or ignored. Parameters\n"
20"must be entered in as decimal or hexadecimal numbers or text.\n"
21"\n"
22"Menu items beginning with following braces represent features that\n"
23" [ ] can be built in or removed\n"
24" < > can be built in, modularized or removed\n"
25" { } can be built in or modularized (selected by other feature)\n"
26" - - are selected by other feature,\n"
27" XXX cannot be selected. Use Symbol Info to find out why,\n"
28"while *, M or whitespace inside braces means to build in, build as\n"
29"a module or to exclude the feature respectively.\n"
30"\n"
31"To change any of these features, highlight it with the cursor\n"
32"keys and press <Y> to build it in, <M> to make it a module or\n"
33"<N> to removed it. You may also press the <Space Bar> to cycle\n"
34"through the available options (ie. Y->N->M->Y).\n"
35"\n"
36"Some additional keyboard hints:\n"
37"\n"
38"Menus\n"
39"----------\n"
40"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
41" you wish to change use <Enter> or <Space>. Goto submenu by \n"
42" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
43" Submenus are designated by \"--->\".\n"
44"\n"
45" Searching: pressing '/' triggers interactive search mode.\n"
46" nconfig performs a case insensitive search for the string\n"
47" in the menu prompts (no regex support).\n"
48" Pressing the up/down keys highlights the previous/next\n"
49" matching item. Backspace removes one character from the\n"
50" match string. Pressing either '/' again or ESC exits\n"
51" search mode. All other keys behave normally.\n"
52"\n"
53" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
54" unseen options into view.\n"
55"\n"
56"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
57"\n"
58"o To get help with an item, press <F1>\n"
59" Shortcut: Press <h> or <?>.\n"
60"\n"
61"\n"
62"Radiolists (Choice lists)\n"
63"-----------\n"
64"o Use the cursor keys to select the option you wish to set and press\n"
65" <S> or the <SPACE BAR>.\n"
66"\n"
67" Shortcut: Press the first letter of the option you wish to set then\n"
68" press <S> or <SPACE BAR>.\n"
69"\n"
70"o To see available help for the item, press <F1>\n"
71" Shortcut: Press <H> or <?>.\n"
72"\n"
73"\n"
74"Data Entry\n"
75"-----------\n"
76"o Enter the requested information and press <ENTER>\n"
77" If you are entering hexadecimal values, it is not necessary to\n"
78" add the '0x' prefix to the entry.\n"
79"\n"
80"o For help, press <F1>.\n"
81"\n"
82"\n"
83"Text Box (Help Window)\n"
84"--------\n"
85"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
86" keys h,j,k,l function here as do <SPACE BAR> for those\n"
87" who are familiar with less and lynx.\n"
88"\n"
89"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
90"\n"
91"\n"
92"Alternate Configuration Files\n"
93"-----------------------------\n"
94"nconfig supports the use of alternate configuration files for\n"
95"those who, for various reasons, find it necessary to switch\n"
96"between different configurations.\n"
97"\n"
98"At the end of the main menu you will find two options. One is\n"
99"for saving the current configuration to a file of your choosing.\n"
100"The other option is for loading a previously saved alternate\n"
101"configuration.\n"
102"\n"
103"Even if you don't use alternate configuration files, but you\n"
104"find during a nconfig session that you have completely messed\n"
105"up your settings, you may use the \"Load Alternate...\" option to\n"
106"restore your previously saved settings from \".config\" without\n"
107"restarting nconfig.\n"
108"\n"
109"Other information\n"
110"-----------------\n"
111"If you use nconfig in an XTERM window make sure you have your\n"
112"$TERM variable set to point to a xterm definition which supports color.\n"
113"Otherwise, nconfig will look rather bad. nconfig will not\n"
114"display correctly in a RXVT window because rxvt displays only one\n"
115"intensity of color, bright.\n"
116"\n"
117"nconfig will display larger menus on screens or xterms which are\n"
118"set to display more than the standard 25 row by 80 column geometry.\n"
119"In order for this to work, the \"stty size\" command must be able to\n"
120"display the screen's current row and column geometry. I STRONGLY\n"
121"RECOMMEND that you make sure you do NOT have the shell variables\n"
122"LINES and COLUMNS exported into your environment. Some distributions\n"
123"export those variables via /etc/profile. Some ncurses programs can\n"
124"become confused when those variables (LINES & COLUMNS) don't reflect\n"
125"the true screen size.\n"
126"\n"
127"Optional personality available\n"
128"------------------------------\n"
129"If you prefer to have all of the options listed in a single menu, rather\n"
130"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
131"environment variable set to single_menu. Example:\n"
132"\n"
133"make NCONFIG_MODE=single_menu nconfig\n"
134"\n"
135"<Enter> will then unroll the appropriate category, or enfold it if it\n"
136"is already unrolled.\n"
137"\n"
138"Note that this mode can eventually be a little more CPU expensive\n"
139"(especially with a larger number of unrolled categories) than the\n"
140"default mode.\n"
141"\n"),
142menu_no_f_instructions[] = N_(
143" You do not have function keys support. Please follow the\n"
144" following instructions:\n"
145" Arrow keys navigate the menu.\n"
146" <Enter> or <right-arrow> selects submenus --->.\n"
147" Capital Letters are hotkeys.\n"
148" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
149" Pressing SpaceBar toggles between the above options.\n"
150" Press <Esc> or <left-arrow> to go back one menu,\n"
151" <?> or <h> for Help, </> for Search.\n"
152" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
153" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
154" <Esc> always leaves the current window.\n"),
155menu_instructions[] = N_(
156" Arrow keys navigate the menu.\n"
157" <Enter> or <right-arrow> selects submenus --->.\n"
158" Capital Letters are hotkeys.\n"
159" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
160" Pressing SpaceBar toggles between the above options\n"
161" Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
162" <?>, <F1> or <h> for Help, </> for Search.\n"
163" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
164" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
165" <Esc> always leaves the current window\n"),
166radiolist_instructions[] = N_(
167" Use the arrow keys to navigate this window or\n"
168" press the hotkey of the item you wish to select\n"
169" followed by the <SPACE BAR>.\n"
170" Press <?>, <F1> or <h> for additional information about this option.\n"),
171inputbox_instructions_int[] = N_(
172"Please enter a decimal value.\n"
173"Fractions will not be accepted.\n"
174"Press <RETURN> to accept, <ESC> to cancel."),
175inputbox_instructions_hex[] = N_(
176"Please enter a hexadecimal value.\n"
177"Press <RETURN> to accept, <ESC> to cancel."),
178inputbox_instructions_string[] = N_(
179"Please enter a string value.\n"
180"Press <RETURN> to accept, <ESC> to cancel."),
181setmod_text[] = N_(
182"This feature depends on another which\n"
183"has been configured as a module.\n"
184"As a result, this feature will be built as a module."),
185nohelp_text[] = N_(
186"There is no help available for this option.\n"),
187load_config_text[] = N_(
188"Enter the name of the configuration file you wish to load.\n"
189"Accept the name shown to restore the configuration you\n"
190"last retrieved. Leave blank to abort."),
191load_config_help[] = N_(
192"\n"
193"For various reasons, one may wish to keep several different\n"
194"configurations available on a single machine.\n"
195"\n"
196"If you have saved a previous configuration in a file other than the\n"
197"default one, entering its name here will allow you to modify that\n"
198"configuration.\n"
199"\n"
200"If you are uncertain, then you have probably never used alternate\n"
201"configuration files. You should therefor leave this blank to abort.\n"),
202save_config_text[] = N_(
203"Enter a filename to which this configuration should be saved\n"
204"as an alternate. Leave blank to abort."),
205save_config_help[] = N_(
206"\n"
207"For various reasons, one may wish to keep different configurations\n"
208"available on a single machine.\n"
209"\n"
210"Entering a file name here will allow you to later retrieve, modify\n"
211"and use the current configuration as an alternate to whatever\n"
212"configuration options you have selected at that time.\n"
213"\n"
214"If you are uncertain what all this means then you should probably\n"
215"leave this blank.\n"),
216search_help[] = N_(
217"\n"
218"Search for symbols and display their relations. Regular expressions\n"
219"are allowed.\n"
220"Example: search for \"^FOO\"\n"
221"Result:\n"
222"-----------------------------------------------------------------\n"
223"Symbol: FOO [ = m]\n"
224"Prompt: Foo bus is used to drive the bar HW\n"
225"Defined at drivers/pci/Kconfig:47\n"
226"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
227"Location:\n"
228" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
229" -> PCI support (PCI [ = y])\n"
230" -> PCI access mode (<choice> [ = y])\n"
231"Selects: LIBCRC32\n"
232"Selected by: BAR\n"
233"-----------------------------------------------------------------\n"
234"o The line 'Prompt:' shows the text used in the menu structure for\n"
235" this symbol\n"
236"o The 'Defined at' line tell at what file / line number the symbol\n"
237" is defined\n"
238"o The 'Depends on:' line tell what symbols needs to be defined for\n"
239" this symbol to be visible in the menu (selectable)\n"
240"o The 'Location:' lines tell where in the menu structure this symbol\n"
241" is located\n"
242" A location followed by a [ = y] indicate that this is a selectable\n"
243" menu item - and current value is displayed inside brackets.\n"
244"o The 'Selects:' line tell what symbol will be automatically\n"
245" selected if this symbol is selected (y or m)\n"
246"o The 'Selected by' line tell what symbol has selected this symbol\n"
247"\n"
248"Only relevant lines are shown.\n"
249"\n\n"
250"Search examples:\n"
251"Examples: USB => find all symbols containing USB\n"
252" ^USB => find all symbols starting with USB\n"
253" USB$ => find all symbols ending with USB\n"
254"\n");
255
256struct mitem {
257 char str[256];
258 char tag;
259 void *usrptr;
260 int is_visible;
261};
262
263#define MAX_MENU_ITEMS 4096
264static int show_all_items;
265static int indent;
266static struct menu *current_menu;
267static int child_count;
268static int single_menu_mode;
269/* the window in which all information appears */
270static WINDOW *main_window;
271/* the largest size of the menu window */
272static int mwin_max_lines;
273static int mwin_max_cols;
274/* the window in which we show option buttons */
275static MENU *curses_menu;
276static ITEM *curses_menu_items[MAX_MENU_ITEMS];
277static struct mitem k_menu_items[MAX_MENU_ITEMS];
278static int items_num;
279static int global_exit;
280/* the currently selected button */
281const char *current_instructions = menu_instructions;
282
283static void conf(struct menu *menu);
284static void conf_choice(struct menu *menu);
285static void conf_string(struct menu *menu);
286static void conf_load(void);
287static void conf_save(void);
288static void show_help(struct menu *menu);
289static int do_exit(void);
290static void setup_windows(void);
291static void search_conf(void);
292
293typedef void (*function_key_handler_t)(int *key, struct menu *menu);
294static void handle_f1(int *key, struct menu *current_item);
295static void handle_f2(int *key, struct menu *current_item);
296static void handle_f3(int *key, struct menu *current_item);
297static void handle_f4(int *key, struct menu *current_item);
298static void handle_f5(int *key, struct menu *current_item);
299static void handle_f6(int *key, struct menu *current_item);
300static void handle_f7(int *key, struct menu *current_item);
301static void handle_f8(int *key, struct menu *current_item);
302static void handle_f9(int *key, struct menu *current_item);
303
304struct function_keys {
305 const char *key_str;
306 const char *func;
307 function_key key;
308 function_key_handler_t handler;
309};
310
311static const int function_keys_num = 9;
312struct function_keys function_keys[] = {
313 {
314 .key_str = "F1",
315 .func = "Help",
316 .key = F_HELP,
317 .handler = handle_f1,
318 },
319 {
320 .key_str = "F2",
321 .func = "Sym Info",
322 .key = F_SYMBOL,
323 .handler = handle_f2,
324 },
325 {
326 .key_str = "F3",
327 .func = "Insts",
328 .key = F_INSTS,
329 .handler = handle_f3,
330 },
331 {
332 .key_str = "F4",
333 .func = "Config",
334 .key = F_CONF,
335 .handler = handle_f4,
336 },
337 {
338 .key_str = "F5",
339 .func = "Back",
340 .key = F_BACK,
341 .handler = handle_f5,
342 },
343 {
344 .key_str = "F6",
345 .func = "Save",
346 .key = F_SAVE,
347 .handler = handle_f6,
348 },
349 {
350 .key_str = "F7",
351 .func = "Load",
352 .key = F_LOAD,
353 .handler = handle_f7,
354 },
355 {
356 .key_str = "F8",
357 .func = "Sym Search",
358 .key = F_SEARCH,
359 .handler = handle_f8,
360 },
361 {
362 .key_str = "F9",
363 .func = "Exit",
364 .key = F_EXIT,
365 .handler = handle_f9,
366 },
367};
368
369static void print_function_line(void)
370{
371 int i;
372 int offset = 1;
373 const int skip = 1;
374
375 for (i = 0; i < function_keys_num; i++) {
376 wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
377 mvwprintw(main_window, LINES-3, offset,
378 "%s",
379 function_keys[i].key_str);
380 wattrset(main_window, attributes[FUNCTION_TEXT]);
381 offset += strlen(function_keys[i].key_str);
382 mvwprintw(main_window, LINES-3,
383 offset, "%s",
384 function_keys[i].func);
385 offset += strlen(function_keys[i].func) + skip;
386 }
387 wattrset(main_window, attributes[NORMAL]);
388}
389
390/* help */
391static void handle_f1(int *key, struct menu *current_item)
392{
393 show_scroll_win(main_window,
394 _("README"), _(nconf_readme));
395 return;
396}
397
398/* symbole help */
399static void handle_f2(int *key, struct menu *current_item)
400{
401 show_help(current_item);
402 return;
403}
404
405/* instructions */
406static void handle_f3(int *key, struct menu *current_item)
407{
408 show_scroll_win(main_window,
409 _("Instructions"),
410 _(current_instructions));
411 return;
412}
413
414/* config */
415static void handle_f4(int *key, struct menu *current_item)
416{
417 int res = btn_dialog(main_window,
418 _("Show all symbols?"),
419 2,
420 " <Show All> ",
421 "<Don't show all>");
422 if (res == 0)
423 show_all_items = 1;
424 else if (res == 1)
425 show_all_items = 0;
426
427 return;
428}
429
430/* back */
431static void handle_f5(int *key, struct menu *current_item)
432{
433 *key = KEY_LEFT;
434 return;
435}
436
437/* save */
438static void handle_f6(int *key, struct menu *current_item)
439{
440 conf_save();
441 return;
442}
443
444/* load */
445static void handle_f7(int *key, struct menu *current_item)
446{
447 conf_load();
448 return;
449}
450
451/* search */
452static void handle_f8(int *key, struct menu *current_item)
453{
454 search_conf();
455 return;
456}
457
458/* exit */
459static void handle_f9(int *key, struct menu *current_item)
460{
461 do_exit();
462 return;
463}
464
465/* return != 0 to indicate the key was handles */
466static int process_special_keys(int *key, struct menu *menu)
467{
468 int i;
469
470 if (*key == KEY_RESIZE) {
471 setup_windows();
472 return 1;
473 }
474
475 for (i = 0; i < function_keys_num; i++) {
476 if (*key == KEY_F(function_keys[i].key) ||
477 *key == '0' + function_keys[i].key){
478 function_keys[i].handler(key, menu);
479 return 1;
480 }
481 }
482
483 return 0;
484}
485
486static void clean_items(void)
487{
488 int i;
489 for (i = 0; curses_menu_items[i]; i++)
490 free_item(curses_menu_items[i]);
491 bzero(curses_menu_items, sizeof(curses_menu_items));
492 bzero(k_menu_items, sizeof(k_menu_items));
493 items_num = 0;
494}
495
496typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
497 FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
498
499/* return the index of the matched item, or -1 if no such item exists */
500static int get_mext_match(const char *match_str, match_f flag)
501{
502 int match_start = item_index(current_item(curses_menu));
503 int index;
504
505 if (flag == FIND_NEXT_MATCH_DOWN)
506 ++match_start;
507 else if (flag == FIND_NEXT_MATCH_UP)
508 --match_start;
509
510 index = match_start;
511 index = (index + items_num) % items_num;
512 while (true) {
513 char *str = k_menu_items[index].str;
514 if (strcasestr(str, match_str) != 0)
515 return index;
516 if (flag == FIND_NEXT_MATCH_UP ||
517 flag == MATCH_TINKER_PATTERN_UP)
518 --index;
519 else
520 ++index;
521 index = (index + items_num) % items_num;
522 if (index == match_start)
523 return -1;
524 }
525}
526
527/* Make a new item. */
528static void item_make(struct menu *menu, char tag, const char *fmt, ...)
529{
530 va_list ap;
531
532 if (items_num > MAX_MENU_ITEMS-1)
533 return;
534
535 bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
536 k_menu_items[items_num].tag = tag;
537 k_menu_items[items_num].usrptr = menu;
538 if (menu != NULL)
539 k_menu_items[items_num].is_visible =
540 menu_is_visible(menu);
541 else
542 k_menu_items[items_num].is_visible = 1;
543
544 va_start(ap, fmt);
545 vsnprintf(k_menu_items[items_num].str,
546 sizeof(k_menu_items[items_num].str),
547 fmt, ap);
548 va_end(ap);
549
550 if (!k_menu_items[items_num].is_visible)
551 memcpy(k_menu_items[items_num].str, "XXX", 3);
552
553 curses_menu_items[items_num] = new_item(
554 k_menu_items[items_num].str,
555 k_menu_items[items_num].str);
556 set_item_userptr(curses_menu_items[items_num],
557 &k_menu_items[items_num]);
558 /*
559 if (!k_menu_items[items_num].is_visible)
560 item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
561 */
562
563 items_num++;
564 curses_menu_items[items_num] = NULL;
565}
566
567/* very hackish. adds a string to the last item added */
568static void item_add_str(const char *fmt, ...)
569{
570 va_list ap;
571 int index = items_num-1;
572 char new_str[256];
573 char tmp_str[256];
574
575 if (index < 0)
576 return;
577
578 va_start(ap, fmt);
579 vsnprintf(new_str, sizeof(new_str), fmt, ap);
580 va_end(ap);
581 snprintf(tmp_str, sizeof(tmp_str), "%s%s",
582 k_menu_items[index].str, new_str);
583 strncpy(k_menu_items[index].str,
584 tmp_str,
585 sizeof(k_menu_items[index].str));
586
587 free_item(curses_menu_items[index]);
588 curses_menu_items[index] = new_item(
589 k_menu_items[index].str,
590 k_menu_items[index].str);
591 set_item_userptr(curses_menu_items[index],
592 &k_menu_items[index]);
593}
594
595/* get the tag of the currently selected item */
596static char item_tag(void)
597{
598 ITEM *cur;
599 struct mitem *mcur;
600
601 cur = current_item(curses_menu);
602 if (cur == NULL)
603 return 0;
604 mcur = (struct mitem *) item_userptr(cur);
605 return mcur->tag;
606}
607
608static int curses_item_index(void)
609{
610 return item_index(current_item(curses_menu));
611}
612
613static void *item_data(void)
614{
615 ITEM *cur;
616 struct mitem *mcur;
617
618 cur = current_item(curses_menu);
619 if (!cur)
620 return NULL;
621 mcur = (struct mitem *) item_userptr(cur);
622 return mcur->usrptr;
623
624}
625
626static int item_is_tag(char tag)
627{
628 return item_tag() == tag;
629}
630
631static char filename[PATH_MAX+1];
632static char menu_backtitle[PATH_MAX+128];
633static const char *set_config_filename(const char *config_filename)
634{
635 int size;
636
637 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
638 "%s - %s", config_filename, rootmenu.prompt->text);
639 if (size >= sizeof(menu_backtitle))
640 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
641
642 size = snprintf(filename, sizeof(filename), "%s", config_filename);
643 if (size >= sizeof(filename))
644 filename[sizeof(filename)-1] = '\0';
645 return menu_backtitle;
646}
647
648/* return = 0 means we are successful.
649 * -1 means go on doing what you were doing
650 */
651static int do_exit(void)
652{
653 int res;
654 if (!conf_get_changed()) {
655 global_exit = 1;
656 return 0;
657 }
658 res = btn_dialog(main_window,
659 _("Do you wish to save your new configuration?\n"
660 "<ESC> to cancel and resume nconfig."),
661 2,
662 " <save> ",
663 "<don't save>");
664 if (res == KEY_EXIT) {
665 global_exit = 0;
666 return -1;
667 }
668
669 /* if we got here, the user really wants to exit */
670 switch (res) {
671 case 0:
672 res = conf_write(filename);
673 if (res)
674 btn_dialog(
675 main_window,
676 _("Error during writing of configuration.\n"
677 "Your configuration changes were NOT saved."),
678 1,
679 "<OK>");
680 break;
681 default:
682 btn_dialog(
683 main_window,
684 _("Your configuration changes were NOT saved."),
685 1,
686 "<OK>");
687 break;
688 }
689 global_exit = 1;
690 return 0;
691}
692
693
694static void search_conf(void)
695{
696 struct symbol **sym_arr;
697 struct gstr res;
698 char dialog_input_result[100];
699 char *dialog_input;
700 int dres;
701again:
702 dres = dialog_inputbox(main_window,
703 _("Search Configuration Parameter"),
704 _("Enter " CONFIG_ " (sub)string to search for "
705 "(with or without \"" CONFIG_ "\")"),
706 "", dialog_input_result, 99);
707 switch (dres) {
708 case 0:
709 break;
710 case 1:
711 show_scroll_win(main_window,
712 _("Search Configuration"), search_help);
713 goto again;
714 default:
715 return;
716 }
717
718 /* strip the prefix if necessary */
719 dialog_input = dialog_input_result;
720 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
721 dialog_input += strlen(CONFIG_);
722
723 sym_arr = sym_re_search(dialog_input);
724 res = get_relations_str(sym_arr);
725 free(sym_arr);
726 show_scroll_win(main_window,
727 _("Search Results"), str_get(&res));
728 str_free(&res);
729}
730
731
732static void build_conf(struct menu *menu)
733{
734 struct symbol *sym;
735 struct property *prop;
736 struct menu *child;
737 int type, tmp, doint = 2;
738 tristate val;
739 char ch;
740
741 if (!menu || (!show_all_items && !menu_is_visible(menu)))
742 return;
743
744 sym = menu->sym;
745 prop = menu->prompt;
746 if (!sym) {
747 if (prop && menu != current_menu) {
748 const char *prompt = menu_get_prompt(menu);
749 enum prop_type ptype;
750 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
751 switch (ptype) {
752 case P_MENU:
753 child_count++;
754 prompt = _(prompt);
755 if (single_menu_mode) {
756 item_make(menu, 'm',
757 "%s%*c%s",
758 menu->data ? "-->" : "++>",
759 indent + 1, ' ', prompt);
760 } else
761 item_make(menu, 'm',
762 " %*c%s --->",
763 indent + 1,
764 ' ', prompt);
765
766 if (single_menu_mode && menu->data)
767 goto conf_childs;
768 return;
769 case P_COMMENT:
770 if (prompt) {
771 child_count++;
772 item_make(menu, ':',
773 " %*c*** %s ***",
774 indent + 1, ' ',
775 _(prompt));
776 }
777 break;
778 default:
779 if (prompt) {
780 child_count++;
781 item_make(menu, ':', "---%*c%s",
782 indent + 1, ' ',
783 _(prompt));
784 }
785 }
786 } else
787 doint = 0;
788 goto conf_childs;
789 }
790
791 type = sym_get_type(sym);
792 if (sym_is_choice(sym)) {
793 struct symbol *def_sym = sym_get_choice_value(sym);
794 struct menu *def_menu = NULL;
795
796 child_count++;
797 for (child = menu->list; child; child = child->next) {
798 if (menu_is_visible(child) && child->sym == def_sym)
799 def_menu = child;
800 }
801
802 val = sym_get_tristate_value(sym);
803 if (sym_is_changable(sym)) {
804 switch (type) {
805 case S_BOOLEAN:
806 item_make(menu, 't', "[%c]",
807 val == no ? ' ' : '*');
808 break;
809 case S_TRISTATE:
810 switch (val) {
811 case yes:
812 ch = '*';
813 break;
814 case mod:
815 ch = 'M';
816 break;
817 default:
818 ch = ' ';
819 break;
820 }
821 item_make(menu, 't', "<%c>", ch);
822 break;
823 }
824 } else {
825 item_make(menu, def_menu ? 't' : ':', " ");
826 }
827
828 item_add_str("%*c%s", indent + 1,
829 ' ', _(menu_get_prompt(menu)));
830 if (val == yes) {
831 if (def_menu) {
832 item_add_str(" (%s)",
833 _(menu_get_prompt(def_menu)));
834 item_add_str(" --->");
835 if (def_menu->list) {
836 indent += 2;
837 build_conf(def_menu);
838 indent -= 2;
839 }
840 }
841 return;
842 }
843 } else {
844 if (menu == current_menu) {
845 item_make(menu, ':',
846 "---%*c%s", indent + 1,
847 ' ', _(menu_get_prompt(menu)));
848 goto conf_childs;
849 }
850 child_count++;
851 val = sym_get_tristate_value(sym);
852 if (sym_is_choice_value(sym) && val == yes) {
853 item_make(menu, ':', " ");
854 } else {
855 switch (type) {
856 case S_BOOLEAN:
857 if (sym_is_changable(sym))
858 item_make(menu, 't', "[%c]",
859 val == no ? ' ' : '*');
860 else
861 item_make(menu, 't', "-%c-",
862 val == no ? ' ' : '*');
863 break;
864 case S_TRISTATE:
865 switch (val) {
866 case yes:
867 ch = '*';
868 break;
869 case mod:
870 ch = 'M';
871 break;
872 default:
873 ch = ' ';
874 break;
875 }
876 if (sym_is_changable(sym)) {
877 if (sym->rev_dep.tri == mod)
878 item_make(menu,
879 't', "{%c}", ch);
880 else
881 item_make(menu,
882 't', "<%c>", ch);
883 } else
884 item_make(menu, 't', "-%c-", ch);
885 break;
886 default:
887 tmp = 2 + strlen(sym_get_string_value(sym));
888 item_make(menu, 's', " (%s)",
889 sym_get_string_value(sym));
890 tmp = indent - tmp + 4;
891 if (tmp < 0)
892 tmp = 0;
893 item_add_str("%*c%s%s", tmp, ' ',
894 _(menu_get_prompt(menu)),
895 (sym_has_value(sym) ||
896 !sym_is_changable(sym)) ? "" :
897 _(" (NEW)"));
898 goto conf_childs;
899 }
900 }
901 item_add_str("%*c%s%s", indent + 1, ' ',
902 _(menu_get_prompt(menu)),
903 (sym_has_value(sym) || !sym_is_changable(sym)) ?
904 "" : _(" (NEW)"));
905 if (menu->prompt && menu->prompt->type == P_MENU) {
906 item_add_str(" --->");
907 return;
908 }
909 }
910
911conf_childs:
912 indent += doint;
913 for (child = menu->list; child; child = child->next)
914 build_conf(child);
915 indent -= doint;
916}
917
918static void reset_menu(void)
919{
920 unpost_menu(curses_menu);
921 clean_items();
922}
923
924/* adjust the menu to show this item.
925 * prefer not to scroll the menu if possible*/
926static void center_item(int selected_index, int *last_top_row)
927{
928 int toprow;
929
930 set_top_row(curses_menu, *last_top_row);
931 toprow = top_row(curses_menu);
932 if (selected_index < toprow ||
933 selected_index >= toprow+mwin_max_lines) {
934 toprow = max(selected_index-mwin_max_lines/2, 0);
935 if (toprow >= item_count(curses_menu)-mwin_max_lines)
936 toprow = item_count(curses_menu)-mwin_max_lines;
937 set_top_row(curses_menu, toprow);
938 }
939 set_current_item(curses_menu,
940 curses_menu_items[selected_index]);
941 *last_top_row = toprow;
942 post_menu(curses_menu);
943 refresh_all_windows(main_window);
944}
945
946/* this function assumes reset_menu has been called before */
947static void show_menu(const char *prompt, const char *instructions,
948 int selected_index, int *last_top_row)
949{
950 int maxx, maxy;
951 WINDOW *menu_window;
952
953 current_instructions = instructions;
954
955 clear();
956 wattrset(main_window, attributes[NORMAL]);
957 print_in_middle(stdscr, 1, 0, COLS,
958 menu_backtitle,
959 attributes[MAIN_HEADING]);
960
961 wattrset(main_window, attributes[MAIN_MENU_BOX]);
962 box(main_window, 0, 0);
963 wattrset(main_window, attributes[MAIN_MENU_HEADING]);
964 mvwprintw(main_window, 0, 3, " %s ", prompt);
965 wattrset(main_window, attributes[NORMAL]);
966
967 set_menu_items(curses_menu, curses_menu_items);
968
969 /* position the menu at the middle of the screen */
970 scale_menu(curses_menu, &maxy, &maxx);
971 maxx = min(maxx, mwin_max_cols-2);
972 maxy = mwin_max_lines;
973 menu_window = derwin(main_window,
974 maxy,
975 maxx,
976 2,
977 (mwin_max_cols-maxx)/2);
978 keypad(menu_window, TRUE);
979 set_menu_win(curses_menu, menu_window);
980 set_menu_sub(curses_menu, menu_window);
981
982 /* must reassert this after changing items, otherwise returns to a
983 * default of 16
984 */
985 set_menu_format(curses_menu, maxy, 1);
986 center_item(selected_index, last_top_row);
987 set_menu_format(curses_menu, maxy, 1);
988
989 print_function_line();
990
991 /* Post the menu */
992 post_menu(curses_menu);
993 refresh_all_windows(main_window);
994}
995
996static void adj_match_dir(match_f *match_direction)
997{
998 if (*match_direction == FIND_NEXT_MATCH_DOWN)
999 *match_direction =
1000 MATCH_TINKER_PATTERN_DOWN;
1001 else if (*match_direction == FIND_NEXT_MATCH_UP)
1002 *match_direction =
1003 MATCH_TINKER_PATTERN_UP;
1004 /* else, do no change.. */
1005}
1006
1007struct match_state
1008{
1009 int in_search;
1010 match_f match_direction;
1011 char pattern[256];
1012};
1013
1014/* Return 0 means I have handled the key. In such a case, ans should hold the
1015 * item to center, or -1 otherwise.
1016 * Else return -1 .
1017 */
1018static int do_match(int key, struct match_state *state, int *ans)
1019{
1020 char c = (char) key;
1021 int terminate_search = 0;
1022 *ans = -1;
1023 if (key == '/' || (state->in_search && key == 27)) {
1024 move(0, 0);
1025 refresh();
1026 clrtoeol();
1027 state->in_search = 1-state->in_search;
1028 bzero(state->pattern, sizeof(state->pattern));
1029 state->match_direction = MATCH_TINKER_PATTERN_DOWN;
1030 return 0;
1031 } else if (!state->in_search)
1032 return 1;
1033
1034 if (isalnum(c) || isgraph(c) || c == ' ') {
1035 state->pattern[strlen(state->pattern)] = c;
1036 state->pattern[strlen(state->pattern)] = '\0';
1037 adj_match_dir(&state->match_direction);
1038 *ans = get_mext_match(state->pattern,
1039 state->match_direction);
1040 } else if (key == KEY_DOWN) {
1041 state->match_direction = FIND_NEXT_MATCH_DOWN;
1042 *ans = get_mext_match(state->pattern,
1043 state->match_direction);
1044 } else if (key == KEY_UP) {
1045 state->match_direction = FIND_NEXT_MATCH_UP;
1046 *ans = get_mext_match(state->pattern,
1047 state->match_direction);
1048 } else if (key == KEY_BACKSPACE || key == 127) {
1049 state->pattern[strlen(state->pattern)-1] = '\0';
1050 adj_match_dir(&state->match_direction);
1051 } else
1052 terminate_search = 1;
1053
1054 if (terminate_search) {
1055 state->in_search = 0;
1056 bzero(state->pattern, sizeof(state->pattern));
1057 move(0, 0);
1058 refresh();
1059 clrtoeol();
1060 return -1;
1061 }
1062 return 0;
1063}
1064
1065static void conf(struct menu *menu)
1066{
1067 struct menu *submenu = 0;
1068 const char *prompt = menu_get_prompt(menu);
1069 struct symbol *sym;
1070 struct menu *active_menu = NULL;
1071 int res;
1072 int current_index = 0;
1073 int last_top_row = 0;
1074 struct match_state match_state = {
1075 .in_search = 0,
1076 .match_direction = MATCH_TINKER_PATTERN_DOWN,
1077 .pattern = "",
1078 };
1079
1080 while (!global_exit) {
1081 reset_menu();
1082 current_menu = menu;
1083 build_conf(menu);
1084 if (!child_count)
1085 break;
1086
1087 show_menu(prompt ? _(prompt) : _("Main Menu"),
1088 _(menu_instructions),
1089 current_index, &last_top_row);
1090 keypad((menu_win(curses_menu)), TRUE);
1091 while (!global_exit) {
1092 if (match_state.in_search) {
1093 mvprintw(0, 0,
1094 "searching: %s", match_state.pattern);
1095 clrtoeol();
1096 }
1097 refresh_all_windows(main_window);
1098 res = wgetch(menu_win(curses_menu));
1099 if (!res)
1100 break;
1101 if (do_match(res, &match_state, &current_index) == 0) {
1102 if (current_index != -1)
1103 center_item(current_index,
1104 &last_top_row);
1105 continue;
1106 }
1107 if (process_special_keys(&res,
1108 (struct menu *) item_data()))
1109 break;
1110 switch (res) {
1111 case KEY_DOWN:
1112 menu_driver(curses_menu, REQ_DOWN_ITEM);
1113 break;
1114 case KEY_UP:
1115 menu_driver(curses_menu, REQ_UP_ITEM);
1116 break;
1117 case KEY_NPAGE:
1118 menu_driver(curses_menu, REQ_SCR_DPAGE);
1119 break;
1120 case KEY_PPAGE:
1121 menu_driver(curses_menu, REQ_SCR_UPAGE);
1122 break;
1123 case KEY_HOME:
1124 menu_driver(curses_menu, REQ_FIRST_ITEM);
1125 break;
1126 case KEY_END:
1127 menu_driver(curses_menu, REQ_LAST_ITEM);
1128 break;
1129 case 'h':
1130 case '?':
1131 show_help((struct menu *) item_data());
1132 break;
1133 }
1134 if (res == 10 || res == 27 ||
1135 res == 32 || res == 'n' || res == 'y' ||
1136 res == KEY_LEFT || res == KEY_RIGHT ||
1137 res == 'm')
1138 break;
1139 refresh_all_windows(main_window);
1140 }
1141
1142 refresh_all_windows(main_window);
1143 /* if ESC or left*/
1144 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1145 break;
1146
1147 /* remember location in the menu */
1148 last_top_row = top_row(curses_menu);
1149 current_index = curses_item_index();
1150
1151 if (!item_tag())
1152 continue;
1153
1154 submenu = (struct menu *) item_data();
1155 active_menu = (struct menu *)item_data();
1156 if (!submenu || !menu_is_visible(submenu))
1157 continue;
1158 if (submenu)
1159 sym = submenu->sym;
1160 else
1161 sym = NULL;
1162
1163 switch (res) {
1164 case ' ':
1165 if (item_is_tag('t'))
1166 sym_toggle_tristate_value(sym);
1167 else if (item_is_tag('m'))
1168 conf(submenu);
1169 break;
1170 case KEY_RIGHT:
1171 case 10: /* ENTER WAS PRESSED */
1172 switch (item_tag()) {
1173 case 'm':
1174 if (single_menu_mode)
1175 submenu->data =
1176 (void *) (long) !submenu->data;
1177 else
1178 conf(submenu);
1179 break;
1180 case 't':
1181 if (sym_is_choice(sym) &&
1182 sym_get_tristate_value(sym) == yes)
1183 conf_choice(submenu);
1184 else if (submenu->prompt &&
1185 submenu->prompt->type == P_MENU)
1186 conf(submenu);
1187 else if (res == 10)
1188 sym_toggle_tristate_value(sym);
1189 break;
1190 case 's':
1191 conf_string(submenu);
1192 break;
1193 }
1194 break;
1195 case 'y':
1196 if (item_is_tag('t')) {
1197 if (sym_set_tristate_value(sym, yes))
1198 break;
1199 if (sym_set_tristate_value(sym, mod))
1200 btn_dialog(main_window, setmod_text, 0);
1201 }
1202 break;
1203 case 'n':
1204 if (item_is_tag('t'))
1205 sym_set_tristate_value(sym, no);
1206 break;
1207 case 'm':
1208 if (item_is_tag('t'))
1209 sym_set_tristate_value(sym, mod);
1210 break;
1211 }
1212 }
1213}
1214
1215static void conf_message_callback(const char *fmt, va_list ap)
1216{
1217 char buf[1024];
1218
1219 vsnprintf(buf, sizeof(buf), fmt, ap);
1220 btn_dialog(main_window, buf, 1, "<OK>");
1221}
1222
1223static void show_help(struct menu *menu)
1224{
1225 struct gstr help = str_new();
1226
1227 if (menu && menu->sym && menu_has_help(menu)) {
1228 if (menu->sym->name) {
1229 str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name);
1230 str_append(&help, _(menu_get_help(menu)));
1231 str_append(&help, "\n");
1232 get_symbol_str(&help, menu->sym);
1233 } else {
1234 str_append(&help, _(menu_get_help(menu)));
1235 }
1236 } else {
1237 str_append(&help, nohelp_text);
1238 }
1239 show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
1240 str_free(&help);
1241}
1242
1243static void conf_choice(struct menu *menu)
1244{
1245 const char *prompt = _(menu_get_prompt(menu));
1246 struct menu *child = 0;
1247 struct symbol *active;
1248 int selected_index = 0;
1249 int last_top_row = 0;
1250 int res, i = 0;
1251 struct match_state match_state = {
1252 .in_search = 0,
1253 .match_direction = MATCH_TINKER_PATTERN_DOWN,
1254 .pattern = "",
1255 };
1256
1257 active = sym_get_choice_value(menu->sym);
1258 /* this is mostly duplicated from the conf() function. */
1259 while (!global_exit) {
1260 reset_menu();
1261
1262 for (i = 0, child = menu->list; child; child = child->next) {
1263 if (!show_all_items && !menu_is_visible(child))
1264 continue;
1265
1266 if (child->sym == sym_get_choice_value(menu->sym))
1267 item_make(child, ':', "<X> %s",
1268 _(menu_get_prompt(child)));
1269 else if (child->sym)
1270 item_make(child, ':', " %s",
1271 _(menu_get_prompt(child)));
1272 else
1273 item_make(child, ':', "*** %s ***",
1274 _(menu_get_prompt(child)));
1275
1276 if (child->sym == active){
1277 last_top_row = top_row(curses_menu);
1278 selected_index = i;
1279 }
1280 i++;
1281 }
1282 show_menu(prompt ? _(prompt) : _("Choice Menu"),
1283 _(radiolist_instructions),
1284 selected_index,
1285 &last_top_row);
1286 while (!global_exit) {
1287 if (match_state.in_search) {
1288 mvprintw(0, 0, "searching: %s",
1289 match_state.pattern);
1290 clrtoeol();
1291 }
1292 refresh_all_windows(main_window);
1293 res = wgetch(menu_win(curses_menu));
1294 if (!res)
1295 break;
1296 if (do_match(res, &match_state, &selected_index) == 0) {
1297 if (selected_index != -1)
1298 center_item(selected_index,
1299 &last_top_row);
1300 continue;
1301 }
1302 if (process_special_keys(
1303 &res,
1304 (struct menu *) item_data()))
1305 break;
1306 switch (res) {
1307 case KEY_DOWN:
1308 menu_driver(curses_menu, REQ_DOWN_ITEM);
1309 break;
1310 case KEY_UP:
1311 menu_driver(curses_menu, REQ_UP_ITEM);
1312 break;
1313 case KEY_NPAGE:
1314 menu_driver(curses_menu, REQ_SCR_DPAGE);
1315 break;
1316 case KEY_PPAGE:
1317 menu_driver(curses_menu, REQ_SCR_UPAGE);
1318 break;
1319 case KEY_HOME:
1320 menu_driver(curses_menu, REQ_FIRST_ITEM);
1321 break;
1322 case KEY_END:
1323 menu_driver(curses_menu, REQ_LAST_ITEM);
1324 break;
1325 case 'h':
1326 case '?':
1327 show_help((struct menu *) item_data());
1328 break;
1329 }
1330 if (res == 10 || res == 27 || res == ' ' ||
1331 res == KEY_LEFT){
1332 break;
1333 }
1334 refresh_all_windows(main_window);
1335 }
1336 /* if ESC or left */
1337 if (res == 27 || res == KEY_LEFT)
1338 break;
1339
1340 child = item_data();
1341 if (!child || !menu_is_visible(child) || !child->sym)
1342 continue;
1343 switch (res) {
1344 case ' ':
1345 case 10:
1346 case KEY_RIGHT:
1347 sym_set_tristate_value(child->sym, yes);
1348 return;
1349 case 'h':
1350 case '?':
1351 show_help(child);
1352 active = child->sym;
1353 break;
1354 case KEY_EXIT:
1355 return;
1356 }
1357 }
1358}
1359
1360static void conf_string(struct menu *menu)
1361{
1362 const char *prompt = menu_get_prompt(menu);
1363 char dialog_input_result[256];
1364
1365 while (1) {
1366 int res;
1367 const char *heading;
1368
1369 switch (sym_get_type(menu->sym)) {
1370 case S_INT:
1371 heading = _(inputbox_instructions_int);
1372 break;
1373 case S_HEX:
1374 heading = _(inputbox_instructions_hex);
1375 break;
1376 case S_STRING:
1377 heading = _(inputbox_instructions_string);
1378 break;
1379 default:
1380 heading = _("Internal nconf error!");
1381 }
1382 res = dialog_inputbox(main_window,
1383 prompt ? _(prompt) : _("Main Menu"),
1384 heading,
1385 sym_get_string_value(menu->sym),
1386 dialog_input_result,
1387 sizeof(dialog_input_result));
1388 switch (res) {
1389 case 0:
1390 if (sym_set_string_value(menu->sym,
1391 dialog_input_result))
1392 return;
1393 btn_dialog(main_window,
1394 _("You have made an invalid entry."), 0);
1395 break;
1396 case 1:
1397 show_help(menu);
1398 break;
1399 case KEY_EXIT:
1400 return;
1401 }
1402 }
1403}
1404
1405static void conf_load(void)
1406{
1407 char dialog_input_result[256];
1408 while (1) {
1409 int res;
1410 res = dialog_inputbox(main_window,
1411 NULL, load_config_text,
1412 filename,
1413 dialog_input_result,
1414 sizeof(dialog_input_result));
1415 switch (res) {
1416 case 0:
1417 if (!dialog_input_result[0])
1418 return;
1419 if (!conf_read(dialog_input_result)) {
1420 set_config_filename(dialog_input_result);
1421 sym_set_change_count(1);
1422 return;
1423 }
1424 btn_dialog(main_window, _("File does not exist!"), 0);
1425 break;
1426 case 1:
1427 show_scroll_win(main_window,
1428 _("Load Alternate Configuration"),
1429 load_config_help);
1430 break;
1431 case KEY_EXIT:
1432 return;
1433 }
1434 }
1435}
1436
1437static void conf_save(void)
1438{
1439 char dialog_input_result[256];
1440 while (1) {
1441 int res;
1442 res = dialog_inputbox(main_window,
1443 NULL, save_config_text,
1444 filename,
1445 dialog_input_result,
1446 sizeof(dialog_input_result));
1447 switch (res) {
1448 case 0:
1449 if (!dialog_input_result[0])
1450 return;
1451 res = conf_write(dialog_input_result);
1452 if (!res) {
1453 set_config_filename(dialog_input_result);
1454 return;
1455 }
1456 btn_dialog(main_window, _("Can't create file! "
1457 "Probably a nonexistent directory."),
1458 1, "<OK>");
1459 break;
1460 case 1:
1461 show_scroll_win(main_window,
1462 _("Save Alternate Configuration"),
1463 save_config_help);
1464 break;
1465 case KEY_EXIT:
1466 return;
1467 }
1468 }
1469}
1470
1471void setup_windows(void)
1472{
1473 if (main_window != NULL)
1474 delwin(main_window);
1475
1476 /* set up the menu and menu window */
1477 main_window = newwin(LINES-2, COLS-2, 2, 1);
1478 keypad(main_window, TRUE);
1479 mwin_max_lines = LINES-7;
1480 mwin_max_cols = COLS-6;
1481
1482 /* panels order is from bottom to top */
1483 new_panel(main_window);
1484}
1485
1486int main(int ac, char **av)
1487{
1488 char *mode;
1489
1490 setlocale(LC_ALL, "");
1491 bindtextdomain(PACKAGE, LOCALEDIR);
1492 textdomain(PACKAGE);
1493
1494 conf_parse(av[1]);
1495 conf_read(NULL);
1496
1497 mode = getenv("NCONFIG_MODE");
1498 if (mode) {
1499 if (!strcasecmp(mode, "single_menu"))
1500 single_menu_mode = 1;
1501 }
1502
1503 /* Initialize curses */
1504 initscr();
1505 /* set color theme */
1506 set_colors();
1507
1508 cbreak();
1509 noecho();
1510 keypad(stdscr, TRUE);
1511 curs_set(0);
1512
1513 if (COLS < 75 || LINES < 20) {
1514 endwin();
1515 printf("Your terminal should have at "
1516 "least 20 lines and 75 columns\n");
1517 return 1;
1518 }
1519
1520 notimeout(stdscr, FALSE);
1521 ESCDELAY = 1;
1522
1523 /* set btns menu */
1524 curses_menu = new_menu(curses_menu_items);
1525 menu_opts_off(curses_menu, O_SHOWDESC);
1526 menu_opts_on(curses_menu, O_SHOWMATCH);
1527 menu_opts_on(curses_menu, O_ONEVALUE);
1528 menu_opts_on(curses_menu, O_NONCYCLIC);
1529 menu_opts_on(curses_menu, O_IGNORECASE);
1530 set_menu_mark(curses_menu, " ");
1531 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1532 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
1533 set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
1534
1535 set_config_filename(conf_get_configname());
1536 setup_windows();
1537
1538 /* check for KEY_FUNC(1) */
1539 if (has_key(KEY_F(1)) == FALSE) {
1540 show_scroll_win(main_window,
1541 _("Instructions"),
1542 _(menu_no_f_instructions));
1543 }
1544
1545 conf_set_message_callback(conf_message_callback);
1546 /* do the work */
1547 while (!global_exit) {
1548 conf(&rootmenu);
1549 if (!global_exit && do_exit() == 0)
1550 break;
1551 }
1552 /* ok, we are done */
1553 unpost_menu(curses_menu);
1554 free_menu(curses_menu);
1555 delwin(main_window);
1556 clear();
1557 refresh();
1558 endwin();
1559 return 0;
1560}
1561
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
new file mode 100644
index 000000000000..f8137b3a5382
--- /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 defaults */
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 (void) 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 (void) wattrset(win, attributes[DIALOG_BOX]);
301 box(win, 0, 0);
302
303 /* print message */
304 (void) 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 (void) wattrset(form_win, attributes[INPUT_FIELD]);
396
397 (void) wattrset(win, attributes[INPUT_BOX]);
398 box(win, 0, 0);
399 (void) wattrset(win, attributes[INPUT_HEADING]);
400 if (title)
401 mvwprintw(win, 0, 3, "%s", title);
402
403 /* print message */
404 (void) 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 (void) 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 (void) wattrset(win, attributes[SCROLLWIN_BOX]);
550 box(win, 0, 0);
551 (void) 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..58fbda8fc0dc
--- /dev/null
+++ b/scripts/kconfig/nconf.h
@@ -0,0 +1,96 @@
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_SEARCH = 8,
73 F_EXIT = 9,
74} function_key;
75
76void set_colors(void);
77
78/* this changes the windows attributes !!! */
79void print_in_middle(WINDOW *win,
80 int starty,
81 int startx,
82 int width,
83 const char *string,
84 chtype color);
85int get_line_length(const char *line);
86int get_line_no(const char *text);
87const char *get_line(const char *text, int line_no);
88void fill_window(WINDOW *win, const char *text);
89int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
90int dialog_inputbox(WINDOW *main_window,
91 const char *title, const char *prompt,
92 const char *init, char *result, int result_len);
93void refresh_all_windows(WINDOW *main_window);
94void show_scroll_win(WINDOW *main_window,
95 const char *title,
96 const char *text);
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index ce7d508c7520..06dd2e33581d 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -3,25 +3,42 @@
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <qapplication.h> 6#include <qglobal.h>
7
8#if QT_VERSION < 0x040000
7#include <qmainwindow.h> 9#include <qmainwindow.h>
10#include <qvbox.h>
11#include <qvaluelist.h>
12#include <qtextbrowser.h>
13#include <qaction.h>
14#include <qheader.h>
15#include <qfiledialog.h>
16#include <qdragobject.h>
17#include <qpopupmenu.h>
18#else
19#include <q3mainwindow.h>
20#include <q3vbox.h>
21#include <q3valuelist.h>
22#include <q3textbrowser.h>
23#include <q3action.h>
24#include <q3header.h>
25#include <q3filedialog.h>
26#include <q3dragobject.h>
27#include <q3popupmenu.h>
28#endif
29
30#include <qapplication.h>
8#include <qdesktopwidget.h> 31#include <qdesktopwidget.h>
9#include <qtoolbar.h> 32#include <qtoolbar.h>
10#include <qlayout.h> 33#include <qlayout.h>
11#include <qvbox.h>
12#include <qsplitter.h> 34#include <qsplitter.h>
13#include <qlistview.h>
14#include <qtextbrowser.h>
15#include <qlineedit.h> 35#include <qlineedit.h>
16#include <qlabel.h> 36#include <qlabel.h>
17#include <qpushbutton.h> 37#include <qpushbutton.h>
18#include <qmenubar.h> 38#include <qmenubar.h>
19#include <qmessagebox.h> 39#include <qmessagebox.h>
20#include <qaction.h>
21#include <qheader.h>
22#include <qfiledialog.h>
23#include <qdragobject.h>
24#include <qregexp.h> 40#include <qregexp.h>
41#include <qevent.h>
25 42
26#include <stdlib.h> 43#include <stdlib.h>
27 44
@@ -39,7 +56,7 @@
39static QApplication *configApp; 56static QApplication *configApp;
40static ConfigSettings *configSettings; 57static ConfigSettings *configSettings;
41 58
42QAction *ConfigMainWindow::saveAction; 59Q3Action *ConfigMainWindow::saveAction;
43 60
44static inline QString qgettext(const char* str) 61static inline QString qgettext(const char* str)
45{ 62{
@@ -54,15 +71,14 @@ static inline QString qgettext(const QString& str)
54/** 71/**
55 * Reads a list of integer values from the application settings. 72 * Reads a list of integer values from the application settings.
56 */ 73 */
57QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok) 74Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58{ 75{
59 QValueList<int> result; 76 Q3ValueList<int> result;
60 QStringList entryList = readListEntry(key, ok); 77 QStringList entryList = readListEntry(key, ok);
61 if (ok) { 78 QStringList::Iterator it;
62 QStringList::Iterator it; 79
63 for (it = entryList.begin(); it != entryList.end(); ++it) 80 for (it = entryList.begin(); it != entryList.end(); ++it)
64 result.push_back((*it).toInt()); 81 result.push_back((*it).toInt());
65 }
66 82
67 return result; 83 return result;
68} 84}
@@ -70,10 +86,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
70/** 86/**
71 * Writes a list of integer values to the application settings. 87 * Writes a list of integer values to the application settings.
72 */ 88 */
73bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value) 89bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
74{ 90{
75 QStringList stringList; 91 QStringList stringList;
76 QValueList<int>::ConstIterator it; 92 Q3ValueList<int>::ConstIterator it;
77 93
78 for (it = value.begin(); it != value.end(); ++it) 94 for (it = value.begin(); it != value.end(); ++it)
79 stringList.push_back(QString::number(*it)); 95 stringList.push_back(QString::number(*it));
@@ -81,7 +97,6 @@ bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value
81} 97}
82 98
83 99
84#if QT_VERSION >= 300
85/* 100/*
86 * set the new data 101 * set the new data
87 * TODO check the value 102 * TODO check the value
@@ -92,7 +107,6 @@ void ConfigItem::okRename(int col)
92 sym_set_string_value(menu->sym, text(dataColIdx).latin1()); 107 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
93 listView()->updateList(this); 108 listView()->updateList(this);
94} 109}
95#endif
96 110
97/* 111/*
98 * update the displayed of a menu entry 112 * update the displayed of a menu entry
@@ -149,7 +163,7 @@ void ConfigItem::updateMenu(void)
149 case S_TRISTATE: 163 case S_TRISTATE:
150 char ch; 164 char ch;
151 165
152 if (!sym_is_changable(sym) && !list->showAll) { 166 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
153 setPixmap(promptColIdx, 0); 167 setPixmap(promptColIdx, 0);
154 setText(noColIdx, QString::null); 168 setText(noColIdx, QString::null);
155 setText(modColIdx, QString::null); 169 setText(modColIdx, QString::null);
@@ -196,11 +210,9 @@ void ConfigItem::updateMenu(void)
196 210
197 data = sym_get_string_value(sym); 211 data = sym_get_string_value(sym);
198 212
199#if QT_VERSION >= 300
200 int i = list->mapIdx(dataColIdx); 213 int i = list->mapIdx(dataColIdx);
201 if (i >= 0) 214 if (i >= 0)
202 setRenameEnabled(i, TRUE); 215 setRenameEnabled(i, TRUE);
203#endif
204 setText(dataColIdx, data); 216 setText(dataColIdx, data);
205 if (type == S_STRING) 217 if (type == S_STRING)
206 prompt = QString("%1: %2").arg(prompt).arg(data); 218 prompt = QString("%1: %2").arg(prompt).arg(data);
@@ -320,7 +332,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
320 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), 332 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
321 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), 333 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
322 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), 334 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
323 showAll(false), showName(false), showRange(false), showData(false), 335 showName(false), showRange(false), showData(false), optMode(normalOpt),
324 rootEntry(0), headerPopup(0) 336 rootEntry(0), headerPopup(0)
325{ 337{
326 int i; 338 int i;
@@ -337,10 +349,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
337 349
338 if (name) { 350 if (name) {
339 configSettings->beginGroup(name); 351 configSettings->beginGroup(name);
340 showAll = configSettings->readBoolEntry("/showAll", false);
341 showName = configSettings->readBoolEntry("/showName", false); 352 showName = configSettings->readBoolEntry("/showName", false);
342 showRange = configSettings->readBoolEntry("/showRange", false); 353 showRange = configSettings->readBoolEntry("/showRange", false);
343 showData = configSettings->readBoolEntry("/showData", false); 354 showData = configSettings->readBoolEntry("/showData", false);
355 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
344 configSettings->endGroup(); 356 configSettings->endGroup();
345 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); 357 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
346 } 358 }
@@ -352,6 +364,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
352 reinit(); 364 reinit();
353} 365}
354 366
367bool ConfigList::menuSkip(struct menu *menu)
368{
369 if (optMode == normalOpt && menu_is_visible(menu))
370 return false;
371 if (optMode == promptOpt && menu_has_prompt(menu))
372 return false;
373 if (optMode == allOpt)
374 return false;
375 return true;
376}
377
355void ConfigList::reinit(void) 378void ConfigList::reinit(void)
356{ 379{
357 removeColumn(dataColIdx); 380 removeColumn(dataColIdx);
@@ -380,7 +403,7 @@ void ConfigList::saveSettings(void)
380 configSettings->writeEntry("/showName", showName); 403 configSettings->writeEntry("/showName", showName);
381 configSettings->writeEntry("/showRange", showRange); 404 configSettings->writeEntry("/showRange", showRange);
382 configSettings->writeEntry("/showData", showData); 405 configSettings->writeEntry("/showData", showData);
383 configSettings->writeEntry("/showAll", showAll); 406 configSettings->writeEntry("/optionMode", (int)optMode);
384 configSettings->endGroup(); 407 configSettings->endGroup();
385 } 408 }
386} 409}
@@ -422,7 +445,7 @@ void ConfigList::updateList(ConfigItem* item)
422 if (!rootEntry) { 445 if (!rootEntry) {
423 if (mode != listMode) 446 if (mode != listMode)
424 goto update; 447 goto update;
425 QListViewItemIterator it(this); 448 Q3ListViewItemIterator it(this);
426 ConfigItem* item; 449 ConfigItem* item;
427 450
428 for (; it.current(); ++it) { 451 for (; it.current(); ++it) {
@@ -517,11 +540,9 @@ void ConfigList::changeValue(ConfigItem* item)
517 case S_INT: 540 case S_INT:
518 case S_HEX: 541 case S_HEX:
519 case S_STRING: 542 case S_STRING:
520#if QT_VERSION >= 300
521 if (colMap[dataColIdx] >= 0) 543 if (colMap[dataColIdx] >= 0)
522 item->startRename(colMap[dataColIdx]); 544 item->startRename(colMap[dataColIdx]);
523 else 545 else
524#endif
525 parent()->lineEdit->show(item); 546 parent()->lineEdit->show(item);
526 break; 547 break;
527 } 548 }
@@ -553,7 +574,7 @@ void ConfigList::setParentMenu(void)
553 return; 574 return;
554 setRootMenu(menu_get_parent_menu(rootEntry->parent)); 575 setRootMenu(menu_get_parent_menu(rootEntry->parent));
555 576
556 QListViewItemIterator it(this); 577 Q3ListViewItemIterator it(this);
557 for (; (item = (ConfigItem*)it.current()); it++) { 578 for (; (item = (ConfigItem*)it.current()); it++) {
558 if (item->menu == oldroot) { 579 if (item->menu == oldroot) {
559 setCurrentItem(item); 580 setCurrentItem(item);
@@ -606,7 +627,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
606 } 627 }
607 628
608 visible = menu_is_visible(child); 629 visible = menu_is_visible(child);
609 if (showAll || visible) { 630 if (!menuSkip(child)) {
610 if (!child->sym && !child->list && !child->prompt) 631 if (!child->sym && !child->list && !child->prompt)
611 continue; 632 continue;
612 if (!item || item->menu != child) 633 if (!item || item->menu != child)
@@ -635,7 +656,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
635 656
636void ConfigList::keyPressEvent(QKeyEvent* ev) 657void ConfigList::keyPressEvent(QKeyEvent* ev)
637{ 658{
638 QListViewItem* i = currentItem(); 659 Q3ListViewItem* i = currentItem();
639 ConfigItem* item; 660 ConfigItem* item;
640 struct menu *menu; 661 struct menu *menu;
641 enum prop_type type; 662 enum prop_type type;
@@ -801,10 +822,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
801{ 822{
802 if (e->y() <= header()->geometry().bottom()) { 823 if (e->y() <= header()->geometry().bottom()) {
803 if (!headerPopup) { 824 if (!headerPopup) {
804 QAction *action; 825 Q3Action *action;
805 826
806 headerPopup = new QPopupMenu(this); 827 headerPopup = new Q3PopupMenu(this);
807 action = new QAction(NULL, _("Show Name"), 0, this); 828 action = new Q3Action(NULL, _("Show Name"), 0, this);
808 action->setToggleAction(TRUE); 829 action->setToggleAction(TRUE);
809 connect(action, SIGNAL(toggled(bool)), 830 connect(action, SIGNAL(toggled(bool)),
810 parent(), SLOT(setShowName(bool))); 831 parent(), SLOT(setShowName(bool)));
@@ -812,7 +833,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
812 action, SLOT(setOn(bool))); 833 action, SLOT(setOn(bool)));
813 action->setOn(showName); 834 action->setOn(showName);
814 action->addTo(headerPopup); 835 action->addTo(headerPopup);
815 action = new QAction(NULL, _("Show Range"), 0, this); 836 action = new Q3Action(NULL, _("Show Range"), 0, this);
816 action->setToggleAction(TRUE); 837 action->setToggleAction(TRUE);
817 connect(action, SIGNAL(toggled(bool)), 838 connect(action, SIGNAL(toggled(bool)),
818 parent(), SLOT(setShowRange(bool))); 839 parent(), SLOT(setShowRange(bool)));
@@ -820,7 +841,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
820 action, SLOT(setOn(bool))); 841 action, SLOT(setOn(bool)));
821 action->setOn(showRange); 842 action->setOn(showRange);
822 action->addTo(headerPopup); 843 action->addTo(headerPopup);
823 action = new QAction(NULL, _("Show Data"), 0, this); 844 action = new Q3Action(NULL, _("Show Data"), 0, this);
824 action->setToggleAction(TRUE); 845 action->setToggleAction(TRUE);
825 connect(action, SIGNAL(toggled(bool)), 846 connect(action, SIGNAL(toggled(bool)),
826 parent(), SLOT(setShowData(bool))); 847 parent(), SLOT(setShowData(bool)));
@@ -835,7 +856,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
835 e->ignore(); 856 e->ignore();
836} 857}
837 858
838ConfigView* ConfigView::viewList; 859ConfigView*ConfigView::viewList;
860QAction *ConfigView::showNormalAction;
861QAction *ConfigView::showAllAction;
862QAction *ConfigView::showPromptAction;
839 863
840ConfigView::ConfigView(QWidget* parent, const char *name) 864ConfigView::ConfigView(QWidget* parent, const char *name)
841 : Parent(parent, name) 865 : Parent(parent, name)
@@ -860,13 +884,16 @@ ConfigView::~ConfigView(void)
860 } 884 }
861} 885}
862 886
863void ConfigView::setShowAll(bool b) 887void ConfigView::setOptionMode(QAction *act)
864{ 888{
865 if (list->showAll != b) { 889 if (act == showNormalAction)
866 list->showAll = b; 890 list->optMode = normalOpt;
867 list->updateListAll(); 891 else if (act == showAllAction)
868 emit showAllChanged(b); 892 list->optMode = allOpt;
869 } 893 else
894 list->optMode = promptOpt;
895
896 list->updateListAll();
870} 897}
871 898
872void ConfigView::setShowName(bool b) 899void ConfigView::setShowName(bool b)
@@ -898,7 +925,7 @@ void ConfigView::setShowData(bool b)
898 925
899void ConfigList::setAllOpen(bool open) 926void ConfigList::setAllOpen(bool open)
900{ 927{
901 QListViewItemIterator it(this); 928 Q3ListViewItemIterator it(this);
902 929
903 for (; it.current(); it++) 930 for (; it.current(); it++)
904 it.current()->setOpen(open); 931 it.current()->setOpen(open);
@@ -921,7 +948,7 @@ void ConfigView::updateListAll(void)
921} 948}
922 949
923ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) 950ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
924 : Parent(parent, name), sym(0), menu(0) 951 : Parent(parent, name), sym(0), _menu(0)
925{ 952{
926 if (name) { 953 if (name) {
927 configSettings->beginGroup(name); 954 configSettings->beginGroup(name);
@@ -944,7 +971,7 @@ void ConfigInfoView::setShowDebug(bool b)
944{ 971{
945 if (_showDebug != b) { 972 if (_showDebug != b) {
946 _showDebug = b; 973 _showDebug = b;
947 if (menu) 974 if (_menu)
948 menuInfo(); 975 menuInfo();
949 else if (sym) 976 else if (sym)
950 symbolInfo(); 977 symbolInfo();
@@ -954,44 +981,16 @@ void ConfigInfoView::setShowDebug(bool b)
954 981
955void ConfigInfoView::setInfo(struct menu *m) 982void ConfigInfoView::setInfo(struct menu *m)
956{ 983{
957 if (menu == m) 984 if (_menu == m)
958 return; 985 return;
959 menu = m; 986 _menu = m;
960 sym = NULL; 987 sym = NULL;
961 if (!menu) 988 if (!_menu)
962 clear(); 989 clear();
963 else 990 else
964 menuInfo(); 991 menuInfo();
965} 992}
966 993
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) 994void ConfigInfoView::symbolInfo(void)
996{ 995{
997 QString str; 996 QString str;
@@ -1013,11 +1012,11 @@ void ConfigInfoView::menuInfo(void)
1013 struct symbol* sym; 1012 struct symbol* sym;
1014 QString head, debug, help; 1013 QString head, debug, help;
1015 1014
1016 sym = menu->sym; 1015 sym = _menu->sym;
1017 if (sym) { 1016 if (sym) {
1018 if (menu->prompt) { 1017 if (_menu->prompt) {
1019 head += "<big><b>"; 1018 head += "<big><b>";
1020 head += print_filter(_(menu->prompt->text)); 1019 head += print_filter(_(_menu->prompt->text));
1021 head += "</b></big>"; 1020 head += "</b></big>";
1022 if (sym->name) { 1021 if (sym->name) {
1023 head += " ("; 1022 head += " (";
@@ -1042,26 +1041,24 @@ void ConfigInfoView::menuInfo(void)
1042 if (showDebug()) 1041 if (showDebug())
1043 debug = debug_info(sym); 1042 debug = debug_info(sym);
1044 1043
1045 help = menu_get_help(menu); 1044 struct gstr help_gstr = str_new();
1046 /* Gettextize if the help text not empty */ 1045 menu_get_ext_help(_menu, &help_gstr);
1047 if (help.isEmpty()) 1046 help = print_filter(str_get(&help_gstr));
1048 help = print_filter(menu_get_help(menu)); 1047 str_free(&help_gstr);
1049 else 1048 } else if (_menu->prompt) {
1050 help = print_filter(_(menu_get_help(menu)));
1051 } else if (menu->prompt) {
1052 head += "<big><b>"; 1049 head += "<big><b>";
1053 head += print_filter(_(menu->prompt->text)); 1050 head += print_filter(_(_menu->prompt->text));
1054 head += "</b></big><br><br>"; 1051 head += "</b></big><br><br>";
1055 if (showDebug()) { 1052 if (showDebug()) {
1056 if (menu->prompt->visible.expr) { 1053 if (_menu->prompt->visible.expr) {
1057 debug += "&nbsp;&nbsp;dep: "; 1054 debug += "&nbsp;&nbsp;dep: ";
1058 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); 1055 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1059 debug += "<br><br>"; 1056 debug += "<br><br>";
1060 } 1057 }
1061 } 1058 }
1062 } 1059 }
1063 if (showDebug()) 1060 if (showDebug())
1064 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno); 1061 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1065 1062
1066 setText(head + debug + help); 1063 setText(head + debug + help);
1067} 1064}
@@ -1164,10 +1161,10 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
1164 *text += str2; 1161 *text += str2;
1165} 1162}
1166 1163
1167QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) 1164Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1168{ 1165{
1169 QPopupMenu* popup = Parent::createPopupMenu(pos); 1166 Q3PopupMenu* popup = Parent::createPopupMenu(pos);
1170 QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup); 1167 Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
1171 action->setToggleAction(TRUE); 1168 action->setToggleAction(TRUE);
1172 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); 1169 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1173 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); 1170 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1224,7 +1221,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
1224 y = configSettings->readNumEntry("/window y", 0, &ok); 1221 y = configSettings->readNumEntry("/window y", 0, &ok);
1225 if (ok) 1222 if (ok)
1226 move(x, y); 1223 move(x, y);
1227 QValueList<int> sizes = configSettings->readSizes("/split", &ok); 1224 Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
1228 if (ok) 1225 if (ok)
1229 split->setSizes(sizes); 1226 split->setSizes(sizes);
1230 configSettings->endGroup(); 1227 configSettings->endGroup();
@@ -1277,8 +1274,14 @@ ConfigMainWindow::ConfigMainWindow(void)
1277 char title[256]; 1274 char title[256];
1278 1275
1279 QDesktopWidget *d = configApp->desktop(); 1276 QDesktopWidget *d = configApp->desktop();
1280 snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"), 1277 snprintf(title, sizeof(title), "%s%s",
1281 getenv("KERNELVERSION")); 1278 rootmenu.prompt->text,
1279#if QT_VERSION < 0x040000
1280 " (Qt3)"
1281#else
1282 ""
1283#endif
1284 );
1282 setCaption(title); 1285 setCaption(title);
1283 1286
1284 width = configSettings->readNumEntry("/window width", d->width() - 64); 1287 width = configSettings->readNumEntry("/window width", d->width() - 64);
@@ -1311,60 +1314,79 @@ ConfigMainWindow::ConfigMainWindow(void)
1311 configList->setFocus(); 1314 configList->setFocus();
1312 1315
1313 menu = menuBar(); 1316 menu = menuBar();
1314 toolBar = new QToolBar("Tools", this); 1317 toolBar = new Q3ToolBar("Tools", this);
1315 1318
1316 backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this); 1319 backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
1317 connect(backAction, SIGNAL(activated()), SLOT(goBack())); 1320 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1318 backAction->setEnabled(FALSE); 1321 backAction->setEnabled(FALSE);
1319 QAction *quitAction = new QAction("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this); 1322 Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1320 connect(quitAction, SIGNAL(activated()), SLOT(close())); 1323 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1321 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this); 1324 Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1322 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); 1325 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1323 saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this); 1326 saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1324 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); 1327 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1325 conf_set_changed_callback(conf_changed); 1328 conf_set_changed_callback(conf_changed);
1326 // Set saveAction's initial state 1329 // Set saveAction's initial state
1327 conf_changed(); 1330 conf_changed();
1328 QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this); 1331 Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
1329 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); 1332 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1330 QAction *searchAction = new QAction("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this); 1333 Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1331 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig())); 1334 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1332 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this); 1335 Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1333 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); 1336 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1334 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this); 1337 Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1335 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); 1338 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1336 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this); 1339 Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1337 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); 1340 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1338 1341
1339 QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this); 1342 Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
1340 showNameAction->setToggleAction(TRUE); 1343 showNameAction->setToggleAction(TRUE);
1341 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); 1344 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1342 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool))); 1345 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1343 showNameAction->setOn(configView->showName()); 1346 showNameAction->setOn(configView->showName());
1344 QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this); 1347 Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
1345 showRangeAction->setToggleAction(TRUE); 1348 showRangeAction->setToggleAction(TRUE);
1346 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); 1349 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1347 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool))); 1350 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1348 showRangeAction->setOn(configList->showRange); 1351 showRangeAction->setOn(configList->showRange);
1349 QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this); 1352 Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
1350 showDataAction->setToggleAction(TRUE); 1353 showDataAction->setToggleAction(TRUE);
1351 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); 1354 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1352 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); 1355 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1353 showDataAction->setOn(configList->showData); 1356 showDataAction->setOn(configList->showData);
1354 QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this); 1357
1355 showAllAction->setToggleAction(TRUE); 1358 QActionGroup *optGroup = new QActionGroup(this);
1356 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); 1359 optGroup->setExclusive(TRUE);
1357 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); 1360 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1358 showAllAction->setOn(configList->showAll); 1361 SLOT(setOptionMode(QAction *)));
1359 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); 1362 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1363 SLOT(setOptionMode(QAction *)));
1364
1365#if QT_VERSION >= 0x040000
1366 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1367 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1368 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1369#else
1370 configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
1371 configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
1372 configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
1373#endif
1374 configView->showNormalAction->setToggleAction(TRUE);
1375 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1376 configView->showAllAction->setToggleAction(TRUE);
1377 configView->showAllAction->setOn(configList->optMode == allOpt);
1378 configView->showPromptAction->setToggleAction(TRUE);
1379 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1380
1381 Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
1360 showDebugAction->setToggleAction(TRUE); 1382 showDebugAction->setToggleAction(TRUE);
1361 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); 1383 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1362 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); 1384 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1363 showDebugAction->setOn(helpText->showDebug()); 1385 showDebugAction->setOn(helpText->showDebug());
1364 1386
1365 QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this); 1387 Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
1366 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); 1388 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1367 QAction *showAboutAction = new QAction(NULL, _("About"), 0, this); 1389 Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
1368 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); 1390 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1369 1391
1370 // init tool bar 1392 // init tool bar
@@ -1378,7 +1400,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1378 fullViewAction->addTo(toolBar); 1400 fullViewAction->addTo(toolBar);
1379 1401
1380 // create config menu 1402 // create config menu
1381 QPopupMenu* config = new QPopupMenu(this); 1403 Q3PopupMenu* config = new Q3PopupMenu(this);
1382 menu->insertItem(_("&File"), config); 1404 menu->insertItem(_("&File"), config);
1383 loadAction->addTo(config); 1405 loadAction->addTo(config);
1384 saveAction->addTo(config); 1406 saveAction->addTo(config);
@@ -1387,22 +1409,22 @@ ConfigMainWindow::ConfigMainWindow(void)
1387 quitAction->addTo(config); 1409 quitAction->addTo(config);
1388 1410
1389 // create edit menu 1411 // create edit menu
1390 QPopupMenu* editMenu = new QPopupMenu(this); 1412 Q3PopupMenu* editMenu = new Q3PopupMenu(this);
1391 menu->insertItem(_("&Edit"), editMenu); 1413 menu->insertItem(_("&Edit"), editMenu);
1392 searchAction->addTo(editMenu); 1414 searchAction->addTo(editMenu);
1393 1415
1394 // create options menu 1416 // create options menu
1395 QPopupMenu* optionMenu = new QPopupMenu(this); 1417 Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
1396 menu->insertItem(_("&Option"), optionMenu); 1418 menu->insertItem(_("&Option"), optionMenu);
1397 showNameAction->addTo(optionMenu); 1419 showNameAction->addTo(optionMenu);
1398 showRangeAction->addTo(optionMenu); 1420 showRangeAction->addTo(optionMenu);
1399 showDataAction->addTo(optionMenu); 1421 showDataAction->addTo(optionMenu);
1400 optionMenu->insertSeparator(); 1422 optionMenu->insertSeparator();
1401 showAllAction->addTo(optionMenu); 1423 optGroup->addTo(optionMenu);
1402 showDebugAction->addTo(optionMenu); 1424 optionMenu->insertSeparator();
1403 1425
1404 // create help menu 1426 // create help menu
1405 QPopupMenu* helpMenu = new QPopupMenu(this); 1427 Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
1406 menu->insertSeparator(); 1428 menu->insertSeparator();
1407 menu->insertItem(_("&Help"), helpMenu); 1429 menu->insertItem(_("&Help"), helpMenu);
1408 showIntroAction->addTo(helpMenu); 1430 showIntroAction->addTo(helpMenu);
@@ -1437,7 +1459,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1437 showSplitView(); 1459 showSplitView();
1438 1460
1439 // UI setup done, restore splitter positions 1461 // UI setup done, restore splitter positions
1440 QValueList<int> sizes = configSettings->readSizes("/split1", &ok); 1462 Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1441 if (ok) 1463 if (ok)
1442 split1->setSizes(sizes); 1464 split1->setSizes(sizes);
1443 1465
@@ -1448,7 +1470,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1448 1470
1449void ConfigMainWindow::loadConfig(void) 1471void ConfigMainWindow::loadConfig(void)
1450{ 1472{
1451 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this); 1473 QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1452 if (s.isNull()) 1474 if (s.isNull())
1453 return; 1475 return;
1454 if (conf_read(QFile::encodeName(s))) 1476 if (conf_read(QFile::encodeName(s)))
@@ -1464,7 +1486,7 @@ void ConfigMainWindow::saveConfig(void)
1464 1486
1465void ConfigMainWindow::saveConfigAs(void) 1487void ConfigMainWindow::saveConfigAs(void)
1466{ 1488{
1467 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this); 1489 QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1468 if (s.isNull()) 1490 if (s.isNull())
1469 return; 1491 return;
1470 if (conf_write(QFile::encodeName(s))) 1492 if (conf_write(QFile::encodeName(s)))
@@ -1493,7 +1515,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
1493 ConfigList* list = NULL; 1515 ConfigList* list = NULL;
1494 ConfigItem* item; 1516 ConfigItem* item;
1495 1517
1496 if (!menu_is_visible(menu) && !configView->showAll()) 1518 if (configList->menuSkip(menu))
1497 return; 1519 return;
1498 1520
1499 switch (configList->mode) { 1521 switch (configList->mode) {
@@ -1633,7 +1655,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
1633 1655
1634void ConfigMainWindow::showIntro(void) 1656void ConfigMainWindow::showIntro(void)
1635{ 1657{
1636 static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n" 1658 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1637 "For each option, a blank box indicates the feature is disabled, a check\n" 1659 "For each option, a blank box indicates the feature is disabled, a check\n"
1638 "indicates it is enabled, and a dot indicates that it is to be compiled\n" 1660 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1639 "as a module. Clicking on the box will cycle through the three states.\n\n" 1661 "as a module. Clicking on the box will cycle through the three states.\n\n"
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index b3b5657b6b35..91677d900dbd 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -3,26 +3,25 @@
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#if QT_VERSION < 0x040000
6#include <qlistview.h> 7#include <qlistview.h>
7#if QT_VERSION >= 300
8#include <qsettings.h>
9#else 8#else
10class QSettings { 9#include <q3listview.h>
11public: 10#endif
12 void beginGroup(const QString& group) { } 11#include <qsettings.h>
13 void endGroup(void) { } 12
14 bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const 13#if QT_VERSION < 0x040000
15 { if (ok) *ok = FALSE; return def; } 14#define Q3ValueList QValueList
16 int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const 15#define Q3PopupMenu QPopupMenu
17 { if (ok) *ok = FALSE; return def; } 16#define Q3ListView QListView
18 QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const 17#define Q3ListViewItem QListViewItem
19 { if (ok) *ok = FALSE; return def; } 18#define Q3VBox QVBox
20 QStringList readListEntry(const QString& key, bool* ok = 0) const 19#define Q3TextBrowser QTextBrowser
21 { if (ok) *ok = FALSE; return QStringList(); } 20#define Q3MainWindow QMainWindow
22 template <class t> 21#define Q3Action QAction
23 bool writeEntry(const QString& key, t value) 22#define Q3ToolBar QToolBar
24 { return TRUE; } 23#define Q3ListViewItemIterator QListViewItemIterator
25}; 24#define Q3FileDialog QFileDialog
26#endif 25#endif
27 26
28class ConfigView; 27class ConfigView;
@@ -31,11 +30,10 @@ class ConfigItem;
31class ConfigLineEdit; 30class ConfigLineEdit;
32class ConfigMainWindow; 31class ConfigMainWindow;
33 32
34
35class ConfigSettings : public QSettings { 33class ConfigSettings : public QSettings {
36public: 34public:
37 QValueList<int> readSizes(const QString& key, bool *ok); 35 Q3ValueList<int> readSizes(const QString& key, bool *ok);
38 bool writeSizes(const QString& key, const QValueList<int>& value); 36 bool writeSizes(const QString& key, const Q3ValueList<int>& value);
39}; 37};
40 38
41enum colIdx { 39enum colIdx {
@@ -44,10 +42,13 @@ enum colIdx {
44enum listMode { 42enum listMode {
45 singleMode, menuMode, symbolMode, fullMode, listMode 43 singleMode, menuMode, symbolMode, fullMode, listMode
46}; 44};
45enum optionMode {
46 normalOpt = 0, allOpt, promptOpt
47};
47 48
48class ConfigList : public QListView { 49class ConfigList : public Q3ListView {
49 Q_OBJECT 50 Q_OBJECT
50 typedef class QListView Parent; 51 typedef class Q3ListView Parent;
51public: 52public:
52 ConfigList(ConfigView* p, const char *name = 0); 53 ConfigList(ConfigView* p, const char *name = 0);
53 void reinit(void); 54 void reinit(void);
@@ -115,6 +116,8 @@ public:
115 void setAllOpen(bool open); 116 void setAllOpen(bool open);
116 void setParentMenu(void); 117 void setParentMenu(void);
117 118
119 bool menuSkip(struct menu *);
120
118 template <class P> 121 template <class P>
119 void updateMenuList(P*, struct menu*); 122 void updateMenuList(P*, struct menu*);
120 123
@@ -124,22 +127,23 @@ public:
124 QPixmap choiceYesPix, choiceNoPix; 127 QPixmap choiceYesPix, choiceNoPix;
125 QPixmap menuPix, menuInvPix, menuBackPix, voidPix; 128 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
126 129
127 bool showAll, showName, showRange, showData; 130 bool showName, showRange, showData;
128 enum listMode mode; 131 enum listMode mode;
132 enum optionMode optMode;
129 struct menu *rootEntry; 133 struct menu *rootEntry;
130 QColorGroup disabledColorGroup; 134 QColorGroup disabledColorGroup;
131 QColorGroup inactivedColorGroup; 135 QColorGroup inactivedColorGroup;
132 QPopupMenu* headerPopup; 136 Q3PopupMenu* headerPopup;
133 137
134private: 138private:
135 int colMap[colNr]; 139 int colMap[colNr];
136 int colRevMap[colNr]; 140 int colRevMap[colNr];
137}; 141};
138 142
139class ConfigItem : public QListViewItem { 143class ConfigItem : public Q3ListViewItem {
140 typedef class QListViewItem Parent; 144 typedef class Q3ListViewItem Parent;
141public: 145public:
142 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) 146 ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v)
143 : Parent(parent, after), menu(m), visible(v), goParent(false) 147 : Parent(parent, after), menu(m), visible(v), goParent(false)
144 { 148 {
145 init(); 149 init();
@@ -149,16 +153,14 @@ public:
149 { 153 {
150 init(); 154 init();
151 } 155 }
152 ConfigItem(QListView *parent, ConfigItem *after, bool v) 156 ConfigItem(Q3ListView *parent, ConfigItem *after, bool v)
153 : Parent(parent, after), menu(0), visible(v), goParent(true) 157 : Parent(parent, after), menu(0), visible(v), goParent(true)
154 { 158 {
155 init(); 159 init();
156 } 160 }
157 ~ConfigItem(void); 161 ~ConfigItem(void);
158 void init(void); 162 void init(void);
159#if QT_VERSION >= 300
160 void okRename(int col); 163 void okRename(int col);
161#endif
162 void updateMenu(void); 164 void updateMenu(void);
163 void testUpdateMenu(bool v); 165 void testUpdateMenu(bool v);
164 ConfigList* listView() const 166 ConfigList* listView() const
@@ -213,26 +215,24 @@ public:
213 ConfigItem *item; 215 ConfigItem *item;
214}; 216};
215 217
216class ConfigView : public QVBox { 218class ConfigView : public Q3VBox {
217 Q_OBJECT 219 Q_OBJECT
218 typedef class QVBox Parent; 220 typedef class Q3VBox Parent;
219public: 221public:
220 ConfigView(QWidget* parent, const char *name = 0); 222 ConfigView(QWidget* parent, const char *name = 0);
221 ~ConfigView(void); 223 ~ConfigView(void);
222 static void updateList(ConfigItem* item); 224 static void updateList(ConfigItem* item);
223 static void updateListAll(void); 225 static void updateListAll(void);
224 226
225 bool showAll(void) const { return list->showAll; }
226 bool showName(void) const { return list->showName; } 227 bool showName(void) const { return list->showName; }
227 bool showRange(void) const { return list->showRange; } 228 bool showRange(void) const { return list->showRange; }
228 bool showData(void) const { return list->showData; } 229 bool showData(void) const { return list->showData; }
229public slots: 230public slots:
230 void setShowAll(bool);
231 void setShowName(bool); 231 void setShowName(bool);
232 void setShowRange(bool); 232 void setShowRange(bool);
233 void setShowData(bool); 233 void setShowData(bool);
234 void setOptionMode(QAction *);
234signals: 235signals:
235 void showAllChanged(bool);
236 void showNameChanged(bool); 236 void showNameChanged(bool);
237 void showRangeChanged(bool); 237 void showRangeChanged(bool);
238 void showDataChanged(bool); 238 void showDataChanged(bool);
@@ -242,11 +242,15 @@ public:
242 242
243 static ConfigView* viewList; 243 static ConfigView* viewList;
244 ConfigView* nextView; 244 ConfigView* nextView;
245
246 static QAction *showNormalAction;
247 static QAction *showAllAction;
248 static QAction *showPromptAction;
245}; 249};
246 250
247class ConfigInfoView : public QTextBrowser { 251class ConfigInfoView : public Q3TextBrowser {
248 Q_OBJECT 252 Q_OBJECT
249 typedef class QTextBrowser Parent; 253 typedef class Q3TextBrowser Parent;
250public: 254public:
251 ConfigInfoView(QWidget* parent, const char *name = 0); 255 ConfigInfoView(QWidget* parent, const char *name = 0);
252 bool showDebug(void) const { return _showDebug; } 256 bool showDebug(void) const { return _showDebug; }
@@ -254,7 +258,6 @@ public:
254public slots: 258public slots:
255 void setInfo(struct menu *menu); 259 void setInfo(struct menu *menu);
256 void saveSettings(void); 260 void saveSettings(void);
257 void setSource(const QString& name);
258 void setShowDebug(bool); 261 void setShowDebug(bool);
259 262
260signals: 263signals:
@@ -267,11 +270,11 @@ protected:
267 QString debug_info(struct symbol *sym); 270 QString debug_info(struct symbol *sym);
268 static QString print_filter(const QString &str); 271 static QString print_filter(const QString &str);
269 static void expr_print_help(void *data, struct symbol *sym, const char *str); 272 static void expr_print_help(void *data, struct symbol *sym, const char *str);
270 QPopupMenu* createPopupMenu(const QPoint& pos); 273 Q3PopupMenu* createPopupMenu(const QPoint& pos);
271 void contentsContextMenuEvent(QContextMenuEvent *e); 274 void contentsContextMenuEvent(QContextMenuEvent *e);
272 275
273 struct symbol *sym; 276 struct symbol *sym;
274 struct menu *menu; 277 struct menu *_menu;
275 bool _showDebug; 278 bool _showDebug;
276}; 279};
277 280
@@ -295,10 +298,10 @@ protected:
295 struct symbol **result; 298 struct symbol **result;
296}; 299};
297 300
298class ConfigMainWindow : public QMainWindow { 301class ConfigMainWindow : public Q3MainWindow {
299 Q_OBJECT 302 Q_OBJECT
300 303
301 static QAction *saveAction; 304 static Q3Action *saveAction;
302 static void conf_changed(void); 305 static void conf_changed(void);
303public: 306public:
304 ConfigMainWindow(void); 307 ConfigMainWindow(void);
@@ -327,8 +330,8 @@ protected:
327 ConfigView *configView; 330 ConfigView *configView;
328 ConfigList *configList; 331 ConfigList *configList;
329 ConfigInfoView *helpText; 332 ConfigInfoView *helpText;
330 QToolBar *toolBar; 333 Q3ToolBar *toolBar;
331 QAction *backAction; 334 Q3Action *backAction;
332 QSplitter* split1; 335 QSplitter* split1;
333 QSplitter* split2; 336 QSplitter* split2;
334}; 337};
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
new file mode 100644
index 000000000000..fd81fc33d633
--- /dev/null
+++ b/scripts/kconfig/streamline_config.pl
@@ -0,0 +1,451 @@
1#!/usr/bin/perl -w
2#
3# Copywrite 2005-2009 - Steven Rostedt
4# Licensed under the terms of the GNU GPL License version 2
5#
6# It's simple enough to figure out how this works.
7# If not, then you can ask me at stripconfig@goodmis.org
8#
9# What it does?
10#
11# If you have installed a Linux kernel from a distribution
12# that turns on way too many modules than you need, and
13# you only want the modules you use, then this program
14# is perfect for you.
15#
16# It gives you the ability to turn off all the modules that are
17# not loaded on your system.
18#
19# Howto:
20#
21# 1. Boot up the kernel that you want to stream line the config on.
22# 2. Change directory to the directory holding the source of the
23# kernel that you just booted.
24# 3. Copy the configuraton file to this directory as .config
25# 4. Have all your devices that you need modules for connected and
26# operational (make sure that their corresponding modules are loaded)
27# 5. Run this script redirecting the output to some other file
28# like config_strip.
29# 6. Back up your old config (if you want too).
30# 7. copy the config_strip file to .config
31# 8. Run "make oldconfig"
32#
33# Now your kernel is ready to be built with only the modules that
34# are loaded.
35#
36# Here's what I did with my Debian distribution.
37#
38# cd /usr/src/linux-2.6.10
39# cp /boot/config-2.6.10-1-686-smp .config
40# ~/bin/streamline_config > config_strip
41# mv .config config_sav
42# mv config_strip .config
43# make oldconfig
44#
45use strict;
46
47my $config = ".config";
48
49my $uname = `uname -r`;
50chomp $uname;
51
52my @searchconfigs = (
53 {
54 "file" => ".config",
55 "exec" => "cat",
56 },
57 {
58 "file" => "/proc/config.gz",
59 "exec" => "zcat",
60 },
61 {
62 "file" => "/boot/config-$uname",
63 "exec" => "cat",
64 },
65 {
66 "file" => "/boot/vmlinuz-$uname",
67 "exec" => "scripts/extract-ikconfig",
68 "test" => "scripts/extract-ikconfig",
69 },
70 {
71 "file" => "vmlinux",
72 "exec" => "scripts/extract-ikconfig",
73 "test" => "scripts/extract-ikconfig",
74 },
75 {
76 "file" => "/lib/modules/$uname/kernel/kernel/configs.ko",
77 "exec" => "scripts/extract-ikconfig",
78 "test" => "scripts/extract-ikconfig",
79 },
80 {
81 "file" => "kernel/configs.ko",
82 "exec" => "scripts/extract-ikconfig",
83 "test" => "scripts/extract-ikconfig",
84 },
85 {
86 "file" => "kernel/configs.o",
87 "exec" => "scripts/extract-ikconfig",
88 "test" => "scripts/extract-ikconfig",
89 },
90);
91
92sub find_config {
93 foreach my $conf (@searchconfigs) {
94 my $file = $conf->{"file"};
95
96 next if ( ! -f "$file");
97
98 if (defined($conf->{"test"})) {
99 `$conf->{"test"} $conf->{"file"} 2>/dev/null`;
100 next if ($?);
101 }
102
103 my $exec = $conf->{"exec"};
104
105 print STDERR "using config: '$file'\n";
106
107 open(CIN, "$exec $file |") || die "Failed to run $exec $file";
108 return;
109 }
110 die "No config file found";
111}
112
113find_config;
114
115# Get the build source and top level Kconfig file (passed in)
116my $ksource = $ARGV[0];
117my $kconfig = $ARGV[1];
118my $lsmod_file = $ARGV[2];
119
120my @makefiles = `find $ksource -name Makefile 2>/dev/null`;
121chomp @makefiles;
122
123my %depends;
124my %selects;
125my %prompts;
126my %objects;
127my $var;
128my $iflevel = 0;
129my @ifdeps;
130
131# prevent recursion
132my %read_kconfigs;
133
134sub read_kconfig {
135 my ($kconfig) = @_;
136
137 my $state = "NONE";
138 my $config;
139 my @kconfigs;
140
141 my $cont = 0;
142 my $line;
143
144 my $source = "$ksource/$kconfig";
145 my $last_source = "";
146
147 # Check for any environment variables used
148 while ($source =~ /\$(\w+)/ && $last_source ne $source) {
149 my $env = $1;
150 $last_source = $source;
151 $source =~ s/\$$env/$ENV{$env}/;
152 }
153
154 open(KIN, "$source") || die "Can't open $kconfig";
155 while (<KIN>) {
156 chomp;
157
158 # Make sure that lines ending with \ continue
159 if ($cont) {
160 $_ = $line . " " . $_;
161 }
162
163 if (s/\\$//) {
164 $cont = 1;
165 $line = $_;
166 next;
167 }
168
169 $cont = 0;
170
171 # collect any Kconfig sources
172 if (/^source\s*"(.*)"/) {
173 $kconfigs[$#kconfigs+1] = $1;
174 }
175
176 # configs found
177 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
178 $state = "NEW";
179 $config = $2;
180
181 for (my $i = 0; $i < $iflevel; $i++) {
182 if ($i) {
183 $depends{$config} .= " " . $ifdeps[$i];
184 } else {
185 $depends{$config} = $ifdeps[$i];
186 }
187 $state = "DEP";
188 }
189
190 # collect the depends for the config
191 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
192 $state = "DEP";
193 $depends{$config} = $1;
194 } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) {
195 $depends{$config} .= " " . $1;
196
197 # Get the configs that select this config
198 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
199 if (defined($selects{$1})) {
200 $selects{$1} .= " " . $config;
201 } else {
202 $selects{$1} = $config;
203 }
204
205 # configs without prompts must be selected
206 } elsif ($state ne "NONE" && /^\s*tristate\s\S/) {
207 # note if the config has a prompt
208 $prompts{$config} = 1;
209
210 # Check for if statements
211 } elsif (/^if\s+(.*\S)\s*$/) {
212 my $deps = $1;
213 # remove beginning and ending non text
214 $deps =~ s/^[^a-zA-Z0-9_]*//;
215 $deps =~ s/[^a-zA-Z0-9_]*$//;
216
217 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
218
219 $ifdeps[$iflevel++] = join ':', @deps;
220
221 } elsif (/^endif/) {
222
223 $iflevel-- if ($iflevel);
224
225 # stop on "help"
226 } elsif (/^\s*help\s*$/) {
227 $state = "NONE";
228 }
229 }
230 close(KIN);
231
232 # read in any configs that were found.
233 foreach $kconfig (@kconfigs) {
234 if (!defined($read_kconfigs{$kconfig})) {
235 $read_kconfigs{$kconfig} = 1;
236 read_kconfig($kconfig);
237 }
238 }
239}
240
241if ($kconfig) {
242 read_kconfig($kconfig);
243}
244
245# Read all Makefiles to map the configs to the objects
246foreach my $makefile (@makefiles) {
247
248 my $cont = 0;
249
250 open(MIN,$makefile) || die "Can't open $makefile";
251 while (<MIN>) {
252 my $objs;
253
254 # is this a line after a line with a backslash?
255 if ($cont && /(\S.*)$/) {
256 $objs = $1;
257 }
258 $cont = 0;
259
260 # collect objects after obj-$(CONFIG_FOO_BAR)
261 if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) {
262 $var = $1;
263 $objs = $2;
264 }
265 if (defined($objs)) {
266 # test if the line ends with a backslash
267 if ($objs =~ m,(.*)\\$,) {
268 $objs = $1;
269 $cont = 1;
270 }
271
272 foreach my $obj (split /\s+/,$objs) {
273 $obj =~ s/-/_/g;
274 if ($obj =~ /(.*)\.o$/) {
275 # Objects may be enabled by more than one config.
276 # Store configs in an array.
277 my @arr;
278
279 if (defined($objects{$1})) {
280 @arr = @{$objects{$1}};
281 }
282
283 $arr[$#arr+1] = $var;
284
285 # The objects have a hash mapping to a reference
286 # of an array of configs.
287 $objects{$1} = \@arr;
288 }
289 }
290 }
291 }
292 close(MIN);
293}
294
295my %modules;
296
297if (defined($lsmod_file)) {
298 if ( ! -f $lsmod_file) {
299 die "$lsmod_file not found";
300 }
301 if ( -x $lsmod_file) {
302 # the file is executable, run it
303 open(LIN, "$lsmod_file|");
304 } else {
305 # Just read the contents
306 open(LIN, "$lsmod_file");
307 }
308} else {
309
310 # see what modules are loaded on this system
311 my $lsmod;
312
313 foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
314 if ( -x "$dir/lsmod" ) {
315 $lsmod = "$dir/lsmod";
316 last;
317 }
318}
319 if (!defined($lsmod)) {
320 # try just the path
321 $lsmod = "lsmod";
322 }
323
324 open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod";
325}
326
327while (<LIN>) {
328 next if (/^Module/); # Skip the first line.
329 if (/^(\S+)/) {
330 $modules{$1} = 1;
331 }
332}
333close (LIN);
334
335# add to the configs hash all configs that are needed to enable
336# a loaded module.
337my %configs;
338foreach my $module (keys(%modules)) {
339 if (defined($objects{$module})) {
340 my @arr = @{$objects{$module}};
341 foreach my $conf (@arr) {
342 $configs{$conf} = $module;
343 }
344 } else {
345 # Most likely, someone has a custom (binary?) module loaded.
346 print STDERR "$module config not found!!\n";
347 }
348}
349
350my $valid = "A-Za-z_0-9";
351my $repeat = 1;
352
353#
354# Note, we do not care about operands (like: &&, ||, !) we want to add any
355# config that is in the depend list of another config. This script does
356# not enable configs that are not already enabled. If we come across a
357# config A that depends on !B, we can still add B to the list of depends
358# to keep on. If A was on in the original config, B would not have been
359# and B would not be turned on by this script.
360#
361sub parse_config_dep_select
362{
363 my ($p) = @_;
364
365 while ($p =~ /[$valid]/) {
366
367 if ($p =~ /^[^$valid]*([$valid]+)/) {
368 my $conf = "CONFIG_" . $1;
369
370 $p =~ s/^[^$valid]*[$valid]+//;
371
372 if (!defined($configs{$conf})) {
373 # We must make sure that this config has its
374 # dependencies met.
375 $repeat = 1; # do again
376 $configs{$conf} = 1;
377 }
378 } else {
379 die "this should never happen";
380 }
381 }
382}
383
384while ($repeat) {
385 $repeat = 0;
386
387 foreach my $config (keys %configs) {
388 $config =~ s/^CONFIG_//;
389
390 if (defined($depends{$config})) {
391 # This config has dependencies. Make sure they are also included
392 parse_config_dep_select $depends{$config};
393 }
394
395 if (defined($prompts{$config}) || !defined($selects{$config})) {
396 next;
397 }
398
399 # config has no prompt and must be selected.
400 parse_config_dep_select $selects{$config};
401 }
402}
403
404my %setconfigs;
405
406# Finally, read the .config file and turn off any module enabled that
407# we could not find a reason to keep enabled.
408while(<CIN>) {
409
410 if (/CONFIG_IKCONFIG/) {
411 if (/# CONFIG_IKCONFIG is not set/) {
412 # enable IKCONFIG at least as a module
413 print "CONFIG_IKCONFIG=m\n";
414 # don't ask about PROC
415 print "# CONFIG_IKCONFIG_PROC is not set\n";
416 } else {
417 print;
418 }
419 next;
420 }
421
422 if (/^(CONFIG.*)=(m|y)/) {
423 if (defined($configs{$1})) {
424 $setconfigs{$1} = $2;
425 } elsif ($2 eq "m") {
426 print "# $1 is not set\n";
427 next;
428 }
429 }
430 print;
431}
432close(CIN);
433
434# Integrity check, make sure all modules that we want enabled do
435# indeed have their configs set.
436loop:
437foreach my $module (keys(%modules)) {
438 if (defined($objects{$module})) {
439 my @arr = @{$objects{$module}};
440 foreach my $conf (@arr) {
441 if (defined($setconfigs{$conf})) {
442 next loop;
443 }
444 }
445 print STDERR "module $module did not have configs";
446 foreach my $conf (@arr) {
447 print STDERR " " , $conf;
448 }
449 print STDERR "\n";
450 }
451}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 18f3e5c33634..a796c95fe8a0 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -36,7 +36,7 @@ tristate modules_val;
36 36
37struct expr *sym_env_list; 37struct expr *sym_env_list;
38 38
39void sym_add_default(struct symbol *sym, const char *def) 39static void sym_add_default(struct symbol *sym, const char *def)
40{ 40{
41 struct property *prop = prop_alloc(P_DEFAULT, sym); 41 struct property *prop = prop_alloc(P_DEFAULT, sym);
42 42
@@ -125,7 +125,7 @@ struct property *sym_get_default_prop(struct symbol *sym)
125 return NULL; 125 return NULL;
126} 126}
127 127
128struct property *sym_get_range_prop(struct symbol *sym) 128static struct property *sym_get_range_prop(struct symbol *sym)
129{ 129{
130 struct property *prop; 130 struct property *prop;
131 131
@@ -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,18 @@ void sym_calc_value(struct symbol *sym)
321 } 350 }
322 } 351 }
323 calc_newval: 352 calc_newval:
353 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
354 struct expr *e;
355 e = expr_simplify_unmet_dep(sym->rev_dep.expr,
356 sym->dir_dep.expr);
357 fprintf(stderr, "warning: (");
358 expr_fprint(e, stderr);
359 fprintf(stderr, ") selects %s which has unmet direct dependencies (",
360 sym->name);
361 expr_fprint(sym->dir_dep.expr, stderr);
362 fprintf(stderr, ")\n");
363 expr_free(e);
364 }
324 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); 365 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
325 } 366 }
326 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) 367 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
@@ -365,12 +406,13 @@ void sym_calc_value(struct symbol *sym)
365 406
366 if (sym_is_choice(sym)) { 407 if (sym_is_choice(sym)) {
367 struct symbol *choice_sym; 408 struct symbol *choice_sym;
368 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
369 409
370 prop = sym_get_choice_prop(sym); 410 prop = sym_get_choice_prop(sym);
371 expr_list_for_each_sym(prop->expr, e, choice_sym) { 411 expr_list_for_each_sym(prop->expr, e, choice_sym) {
372 choice_sym->flags |= flags; 412 if ((sym->flags & SYMBOL_WRITE) &&
373 if (flags & SYMBOL_CHANGED) 413 choice_sym->visible != no)
414 choice_sym->flags |= SYMBOL_WRITE;
415 if (sym->flags & SYMBOL_CHANGED)
374 sym_set_changed(choice_sym); 416 sym_set_changed(choice_sym);
375 } 417 }
376 } 418 }
@@ -623,6 +665,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
623 return true; 665 return true;
624} 666}
625 667
668/*
669 * Find the default value associated to a symbol.
670 * For tristate symbol handle the modules=n case
671 * in which case "m" becomes "y".
672 * If the symbol does not have any default then fallback
673 * to the fixed default values.
674 */
675const char *sym_get_string_default(struct symbol *sym)
676{
677 struct property *prop;
678 struct symbol *ds;
679 const char *str;
680 tristate val;
681
682 sym_calc_visibility(sym);
683 sym_calc_value(modules_sym);
684 val = symbol_no.curr.tri;
685 str = symbol_empty.curr.val;
686
687 /* If symbol has a default value look it up */
688 prop = sym_get_default_prop(sym);
689 if (prop != NULL) {
690 switch (sym->type) {
691 case S_BOOLEAN:
692 case S_TRISTATE:
693 /* The visibility may limit the value from yes => mod */
694 val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
695 break;
696 default:
697 /*
698 * The following fails to handle the situation
699 * where a default value is further limited by
700 * the valid range.
701 */
702 ds = prop_get_symbol(prop);
703 if (ds != NULL) {
704 sym_calc_value(ds);
705 str = (const char *)ds->curr.val;
706 }
707 }
708 }
709
710 /* Handle select statements */
711 val = EXPR_OR(val, sym->rev_dep.tri);
712
713 /* transpose mod to yes if modules are not enabled */
714 if (val == mod)
715 if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
716 val = yes;
717
718 /* transpose mod to yes if type is bool */
719 if (sym->type == S_BOOLEAN && val == mod)
720 val = yes;
721
722 switch (sym->type) {
723 case S_BOOLEAN:
724 case S_TRISTATE:
725 switch (val) {
726 case no: return "n";
727 case mod: return "m";
728 case yes: return "y";
729 }
730 case S_INT:
731 case S_HEX:
732 return str;
733 case S_STRING:
734 return str;
735 case S_OTHER:
736 case S_UNKNOWN:
737 break;
738 }
739 return "";
740}
741
626const char *sym_get_string_value(struct symbol *sym) 742const char *sym_get_string_value(struct symbol *sym)
627{ 743{
628 tristate val; 744 tristate val;
@@ -651,12 +767,20 @@ bool sym_is_changable(struct symbol *sym)
651 return sym->visible > sym->rev_dep.tri; 767 return sym->visible > sym->rev_dep.tri;
652} 768}
653 769
770static unsigned strhash(const char *s)
771{
772 /* fnv32 hash */
773 unsigned hash = 2166136261U;
774 for (; *s; s++)
775 hash = (hash ^ *s) * 0x01000193;
776 return hash;
777}
778
654struct symbol *sym_lookup(const char *name, int flags) 779struct symbol *sym_lookup(const char *name, int flags)
655{ 780{
656 struct symbol *symbol; 781 struct symbol *symbol;
657 const char *ptr;
658 char *new_name; 782 char *new_name;
659 int hash = 0; 783 int hash;
660 784
661 if (name) { 785 if (name) {
662 if (name[0] && !name[1]) { 786 if (name[0] && !name[1]) {
@@ -666,12 +790,11 @@ struct symbol *sym_lookup(const char *name, int flags)
666 case 'n': return &symbol_no; 790 case 'n': return &symbol_no;
667 } 791 }
668 } 792 }
669 for (ptr = name; *ptr; ptr++) 793 hash = strhash(name) % SYMBOL_HASHSIZE;
670 hash += *ptr;
671 hash &= 0xff;
672 794
673 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 795 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
674 if (!strcmp(symbol->name, name) && 796 if (symbol->name &&
797 !strcmp(symbol->name, name) &&
675 (flags ? symbol->flags & flags 798 (flags ? symbol->flags & flags
676 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) 799 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
677 return symbol; 800 return symbol;
@@ -679,7 +802,7 @@ struct symbol *sym_lookup(const char *name, int flags)
679 new_name = strdup(name); 802 new_name = strdup(name);
680 } else { 803 } else {
681 new_name = NULL; 804 new_name = NULL;
682 hash = 256; 805 hash = 0;
683 } 806 }
684 807
685 symbol = malloc(sizeof(*symbol)); 808 symbol = malloc(sizeof(*symbol));
@@ -697,7 +820,6 @@ struct symbol *sym_lookup(const char *name, int flags)
697struct symbol *sym_find(const char *name) 820struct symbol *sym_find(const char *name)
698{ 821{
699 struct symbol *symbol = NULL; 822 struct symbol *symbol = NULL;
700 const char *ptr;
701 int hash = 0; 823 int hash = 0;
702 824
703 if (!name) 825 if (!name)
@@ -710,12 +832,11 @@ struct symbol *sym_find(const char *name)
710 case 'n': return &symbol_no; 832 case 'n': return &symbol_no;
711 } 833 }
712 } 834 }
713 for (ptr = name; *ptr; ptr++) 835 hash = strhash(name) % SYMBOL_HASHSIZE;
714 hash += *ptr;
715 hash &= 0xff;
716 836
717 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 837 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
718 if (!strcmp(symbol->name, name) && 838 if (symbol->name &&
839 !strcmp(symbol->name, name) &&
719 !(symbol->flags & SYMBOL_CONST)) 840 !(symbol->flags & SYMBOL_CONST))
720 break; 841 break;
721 } 842 }
@@ -723,6 +844,55 @@ struct symbol *sym_find(const char *name)
723 return symbol; 844 return symbol;
724} 845}
725 846
847/*
848 * Expand symbol's names embedded in the string given in argument. Symbols'
849 * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
850 * the empty string.
851 */
852const char *sym_expand_string_value(const char *in)
853{
854 const char *src;
855 char *res;
856 size_t reslen;
857
858 reslen = strlen(in) + 1;
859 res = malloc(reslen);
860 res[0] = '\0';
861
862 while ((src = strchr(in, '$'))) {
863 char *p, name[SYMBOL_MAXLENGTH];
864 const char *symval = "";
865 struct symbol *sym;
866 size_t newlen;
867
868 strncat(res, in, src - in);
869 src++;
870
871 p = name;
872 while (isalnum(*src) || *src == '_')
873 *p++ = *src++;
874 *p = '\0';
875
876 sym = sym_find(name);
877 if (sym != NULL) {
878 sym_calc_value(sym);
879 symval = sym_get_string_value(sym);
880 }
881
882 newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
883 if (newlen > reslen) {
884 reslen = newlen;
885 res = realloc(res, reslen);
886 }
887
888 strcat(res, symval);
889 in = src;
890 }
891 strcat(res, in);
892
893 return res;
894}
895
726struct symbol **sym_re_search(const char *pattern) 896struct symbol **sym_re_search(const char *pattern)
727{ 897{
728 struct symbol *sym, **sym_arr = NULL; 898 struct symbol *sym, **sym_arr = NULL;
@@ -750,6 +920,7 @@ struct symbol **sym_re_search(const char *pattern)
750 return NULL; 920 return NULL;
751 } 921 }
752 } 922 }
923 sym_calc_value(sym);
753 sym_arr[cnt++] = sym; 924 sym_arr[cnt++] = sym;
754 } 925 }
755 if (sym_arr) 926 if (sym_arr)
@@ -759,6 +930,112 @@ struct symbol **sym_re_search(const char *pattern)
759 return sym_arr; 930 return sym_arr;
760} 931}
761 932
933/*
934 * When we check for recursive dependencies we use a stack to save
935 * current state so we can print out relevant info to user.
936 * The entries are located on the call stack so no need to free memory.
937 * Note inser() remove() must always match to properly clear the stack.
938 */
939static struct dep_stack {
940 struct dep_stack *prev, *next;
941 struct symbol *sym;
942 struct property *prop;
943 struct expr *expr;
944} *check_top;
945
946static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
947{
948 memset(stack, 0, sizeof(*stack));
949 if (check_top)
950 check_top->next = stack;
951 stack->prev = check_top;
952 stack->sym = sym;
953 check_top = stack;
954}
955
956static void dep_stack_remove(void)
957{
958 check_top = check_top->prev;
959 if (check_top)
960 check_top->next = NULL;
961}
962
963/*
964 * Called when we have detected a recursive dependency.
965 * check_top point to the top of the stact so we use
966 * the ->prev pointer to locate the bottom of the stack.
967 */
968static void sym_check_print_recursive(struct symbol *last_sym)
969{
970 struct dep_stack *stack;
971 struct symbol *sym, *next_sym;
972 struct menu *menu = NULL;
973 struct property *prop;
974 struct dep_stack cv_stack;
975
976 if (sym_is_choice_value(last_sym)) {
977 dep_stack_insert(&cv_stack, last_sym);
978 last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
979 }
980
981 for (stack = check_top; stack != NULL; stack = stack->prev)
982 if (stack->sym == last_sym)
983 break;
984 if (!stack) {
985 fprintf(stderr, "unexpected recursive dependency error\n");
986 return;
987 }
988
989 for (; stack; stack = stack->next) {
990 sym = stack->sym;
991 next_sym = stack->next ? stack->next->sym : last_sym;
992 prop = stack->prop;
993 if (prop == NULL)
994 prop = stack->sym->prop;
995
996 /* for choice values find the menu entry (used below) */
997 if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
998 for (prop = sym->prop; prop; prop = prop->next) {
999 menu = prop->menu;
1000 if (prop->menu)
1001 break;
1002 }
1003 }
1004 if (stack->sym == last_sym)
1005 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
1006 prop->file->name, prop->lineno);
1007 if (stack->expr) {
1008 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
1009 prop->file->name, prop->lineno,
1010 sym->name ? sym->name : "<choice>",
1011 prop_get_type_name(prop->type),
1012 next_sym->name ? next_sym->name : "<choice>");
1013 } else if (stack->prop) {
1014 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
1015 prop->file->name, prop->lineno,
1016 sym->name ? sym->name : "<choice>",
1017 next_sym->name ? next_sym->name : "<choice>");
1018 } else if (sym_is_choice(sym)) {
1019 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
1020 menu->file->name, menu->lineno,
1021 sym->name ? sym->name : "<choice>",
1022 next_sym->name ? next_sym->name : "<choice>");
1023 } else if (sym_is_choice_value(sym)) {
1024 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
1025 menu->file->name, menu->lineno,
1026 sym->name ? sym->name : "<choice>",
1027 next_sym->name ? next_sym->name : "<choice>");
1028 } else {
1029 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
1030 prop->file->name, prop->lineno,
1031 sym->name ? sym->name : "<choice>",
1032 next_sym->name ? next_sym->name : "<choice>");
1033 }
1034 }
1035
1036 if (check_top == &cv_stack)
1037 dep_stack_remove();
1038}
762 1039
763static struct symbol *sym_check_expr_deps(struct expr *e) 1040static struct symbol *sym_check_expr_deps(struct expr *e)
764{ 1041{
@@ -795,24 +1072,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
795{ 1072{
796 struct symbol *sym2; 1073 struct symbol *sym2;
797 struct property *prop; 1074 struct property *prop;
1075 struct dep_stack stack;
1076
1077 dep_stack_insert(&stack, sym);
798 1078
799 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 1079 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
800 if (sym2) 1080 if (sym2)
801 return sym2; 1081 goto out;
802 1082
803 for (prop = sym->prop; prop; prop = prop->next) { 1083 for (prop = sym->prop; prop; prop = prop->next) {
804 if (prop->type == P_CHOICE || prop->type == P_SELECT) 1084 if (prop->type == P_CHOICE || prop->type == P_SELECT)
805 continue; 1085 continue;
1086 stack.prop = prop;
806 sym2 = sym_check_expr_deps(prop->visible.expr); 1087 sym2 = sym_check_expr_deps(prop->visible.expr);
807 if (sym2) 1088 if (sym2)
808 break; 1089 break;
809 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 1090 if (prop->type != P_DEFAULT || sym_is_choice(sym))
810 continue; 1091 continue;
1092 stack.expr = prop->expr;
811 sym2 = sym_check_expr_deps(prop->expr); 1093 sym2 = sym_check_expr_deps(prop->expr);
812 if (sym2) 1094 if (sym2)
813 break; 1095 break;
1096 stack.expr = NULL;
814 } 1097 }
815 1098
1099out:
1100 dep_stack_remove();
1101
816 return sym2; 1102 return sym2;
817} 1103}
818 1104
@@ -821,6 +1107,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
821 struct symbol *sym, *sym2; 1107 struct symbol *sym, *sym2;
822 struct property *prop; 1108 struct property *prop;
823 struct expr *e; 1109 struct expr *e;
1110 struct dep_stack stack;
1111
1112 dep_stack_insert(&stack, choice);
824 1113
825 prop = sym_get_choice_prop(choice); 1114 prop = sym_get_choice_prop(choice);
826 expr_list_for_each_sym(prop->expr, e, sym) 1115 expr_list_for_each_sym(prop->expr, e, sym)
@@ -834,10 +1123,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
834 1123
835 expr_list_for_each_sym(prop->expr, e, sym) { 1124 expr_list_for_each_sym(prop->expr, e, sym) {
836 sym2 = sym_check_sym_deps(sym); 1125 sym2 = sym_check_sym_deps(sym);
837 if (sym2) { 1126 if (sym2)
838 fprintf(stderr, " -> %s", sym->name);
839 break; 1127 break;
840 }
841 } 1128 }
842out: 1129out:
843 expr_list_for_each_sym(prop->expr, e, sym) 1130 expr_list_for_each_sym(prop->expr, e, sym)
@@ -847,6 +1134,8 @@ out:
847 prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 1134 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
848 sym2 = choice; 1135 sym2 = choice;
849 1136
1137 dep_stack_remove();
1138
850 return sym2; 1139 return sym2;
851} 1140}
852 1141
@@ -856,18 +1145,20 @@ struct symbol *sym_check_deps(struct symbol *sym)
856 struct property *prop; 1145 struct property *prop;
857 1146
858 if (sym->flags & SYMBOL_CHECK) { 1147 if (sym->flags & SYMBOL_CHECK) {
859 fprintf(stderr, "%s:%d:error: found recursive dependency: %s", 1148 sym_check_print_recursive(sym);
860 sym->prop->file->name, sym->prop->lineno,
861 sym->name ? sym->name : "<choice>");
862 return sym; 1149 return sym;
863 } 1150 }
864 if (sym->flags & SYMBOL_CHECKED) 1151 if (sym->flags & SYMBOL_CHECKED)
865 return NULL; 1152 return NULL;
866 1153
867 if (sym_is_choice_value(sym)) { 1154 if (sym_is_choice_value(sym)) {
1155 struct dep_stack stack;
1156
868 /* for choice groups start the check with main choice symbol */ 1157 /* for choice groups start the check with main choice symbol */
1158 dep_stack_insert(&stack, sym);
869 prop = sym_get_choice_prop(sym); 1159 prop = sym_get_choice_prop(sym);
870 sym2 = sym_check_deps(prop_get_symbol(prop)); 1160 sym2 = sym_check_deps(prop_get_symbol(prop));
1161 dep_stack_remove();
871 } else if (sym_is_choice(sym)) { 1162 } else if (sym_is_choice(sym)) {
872 sym2 = sym_check_choice_deps(sym); 1163 sym2 = sym_check_choice_deps(sym);
873 } else { 1164 } else {
@@ -876,14 +1167,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
876 sym->flags &= ~SYMBOL_CHECK; 1167 sym->flags &= ~SYMBOL_CHECK;
877 } 1168 }
878 1169
879 if (sym2) { 1170 if (sym2 && sym2 == sym)
880 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); 1171 sym2 = NULL;
881 if (sym2 == sym) {
882 fprintf(stderr, "\n");
883 zconfnerrs++;
884 sym2 = NULL;
885 }
886 }
887 1172
888 return sym2; 1173 return sym2;
889} 1174}
@@ -937,13 +1222,15 @@ const char *prop_get_type_name(enum prop_type type)
937 return "select"; 1222 return "select";
938 case P_RANGE: 1223 case P_RANGE:
939 return "range"; 1224 return "range";
1225 case P_SYMBOL:
1226 return "symbol";
940 case P_UNKNOWN: 1227 case P_UNKNOWN:
941 break; 1228 break;
942 } 1229 }
943 return "unknown"; 1230 return "unknown";
944} 1231}
945 1232
946void prop_add_env(const char *env) 1233static void prop_add_env(const char *env)
947{ 1234{
948 struct symbol *sym, *sym2; 1235 struct symbol *sym, *sym2;
949 struct property *prop; 1236 struct property *prop;
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index b6b2a46af14c..6330cc871a47 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -12,15 +12,18 @@
12struct file *file_lookup(const char *name) 12struct file *file_lookup(const char *name)
13{ 13{
14 struct file *file; 14 struct file *file;
15 const char *file_name = sym_expand_string_value(name);
15 16
16 for (file = file_list; file; file = file->next) { 17 for (file = file_list; file; file = file->next) {
17 if (!strcmp(name, file->name)) 18 if (!strcmp(name, file->name)) {
19 free((void *)file_name);
18 return file; 20 return file;
21 }
19 } 22 }
20 23
21 file = malloc(sizeof(*file)); 24 file = malloc(sizeof(*file));
22 memset(file, 0, sizeof(*file)); 25 memset(file, 0, sizeof(*file));
23 file->name = strdup(name); 26 file->name = file_name;
24 file->next = file_list; 27 file->next = file_list;
25 file_list = file; 28 file_list = file;
26 return file; 29 return file;
@@ -72,12 +75,13 @@ int file_write_dep(const char *name)
72} 75}
73 76
74 77
75/* Allocate initial growable sting */ 78/* Allocate initial growable string */
76struct gstr str_new(void) 79struct gstr str_new(void)
77{ 80{
78 struct gstr gs; 81 struct gstr gs;
79 gs.s = malloc(sizeof(char) * 64); 82 gs.s = malloc(sizeof(char) * 64);
80 gs.len = 64; 83 gs.len = 64;
84 gs.max_width = 0;
81 strcpy(gs.s, "\0"); 85 strcpy(gs.s, "\0");
82 return gs; 86 return gs;
83} 87}
@@ -88,6 +92,7 @@ struct gstr str_assign(const char *s)
88 struct gstr gs; 92 struct gstr gs;
89 gs.s = strdup(s); 93 gs.s = strdup(s);
90 gs.len = strlen(s) + 1; 94 gs.len = strlen(s) + 1;
95 gs.max_width = 0;
91 return gs; 96 return gs;
92} 97}
93 98
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index 25ef5d01c0af..c9e690eb7545 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -9,6 +9,8 @@
9 9
10struct kconf_id; 10struct kconf_id;
11 11
12static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
13
12%% 14%%
13mainmenu, T_MAINMENU, TF_COMMAND 15mainmenu, T_MAINMENU, TF_COMMAND
14menu, T_MENU, TF_COMMAND 16menu, T_MENU, TF_COMMAND
@@ -36,6 +38,7 @@ hex, T_TYPE, TF_COMMAND, S_HEX
36string, T_TYPE, TF_COMMAND, S_STRING 38string, T_TYPE, TF_COMMAND, S_STRING
37select, T_SELECT, TF_COMMAND 39select, T_SELECT, TF_COMMAND
38range, T_RANGE, TF_COMMAND 40range, T_RANGE, TF_COMMAND
41visible, T_VISIBLE, TF_COMMAND
39option, T_OPTION, TF_COMMAND 42option, T_OPTION, TF_COMMAND
40on, T_ON, TF_PARAM 43on, T_ON, TF_PARAM
41modules, T_OPT_MODULES, TF_OPTION 44modules, T_OPT_MODULES, TF_OPTION
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index 5c73d51339d8..4055d5de1750 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -30,7 +30,9 @@
30#endif 30#endif
31 31
32struct kconf_id; 32struct kconf_id;
33/* maximum key range = 47, duplicates = 0 */ 33
34static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
35/* maximum key range = 50, duplicates = 0 */
34 36
35#ifdef __GNUC__ 37#ifdef __GNUC__
36__inline 38__inline
@@ -44,32 +46,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
44{ 46{
45 static unsigned char asso_values[] = 47 static unsigned char asso_values[] =
46 { 48 {
47 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
48 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
49 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 51 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
50 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 52 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
51 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
52 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
53 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 55 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
54 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 56 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
55 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 57 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
56 49, 49, 49, 49, 49, 49, 49, 49, 11, 5, 58 52, 52, 52, 52, 52, 52, 52, 52, 40, 5,
57 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, 59 0, 0, 5, 52, 0, 20, 52, 52, 10, 20,
58 5, 0, 30, 49, 0, 15, 0, 10, 0, 49, 60 5, 0, 35, 52, 0, 30, 0, 15, 0, 52,
59 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, 61 15, 52, 52, 52, 52, 52, 52, 52, 52, 52,
60 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 62 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
61 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 63 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
62 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 64 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
63 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 65 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
64 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 66 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
65 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 67 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
66 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 68 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
67 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 69 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
68 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 70 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
69 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 71 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
70 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 72 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
71 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 73 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
72 49, 49, 49, 49, 49, 49 74 52, 52, 52, 52, 52, 52
73 }; 75 };
74 register int hval = len; 76 register int hval = len;
75 77
@@ -100,25 +102,26 @@ struct kconf_id_strings_t
100 char kconf_id_strings_str12[sizeof("default")]; 102 char kconf_id_strings_str12[sizeof("default")];
101 char kconf_id_strings_str13[sizeof("def_bool")]; 103 char kconf_id_strings_str13[sizeof("def_bool")];
102 char kconf_id_strings_str14[sizeof("help")]; 104 char kconf_id_strings_str14[sizeof("help")];
103 char kconf_id_strings_str15[sizeof("bool")];
104 char kconf_id_strings_str16[sizeof("config")]; 105 char kconf_id_strings_str16[sizeof("config")];
105 char kconf_id_strings_str17[sizeof("def_tristate")]; 106 char kconf_id_strings_str17[sizeof("def_tristate")];
106 char kconf_id_strings_str18[sizeof("boolean")]; 107 char kconf_id_strings_str18[sizeof("hex")];
107 char kconf_id_strings_str19[sizeof("defconfig_list")]; 108 char kconf_id_strings_str19[sizeof("defconfig_list")];
108 char kconf_id_strings_str21[sizeof("string")];
109 char kconf_id_strings_str22[sizeof("if")]; 109 char kconf_id_strings_str22[sizeof("if")];
110 char kconf_id_strings_str23[sizeof("int")]; 110 char kconf_id_strings_str23[sizeof("int")];
111 char kconf_id_strings_str26[sizeof("select")];
112 char kconf_id_strings_str27[sizeof("modules")]; 111 char kconf_id_strings_str27[sizeof("modules")];
113 char kconf_id_strings_str28[sizeof("tristate")]; 112 char kconf_id_strings_str28[sizeof("tristate")];
114 char kconf_id_strings_str29[sizeof("menu")]; 113 char kconf_id_strings_str29[sizeof("menu")];
115 char kconf_id_strings_str31[sizeof("source")];
116 char kconf_id_strings_str32[sizeof("comment")]; 114 char kconf_id_strings_str32[sizeof("comment")];
117 char kconf_id_strings_str33[sizeof("hex")];
118 char kconf_id_strings_str35[sizeof("menuconfig")]; 115 char kconf_id_strings_str35[sizeof("menuconfig")];
119 char kconf_id_strings_str36[sizeof("prompt")]; 116 char kconf_id_strings_str36[sizeof("string")];
120 char kconf_id_strings_str37[sizeof("depends")]; 117 char kconf_id_strings_str37[sizeof("visible")];
118 char kconf_id_strings_str41[sizeof("prompt")];
119 char kconf_id_strings_str42[sizeof("depends")];
120 char kconf_id_strings_str44[sizeof("bool")];
121 char kconf_id_strings_str46[sizeof("select")];
122 char kconf_id_strings_str47[sizeof("boolean")];
121 char kconf_id_strings_str48[sizeof("mainmenu")]; 123 char kconf_id_strings_str48[sizeof("mainmenu")];
124 char kconf_id_strings_str51[sizeof("source")];
122 }; 125 };
123static struct kconf_id_strings_t kconf_id_strings_contents = 126static struct kconf_id_strings_t kconf_id_strings_contents =
124 { 127 {
@@ -134,25 +137,26 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
134 "default", 137 "default",
135 "def_bool", 138 "def_bool",
136 "help", 139 "help",
137 "bool",
138 "config", 140 "config",
139 "def_tristate", 141 "def_tristate",
140 "boolean", 142 "hex",
141 "defconfig_list", 143 "defconfig_list",
142 "string",
143 "if", 144 "if",
144 "int", 145 "int",
145 "select",
146 "modules", 146 "modules",
147 "tristate", 147 "tristate",
148 "menu", 148 "menu",
149 "source",
150 "comment", 149 "comment",
151 "hex",
152 "menuconfig", 150 "menuconfig",
151 "string",
152 "visible",
153 "prompt", 153 "prompt",
154 "depends", 154 "depends",
155 "mainmenu" 155 "bool",
156 "select",
157 "boolean",
158 "mainmenu",
159 "source"
156 }; 160 };
157#define kconf_id_strings ((const char *) &kconf_id_strings_contents) 161#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
158#ifdef __GNUC__ 162#ifdef __GNUC__
@@ -166,11 +170,11 @@ kconf_id_lookup (register const char *str, register unsigned int len)
166{ 170{
167 enum 171 enum
168 { 172 {
169 TOTAL_KEYWORDS = 31, 173 TOTAL_KEYWORDS = 32,
170 MIN_WORD_LENGTH = 2, 174 MIN_WORD_LENGTH = 2,
171 MAX_WORD_LENGTH = 14, 175 MAX_WORD_LENGTH = 14,
172 MIN_HASH_VALUE = 2, 176 MIN_HASH_VALUE = 2,
173 MAX_HASH_VALUE = 48 177 MAX_HASH_VALUE = 51
174 }; 178 };
175 179
176 static struct kconf_id wordlist[] = 180 static struct kconf_id wordlist[] =
@@ -189,31 +193,35 @@ kconf_id_lookup (register const char *str, register unsigned int len)
189 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, 193 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
190 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, 194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
191 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND}, 195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND},
192 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN}, 196 {-1},
193 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND}, 197 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND},
194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, 198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN}, 199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_HEX},
196 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION}, 200 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION},
197 {-1}, 201 {-1}, {-1},
198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, 202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
200 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, 203 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
201 {-1}, {-1}, 204 {-1}, {-1}, {-1},
202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
203 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, 205 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
204 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, 206 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
205 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND}, 207 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
206 {-1}, 208 {-1}, {-1},
207 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND},
208 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, 209 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
209 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX}, 210 {-1}, {-1},
210 {-1},
211 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND}, 211 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
212 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND}, 212 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_TYPE, TF_COMMAND, S_STRING},
213 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND}, 213 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_VISIBLE, TF_COMMAND},
214 {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, 214 {-1}, {-1}, {-1},
215 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_PROMPT, TF_COMMAND},
216 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_DEPENDS, TF_COMMAND},
215 {-1}, 217 {-1},
216 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND} 218 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44, T_TYPE, TF_COMMAND, S_BOOLEAN},
219 {-1},
220 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND},
221 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
222 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND},
223 {-1}, {-1},
224 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_SOURCE, TF_COMMAND}
217 }; 225 };
218 226
219 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 227 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 21ff69c9ad4e..3dbaec185cc4 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -39,7 +39,7 @@ static int last_ts, first_ts;
39static void zconf_endhelp(void); 39static void zconf_endhelp(void);
40static void zconf_endfile(void); 40static void zconf_endfile(void);
41 41
42void new_string(void) 42static void new_string(void)
43{ 43{
44 text = malloc(START_STRSIZE); 44 text = malloc(START_STRSIZE);
45 text_asize = START_STRSIZE; 45 text_asize = START_STRSIZE;
@@ -47,7 +47,7 @@ void new_string(void)
47 *text = 0; 47 *text = 0;
48} 48}
49 49
50void append_string(const char *str, int size) 50static void append_string(const char *str, int size)
51{ 51{
52 int new_size = text_size + size + 1; 52 int new_size = text_size + size + 1;
53 if (new_size > text_asize) { 53 if (new_size > text_asize) {
@@ -61,7 +61,7 @@ void append_string(const char *str, int size)
61 text[text_size] = 0; 61 text[text_size] = 0;
62} 62}
63 63
64void alloc_string(const char *str, int size) 64static void alloc_string(const char *str, int size)
65{ 65{
66 text = malloc(size + 1); 66 text = malloc(size + 1);
67 memcpy(text, str, size); 67 memcpy(text, str, size);
@@ -304,9 +304,10 @@ void zconf_nextfile(const char *name)
304 memset(buf, 0, sizeof(*buf)); 304 memset(buf, 0, sizeof(*buf));
305 305
306 current_buf->state = YY_CURRENT_BUFFER; 306 current_buf->state = YY_CURRENT_BUFFER;
307 yyin = zconf_fopen(name); 307 yyin = zconf_fopen(file->name);
308 if (!yyin) { 308 if (!yyin) {
309 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); 309 printf("%s:%d: can't open file \"%s\"\n",
310 zconf_curname(), zconf_lineno(), file->name);
310 exit(1); 311 exit(1);
311 } 312 }
312 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 313 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
@@ -353,7 +354,7 @@ int zconf_lineno(void)
353 return current_pos.lineno; 354 return current_pos.lineno;
354} 355}
355 356
356char *zconf_curname(void) 357const char *zconf_curname(void)
357{ 358{
358 return current_pos.file ? current_pos.file->name : "<none>"; 359 return current_pos.file ? current_pos.file->name : "<none>";
359} 360}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 95df833b5a9d..4c5495ea205e 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,24 +1,23 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2 1
3/* Skeleton implementation for Bison's Yacc-like parsers in C 2/* A Bison parser, made by GNU Bison 2.4.1. */
4 3
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4/* Skeleton implementation for Bison's Yacc-like parsers in C
5
6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc. 7 Free Software Foundation, Inc.
7 8
8 This program is free software; you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option) 11 the Free Software Foundation, either version 3 of the License, or
11 any later version. 12 (at your option) any later version.
12 13
13 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 17 GNU General Public License for more details.
17 18
18 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22 21
23/* As a special exception, you may create a larger work that contains 22/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work 23 part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +28,7 @@
29 special exception, which will cause the skeleton and the resulting 28 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public 29 Bison output files to be licensed under the GNU General Public
31 License without this special exception. 30 License without this special exception.
32 31
33 This special exception was added by the Free Software Foundation in 32 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */ 33 version 2.2 of Bison. */
35 34
@@ -47,7 +46,7 @@
47#define YYBISON 1 46#define YYBISON 1
48 47
49/* Bison version. */ 48/* Bison version. */
50#define YYBISON_VERSION "2.3" 49#define YYBISON_VERSION "2.4.1"
51 50
52/* Skeleton name. */ 51/* Skeleton name. */
53#define YYSKELETON_NAME "yacc.c" 52#define YYSKELETON_NAME "yacc.c"
@@ -55,94 +54,23 @@
55/* Pure parsers. */ 54/* Pure parsers. */
56#define YYPURE 0 55#define YYPURE 0
57 56
57/* Push parsers. */
58#define YYPUSH 0
59
60/* Pull parsers. */
61#define YYPULL 1
62
58/* Using locations. */ 63/* Using locations. */
59#define YYLSP_NEEDED 0 64#define YYLSP_NEEDED 0
60 65
61/* Substitute the variable and function names. */ 66/* Substitute the variable and function names. */
62#define yyparse zconfparse 67#define yyparse zconfparse
63#define yylex zconflex 68#define yylex zconflex
64#define yyerror zconferror 69#define yyerror zconferror
65#define yylval zconflval 70#define yylval zconflval
66#define yychar zconfchar 71#define yychar zconfchar
67#define yydebug zconfdebug 72#define yydebug zconfdebug
68#define yynerrs zconfnerrs 73#define yynerrs zconfnerrs
69
70
71/* Tokens. */
72#ifndef YYTOKENTYPE
73# define YYTOKENTYPE
74 /* Put the tokens into the symbol table, so that GDB and other debuggers
75 know about them. */
76 enum yytokentype {
77 T_MAINMENU = 258,
78 T_MENU = 259,
79 T_ENDMENU = 260,
80 T_SOURCE = 261,
81 T_CHOICE = 262,
82 T_ENDCHOICE = 263,
83 T_COMMENT = 264,
84 T_CONFIG = 265,
85 T_MENUCONFIG = 266,
86 T_HELP = 267,
87 T_HELPTEXT = 268,
88 T_IF = 269,
89 T_ENDIF = 270,
90 T_DEPENDS = 271,
91 T_OPTIONAL = 272,
92 T_PROMPT = 273,
93 T_TYPE = 274,
94 T_DEFAULT = 275,
95 T_SELECT = 276,
96 T_RANGE = 277,
97 T_OPTION = 278,
98 T_ON = 279,
99 T_WORD = 280,
100 T_WORD_QUOTE = 281,
101 T_UNEQUAL = 282,
102 T_CLOSE_PAREN = 283,
103 T_OPEN_PAREN = 284,
104 T_EOL = 285,
105 T_OR = 286,
106 T_AND = 287,
107 T_EQUAL = 288,
108 T_NOT = 289
109 };
110#endif
111/* Tokens. */
112#define T_MAINMENU 258
113#define T_MENU 259
114#define T_ENDMENU 260
115#define T_SOURCE 261
116#define T_CHOICE 262
117#define T_ENDCHOICE 263
118#define T_COMMENT 264
119#define T_CONFIG 265
120#define T_MENUCONFIG 266
121#define T_HELP 267
122#define T_HELPTEXT 268
123#define T_IF 269
124#define T_ENDIF 270
125#define T_DEPENDS 271
126#define T_OPTIONAL 272
127#define T_PROMPT 273
128#define T_TYPE 274
129#define T_DEFAULT 275
130#define T_SELECT 276
131#define T_RANGE 277
132#define T_OPTION 278
133#define T_ON 279
134#define T_WORD 280
135#define T_WORD_QUOTE 281
136#define T_UNEQUAL 282
137#define T_CLOSE_PAREN 283
138#define T_OPEN_PAREN 284
139#define T_EOL 285
140#define T_OR 286
141#define T_AND 287
142#define T_EQUAL 288
143#define T_NOT 289
144
145
146 74
147 75
148/* Copy the first part of user declarations. */ 76/* Copy the first part of user declarations. */
@@ -163,8 +91,6 @@
163#define LKC_DIRECT_LINK 91#define LKC_DIRECT_LINK
164#include "lkc.h" 92#include "lkc.h"
165 93
166#include "zconf.hash.c"
167
168#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 94#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
169 95
170#define PRINTD 0x0001 96#define PRINTD 0x0001
@@ -178,7 +104,7 @@ static void zconf_error(const char *err, ...);
178static void zconferror(const char *err); 104static void zconferror(const char *err);
179static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); 105static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
180 106
181struct symbol *symbol_hash[257]; 107struct symbol *symbol_hash[SYMBOL_HASHSIZE];
182 108
183static struct menu *current_menu, *current_entry; 109static struct menu *current_menu, *current_entry;
184 110
@@ -188,6 +114,7 @@ static struct menu *current_menu, *current_entry;
188#endif 114#endif
189 115
190 116
117
191/* Enabling traces. */ 118/* Enabling traces. */
192#ifndef YYDEBUG 119#ifndef YYDEBUG
193# define YYDEBUG 0 120# define YYDEBUG 0
@@ -206,31 +133,78 @@ static struct menu *current_menu, *current_entry;
206# define YYTOKEN_TABLE 0 133# define YYTOKEN_TABLE 0
207#endif 134#endif
208 135
136
137/* Tokens. */
138#ifndef YYTOKENTYPE
139# define YYTOKENTYPE
140 /* Put the tokens into the symbol table, so that GDB and other debuggers
141 know about them. */
142 enum yytokentype {
143 T_MAINMENU = 258,
144 T_MENU = 259,
145 T_ENDMENU = 260,
146 T_SOURCE = 261,
147 T_CHOICE = 262,
148 T_ENDCHOICE = 263,
149 T_COMMENT = 264,
150 T_CONFIG = 265,
151 T_MENUCONFIG = 266,
152 T_HELP = 267,
153 T_HELPTEXT = 268,
154 T_IF = 269,
155 T_ENDIF = 270,
156 T_DEPENDS = 271,
157 T_OPTIONAL = 272,
158 T_PROMPT = 273,
159 T_TYPE = 274,
160 T_DEFAULT = 275,
161 T_SELECT = 276,
162 T_RANGE = 277,
163 T_VISIBLE = 278,
164 T_OPTION = 279,
165 T_ON = 280,
166 T_WORD = 281,
167 T_WORD_QUOTE = 282,
168 T_UNEQUAL = 283,
169 T_CLOSE_PAREN = 284,
170 T_OPEN_PAREN = 285,
171 T_EOL = 286,
172 T_OR = 287,
173 T_AND = 288,
174 T_EQUAL = 289,
175 T_NOT = 290
176 };
177#endif
178
179
180
209#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 181#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
210typedef union YYSTYPE 182typedef union YYSTYPE
211
212{ 183{
184
185
213 char *string; 186 char *string;
214 struct file *file; 187 struct file *file;
215 struct symbol *symbol; 188 struct symbol *symbol;
216 struct expr *expr; 189 struct expr *expr;
217 struct menu *menu; 190 struct menu *menu;
218 struct kconf_id *id; 191 struct kconf_id *id;
219}
220/* Line 187 of yacc.c. */
221 192
222 YYSTYPE; 193
194
195} YYSTYPE;
196# define YYSTYPE_IS_TRIVIAL 1
223# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 197# define yystype YYSTYPE /* obsolescent; will be withdrawn */
224# define YYSTYPE_IS_DECLARED 1 198# define YYSTYPE_IS_DECLARED 1
225# define YYSTYPE_IS_TRIVIAL 1
226#endif 199#endif
227 200
228 201
229
230/* Copy the second part of user declarations. */ 202/* Copy the second part of user declarations. */
231 203
232 204
233/* Line 216 of yacc.c. */ 205/* Include zconf.hash.c here so it can see the token constants. */
206#include "zconf.hash.c"
207
234 208
235 209
236#ifdef short 210#ifdef short
@@ -306,14 +280,14 @@ typedef short int yytype_int16;
306#if (defined __STDC__ || defined __C99__FUNC__ \ 280#if (defined __STDC__ || defined __C99__FUNC__ \
307 || defined __cplusplus || defined _MSC_VER) 281 || defined __cplusplus || defined _MSC_VER)
308static int 282static int
309YYID (int i) 283YYID (int yyi)
310#else 284#else
311static int 285static int
312YYID (i) 286YYID (yyi)
313 int i; 287 int yyi;
314#endif 288#endif
315{ 289{
316 return i; 290 return yyi;
317} 291}
318#endif 292#endif
319 293
@@ -394,9 +368,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
394/* A type that is properly aligned for any stack member. */ 368/* A type that is properly aligned for any stack member. */
395union yyalloc 369union yyalloc
396{ 370{
397 yytype_int16 yyss; 371 yytype_int16 yyss_alloc;
398 YYSTYPE yyvs; 372 YYSTYPE yyvs_alloc;
399 }; 373};
400 374
401/* The size of the maximum gap between one aligned stack and the next. */ 375/* The size of the maximum gap between one aligned stack and the next. */
402# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) 376# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -430,12 +404,12 @@ union yyalloc
430 elements in the stack, and YYPTR gives the new location of the 404 elements in the stack, and YYPTR gives the new location of the
431 stack. Advance YYPTR to a properly aligned location for the next 405 stack. Advance YYPTR to a properly aligned location for the next
432 stack. */ 406 stack. */
433# define YYSTACK_RELOCATE(Stack) \ 407# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
434 do \ 408 do \
435 { \ 409 { \
436 YYSIZE_T yynewbytes; \ 410 YYSIZE_T yynewbytes; \
437 YYCOPY (&yyptr->Stack, Stack, yysize); \ 411 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
438 Stack = &yyptr->Stack; \ 412 Stack = &yyptr->Stack_alloc; \
439 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ 413 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
440 yyptr += yynewbytes / sizeof (*yyptr); \ 414 yyptr += yynewbytes / sizeof (*yyptr); \
441 } \ 415 } \
@@ -444,22 +418,22 @@ union yyalloc
444#endif 418#endif
445 419
446/* YYFINAL -- State number of the termination state. */ 420/* YYFINAL -- State number of the termination state. */
447#define YYFINAL 3 421#define YYFINAL 11
448/* YYLAST -- Last index in YYTABLE. */ 422/* YYLAST -- Last index in YYTABLE. */
449#define YYLAST 259 423#define YYLAST 290
450 424
451/* YYNTOKENS -- Number of terminals. */ 425/* YYNTOKENS -- Number of terminals. */
452#define YYNTOKENS 35 426#define YYNTOKENS 36
453/* YYNNTS -- Number of nonterminals. */ 427/* YYNNTS -- Number of nonterminals. */
454#define YYNNTS 46 428#define YYNNTS 50
455/* YYNRULES -- Number of rules. */ 429/* YYNRULES -- Number of rules. */
456#define YYNRULES 110 430#define YYNRULES 118
457/* YYNRULES -- Number of states. */ 431/* YYNRULES -- Number of states. */
458#define YYNSTATES 180 432#define YYNSTATES 191
459 433
460/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 434/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
461#define YYUNDEFTOK 2 435#define YYUNDEFTOK 2
462#define YYMAXUTOK 289 436#define YYMAXUTOK 290
463 437
464#define YYTRANSLATE(YYX) \ 438#define YYTRANSLATE(YYX) \
465 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 439 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -495,7 +469,8 @@ static const yytype_uint8 yytranslate[] =
495 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 469 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
496 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 470 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
497 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 471 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
498 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 472 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
473 35
499}; 474};
500 475
501#if YYDEBUG 476#if YYDEBUG
@@ -503,73 +478,75 @@ static const yytype_uint8 yytranslate[] =
503 YYRHS. */ 478 YYRHS. */
504static const yytype_uint16 yyprhs[] = 479static const yytype_uint16 yyprhs[] =
505{ 480{
506 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, 481 0, 0, 3, 6, 8, 11, 13, 14, 17, 20,
507 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, 482 23, 26, 31, 36, 40, 42, 44, 46, 48, 50,
508 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, 483 52, 54, 56, 58, 60, 62, 64, 66, 68, 72,
509 81, 84, 85, 88, 91, 94, 97, 100, 103, 107, 484 75, 79, 82, 86, 89, 90, 93, 96, 99, 102,
510 112, 117, 122, 128, 132, 133, 137, 138, 141, 145, 485 105, 108, 112, 117, 122, 127, 133, 137, 138, 142,
511 148, 150, 154, 155, 158, 161, 164, 167, 170, 175, 486 143, 146, 150, 153, 155, 159, 160, 163, 166, 169,
512 179, 182, 187, 188, 191, 195, 197, 201, 202, 205, 487 172, 175, 180, 184, 187, 192, 193, 196, 200, 202,
513 208, 211, 215, 218, 220, 224, 225, 228, 231, 234, 488 206, 207, 210, 213, 216, 220, 224, 228, 230, 234,
514 238, 242, 245, 248, 251, 252, 255, 258, 261, 266, 489 235, 238, 241, 244, 248, 252, 255, 258, 261, 262,
515 267, 270, 272, 274, 277, 280, 283, 285, 288, 289, 490 265, 268, 271, 276, 277, 280, 283, 286, 287, 290,
516 292, 294, 298, 302, 306, 309, 313, 317, 319, 321, 491 292, 294, 297, 300, 303, 305, 308, 309, 312, 314,
517 322 492 318, 322, 326, 329, 333, 337, 339, 341, 342
518}; 493};
519 494
520/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 495/* YYRHS -- A `-1'-separated list of the rules' RHS. */
521static const yytype_int8 yyrhs[] = 496static const yytype_int8 yyrhs[] =
522{ 497{
523 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, 498 37, 0, -1, 81, 38, -1, 38, -1, 63, 39,
524 53, -1, 37, 64, -1, 37, 3, 74, 76, -1, 499 -1, 39, -1, -1, 39, 41, -1, 39, 55, -1,
525 37, 75, -1, 37, 25, 1, 30, -1, 37, 38, 500 39, 67, -1, 39, 80, -1, 39, 26, 1, 31,
526 1, 30, -1, 37, 1, 30, -1, 16, -1, 18, 501 -1, 39, 40, 1, 31, -1, 39, 1, 31, -1,
527 -1, 19, -1, 21, -1, 17, -1, 22, -1, 20, 502 16, -1, 18, -1, 19, -1, 21, -1, 17, -1,
528 -1, 30, -1, 59, -1, 68, -1, 42, -1, 44, 503 22, -1, 20, -1, 23, -1, 31, -1, 61, -1,
529 -1, 66, -1, 25, 1, 30, -1, 1, 30, -1, 504 71, -1, 44, -1, 46, -1, 69, -1, 26, 1,
530 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, 505 31, -1, 1, 31, -1, 10, 26, 31, -1, 43,
531 -1, 43, 45, -1, -1, 45, 46, -1, 45, 47, 506 47, -1, 11, 26, 31, -1, 45, 47, -1, -1,
532 -1, 45, 72, -1, 45, 70, -1, 45, 40, -1, 507 47, 48, -1, 47, 49, -1, 47, 75, -1, 47,
533 45, 30, -1, 19, 73, 30, -1, 18, 74, 77, 508 73, -1, 47, 42, -1, 47, 31, -1, 19, 78,
534 30, -1, 20, 78, 77, 30, -1, 21, 25, 77, 509 31, -1, 18, 79, 82, 31, -1, 20, 83, 82,
535 30, -1, 22, 79, 79, 77, 30, -1, 23, 48, 510 31, -1, 21, 26, 82, 31, -1, 22, 84, 84,
536 30, -1, -1, 48, 25, 49, -1, -1, 33, 74, 511 82, 31, -1, 24, 50, 31, -1, -1, 50, 26,
537 -1, 7, 80, 30, -1, 50, 54, -1, 75, -1, 512 51, -1, -1, 34, 79, -1, 7, 85, 31, -1,
538 51, 56, 52, -1, -1, 54, 55, -1, 54, 72, 513 52, 56, -1, 80, -1, 53, 58, 54, -1, -1,
539 -1, 54, 70, -1, 54, 30, -1, 54, 40, -1, 514 56, 57, -1, 56, 75, -1, 56, 73, -1, 56,
540 18, 74, 77, 30, -1, 19, 73, 30, -1, 17, 515 31, -1, 56, 42, -1, 18, 79, 82, 31, -1,
541 30, -1, 20, 25, 77, 30, -1, -1, 56, 39, 516 19, 78, 31, -1, 17, 31, -1, 20, 26, 82,
542 -1, 14, 78, 76, -1, 75, -1, 57, 60, 58, 517 31, -1, -1, 58, 41, -1, 14, 83, 81, -1,
543 -1, -1, 60, 39, -1, 60, 64, -1, 60, 53, 518 80, -1, 59, 62, 60, -1, -1, 62, 41, -1,
544 -1, 4, 74, 30, -1, 61, 71, -1, 75, -1, 519 62, 67, -1, 62, 55, -1, 3, 79, 81, -1,
545 62, 65, 63, -1, -1, 65, 39, -1, 65, 64, 520 4, 79, 31, -1, 64, 76, 74, -1, 80, -1,
546 -1, 65, 53, -1, 6, 74, 30, -1, 9, 74, 521 65, 68, 66, -1, -1, 68, 41, -1, 68, 67,
547 30, -1, 67, 71, -1, 12, 30, -1, 69, 13, 522 -1, 68, 55, -1, 6, 79, 31, -1, 9, 79,
548 -1, -1, 71, 72, -1, 71, 30, -1, 71, 40, 523 31, -1, 70, 74, -1, 12, 31, -1, 72, 13,
549 -1, 16, 24, 78, 30, -1, -1, 74, 77, -1, 524 -1, -1, 74, 75, -1, 74, 31, -1, 74, 42,
550 25, -1, 26, -1, 5, 30, -1, 8, 30, -1, 525 -1, 16, 25, 83, 31, -1, -1, 76, 77, -1,
551 15, 30, -1, 30, -1, 76, 30, -1, -1, 14, 526 76, 31, -1, 23, 82, -1, -1, 79, 82, -1,
552 78, -1, 79, -1, 79, 33, 79, -1, 79, 27, 527 26, -1, 27, -1, 5, 31, -1, 8, 31, -1,
553 79, -1, 29, 78, 28, -1, 34, 78, -1, 78, 528 15, 31, -1, 31, -1, 81, 31, -1, -1, 14,
554 31, 78, -1, 78, 32, 78, -1, 25, -1, 26, 529 83, -1, 84, -1, 84, 34, 84, -1, 84, 28,
555 -1, -1, 25, -1 530 84, -1, 30, 83, 29, -1, 35, 83, -1, 83,
531 32, 83, -1, 83, 33, 83, -1, 26, -1, 27,
532 -1, -1, 26, -1
556}; 533};
557 534
558/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 535/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
559static const yytype_uint16 yyrline[] = 536static const yytype_uint16 yyrline[] =
560{ 537{
561 0, 104, 104, 106, 108, 109, 110, 111, 112, 113, 538 0, 108, 108, 108, 110, 110, 112, 114, 115, 116,
562 114, 118, 122, 122, 122, 122, 122, 122, 122, 126, 539 117, 118, 119, 123, 127, 127, 127, 127, 127, 127,
563 127, 128, 129, 130, 131, 135, 136, 142, 150, 156, 540 127, 127, 131, 132, 133, 134, 135, 136, 140, 141,
564 164, 174, 176, 177, 178, 179, 180, 181, 184, 192, 541 147, 155, 161, 169, 179, 181, 182, 183, 184, 185,
565 198, 208, 214, 220, 223, 225, 236, 237, 242, 251, 542 186, 189, 197, 203, 213, 219, 225, 228, 230, 241,
566 256, 264, 267, 269, 270, 271, 272, 273, 276, 282, 543 242, 247, 256, 261, 269, 272, 274, 275, 276, 277,
567 293, 299, 309, 311, 316, 324, 332, 335, 337, 338, 544 278, 281, 287, 298, 304, 314, 316, 321, 329, 337,
568 339, 344, 351, 356, 364, 367, 369, 370, 371, 374, 545 340, 342, 343, 344, 349, 356, 363, 368, 376, 379,
569 382, 389, 396, 402, 409, 411, 412, 413, 416, 424, 546 381, 382, 383, 386, 394, 401, 408, 414, 421, 423,
570 426, 431, 432, 435, 436, 437, 441, 442, 445, 446, 547 424, 425, 428, 436, 438, 439, 442, 449, 451, 456,
571 449, 450, 451, 452, 453, 454, 455, 458, 459, 462, 548 457, 460, 461, 462, 466, 467, 470, 471, 474, 475,
572 463 549 476, 477, 478, 479, 480, 483, 484, 487, 488
573}; 550};
574#endif 551#endif
575 552
@@ -582,19 +559,19 @@ static const char *const yytname[] =
582 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", 559 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
583 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", 560 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
584 "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE", 561 "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
585 "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", 562 "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
586 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", 563 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
587 "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", 564 "T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
588 "option_error", "config_entry_start", "config_stmt", 565 "common_stmt", "option_error", "config_entry_start", "config_stmt",
589 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", 566 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
590 "config_option", "symbol_option", "symbol_option_list", 567 "config_option", "symbol_option", "symbol_option_list",
591 "symbol_option_arg", "choice", "choice_entry", "choice_end", 568 "symbol_option_arg", "choice", "choice_entry", "choice_end",
592 "choice_stmt", "choice_option_list", "choice_option", "choice_block", 569 "choice_stmt", "choice_option_list", "choice_option", "choice_block",
593 "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry", 570 "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
594 "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment", 571 "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
595 "comment_stmt", "help_start", "help", "depends_list", "depends", 572 "comment", "comment_stmt", "help_start", "help", "depends_list",
596 "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 573 "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt",
597 "word_opt", 0 574 "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0
598}; 575};
599#endif 576#endif
600 577
@@ -606,42 +583,42 @@ static const yytype_uint16 yytoknum[] =
606 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 583 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
607 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 584 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
608 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 585 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
609 285, 286, 287, 288, 289 586 285, 286, 287, 288, 289, 290
610}; 587};
611# endif 588# endif
612 589
613/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 590/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
614static const yytype_uint8 yyr1[] = 591static const yytype_uint8 yyr1[] =
615{ 592{
616 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, 593 0, 36, 37, 37, 38, 38, 39, 39, 39, 39,
617 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, 594 39, 39, 39, 39, 40, 40, 40, 40, 40, 40,
618 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, 595 40, 40, 41, 41, 41, 41, 41, 41, 42, 42,
619 44, 45, 45, 45, 45, 45, 45, 45, 46, 46, 596 43, 44, 45, 46, 47, 47, 47, 47, 47, 47,
620 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, 597 47, 48, 48, 48, 48, 48, 49, 50, 50, 51,
621 52, 53, 54, 54, 54, 54, 54, 54, 55, 55, 598 51, 52, 53, 54, 55, 56, 56, 56, 56, 56,
622 55, 55, 56, 56, 57, 58, 59, 60, 60, 60, 599 56, 57, 57, 57, 57, 58, 58, 59, 60, 61,
623 60, 61, 62, 63, 64, 65, 65, 65, 65, 66, 600 62, 62, 62, 62, 63, 64, 65, 66, 67, 68,
624 67, 68, 69, 70, 71, 71, 71, 71, 72, 73, 601 68, 68, 68, 69, 70, 71, 72, 73, 74, 74,
625 73, 74, 74, 75, 75, 75, 76, 76, 77, 77, 602 74, 74, 75, 76, 76, 76, 77, 78, 78, 79,
626 78, 78, 78, 78, 78, 78, 78, 79, 79, 80, 603 79, 80, 80, 80, 81, 81, 82, 82, 83, 83,
627 80 604 83, 83, 83, 83, 83, 84, 84, 85, 85
628}; 605};
629 606
630/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 607/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
631static const yytype_uint8 yyr2[] = 608static const yytype_uint8 yyr2[] =
632{ 609{
633 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, 610 0, 2, 2, 1, 2, 1, 0, 2, 2, 2,
634 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 611 2, 4, 4, 3, 1, 1, 1, 1, 1, 1,
635 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, 612 1, 1, 1, 1, 1, 1, 1, 1, 3, 2,
636 2, 0, 2, 2, 2, 2, 2, 2, 3, 4, 613 3, 2, 3, 2, 0, 2, 2, 2, 2, 2,
637 4, 4, 5, 3, 0, 3, 0, 2, 3, 2, 614 2, 3, 4, 4, 4, 5, 3, 0, 3, 0,
638 1, 3, 0, 2, 2, 2, 2, 2, 4, 3, 615 2, 3, 2, 1, 3, 0, 2, 2, 2, 2,
639 2, 4, 0, 2, 3, 1, 3, 0, 2, 2, 616 2, 4, 3, 2, 4, 0, 2, 3, 1, 3,
640 2, 3, 2, 1, 3, 0, 2, 2, 2, 3, 617 0, 2, 2, 2, 3, 3, 3, 1, 3, 0,
641 3, 2, 2, 2, 0, 2, 2, 2, 4, 0, 618 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
642 2, 1, 1, 2, 2, 2, 1, 2, 0, 2, 619 2, 2, 4, 0, 2, 2, 2, 0, 2, 1,
643 1, 3, 3, 3, 2, 3, 3, 1, 1, 0, 620 1, 2, 2, 2, 1, 2, 0, 2, 1, 3,
644 1 621 3, 3, 2, 3, 3, 1, 1, 0, 1
645}; 622};
646 623
647/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 624/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -649,158 +626,172 @@ static const yytype_uint8 yyr2[] =
649 means the default is an error. */ 626 means the default is an error. */
650static const yytype_uint8 yydefact[] = 627static const yytype_uint8 yydefact[] =
651{ 628{
652 3, 0, 0, 1, 0, 0, 0, 0, 0, 109, 629 6, 0, 104, 0, 3, 0, 6, 6, 99, 100,
653 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, 630 0, 1, 0, 0, 0, 0, 117, 0, 0, 0,
654 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, 631 0, 0, 0, 14, 18, 15, 16, 20, 17, 19,
655 23, 52, 62, 5, 67, 20, 84, 75, 6, 24, 632 21, 0, 22, 0, 7, 34, 25, 34, 26, 55,
656 84, 21, 8, 11, 91, 92, 0, 0, 93, 0, 633 65, 8, 70, 23, 93, 79, 9, 27, 88, 24,
657 110, 0, 94, 0, 0, 0, 107, 108, 0, 0, 634 10, 0, 105, 2, 74, 13, 0, 101, 0, 118,
658 0, 100, 95, 0, 0, 0, 0, 0, 0, 0, 635 0, 102, 0, 0, 0, 115, 116, 0, 0, 0,
659 0, 0, 0, 96, 7, 71, 79, 48, 80, 27, 636 108, 103, 0, 0, 0, 0, 0, 0, 0, 88,
660 29, 0, 104, 0, 0, 64, 0, 0, 9, 10, 637 0, 0, 75, 83, 51, 84, 30, 32, 0, 112,
661 0, 0, 0, 0, 89, 0, 0, 0, 44, 0, 638 0, 0, 67, 0, 0, 11, 12, 0, 0, 0,
662 37, 36, 32, 33, 0, 35, 34, 0, 0, 89, 639 0, 97, 0, 0, 0, 47, 0, 40, 39, 35,
663 0, 56, 57, 53, 55, 54, 63, 51, 50, 68, 640 36, 0, 38, 37, 0, 0, 97, 0, 59, 60,
664 70, 66, 69, 65, 86, 87, 85, 76, 78, 74, 641 56, 58, 57, 66, 54, 53, 71, 73, 69, 72,
665 77, 73, 97, 103, 105, 106, 102, 101, 26, 82, 642 68, 106, 95, 0, 94, 80, 82, 78, 81, 77,
666 0, 98, 0, 98, 98, 98, 0, 0, 0, 83, 643 90, 91, 89, 111, 113, 114, 110, 109, 29, 86,
667 60, 98, 0, 98, 0, 0, 0, 38, 90, 0, 644 0, 106, 0, 106, 106, 106, 0, 0, 0, 87,
668 0, 98, 46, 43, 25, 0, 59, 0, 88, 99, 645 63, 106, 0, 106, 0, 96, 0, 0, 41, 98,
669 39, 40, 41, 0, 0, 45, 58, 61, 42, 47 646 0, 0, 106, 49, 46, 28, 0, 62, 0, 107,
647 92, 42, 43, 44, 0, 0, 48, 61, 64, 45,
648 50
670}; 649};
671 650
672/* YYDEFGOTO[NTERM-NUM]. */ 651/* YYDEFGOTO[NTERM-NUM]. */
673static const yytype_int16 yydefgoto[] = 652static const yytype_int16 yydefgoto[] =
674{ 653{
675 -1, 1, 2, 25, 26, 101, 27, 28, 29, 30, 654 -1, 3, 4, 5, 33, 34, 108, 35, 36, 37,
676 65, 102, 103, 147, 175, 31, 32, 117, 33, 67, 655 38, 74, 109, 110, 157, 186, 39, 40, 124, 41,
677 113, 68, 34, 121, 35, 69, 36, 37, 129, 38, 656 76, 120, 77, 42, 128, 43, 78, 6, 44, 45,
678 71, 39, 40, 41, 104, 105, 70, 106, 142, 143, 657 137, 46, 80, 47, 48, 49, 111, 112, 81, 113,
679 42, 74, 156, 60, 61, 51 658 79, 134, 152, 153, 50, 7, 165, 69, 70, 60
680}; 659};
681 660
682/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 661/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
683 STATE-NUM. */ 662 STATE-NUM. */
684#define YYPACT_NINF -80 663#define YYPACT_NINF -90
685static const yytype_int16 yypact[] = 664static const yytype_int16 yypact[] =
686{ 665{
687 -80, 2, 132, -80, -13, -1, -1, -2, -1, 9, 666 4, 42, -90, 96, -90, 111, -90, 15, -90, -90,
688 33, -1, 27, 40, -3, 38, -80, -80, -80, -80, 667 75, -90, 82, 42, 104, 42, 110, 107, 42, 115,
689 -80, -80, -80, 71, -80, 77, -80, -80, -80, -80, 668 125, -4, 121, -90, -90, -90, -90, -90, -90, -90,
690 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 669 -90, 162, -90, 163, -90, -90, -90, -90, -90, -90,
691 -80, -80, -80, -80, -80, -80, 57, 61, -80, 63, 670 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
692 -80, 76, -80, 87, 101, 133, -80, -80, -3, -3, 671 -90, 139, -90, -90, 138, -90, 142, -90, 143, -90,
693 195, -6, -80, 136, 149, 39, 104, 65, 150, 5, 672 152, -90, 164, 167, 168, -90, -90, -4, -4, 77,
694 194, 5, 167, -80, 176, -80, -80, -80, -80, -80, 673 -18, -90, 177, 185, 33, 71, 195, 247, 236, -2,
695 -80, 68, -80, -3, -3, 176, 72, 72, -80, -80, 674 236, 171, -90, -90, -90, -90, -90, -90, 41, -90,
696 177, 187, 78, -1, -1, -3, 196, 72, -80, 222, 675 -4, -4, 138, 97, 97, -90, -90, 186, 187, 194,
697 -80, -80, -80, -80, 221, -80, -80, 205, -1, -1, 676 42, 42, -4, 196, 97, -90, 219, -90, -90, -90,
698 211, -80, -80, -80, -80, -80, -80, -80, -80, -80, 677 -90, 210, -90, -90, 204, 42, 42, 199, -90, -90,
699 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 678 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
700 -80, -80, -80, -80, 206, -80, -80, -80, -80, -80, 679 -90, 222, -90, 223, -90, -90, -90, -90, -90, -90,
701 -3, 223, 209, 223, 197, 223, 72, 7, 210, -80, 680 -90, -90, -90, -90, 215, -90, -90, -90, -90, -90,
702 -80, 223, 212, 223, 201, -3, 213, -80, -80, 214, 681 -4, 222, 228, 222, -5, 222, 97, 35, 229, -90,
703 215, 223, 208, -80, -80, 216, -80, 217, -80, 113, 682 -90, 222, 232, 222, -4, -90, 135, 233, -90, -90,
704 -80, -80, -80, 218, -1, -80, -80, -80, -80, -80 683 234, 235, 222, 240, -90, -90, 237, -90, 239, -13,
684 -90, -90, -90, -90, 244, 42, -90, -90, -90, -90,
685 -90
705}; 686};
706 687
707/* YYPGOTO[NTERM-NUM]. */ 688/* YYPGOTO[NTERM-NUM]. */
708static const yytype_int16 yypgoto[] = 689static const yytype_int16 yypgoto[] =
709{ 690{
710 -80, -80, -80, -80, 122, -34, -80, -80, -80, -80, 691 -90, -90, 269, 271, -90, 23, -70, -90, -90, -90,
711 220, -80, -80, -80, -80, -80, -80, -80, 59, -80, 692 -90, 243, -90, -90, -90, -90, -90, -90, -90, -48,
712 -80, -80, -80, -80, -80, -80, -80, -80, -80, 125, 693 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
713 -80, -80, -80, -80, -80, 183, 219, 22, 142, -5, 694 -90, -20, -90, -90, -90, -90, -90, 206, 205, -68,
714 147, 192, 69, -54, -79, -80 695 -90, -90, 169, -1, 27, -7, 118, -66, -89, -90
715}; 696};
716 697
717/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 698/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
718 positive, shift that token. If negative, reduce the rule which 699 positive, shift that token. If negative, reduce the rule which
719 number is the opposite. If zero, do what YYDEFACT says. 700 number is the opposite. If zero, do what YYDEFACT says.
720 If YYTABLE_NINF, syntax error. */ 701 If YYTABLE_NINF, syntax error. */
721#define YYTABLE_NINF -82 702#define YYTABLE_NINF -86
722static const yytype_int16 yytable[] = 703static const yytype_int16 yytable[] =
723{ 704{
724 46, 47, 3, 49, 81, 82, 53, 136, 137, 6, 705 10, 88, 89, 54, 146, 147, 119, 1, 122, 164,
725 7, 8, 9, 10, 11, 12, 13, 43, 146, 14, 706 93, 141, 56, 142, 58, 156, 94, 62, 1, 90,
726 15, 86, 56, 57, 44, 45, 58, 87, 48, 134, 707 91, 131, 65, 66, 144, 145, 67, 90, 91, 132,
727 135, 59, 162, 112, 50, 24, 125, 163, 125, -28, 708 127, 68, 136, -31, 97, 2, 154, -31, -31, -31,
728 90, 144, -28, -28, -28, -28, -28, -28, -28, -28, 709 -31, -31, -31, -31, -31, 98, 52, -31, -31, 99,
729 -28, 91, 54, -28, -28, 92, -28, 93, 94, 95, 710 -31, 100, 101, 102, 103, 104, -31, 105, 129, 106,
730 96, 97, 98, 52, 99, 55, 90, 161, 62, 100, 711 138, 173, 92, 141, 107, 142, 174, 172, 8, 9,
731 -49, -49, 63, -49, -49, -49, -49, 91, 64, -49, 712 143, -33, 97, 90, 91, -33, -33, -33, -33, -33,
732 -49, 92, 107, 108, 109, 110, 154, 73, 141, 115, 713 -33, -33, -33, 98, 166, -33, -33, 99, -33, 100,
733 99, 75, 126, 76, 126, 111, 133, 56, 57, 83, 714 101, 102, 103, 104, -33, 105, 11, 106, 179, 151,
734 84, 169, 140, 151, -30, 90, 77, -30, -30, -30, 715 123, 126, 107, 135, 125, 130, 2, 139, 2, 90,
735 -30, -30, -30, -30, -30, -30, 91, 78, -30, -30, 716 91, -5, 12, 55, 161, 13, 14, 15, 16, 17,
736 92, -30, 93, 94, 95, 96, 97, 98, 120, 99, 717 18, 19, 20, 65, 66, 21, 22, 23, 24, 25,
737 128, 79, -2, 4, 100, 5, 6, 7, 8, 9, 718 26, 27, 28, 29, 30, 57, 59, 31, 61, -4,
738 10, 11, 12, 13, 83, 84, 14, 15, 16, 17, 719 12, 63, 32, 13, 14, 15, 16, 17, 18, 19,
739 18, 19, 20, 21, 22, 7, 8, 23, 10, 11, 720 20, 64, 71, 21, 22, 23, 24, 25, 26, 27,
740 12, 13, 24, 80, 14, 15, 88, -81, 90, 179, 721 28, 29, 30, 72, 73, 31, 180, 90, 91, 52,
741 -81, -81, -81, -81, -81, -81, -81, -81, -81, 89, 722 32, -85, 97, 82, 83, -85, -85, -85, -85, -85,
742 24, -81, -81, 92, -81, -81, -81, -81, -81, -81, 723 -85, -85, -85, 84, 190, -85, -85, 99, -85, -85,
743 116, 119, 99, 127, 122, 90, 130, 124, -72, -72, 724 -85, -85, -85, -85, -85, 85, 97, 106, 86, 87,
744 -72, -72, -72, -72, -72, -72, 132, 138, -72, -72, 725 -52, -52, 140, -52, -52, -52, -52, 98, 95, -52,
745 92, 155, 158, 159, 160, 118, 123, 139, 131, 99, 726 -52, 99, 114, 115, 116, 117, 96, 148, 149, 150,
746 165, 145, 167, 148, 124, 73, 83, 84, 83, 84, 727 158, 106, 155, 159, 97, 163, 118, -76, -76, -76,
747 173, 168, 83, 84, 149, 150, 153, 155, 84, 157, 728 -76, -76, -76, -76, -76, 160, 164, -76, -76, 99,
748 164, 174, 166, 170, 171, 172, 176, 177, 178, 66, 729 13, 14, 15, 16, 17, 18, 19, 20, 91, 106,
749 114, 152, 85, 0, 0, 0, 0, 0, 0, 72 730 21, 22, 14, 15, 140, 17, 18, 19, 20, 168,
731 175, 21, 22, 177, 181, 182, 183, 32, 187, 167,
732 188, 169, 170, 171, 185, 189, 53, 51, 32, 176,
733 75, 178, 121, 0, 133, 162, 0, 0, 0, 0,
734 184
750}; 735};
751 736
752static const yytype_int16 yycheck[] = 737static const yytype_int16 yycheck[] =
753{ 738{
754 5, 6, 0, 8, 58, 59, 11, 86, 87, 4, 739 1, 67, 68, 10, 93, 94, 76, 3, 76, 14,
755 5, 6, 7, 8, 9, 10, 11, 30, 97, 14, 740 28, 81, 13, 81, 15, 104, 34, 18, 3, 32,
756 15, 27, 25, 26, 25, 26, 29, 33, 30, 83, 741 33, 23, 26, 27, 90, 91, 30, 32, 33, 31,
757 84, 34, 25, 67, 25, 30, 70, 30, 72, 0, 742 78, 35, 80, 0, 1, 31, 102, 4, 5, 6,
758 1, 95, 3, 4, 5, 6, 7, 8, 9, 10, 743 7, 8, 9, 10, 11, 12, 31, 14, 15, 16,
759 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, 744 17, 18, 19, 20, 21, 22, 23, 24, 78, 26,
760 21, 22, 23, 30, 25, 25, 1, 146, 30, 30, 745 80, 26, 69, 133, 31, 133, 31, 156, 26, 27,
761 5, 6, 1, 8, 9, 10, 11, 12, 1, 14, 746 29, 0, 1, 32, 33, 4, 5, 6, 7, 8,
762 15, 16, 17, 18, 19, 20, 140, 30, 93, 67, 747 9, 10, 11, 12, 150, 14, 15, 16, 17, 18,
763 25, 30, 70, 30, 72, 30, 28, 25, 26, 31, 748 19, 20, 21, 22, 23, 24, 0, 26, 164, 100,
764 32, 155, 24, 108, 0, 1, 30, 3, 4, 5, 749 77, 78, 31, 80, 77, 78, 31, 80, 31, 32,
765 6, 7, 8, 9, 10, 11, 12, 30, 14, 15, 750 33, 0, 1, 31, 115, 4, 5, 6, 7, 8,
766 16, 17, 18, 19, 20, 21, 22, 23, 69, 25, 751 9, 10, 11, 26, 27, 14, 15, 16, 17, 18,
767 71, 30, 0, 1, 30, 3, 4, 5, 6, 7, 752 19, 20, 21, 22, 23, 31, 26, 26, 31, 0,
768 8, 9, 10, 11, 31, 32, 14, 15, 16, 17, 753 1, 26, 31, 4, 5, 6, 7, 8, 9, 10,
769 18, 19, 20, 21, 22, 5, 6, 25, 8, 9, 754 11, 26, 31, 14, 15, 16, 17, 18, 19, 20,
770 10, 11, 30, 30, 14, 15, 30, 0, 1, 174, 755 21, 22, 23, 1, 1, 26, 31, 32, 33, 31,
771 3, 4, 5, 6, 7, 8, 9, 10, 11, 30, 756 31, 0, 1, 31, 31, 4, 5, 6, 7, 8,
772 30, 14, 15, 16, 17, 18, 19, 20, 21, 22, 757 9, 10, 11, 31, 185, 14, 15, 16, 17, 18,
773 68, 69, 25, 71, 69, 1, 71, 30, 4, 5, 758 19, 20, 21, 22, 23, 31, 1, 26, 31, 31,
774 6, 7, 8, 9, 10, 11, 30, 30, 14, 15, 759 5, 6, 31, 8, 9, 10, 11, 12, 31, 14,
775 16, 14, 143, 144, 145, 68, 69, 30, 71, 25, 760 15, 16, 17, 18, 19, 20, 31, 31, 31, 25,
776 151, 25, 153, 1, 30, 30, 31, 32, 31, 32, 761 1, 26, 26, 13, 1, 26, 31, 4, 5, 6,
777 161, 30, 31, 32, 13, 30, 25, 14, 32, 30, 762 7, 8, 9, 10, 11, 31, 14, 14, 15, 16,
778 30, 33, 30, 30, 30, 30, 30, 30, 30, 29, 763 4, 5, 6, 7, 8, 9, 10, 11, 33, 26,
779 67, 109, 60, -1, -1, -1, -1, -1, -1, 40 764 14, 15, 5, 6, 31, 8, 9, 10, 11, 31,
765 31, 14, 15, 31, 31, 31, 31, 31, 31, 151,
766 31, 153, 154, 155, 34, 31, 7, 6, 31, 161,
767 37, 163, 76, -1, 79, 116, -1, -1, -1, -1,
768 172
780}; 769};
781 770
782/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 771/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
783 symbol of state STATE-NUM. */ 772 symbol of state STATE-NUM. */
784static const yytype_uint8 yystos[] = 773static const yytype_uint8 yystos[] =
785{ 774{
786 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, 775 0, 3, 31, 37, 38, 39, 63, 81, 26, 27,
787 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 776 79, 0, 1, 4, 5, 6, 7, 8, 9, 10,
788 20, 21, 22, 25, 30, 38, 39, 41, 42, 43, 777 11, 14, 15, 16, 17, 18, 19, 20, 21, 22,
789 44, 50, 51, 53, 57, 59, 61, 62, 64, 66, 778 23, 26, 31, 40, 41, 43, 44, 45, 46, 52,
790 67, 68, 75, 30, 25, 26, 74, 74, 30, 74, 779 53, 55, 59, 61, 64, 65, 67, 69, 70, 71,
791 25, 80, 30, 74, 25, 25, 25, 26, 29, 34, 780 80, 39, 31, 38, 81, 31, 79, 31, 79, 26,
792 78, 79, 30, 1, 1, 45, 45, 54, 56, 60, 781 85, 31, 79, 26, 26, 26, 27, 30, 35, 83,
793 71, 65, 71, 30, 76, 30, 30, 30, 30, 30, 782 84, 31, 1, 1, 47, 47, 56, 58, 62, 76,
794 30, 78, 78, 31, 32, 76, 27, 33, 30, 30, 783 68, 74, 31, 31, 31, 31, 31, 31, 83, 83,
795 1, 12, 16, 18, 19, 20, 21, 22, 23, 25, 784 32, 33, 81, 28, 34, 31, 31, 1, 12, 16,
796 30, 40, 46, 47, 69, 70, 72, 17, 18, 19, 785 18, 19, 20, 21, 22, 24, 26, 31, 42, 48,
797 20, 30, 40, 55, 70, 72, 39, 52, 75, 39, 786 49, 72, 73, 75, 17, 18, 19, 20, 31, 42,
798 53, 58, 64, 75, 30, 40, 72, 39, 53, 63, 787 57, 73, 75, 41, 54, 80, 41, 55, 60, 67,
799 64, 75, 30, 28, 78, 78, 79, 79, 30, 30, 788 80, 23, 31, 74, 77, 41, 55, 66, 67, 80,
800 24, 74, 73, 74, 78, 25, 79, 48, 1, 13, 789 31, 42, 75, 29, 83, 83, 84, 84, 31, 31,
801 30, 74, 73, 25, 78, 14, 77, 30, 77, 77, 790 25, 79, 78, 79, 83, 26, 84, 50, 1, 13,
802 77, 79, 25, 30, 30, 77, 30, 77, 30, 78, 791 31, 79, 78, 26, 14, 82, 83, 82, 31, 82,
803 30, 30, 30, 77, 33, 49, 30, 30, 30, 74 792 82, 82, 84, 26, 31, 31, 82, 31, 82, 83,
793 31, 31, 31, 31, 82, 34, 51, 31, 31, 31,
794 79
804}; 795};
805 796
806#define yyerrok (yyerrstatus = 0) 797#define yyerrok (yyerrstatus = 0)
@@ -985,17 +976,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
985#if (defined __STDC__ || defined __C99__FUNC__ \ 976#if (defined __STDC__ || defined __C99__FUNC__ \
986 || defined __cplusplus || defined _MSC_VER) 977 || defined __cplusplus || defined _MSC_VER)
987static void 978static void
988yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) 979yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
989#else 980#else
990static void 981static void
991yy_stack_print (bottom, top) 982yy_stack_print (yybottom, yytop)
992 yytype_int16 *bottom; 983 yytype_int16 *yybottom;
993 yytype_int16 *top; 984 yytype_int16 *yytop;
994#endif 985#endif
995{ 986{
996 YYFPRINTF (stderr, "Stack now"); 987 YYFPRINTF (stderr, "Stack now");
997 for (; bottom <= top; ++bottom) 988 for (; yybottom <= yytop; yybottom++)
998 YYFPRINTF (stderr, " %d", *bottom); 989 {
990 int yybot = *yybottom;
991 YYFPRINTF (stderr, " %d", yybot);
992 }
999 YYFPRINTF (stderr, "\n"); 993 YYFPRINTF (stderr, "\n");
1000} 994}
1001 995
@@ -1029,11 +1023,11 @@ yy_reduce_print (yyvsp, yyrule)
1029 /* The symbols being reduced. */ 1023 /* The symbols being reduced. */
1030 for (yyi = 0; yyi < yynrhs; yyi++) 1024 for (yyi = 0; yyi < yynrhs; yyi++)
1031 { 1025 {
1032 fprintf (stderr, " $%d = ", yyi + 1); 1026 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1033 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], 1027 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1034 &(yyvsp[(yyi + 1) - (yynrhs)]) 1028 &(yyvsp[(yyi + 1) - (yynrhs)])
1035 ); 1029 );
1036 fprintf (stderr, "\n"); 1030 YYFPRINTF (stderr, "\n");
1037 } 1031 }
1038} 1032}
1039 1033
@@ -1308,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep)
1308 1302
1309 switch (yytype) 1303 switch (yytype)
1310 { 1304 {
1311 case 51: /* "choice_entry" */ 1305 case 53: /* "choice_entry" */
1312 1306
1313 { 1307 {
1314 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1308 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1318,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep)
1318}; 1312};
1319 1313
1320 break; 1314 break;
1321 case 57: /* "if_entry" */ 1315 case 59: /* "if_entry" */
1322 1316
1323 { 1317 {
1324 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1318 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1328,7 +1322,7 @@ yydestruct (yymsg, yytype, yyvaluep)
1328}; 1322};
1329 1323
1330 break; 1324 break;
1331 case 62: /* "menu_entry" */ 1325 case 65: /* "menu_entry" */
1332 1326
1333 { 1327 {
1334 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1328 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1343,10 +1337,8 @@ yydestruct (yymsg, yytype, yyvaluep)
1343 break; 1337 break;
1344 } 1338 }
1345} 1339}
1346
1347 1340
1348/* Prevent warnings from -Wmissing-prototypes. */ 1341/* Prevent warnings from -Wmissing-prototypes. */
1349
1350#ifdef YYPARSE_PARAM 1342#ifdef YYPARSE_PARAM
1351#if defined __STDC__ || defined __cplusplus 1343#if defined __STDC__ || defined __cplusplus
1352int yyparse (void *YYPARSE_PARAM); 1344int yyparse (void *YYPARSE_PARAM);
@@ -1362,11 +1354,10 @@ int yyparse ();
1362#endif /* ! YYPARSE_PARAM */ 1354#endif /* ! YYPARSE_PARAM */
1363 1355
1364 1356
1365 1357/* The lookahead symbol. */
1366/* The look-ahead symbol. */
1367int yychar; 1358int yychar;
1368 1359
1369/* The semantic value of the look-ahead symbol. */ 1360/* The semantic value of the lookahead symbol. */
1370YYSTYPE yylval; 1361YYSTYPE yylval;
1371 1362
1372/* Number of syntax errors so far. */ 1363/* Number of syntax errors so far. */
@@ -1374,9 +1365,9 @@ int yynerrs;
1374 1365
1375 1366
1376 1367
1377/*----------. 1368/*-------------------------.
1378| yyparse. | 1369| yyparse or yypush_parse. |
1379`----------*/ 1370`-------------------------*/
1380 1371
1381#ifdef YYPARSE_PARAM 1372#ifdef YYPARSE_PARAM
1382#if (defined __STDC__ || defined __C99__FUNC__ \ 1373#if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1400,66 +1391,68 @@ yyparse ()
1400#endif 1391#endif
1401#endif 1392#endif
1402{ 1393{
1403
1404 int yystate;
1405 int yyn;
1406 int yyresult;
1407 /* Number of tokens to shift before error messages enabled. */
1408 int yyerrstatus;
1409 /* Look-ahead token as an internal (translated) token number. */
1410 int yytoken = 0;
1411#if YYERROR_VERBOSE
1412 /* Buffer for error messages, and its allocated size. */
1413 char yymsgbuf[128];
1414 char *yymsg = yymsgbuf;
1415 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1416#endif
1417
1418 /* Three stacks and their tools:
1419 `yyss': related to states,
1420 `yyvs': related to semantic values,
1421 `yyls': related to locations.
1422 1394
1423 Refer to the stacks thru separate pointers, to allow yyoverflow
1424 to reallocate them elsewhere. */
1425 1395
1426 /* The state stack. */ 1396 int yystate;
1427 yytype_int16 yyssa[YYINITDEPTH]; 1397 /* Number of tokens to shift before error messages enabled. */
1428 yytype_int16 *yyss = yyssa; 1398 int yyerrstatus;
1429 yytype_int16 *yyssp;
1430 1399
1431 /* The semantic value stack. */ 1400 /* The stacks and their tools:
1432 YYSTYPE yyvsa[YYINITDEPTH]; 1401 `yyss': related to states.
1433 YYSTYPE *yyvs = yyvsa; 1402 `yyvs': related to semantic values.
1434 YYSTYPE *yyvsp;
1435 1403
1404 Refer to the stacks thru separate pointers, to allow yyoverflow
1405 to reallocate them elsewhere. */
1436 1406
1407 /* The state stack. */
1408 yytype_int16 yyssa[YYINITDEPTH];
1409 yytype_int16 *yyss;
1410 yytype_int16 *yyssp;
1437 1411
1438#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) 1412 /* The semantic value stack. */
1413 YYSTYPE yyvsa[YYINITDEPTH];
1414 YYSTYPE *yyvs;
1415 YYSTYPE *yyvsp;
1439 1416
1440 YYSIZE_T yystacksize = YYINITDEPTH; 1417 YYSIZE_T yystacksize;
1441 1418
1419 int yyn;
1420 int yyresult;
1421 /* Lookahead token as an internal (translated) token number. */
1422 int yytoken;
1442 /* The variables used to return semantic value and location from the 1423 /* The variables used to return semantic value and location from the
1443 action routines. */ 1424 action routines. */
1444 YYSTYPE yyval; 1425 YYSTYPE yyval;
1445 1426
1427#if YYERROR_VERBOSE
1428 /* Buffer for error messages, and its allocated size. */
1429 char yymsgbuf[128];
1430 char *yymsg = yymsgbuf;
1431 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1432#endif
1433
1434#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1446 1435
1447 /* The number of symbols on the RHS of the reduced rule. 1436 /* The number of symbols on the RHS of the reduced rule.
1448 Keep to zero when no symbol should be popped. */ 1437 Keep to zero when no symbol should be popped. */
1449 int yylen = 0; 1438 int yylen = 0;
1450 1439
1440 yytoken = 0;
1441 yyss = yyssa;
1442 yyvs = yyvsa;
1443 yystacksize = YYINITDEPTH;
1444
1451 YYDPRINTF ((stderr, "Starting parse\n")); 1445 YYDPRINTF ((stderr, "Starting parse\n"));
1452 1446
1453 yystate = 0; 1447 yystate = 0;
1454 yyerrstatus = 0; 1448 yyerrstatus = 0;
1455 yynerrs = 0; 1449 yynerrs = 0;
1456 yychar = YYEMPTY; /* Cause a token to be read. */ 1450 yychar = YYEMPTY; /* Cause a token to be read. */
1457 1451
1458 /* Initialize stack pointers. 1452 /* Initialize stack pointers.
1459 Waste one element of value and location stack 1453 Waste one element of value and location stack
1460 so that they stay on the same level as the state stack. 1454 so that they stay on the same level as the state stack.
1461 The wasted elements are never initialized. */ 1455 The wasted elements are never initialized. */
1462
1463 yyssp = yyss; 1456 yyssp = yyss;
1464 yyvsp = yyvs; 1457 yyvsp = yyvs;
1465 1458
@@ -1489,7 +1482,6 @@ yyparse ()
1489 YYSTYPE *yyvs1 = yyvs; 1482 YYSTYPE *yyvs1 = yyvs;
1490 yytype_int16 *yyss1 = yyss; 1483 yytype_int16 *yyss1 = yyss;
1491 1484
1492
1493 /* Each stack pointer address is followed by the size of the 1485 /* Each stack pointer address is followed by the size of the
1494 data in use in that stack, in bytes. This used to be a 1486 data in use in that stack, in bytes. This used to be a
1495 conditional around just the two extra args, but that might 1487 conditional around just the two extra args, but that might
@@ -1497,7 +1489,6 @@ yyparse ()
1497 yyoverflow (YY_("memory exhausted"), 1489 yyoverflow (YY_("memory exhausted"),
1498 &yyss1, yysize * sizeof (*yyssp), 1490 &yyss1, yysize * sizeof (*yyssp),
1499 &yyvs1, yysize * sizeof (*yyvsp), 1491 &yyvs1, yysize * sizeof (*yyvsp),
1500
1501 &yystacksize); 1492 &yystacksize);
1502 1493
1503 yyss = yyss1; 1494 yyss = yyss1;
@@ -1520,9 +1511,8 @@ yyparse ()
1520 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1511 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1521 if (! yyptr) 1512 if (! yyptr)
1522 goto yyexhaustedlab; 1513 goto yyexhaustedlab;
1523 YYSTACK_RELOCATE (yyss); 1514 YYSTACK_RELOCATE (yyss_alloc, yyss);
1524 YYSTACK_RELOCATE (yyvs); 1515 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1525
1526# undef YYSTACK_RELOCATE 1516# undef YYSTACK_RELOCATE
1527 if (yyss1 != yyssa) 1517 if (yyss1 != yyssa)
1528 YYSTACK_FREE (yyss1); 1518 YYSTACK_FREE (yyss1);
@@ -1533,7 +1523,6 @@ yyparse ()
1533 yyssp = yyss + yysize - 1; 1523 yyssp = yyss + yysize - 1;
1534 yyvsp = yyvs + yysize - 1; 1524 yyvsp = yyvs + yysize - 1;
1535 1525
1536
1537 YYDPRINTF ((stderr, "Stack size increased to %lu\n", 1526 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1538 (unsigned long int) yystacksize)); 1527 (unsigned long int) yystacksize));
1539 1528
@@ -1543,6 +1532,9 @@ yyparse ()
1543 1532
1544 YYDPRINTF ((stderr, "Entering state %d\n", yystate)); 1533 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1545 1534
1535 if (yystate == YYFINAL)
1536 YYACCEPT;
1537
1546 goto yybackup; 1538 goto yybackup;
1547 1539
1548/*-----------. 1540/*-----------.
@@ -1551,16 +1543,16 @@ yyparse ()
1551yybackup: 1543yybackup:
1552 1544
1553 /* Do appropriate processing given the current state. Read a 1545 /* Do appropriate processing given the current state. Read a
1554 look-ahead token if we need one and don't already have one. */ 1546 lookahead token if we need one and don't already have one. */
1555 1547
1556 /* First try to decide what to do without reference to look-ahead token. */ 1548 /* First try to decide what to do without reference to lookahead token. */
1557 yyn = yypact[yystate]; 1549 yyn = yypact[yystate];
1558 if (yyn == YYPACT_NINF) 1550 if (yyn == YYPACT_NINF)
1559 goto yydefault; 1551 goto yydefault;
1560 1552
1561 /* Not known => get a look-ahead token if don't already have one. */ 1553 /* Not known => get a lookahead token if don't already have one. */
1562 1554
1563 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ 1555 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1564 if (yychar == YYEMPTY) 1556 if (yychar == YYEMPTY)
1565 { 1557 {
1566 YYDPRINTF ((stderr, "Reading a token: ")); 1558 YYDPRINTF ((stderr, "Reading a token: "));
@@ -1592,20 +1584,16 @@ yybackup:
1592 goto yyreduce; 1584 goto yyreduce;
1593 } 1585 }
1594 1586
1595 if (yyn == YYFINAL)
1596 YYACCEPT;
1597
1598 /* Count tokens shifted since error; after three, turn off error 1587 /* Count tokens shifted since error; after three, turn off error
1599 status. */ 1588 status. */
1600 if (yyerrstatus) 1589 if (yyerrstatus)
1601 yyerrstatus--; 1590 yyerrstatus--;
1602 1591
1603 /* Shift the look-ahead token. */ 1592 /* Shift the lookahead token. */
1604 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); 1593 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1605 1594
1606 /* Discard the shifted token unless it is eof. */ 1595 /* Discard the shifted token. */
1607 if (yychar != YYEOF) 1596 yychar = YYEMPTY;
1608 yychar = YYEMPTY;
1609 1597
1610 yystate = yyn; 1598 yystate = yyn;
1611 *++yyvsp = yylval; 1599 *++yyvsp = yylval;
@@ -1644,39 +1632,39 @@ yyreduce:
1644 YY_REDUCE_PRINT (yyn); 1632 YY_REDUCE_PRINT (yyn);
1645 switch (yyn) 1633 switch (yyn)
1646 { 1634 {
1647 case 8: 1635 case 10:
1648 1636
1649 { zconf_error("unexpected end statement"); ;} 1637 { zconf_error("unexpected end statement"); ;}
1650 break; 1638 break;
1651 1639
1652 case 9: 1640 case 11:
1653 1641
1654 { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;} 1642 { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;}
1655 break; 1643 break;
1656 1644
1657 case 10: 1645 case 12:
1658 1646
1659 { 1647 {
1660 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name); 1648 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name);
1661;} 1649;}
1662 break; 1650 break;
1663 1651
1664 case 11: 1652 case 13:
1665 1653
1666 { zconf_error("invalid statement"); ;} 1654 { zconf_error("invalid statement"); ;}
1667 break; 1655 break;
1668 1656
1669 case 25: 1657 case 28:
1670 1658
1671 { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;} 1659 { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
1672 break; 1660 break;
1673 1661
1674 case 26: 1662 case 29:
1675 1663
1676 { zconf_error("invalid option"); ;} 1664 { zconf_error("invalid option"); ;}
1677 break; 1665 break;
1678 1666
1679 case 27: 1667 case 30:
1680 1668
1681 { 1669 {
1682 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); 1670 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1686,7 +1674,7 @@ yyreduce:
1686;} 1674;}
1687 break; 1675 break;
1688 1676
1689 case 28: 1677 case 31:
1690 1678
1691 { 1679 {
1692 menu_end_entry(); 1680 menu_end_entry();
@@ -1694,7 +1682,7 @@ yyreduce:
1694;} 1682;}
1695 break; 1683 break;
1696 1684
1697 case 29: 1685 case 32:
1698 1686
1699 { 1687 {
1700 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0); 1688 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1704,7 +1692,7 @@ yyreduce:
1704;} 1692;}
1705 break; 1693 break;
1706 1694
1707 case 30: 1695 case 33:
1708 1696
1709 { 1697 {
1710 if (current_entry->prompt) 1698 if (current_entry->prompt)
@@ -1716,7 +1704,7 @@ yyreduce:
1716;} 1704;}
1717 break; 1705 break;
1718 1706
1719 case 38: 1707 case 41:
1720 1708
1721 { 1709 {
1722 menu_set_type((yyvsp[(1) - (3)].id)->stype); 1710 menu_set_type((yyvsp[(1) - (3)].id)->stype);
@@ -1726,7 +1714,7 @@ yyreduce:
1726;} 1714;}
1727 break; 1715 break;
1728 1716
1729 case 39: 1717 case 42:
1730 1718
1731 { 1719 {
1732 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); 1720 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1734,7 +1722,7 @@ yyreduce:
1734;} 1722;}
1735 break; 1723 break;
1736 1724
1737 case 40: 1725 case 43:
1738 1726
1739 { 1727 {
1740 menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr)); 1728 menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
@@ -1746,7 +1734,7 @@ yyreduce:
1746;} 1734;}
1747 break; 1735 break;
1748 1736
1749 case 41: 1737 case 44:
1750 1738
1751 { 1739 {
1752 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr)); 1740 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
@@ -1754,7 +1742,7 @@ yyreduce:
1754;} 1742;}
1755 break; 1743 break;
1756 1744
1757 case 42: 1745 case 45:
1758 1746
1759 { 1747 {
1760 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr)); 1748 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
@@ -1762,7 +1750,7 @@ yyreduce:
1762;} 1750;}
1763 break; 1751 break;
1764 1752
1765 case 45: 1753 case 48:
1766 1754
1767 { 1755 {
1768 struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string))); 1756 struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
@@ -1774,17 +1762,17 @@ yyreduce:
1774;} 1762;}
1775 break; 1763 break;
1776 1764
1777 case 46: 1765 case 49:
1778 1766
1779 { (yyval.string) = NULL; ;} 1767 { (yyval.string) = NULL; ;}
1780 break; 1768 break;
1781 1769
1782 case 47: 1770 case 50:
1783 1771
1784 { (yyval.string) = (yyvsp[(2) - (2)].string); ;} 1772 { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
1785 break; 1773 break;
1786 1774
1787 case 48: 1775 case 51:
1788 1776
1789 { 1777 {
1790 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE); 1778 struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
@@ -1795,14 +1783,14 @@ yyreduce:
1795;} 1783;}
1796 break; 1784 break;
1797 1785
1798 case 49: 1786 case 52:
1799 1787
1800 { 1788 {
1801 (yyval.menu) = menu_add_menu(); 1789 (yyval.menu) = menu_add_menu();
1802;} 1790;}
1803 break; 1791 break;
1804 1792
1805 case 50: 1793 case 53:
1806 1794
1807 { 1795 {
1808 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) { 1796 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
@@ -1812,7 +1800,7 @@ yyreduce:
1812;} 1800;}
1813 break; 1801 break;
1814 1802
1815 case 58: 1803 case 61:
1816 1804
1817 { 1805 {
1818 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr)); 1806 menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1820,7 +1808,7 @@ yyreduce:
1820;} 1808;}
1821 break; 1809 break;
1822 1810
1823 case 59: 1811 case 62:
1824 1812
1825 { 1813 {
1826 if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) { 1814 if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
@@ -1833,7 +1821,7 @@ yyreduce:
1833;} 1821;}
1834 break; 1822 break;
1835 1823
1836 case 60: 1824 case 63:
1837 1825
1838 { 1826 {
1839 current_entry->sym->flags |= SYMBOL_OPTIONAL; 1827 current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1841,7 +1829,7 @@ yyreduce:
1841;} 1829;}
1842 break; 1830 break;
1843 1831
1844 case 61: 1832 case 64:
1845 1833
1846 { 1834 {
1847 if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) { 1835 if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
@@ -1853,7 +1841,7 @@ yyreduce:
1853;} 1841;}
1854 break; 1842 break;
1855 1843
1856 case 64: 1844 case 67:
1857 1845
1858 { 1846 {
1859 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 1847 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
@@ -1863,7 +1851,7 @@ yyreduce:
1863;} 1851;}
1864 break; 1852 break;
1865 1853
1866 case 65: 1854 case 68:
1867 1855
1868 { 1856 {
1869 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) { 1857 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
@@ -1873,7 +1861,14 @@ yyreduce:
1873;} 1861;}
1874 break; 1862 break;
1875 1863
1876 case 71: 1864 case 74:
1865
1866 {
1867 menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
1868;}
1869 break;
1870
1871 case 75:
1877 1872
1878 { 1873 {
1879 menu_add_entry(NULL); 1874 menu_add_entry(NULL);
@@ -1882,14 +1877,14 @@ yyreduce:
1882;} 1877;}
1883 break; 1878 break;
1884 1879
1885 case 72: 1880 case 76:
1886 1881
1887 { 1882 {
1888 (yyval.menu) = menu_add_menu(); 1883 (yyval.menu) = menu_add_menu();
1889;} 1884;}
1890 break; 1885 break;
1891 1886
1892 case 73: 1887 case 77:
1893 1888
1894 { 1889 {
1895 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) { 1890 if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
@@ -1899,7 +1894,7 @@ yyreduce:
1899;} 1894;}
1900 break; 1895 break;
1901 1896
1902 case 79: 1897 case 83:
1903 1898
1904 { 1899 {
1905 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string)); 1900 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
@@ -1907,7 +1902,7 @@ yyreduce:
1907;} 1902;}
1908 break; 1903 break;
1909 1904
1910 case 80: 1905 case 84:
1911 1906
1912 { 1907 {
1913 menu_add_entry(NULL); 1908 menu_add_entry(NULL);
@@ -1916,14 +1911,14 @@ yyreduce:
1916;} 1911;}
1917 break; 1912 break;
1918 1913
1919 case 81: 1914 case 85:
1920 1915
1921 { 1916 {
1922 menu_end_entry(); 1917 menu_end_entry();
1923;} 1918;}
1924 break; 1919 break;
1925 1920
1926 case 82: 1921 case 86:
1927 1922
1928 { 1923 {
1929 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 1924 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1931,14 +1926,14 @@ yyreduce:
1931;} 1926;}
1932 break; 1927 break;
1933 1928
1934 case 83: 1929 case 87:
1935 1930
1936 { 1931 {
1937 current_entry->help = (yyvsp[(2) - (2)].string); 1932 current_entry->help = (yyvsp[(2) - (2)].string);
1938;} 1933;}
1939 break; 1934 break;
1940 1935
1941 case 88: 1936 case 92:
1942 1937
1943 { 1938 {
1944 menu_add_dep((yyvsp[(3) - (4)].expr)); 1939 menu_add_dep((yyvsp[(3) - (4)].expr));
@@ -1946,90 +1941,96 @@ yyreduce:
1946;} 1941;}
1947 break; 1942 break;
1948 1943
1949 case 90: 1944 case 96:
1945
1946 {
1947 menu_add_visibility((yyvsp[(2) - (2)].expr));
1948;}
1949 break;
1950
1951 case 98:
1950 1952
1951 { 1953 {
1952 menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr)); 1954 menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
1953;} 1955;}
1954 break; 1956 break;
1955 1957
1956 case 93: 1958 case 101:
1957 1959
1958 { (yyval.id) = (yyvsp[(1) - (2)].id); ;} 1960 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
1959 break; 1961 break;
1960 1962
1961 case 94: 1963 case 102:
1962 1964
1963 { (yyval.id) = (yyvsp[(1) - (2)].id); ;} 1965 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
1964 break; 1966 break;
1965 1967
1966 case 95: 1968 case 103:
1967 1969
1968 { (yyval.id) = (yyvsp[(1) - (2)].id); ;} 1970 { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
1969 break; 1971 break;
1970 1972
1971 case 98: 1973 case 106:
1972 1974
1973 { (yyval.expr) = NULL; ;} 1975 { (yyval.expr) = NULL; ;}
1974 break; 1976 break;
1975 1977
1976 case 99: 1978 case 107:
1977 1979
1978 { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} 1980 { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
1979 break; 1981 break;
1980 1982
1981 case 100: 1983 case 108:
1982 1984
1983 { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;} 1985 { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
1984 break; 1986 break;
1985 1987
1986 case 101: 1988 case 109:
1987 1989
1988 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} 1990 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
1989 break; 1991 break;
1990 1992
1991 case 102: 1993 case 110:
1992 1994
1993 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;} 1995 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
1994 break; 1996 break;
1995 1997
1996 case 103: 1998 case 111:
1997 1999
1998 { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} 2000 { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
1999 break; 2001 break;
2000 2002
2001 case 104: 2003 case 112:
2002 2004
2003 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;} 2005 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
2004 break; 2006 break;
2005 2007
2006 case 105: 2008 case 113:
2007 2009
2008 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} 2010 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
2009 break; 2011 break;
2010 2012
2011 case 106: 2013 case 114:
2012 2014
2013 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} 2015 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
2014 break; 2016 break;
2015 2017
2016 case 107: 2018 case 115:
2017 2019
2018 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;} 2020 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
2019 break; 2021 break;
2020 2022
2021 case 108: 2023 case 116:
2022 2024
2023 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;} 2025 { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
2024 break; 2026 break;
2025 2027
2026 case 109: 2028 case 117:
2027 2029
2028 { (yyval.string) = NULL; ;} 2030 { (yyval.string) = NULL; ;}
2029 break; 2031 break;
2030 2032
2031 2033
2032/* Line 1267 of yacc.c. */
2033 2034
2034 default: break; 2035 default: break;
2035 } 2036 }
@@ -2041,7 +2042,6 @@ yyreduce:
2041 2042
2042 *++yyvsp = yyval; 2043 *++yyvsp = yyval;
2043 2044
2044
2045 /* Now `shift' the result of the reduction. Determine what state 2045 /* Now `shift' the result of the reduction. Determine what state
2046 that goes to, based on the state we popped back to and the rule 2046 that goes to, based on the state we popped back to and the rule
2047 number reduced by. */ 2047 number reduced by. */
@@ -2106,7 +2106,7 @@ yyerrlab:
2106 2106
2107 if (yyerrstatus == 3) 2107 if (yyerrstatus == 3)
2108 { 2108 {
2109 /* If just tried and failed to reuse look-ahead token after an 2109 /* If just tried and failed to reuse lookahead token after an
2110 error, discard it. */ 2110 error, discard it. */
2111 2111
2112 if (yychar <= YYEOF) 2112 if (yychar <= YYEOF)
@@ -2123,7 +2123,7 @@ yyerrlab:
2123 } 2123 }
2124 } 2124 }
2125 2125
2126 /* Else will try to reuse look-ahead token after shifting the error 2126 /* Else will try to reuse lookahead token after shifting the error
2127 token. */ 2127 token. */
2128 goto yyerrlab1; 2128 goto yyerrlab1;
2129 2129
@@ -2180,9 +2180,6 @@ yyerrlab1:
2180 YY_STACK_PRINT (yyss, yyssp); 2180 YY_STACK_PRINT (yyss, yyssp);
2181 } 2181 }
2182 2182
2183 if (yyn == YYFINAL)
2184 YYACCEPT;
2185
2186 *++yyvsp = yylval; 2183 *++yyvsp = yylval;
2187 2184
2188 2185
@@ -2207,7 +2204,7 @@ yyabortlab:
2207 yyresult = 1; 2204 yyresult = 1;
2208 goto yyreturn; 2205 goto yyreturn;
2209 2206
2210#ifndef yyoverflow 2207#if !defined(yyoverflow) || YYERROR_VERBOSE
2211/*-------------------------------------------------. 2208/*-------------------------------------------------.
2212| yyexhaustedlab -- memory exhaustion comes here. | 2209| yyexhaustedlab -- memory exhaustion comes here. |
2213`-------------------------------------------------*/ 2210`-------------------------------------------------*/
@@ -2218,7 +2215,7 @@ yyexhaustedlab:
2218#endif 2215#endif
2219 2216
2220yyreturn: 2217yyreturn:
2221 if (yychar != YYEOF && yychar != YYEMPTY) 2218 if (yychar != YYEMPTY)
2222 yydestruct ("Cleanup: discarding lookahead", 2219 yydestruct ("Cleanup: discarding lookahead",
2223 yytoken, &yylval); 2220 yytoken, &yylval);
2224 /* Do not reclaim the symbols of the rule which action triggered 2221 /* Do not reclaim the symbols of the rule which action triggered
@@ -2255,7 +2252,7 @@ void conf_parse(const char *name)
2255 zconf_initscan(name); 2252 zconf_initscan(name);
2256 2253
2257 sym_init(); 2254 sym_init();
2258 menu_init(); 2255 _menu_init();
2259 modules_sym = sym_lookup(NULL, 0); 2256 modules_sym = sym_lookup(NULL, 0);
2260 modules_sym->type = S_BOOLEAN; 2257 modules_sym->type = S_BOOLEAN;
2261 modules_sym->flags |= SYMBOL_AUTO; 2258 modules_sym->flags |= SYMBOL_AUTO;
@@ -2274,6 +2271,10 @@ void conf_parse(const char *name)
2274 prop = prop_alloc(P_DEFAULT, modules_sym); 2271 prop = prop_alloc(P_DEFAULT, modules_sym);
2275 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); 2272 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
2276 } 2273 }
2274
2275 rootmenu.prompt->text = _(rootmenu.prompt->text);
2276 rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
2277
2277 menu_finalize(&rootmenu); 2278 menu_finalize(&rootmenu);
2278 for_all_symbols(i, sym) { 2279 for_all_symbols(i, sym) {
2279 if (sym_check_deps(sym)) 2280 if (sym_check_deps(sym))
@@ -2284,7 +2285,7 @@ void conf_parse(const char *name)
2284 sym_set_change_count(1); 2285 sym_set_change_count(1);
2285} 2286}
2286 2287
2287const char *zconf_tokenname(int token) 2288static const char *zconf_tokenname(int token)
2288{ 2289{
2289 switch (token) { 2290 switch (token) {
2290 case T_MENU: return "menu"; 2291 case T_MENU: return "menu";
@@ -2294,6 +2295,7 @@ const char *zconf_tokenname(int token)
2294 case T_IF: return "if"; 2295 case T_IF: return "if";
2295 case T_ENDIF: return "endif"; 2296 case T_ENDIF: return "endif";
2296 case T_DEPENDS: return "depends"; 2297 case T_DEPENDS: return "depends";
2298 case T_VISIBLE: return "visible";
2297 } 2299 }
2298 return "<token>"; 2300 return "<token>";
2299} 2301}
@@ -2348,7 +2350,7 @@ static void zconferror(const char *err)
2348#endif 2350#endif
2349} 2351}
2350 2352
2351void print_quoted_string(FILE *out, const char *str) 2353static void print_quoted_string(FILE *out, const char *str)
2352{ 2354{
2353 const char *p; 2355 const char *p;
2354 int len; 2356 int len;
@@ -2365,15 +2367,15 @@ void print_quoted_string(FILE *out, const char *str)
2365 putc('"', out); 2367 putc('"', out);
2366} 2368}
2367 2369
2368void print_symbol(FILE *out, struct menu *menu) 2370static void print_symbol(FILE *out, struct menu *menu)
2369{ 2371{
2370 struct symbol *sym = menu->sym; 2372 struct symbol *sym = menu->sym;
2371 struct property *prop; 2373 struct property *prop;
2372 2374
2373 if (sym_is_choice(sym)) 2375 if (sym_is_choice(sym))
2374 fprintf(out, "choice\n"); 2376 fprintf(out, "\nchoice\n");
2375 else 2377 else
2376 fprintf(out, "config %s\n", sym->name); 2378 fprintf(out, "\nconfig %s\n", sym->name);
2377 switch (sym->type) { 2379 switch (sym->type) {
2378 case S_BOOLEAN: 2380 case S_BOOLEAN:
2379 fputs(" boolean\n", out); 2381 fputs(" boolean\n", out);
@@ -2419,6 +2421,21 @@ void print_symbol(FILE *out, struct menu *menu)
2419 case P_CHOICE: 2421 case P_CHOICE:
2420 fputs(" #choice value\n", out); 2422 fputs(" #choice value\n", out);
2421 break; 2423 break;
2424 case P_SELECT:
2425 fputs( " select ", out);
2426 expr_fprint(prop->expr, out);
2427 fputc('\n', out);
2428 break;
2429 case P_RANGE:
2430 fputs( " range ", out);
2431 expr_fprint(prop->expr, out);
2432 fputc('\n', out);
2433 break;
2434 case P_MENU:
2435 fputs( " menu ", out);
2436 print_quoted_string(out, prop->text);
2437 fputc('\n', out);
2438 break;
2422 default: 2439 default:
2423 fprintf(out, " unknown prop %d!\n", prop->type); 2440 fprintf(out, " unknown prop %d!\n", prop->type);
2424 break; 2441 break;
@@ -2430,7 +2447,6 @@ void print_symbol(FILE *out, struct menu *menu)
2430 menu->help[len] = 0; 2447 menu->help[len] = 0;
2431 fprintf(out, " help\n%s\n", menu->help); 2448 fprintf(out, " help\n%s\n", menu->help);
2432 } 2449 }
2433 fputc('\n', out);
2434} 2450}
2435 2451
2436void zconfdump(FILE *out) 2452void zconfdump(FILE *out)
@@ -2463,7 +2479,6 @@ void zconfdump(FILE *out)
2463 expr_fprint(prop->visible.expr, out); 2479 expr_fprint(prop->visible.expr, out);
2464 fputc('\n', out); 2480 fputc('\n', out);
2465 } 2481 }
2466 fputs("\n", out);
2467 } 2482 }
2468 2483
2469 if (menu->list) 2484 if (menu->list)
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 9710b82466f2..49fb4ab664c3 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -14,8 +14,6 @@
14#define LKC_DIRECT_LINK 14#define LKC_DIRECT_LINK
15#include "lkc.h" 15#include "lkc.h"
16 16
17#include "zconf.hash.c"
18
19#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 17#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
20 18
21#define PRINTD 0x0001 19#define PRINTD 0x0001
@@ -29,7 +27,7 @@ static void zconf_error(const char *err, ...);
29static void zconferror(const char *err); 27static void zconferror(const char *err);
30static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); 28static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
31 29
32struct symbol *symbol_hash[257]; 30struct symbol *symbol_hash[SYMBOL_HASHSIZE];
33 31
34static struct menu *current_menu, *current_entry; 32static struct menu *current_menu, *current_entry;
35 33
@@ -38,7 +36,7 @@ static struct menu *current_menu, *current_entry;
38#define YYERROR_VERBOSE 36#define YYERROR_VERBOSE
39#endif 37#endif
40%} 38%}
41%expect 26 39%expect 30
42 40
43%union 41%union
44{ 42{
@@ -70,6 +68,7 @@ static struct menu *current_menu, *current_entry;
70%token <id>T_DEFAULT 68%token <id>T_DEFAULT
71%token <id>T_SELECT 69%token <id>T_SELECT
72%token <id>T_RANGE 70%token <id>T_RANGE
71%token <id>T_VISIBLE
73%token <id>T_OPTION 72%token <id>T_OPTION
74%token <id>T_ON 73%token <id>T_ON
75%token <string> T_WORD 74%token <string> T_WORD
@@ -100,15 +99,21 @@ static struct menu *current_menu, *current_entry;
100 menu_end_menu(); 99 menu_end_menu();
101} if_entry menu_entry choice_entry 100} if_entry menu_entry choice_entry
102 101
102%{
103/* Include zconf.hash.c here so it can see the token constants. */
104#include "zconf.hash.c"
105%}
106
103%% 107%%
104input: stmt_list; 108input: nl start | start;
109
110start: mainmenu_stmt stmt_list | stmt_list;
105 111
106stmt_list: 112stmt_list:
107 /* empty */ 113 /* empty */
108 | stmt_list common_stmt 114 | stmt_list common_stmt
109 | stmt_list choice_stmt 115 | stmt_list choice_stmt
110 | stmt_list menu_stmt 116 | stmt_list menu_stmt
111 | stmt_list T_MAINMENU prompt nl
112 | stmt_list end { zconf_error("unexpected end statement"); } 117 | stmt_list end { zconf_error("unexpected end statement"); }
113 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } 118 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
114 | stmt_list option_name error T_EOL 119 | stmt_list option_name error T_EOL
@@ -119,7 +124,7 @@ stmt_list:
119; 124;
120 125
121option_name: 126option_name:
122 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT 127 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
123; 128;
124 129
125common_stmt: 130common_stmt:
@@ -339,6 +344,13 @@ if_block:
339 | if_block choice_stmt 344 | if_block choice_stmt
340; 345;
341 346
347/* mainmenu entry */
348
349mainmenu_stmt: T_MAINMENU prompt nl
350{
351 menu_add_prompt(P_MENU, $2, NULL);
352};
353
342/* menu entry */ 354/* menu entry */
343 355
344menu: T_MENU prompt T_EOL 356menu: T_MENU prompt T_EOL
@@ -348,7 +360,7 @@ menu: T_MENU prompt T_EOL
348 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 360 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
349}; 361};
350 362
351menu_entry: menu depends_list 363menu_entry: menu visibility_list depends_list
352{ 364{
353 $$ = menu_add_menu(); 365 $$ = menu_add_menu();
354}; 366};
@@ -419,6 +431,19 @@ depends: T_DEPENDS T_ON expr T_EOL
419 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 431 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
420}; 432};
421 433
434/* visibility option */
435
436visibility_list:
437 /* empty */
438 | visibility_list visible
439 | visibility_list T_EOL
440;
441
442visible: T_VISIBLE if_expr
443{
444 menu_add_visibility($2);
445};
446
422/* prompt statement */ 447/* prompt statement */
423 448
424prompt_stmt_opt: 449prompt_stmt_opt:
@@ -472,7 +497,7 @@ void conf_parse(const char *name)
472 zconf_initscan(name); 497 zconf_initscan(name);
473 498
474 sym_init(); 499 sym_init();
475 menu_init(); 500 _menu_init();
476 modules_sym = sym_lookup(NULL, 0); 501 modules_sym = sym_lookup(NULL, 0);
477 modules_sym->type = S_BOOLEAN; 502 modules_sym->type = S_BOOLEAN;
478 modules_sym->flags |= SYMBOL_AUTO; 503 modules_sym->flags |= SYMBOL_AUTO;
@@ -491,6 +516,10 @@ void conf_parse(const char *name)
491 prop = prop_alloc(P_DEFAULT, modules_sym); 516 prop = prop_alloc(P_DEFAULT, modules_sym);
492 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); 517 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
493 } 518 }
519
520 rootmenu.prompt->text = _(rootmenu.prompt->text);
521 rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
522
494 menu_finalize(&rootmenu); 523 menu_finalize(&rootmenu);
495 for_all_symbols(i, sym) { 524 for_all_symbols(i, sym) {
496 if (sym_check_deps(sym)) 525 if (sym_check_deps(sym))
@@ -501,7 +530,7 @@ void conf_parse(const char *name)
501 sym_set_change_count(1); 530 sym_set_change_count(1);
502} 531}
503 532
504const char *zconf_tokenname(int token) 533static const char *zconf_tokenname(int token)
505{ 534{
506 switch (token) { 535 switch (token) {
507 case T_MENU: return "menu"; 536 case T_MENU: return "menu";
@@ -511,6 +540,7 @@ const char *zconf_tokenname(int token)
511 case T_IF: return "if"; 540 case T_IF: return "if";
512 case T_ENDIF: return "endif"; 541 case T_ENDIF: return "endif";
513 case T_DEPENDS: return "depends"; 542 case T_DEPENDS: return "depends";
543 case T_VISIBLE: return "visible";
514 } 544 }
515 return "<token>"; 545 return "<token>";
516} 546}
@@ -565,7 +595,7 @@ static void zconferror(const char *err)
565#endif 595#endif
566} 596}
567 597
568void print_quoted_string(FILE *out, const char *str) 598static void print_quoted_string(FILE *out, const char *str)
569{ 599{
570 const char *p; 600 const char *p;
571 int len; 601 int len;
@@ -582,15 +612,15 @@ void print_quoted_string(FILE *out, const char *str)
582 putc('"', out); 612 putc('"', out);
583} 613}
584 614
585void print_symbol(FILE *out, struct menu *menu) 615static void print_symbol(FILE *out, struct menu *menu)
586{ 616{
587 struct symbol *sym = menu->sym; 617 struct symbol *sym = menu->sym;
588 struct property *prop; 618 struct property *prop;
589 619
590 if (sym_is_choice(sym)) 620 if (sym_is_choice(sym))
591 fprintf(out, "choice\n"); 621 fprintf(out, "\nchoice\n");
592 else 622 else
593 fprintf(out, "config %s\n", sym->name); 623 fprintf(out, "\nconfig %s\n", sym->name);
594 switch (sym->type) { 624 switch (sym->type) {
595 case S_BOOLEAN: 625 case S_BOOLEAN:
596 fputs(" boolean\n", out); 626 fputs(" boolean\n", out);
@@ -636,6 +666,21 @@ void print_symbol(FILE *out, struct menu *menu)
636 case P_CHOICE: 666 case P_CHOICE:
637 fputs(" #choice value\n", out); 667 fputs(" #choice value\n", out);
638 break; 668 break;
669 case P_SELECT:
670 fputs( " select ", out);
671 expr_fprint(prop->expr, out);
672 fputc('\n', out);
673 break;
674 case P_RANGE:
675 fputs( " range ", out);
676 expr_fprint(prop->expr, out);
677 fputc('\n', out);
678 break;
679 case P_MENU:
680 fputs( " menu ", out);
681 print_quoted_string(out, prop->text);
682 fputc('\n', out);
683 break;
639 default: 684 default:
640 fprintf(out, " unknown prop %d!\n", prop->type); 685 fprintf(out, " unknown prop %d!\n", prop->type);
641 break; 686 break;
@@ -647,7 +692,6 @@ void print_symbol(FILE *out, struct menu *menu)
647 menu->help[len] = 0; 692 menu->help[len] = 0;
648 fprintf(out, " help\n%s\n", menu->help); 693 fprintf(out, " help\n%s\n", menu->help);
649 } 694 }
650 fputc('\n', out);
651} 695}
652 696
653void zconfdump(FILE *out) 697void zconfdump(FILE *out)
@@ -680,7 +724,6 @@ void zconfdump(FILE *out)
680 expr_fprint(prop->visible.expr, out); 724 expr_fprint(prop->visible.expr, out);
681 fputc('\n', out); 725 fputc('\n', out);
682 } 726 }
683 fputs("\n", out);
684 } 727 }
685 728
686 if (menu->list) 729 if (menu->list)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index ed591e9b7d1d..9f85012acf0d 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -5,7 +5,7 @@ use strict;
5## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## 5## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
6## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## 6## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
7## Copyright (C) 2001 Simon Huggins ## 7## Copyright (C) 2001 Simon Huggins ##
8## Copyright (C) 2005-2009 Randy Dunlap ## 8## Copyright (C) 2005-2010 Randy Dunlap ##
9## ## 9## ##
10## #define enhancements by Armin Kuster <akuster@mvista.com> ## 10## #define enhancements by Armin Kuster <akuster@mvista.com> ##
11## Copyright (c) 2000 MontaVista Software, Inc. ## 11## Copyright (c) 2000 MontaVista Software, Inc. ##
@@ -13,8 +13,6 @@ use strict;
13## This software falls under the GNU General Public License. ## 13## This software falls under the GNU General Public License. ##
14## Please read the COPYING file for more information ## 14## Please read the COPYING file for more information ##
15 15
16# w.o. 03-11-2000: added the '-filelist' option.
17
18# 18/01/2001 - Cleanups 16# 18/01/2001 - Cleanups
19# Functions prototyped as foo(void) same as foo() 17# Functions prototyped as foo(void) same as foo()
20# Stop eval'ing where we don't need to. 18# Stop eval'ing where we don't need to.
@@ -46,12 +44,13 @@ use strict;
46# Note: This only supports 'c'. 44# Note: This only supports 'c'.
47 45
48# usage: 46# usage:
49# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ] 47# kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ]
50# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile 48# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
51# or 49# or
52# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile 50# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
53# 51#
54# 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.
55# 54#
56# -no-doc-sections 55# -no-doc-sections
57# Do not output DOC: sections 56# Do not output DOC: sections
@@ -156,6 +155,8 @@ use strict;
156# '@parameter' - name of a parameter 155# '@parameter' - name of a parameter
157# '%CONST' - name of a constant. 156# '%CONST' - name of a constant.
158 157
158## init lots of data
159
159my $errors = 0; 160my $errors = 0;
160my $warnings = 0; 161my $warnings = 0;
161my $anon_struct_union = 0; 162my $anon_struct_union = 0;
@@ -212,21 +213,21 @@ my %highlights_text = ( $type_constant, "\$1",
212 $type_param, "\$1" ); 213 $type_param, "\$1" );
213my $blankline_text = ""; 214my $blankline_text = "";
214 215
215 216# list mode
216sub usage { 217my %highlights_list = ( $type_constant, "\$1",
217 print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n"; 218 $type_func, "\$1",
218 print " [ -function funcname [ -function funcname ...] ]\n"; 219 $type_struct, "\$1",
219 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; 220 $type_param, "\$1" );
220 print " c source file(s) > outputfile\n"; 221my $blankline_list = "";
221 print " -v : verbose output, more warnings & other info listed\n";
222 exit 1;
223}
224 222
225# read arguments 223# read arguments
226if ($#ARGV == -1) { 224if ($#ARGV == -1) {
227 usage(); 225 usage();
228} 226}
229 227
228my $kernelversion;
229my $dohighlight = "";
230
230my $verbose = 0; 231my $verbose = 0;
231my $output_mode = "man"; 232my $output_mode = "man";
232my $no_doc_sections = 0; 233my $no_doc_sections = 0;
@@ -239,13 +240,13 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
239 'November', 'December')[(localtime)[4]] . 240 'November', 'December')[(localtime)[4]] .
240 " " . ((localtime)[5]+1900); 241 " " . ((localtime)[5]+1900);
241 242
242# Essentially these are globals 243# Essentially these are globals.
243# They probably want to be tidied up, made more localised or something. 244# They probably want to be tidied up, made more localised or something.
244# CAVEAT EMPTOR! Some of the others I localised may not want to be, which 245# CAVEAT EMPTOR! Some of the others I localised may not want to be, which
245# could cause "use of undefined value" or other bugs. 246# could cause "use of undefined value" or other bugs.
246my ($function, %function_table, %parametertypes, $declaration_purpose); 247my ($function, %function_table, %parametertypes, $declaration_purpose);
247my ($type, $declaration_name, $return_type); 248my ($type, $declaration_name, $return_type);
248my ($newsection, $newcontents, $prototype, $filelist, $brcount, %source_map); 249my ($newsection, $newcontents, $prototype, $brcount, %source_map);
249 250
250if (defined($ENV{'KBUILD_VERBOSE'})) { 251if (defined($ENV{'KBUILD_VERBOSE'})) {
251 $verbose = "$ENV{'KBUILD_VERBOSE'}"; 252 $verbose = "$ENV{'KBUILD_VERBOSE'}";
@@ -320,6 +321,10 @@ while ($ARGV[0] =~ m/^-(.*)/) {
320 $output_mode = "xml"; 321 $output_mode = "xml";
321 %highlights = %highlights_xml; 322 %highlights = %highlights_xml;
322 $blankline = $blankline_xml; 323 $blankline = $blankline_xml;
324 } elsif ($cmd eq "-list") {
325 $output_mode = "list";
326 %highlights = %highlights_list;
327 $blankline = $blankline_list;
323 } elsif ($cmd eq "-gnome") { 328 } elsif ($cmd eq "-gnome") {
324 $output_mode = "gnome"; 329 $output_mode = "gnome";
325 %highlights = %highlights_gnome; 330 %highlights = %highlights_gnome;
@@ -338,13 +343,23 @@ while ($ARGV[0] =~ m/^-(.*)/) {
338 $verbose = 1; 343 $verbose = 1;
339 } elsif (($cmd eq "-h") || ($cmd eq "--help")) { 344 } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
340 usage(); 345 usage();
341 } elsif ($cmd eq '-filelist') {
342 $filelist = shift @ARGV;
343 } elsif ($cmd eq '-no-doc-sections') { 346 } elsif ($cmd eq '-no-doc-sections') {
344 $no_doc_sections = 1; 347 $no_doc_sections = 1;
345 } 348 }
346} 349}
347 350
351# continue execution near EOF;
352
353sub usage {
354 print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n";
355 print " [ -no-doc-sections ]\n";
356 print " [ -function funcname [ -function funcname ...] ]\n";
357 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
358 print " c source file(s) > outputfile\n";
359 print " -v : verbose output, more warnings & other info listed\n";
360 exit 1;
361}
362
348# get kernel version from env 363# get kernel version from env
349sub get_kernel_version() { 364sub get_kernel_version() {
350 my $version = 'unknown kernel version'; 365 my $version = 'unknown kernel version';
@@ -354,15 +369,6 @@ sub get_kernel_version() {
354 } 369 }
355 return $version; 370 return $version;
356} 371}
357my $kernelversion = get_kernel_version();
358
359# generate a sequence of code that will splice in highlighting information
360# using the s// operator.
361my $dohighlight = "";
362foreach my $pattern (keys %highlights) {
363# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
364 $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
365}
366 372
367## 373##
368# dumps section contents to arrays/hashes intended for that purpose. 374# dumps section contents to arrays/hashes intended for that purpose.
@@ -445,7 +451,7 @@ sub output_highlight {
445 if ($output_mode eq "html" || $output_mode eq "xml") { 451 if ($output_mode eq "html" || $output_mode eq "xml") {
446 $contents = local_unescape($contents); 452 $contents = local_unescape($contents);
447 # convert data read & converted thru xml_escape() into &xyz; format: 453 # convert data read & converted thru xml_escape() into &xyz; format:
448 $contents =~ s/\\\\\\/&/g; 454 $contents =~ s/\\\\\\/\&/g;
449 } 455 }
450# print STDERR "contents b4:$contents\n"; 456# print STDERR "contents b4:$contents\n";
451 eval $dohighlight; 457 eval $dohighlight;
@@ -762,7 +768,11 @@ sub output_struct_xml(%) {
762 print $args{'type'} . " " . $args{'struct'} . " {\n"; 768 print $args{'type'} . " " . $args{'struct'} . " {\n";
763 foreach $parameter (@{$args{'parameterlist'}}) { 769 foreach $parameter (@{$args{'parameterlist'}}) {
764 if ($parameter =~ /^#/) { 770 if ($parameter =~ /^#/) {
765 print "$parameter\n"; 771 my $prm = $parameter;
772 # convert data read & converted thru xml_escape() into &xyz; format:
773 # This allows us to have #define macros interspersed in a struct.
774 $prm =~ s/\\\\\\/\&/g;
775 print "$prm\n";
766 next; 776 next;
767 } 777 }
768 778
@@ -1365,6 +1375,42 @@ sub output_blockhead_text(%) {
1365 } 1375 }
1366} 1376}
1367 1377
1378## list mode output functions
1379
1380sub output_function_list(%) {
1381 my %args = %{$_[0]};
1382
1383 print $args{'function'} . "\n";
1384}
1385
1386# output enum in list
1387sub output_enum_list(%) {
1388 my %args = %{$_[0]};
1389 print $args{'enum'} . "\n";
1390}
1391
1392# output typedef in list
1393sub output_typedef_list(%) {
1394 my %args = %{$_[0]};
1395 print $args{'typedef'} . "\n";
1396}
1397
1398# output struct as list
1399sub output_struct_list(%) {
1400 my %args = %{$_[0]};
1401
1402 print $args{'struct'} . "\n";
1403}
1404
1405sub output_blockhead_list(%) {
1406 my %args = %{$_[0]};
1407 my ($parameter, $section);
1408
1409 foreach $section (@{$args{'sectionlist'}}) {
1410 print "DOC: $section\n";
1411 }
1412}
1413
1368## 1414##
1369# generic output function for all types (function, struct/union, typedef, enum); 1415# generic output function for all types (function, struct/union, typedef, enum);
1370# calls the generated, variable output_ function name based on 1416# calls the generated, variable output_ function name based on
@@ -1426,6 +1472,10 @@ sub dump_struct($$) {
1426 # strip comments: 1472 # strip comments:
1427 $members =~ s/\/\*.*?\*\///gos; 1473 $members =~ s/\/\*.*?\*\///gos;
1428 $nested =~ s/\/\*.*?\*\///gos; 1474 $nested =~ s/\/\*.*?\*\///gos;
1475 # strip kmemcheck_bitfield_{begin,end}.*;
1476 $members =~ s/kmemcheck_bitfield_.*?;//gos;
1477 # strip attributes
1478 $members =~ s/__aligned\s*\(\d+\)//gos;
1429 1479
1430 create_parameterlist($members, ';', $file); 1480 create_parameterlist($members, ';', $file);
1431 check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); 1481 check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
@@ -1454,6 +1504,8 @@ sub dump_enum($$) {
1454 my $file = shift; 1504 my $file = shift;
1455 1505
1456 $x =~ s@/\*.*?\*/@@gos; # strip comments. 1506 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1507 $x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums
1508
1457 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { 1509 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
1458 $declaration_name = $1; 1510 $declaration_name = $1;
1459 my $members = $2; 1511 my $members = $2;
@@ -1468,8 +1520,6 @@ sub dump_enum($$) {
1468 } 1520 }
1469 1521
1470 } 1522 }
1471 # strip kmemcheck_bitfield_{begin,end}.*;
1472 $members =~ s/kmemcheck_bitfield_.*?;//gos;
1473 1523
1474 output_declaration($declaration_name, 1524 output_declaration($declaration_name,
1475 'enum', 1525 'enum',
@@ -1653,6 +1703,8 @@ sub push_parameter($$$) {
1653 } 1703 }
1654 } 1704 }
1655 1705
1706 $param = xml_escape($param);
1707
1656 # strip spaces from $param so that it is one continous string 1708 # strip spaces from $param so that it is one continous string
1657 # on @parameterlist; 1709 # on @parameterlist;
1658 # this fixes a problem where check_sections() cannot find 1710 # this fixes a problem where check_sections() cannot find
@@ -1679,7 +1731,7 @@ sub check_sections($$$$$$) {
1679 foreach $px (0 .. $#prms) { 1731 foreach $px (0 .. $#prms) {
1680 $prm_clean = $prms[$px]; 1732 $prm_clean = $prms[$px];
1681 $prm_clean =~ s/\[.*\]//; 1733 $prm_clean =~ s/\[.*\]//;
1682 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//; 1734 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
1683 # ignore array size in a parameter string; 1735 # ignore array size in a parameter string;
1684 # however, the original param string may contain 1736 # however, the original param string may contain
1685 # spaces, e.g.: addr[6 + 2] 1737 # spaces, e.g.: addr[6 + 2]
@@ -1732,6 +1784,7 @@ sub dump_function($$) {
1732 $prototype =~ s/^noinline +//; 1784 $prototype =~ s/^noinline +//;
1733 $prototype =~ s/__devinit +//; 1785 $prototype =~ s/__devinit +//;
1734 $prototype =~ s/__init +//; 1786 $prototype =~ s/__init +//;
1787 $prototype =~ s/__init_or_module +//;
1735 $prototype =~ s/^#\s*define\s+//; #ak added 1788 $prototype =~ s/^#\s*define\s+//; #ak added
1736 $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; 1789 $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
1737 1790
@@ -1796,42 +1849,6 @@ sub dump_function($$) {
1796 }); 1849 });
1797} 1850}
1798 1851
1799sub process_file($);
1800
1801# Read the file that maps relative names to absolute names for
1802# separate source and object directories and for shadow trees.
1803if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
1804 my ($relname, $absname);
1805 while(<SOURCE_MAP>) {
1806 chop();
1807 ($relname, $absname) = (split())[0..1];
1808 $relname =~ s:^/+::;
1809 $source_map{$relname} = $absname;
1810 }
1811 close(SOURCE_MAP);
1812}
1813
1814if ($filelist) {
1815 open(FLIST,"<$filelist") or die "Can't open file list $filelist";
1816 while(<FLIST>) {
1817 chop;
1818 process_file($_);
1819 }
1820}
1821
1822foreach (@ARGV) {
1823 chomp;
1824 process_file($_);
1825}
1826if ($verbose && $errors) {
1827 print STDERR "$errors errors\n";
1828}
1829if ($verbose && $warnings) {
1830 print STDERR "$warnings warnings\n";
1831}
1832
1833exit($errors);
1834
1835sub reset_state { 1852sub reset_state {
1836 $function = ""; 1853 $function = "";
1837 %constants = (); 1854 %constants = ();
@@ -1852,10 +1869,17 @@ sub tracepoint_munge($) {
1852 my $tracepointname = 0; 1869 my $tracepointname = 0;
1853 my $tracepointargs = 0; 1870 my $tracepointargs = 0;
1854 1871
1855 if($prototype =~ m/TRACE_EVENT\((.*?),/) { 1872 if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
1856 $tracepointname = $1; 1873 $tracepointname = $1;
1857 } 1874 }
1858 if($prototype =~ m/TP_PROTO\((.*?)\)/) { 1875 if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
1876 $tracepointname = $1;
1877 }
1878 if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
1879 $tracepointname = $2;
1880 }
1881 $tracepointname =~ s/^\s+//; #strip leading whitespace
1882 if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
1859 $tracepointargs = $1; 1883 $tracepointargs = $1;
1860 } 1884 }
1861 if (($tracepointname eq 0) || ($tracepointargs eq 0)) { 1885 if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
@@ -1920,7 +1944,9 @@ sub process_state3_function($$) {
1920 if ($prototype =~ /SYSCALL_DEFINE/) { 1944 if ($prototype =~ /SYSCALL_DEFINE/) {
1921 syscall_munge(); 1945 syscall_munge();
1922 } 1946 }
1923 if ($prototype =~ /TRACE_EVENT/) { 1947 if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
1948 $prototype =~ /DEFINE_SINGLE_EVENT/)
1949 {
1924 tracepoint_munge($file); 1950 tracepoint_munge($file);
1925 } 1951 }
1926 dump_function($prototype, $file); 1952 dump_function($prototype, $file);
@@ -1995,6 +2021,7 @@ sub process_file($) {
1995 my $identifier; 2021 my $identifier;
1996 my $func; 2022 my $func;
1997 my $descr; 2023 my $descr;
2024 my $in_purpose = 0;
1998 my $initial_section_counter = $section_counter; 2025 my $initial_section_counter = $section_counter;
1999 2026
2000 if (defined($ENV{'SRCTREE'})) { 2027 if (defined($ENV{'SRCTREE'})) {
@@ -2013,6 +2040,8 @@ sub process_file($) {
2013 return; 2040 return;
2014 } 2041 }
2015 2042
2043 $. = 1;
2044
2016 $section_counter = 0; 2045 $section_counter = 0;
2017 while (<IN>) { 2046 while (<IN>) {
2018 if ($state == 0) { 2047 if ($state == 0) {
@@ -2044,6 +2073,7 @@ sub process_file($) {
2044 $descr =~ s/\s*$//; 2073 $descr =~ s/\s*$//;
2045 $descr =~ s/\s+/ /; 2074 $descr =~ s/\s+/ /;
2046 $declaration_purpose = xml_escape($descr); 2075 $declaration_purpose = xml_escape($descr);
2076 $in_purpose = 1;
2047 } else { 2077 } else {
2048 $declaration_purpose = ""; 2078 $declaration_purpose = "";
2049 } 2079 }
@@ -2090,6 +2120,7 @@ sub process_file($) {
2090 } 2120 }
2091 2121
2092 $in_doc_sect = 1; 2122 $in_doc_sect = 1;
2123 $in_purpose = 0;
2093 $contents = $newcontents; 2124 $contents = $newcontents;
2094 if ($contents ne "") { 2125 if ($contents ne "") {
2095 while ((substr($contents, 0, 1) eq " ") || 2126 while ((substr($contents, 0, 1) eq " ") ||
@@ -2101,7 +2132,7 @@ sub process_file($) {
2101 $section = $newsection; 2132 $section = $newsection;
2102 } elsif (/$doc_end/) { 2133 } elsif (/$doc_end/) {
2103 2134
2104 if ($contents ne "") { 2135 if (($contents ne "") && ($contents ne "\n")) {
2105 dump_section($file, $section, xml_escape($contents)); 2136 dump_section($file, $section, xml_escape($contents));
2106 $section = $section_default; 2137 $section = $section_default;
2107 $contents = ""; 2138 $contents = "";
@@ -2119,11 +2150,19 @@ sub process_file($) {
2119 } elsif (/$doc_content/) { 2150 } elsif (/$doc_content/) {
2120 # miguel-style comment kludge, look for blank lines after 2151 # miguel-style comment kludge, look for blank lines after
2121 # @parameter line to signify start of description 2152 # @parameter line to signify start of description
2122 if ($1 eq "" && 2153 if ($1 eq "") {
2123 ($section =~ m/^@/ || $section eq $section_context)) { 2154 if ($section =~ m/^@/ || $section eq $section_context) {
2124 dump_section($file, $section, xml_escape($contents)); 2155 dump_section($file, $section, xml_escape($contents));
2125 $section = $section_default; 2156 $section = $section_default;
2126 $contents = ""; 2157 $contents = "";
2158 } else {
2159 $contents .= "\n";
2160 }
2161 $in_purpose = 0;
2162 } elsif ($in_purpose == 1) {
2163 # Continued declaration purpose
2164 chomp($declaration_purpose);
2165 $declaration_purpose .= " " . xml_escape($1);
2127 } else { 2166 } else {
2128 $contents .= $1 . "\n"; 2167 $contents .= $1 . "\n";
2129 } 2168 }
@@ -2216,3 +2255,39 @@ sub process_file($) {
2216 } 2255 }
2217 } 2256 }
2218} 2257}
2258
2259
2260$kernelversion = get_kernel_version();
2261
2262# generate a sequence of code that will splice in highlighting information
2263# using the s// operator.
2264foreach my $pattern (keys %highlights) {
2265# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
2266 $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
2267}
2268
2269# Read the file that maps relative names to absolute names for
2270# separate source and object directories and for shadow trees.
2271if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
2272 my ($relname, $absname);
2273 while(<SOURCE_MAP>) {
2274 chop();
2275 ($relname, $absname) = (split())[0..1];
2276 $relname =~ s:^/+::;
2277 $source_map{$relname} = $absname;
2278 }
2279 close(SOURCE_MAP);
2280}
2281
2282foreach (@ARGV) {
2283 chomp;
2284 process_file($_);
2285}
2286if ($verbose && $errors) {
2287 print STDERR "$errors errors\n";
2288}
2289if ($verbose && $warnings) {
2290 print STDERR "$warnings warnings\n";
2291}
2292
2293exit($errors);
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index 528492bcba5b..827896f56501 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -1,6 +1,8 @@
1#!/usr/bin/perl 1#!/usr/bin/perl
2 2
3use File::Basename; 3use File::Basename;
4use Math::BigInt;
5use Getopt::Long;
4 6
5# Copyright 2008, Intel Corporation 7# Copyright 2008, Intel Corporation
6# 8#
@@ -14,6 +16,16 @@ use File::Basename;
14# Arjan van de Ven <arjan@linux.intel.com> 16# Arjan van de Ven <arjan@linux.intel.com>
15 17
16 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 ();
17my $vmlinux_name = $ARGV[0]; 29my $vmlinux_name = $ARGV[0];
18if (!defined($vmlinux_name)) { 30if (!defined($vmlinux_name)) {
19 my $kerver = `uname -r`; 31 my $kerver = `uname -r`;
@@ -22,9 +34,8 @@ if (!defined($vmlinux_name)) {
22 print "No vmlinux specified, assuming $vmlinux_name\n"; 34 print "No vmlinux specified, assuming $vmlinux_name\n";
23} 35}
24my $filename = $vmlinux_name; 36my $filename = $vmlinux_name;
25# 37
26# Step 1: Parse the oops to find the EIP value 38# Parse the oops to find the EIP value
27#
28 39
29my $target = "0"; 40my $target = "0";
30my $function; 41my $function;
@@ -153,11 +164,11 @@ while (<STDIN>) {
153 if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) { 164 if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) {
154 $target = $1; 165 $target = $1;
155 } 166 }
156 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { 167 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+0x([0-9a-f]+)\/0x[a-f0-9]/) {
157 $function = $1; 168 $function = $1;
158 $func_offset = $2; 169 $func_offset = $2;
159 } 170 }
160 if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { 171 if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+0x([0-9a-f]+)\/0x[a-f0-9]/) {
161 $function = $1; 172 $function = $1;
162 $func_offset = $2; 173 $func_offset = $2;
163 } 174 }
@@ -172,33 +183,30 @@ while (<STDIN>) {
172 parse_x86_regs($line); 183 parse_x86_regs($line);
173} 184}
174 185
175my $decodestart = hex($target) - hex($func_offset); 186my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$func_offset");
176my $decodestop = hex($target) + 8192; 187my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
177if ($target eq "0") { 188if ($target eq "0") {
178 print "No oops found!\n"; 189 print "No oops found!\n";
179 print "Usage: \n"; 190 usage();
180 print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
181 exit;
182} 191}
183 192
184# 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
185if ($module ne "") { 194if ($module ne "") {
186 my $dir = dirname($filename); 195 if ($modulefile eq "") {
187 $dir = $dir . "/"; 196 $modulefile = `modinfo -F filename $module`;
188 my $mod = $module . ".ko"; 197 chomp($modulefile);
189 my $modulefile = `find $dir -name $mod | head -1`; 198 }
190 chomp($modulefile);
191 $filename = $modulefile; 199 $filename = $modulefile;
192 if ($filename eq "") { 200 if ($filename eq "") {
193 print "Module .ko file for $module not found. Aborting\n"; 201 print "Module .ko file for $module not found. Aborting\n";
194 exit; 202 exit;
195 } 203 }
196 # 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
197 open(FILE, "objdump -dS $filename |") || die "Cannot start objdump"; 205 open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
198 while (<FILE>) { 206 while (<FILE>) {
199 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) { 207 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
200 my $fu = $1; 208 my $fu = $1;
201 $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");
202 } 210 }
203 } 211 }
204 close(FILE); 212 close(FILE);
@@ -206,7 +214,7 @@ if ($module ne "") {
206 214
207my $counter = 0; 215my $counter = 0;
208my $state = 0; 216my $state = 0;
209my $center = 0; 217my $center = -1;
210my @lines; 218my @lines;
211my @reglines; 219my @reglines;
212 220
@@ -214,7 +222,7 @@ sub InRange {
214 my ($address, $target) = @_; 222 my ($address, $target) = @_;
215 my $ad = "0x".$address; 223 my $ad = "0x".$address;
216 my $ta = "0x".$target; 224 my $ta = "0x".$target;
217 my $delta = hex($ad) - hex($ta); 225 my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
218 226
219 if (($delta > -4096) && ($delta < 4096)) { 227 if (($delta > -4096) && ($delta < 4096)) {
220 return 1; 228 return 1;
@@ -227,7 +235,7 @@ sub InRange {
227# 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,
228# we only do this for 4Kb around the sweet spot 236# we only do this for 4Kb around the sweet spot
229 237
230open(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";
231 239
232while (<FILE>) { 240while (<FILE>) {
233 my $line = $_; 241 my $line = $_;
@@ -238,7 +246,8 @@ while (<FILE>) {
238 $state = 1; 246 $state = 1;
239 } 247 }
240 } 248 }
241 } else { 249 }
250 if ($state == 1) {
242 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]+)\:/) {
243 my $val = $1; 252 my $val = $1;
244 if (!InRange($val, $target)) { 253 if (!InRange($val, $target)) {
@@ -261,7 +270,7 @@ if ($counter == 0) {
261 exit; 270 exit;
262} 271}
263 272
264if ($center == 0) { 273if ($center == -1) {
265 print "No matching code found \n"; 274 print "No matching code found \n";
266 exit; 275 exit;
267} 276}
@@ -346,3 +355,16 @@ while ($i < $finish) {
346 $i = $i +1; 355 $i = $i +1;
347} 356}
348 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 6a12dd9f1181..50ad317a4bf9 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -1,3 +1,5 @@
1#!/bin/sh
2
1TARGET=$1 3TARGET=$1
2ARCH=$2 4ARCH=$2
3SMP=$3 5SMP=$3
@@ -12,7 +14,7 @@ vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }
12# So "sudo make install" won't change the "compiled by <user>" 14# So "sudo make install" won't change the "compiled by <user>"
13# do "compiled by root" 15# do "compiled by root"
14 16
15if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then 17if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then
16 vecho " SKIPPED $TARGET" 18 vecho " SKIPPED $TARGET"
17 exit 0 19 exit 0
18fi 20fi
@@ -50,7 +52,7 @@ UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP"
50# Truncate to maximum length 52# Truncate to maximum length
51 53
52UTS_LEN=64 54UTS_LEN=64
53UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" 55UTS_TRUNCATE="cut -b -$UTS_LEN"
54 56
55# Generate a temporary compile.h 57# Generate a temporary compile.h
56 58
@@ -65,10 +67,13 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
65 echo \#define LINUX_COMPILE_BY \"`whoami`\" 67 echo \#define LINUX_COMPILE_BY \"`whoami`\"
66 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" 68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
67 69
68 if [ -x /bin/dnsdomainname ]; then 70 domain=`dnsdomainname 2> /dev/null`
69 echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname | $UTS_TRUNCATE`\" 71 if [ -z "$domain" ]; then
70 elif [ -x /bin/domainname ]; then 72 domain=`domainname 2> /dev/null`
71 echo \#define LINUX_COMPILE_DOMAIN \"`domainname | $UTS_TRUNCATE`\" 73 fi
74
75 if [ -n "$domain" ]; then
76 echo \#define LINUX_COMPILE_DOMAIN \"`echo $domain | $UTS_TRUNCATE`\"
72 else 77 else
73 echo \#define LINUX_COMPILE_DOMAIN 78 echo \#define LINUX_COMPILE_DOMAIN
74 fi 79 fi
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/mkuboot.sh b/scripts/mkuboot.sh
index 2e3d3cd916b8..446739c7843a 100755
--- a/scripts/mkuboot.sh
+++ b/scripts/mkuboot.sh
@@ -11,7 +11,7 @@ if [ -z "${MKIMAGE}" ]; then
11 if [ -z "${MKIMAGE}" ]; then 11 if [ -z "${MKIMAGE}" ]; then
12 # Doesn't exist 12 # Doesn't exist
13 echo '"mkimage" command not found - U-Boot images will not be built' >&2 13 echo '"mkimage" command not found - U-Boot images will not be built' >&2
14 exit 0; 14 exit 1;
15 fi 15 fi
16fi 16fi
17 17
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
index 11d69c35e5b4..ff954f8168c1 100644
--- a/scripts/mod/Makefile
+++ b/scripts/mod/Makefile
@@ -8,7 +8,7 @@ modpost-objs := modpost.o file2alias.o sumversion.o
8$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h 8$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h
9 9
10quiet_cmd_elfconfig = MKELF $@ 10quiet_cmd_elfconfig = MKELF $@
11 cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ 11 cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
12 12
13$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE 13$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
14 $(call if_changed,elfconfig) 14 $(call if_changed,elfconfig)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 40e0045876ee..88f3f07205f8 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -104,7 +104,7 @@ static void device_id_check(const char *modname, const char *device_id,
104static void do_usb_entry(struct usb_device_id *id, 104static void do_usb_entry(struct usb_device_id *id,
105 unsigned int bcdDevice_initial, int bcdDevice_initial_digits, 105 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
106 unsigned char range_lo, unsigned char range_hi, 106 unsigned char range_lo, unsigned char range_hi,
107 struct module *mod) 107 unsigned char max, struct module *mod)
108{ 108{
109 char alias[500]; 109 char alias[500];
110 strcpy(alias, "usb:"); 110 strcpy(alias, "usb:");
@@ -118,9 +118,22 @@ static void do_usb_entry(struct usb_device_id *id,
118 sprintf(alias + strlen(alias), "%0*X", 118 sprintf(alias + strlen(alias), "%0*X",
119 bcdDevice_initial_digits, bcdDevice_initial); 119 bcdDevice_initial_digits, bcdDevice_initial);
120 if (range_lo == range_hi) 120 if (range_lo == range_hi)
121 sprintf(alias + strlen(alias), "%u", range_lo); 121 sprintf(alias + strlen(alias), "%X", range_lo);
122 else if (range_lo > 0 || range_hi < 9) 122 else if (range_lo > 0 || range_hi < max) {
123 sprintf(alias + strlen(alias), "[%u-%u]", range_lo, range_hi); 123 if (range_lo > 0x9 || range_hi < 0xA)
124 sprintf(alias + strlen(alias),
125 "[%X-%X]",
126 range_lo,
127 range_hi);
128 else {
129 sprintf(alias + strlen(alias),
130 range_lo < 0x9 ? "[%X-9" : "[%X",
131 range_lo);
132 sprintf(alias + strlen(alias),
133 range_hi > 0xA ? "a-%X]" : "%X]",
134 range_lo);
135 }
136 }
124 if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1)) 137 if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
125 strcat(alias, "*"); 138 strcat(alias, "*");
126 139
@@ -147,10 +160,49 @@ static void do_usb_entry(struct usb_device_id *id,
147 "MODULE_ALIAS(\"%s\");\n", alias); 160 "MODULE_ALIAS(\"%s\");\n", alias);
148} 161}
149 162
163/* Handles increment/decrement of BCD formatted integers */
164/* Returns the previous value, so it works like i++ or i-- */
165static unsigned int incbcd(unsigned int *bcd,
166 int inc,
167 unsigned char max,
168 size_t chars)
169{
170 unsigned int init = *bcd, i, j;
171 unsigned long long c, dec = 0;
172
173 /* If bcd is not in BCD format, just increment */
174 if (max > 0x9) {
175 *bcd += inc;
176 return init;
177 }
178
179 /* Convert BCD to Decimal */
180 for (i=0 ; i < chars ; i++) {
181 c = (*bcd >> (i << 2)) & 0xf;
182 c = c > 9 ? 9 : c; /* force to bcd just in case */
183 for (j=0 ; j < i ; j++)
184 c = c * 10;
185 dec += c;
186 }
187
188 /* Do our increment/decrement */
189 dec += inc;
190 *bcd = 0;
191
192 /* Convert back to BCD */
193 for (i=0 ; i < chars ; i++) {
194 for (c=1,j=0 ; j < i ; j++)
195 c = c * 10;
196 c = (dec / c) % 10;
197 *bcd += c << (i << 2);
198 }
199 return init;
200}
201
150static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) 202static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
151{ 203{
152 unsigned int devlo, devhi; 204 unsigned int devlo, devhi;
153 unsigned char chi, clo; 205 unsigned char chi, clo, max;
154 int ndigits; 206 int ndigits;
155 207
156 id->match_flags = TO_NATIVE(id->match_flags); 208 id->match_flags = TO_NATIVE(id->match_flags);
@@ -162,6 +214,17 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
162 devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ? 214 devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
163 TO_NATIVE(id->bcdDevice_hi) : ~0x0U; 215 TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
164 216
217 /* Figure out if this entry is in bcd or hex format */
218 max = 0x9; /* Default to decimal format */
219 for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) {
220 clo = (devlo >> (ndigits << 2)) & 0xf;
221 chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf;
222 if (clo > max || chi > max) {
223 max = 0xf;
224 break;
225 }
226 }
227
165 /* 228 /*
166 * Some modules (visor) have empty slots as placeholder for 229 * Some modules (visor) have empty slots as placeholder for
167 * run-time specification that results in catch-all alias 230 * run-time specification that results in catch-all alias
@@ -173,21 +236,27 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
173 for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) { 236 for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
174 clo = devlo & 0xf; 237 clo = devlo & 0xf;
175 chi = devhi & 0xf; 238 chi = devhi & 0xf;
176 if (chi > 9) /* it's bcd not hex */ 239 if (chi > max) /* If we are in bcd mode, truncate if necessary */
177 chi = 9; 240 chi = max;
178 devlo >>= 4; 241 devlo >>= 4;
179 devhi >>= 4; 242 devhi >>= 4;
180 243
181 if (devlo == devhi || !ndigits) { 244 if (devlo == devhi || !ndigits) {
182 do_usb_entry(id, devlo, ndigits, clo, chi, mod); 245 do_usb_entry(id, devlo, ndigits, clo, chi, max, mod);
183 break; 246 break;
184 } 247 }
185 248
186 if (clo > 0) 249 if (clo > 0x0)
187 do_usb_entry(id, devlo++, ndigits, clo, 9, mod); 250 do_usb_entry(id,
188 251 incbcd(&devlo, 1, max,
189 if (chi < 9) 252 sizeof(id->bcdDevice_lo) * 2),
190 do_usb_entry(id, devhi--, ndigits, 0, chi, mod); 253 ndigits, clo, max, max, mod);
254
255 if (chi < max)
256 do_usb_entry(id,
257 incbcd(&devhi, -1, max,
258 sizeof(id->bcdDevice_lo) * 2),
259 ndigits, 0x0, chi, max, mod);
191 } 260 }
192} 261}
193 262
@@ -657,6 +726,15 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
657 return 1; 726 return 1;
658} 727}
659 728
729/* Looks like: spi:S */
730static int do_spi_entry(const char *filename, struct spi_device_id *id,
731 char *alias)
732{
733 sprintf(alias, SPI_MODULE_PREFIX "%s", id->name);
734
735 return 1;
736}
737
660static const struct dmifield { 738static const struct dmifield {
661 const char *prefix; 739 const char *prefix;
662 int field; 740 int field;
@@ -718,6 +796,51 @@ static int do_platform_entry(const char *filename,
718 return 1; 796 return 1;
719} 797}
720 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
721/* Ignore any prefix, eg. some architectures prepend _ */ 844/* Ignore any prefix, eg. some architectures prepend _ */
722static inline int sym_is(const char *symbol, const char *name) 845static inline int sym_is(const char *symbol, const char *name)
723{ 846{
@@ -726,7 +849,7 @@ static inline int sym_is(const char *symbol, const char *name)
726 match = strstr(symbol, name); 849 match = strstr(symbol, name);
727 if (!match) 850 if (!match)
728 return 0; 851 return 0;
729 return match[strlen(symbol)] == '\0'; 852 return match[strlen(name)] == '\0';
730} 853}
731 854
732static void do_table(void *symval, unsigned long size, 855static void do_table(void *symval, unsigned long size,
@@ -761,16 +884,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
761 char *zeros = NULL; 884 char *zeros = NULL;
762 885
763 /* We're looking for a section relative symbol */ 886 /* We're looking for a section relative symbol */
764 if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum) 887 if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
765 return; 888 return;
766 889
767 /* Handle all-NULL symbols allocated into .bss */ 890 /* Handle all-NULL symbols allocated into .bss */
768 if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) { 891 if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
769 zeros = calloc(1, sym->st_size); 892 zeros = calloc(1, sym->st_size);
770 symval = zeros; 893 symval = zeros;
771 } else { 894 } else {
772 symval = (void *)info->hdr 895 symval = (void *)info->hdr
773 + info->sechdrs[sym->st_shndx].sh_offset 896 + info->sechdrs[get_secindex(info, sym)].sh_offset
774 + sym->st_value; 897 + sym->st_value;
775 } 898 }
776 899
@@ -853,6 +976,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
853 do_table(symval, sym->st_size, 976 do_table(symval, sym->st_size,
854 sizeof(struct i2c_device_id), "i2c", 977 sizeof(struct i2c_device_id), "i2c",
855 do_i2c_entry, mod); 978 do_i2c_entry, mod);
979 else if (sym_is(symname, "__mod_spi_device_table"))
980 do_table(symval, sym->st_size,
981 sizeof(struct spi_device_id), "spi",
982 do_spi_entry, mod);
856 else if (sym_is(symname, "__mod_dmi_device_table")) 983 else if (sym_is(symname, "__mod_dmi_device_table"))
857 do_table(symval, sym->st_size, 984 do_table(symval, sym->st_size,
858 sizeof(struct dmi_system_id), "dmi", 985 sizeof(struct dmi_system_id), "dmi",
@@ -861,6 +988,18 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
861 do_table(symval, sym->st_size, 988 do_table(symval, sym->st_size,
862 sizeof(struct platform_device_id), "platform", 989 sizeof(struct platform_device_id), "platform",
863 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);
864 free(zeros); 1003 free(zeros);
865} 1004}
866 1005
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
index 6a96d47bd1e6..639bca7ba559 100644
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -9,9 +9,6 @@ main(int argc, char **argv)
9 unsigned char ei[EI_NIDENT]; 9 unsigned char ei[EI_NIDENT];
10 union { short s; char c[2]; } endian_test; 10 union { short s; char c[2]; } endian_test;
11 11
12 if (argc != 2) {
13 fprintf(stderr, "Error: no arch\n");
14 }
15 if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) { 12 if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
16 fprintf(stderr, "Error: input truncated\n"); 13 fprintf(stderr, "Error: input truncated\n");
17 return 1; 14 return 1;
@@ -55,12 +52,6 @@ main(int argc, char **argv)
55 else 52 else
56 exit(1); 53 exit(1);
57 54
58 if ((strcmp(argv[1], "h8300") == 0)
59 || (strcmp(argv[1], "blackfin") == 0))
60 printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
61 else
62 printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
63
64 return 0; 55 return 0;
65} 56}
66 57
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4522948a012e..97d2259ae999 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -14,9 +14,19 @@
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"
19#include "../../include/generated/autoconf.h"
18#include "../../include/linux/license.h" 20#include "../../include/linux/license.h"
19 21
22/* Some toolchains use a `_' prefix for all user symbols. */
23#ifdef CONFIG_SYMBOL_PREFIX
24#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
25#else
26#define MODULE_SYMBOL_PREFIX ""
27#endif
28
29
20/* Are we using CONFIG_MODVERSIONS? */ 30/* Are we using CONFIG_MODVERSIONS? */
21int modversions = 0; 31int modversions = 0;
22/* Warn about undefined symbols? (do so if we have vmlinux) */ 32/* Warn about undefined symbols? (do so if we have vmlinux) */
@@ -244,7 +254,7 @@ static enum export export_no(const char *s)
244 return export_unknown; 254 return export_unknown;
245} 255}
246 256
247static 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)
248{ 258{
249 if (sec == elf->export_sec) 259 if (sec == elf->export_sec)
250 return export_plain; 260 return export_plain;
@@ -364,6 +374,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
364 Elf_Ehdr *hdr; 374 Elf_Ehdr *hdr;
365 Elf_Shdr *sechdrs; 375 Elf_Shdr *sechdrs;
366 Elf_Sym *sym; 376 Elf_Sym *sym;
377 const char *secstrings;
378 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
367 379
368 hdr = grab_file(filename, &info->size); 380 hdr = grab_file(filename, &info->size);
369 if (!hdr) { 381 if (!hdr) {
@@ -408,8 +420,27 @@ static int parse_elf(struct elf_info *info, const char *filename)
408 return 0; 420 return 0;
409 } 421 }
410 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
411 /* Fix endianness in section headers */ 442 /* Fix endianness in section headers */
412 for (i = 0; i < hdr->e_shnum; i++) { 443 for (i = 0; i < info->num_sections; i++) {
413 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); 444 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
414 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); 445 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
415 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); 446 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
@@ -422,9 +453,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
422 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); 453 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
423 } 454 }
424 /* Find symbol table. */ 455 /* Find symbol table. */
425 for (i = 1; i < hdr->e_shnum; i++) { 456 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
426 const char *secstrings 457 for (i = 1; i < info->num_sections; i++) {
427 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
428 const char *secname; 458 const char *secname;
429 int nobits = sechdrs[i].sh_type == SHT_NOBITS; 459 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
430 460
@@ -451,17 +481,27 @@ static int parse_elf(struct elf_info *info, const char *filename)
451 info->export_unused_gpl_sec = i; 481 info->export_unused_gpl_sec = i;
452 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 482 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
453 info->export_gpl_future_sec = i; 483 info->export_gpl_future_sec = i;
454 else if (strcmp(secname, "__markers_strings") == 0)
455 info->markers_strings_sec = i;
456 484
457 if (sechdrs[i].sh_type != SHT_SYMTAB) 485 if (sechdrs[i].sh_type == SHT_SYMTAB) {
458 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 }
459 496
460 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; 497 /* 32bit section no. table? ("more than 64k sections") */
461 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset 498 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
462 + sechdrs[i].sh_size; 499 symtab_shndx_idx = i;
463 info->strtab = (void *)hdr + 500 info->symtab_shndx_start = (void *)hdr +
464 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 }
465 } 505 }
466 if (!info->symtab_start) 506 if (!info->symtab_start)
467 fatal("%s has no symtab?\n", filename); 507 fatal("%s has no symtab?\n", filename);
@@ -473,6 +513,21 @@ static int parse_elf(struct elf_info *info, const char *filename)
473 sym->st_value = TO_NATIVE(sym->st_value); 513 sym->st_value = TO_NATIVE(sym->st_value);
474 sym->st_size = TO_NATIVE(sym->st_size); 514 sym->st_size = TO_NATIVE(sym->st_size);
475 } 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
476 return 1; 531 return 1;
477} 532}
478 533
@@ -496,6 +551,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
496 strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || 551 strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 ||
497 strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) 552 strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0)
498 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;
499 /* Do not ignore this symbol */ 559 /* Do not ignore this symbol */
500 return 0; 560 return 0;
501} 561}
@@ -507,7 +567,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
507 Elf_Sym *sym, const char *symname) 567 Elf_Sym *sym, const char *symname)
508{ 568{
509 unsigned int crc; 569 unsigned int crc;
510 enum export export = export_from_sec(info, sym->st_shndx); 570 enum export export = export_from_sec(info, get_secindex(info, sym));
511 571
512 switch (sym->st_shndx) { 572 switch (sym->st_shndx) {
513 case SHN_COMMON: 573 case SHN_COMMON:
@@ -515,7 +575,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
515 break; 575 break;
516 case SHN_ABS: 576 case SHN_ABS:
517 /* CRC'd symbol */ 577 /* CRC'd symbol */
518 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 578 if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
519 crc = (unsigned int) sym->st_value; 579 crc = (unsigned int) sym->st_value;
520 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 580 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
521 export); 581 export);
@@ -559,7 +619,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
559 break; 619 break;
560 default: 620 default:
561 /* All exported symbols */ 621 /* All exported symbols */
562 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 622 if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
563 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, 623 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
564 export); 624 export);
565 } 625 }
@@ -649,19 +709,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
649 return "(unknown)"; 709 return "(unknown)";
650} 710}
651 711
652static const char *sec_name(struct elf_info *elf, int shndx) 712static const char *sec_name(struct elf_info *elf, int secindex)
653{ 713{
654 Elf_Shdr *sechdrs = elf->sechdrs; 714 Elf_Shdr *sechdrs = elf->sechdrs;
655 return (void *)elf->hdr + 715 return (void *)elf->hdr +
656 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 716 elf->sechdrs[elf->secindex_strings].sh_offset +
657 sechdrs[shndx].sh_name; 717 sechdrs[secindex].sh_name;
658} 718}
659 719
660static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) 720static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
661{ 721{
662 return (void *)elf->hdr + 722 return (void *)elf->hdr +
663 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 723 elf->sechdrs[elf->secindex_strings].sh_offset +
664 sechdr->sh_name; 724 sechdr->sh_name;
665} 725}
666 726
667/* if sym is empty or point to a string 727/* if sym is empty or point to a string
@@ -691,7 +751,7 @@ static int number_prefix(const char *sym)
691 * The $ syntax is for sections where ld append a dot number 751 * The $ syntax is for sections where ld append a dot number
692 * to make section name unique. 752 * to make section name unique.
693 */ 753 */
694int match(const char *sym, const char * const pat[]) 754static int match(const char *sym, const char * const pat[])
695{ 755{
696 const char *p; 756 const char *p;
697 while (*pat) { 757 while (*pat) {
@@ -730,6 +790,8 @@ static const char *section_white_list[] =
730{ 790{
731 ".comment*", 791 ".comment*",
732 ".debug*", 792 ".debug*",
793 ".zdebug*", /* Compressed debug sections. */
794 ".GCC-command-line", /* mn10300 */
733 ".mdebug*", /* alpha, score, mips etc. */ 795 ".mdebug*", /* alpha, score, mips etc. */
734 ".pdr", /* alpha, score, mips etc. */ 796 ".pdr", /* alpha, score, mips etc. */
735 ".stab*", 797 ".stab*",
@@ -774,10 +836,13 @@ static void check_section(const char *modname, struct elf_info *elf,
774#define ALL_EXIT_TEXT_SECTIONS \ 836#define ALL_EXIT_TEXT_SECTIONS \
775 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" 837 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
776 838
777#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \ 839#define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
778 CPU_INIT_SECTIONS, MEM_INIT_SECTIONS 840 MEM_INIT_SECTIONS
779#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \ 841#define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
780 CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS 842 MEM_EXIT_SECTIONS
843
844#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
845#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
781 846
782#define DATA_SECTIONS ".data$", ".data.rel$" 847#define DATA_SECTIONS ".data$", ".data.rel$"
783#define TEXT_SECTIONS ".text$" 848#define TEXT_SECTIONS ".text$"
@@ -807,33 +872,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
807 872
808 873
809/* symbols in .data that may refer to init/exit sections */ 874/* symbols in .data that may refer to init/exit sections */
810static const char *symbol_white_list[] = 875#define DEFAULT_SYMBOL_WHITE_LIST \
811{ 876 "*driver", \
812 "*driver", 877 "*_template", /* scsi uses *_template a lot */ \
813 "*_template", /* scsi uses *_template a lot */ 878 "*_timer", /* arm uses ops structures named _timer a lot */ \
814 "*_timer", /* arm uses ops structures named _timer a lot */ 879 "*_sht", /* scsi also used *_sht to some extent */ \
815 "*_sht", /* scsi also used *_sht to some extent */ 880 "*_ops", \
816 "*_ops", 881 "*_probe", \
817 "*_probe", 882 "*_probe_one", \
818 "*_probe_one", 883 "*_console"
819 "*_console",
820 NULL
821};
822 884
823static const char *head_sections[] = { ".head.text*", NULL }; 885static const char *head_sections[] = { ".head.text*", NULL };
824static const char *linker_symbols[] = 886static const char *linker_symbols[] =
825 { "__init_begin", "_sinittext", "_einittext", NULL }; 887 { "__init_begin", "_sinittext", "_einittext", NULL };
826 888
827enum mismatch { 889enum mismatch {
828 NO_MISMATCH, 890 TEXT_TO_ANY_INIT,
829 TEXT_TO_INIT, 891 DATA_TO_ANY_INIT,
830 DATA_TO_INIT, 892 TEXT_TO_ANY_EXIT,
831 TEXT_TO_EXIT, 893 DATA_TO_ANY_EXIT,
832 DATA_TO_EXIT, 894 XXXINIT_TO_SOME_INIT,
833 XXXINIT_TO_INIT, 895 XXXEXIT_TO_SOME_EXIT,
834 XXXEXIT_TO_EXIT, 896 ANY_INIT_TO_ANY_EXIT,
835 INIT_TO_EXIT, 897 ANY_EXIT_TO_ANY_INIT,
836 EXIT_TO_INIT,
837 EXPORT_TO_INIT_EXIT, 898 EXPORT_TO_INIT_EXIT,
838}; 899};
839 900
@@ -841,6 +902,7 @@ struct sectioncheck {
841 const char *fromsec[20]; 902 const char *fromsec[20];
842 const char *tosec[20]; 903 const char *tosec[20];
843 enum mismatch mismatch; 904 enum mismatch mismatch;
905 const char *symbol_white_list[20];
844}; 906};
845 907
846const struct sectioncheck sectioncheck[] = { 908const struct sectioncheck sectioncheck[] = {
@@ -850,80 +912,103 @@ const struct sectioncheck sectioncheck[] = {
850{ 912{
851 .fromsec = { TEXT_SECTIONS, NULL }, 913 .fromsec = { TEXT_SECTIONS, NULL },
852 .tosec = { ALL_INIT_SECTIONS, NULL }, 914 .tosec = { ALL_INIT_SECTIONS, NULL },
853 .mismatch = TEXT_TO_INIT, 915 .mismatch = TEXT_TO_ANY_INIT,
916 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
854}, 917},
855{ 918{
856 .fromsec = { DATA_SECTIONS, NULL }, 919 .fromsec = { DATA_SECTIONS, NULL },
857 .tosec = { ALL_INIT_SECTIONS, NULL }, 920 .tosec = { ALL_XXXINIT_SECTIONS, NULL },
858 .mismatch = DATA_TO_INIT, 921 .mismatch = DATA_TO_ANY_INIT,
922 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
923},
924{
925 .fromsec = { DATA_SECTIONS, NULL },
926 .tosec = { INIT_SECTIONS, NULL },
927 .mismatch = DATA_TO_ANY_INIT,
928 .symbol_white_list = {
929 "*_template", "*_timer", "*_sht", "*_ops",
930 "*_probe", "*_probe_one", "*_console", NULL
931 },
859}, 932},
860{ 933{
861 .fromsec = { TEXT_SECTIONS, NULL }, 934 .fromsec = { TEXT_SECTIONS, NULL },
862 .tosec = { ALL_EXIT_SECTIONS, NULL }, 935 .tosec = { ALL_EXIT_SECTIONS, NULL },
863 .mismatch = TEXT_TO_EXIT, 936 .mismatch = TEXT_TO_ANY_EXIT,
937 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
864}, 938},
865{ 939{
866 .fromsec = { DATA_SECTIONS, NULL }, 940 .fromsec = { DATA_SECTIONS, NULL },
867 .tosec = { ALL_EXIT_SECTIONS, NULL }, 941 .tosec = { ALL_EXIT_SECTIONS, NULL },
868 .mismatch = DATA_TO_EXIT, 942 .mismatch = DATA_TO_ANY_EXIT,
943 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
869}, 944},
870/* Do not reference init code/data from devinit/cpuinit/meminit code/data */ 945/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
871{ 946{
872 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, 947 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
873 .tosec = { INIT_SECTIONS, NULL }, 948 .tosec = { INIT_SECTIONS, NULL },
874 .mismatch = XXXINIT_TO_INIT, 949 .mismatch = XXXINIT_TO_SOME_INIT,
950 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
875}, 951},
876/* Do not reference cpuinit code/data from meminit code/data */ 952/* Do not reference cpuinit code/data from meminit code/data */
877{ 953{
878 .fromsec = { MEM_INIT_SECTIONS, NULL }, 954 .fromsec = { MEM_INIT_SECTIONS, NULL },
879 .tosec = { CPU_INIT_SECTIONS, NULL }, 955 .tosec = { CPU_INIT_SECTIONS, NULL },
880 .mismatch = XXXINIT_TO_INIT, 956 .mismatch = XXXINIT_TO_SOME_INIT,
957 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
881}, 958},
882/* Do not reference meminit code/data from cpuinit code/data */ 959/* Do not reference meminit code/data from cpuinit code/data */
883{ 960{
884 .fromsec = { CPU_INIT_SECTIONS, NULL }, 961 .fromsec = { CPU_INIT_SECTIONS, NULL },
885 .tosec = { MEM_INIT_SECTIONS, NULL }, 962 .tosec = { MEM_INIT_SECTIONS, NULL },
886 .mismatch = XXXINIT_TO_INIT, 963 .mismatch = XXXINIT_TO_SOME_INIT,
964 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
887}, 965},
888/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ 966/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
889{ 967{
890 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, 968 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
891 .tosec = { EXIT_SECTIONS, NULL }, 969 .tosec = { EXIT_SECTIONS, NULL },
892 .mismatch = XXXEXIT_TO_EXIT, 970 .mismatch = XXXEXIT_TO_SOME_EXIT,
971 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
893}, 972},
894/* Do not reference cpuexit code/data from memexit code/data */ 973/* Do not reference cpuexit code/data from memexit code/data */
895{ 974{
896 .fromsec = { MEM_EXIT_SECTIONS, NULL }, 975 .fromsec = { MEM_EXIT_SECTIONS, NULL },
897 .tosec = { CPU_EXIT_SECTIONS, NULL }, 976 .tosec = { CPU_EXIT_SECTIONS, NULL },
898 .mismatch = XXXEXIT_TO_EXIT, 977 .mismatch = XXXEXIT_TO_SOME_EXIT,
978 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
899}, 979},
900/* Do not reference memexit code/data from cpuexit code/data */ 980/* Do not reference memexit code/data from cpuexit code/data */
901{ 981{
902 .fromsec = { CPU_EXIT_SECTIONS, NULL }, 982 .fromsec = { CPU_EXIT_SECTIONS, NULL },
903 .tosec = { MEM_EXIT_SECTIONS, NULL }, 983 .tosec = { MEM_EXIT_SECTIONS, NULL },
904 .mismatch = XXXEXIT_TO_EXIT, 984 .mismatch = XXXEXIT_TO_SOME_EXIT,
985 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
905}, 986},
906/* Do not use exit code/data from init code */ 987/* Do not use exit code/data from init code */
907{ 988{
908 .fromsec = { ALL_INIT_SECTIONS, NULL }, 989 .fromsec = { ALL_INIT_SECTIONS, NULL },
909 .tosec = { ALL_EXIT_SECTIONS, NULL }, 990 .tosec = { ALL_EXIT_SECTIONS, NULL },
910 .mismatch = INIT_TO_EXIT, 991 .mismatch = ANY_INIT_TO_ANY_EXIT,
992 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
911}, 993},
912/* Do not use init code/data from exit code */ 994/* Do not use init code/data from exit code */
913{ 995{
914 .fromsec = { ALL_EXIT_SECTIONS, NULL }, 996 .fromsec = { ALL_EXIT_SECTIONS, NULL },
915 .tosec = { ALL_INIT_SECTIONS, NULL }, 997 .tosec = { ALL_INIT_SECTIONS, NULL },
916 .mismatch = EXIT_TO_INIT, 998 .mismatch = ANY_EXIT_TO_ANY_INIT,
999 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
917}, 1000},
918/* Do not export init/exit functions or data */ 1001/* Do not export init/exit functions or data */
919{ 1002{
920 .fromsec = { "__ksymtab*", NULL }, 1003 .fromsec = { "__ksymtab*", NULL },
921 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, 1004 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
922 .mismatch = EXPORT_TO_INIT_EXIT 1005 .mismatch = EXPORT_TO_INIT_EXIT,
1006 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
923} 1007}
924}; 1008};
925 1009
926static int section_mismatch(const char *fromsec, const char *tosec) 1010static const struct sectioncheck *section_mismatch(
1011 const char *fromsec, const char *tosec)
927{ 1012{
928 int i; 1013 int i;
929 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); 1014 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
@@ -932,10 +1017,10 @@ static int section_mismatch(const char *fromsec, const char *tosec)
932 for (i = 0; i < elems; i++) { 1017 for (i = 0; i < elems; i++) {
933 if (match(fromsec, check->fromsec) && 1018 if (match(fromsec, check->fromsec) &&
934 match(tosec, check->tosec)) 1019 match(tosec, check->tosec))
935 return check->mismatch; 1020 return check;
936 check++; 1021 check++;
937 } 1022 }
938 return NO_MISMATCH; 1023 return NULL;
939} 1024}
940 1025
941/** 1026/**
@@ -951,10 +1036,17 @@ static int section_mismatch(const char *fromsec, const char *tosec)
951 * fromsec = .data* 1036 * fromsec = .data*
952 * atsym =__param* 1037 * atsym =__param*
953 * 1038 *
1039 * Pattern 1a:
1040 * module_param_call() ops can refer to __init set function if permissions=0
1041 * The pattern is identified by:
1042 * tosec = .init.text
1043 * fromsec = .data*
1044 * atsym = __param_ops_*
1045 *
954 * Pattern 2: 1046 * Pattern 2:
955 * Many drivers utilise a *driver container with references to 1047 * Many drivers utilise a *driver container with references to
956 * add, remove, probe functions etc. 1048 * add, remove, probe functions etc.
957 * These functions may often be marked __init and we do not want to 1049 * These functions may often be marked __devinit and we do not want to
958 * warn here. 1050 * warn here.
959 * the pattern is identified by: 1051 * the pattern is identified by:
960 * tosec = init or exit section 1052 * tosec = init or exit section
@@ -975,7 +1067,8 @@ static int section_mismatch(const char *fromsec, const char *tosec)
975 * refsymname = __init_begin, _sinittext, _einittext 1067 * refsymname = __init_begin, _sinittext, _einittext
976 * 1068 *
977 **/ 1069 **/
978static int secref_whitelist(const char *fromsec, const char *fromsym, 1070static int secref_whitelist(const struct sectioncheck *mismatch,
1071 const char *fromsec, const char *fromsym,
979 const char *tosec, const char *tosym) 1072 const char *tosec, const char *tosym)
980{ 1073{
981 /* Check for pattern 1 */ 1074 /* Check for pattern 1 */
@@ -984,10 +1077,16 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
984 (strncmp(fromsym, "__param", strlen("__param")) == 0)) 1077 (strncmp(fromsym, "__param", strlen("__param")) == 0))
985 return 0; 1078 return 0;
986 1079
1080 /* Check for pattern 1a */
1081 if (strcmp(tosec, ".init.text") == 0 &&
1082 match(fromsec, data_sections) &&
1083 (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0))
1084 return 0;
1085
987 /* Check for pattern 2 */ 1086 /* Check for pattern 2 */
988 if (match(tosec, init_exit_sections) && 1087 if (match(tosec, init_exit_sections) &&
989 match(fromsec, data_sections) && 1088 match(fromsec, data_sections) &&
990 match(fromsym, symbol_white_list)) 1089 match(fromsym, mismatch->symbol_white_list))
991 return 0; 1090 return 0;
992 1091
993 /* Check for pattern 3 */ 1092 /* Check for pattern 3 */
@@ -1016,11 +1115,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
1016 Elf_Sym *near = NULL; 1115 Elf_Sym *near = NULL;
1017 Elf64_Sword distance = 20; 1116 Elf64_Sword distance = 20;
1018 Elf64_Sword d; 1117 Elf64_Sword d;
1118 unsigned int relsym_secindex;
1019 1119
1020 if (relsym->st_name != 0) 1120 if (relsym->st_name != 0)
1021 return relsym; 1121 return relsym;
1122
1123 relsym_secindex = get_secindex(elf, relsym);
1022 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1124 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1023 if (sym->st_shndx != relsym->st_shndx) 1125 if (get_secindex(elf, sym) != relsym_secindex)
1024 continue; 1126 continue;
1025 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) 1127 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1026 continue; 1128 continue;
@@ -1082,9 +1184,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1082 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1184 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1083 const char *symsec; 1185 const char *symsec;
1084 1186
1085 if (sym->st_shndx >= SHN_LORESERVE) 1187 if (is_shndx_special(sym->st_shndx))
1086 continue; 1188 continue;
1087 symsec = sec_name(elf, sym->st_shndx); 1189 symsec = sec_name(elf, get_secindex(elf, sym));
1088 if (strcmp(symsec, sec) != 0) 1190 if (strcmp(symsec, sec) != 0)
1089 continue; 1191 continue;
1090 if (!is_valid_name(elf, sym)) 1192 if (!is_valid_name(elf, sym))
@@ -1107,6 +1209,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1107 * .cpuinit.data => __cpudata 1209 * .cpuinit.data => __cpudata
1108 * .memexitconst => __memconst 1210 * .memexitconst => __memconst
1109 * etc. 1211 * etc.
1212 *
1213 * The memory of returned value has been allocated on a heap. The user of this
1214 * method should free it after usage.
1110*/ 1215*/
1111static char *sec2annotation(const char *s) 1216static char *sec2annotation(const char *s)
1112{ 1217{
@@ -1129,9 +1234,9 @@ static char *sec2annotation(const char *s)
1129 strcat(p, "data "); 1234 strcat(p, "data ");
1130 else 1235 else
1131 strcat(p, " "); 1236 strcat(p, " ");
1132 return r; /* we leak her but we do not care */ 1237 return r;
1133 } else { 1238 } else {
1134 return ""; 1239 return strdup("");
1135 } 1240 }
1136} 1241}
1137 1242
@@ -1148,7 +1253,8 @@ static int is_function(Elf_Sym *sym)
1148 * Try to find symbols near it so user can find it. 1253 * Try to find symbols near it so user can find it.
1149 * Check whitelist before warning - it may be a false positive. 1254 * Check whitelist before warning - it may be a false positive.
1150 */ 1255 */
1151static void report_sec_mismatch(const char *modname, enum mismatch mismatch, 1256static void report_sec_mismatch(const char *modname,
1257 const struct sectioncheck *mismatch,
1152 const char *fromsec, 1258 const char *fromsec,
1153 unsigned long long fromaddr, 1259 unsigned long long fromaddr,
1154 const char *fromsym, 1260 const char *fromsym,
@@ -1158,6 +1264,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1158{ 1264{
1159 const char *from, *from_p; 1265 const char *from, *from_p;
1160 const char *to, *to_p; 1266 const char *to, *to_p;
1267 char *prl_from;
1268 char *prl_to;
1161 1269
1162 switch (from_is_func) { 1270 switch (from_is_func) {
1163 case 0: from = "variable"; from_p = ""; break; 1271 case 0: from = "variable"; from_p = ""; break;
@@ -1179,64 +1287,80 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1179 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, 1287 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1180 tosym, to_p); 1288 tosym, to_p);
1181 1289
1182 switch (mismatch) { 1290 switch (mismatch->mismatch) {
1183 case TEXT_TO_INIT: 1291 case TEXT_TO_ANY_INIT:
1292 prl_from = sec2annotation(fromsec);
1293 prl_to = sec2annotation(tosec);
1184 fprintf(stderr, 1294 fprintf(stderr,
1185 "The function %s%s() references\n" 1295 "The function %s%s() references\n"
1186 "the %s %s%s%s.\n" 1296 "the %s %s%s%s.\n"
1187 "This is often because %s lacks a %s\n" 1297 "This is often because %s lacks a %s\n"
1188 "annotation or the annotation of %s is wrong.\n", 1298 "annotation or the annotation of %s is wrong.\n",
1189 sec2annotation(fromsec), fromsym, 1299 prl_from, fromsym,
1190 to, sec2annotation(tosec), tosym, to_p, 1300 to, prl_to, tosym, to_p,
1191 fromsym, sec2annotation(tosec), tosym); 1301 fromsym, prl_to, tosym);
1302 free(prl_from);
1303 free(prl_to);
1192 break; 1304 break;
1193 case DATA_TO_INIT: { 1305 case DATA_TO_ANY_INIT: {
1194 const char **s = symbol_white_list; 1306 prl_to = sec2annotation(tosec);
1307 const char *const *s = mismatch->symbol_white_list;
1195 fprintf(stderr, 1308 fprintf(stderr,
1196 "The variable %s references\n" 1309 "The variable %s references\n"
1197 "the %s %s%s%s\n" 1310 "the %s %s%s%s\n"
1198 "If the reference is valid then annotate the\n" 1311 "If the reference is valid then annotate the\n"
1199 "variable with __init* or __refdata (see linux/init.h) " 1312 "variable with __init* or __refdata (see linux/init.h) "
1200 "or name the variable:\n", 1313 "or name the variable:\n",
1201 fromsym, to, sec2annotation(tosec), tosym, to_p); 1314 fromsym, to, prl_to, tosym, to_p);
1202 while (*s) 1315 while (*s)
1203 fprintf(stderr, "%s, ", *s++); 1316 fprintf(stderr, "%s, ", *s++);
1204 fprintf(stderr, "\n"); 1317 fprintf(stderr, "\n");
1318 free(prl_to);
1205 break; 1319 break;
1206 } 1320 }
1207 case TEXT_TO_EXIT: 1321 case TEXT_TO_ANY_EXIT:
1322 prl_to = sec2annotation(tosec);
1208 fprintf(stderr, 1323 fprintf(stderr,
1209 "The function %s() references a %s in an exit section.\n" 1324 "The function %s() references a %s in an exit section.\n"
1210 "Often the %s %s%s has valid usage outside the exit section\n" 1325 "Often the %s %s%s has valid usage outside the exit section\n"
1211 "and the fix is to remove the %sannotation of %s.\n", 1326 "and the fix is to remove the %sannotation of %s.\n",
1212 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); 1327 fromsym, to, to, tosym, to_p, prl_to, tosym);
1328 free(prl_to);
1213 break; 1329 break;
1214 case DATA_TO_EXIT: { 1330 case DATA_TO_ANY_EXIT: {
1215 const char **s = symbol_white_list; 1331 prl_to = sec2annotation(tosec);
1332 const char *const *s = mismatch->symbol_white_list;
1216 fprintf(stderr, 1333 fprintf(stderr,
1217 "The variable %s references\n" 1334 "The variable %s references\n"
1218 "the %s %s%s%s\n" 1335 "the %s %s%s%s\n"
1219 "If the reference is valid then annotate the\n" 1336 "If the reference is valid then annotate the\n"
1220 "variable with __exit* (see linux/init.h) or " 1337 "variable with __exit* (see linux/init.h) or "
1221 "name the variable:\n", 1338 "name the variable:\n",
1222 fromsym, to, sec2annotation(tosec), tosym, to_p); 1339 fromsym, to, prl_to, tosym, to_p);
1223 while (*s) 1340 while (*s)
1224 fprintf(stderr, "%s, ", *s++); 1341 fprintf(stderr, "%s, ", *s++);
1225 fprintf(stderr, "\n"); 1342 fprintf(stderr, "\n");
1343 free(prl_to);
1226 break; 1344 break;
1227 } 1345 }
1228 case XXXINIT_TO_INIT: 1346 case XXXINIT_TO_SOME_INIT:
1229 case XXXEXIT_TO_EXIT: 1347 case XXXEXIT_TO_SOME_EXIT:
1348 prl_from = sec2annotation(fromsec);
1349 prl_to = sec2annotation(tosec);
1230 fprintf(stderr, 1350 fprintf(stderr,
1231 "The %s %s%s%s references\n" 1351 "The %s %s%s%s references\n"
1232 "a %s %s%s%s.\n" 1352 "a %s %s%s%s.\n"
1233 "If %s is only used by %s then\n" 1353 "If %s is only used by %s then\n"
1234 "annotate %s with a matching annotation.\n", 1354 "annotate %s with a matching annotation.\n",
1235 from, sec2annotation(fromsec), fromsym, from_p, 1355 from, prl_from, fromsym, from_p,
1236 to, sec2annotation(tosec), tosym, to_p, 1356 to, prl_to, tosym, to_p,
1237 tosym, fromsym, tosym); 1357 tosym, fromsym, tosym);
1358 free(prl_from);
1359 free(prl_to);
1238 break; 1360 break;
1239 case INIT_TO_EXIT: 1361 case ANY_INIT_TO_ANY_EXIT:
1362 prl_from = sec2annotation(fromsec);
1363 prl_to = sec2annotation(tosec);
1240 fprintf(stderr, 1364 fprintf(stderr,
1241 "The %s %s%s%s references\n" 1365 "The %s %s%s%s references\n"
1242 "a %s %s%s%s.\n" 1366 "a %s %s%s%s.\n"
@@ -1245,11 +1369,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1245 "uses functionality in the exit path.\n" 1369 "uses functionality in the exit path.\n"
1246 "The fix is often to remove the %sannotation of\n" 1370 "The fix is often to remove the %sannotation of\n"
1247 "%s%s so it may be used outside an exit section.\n", 1371 "%s%s so it may be used outside an exit section.\n",
1248 from, sec2annotation(fromsec), fromsym, from_p, 1372 from, prl_from, fromsym, from_p,
1249 to, sec2annotation(tosec), tosym, to_p, 1373 to, prl_to, tosym, to_p,
1250 sec2annotation(tosec), tosym, to_p); 1374 prl_to, tosym, to_p);
1375 free(prl_from);
1376 free(prl_to);
1251 break; 1377 break;
1252 case EXIT_TO_INIT: 1378 case ANY_EXIT_TO_ANY_INIT:
1379 prl_from = sec2annotation(fromsec);
1380 prl_to = sec2annotation(tosec);
1253 fprintf(stderr, 1381 fprintf(stderr,
1254 "The %s %s%s%s references\n" 1382 "The %s %s%s%s references\n"
1255 "a %s %s%s%s.\n" 1383 "a %s %s%s%s.\n"
@@ -1258,18 +1386,20 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1258 "uses functionality in the init path.\n" 1386 "uses functionality in the init path.\n"
1259 "The fix is often to remove the %sannotation of\n" 1387 "The fix is often to remove the %sannotation of\n"
1260 "%s%s so it may be used outside an init section.\n", 1388 "%s%s so it may be used outside an init section.\n",
1261 from, sec2annotation(fromsec), fromsym, from_p, 1389 from, prl_from, fromsym, from_p,
1262 to, sec2annotation(tosec), tosym, to_p, 1390 to, prl_to, tosym, to_p,
1263 sec2annotation(tosec), tosym, to_p); 1391 prl_to, tosym, to_p);
1392 free(prl_from);
1393 free(prl_to);
1264 break; 1394 break;
1265 case EXPORT_TO_INIT_EXIT: 1395 case EXPORT_TO_INIT_EXIT:
1396 prl_to = sec2annotation(tosec);
1266 fprintf(stderr, 1397 fprintf(stderr,
1267 "The symbol %s is exported and annotated %s\n" 1398 "The symbol %s is exported and annotated %s\n"
1268 "Fix this by removing the %sannotation of %s " 1399 "Fix this by removing the %sannotation of %s "
1269 "or drop the export.\n", 1400 "or drop the export.\n",
1270 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); 1401 tosym, prl_to, prl_to, tosym);
1271 case NO_MISMATCH: 1402 free(prl_to);
1272 /* To get warnings on missing members */
1273 break; 1403 break;
1274 } 1404 }
1275 fprintf(stderr, "\n"); 1405 fprintf(stderr, "\n");
@@ -1279,11 +1409,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1279 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1409 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1280{ 1410{
1281 const char *tosec; 1411 const char *tosec;
1282 enum mismatch mismatch; 1412 const struct sectioncheck *mismatch;
1283 1413
1284 tosec = sec_name(elf, sym->st_shndx); 1414 tosec = sec_name(elf, get_secindex(elf, sym));
1285 mismatch = section_mismatch(fromsec, tosec); 1415 mismatch = section_mismatch(fromsec, tosec);
1286 if (mismatch != NO_MISMATCH) { 1416 if (mismatch) {
1287 Elf_Sym *to; 1417 Elf_Sym *to;
1288 Elf_Sym *from; 1418 Elf_Sym *from;
1289 const char *tosym; 1419 const char *tosym;
@@ -1295,7 +1425,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1295 tosym = sym_name(elf, to); 1425 tosym = sym_name(elf, to);
1296 1426
1297 /* check whitelist - we may ignore it */ 1427 /* check whitelist - we may ignore it */
1298 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { 1428 if (secref_whitelist(mismatch,
1429 fromsec, fromsym, tosec, tosym)) {
1299 report_sec_mismatch(modname, mismatch, 1430 report_sec_mismatch(modname, mismatch,
1300 fromsec, r->r_offset, fromsym, 1431 fromsec, r->r_offset, fromsym,
1301 is_function(from), tosec, tosym, 1432 is_function(from), tosec, tosym,
@@ -1308,10 +1439,10 @@ static unsigned int *reloc_location(struct elf_info *elf,
1308 Elf_Shdr *sechdr, Elf_Rela *r) 1439 Elf_Shdr *sechdr, Elf_Rela *r)
1309{ 1440{
1310 Elf_Shdr *sechdrs = elf->sechdrs; 1441 Elf_Shdr *sechdrs = elf->sechdrs;
1311 int section = sechdr->sh_info; 1442 int section = shndx2secindex(sechdr->sh_info);
1312 1443
1313 return (void *)elf->hdr + sechdrs[section].sh_offset + 1444 return (void *)elf->hdr + sechdrs[section].sh_offset +
1314 (r->r_offset - sechdrs[section].sh_addr); 1445 r->r_offset;
1315} 1446}
1316 1447
1317static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) 1448static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
@@ -1416,7 +1547,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
1416 r.r_addend = TO_NATIVE(rela->r_addend); 1547 r.r_addend = TO_NATIVE(rela->r_addend);
1417 sym = elf->symtab_start + r_sym; 1548 sym = elf->symtab_start + r_sym;
1418 /* Skip special sections */ 1549 /* Skip special sections */
1419 if (sym->st_shndx >= SHN_LORESERVE) 1550 if (is_shndx_special(sym->st_shndx))
1420 continue; 1551 continue;
1421 check_section_mismatch(modname, elf, &r, sym, fromsec); 1552 check_section_mismatch(modname, elf, &r, sym, fromsec);
1422 } 1553 }
@@ -1474,7 +1605,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
1474 } 1605 }
1475 sym = elf->symtab_start + r_sym; 1606 sym = elf->symtab_start + r_sym;
1476 /* Skip special sections */ 1607 /* Skip special sections */
1477 if (sym->st_shndx >= SHN_LORESERVE) 1608 if (is_shndx_special(sym->st_shndx))
1478 continue; 1609 continue;
1479 check_section_mismatch(modname, elf, &r, sym, fromsec); 1610 check_section_mismatch(modname, elf, &r, sym, fromsec);
1480 } 1611 }
@@ -1499,7 +1630,7 @@ static void check_sec_ref(struct module *mod, const char *modname,
1499 Elf_Shdr *sechdrs = elf->sechdrs; 1630 Elf_Shdr *sechdrs = elf->sechdrs;
1500 1631
1501 /* Walk through all sections */ 1632 /* Walk through all sections */
1502 for (i = 0; i < elf->hdr->e_shnum; i++) { 1633 for (i = 0; i < elf->num_sections; i++) {
1503 check_section(modname, elf, &elf->sechdrs[i]); 1634 check_section(modname, elf, &elf->sechdrs[i]);
1504 /* We want to process only relocation sections and not .init */ 1635 /* We want to process only relocation sections and not .init */
1505 if (sechdrs[i].sh_type == SHT_RELA) 1636 if (sechdrs[i].sh_type == SHT_RELA)
@@ -1509,62 +1640,6 @@ static void check_sec_ref(struct module *mod, const char *modname,
1509 } 1640 }
1510} 1641}
1511 1642
1512static void get_markers(struct elf_info *info, struct module *mod)
1513{
1514 const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec];
1515 const char *strings = (const char *) info->hdr + sh->sh_offset;
1516 const Elf_Sym *sym, *first_sym, *last_sym;
1517 size_t n;
1518
1519 if (!info->markers_strings_sec)
1520 return;
1521
1522 /*
1523 * First count the strings. We look for all the symbols defined
1524 * in the __markers_strings section named __mstrtab_*. For
1525 * these local names, the compiler puts a random .NNN suffix on,
1526 * so the names don't correspond exactly.
1527 */
1528 first_sym = last_sym = NULL;
1529 n = 0;
1530 for (sym = info->symtab_start; sym < info->symtab_stop; sym++)
1531 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1532 sym->st_shndx == info->markers_strings_sec &&
1533 !strncmp(info->strtab + sym->st_name,
1534 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1535 if (first_sym == NULL)
1536 first_sym = sym;
1537 last_sym = sym;
1538 ++n;
1539 }
1540
1541 if (n == 0)
1542 return;
1543
1544 /*
1545 * Now collect each name and format into a line for the output.
1546 * Lines look like:
1547 * marker_name vmlinux marker %s format %d
1548 * The format string after the second \t can use whitespace.
1549 */
1550 mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n));
1551 mod->nmarkers = n;
1552
1553 n = 0;
1554 for (sym = first_sym; sym <= last_sym; sym++)
1555 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1556 sym->st_shndx == info->markers_strings_sec &&
1557 !strncmp(info->strtab + sym->st_name,
1558 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1559 const char *name = strings + sym->st_value;
1560 const char *fmt = strchr(name, '\0') + 1;
1561 char *line = NULL;
1562 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1563 NOFAIL(line);
1564 mod->markers[n++] = line;
1565 }
1566}
1567
1568static void read_symbols(char *modname) 1643static void read_symbols(char *modname)
1569{ 1644{
1570 const char *symname; 1645 const char *symname;
@@ -1620,8 +1695,6 @@ static void read_symbols(char *modname)
1620 get_src_version(modname, mod->srcversion, 1695 get_src_version(modname, mod->srcversion,
1621 sizeof(mod->srcversion)-1); 1696 sizeof(mod->srcversion)-1);
1622 1697
1623 get_markers(&info, mod);
1624
1625 parse_elf_finish(&info); 1698 parse_elf_finish(&info);
1626 1699
1627 /* Our trick to get versioning for module struct etc. - it's 1700 /* Our trick to get versioning for module struct etc. - it's
@@ -1746,7 +1819,7 @@ static void add_header(struct buffer *b, struct module *mod)
1746 buf_printf(b, "};\n"); 1819 buf_printf(b, "};\n");
1747} 1820}
1748 1821
1749void add_staging_flag(struct buffer *b, const char *name) 1822static void add_staging_flag(struct buffer *b, const char *name)
1750{ 1823{
1751 static const char *staging_dir = "drivers/staging"; 1824 static const char *staging_dir = "drivers/staging";
1752 1825
@@ -1976,96 +2049,6 @@ static void write_dump(const char *fname)
1976 write_if_changed(&buf, fname); 2049 write_if_changed(&buf, fname);
1977} 2050}
1978 2051
1979static void add_marker(struct module *mod, const char *name, const char *fmt)
1980{
1981 char *line = NULL;
1982 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1983 NOFAIL(line);
1984
1985 mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) *
1986 sizeof mod->markers[0])));
1987 mod->markers[mod->nmarkers++] = line;
1988}
1989
1990static void read_markers(const char *fname)
1991{
1992 unsigned long size, pos = 0;
1993 void *file = grab_file(fname, &size);
1994 char *line;
1995
1996 if (!file) /* No old markers, silently ignore */
1997 return;
1998
1999 while ((line = get_next_line(&pos, file, size))) {
2000 char *marker, *modname, *fmt;
2001 struct module *mod;
2002
2003 marker = line;
2004 modname = strchr(marker, '\t');
2005 if (!modname)
2006 goto fail;
2007 *modname++ = '\0';
2008 fmt = strchr(modname, '\t');
2009 if (!fmt)
2010 goto fail;
2011 *fmt++ = '\0';
2012 if (*marker == '\0' || *modname == '\0')
2013 goto fail;
2014
2015 mod = find_module(modname);
2016 if (!mod) {
2017 mod = new_module(modname);
2018 mod->skip = 1;
2019 }
2020 if (is_vmlinux(modname)) {
2021 have_vmlinux = 1;
2022 mod->skip = 0;
2023 }
2024
2025 if (!mod->skip)
2026 add_marker(mod, marker, fmt);
2027 }
2028 release_file(file, size);
2029 return;
2030fail:
2031 fatal("parse error in markers list file\n");
2032}
2033
2034static int compare_strings(const void *a, const void *b)
2035{
2036 return strcmp(*(const char **) a, *(const char **) b);
2037}
2038
2039static void write_markers(const char *fname)
2040{
2041 struct buffer buf = { };
2042 struct module *mod;
2043 size_t i;
2044
2045 for (mod = modules; mod; mod = mod->next)
2046 if ((!external_module || !mod->skip) && mod->markers != NULL) {
2047 /*
2048 * Sort the strings so we can skip duplicates when
2049 * we write them out.
2050 */
2051 qsort(mod->markers, mod->nmarkers,
2052 sizeof mod->markers[0], &compare_strings);
2053 for (i = 0; i < mod->nmarkers; ++i) {
2054 char *line = mod->markers[i];
2055 buf_write(&buf, line, strlen(line));
2056 while (i + 1 < mod->nmarkers &&
2057 !strcmp(mod->markers[i],
2058 mod->markers[i + 1]))
2059 free(mod->markers[i++]);
2060 free(mod->markers[i]);
2061 }
2062 free(mod->markers);
2063 mod->markers = NULL;
2064 }
2065
2066 write_if_changed(&buf, fname);
2067}
2068
2069struct ext_sym_list { 2052struct ext_sym_list {
2070 struct ext_sym_list *next; 2053 struct ext_sym_list *next;
2071 const char *file; 2054 const char *file;
@@ -2077,8 +2060,6 @@ int main(int argc, char **argv)
2077 struct buffer buf = { }; 2060 struct buffer buf = { };
2078 char *kernel_read = NULL, *module_read = NULL; 2061 char *kernel_read = NULL, *module_read = NULL;
2079 char *dump_write = NULL; 2062 char *dump_write = NULL;
2080 char *markers_read = NULL;
2081 char *markers_write = NULL;
2082 int opt; 2063 int opt;
2083 int err; 2064 int err;
2084 struct ext_sym_list *extsym_iter; 2065 struct ext_sym_list *extsym_iter;
@@ -2122,12 +2103,6 @@ int main(int argc, char **argv)
2122 case 'w': 2103 case 'w':
2123 warn_unresolved = 1; 2104 warn_unresolved = 1;
2124 break; 2105 break;
2125 case 'M':
2126 markers_write = optarg;
2127 break;
2128 case 'K':
2129 markers_read = optarg;
2130 break;
2131 default: 2106 default:
2132 exit(1); 2107 exit(1);
2133 } 2108 }
@@ -2182,11 +2157,5 @@ int main(int argc, char **argv)
2182 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", 2157 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
2183 sec_mismatch_count); 2158 sec_mismatch_count);
2184 2159
2185 if (markers_read)
2186 read_markers(markers_read);
2187
2188 if (markers_write)
2189 write_markers(markers_write);
2190
2191 return err; 2160 return err;
2192} 2161}
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 09f58e33d227..0388cfccac8d 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -112,8 +112,6 @@ struct module {
112 int has_init; 112 int has_init;
113 int has_cleanup; 113 int has_cleanup;
114 struct buffer dev_table_buf; 114 struct buffer dev_table_buf;
115 char **markers;
116 size_t nmarkers;
117 char srcversion[25]; 115 char srcversion[25];
118}; 116};
119 117
@@ -128,12 +126,54 @@ struct elf_info {
128 Elf_Section export_gpl_sec; 126 Elf_Section export_gpl_sec;
129 Elf_Section export_unused_gpl_sec; 127 Elf_Section export_unused_gpl_sec;
130 Elf_Section export_gpl_future_sec; 128 Elf_Section export_gpl_future_sec;
131 Elf_Section markers_strings_sec;
132 const char *strtab; 129 const char *strtab;
133 char *modinfo; 130 char *modinfo;
134 unsigned int modinfo_len; 131 unsigned int modinfo_len;
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;
135}; 141};
136 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
137/* file2alias.c */ 177/* file2alias.c */
138extern unsigned int cross_build; 178extern unsigned int cross_build;
139void handle_moddevtable(struct module *mod, struct elf_info *info, 179void handle_moddevtable(struct module *mod, struct elf_info *info,
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
index aadc5223dcdb..ecf9c7dc1825 100644
--- a/scripts/mod/sumversion.c
+++ b/scripts/mod/sumversion.c
@@ -334,8 +334,6 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
334 deps_drivers/net/dummy.o := \ 334 deps_drivers/net/dummy.o := \
335 drivers/net/dummy.c \ 335 drivers/net/dummy.c \
336 $(wildcard include/config/net/fastroute.h) \ 336 $(wildcard include/config/net/fastroute.h) \
337 include/linux/config.h \
338 $(wildcard include/config/h.h) \
339 include/linux/module.h \ 337 include/linux/module.h \
340 338
341 Sum all files in the same dir or subdirs. 339 Sum all files in the same dir or subdirs.
diff --git a/scripts/module-common.lds b/scripts/module-common.lds
new file mode 100644
index 000000000000..47a1f9ae0ede
--- /dev/null
+++ b/scripts/module-common.lds
@@ -0,0 +1,8 @@
1/*
2 * Common module linker script, always used when linking a module.
3 * Archs are free to supply their own linker scripts. ld will
4 * combine them automatically.
5 */
6SECTIONS {
7 /DISCARD/ : { *(.discard) }
8}
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index c6e88c652c2f..a71be6b7cdec 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_
84my %ref = (); # $ref{$name} exists if there is a true external reference to $name 84my %ref = (); # $ref{$name} exists if there is a true external reference to $name
85my %export = (); # $export{$name} exists if there is an EXPORT_... of $name 85my %export = (); # $export{$name} exists if there is an EXPORT_... of $name
86 86
87my %nmexception = (
88 'fs/ext3/bitmap' => 1,
89 'fs/ext4/bitmap' => 1,
90 'arch/x86/lib/thunk_32' => 1,
91 'arch/x86/lib/cmpxchg' => 1,
92 'arch/x86/vdso/vdso32/note' => 1,
93 'lib/irq_regs' => 1,
94 'usr/initramfs_data' => 1,
95 'drivers/scsi/aic94xx/aic94xx_dump' => 1,
96 'drivers/scsi/libsas/sas_dump' => 1,
97 'lib/dec_and_lock' => 1,
98 'drivers/ide/ide-probe-mini' => 1,
99 'usr/initramfs_data' => 1,
100 'drivers/acpi/acpia/exdump' => 1,
101 'drivers/acpi/acpia/rsdump' => 1,
102 'drivers/acpi/acpia/nsdumpdv' => 1,
103 'drivers/acpi/acpia/nsdump' => 1,
104 'arch/ia64/sn/kernel/sn2/io' => 1,
105 'arch/ia64/kernel/gate-data' => 1,
106 'security/capability' => 1,
107 'fs/ntfs/sysctl' => 1,
108 'fs/jfs/jfs_debug' => 1,
109);
110
111my %nameexception = (
112 'mod_use_count_' => 1,
113 '__initramfs_end' => 1,
114 '__initramfs_start' => 1,
115 '_einittext' => 1,
116 '_sinittext' => 1,
117 'kallsyms_names' => 1,
118 'kallsyms_num_syms' => 1,
119 'kallsyms_addresses'=> 1,
120 '__this_module' => 1,
121 '_etext' => 1,
122 '_edata' => 1,
123 '_end' => 1,
124 '__bss_start' => 1,
125 '_text' => 1,
126 '_stext' => 1,
127 '__gp' => 1,
128 'ia64_unw_start' => 1,
129 'ia64_unw_end' => 1,
130 '__init_begin' => 1,
131 '__init_end' => 1,
132 '__bss_stop' => 1,
133 '__nosave_begin' => 1,
134 '__nosave_end' => 1,
135 'pg0' => 1,
136 'vdso_enabled' => 1,
137 '__stack_chk_fail' => 1,
138 'VDSO32_PRELINK' => 1,
139 'VDSO32_vsyscall' => 1,
140 'VDSO32_rt_sigreturn'=>1,
141 'VDSO32_sigreturn' => 1,
142);
143
144
87&find(\&linux_objects, '.'); # find the objects and do_nm on them 145&find(\&linux_objects, '.'); # find the objects and do_nm on them
88&list_multiply_defined(); 146&list_multiply_defined();
89&resolve_external_references(); 147&resolve_external_references();
@@ -105,7 +163,8 @@ sub linux_objects
105 if (/.*\.o$/ && 163 if (/.*\.o$/ &&
106 ! ( 164 ! (
107 m:/built-in.o$: 165 m:/built-in.o$:
108 || m:arch/x86/kernel/vsyscall-syms.o$: 166 || m:arch/x86/vdso/:
167 || m:arch/x86/boot/:
109 || m:arch/ia64/ia32/ia32.o$: 168 || m:arch/ia64/ia32/ia32.o$:
110 || m:arch/ia64/kernel/gate-syms.o$: 169 || m:arch/ia64/kernel/gate-syms.o$:
111 || m:arch/ia64/lib/__divdi3.o$: 170 || m:arch/ia64/lib/__divdi3.o$:
@@ -148,6 +207,7 @@ sub linux_objects
148 || m:^.*/\.tmp_: 207 || m:^.*/\.tmp_:
149 || m:^\.tmp_: 208 || m:^\.tmp_:
150 || m:/vmlinux-obj.o$: 209 || m:/vmlinux-obj.o$:
210 || m:^tools/:
151 ) 211 )
152 ) { 212 ) {
153 do_nm($basename, $_); 213 do_nm($basename, $_);
@@ -167,20 +227,19 @@ sub do_nm
167 printf STDERR "$fullname is not an object file\n"; 227 printf STDERR "$fullname is not an object file\n";
168 return; 228 return;
169 } 229 }
170 ($source = $fullname) =~ s/\.o$//; 230 ($source = $basename) =~ s/\.o$//;
171 if (-e "$objtree$source.c" || -e "$objtree$source.S") { 231 if (-e "$source.c" || -e "$source.S") {
172 $source = "$objtree$source"; 232 $source = "$objtree$File::Find::dir/$source";
173 } else { 233 } else {
174 $source = "$srctree$source"; 234 $source = "$srctree$File::Find::dir/$source";
175 } 235 }
176 if (! -e "$source.c" && ! -e "$source.S") { 236 if (! -e "$source.c" && ! -e "$source.S") {
177 # No obvious source, exclude the object if it is conglomerate 237 # No obvious source, exclude the object if it is conglomerate
178 if (! open(OBJDUMPDATA, "$objdump $basename|")) { 238 open(my $objdumpdata, "$objdump $basename|")
179 printf STDERR "$objdump $fullname failed $!\n"; 239 or die "$objdump $fullname failed $!\n";
180 return; 240
181 }
182 my $comment; 241 my $comment;
183 while (<OBJDUMPDATA>) { 242 while (<$objdumpdata>) {
184 chomp(); 243 chomp();
185 if (/^In archive/) { 244 if (/^In archive/) {
186 # Archives are always conglomerate 245 # Archives are always conglomerate
@@ -190,18 +249,18 @@ sub do_nm
190 next if (! /^[ 0-9a-f]{5,} /); 249 next if (! /^[ 0-9a-f]{5,} /);
191 $comment .= substr($_, 43); 250 $comment .= substr($_, 43);
192 } 251 }
193 close(OBJDUMPDATA); 252 close($objdumpdata);
253
194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) { 254 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
195 printf STDERR "No source file found for $fullname\n"; 255 printf STDERR "No source file found for $fullname\n";
196 } 256 }
197 return; 257 return;
198 } 258 }
199 if (! open(NMDATA, "$nm $basename|")) { 259 open (my $nmdata, "$nm $basename|")
200 printf STDERR "$nm $fullname failed $!\n"; 260 or die "$nm $fullname failed $!\n";
201 return; 261
202 }
203 my @nmdata; 262 my @nmdata;
204 while (<NMDATA>) { 263 while (<$nmdata>) {
205 chop; 264 chop;
206 ($type, $name) = (split(/ +/, $_, 3))[1..2]; 265 ($type, $name) = (split(/ +/, $_, 3))[1..2];
207 # Expected types 266 # Expected types
@@ -215,6 +274,7 @@ sub do_nm
215 # T global label/procedure 274 # T global label/procedure
216 # U external reference 275 # U external reference
217 # W weak external reference to text that has been resolved 276 # W weak external reference to text that has been resolved
277 # V similar to W, but the value of the weak symbol becomes zero with no error.
218 # a assembler equate 278 # a assembler equate
219 # b static variable, uninitialised 279 # b static variable, uninitialised
220 # d static variable, initialised 280 # d static variable, initialised
@@ -223,8 +283,9 @@ sub do_nm
223 # s static variable, uninitialised, small bss 283 # s static variable, uninitialised, small bss
224 # t static label/procedures 284 # t static label/procedures
225 # w weak external reference to text that has not been resolved 285 # w weak external reference to text that has not been resolved
286 # v similar to w
226 # ? undefined type, used a lot by modules 287 # ? undefined type, used a lot by modules
227 if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) { 288 if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) {
228 printf STDERR "nm output for $fullname contains unknown type '$_'\n"; 289 printf STDERR "nm output for $fullname contains unknown type '$_'\n";
229 } 290 }
230 elsif ($name =~ /\./) { 291 elsif ($name =~ /\./) {
@@ -235,7 +296,7 @@ sub do_nm
235 # binutils keeps changing the type for exported symbols, force it to R 296 # binutils keeps changing the type for exported symbols, force it to R
236 $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); 297 $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
237 $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this 298 $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this
238 if ($type =~ /[ABCDGRSTW]/ && 299 if ($type =~ /[ABCDGRSTWV]/ &&
239 $name ne 'init_module' && 300 $name ne 'init_module' &&
240 $name ne 'cleanup_module' && 301 $name ne 'cleanup_module' &&
241 $name ne 'Using_Versions' && 302 $name ne 'Using_Versions' &&
@@ -268,29 +329,12 @@ sub do_nm
268 } 329 }
269 } 330 }
270 } 331 }
271 close(NMDATA); 332 close($nmdata);
333
272 if ($#nmdata < 0) { 334 if ($#nmdata < 0) {
273 if ( 335 printf "No nm data for $fullname\n"
274 $fullname ne "lib/brlock.o" 336 unless $nmexception{$fullname};
275 && $fullname ne "lib/dec_and_lock.o" 337 return;
276 && $fullname ne "fs/xfs/xfs_macros.o"
277 && $fullname ne "drivers/ide/ide-probe-mini.o"
278 && $fullname ne "usr/initramfs_data.o"
279 && $fullname ne "drivers/acpi/executer/exdump.o"
280 && $fullname ne "drivers/acpi/resources/rsdump.o"
281 && $fullname ne "drivers/acpi/namespace/nsdumpdv.o"
282 && $fullname ne "drivers/acpi/namespace/nsdump.o"
283 && $fullname ne "arch/ia64/sn/kernel/sn2/io.o"
284 && $fullname ne "arch/ia64/kernel/gate-data.o"
285 && $fullname ne "drivers/ieee1394/oui.o"
286 && $fullname ne "security/capability.o"
287 && $fullname ne "sound/core/wrappers.o"
288 && $fullname ne "fs/ntfs/sysctl.o"
289 && $fullname ne "fs/jfs/jfs_debug.o"
290 ) {
291 printf "No nm data for $fullname\n";
292 }
293 return;
294 } 338 }
295 $nmdata{$fullname} = \@nmdata; 339 $nmdata{$fullname} = \@nmdata;
296} 340}
@@ -316,25 +360,21 @@ sub drop_def
316 360
317sub list_multiply_defined 361sub list_multiply_defined
318{ 362{
319 my ($name, $module); 363 foreach my $name (keys(%def)) {
320 foreach $name (keys(%def)) {
321 if ($#{$def{$name}} > 0) { 364 if ($#{$def{$name}} > 0) {
322 # Special case for cond_syscall 365 # Special case for cond_syscall
323 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && 366 if ($#{$def{$name}} == 1 &&
324 ($def{$name}[0] eq "kernel/sys.o" || 367 ($name =~ /^sys_/ || $name =~ /^compat_sys_/ ||
325 $def{$name}[1] eq "kernel/sys.o")) { 368 $name =~ /^sys32_/)) {
326 &drop_def("kernel/sys.o", $name); 369 if($def{$name}[0] eq "kernel/sys_ni.o" ||
327 next; 370 $def{$name}[1] eq "kernel/sys_ni.o") {
328 } 371 &drop_def("kernel/sys_ni.o", $name);
329 # Special case for i386 entry code 372 next;
330 if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && 373 }
331 $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" &&
332 $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") {
333 &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
334 next;
335 } 374 }
375
336 printf "$name is multiply defined in :-\n"; 376 printf "$name is multiply defined in :-\n";
337 foreach $module (@{$def{$name}}) { 377 foreach my $module (@{$def{$name}}) {
338 printf "\t$module\n"; 378 printf "\t$module\n";
339 } 379 }
340 } 380 }
@@ -343,12 +383,13 @@ sub list_multiply_defined
343 383
344sub resolve_external_references 384sub resolve_external_references
345{ 385{
346 my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export); 386 my ($kstrtab, $ksymtab, $export);
387
347 printf "\n"; 388 printf "\n";
348 foreach $object (keys(%nmdata)) { 389 foreach my $object (keys(%nmdata)) {
349 my $nmdata = $nmdata{$object}; 390 my $nmdata = $nmdata{$object};
350 for ($i = 0; $i <= $#{$nmdata}; ++$i) { 391 for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
351 ($type, $name) = split(' ', $nmdata->[$i], 2); 392 my ($type, $name) = split(' ', $nmdata->[$i], 2);
352 if ($type eq "U" || $type eq "w") { 393 if ($type eq "U" || $type eq "w") {
353 if (exists($def{$name}) || exists($ksymtab{$name})) { 394 if (exists($def{$name}) || exists($ksymtab{$name})) {
354 # add the owning object to the nmdata 395 # add the owning object to the nmdata
@@ -357,7 +398,7 @@ sub resolve_external_references
357 $kstrtab = "R __kstrtab_$name"; 398 $kstrtab = "R __kstrtab_$name";
358 $ksymtab = "R __ksymtab_$name"; 399 $ksymtab = "R __ksymtab_$name";
359 $export = 0; 400 $export = 0;
360 for ($j = 0; $j <= $#{$nmdata}; ++$j) { 401 for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
361 if ($nmdata->[$j] eq $kstrtab || 402 if ($nmdata->[$j] eq $kstrtab ||
362 $nmdata->[$j] eq $ksymtab) { 403 $nmdata->[$j] eq $ksymtab) {
363 $export = 1; 404 $export = 1;
@@ -371,31 +412,7 @@ sub resolve_external_references
371 $ref{$name} = "" 412 $ref{$name} = ""
372 } 413 }
373 } 414 }
374 elsif ( $name ne "mod_use_count_" 415 elsif ( ! $nameexception{$name}
375 && $name ne "__initramfs_end"
376 && $name ne "__initramfs_start"
377 && $name ne "_einittext"
378 && $name ne "_sinittext"
379 && $name ne "kallsyms_names"
380 && $name ne "kallsyms_num_syms"
381 && $name ne "kallsyms_addresses"
382 && $name ne "__this_module"
383 && $name ne "_etext"
384 && $name ne "_edata"
385 && $name ne "_end"
386 && $name ne "__bss_start"
387 && $name ne "_text"
388 && $name ne "_stext"
389 && $name ne "__gp"
390 && $name ne "ia64_unw_start"
391 && $name ne "ia64_unw_end"
392 && $name ne "__init_begin"
393 && $name ne "__init_end"
394 && $name ne "__bss_stop"
395 && $name ne "__nosave_begin"
396 && $name ne "__nosave_end"
397 && $name ne "pg0"
398 && $name ne "__module_text_address"
399 && $name !~ /^__sched_text_/ 416 && $name !~ /^__sched_text_/
400 && $name !~ /^__start_/ 417 && $name !~ /^__start_/
401 && $name !~ /^__end_/ 418 && $name !~ /^__end_/
@@ -406,7 +423,6 @@ sub resolve_external_references
406 && $name !~ /^__.*per_cpu_end/ 423 && $name !~ /^__.*per_cpu_end/
407 && $name !~ /^__alt_instructions/ 424 && $name !~ /^__alt_instructions/
408 && $name !~ /^__setup_/ 425 && $name !~ /^__setup_/
409 && $name !~ /^jiffies/
410 && $name !~ /^__mod_timer/ 426 && $name !~ /^__mod_timer/
411 && $name !~ /^__mod_page_state/ 427 && $name !~ /^__mod_page_state/
412 && $name !~ /^init_module/ 428 && $name !~ /^init_module/
@@ -424,11 +440,11 @@ sub resolve_external_references
424sub list_extra_externals 440sub list_extra_externals
425{ 441{
426 my %noref = (); 442 my %noref = ();
427 my ($name, @module, $module, $export); 443
428 foreach $name (keys(%def)) { 444 foreach my $name (keys(%def)) {
429 if (! exists($ref{$name})) { 445 if (! exists($ref{$name})) {
430 @module = @{$def{$name}}; 446 my @module = @{$def{$name}};
431 foreach $module (@module) { 447 foreach my $module (@module) {
432 if (! exists($noref{$module})) { 448 if (! exists($noref{$module})) {
433 $noref{$module} = []; 449 $noref{$module} = [];
434 } 450 }
@@ -438,16 +454,16 @@ sub list_extra_externals
438 } 454 }
439 if (%noref) { 455 if (%noref) {
440 printf "\nExternally defined symbols with no external references\n"; 456 printf "\nExternally defined symbols with no external references\n";
441 foreach $module (sort(keys(%noref))) { 457 foreach my $module (sort(keys(%noref))) {
442 printf " $module\n"; 458 printf " $module\n";
443 foreach (sort(@{$noref{$module}})) { 459 foreach (sort(@{$noref{$module}})) {
444 if (exists($export{$_})) { 460 my $export;
445 $export = " (export only)"; 461 if (exists($export{$_})) {
446 } 462 $export = " (export only)";
447 else { 463 } else {
448 $export = ""; 464 $export = "";
449 } 465 }
450 printf " $_$export\n"; 466 printf " $_$export\n";
451 } 467 }
452 } 468 }
453 } 469 }
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index fa4a0a17b7e0..d0b931b994fc 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -18,6 +18,9 @@
18# e) generate the rpm files, based on kernel.spec 18# e) generate the rpm files, based on kernel.spec
19# - Use /. to avoid tar packing just the symlink 19# - Use /. to avoid tar packing just the symlink
20 20
21# Note that the rpm-pkg target cannot be used with KBUILD_OUTPUT,
22# but the binrpm-pkg target can; for some reason O= gets ignored.
23
21# Do we have rpmbuild, otherwise fall back to the older rpm 24# Do we have rpmbuild, otherwise fall back to the older rpm
22RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ 25RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
23 else echo rpm; fi) 26 else echo rpm; fi)
@@ -33,9 +36,15 @@ $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
33 $(CONFIG_SHELL) $(MKSPEC) > $@ 36 $(CONFIG_SHELL) $(MKSPEC) > $@
34 37
35rpm-pkg rpm: $(objtree)/kernel.spec FORCE 38rpm-pkg rpm: $(objtree)/kernel.spec FORCE
39 @if test -n "$(KBUILD_OUTPUT)"; then \
40 echo "Building source + binary RPM is not possible outside the"; \
41 echo "kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \
42 echo "binrpm-pkg target instead."; \
43 false; \
44 fi
36 $(MAKE) clean 45 $(MAKE) clean
37 $(PREV) ln -sf $(srctree) $(KERNELPATH) 46 $(PREV) ln -sf $(srctree) $(KERNELPATH)
38 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion 47 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion --save-scmversion
39 $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. 48 $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
40 $(PREV) rm $(KERNELPATH) 49 $(PREV) rm $(KERNELPATH)
41 rm -f $(objtree)/.scmversion 50 rm -f $(objtree)/.scmversion
@@ -61,16 +70,34 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE
61 set -e; \ 70 set -e; \
62 mv -f $(objtree)/.tmp_version $(objtree)/.version 71 mv -f $(objtree)/.tmp_version $(objtree)/.version
63 72
64 $(RPM) $(RPMOPTS) --define "_builddir $(srctree)" --target \ 73 $(RPM) $(RPMOPTS) --define "_builddir $(objtree)" --target \
65 $(UTS_MACHINE) -bb $< 74 $(UTS_MACHINE) -bb $<
66 75
67clean-files += $(objtree)/binkernel.spec 76clean-files += $(objtree)/binkernel.spec
68 77
69# Deb target 78# Deb target
70# --------------------------------------------------------------------------- 79# ---------------------------------------------------------------------------
80quiet_cmd_builddeb = BUILDDEB
81 cmd_builddeb = set -e; \
82 test `id -u` = 0 || \
83 test -n "$(KBUILD_PKG_ROOTCMD)" || { \
84 which fakeroot >/dev/null 2>&1 && \
85 KBUILD_PKG_ROOTCMD="fakeroot -u"; \
86 } || { \
87 echo; \
88 echo "builddeb must be run as root (or using fakeroot)."; \
89 echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \
90 echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \
91 echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \
92 false; \
93 } && \
94 \
95 $$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \
96 $(srctree)/scripts/package/builddeb
97
71deb-pkg: FORCE 98deb-pkg: FORCE
72 $(MAKE) KBUILD_SRC= 99 $(MAKE) KBUILD_SRC=
73 $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb 100 $(call cmd,builddeb)
74 101
75clean-dirs += $(objtree)/debian/ 102clean-dirs += $(objtree)/debian/
76 103
@@ -84,13 +111,38 @@ tar%pkg: FORCE
84clean-dirs += $(objtree)/tar-install/ 111clean-dirs += $(objtree)/tar-install/
85 112
86 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
87# Help text displayed when executing 'make help' 136# Help text displayed when executing 'make help'
88# --------------------------------------------------------------------------- 137# ---------------------------------------------------------------------------
89help: FORCE 138help: FORCE
90 @echo ' rpm-pkg - Build both source and binary RPM kernel packages' 139 @echo ' rpm-pkg - Build both source and binary RPM kernel packages'
91 @echo ' binrpm-pkg - Build only the binary kernel package' 140 @echo ' binrpm-pkg - Build only the binary kernel package'
92 @echo ' deb-pkg - Build the kernel as an deb package' 141 @echo ' deb-pkg - Build the kernel as an deb package'
93 @echo ' tar-pkg - Build the kernel as an uncompressed tarball' 142 @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
94 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' 143 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
95 @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'
96 148
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 01c2d13dd020..b0b2357aef42 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -16,13 +16,53 @@ create_package() {
16 local pname="$1" pdir="$2" 16 local pname="$1" pdir="$2"
17 17
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"
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"
19 23
20 # Fix ownership and permissions 24 # Fix ownership and permissions
21 chown -R root:root "$pdir" 25 chown -R root:root "$pdir"
22 chmod -R go-w "$pdir" 26 chmod -R go-w "$pdir"
23 27
28 # Attempt to find the correct Debian architecture
29 local forcearch="" debarch=""
30 case "$UTS_MACHINE" in
31 i386|ia64|alpha)
32 debarch="$UTS_MACHINE" ;;
33 x86_64)
34 debarch=amd64 ;;
35 sparc*)
36 debarch=sparc ;;
37 s390*)
38 debarch=s390 ;;
39 ppc*)
40 debarch=powerpc ;;
41 parisc*)
42 debarch=hppa ;;
43 mips*)
44 debarch=mips$(grep -q CPU_LITTLE_ENDIAN=y .config && echo el) ;;
45 arm*)
46 debarch=arm$(grep -q CONFIG_AEABI=y .config && echo el) ;;
47 *)
48 echo "" >&2
49 echo "** ** ** WARNING ** ** **" >&2
50 echo "" >&2
51 echo "Your architecture doesn't have it's equivalent" >&2
52 echo "Debian userspace architecture defined!" >&2
53 echo "Falling back to using your current userspace instead!" >&2
54 echo "Please add support for $UTS_MACHINE to ${0} ..." >&2
55 echo "" >&2
56 esac
57 if [ -n "$KBUILD_DEBARCH" ] ; then
58 debarch="$KBUILD_DEBARCH"
59 fi
60 if [ -n "$debarch" ] ; then
61 forcearch="-DArchitecture=$debarch"
62 fi
63
24 # Create the package 64 # Create the package
25 dpkg-gencontrol -isp -p$pname -P"$pdir" 65 dpkg-gencontrol -isp $forcearch -p$pname -P"$pdir"
26 dpkg --build "$pdir" .. 66 dpkg --build "$pdir" ..
27} 67}
28 68
@@ -36,17 +76,27 @@ else
36fi 76fi
37tmpdir="$objtree/debian/tmp" 77tmpdir="$objtree/debian/tmp"
38fwdir="$objtree/debian/fwtmp" 78fwdir="$objtree/debian/fwtmp"
79kernel_headers_dir="$objtree/debian/hdrtmp"
80libc_headers_dir="$objtree/debian/headertmp"
39packagename=linux-image-$version 81packagename=linux-image-$version
40fwpackagename=linux-firmware-image 82fwpackagename=linux-firmware-image
83kernel_headers_packagename=linux-headers-$version
84libc_headers_packagename=linux-libc-dev
41 85
42if [ "$ARCH" = "um" ] ; then 86if [ "$ARCH" = "um" ] ; then
43 packagename=user-mode-linux-$version 87 packagename=user-mode-linux-$version
44fi 88fi
45 89
46# Setup the directory structure 90# Setup the directory structure
47rm -rf "$tmpdir" "$fwdir" 91rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir"
48mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" 92mkdir -m 755 -p "$tmpdir/DEBIAN"
49mkdir -p "$fwdir/DEBIAN" "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename" 93mkdir -p "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename"
94mkdir -m 755 -p "$fwdir/DEBIAN"
95mkdir -p "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename"
96mkdir -m 755 -p "$libc_headers_dir/DEBIAN"
97mkdir -p "$libc_headers_dir/usr/share/doc/$libc_headers_packagename"
98mkdir -m 755 -p "$kernel_headers_dir/DEBIAN"
99mkdir -p "$kernel_headers_dir/usr/share/doc/$kernel_headers_packagename"
50if [ "$ARCH" = "um" ] ; then 100if [ "$ARCH" = "um" ] ; then
51 mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin" 101 mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin"
52fi 102fi
@@ -62,7 +112,9 @@ else
62 cp System.map "$tmpdir/boot/System.map-$version" 112 cp System.map "$tmpdir/boot/System.map-$version"
63 cp .config "$tmpdir/boot/config-$version" 113 cp .config "$tmpdir/boot/config-$version"
64 # Not all arches include the boot path in KBUILD_IMAGE 114 # Not all arches include the boot path in KBUILD_IMAGE
65 if ! cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"; then 115 if [ -e $KBUILD_IMAGE ]; then
116 cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
117 else
66 cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version" 118 cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
67 fi 119 fi
68fi 120fi
@@ -75,6 +127,9 @@ if grep -q '^CONFIG_MODULES=y' .config ; then
75 fi 127 fi
76fi 128fi
77 129
130make headers_check
131make headers_install INSTALL_HDR_PATH="$libc_headers_dir/usr"
132
78# Install the maintainer scripts 133# Install the maintainer scripts
79# Note: hook scripts under /etc/kernel are also executed by official Debian 134# Note: hook scripts under /etc/kernel are also executed by official Debian
80# kernel packages, as well as kernel packages built using make-kpkg 135# kernel packages, as well as kernel packages built using make-kpkg
@@ -87,7 +142,7 @@ for script in postinst postrm preinst prerm ; do
87set -e 142set -e
88 143
89# Pass maintainer script parameters to hook scripts 144# Pass maintainer script parameters to hook scripts
90export DEB_MAINT_PARAMS="\$@" 145export DEB_MAINT_PARAMS="\$*"
91 146
92test -d $debhookdir/$script.d && run-parts --arg="$version" $debhookdir/$script.d 147test -d $debhookdir/$script.d && run-parts --arg="$version" $debhookdir/$script.d
93exit 0 148exit 0
@@ -144,10 +199,11 @@ EOF
144# Generate a control file 199# Generate a control file
145cat <<EOF > debian/control 200cat <<EOF > debian/control
146Source: linux-upstream 201Source: linux-upstream
147Section: admin 202Section: kernel
148Priority: optional 203Priority: optional
149Maintainer: $maintainer 204Maintainer: $maintainer
150Standards-Version: 3.8.1 205Standards-Version: 3.8.4
206Homepage: http://www.kernel.org/
151EOF 207EOF
152 208
153if [ "$ARCH" = "um" ]; then 209if [ "$ARCH" = "um" ]; then
@@ -181,6 +237,30 @@ EOF
181 237
182fi 238fi
183 239
240# Build header package
241find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$
242find arch/x86/include include scripts -type f >> /tmp/files$$
243(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$)
244destdir=$kernel_headers_dir/usr/src/linux-headers-$version
245mkdir -p "$destdir"
246tar -c -f - -T /tmp/files$$ | (cd $destdir; tar -xf -)
247(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -)
248rm -f /tmp/files$$ /tmp/objfiles$$
249arch=$(dpkg --print-architecture)
250
251cat <<EOF >> debian/control
252
253Package: $kernel_headers_packagename
254Provides: linux-headers, linux-headers-2.6
255Architecture: $arch
256Description: Linux kernel headers for $KERNELRELEASE on $arch
257 This package provides kernel header files for $KERNELRELEASE on $arch
258 .
259 This is useful for people who need to build external modules
260EOF
261
262create_package "$kernel_headers_packagename" "$kernel_headers_dir"
263
184# Do we have firmware? Move it out of the way and build it into a package. 264# Do we have firmware? Move it out of the way and build it into a package.
185if [ -e "$tmpdir/lib/firmware" ]; then 265if [ -e "$tmpdir/lib/firmware" ]; then
186 mv "$tmpdir/lib/firmware" "$fwdir/lib/" 266 mv "$tmpdir/lib/firmware" "$fwdir/lib/"
@@ -196,6 +276,18 @@ EOF
196 create_package "$fwpackagename" "$fwdir" 276 create_package "$fwpackagename" "$fwdir"
197fi 277fi
198 278
279cat <<EOF >> debian/control
280
281Package: $libc_headers_packagename
282Section: devel
283Provides: linux-kernel-headers
284Architecture: any
285Description: Linux support headers for userspace development
286 This package provides userspaces headers from the Linux kernel. These headers
287 are used by the installed headers for GNU glibc and other system libraries.
288EOF
289
290create_package "$libc_headers_packagename" "$libc_headers_dir"
199create_package "$packagename" "$tmpdir" 291create_package "$packagename" "$tmpdir"
200 292
201exit 0 293exit 0
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index b1fd48db1640..51b2aa0acb82 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -101,7 +101,11 @@ esac
101# 101#
102( 102(
103 cd "${tmpdir}" 103 cd "${tmpdir}"
104 tar cf - . | ${compress} > "${tarball}${file_ext}" 104 opts=
105 if tar --owner=root --group=root --help >/dev/null 2>&1; then
106 opts="--owner=root --group=root"
107 fi
108 tar cf - . $opts | ${compress} > "${tarball}${file_ext}"
105) 109)
106 110
107echo "Tarball successfully created in ${tarball}${file_ext}" 111echo "Tarball successfully created in ${tarball}${file_ext}"
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 3d93f8c81252..e1c1d5b8ca70 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}"
@@ -70,7 +70,7 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware' 70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
71echo "%endif" 71echo "%endif"
72 72
73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install' 73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install'
74echo "%ifarch ia64" 74echo "%ifarch ia64"
75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" 75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" 76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
diff --git a/scripts/pnmtologo.c b/scripts/pnmtologo.c
index 64f5ddb09ea6..5c113123ed9f 100644
--- a/scripts/pnmtologo.c
+++ b/scripts/pnmtologo.c
@@ -237,7 +237,7 @@ static void write_header(void)
237 fprintf(out, " * Linux logo %s\n", logoname); 237 fprintf(out, " * Linux logo %s\n", logoname);
238 fputs(" */\n\n", out); 238 fputs(" */\n\n", out);
239 fputs("#include <linux/linux_logo.h>\n\n", out); 239 fputs("#include <linux/linux_logo.h>\n\n", out);
240 fprintf(out, "static const unsigned char %s_data[] __initconst = {\n", 240 fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
241 logoname); 241 logoname);
242} 242}
243 243
@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
374 fputs("\n};\n\n", out); 374 fputs("\n};\n\n", out);
375 375
376 /* write logo clut */ 376 /* write logo clut */
377 fprintf(out, "static const unsigned char %s_clut[] __initconst = {\n", 377 fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
378 logoname); 378 logoname);
379 write_hex_cnt = 0; 379 write_hex_cnt = 0;
380 for (i = 0; i < logo_clutsize; i++) { 380 for (i = 0; i < logo_clutsize; i++) {
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.c b/scripts/recordmcount.c
new file mode 100644
index 000000000000..038b3d1e2981
--- /dev/null
+++ b/scripts/recordmcount.c
@@ -0,0 +1,410 @@
1/*
2 * recordmcount.c: construct a table of the locations of calls to 'mcount'
3 * so that ftrace can find them quickly.
4 * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
5 * Licensed under the GNU General Public License, version 2 (GPLv2).
6 *
7 * Restructured to fit Linux format, as well as other updates:
8 * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
9 */
10
11/*
12 * Strategy: alter the .o file in-place.
13 *
14 * Append a new STRTAB that has the new section names, followed by a new array
15 * ElfXX_Shdr[] that has the new section headers, followed by the section
16 * contents for __mcount_loc and its relocations. The old shstrtab strings,
17 * and the old ElfXX_Shdr[] array, remain as "garbage" (commonly, a couple
18 * kilobytes.) Subsequent processing by /bin/ld (or the kernel module loader)
19 * will ignore the garbage regions, because they are not designated by the
20 * new .e_shoff nor the new ElfXX_Shdr[]. [In order to remove the garbage,
21 * then use "ld -r" to create a new file that omits the garbage.]
22 */
23
24#include <sys/types.h>
25#include <sys/mman.h>
26#include <sys/stat.h>
27#include <elf.h>
28#include <fcntl.h>
29#include <setjmp.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35static int fd_map; /* File descriptor for file being modified. */
36static int mmap_failed; /* Boolean flag. */
37static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
38static char gpfx; /* prefix for global symbol name (sometimes '_') */
39static struct stat sb; /* Remember .st_size, etc. */
40static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
41static const char *altmcount; /* alternate mcount symbol name */
42
43/* setjmp() return values */
44enum {
45 SJ_SETJMP = 0, /* hardwired first return */
46 SJ_FAIL,
47 SJ_SUCCEED
48};
49
50/* Per-file resource cleanup when multiple files. */
51static void
52cleanup(void)
53{
54 if (!mmap_failed)
55 munmap(ehdr_curr, sb.st_size);
56 else
57 free(ehdr_curr);
58 close(fd_map);
59}
60
61static void __attribute__((noreturn))
62fail_file(void)
63{
64 cleanup();
65 longjmp(jmpenv, SJ_FAIL);
66}
67
68static void __attribute__((noreturn))
69succeed_file(void)
70{
71 cleanup();
72 longjmp(jmpenv, SJ_SUCCEED);
73}
74
75/* ulseek, uread, ...: Check return value for errors. */
76
77static off_t
78ulseek(int const fd, off_t const offset, int const whence)
79{
80 off_t const w = lseek(fd, offset, whence);
81 if ((off_t)-1 == w) {
82 perror("lseek");
83 fail_file();
84 }
85 return w;
86}
87
88static size_t
89uread(int const fd, void *const buf, size_t const count)
90{
91 size_t const n = read(fd, buf, count);
92 if (n != count) {
93 perror("read");
94 fail_file();
95 }
96 return n;
97}
98
99static size_t
100uwrite(int const fd, void const *const buf, size_t const count)
101{
102 size_t const n = write(fd, buf, count);
103 if (n != count) {
104 perror("write");
105 fail_file();
106 }
107 return n;
108}
109
110static void *
111umalloc(size_t size)
112{
113 void *const addr = malloc(size);
114 if (0 == addr) {
115 fprintf(stderr, "malloc failed: %zu bytes\n", size);
116 fail_file();
117 }
118 return addr;
119}
120
121/*
122 * Get the whole file as a programming convenience in order to avoid
123 * malloc+lseek+read+free of many pieces. If successful, then mmap
124 * avoids copying unused pieces; else just read the whole file.
125 * Open for both read and write; new info will be appended to the file.
126 * Use MAP_PRIVATE so that a few changes to the in-memory ElfXX_Ehdr
127 * do not propagate to the file until an explicit overwrite at the last.
128 * This preserves most aspects of consistency (all except .st_size)
129 * for simultaneous readers of the file while we are appending to it.
130 * However, multiple writers still are bad. We choose not to use
131 * locking because it is expensive and the use case of kernel build
132 * makes multiple writers unlikely.
133 */
134static void *mmap_file(char const *fname)
135{
136 void *addr;
137
138 fd_map = open(fname, O_RDWR);
139 if (0 > fd_map || 0 > fstat(fd_map, &sb)) {
140 perror(fname);
141 fail_file();
142 }
143 if (!S_ISREG(sb.st_mode)) {
144 fprintf(stderr, "not a regular file: %s\n", fname);
145 fail_file();
146 }
147 addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
148 fd_map, 0);
149 mmap_failed = 0;
150 if (MAP_FAILED == addr) {
151 mmap_failed = 1;
152 addr = umalloc(sb.st_size);
153 uread(fd_map, addr, sb.st_size);
154 }
155 return addr;
156}
157
158/* w8rev, w8nat, ...: Handle endianness. */
159
160static uint64_t w8rev(uint64_t const x)
161{
162 return ((0xff & (x >> (0 * 8))) << (7 * 8))
163 | ((0xff & (x >> (1 * 8))) << (6 * 8))
164 | ((0xff & (x >> (2 * 8))) << (5 * 8))
165 | ((0xff & (x >> (3 * 8))) << (4 * 8))
166 | ((0xff & (x >> (4 * 8))) << (3 * 8))
167 | ((0xff & (x >> (5 * 8))) << (2 * 8))
168 | ((0xff & (x >> (6 * 8))) << (1 * 8))
169 | ((0xff & (x >> (7 * 8))) << (0 * 8));
170}
171
172static uint32_t w4rev(uint32_t const x)
173{
174 return ((0xff & (x >> (0 * 8))) << (3 * 8))
175 | ((0xff & (x >> (1 * 8))) << (2 * 8))
176 | ((0xff & (x >> (2 * 8))) << (1 * 8))
177 | ((0xff & (x >> (3 * 8))) << (0 * 8));
178}
179
180static uint32_t w2rev(uint16_t const x)
181{
182 return ((0xff & (x >> (0 * 8))) << (1 * 8))
183 | ((0xff & (x >> (1 * 8))) << (0 * 8));
184}
185
186static uint64_t w8nat(uint64_t const x)
187{
188 return x;
189}
190
191static uint32_t w4nat(uint32_t const x)
192{
193 return x;
194}
195
196static uint32_t w2nat(uint16_t const x)
197{
198 return x;
199}
200
201static uint64_t (*w8)(uint64_t);
202static uint32_t (*w)(uint32_t);
203static uint32_t (*w2)(uint16_t);
204
205/* Names of the sections that could contain calls to mcount. */
206static int
207is_mcounted_section_name(char const *const txtname)
208{
209 return 0 == strcmp(".text", txtname) ||
210 0 == strcmp(".sched.text", txtname) ||
211 0 == strcmp(".spinlock.text", txtname) ||
212 0 == strcmp(".irqentry.text", txtname) ||
213 0 == strcmp(".text.unlikely", txtname);
214}
215
216/* 32 bit and 64 bit are very similar */
217#include "recordmcount.h"
218#define RECORD_MCOUNT_64
219#include "recordmcount.h"
220
221/* 64-bit EM_MIPS has weird ELF64_Rela.r_info.
222 * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
223 * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40]
224 * to imply the order of the members; the spec does not say so.
225 * typedef unsigned char Elf64_Byte;
226 * fails on MIPS64 because their <elf.h> already has it!
227 */
228
229typedef uint8_t myElf64_Byte; /* Type for a 8-bit quantity. */
230
231union mips_r_info {
232 Elf64_Xword r_info;
233 struct {
234 Elf64_Word r_sym; /* Symbol index. */
235 myElf64_Byte r_ssym; /* Special symbol. */
236 myElf64_Byte r_type3; /* Third relocation. */
237 myElf64_Byte r_type2; /* Second relocation. */
238 myElf64_Byte r_type; /* First relocation. */
239 } r_mips;
240};
241
242static uint64_t MIPS64_r_sym(Elf64_Rel const *rp)
243{
244 return w(((union mips_r_info){ .r_info = rp->r_info }).r_mips.r_sym);
245}
246
247static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type)
248{
249 rp->r_info = ((union mips_r_info){
250 .r_mips = { .r_sym = w(sym), .r_type = type }
251 }).r_info;
252}
253
254static void
255do_file(char const *const fname)
256{
257 Elf32_Ehdr *const ehdr = mmap_file(fname);
258 unsigned int reltype = 0;
259
260 ehdr_curr = ehdr;
261 w = w4nat;
262 w2 = w2nat;
263 w8 = w8nat;
264 switch (ehdr->e_ident[EI_DATA]) {
265 static unsigned int const endian = 1;
266 default: {
267 fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
268 ehdr->e_ident[EI_DATA], fname);
269 fail_file();
270 } break;
271 case ELFDATA2LSB: {
272 if (1 != *(unsigned char const *)&endian) {
273 /* main() is big endian, file.o is little endian. */
274 w = w4rev;
275 w2 = w2rev;
276 w8 = w8rev;
277 }
278 } break;
279 case ELFDATA2MSB: {
280 if (0 != *(unsigned char const *)&endian) {
281 /* main() is little endian, file.o is big endian. */
282 w = w4rev;
283 w2 = w2rev;
284 w8 = w8rev;
285 }
286 } break;
287 } /* end switch */
288 if (0 != memcmp(ELFMAG, ehdr->e_ident, SELFMAG)
289 || ET_REL != w2(ehdr->e_type)
290 || EV_CURRENT != ehdr->e_ident[EI_VERSION]) {
291 fprintf(stderr, "unrecognized ET_REL file %s\n", fname);
292 fail_file();
293 }
294
295 gpfx = 0;
296 switch (w2(ehdr->e_machine)) {
297 default: {
298 fprintf(stderr, "unrecognized e_machine %d %s\n",
299 w2(ehdr->e_machine), fname);
300 fail_file();
301 } break;
302 case EM_386: reltype = R_386_32; break;
303 case EM_ARM: reltype = R_ARM_ABS32;
304 altmcount = "__gnu_mcount_nc";
305 break;
306 case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
307 case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break;
308 case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break;
309 case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break;
310 case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
311 case EM_SH: reltype = R_SH_DIR32; break;
312 case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break;
313 case EM_X86_64: reltype = R_X86_64_64; break;
314 } /* end switch */
315
316 switch (ehdr->e_ident[EI_CLASS]) {
317 default: {
318 fprintf(stderr, "unrecognized ELF class %d %s\n",
319 ehdr->e_ident[EI_CLASS], fname);
320 fail_file();
321 } break;
322 case ELFCLASS32: {
323 if (sizeof(Elf32_Ehdr) != w2(ehdr->e_ehsize)
324 || sizeof(Elf32_Shdr) != w2(ehdr->e_shentsize)) {
325 fprintf(stderr,
326 "unrecognized ET_REL file: %s\n", fname);
327 fail_file();
328 }
329 if (EM_S390 == w2(ehdr->e_machine))
330 reltype = R_390_32;
331 if (EM_MIPS == w2(ehdr->e_machine)) {
332 reltype = R_MIPS_32;
333 is_fake_mcount32 = MIPS32_is_fake_mcount;
334 }
335 do32(ehdr, fname, reltype);
336 } break;
337 case ELFCLASS64: {
338 Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr;
339 if (sizeof(Elf64_Ehdr) != w2(ghdr->e_ehsize)
340 || sizeof(Elf64_Shdr) != w2(ghdr->e_shentsize)) {
341 fprintf(stderr,
342 "unrecognized ET_REL file: %s\n", fname);
343 fail_file();
344 }
345 if (EM_S390 == w2(ghdr->e_machine))
346 reltype = R_390_64;
347 if (EM_MIPS == w2(ghdr->e_machine)) {
348 reltype = R_MIPS_64;
349 Elf64_r_sym = MIPS64_r_sym;
350 Elf64_r_info = MIPS64_r_info;
351 is_fake_mcount64 = MIPS64_is_fake_mcount;
352 }
353 do64(ghdr, fname, reltype);
354 } break;
355 } /* end switch */
356
357 cleanup();
358}
359
360int
361main(int argc, char const *argv[])
362{
363 const char ftrace[] = "/ftrace.o";
364 int ftrace_size = sizeof(ftrace) - 1;
365 int n_error = 0; /* gcc-4.3.0 false positive complaint */
366
367 if (argc <= 1) {
368 fprintf(stderr, "usage: recordmcount file.o...\n");
369 return 0;
370 }
371
372 /* Process each file in turn, allowing deep failure. */
373 for (--argc, ++argv; 0 < argc; --argc, ++argv) {
374 int const sjval = setjmp(jmpenv);
375 int len;
376
377 /*
378 * The file kernel/trace/ftrace.o references the mcount
379 * function but does not call it. Since ftrace.o should
380 * not be traced anyway, we just skip it.
381 */
382 len = strlen(argv[0]);
383 if (len >= ftrace_size &&
384 strcmp(argv[0] + (len - ftrace_size), ftrace) == 0)
385 continue;
386
387 switch (sjval) {
388 default: {
389 fprintf(stderr, "internal error: %s\n", argv[0]);
390 exit(1);
391 } break;
392 case SJ_SETJMP: { /* normal sequence */
393 /* Avoid problems if early cleanup() */
394 fd_map = -1;
395 ehdr_curr = NULL;
396 mmap_failed = 1;
397 do_file(argv[0]);
398 } break;
399 case SJ_FAIL: { /* error in do_file or below */
400 ++n_error;
401 } break;
402 case SJ_SUCCEED: { /* premature success */
403 /* do nothing */
404 } break;
405 } /* end switch */
406 }
407 return !!n_error;
408}
409
410
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
new file mode 100644
index 000000000000..baf187bee983
--- /dev/null
+++ b/scripts/recordmcount.h
@@ -0,0 +1,443 @@
1/*
2 * recordmcount.h
3 *
4 * This code was taken out of recordmcount.c written by
5 * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
6 *
7 * The original code had the same algorithms for both 32bit
8 * and 64bit ELF files, but the code was duplicated to support
9 * the difference in structures that were used. This
10 * file creates a macro of everything that is different between
11 * the 64 and 32 bit code, such that by including this header
12 * twice we can create both sets of functions by including this
13 * header once with RECORD_MCOUNT_64 undefined, and again with
14 * it defined.
15 *
16 * This conversion to macros was done by:
17 * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
18 *
19 * Licensed under the GNU General Public License, version 2 (GPLv2).
20 */
21#undef append_func
22#undef is_fake_mcount
23#undef fn_is_fake_mcount
24#undef MIPS_is_fake_mcount
25#undef sift_rel_mcount
26#undef find_secsym_ndx
27#undef __has_rel_mcount
28#undef has_rel_mcount
29#undef tot_relsize
30#undef do_func
31#undef Elf_Addr
32#undef Elf_Ehdr
33#undef Elf_Shdr
34#undef Elf_Rel
35#undef Elf_Rela
36#undef Elf_Sym
37#undef ELF_R_SYM
38#undef Elf_r_sym
39#undef ELF_R_INFO
40#undef Elf_r_info
41#undef ELF_ST_BIND
42#undef fn_ELF_R_SYM
43#undef fn_ELF_R_INFO
44#undef uint_t
45#undef _w
46#undef _align
47#undef _size
48
49#ifdef RECORD_MCOUNT_64
50# define append_func append64
51# define sift_rel_mcount sift64_rel_mcount
52# define find_secsym_ndx find64_secsym_ndx
53# define __has_rel_mcount __has64_rel_mcount
54# define has_rel_mcount has64_rel_mcount
55# define tot_relsize tot64_relsize
56# define do_func do64
57# define is_fake_mcount is_fake_mcount64
58# define fn_is_fake_mcount fn_is_fake_mcount64
59# define MIPS_is_fake_mcount MIPS64_is_fake_mcount
60# define Elf_Addr Elf64_Addr
61# define Elf_Ehdr Elf64_Ehdr
62# define Elf_Shdr Elf64_Shdr
63# define Elf_Rel Elf64_Rel
64# define Elf_Rela Elf64_Rela
65# define Elf_Sym Elf64_Sym
66# define ELF_R_SYM ELF64_R_SYM
67# define Elf_r_sym Elf64_r_sym
68# define ELF_R_INFO ELF64_R_INFO
69# define Elf_r_info Elf64_r_info
70# define ELF_ST_BIND ELF64_ST_BIND
71# define fn_ELF_R_SYM fn_ELF64_R_SYM
72# define fn_ELF_R_INFO fn_ELF64_R_INFO
73# define uint_t uint64_t
74# define _w w8
75# define _align 7u
76# define _size 8
77#else
78# define append_func append32
79# define sift_rel_mcount sift32_rel_mcount
80# define find_secsym_ndx find32_secsym_ndx
81# define __has_rel_mcount __has32_rel_mcount
82# define has_rel_mcount has32_rel_mcount
83# define tot_relsize tot32_relsize
84# define do_func do32
85# define is_fake_mcount is_fake_mcount32
86# define fn_is_fake_mcount fn_is_fake_mcount32
87# define MIPS_is_fake_mcount MIPS32_is_fake_mcount
88# define Elf_Addr Elf32_Addr
89# define Elf_Ehdr Elf32_Ehdr
90# define Elf_Shdr Elf32_Shdr
91# define Elf_Rel Elf32_Rel
92# define Elf_Rela Elf32_Rela
93# define Elf_Sym Elf32_Sym
94# define ELF_R_SYM ELF32_R_SYM
95# define Elf_r_sym Elf32_r_sym
96# define ELF_R_INFO ELF32_R_INFO
97# define Elf_r_info Elf32_r_info
98# define ELF_ST_BIND ELF32_ST_BIND
99# define fn_ELF_R_SYM fn_ELF32_R_SYM
100# define fn_ELF_R_INFO fn_ELF32_R_INFO
101# define uint_t uint32_t
102# define _w w
103# define _align 3u
104# define _size 4
105#endif
106
107/* Functions and pointers that do_file() may override for specific e_machine. */
108static int fn_is_fake_mcount(Elf_Rel const *rp)
109{
110 return 0;
111}
112static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount;
113
114static uint_t fn_ELF_R_SYM(Elf_Rel const *rp)
115{
116 return ELF_R_SYM(_w(rp->r_info));
117}
118static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
119
120static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
121{
122 rp->r_info = _w(ELF_R_INFO(sym, type));
123}
124static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
125
126/*
127 * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st
128 * _mcount symbol is needed for dynamic function tracer, with it, to disable
129 * tracing(ftrace_make_nop), the instruction in the position is replaced with
130 * the "b label" instruction, to enable tracing(ftrace_make_call), replace the
131 * instruction back. So, here, we set the 2nd one as fake and filter it.
132 *
133 * c: 3c030000 lui v1,0x0 <--> b label
134 * c: R_MIPS_HI16 _mcount
135 * c: R_MIPS_NONE *ABS*
136 * c: R_MIPS_NONE *ABS*
137 * 10: 64630000 daddiu v1,v1,0
138 * 10: R_MIPS_LO16 _mcount
139 * 10: R_MIPS_NONE *ABS*
140 * 10: R_MIPS_NONE *ABS*
141 * 14: 03e0082d move at,ra
142 * 18: 0060f809 jalr v1
143 * label:
144 */
145#define MIPS_FAKEMCOUNT_OFFSET 4
146
147static int MIPS_is_fake_mcount(Elf_Rel const *rp)
148{
149 static Elf_Addr old_r_offset;
150 Elf_Addr current_r_offset = _w(rp->r_offset);
151 int is_fake;
152
153 is_fake = old_r_offset &&
154 (current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET);
155 old_r_offset = current_r_offset;
156
157 return is_fake;
158}
159
160/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
161static void append_func(Elf_Ehdr *const ehdr,
162 Elf_Shdr *const shstr,
163 uint_t const *const mloc0,
164 uint_t const *const mlocp,
165 Elf_Rel const *const mrel0,
166 Elf_Rel const *const mrelp,
167 unsigned int const rel_entsize,
168 unsigned int const symsec_sh_link)
169{
170 /* Begin constructing output file */
171 Elf_Shdr mcsec;
172 char const *mc_name = (sizeof(Elf_Rela) == rel_entsize)
173 ? ".rela__mcount_loc"
174 : ".rel__mcount_loc";
175 unsigned const old_shnum = w2(ehdr->e_shnum);
176 uint_t const old_shoff = _w(ehdr->e_shoff);
177 uint_t const old_shstr_sh_size = _w(shstr->sh_size);
178 uint_t const old_shstr_sh_offset = _w(shstr->sh_offset);
179 uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size);
180 uint_t new_e_shoff;
181
182 shstr->sh_size = _w(t);
183 shstr->sh_offset = _w(sb.st_size);
184 t += sb.st_size;
185 t += (_align & -t); /* word-byte align */
186 new_e_shoff = t;
187
188 /* body for new shstrtab */
189 ulseek(fd_map, sb.st_size, SEEK_SET);
190 uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size);
191 uwrite(fd_map, mc_name, 1 + strlen(mc_name));
192
193 /* old(modified) Elf_Shdr table, word-byte aligned */
194 ulseek(fd_map, t, SEEK_SET);
195 t += sizeof(Elf_Shdr) * old_shnum;
196 uwrite(fd_map, old_shoff + (void *)ehdr,
197 sizeof(Elf_Shdr) * old_shnum);
198
199 /* new sections __mcount_loc and .rel__mcount_loc */
200 t += 2*sizeof(mcsec);
201 mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel")
202 + old_shstr_sh_size);
203 mcsec.sh_type = w(SHT_PROGBITS);
204 mcsec.sh_flags = _w(SHF_ALLOC);
205 mcsec.sh_addr = 0;
206 mcsec.sh_offset = _w(t);
207 mcsec.sh_size = _w((void *)mlocp - (void *)mloc0);
208 mcsec.sh_link = 0;
209 mcsec.sh_info = 0;
210 mcsec.sh_addralign = _w(_size);
211 mcsec.sh_entsize = _w(_size);
212 uwrite(fd_map, &mcsec, sizeof(mcsec));
213
214 mcsec.sh_name = w(old_shstr_sh_size);
215 mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize)
216 ? w(SHT_RELA)
217 : w(SHT_REL);
218 mcsec.sh_flags = 0;
219 mcsec.sh_addr = 0;
220 mcsec.sh_offset = _w((void *)mlocp - (void *)mloc0 + t);
221 mcsec.sh_size = _w((void *)mrelp - (void *)mrel0);
222 mcsec.sh_link = w(symsec_sh_link);
223 mcsec.sh_info = w(old_shnum);
224 mcsec.sh_addralign = _w(_size);
225 mcsec.sh_entsize = _w(rel_entsize);
226 uwrite(fd_map, &mcsec, sizeof(mcsec));
227
228 uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0);
229 uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0);
230
231 ehdr->e_shoff = _w(new_e_shoff);
232 ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */
233 ulseek(fd_map, 0, SEEK_SET);
234 uwrite(fd_map, ehdr, sizeof(*ehdr));
235}
236
237/*
238 * Look at the relocations in order to find the calls to mcount.
239 * Accumulate the section offsets that are found, and their relocation info,
240 * onto the end of the existing arrays.
241 */
242static uint_t *sift_rel_mcount(uint_t *mlocp,
243 unsigned const offbase,
244 Elf_Rel **const mrelpp,
245 Elf_Shdr const *const relhdr,
246 Elf_Ehdr const *const ehdr,
247 unsigned const recsym,
248 uint_t const recval,
249 unsigned const reltype)
250{
251 uint_t *const mloc0 = mlocp;
252 Elf_Rel *mrelp = *mrelpp;
253 Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
254 + (void *)ehdr);
255 unsigned const symsec_sh_link = w(relhdr->sh_link);
256 Elf_Shdr const *const symsec = &shdr0[symsec_sh_link];
257 Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset)
258 + (void *)ehdr);
259
260 Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)];
261 char const *const str0 = (char const *)(_w(strsec->sh_offset)
262 + (void *)ehdr);
263
264 Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset)
265 + (void *)ehdr);
266 unsigned rel_entsize = _w(relhdr->sh_entsize);
267 unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
268 Elf_Rel const *relp = rel0;
269
270 unsigned mcountsym = 0;
271 unsigned t;
272
273 for (t = nrel; t; --t) {
274 if (!mcountsym) {
275 Elf_Sym const *const symp =
276 &sym0[Elf_r_sym(relp)];
277 char const *symname = &str0[w(symp->st_name)];
278 char const *mcount = '_' == gpfx ? "_mcount" : "mcount";
279
280 if ('.' == symname[0])
281 ++symname; /* ppc64 hack */
282 if (0 == strcmp(mcount, symname) ||
283 (altmcount && 0 == strcmp(altmcount, symname)))
284 mcountsym = Elf_r_sym(relp);
285 }
286
287 if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
288 uint_t const addend = _w(_w(relp->r_offset) - recval);
289
290 mrelp->r_offset = _w(offbase
291 + ((void *)mlocp - (void *)mloc0));
292 Elf_r_info(mrelp, recsym, reltype);
293 if (sizeof(Elf_Rela) == rel_entsize) {
294 ((Elf_Rela *)mrelp)->r_addend = addend;
295 *mlocp++ = 0;
296 } else
297 *mlocp++ = addend;
298
299 mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp);
300 }
301 relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
302 }
303 *mrelpp = mrelp;
304 return mlocp;
305}
306
307
308/*
309 * Find a symbol in the given section, to be used as the base for relocating
310 * the table of offsets of calls to mcount. A local or global symbol suffices,
311 * but avoid a Weak symbol because it may be overridden; the change in value
312 * would invalidate the relocations of the offsets of the calls to mcount.
313 * Often the found symbol will be the unnamed local symbol generated by
314 * GNU 'as' for the start of each section. For example:
315 * Num: Value Size Type Bind Vis Ndx Name
316 * 2: 00000000 0 SECTION LOCAL DEFAULT 1
317 */
318static unsigned find_secsym_ndx(unsigned const txtndx,
319 char const *const txtname,
320 uint_t *const recvalp,
321 Elf_Shdr const *const symhdr,
322 Elf_Ehdr const *const ehdr)
323{
324 Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset)
325 + (void *)ehdr);
326 unsigned const nsym = _w(symhdr->sh_size) / _w(symhdr->sh_entsize);
327 Elf_Sym const *symp;
328 unsigned t;
329
330 for (symp = sym0, t = nsym; t; --t, ++symp) {
331 unsigned int const st_bind = ELF_ST_BIND(symp->st_info);
332
333 if (txtndx == w2(symp->st_shndx)
334 /* avoid STB_WEAK */
335 && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
336 *recvalp = _w(symp->st_value);
337 return symp - sym0;
338 }
339 }
340 fprintf(stderr, "Cannot find symbol for section %d: %s.\n",
341 txtndx, txtname);
342 fail_file();
343}
344
345
346/* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */
347static char const *
348__has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
349 Elf_Shdr const *const shdr0,
350 char const *const shstrtab,
351 char const *const fname)
352{
353 /* .sh_info depends on .sh_type == SHT_REL[,A] */
354 Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
355 char const *const txtname = &shstrtab[w(txthdr->sh_name)];
356
357 if (0 == strcmp("__mcount_loc", txtname)) {
358 fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
359 fname);
360 succeed_file();
361 }
362 if (SHT_PROGBITS != w(txthdr->sh_type) ||
363 !is_mcounted_section_name(txtname))
364 return NULL;
365 return txtname;
366}
367
368static char const *has_rel_mcount(Elf_Shdr const *const relhdr,
369 Elf_Shdr const *const shdr0,
370 char const *const shstrtab,
371 char const *const fname)
372{
373 if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type))
374 return NULL;
375 return __has_rel_mcount(relhdr, shdr0, shstrtab, fname);
376}
377
378
379static unsigned tot_relsize(Elf_Shdr const *const shdr0,
380 unsigned nhdr,
381 const char *const shstrtab,
382 const char *const fname)
383{
384 unsigned totrelsz = 0;
385 Elf_Shdr const *shdrp = shdr0;
386
387 for (; nhdr; --nhdr, ++shdrp) {
388 if (has_rel_mcount(shdrp, shdr0, shstrtab, fname))
389 totrelsz += _w(shdrp->sh_size);
390 }
391 return totrelsz;
392}
393
394
395/* Overall supervision for Elf32 ET_REL file. */
396static void
397do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
398{
399 Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
400 + (void *)ehdr);
401 unsigned const nhdr = w2(ehdr->e_shnum);
402 Elf_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)];
403 char const *const shstrtab = (char const *)(_w(shstr->sh_offset)
404 + (void *)ehdr);
405
406 Elf_Shdr const *relhdr;
407 unsigned k;
408
409 /* Upper bound on space: assume all relevant relocs are for mcount. */
410 unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname);
411 Elf_Rel *const mrel0 = umalloc(totrelsz);
412 Elf_Rel * mrelp = mrel0;
413
414 /* 2*sizeof(address) <= sizeof(Elf_Rel) */
415 uint_t *const mloc0 = umalloc(totrelsz>>1);
416 uint_t * mlocp = mloc0;
417
418 unsigned rel_entsize = 0;
419 unsigned symsec_sh_link = 0;
420
421 for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
422 char const *const txtname = has_rel_mcount(relhdr, shdr0,
423 shstrtab, fname);
424 if (txtname) {
425 uint_t recval = 0;
426 unsigned const recsym = find_secsym_ndx(
427 w(relhdr->sh_info), txtname, &recval,
428 &shdr0[symsec_sh_link = w(relhdr->sh_link)],
429 ehdr);
430
431 rel_entsize = _w(relhdr->sh_entsize);
432 mlocp = sift_rel_mcount(mlocp,
433 (void *)mlocp - (void *)mloc0, &mrelp,
434 relhdr, ehdr, recsym, recval, reltype);
435 }
436 }
437 if (mloc0 != mlocp) {
438 append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
439 rel_entsize, symsec_sh_link);
440 }
441 free(mrel0);
442 free(mloc0);
443}
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 7109e2b5bc0a..1d7963f4ee79 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -6,78 +6,93 @@
6# all the offsets to the calls to mcount. 6# all the offsets to the calls to mcount.
7# 7#
8# 8#
9# What we want to end up with is a section in vmlinux called 9# What we want to end up with this is that each object file will have a
10# __mcount_loc that contains a list of pointers to all the 10# section called __mcount_loc that will hold the list of pointers to mcount
11# call sites in the kernel that call mcount. Later on boot up, the kernel 11# callers. After final linking, the vmlinux will have within .init.data the
12# will read this list, save the locations and turn them into nops. 12# list of all callers to mcount between __start_mcount_loc and __stop_mcount_loc.
13# When tracing or profiling is later enabled, these locations will then 13# Later on boot up, the kernel will read this list, save the locations and turn
14# be converted back to pointers to some function. 14# them into nops. When tracing or profiling is later enabled, these locations
15# will then be converted back to pointers to some function.
15# 16#
16# This is no easy feat. This script is called just after the original 17# This is no easy feat. This script is called just after the original
17# object is compiled and before it is linked. 18# object is compiled and before it is linked.
18# 19#
19# The references to the call sites are offsets from the section of text 20# When parse this object file using 'objdump', the references to the call
20# that the call site is in. Hence, all functions in a section that 21# sites are offsets from the section that the call site is in. Hence, all
21# has a call site to mcount, will have the offset from the beginning of 22# functions in a section that has a call site to mcount, will have the
22# the section and not the beginning of the function. 23# offset from the beginning of the section and not the beginning of the
24# function.
25#
26# But where this section will reside finally in vmlinx is undetermined at
27# this point. So we can't use this kind of offsets to record the final
28# address of this call site.
29#
30# The trick is to change the call offset referring the start of a section to
31# referring a function symbol in this section. During the link step, 'ld' will
32# compute the final address according to the information we record.
23# 33#
24# The trick is to find a way to record the beginning of the section.
25# The way we do this is to look at the first function in the section
26# which will also be the location of that section after final link.
27# e.g. 34# e.g.
28# 35#
29# .section ".sched.text", "ax" 36# .section ".sched.text", "ax"
30# .globl my_func
31# my_func:
32# [...] 37# [...]
33# call mcount (offset: 0x5) 38# func1:
39# [...]
40# call mcount (offset: 0x10)
34# [...] 41# [...]
35# ret 42# ret
36# other_func: 43# .globl fun2
44# func2: (offset: 0x20)
37# [...] 45# [...]
38# call mcount (offset: 0x1b) 46# [...]
47# ret
48# func3:
49# [...]
50# call mcount (offset: 0x30)
39# [...] 51# [...]
40# 52#
41# Both relocation offsets for the mcounts in the above example will be 53# Both relocation offsets for the mcounts in the above example will be
42# offset from .sched.text. If we make another file called tmp.s with: 54# offset from .sched.text. If we choose global symbol func2 as a reference and
55# make another file called tmp.s with the new offsets:
43# 56#
44# .section __mcount_loc 57# .section __mcount_loc
45# .quad my_func + 0x5 58# .quad func2 - 0x10
46# .quad my_func + 0x1b 59# .quad func2 + 0x10
47# 60#
48# We can then compile this tmp.s into tmp.o, and link it to the original 61# We can then compile this tmp.s into tmp.o, and link it back to the original
49# object. 62# object.
50# 63#
51# But this gets hard if my_func is not globl (a static function). 64# In our algorithm, we will choose the first global function we meet in this
52# In such a case we have: 65# section as the reference. But this gets hard if there is no global functions
66# in this section. In such a case we have to select a local one. E.g. func1:
53# 67#
54# .section ".sched.text", "ax" 68# .section ".sched.text", "ax"
55# my_func: 69# func1:
56# [...] 70# [...]
57# call mcount (offset: 0x5) 71# call mcount (offset: 0x10)
58# [...] 72# [...]
59# ret 73# ret
60# .globl my_func 74# func2:
61# other_func:
62# [...] 75# [...]
63# call mcount (offset: 0x1b) 76# call mcount (offset: 0x20)
64# [...] 77# [...]
78# .section "other.section"
65# 79#
66# If we make the tmp.s the same as above, when we link together with 80# If we make the tmp.s the same as above, when we link together with
67# the original object, we will end up with two symbols for my_func: 81# the original object, we will end up with two symbols for func1:
68# one local, one global. After final compile, we will end up with 82# one local, one global. After final compile, we will end up with
69# an undefined reference to my_func. 83# an undefined reference to func1 or a wrong reference to another global
84# func1 in other files.
70# 85#
71# Since local objects can reference local variables, we need to find 86# Since local objects can reference local variables, we need to find
72# a way to make tmp.o reference the local objects of the original object 87# a way to make tmp.o reference the local objects of the original object
73# file after it is linked together. To do this, we convert the my_func 88# file after it is linked together. To do this, we convert func1
74# into a global symbol before linking tmp.o. Then after we link tmp.o 89# into a global symbol before linking tmp.o. Then after we link tmp.o
75# we will only have a single symbol for my_func that is global. 90# we will only have a single symbol for func1 that is global.
76# We can convert my_func back into a local symbol and we are done. 91# We can convert func1 back into a local symbol and we are done.
77# 92#
78# Here are the steps we take: 93# Here are the steps we take:
79# 94#
80# 1) Record all the local symbols by using 'nm' 95# 1) Record all the local and weak symbols by using 'nm'
81# 2) Use objdump to find all the call site offsets and sections for 96# 2) Use objdump to find all the call site offsets and sections for
82# mcount. 97# mcount.
83# 3) Compile the list into its own object. 98# 3) Compile the list into its own object.
@@ -87,10 +102,8 @@
87# 6) Link together this new object with the list object. 102# 6) Link together this new object with the list object.
88# 7) Convert the local functions back to local symbols and rename 103# 7) Convert the local functions back to local symbols and rename
89# the result as the original object. 104# the result as the original object.
90# End.
91# 8) Link the object with the list object. 105# 8) Link the object with the list object.
92# 9) Move the result back to the original object. 106# 9) Move the result back to the original object.
93# End.
94# 107#
95 108
96use strict; 109use strict;
@@ -100,17 +113,17 @@ $P =~ s@.*/@@g;
100 113
101my $V = '0.1'; 114my $V = '0.1';
102 115
103if ($#ARGV < 7) { 116if ($#ARGV != 11) {
104 print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; 117 print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
105 print "version: $V\n"; 118 print "version: $V\n";
106 exit(1); 119 exit(1);
107} 120}
108 121
109my ($arch, $bits, $objdump, $objcopy, $cc, 122my ($arch, $endian, $bits, $objdump, $objcopy, $cc,
110 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; 123 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
111 124
112# This file refers to mcount and shouldn't be ftraced, so lets' ignore it 125# This file refers to mcount and shouldn't be ftraced, so lets' ignore it
113if ($inputfile eq "kernel/trace/ftrace.o") { 126if ($inputfile =~ m,kernel/trace/ftrace\.o$,) {
114 exit(0); 127 exit(0);
115} 128}
116 129
@@ -120,15 +133,17 @@ my %text_sections = (
120 ".sched.text" => 1, 133 ".sched.text" => 1,
121 ".spinlock.text" => 1, 134 ".spinlock.text" => 1,
122 ".irqentry.text" => 1, 135 ".irqentry.text" => 1,
136 ".text.unlikely" => 1,
123); 137);
124 138
125$objdump = "objdump" if ((length $objdump) == 0); 139# Note: we are nice to C-programmers here, thus we skip the '||='-idiom.
126$objcopy = "objcopy" if ((length $objcopy) == 0); 140$objdump = 'objdump' if (!$objdump);
127$cc = "gcc" if ((length $cc) == 0); 141$objcopy = 'objcopy' if (!$objcopy);
128$ld = "ld" if ((length $ld) == 0); 142$cc = 'gcc' if (!$cc);
129$nm = "nm" if ((length $nm) == 0); 143$ld = 'ld' if (!$ld);
130$rm = "rm" if ((length $rm) == 0); 144$nm = 'nm' if (!$nm);
131$mv = "mv" if ((length $mv) == 0); 145$rm = 'rm' if (!$rm);
146$mv = 'mv' if (!$mv);
132 147
133#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " . 148#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " .
134# "'$nm' '$rm' '$mv' '$inputfile'\n"; 149# "'$nm' '$rm' '$mv' '$inputfile'\n";
@@ -138,15 +153,50 @@ my %weak; # List of weak functions
138my %convert; # List of local functions used that needs conversion 153my %convert; # List of local functions used that needs conversion
139 154
140my $type; 155my $type;
141my $nm_regex; # Find the local functions (return function) 156my $local_regex; # Match a local function (return function)
157my $weak_regex; # Match a weak function (return function)
142my $section_regex; # Find the start of a section 158my $section_regex; # Find the start of a section
143my $function_regex; # Find the name of a function 159my $function_regex; # Find the name of a function
144 # (return offset and func name) 160 # (return offset and func name)
145my $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
146my $alignment; # The .align value to use for $mcount_section 163my $alignment; # The .align value to use for $mcount_section
147my $section_type; # Section header plus possible alignment command 164my $section_type; # Section header plus possible alignment command
165my $can_use_local = 0; # If we can use local function references
166
167# Shut up recordmcount if user has older objcopy
168my $quiet_recordmcount = ".tmp_quiet_recordmcount";
169my $print_warning = 1;
170$print_warning = 0 if ( -f $quiet_recordmcount);
171
172##
173# check_objcopy - whether objcopy supports --globalize-symbols
174#
175# --globalize-symbols came out in 2.17, we must test the version
176# of objcopy, and if it is less than 2.17, then we can not
177# record local functions.
178sub check_objcopy
179{
180 open (IN, "$objcopy --version |") or die "error running $objcopy";
181 while (<IN>) {
182 if (/objcopy.*\s(\d+)\.(\d+)/) {
183 $can_use_local = 1 if ($1 > 2 || ($1 == 2 && $2 >= 17));
184 last;
185 }
186 }
187 close (IN);
188
189 if (!$can_use_local && $print_warning) {
190 print STDERR "WARNING: could not find objcopy version or version " .
191 "is less than 2.17.\n" .
192 "\tLocal function references are disabled.\n";
193 open (QUIET, ">$quiet_recordmcount");
194 printf QUIET "Disables the warning from recordmcount.pl\n";
195 close QUIET;
196 }
197}
148 198
149if ($arch eq "x86") { 199if ($arch =~ /(x86(_64)?)|(i386)/) {
150 if ($bits == 64) { 200 if ($bits == 64) {
151 $arch = "x86_64"; 201 $arch = "x86_64";
152 } else { 202 } else {
@@ -158,11 +208,13 @@ if ($arch eq "x86") {
158# We base the defaults off of i386, the other archs may 208# We base the defaults off of i386, the other archs may
159# feel free to change them in the below if statements. 209# feel free to change them in the below if statements.
160# 210#
161$nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)"; 211$local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
212$weak_regex = "^[0-9a-fA-F]+\\s+([wW])\\s+(\\S+)";
162$section_regex = "Disassembly of section\\s+(\\S+):"; 213$section_regex = "Disassembly of section\\s+(\\S+):";
163$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; 214$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
164$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; 215$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
165$section_type = '@progbits'; 216$section_type = '@progbits';
217$mcount_adjust = 0;
166$type = ".long"; 218$type = ".long";
167 219
168if ($arch eq "x86_64") { 220if ($arch eq "x86_64") {
@@ -207,7 +259,7 @@ if ($arch eq "x86_64") {
207 $cc .= " -m32"; 259 $cc .= " -m32";
208 260
209} elsif ($arch eq "powerpc") { 261} elsif ($arch eq "powerpc") {
210 $nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)"; 262 $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
211 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:"; 263 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
212 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$"; 264 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
213 265
@@ -218,6 +270,8 @@ if ($arch eq "x86_64") {
218} elsif ($arch eq "arm") { 270} elsif ($arch eq "arm") {
219 $alignment = 2; 271 $alignment = 2;
220 $section_type = '%progbits'; 272 $section_type = '%progbits';
273 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" .
274 "\\s+(__gnu_mcount_nc|mcount)\$";
221 275
222} elsif ($arch eq "ia64") { 276} elsif ($arch eq "ia64") {
223 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; 277 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
@@ -246,6 +300,64 @@ if ($arch eq "x86_64") {
246 $ld .= " -m elf64_sparc"; 300 $ld .= " -m elf64_sparc";
247 $cc .= " -m64"; 301 $cc .= " -m64";
248 $objcopy .= " -O elf64-sparc"; 302 $objcopy .= " -O elf64-sparc";
303} elsif ($arch eq "mips") {
304 # To enable module support, we need to enable the -mlong-calls option
305 # of gcc for module, after using this option, we can not get the real
306 # offset of the calling to _mcount, but the offset of the lui
307 # instruction or the addiu one. herein, we record the address of the
308 # first one, and then we can replace this instruction by a branch
309 # instruction to jump over the profiling function to filter the
310 # indicated functions, or swith back to the lui instruction to trace
311 # them, which means dynamic tracing.
312 #
313 # c: 3c030000 lui v1,0x0
314 # c: R_MIPS_HI16 _mcount
315 # c: R_MIPS_NONE *ABS*
316 # c: R_MIPS_NONE *ABS*
317 # 10: 64630000 daddiu v1,v1,0
318 # 10: R_MIPS_LO16 _mcount
319 # 10: R_MIPS_NONE *ABS*
320 # 10: R_MIPS_NONE *ABS*
321 # 14: 03e0082d move at,ra
322 # 18: 0060f809 jalr v1
323 #
324 # for the kernel:
325 #
326 # 10: 03e0082d move at,ra
327 # 14: 0c000000 jal 0 <loongson_halt>
328 # 14: R_MIPS_26 _mcount
329 # 14: R_MIPS_NONE *ABS*
330 # 14: R_MIPS_NONE *ABS*
331 # 18: 00020021 nop
332 if ($is_module eq "0") {
333 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_26\\s+_mcount\$";
334 } else {
335 $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$";
336 }
337 $objdump .= " -Melf-trad".$endian."mips ";
338
339 if ($endian eq "big") {
340 $endian = " -EB ";
341 $ld .= " -melf".$bits."btsmip";
342 } else {
343 $endian = " -EL ";
344 $ld .= " -melf".$bits."ltsmip";
345 }
346
347 $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian;
348 $ld .= $endian;
349
350 if ($bits == 64) {
351 $function_regex =
352 "^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:";
353 $type = ".dword";
354 }
355} elsif ($arch eq "microblaze") {
356 # Microblaze calls '_mcount' instead of plain 'mcount'.
357 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
358} elsif ($arch eq "blackfin") {
359 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
360 $mcount_adjust = -4;
249} else { 361} else {
250 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 362 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
251} 363}
@@ -279,44 +391,17 @@ if ($filename =~ m,^(.*)(\.\S),) {
279my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s"; 391my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
280my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o"; 392my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
281 393
282# 394check_objcopy();
283# --globalize-symbols came out in 2.17, we must test the version
284# of objcopy, and if it is less than 2.17, then we can not
285# record local functions.
286my $use_locals = 01;
287my $local_warn_once = 0;
288my $found_version = 0;
289
290open (IN, "$objcopy --version |") || die "error running $objcopy";
291while (<IN>) {
292 if (/objcopy.*\s(\d+)\.(\d+)/) {
293 my $major = $1;
294 my $minor = $2;
295
296 $found_version = 1;
297 if ($major < 2 ||
298 ($major == 2 && $minor < 17)) {
299 $use_locals = 0;
300 }
301 last;
302 }
303}
304close (IN);
305
306if (!$found_version) {
307 print STDERR "WARNING: could not find objcopy version.\n" .
308 "\tDisabling local function references.\n";
309}
310 395
311# 396#
312# Step 1: find all the local (static functions) and weak symbols. 397# Step 1: find all the local (static functions) and weak symbols.
313# 't' is local, 'w/W' is weak (we never use a weak function) 398# 't' is local, 'w/W' is weak
314# 399#
315open (IN, "$nm $inputfile|") || die "error running $nm"; 400open (IN, "$nm $inputfile|") || die "error running $nm";
316while (<IN>) { 401while (<IN>) {
317 if (/$nm_regex/) { 402 if (/$local_regex/) {
318 $locals{$1} = 1; 403 $locals{$1} = 1;
319 } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) { 404 } elsif (/$weak_regex/) {
320 $weak{$2} = $1; 405 $weak{$2} = $1;
321 } 406 }
322} 407}
@@ -334,26 +419,20 @@ my $offset = 0; # offset of ref_func to section beginning
334# 419#
335sub update_funcs 420sub update_funcs
336{ 421{
337 return if ($#offsets < 0); 422 return unless ($ref_func and @offsets);
338
339 defined($ref_func) || die "No function to reference";
340 423
341 # A section only had a weak function, to represent it. 424 # Sanity check on weak function. A weak function may be overwritten by
342 # Unfortunately, a weak function may be overwritten by another 425 # another function of the same name, making all these offsets incorrect.
343 # function of the same name, making all these offsets incorrect.
344 # To be safe, we simply print a warning and bail.
345 if (defined $weak{$ref_func}) { 426 if (defined $weak{$ref_func}) {
346 print STDERR 427 die "$inputfile: ERROR: referencing weak function" .
347 "$inputfile: WARNING: referencing weak function" .
348 " $ref_func for mcount\n"; 428 " $ref_func for mcount\n";
349 return;
350 } 429 }
351 430
352 # is this function static? If so, note this fact. 431 # is this function static? If so, note this fact.
353 if (defined $locals{$ref_func}) { 432 if (defined $locals{$ref_func}) {
354 433
355 # only use locals if objcopy supports globalize-symbols 434 # only use locals if objcopy supports globalize-symbols
356 if (!$use_locals) { 435 if (!$can_use_local) {
357 return; 436 return;
358 } 437 }
359 $convert{$ref_func} = 1; 438 $convert{$ref_func} = 1;
@@ -361,14 +440,14 @@ sub update_funcs
361 440
362 # Loop through all the mcount caller offsets and print a reference 441 # Loop through all the mcount caller offsets and print a reference
363 # to the caller based from the ref_func. 442 # to the caller based from the ref_func.
364 for (my $i=0; $i <= $#offsets; $i++) { 443 if (!$opened) {
365 if (!$opened) { 444 open(FILE, ">$mcount_s") || die "can't create $mcount_s\n";
366 open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; 445 $opened = 1;
367 $opened = 1; 446 print FILE "\t.section $mcount_section,\"a\",$section_type\n";
368 print FILE "\t.section $mcount_section,\"a\",$section_type\n"; 447 print FILE "\t.align $alignment\n" if (defined($alignment));
369 print FILE "\t.align $alignment\n" if (defined($alignment)); 448 }
370 } 449 foreach my $cur_offset (@offsets) {
371 printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset; 450 printf FILE "\t%s %s + %d\n", $type, $ref_func, $cur_offset - $offset;
372 } 451 }
373} 452}
374 453
@@ -379,21 +458,35 @@ open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump";
379 458
380my $text; 459my $text;
381 460
461
462# read headers first
382my $read_headers = 1; 463my $read_headers = 1;
383 464
384while (<IN>) { 465while (<IN>) {
466
467 if ($read_headers && /$mcount_section/) {
468 #
469 # Somehow the make process can execute this script on an
470 # object twice. If it does, we would duplicate the mcount
471 # section and it will cause the function tracer self test
472 # to fail. Check if the mcount section exists, and if it does,
473 # warn and exit.
474 #
475 print STDERR "ERROR: $mcount_section already in $inputfile\n" .
476 "\tThis may be an indication that your build is corrupted.\n" .
477 "\tDelete $inputfile and try again. If the same object file\n" .
478 "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
479 exit(-1);
480 }
481
385 # is it a section? 482 # is it a section?
386 if (/$section_regex/) { 483 if (/$section_regex/) {
387 $read_headers = 0; 484 $read_headers = 0;
388 485
389 # Only record text sections that we know are safe 486 # Only record text sections that we know are safe
390 if (defined($text_sections{$1})) { 487 $read_function = defined($text_sections{$1});
391 $read_function = 1;
392 } else {
393 $read_function = 0;
394 }
395 # print out any recorded offsets 488 # print out any recorded offsets
396 update_funcs() if ($text_found); 489 update_funcs();
397 490
398 # reset all markers and arrays 491 # reset all markers and arrays
399 $text_found = 0; 492 $text_found = 0;
@@ -403,7 +496,6 @@ while (<IN>) {
403 # section found, now is this a start of a function? 496 # section found, now is this a start of a function?
404 } elsif ($read_function && /$function_regex/) { 497 } elsif ($read_function && /$function_regex/) {
405 $text_found = 1; 498 $text_found = 1;
406 $offset = hex $1;
407 $text = $2; 499 $text = $2;
408 500
409 # if this is either a local function or a weak function 501 # if this is either a local function or a weak function
@@ -412,35 +504,26 @@ while (<IN>) {
412 if (!defined($locals{$text}) && !defined($weak{$text})) { 504 if (!defined($locals{$text}) && !defined($weak{$text})) {
413 $ref_func = $text; 505 $ref_func = $text;
414 $read_function = 0; 506 $read_function = 0;
507 $offset = hex $1;
415 } else { 508 } else {
416 # if we already have a function, and this is weak, skip it 509 # if we already have a function, and this is weak, skip it
417 if (!defined($ref_func) || !defined($weak{$text})) { 510 if (!defined($ref_func) && !defined($weak{$text}) &&
511 # PPC64 can have symbols that start with .L and
512 # gcc considers these special. Don't use them!
513 $text !~ /^\.L/) {
418 $ref_func = $text; 514 $ref_func = $text;
515 $offset = hex $1;
419 } 516 }
420 } 517 }
421 } elsif ($read_headers && /$mcount_section/) {
422 #
423 # Somehow the make process can execute this script on an
424 # object twice. If it does, we would duplicate the mcount
425 # section and it will cause the function tracer self test
426 # to fail. Check if the mcount section exists, and if it does,
427 # warn and exit.
428 #
429 print STDERR "ERROR: $mcount_section already in $inputfile\n" .
430 "\tThis may be an indication that your build is corrupted.\n" .
431 "\tDelete $inputfile and try again. If the same object file\n" .
432 "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
433 exit(-1);
434 } 518 }
435
436 # is this a call site to mcount? If so, record it to print later 519 # is this a call site to mcount? If so, record it to print later
437 if ($text_found && /$mcount_regex/) { 520 if ($text_found && /$mcount_regex/) {
438 $offsets[$#offsets + 1] = hex $1; 521 push(@offsets, (hex $1) + $mcount_adjust);
439 } 522 }
440} 523}
441 524
442# dump out anymore offsets that may have been found 525# dump out anymore offsets that may have been found
443update_funcs() if ($text_found); 526update_funcs();
444 527
445# If we did not find any mcount callers, we are done (do nothing). 528# If we did not find any mcount callers, we are done (do nothing).
446if (!$opened) { 529if (!$opened) {
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/Makefile b/scripts/selinux/Makefile
index ca4b1ec01822..e8049da1831f 100644
--- a/scripts/selinux/Makefile
+++ b/scripts/selinux/Makefile
@@ -1,2 +1,2 @@
1subdir-y := mdp 1subdir-y := mdp genheaders
2subdir- += mdp 2subdir- += mdp genheaders
diff --git a/scripts/selinux/genheaders/.gitignore b/scripts/selinux/genheaders/.gitignore
new file mode 100644
index 000000000000..4c0b646ff8d5
--- /dev/null
+++ b/scripts/selinux/genheaders/.gitignore
@@ -0,0 +1 @@
genheaders
diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile
new file mode 100644
index 000000000000..417b165008ee
--- /dev/null
+++ b/scripts/selinux/genheaders/Makefile
@@ -0,0 +1,5 @@
1hostprogs-y := genheaders
2HOST_EXTRACFLAGS += -Isecurity/selinux/include
3
4always := $(hostprogs-y)
5clean-files := $(hostprogs-y)
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
new file mode 100644
index 000000000000..58a12c278706
--- /dev/null
+++ b/scripts/selinux/genheaders/genheaders.c
@@ -0,0 +1,118 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <errno.h>
6#include <ctype.h>
7
8struct security_class_mapping {
9 const char *name;
10 const char *perms[sizeof(unsigned) * 8 + 1];
11};
12
13#include "classmap.h"
14#include "initial_sid_to_string.h"
15
16#define max(x, y) (((int)(x) > (int)(y)) ? x : y)
17
18const char *progname;
19
20static void usage(void)
21{
22 printf("usage: %s flask.h av_permissions.h\n", progname);
23 exit(1);
24}
25
26static char *stoupperx(const char *s)
27{
28 char *s2 = strdup(s);
29 char *p;
30
31 if (!s2) {
32 fprintf(stderr, "%s: out of memory\n", progname);
33 exit(3);
34 }
35
36 for (p = s2; *p; p++)
37 *p = toupper(*p);
38 return s2;
39}
40
41int main(int argc, char *argv[])
42{
43 int i, j, k;
44 int isids_len;
45 FILE *fout;
46
47 progname = argv[0];
48
49 if (argc < 3)
50 usage();
51
52 fout = fopen(argv[1], "w");
53 if (!fout) {
54 fprintf(stderr, "Could not open %s for writing: %s\n",
55 argv[1], strerror(errno));
56 exit(2);
57 }
58
59 for (i = 0; secclass_map[i].name; i++) {
60 struct security_class_mapping *map = &secclass_map[i];
61 map->name = stoupperx(map->name);
62 for (j = 0; map->perms[j]; j++)
63 map->perms[j] = stoupperx(map->perms[j]);
64 }
65
66 isids_len = sizeof(initial_sid_to_string) / sizeof (char *);
67 for (i = 1; i < isids_len; i++)
68 initial_sid_to_string[i] = stoupperx(initial_sid_to_string[i]);
69
70 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
71 fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
72
73 for (i = 0; secclass_map[i].name; i++) {
74 struct security_class_mapping *map = &secclass_map[i];
75 fprintf(fout, "#define SECCLASS_%s", map->name);
76 for (j = 0; j < max(1, 40 - strlen(map->name)); j++)
77 fprintf(fout, " ");
78 fprintf(fout, "%2d\n", i+1);
79 }
80
81 fprintf(fout, "\n");
82
83 for (i = 1; i < isids_len; i++) {
84 const char *s = initial_sid_to_string[i];
85 fprintf(fout, "#define SECINITSID_%s", s);
86 for (j = 0; j < max(1, 40 - strlen(s)); j++)
87 fprintf(fout, " ");
88 fprintf(fout, "%2d\n", i);
89 }
90 fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
91 fprintf(fout, "\n#endif\n");
92 fclose(fout);
93
94 fout = fopen(argv[2], "w");
95 if (!fout) {
96 fprintf(stderr, "Could not open %s for writing: %s\n",
97 argv[2], strerror(errno));
98 exit(4);
99 }
100
101 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
102 fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
103
104 for (i = 0; secclass_map[i].name; i++) {
105 struct security_class_mapping *map = &secclass_map[i];
106 for (j = 0; map->perms[j]; j++) {
107 fprintf(fout, "#define %s__%s", map->name,
108 map->perms[j]);
109 for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++)
110 fprintf(fout, " ");
111 fprintf(fout, "0x%08xUL\n", (1<<j));
112 }
113 }
114
115 fprintf(fout, "\n#endif\n");
116 fclose(fout);
117 exit(0);
118}
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index ca757d486187..62b34ce1f50d 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -29,86 +29,27 @@
29#include <unistd.h> 29#include <unistd.h>
30#include <string.h> 30#include <string.h>
31 31
32#include "flask.h" 32static void usage(char *name)
33
34void usage(char *name)
35{ 33{
36 printf("usage: %s [-m] policy_file context_file\n", name); 34 printf("usage: %s [-m] policy_file context_file\n", name);
37 exit(1); 35 exit(1);
38} 36}
39 37
40void find_common_name(char *cname, char *dest, int len) 38/* Class/perm mapping support */
41{ 39struct security_class_mapping {
42 char *start, *end; 40 const char *name;
43 41 const char *perms[sizeof(unsigned) * 8 + 1];
44 start = strchr(cname, '_')+1;
45 end = strchr(start, '_');
46 if (!start || !end || start-cname > len || end-start > len) {
47 printf("Error with commons defines\n");
48 exit(1);
49 }
50 strncpy(dest, start, end-start);
51 dest[end-start] = '\0';
52}
53
54#define S_(x) x,
55static char *classlist[] = {
56#include "class_to_string.h"
57 NULL
58}; 42};
59#undef S_
60 43
44#include "classmap.h"
61#include "initial_sid_to_string.h" 45#include "initial_sid_to_string.h"
62 46
63#define TB_(x) char *x[] = {
64#define TE_(x) NULL };
65#define S_(x) x,
66#include "common_perm_to_string.h"
67#undef TB_
68#undef TE_
69#undef S_
70
71struct common {
72 char *cname;
73 char **perms;
74};
75struct common common[] = {
76#define TB_(x) { #x, x },
77#define S_(x)
78#define TE_(x)
79#include "common_perm_to_string.h"
80#undef TB_
81#undef TE_
82#undef S_
83};
84
85#define S_(x, y, z) {x, #y},
86struct av_inherit {
87 int class;
88 char *common;
89};
90struct av_inherit av_inherit[] = {
91#include "av_inherit.h"
92};
93#undef S_
94
95#include "av_permissions.h"
96#define S_(x, y, z) {x, y, z},
97struct av_perms {
98 int class;
99 int perm_i;
100 char *perm_s;
101};
102struct av_perms av_perms[] = {
103#include "av_perm_to_string.h"
104};
105#undef S_
106
107int main(int argc, char *argv[]) 47int main(int argc, char *argv[])
108{ 48{
109 int i, j, mls = 0; 49 int i, j, mls = 0;
50 int initial_sid_to_string_len;
110 char **arg, *polout, *ctxout; 51 char **arg, *polout, *ctxout;
111 int classlist_len, initial_sid_to_string_len; 52
112 FILE *fout; 53 FILE *fout;
113 54
114 if (argc < 3) 55 if (argc < 3)
@@ -127,64 +68,25 @@ int main(int argc, char *argv[])
127 usage(argv[0]); 68 usage(argv[0]);
128 } 69 }
129 70
130 classlist_len = sizeof(classlist) / sizeof(char *);
131 /* print out the classes */ 71 /* print out the classes */
132 for (i=1; i < classlist_len; i++) { 72 for (i = 0; secclass_map[i].name; i++)
133 if(classlist[i]) 73 fprintf(fout, "class %s\n", secclass_map[i].name);
134 fprintf(fout, "class %s\n", classlist[i]);
135 else
136 fprintf(fout, "class user%d\n", i);
137 }
138 fprintf(fout, "\n"); 74 fprintf(fout, "\n");
139 75
140 initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); 76 initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
141 /* print out the sids */ 77 /* print out the sids */
142 for (i=1; i < initial_sid_to_string_len; i++) 78 for (i = 1; i < initial_sid_to_string_len; i++)
143 fprintf(fout, "sid %s\n", initial_sid_to_string[i]); 79 fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
144 fprintf(fout, "\n"); 80 fprintf(fout, "\n");
145 81
146 /* print out the commons */
147 for (i=0; i< sizeof(common)/sizeof(struct common); i++) {
148 char cname[101];
149 find_common_name(common[i].cname, cname, 100);
150 cname[100] = '\0';
151 fprintf(fout, "common %s\n{\n", cname);
152 for (j=0; common[i].perms[j]; j++)
153 fprintf(fout, "\t%s\n", common[i].perms[j]);
154 fprintf(fout, "}\n\n");
155 }
156 fprintf(fout, "\n");
157
158 /* print out the class permissions */ 82 /* print out the class permissions */
159 for (i=1; i < classlist_len; i++) { 83 for (i = 0; secclass_map[i].name; i++) {
160 if (classlist[i]) { 84 struct security_class_mapping *map = &secclass_map[i];
161 int firstperm = -1, numperms = 0; 85 fprintf(fout, "class %s\n", map->name);
162 86 fprintf(fout, "{\n");
163 fprintf(fout, "class %s\n", classlist[i]); 87 for (j = 0; map->perms[j]; j++)
164 /* does it inherit from a common? */ 88 fprintf(fout, "\t%s\n", map->perms[j]);
165 for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++) 89 fprintf(fout, "}\n\n");
166 if (av_inherit[j].class == i)
167 fprintf(fout, "inherits %s\n", av_inherit[j].common);
168
169 for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) {
170 if (av_perms[j].class == i) {
171 if (firstperm == -1)
172 firstperm = j;
173 numperms++;
174 }
175 }
176 if (!numperms) {
177 fprintf(fout, "\n");
178 continue;
179 }
180
181 fprintf(fout, "{\n");
182 /* print out the av_perms */
183 for (j=0; j < numperms; j++) {
184 fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s);
185 }
186 fprintf(fout, "}\n\n");
187 }
188 } 90 }
189 fprintf(fout, "\n"); 91 fprintf(fout, "\n");
190 92
@@ -197,31 +99,34 @@ int main(int argc, char *argv[])
197 /* types, roles, and allows */ 99 /* types, roles, and allows */
198 fprintf(fout, "type base_t;\n"); 100 fprintf(fout, "type base_t;\n");
199 fprintf(fout, "role base_r types { base_t };\n"); 101 fprintf(fout, "role base_r types { base_t };\n");
200 for (i=1; i < classlist_len; i++) { 102 for (i = 0; secclass_map[i].name; i++)
201 if (classlist[i]) 103 fprintf(fout, "allow base_t base_t:%s *;\n",
202 fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]); 104 secclass_map[i].name);
203 else
204 fprintf(fout, "allow base_t base_t:user%d *;\n", i);
205 }
206 fprintf(fout, "user user_u roles { base_r };\n"); 105 fprintf(fout, "user user_u roles { base_r };\n");
207 fprintf(fout, "\n"); 106 fprintf(fout, "\n");
208 107
209 /* default sids */ 108 /* default sids */
210 for (i=1; i < initial_sid_to_string_len; i++) 109 for (i = 1; i < initial_sid_to_string_len; i++)
211 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); 110 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
212 fprintf(fout, "\n"); 111 fprintf(fout, "\n");
213 112
214
215 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); 113 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
216 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); 114 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
115 fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
217 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); 116 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
218 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); 117 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
219 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); 118 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
119 fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
120 fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
121 fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n");
220 122
123 fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
221 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); 124 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
222 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); 125 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
223 126
127 fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
224 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); 128 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
129 fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
225 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); 130 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
226 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); 131 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
227 132
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 46989b88d734..ef8729f48586 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -10,73 +10,164 @@
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 # append a plus sign if the repository is not in a clean
164 # annotated or signed tagged state (as git describe only
165 # looks at signed or annotated tags - git tag -a/-s) and
166 # LOCALVERSION= is not specified
167 if test "${LOCALVERSION+set}" != "set"; then
168 scm=$(scm_version --short)
169 res="$res${scm:++}"
170 fi
82fi 171fi
172
173echo "$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 4a34ec591e8c..92fdc4546141 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
@@ -101,9 +122,12 @@ exuberant()
101 -I ____cacheline_aligned_in_smp \ 122 -I ____cacheline_aligned_in_smp \
102 -I ____cacheline_internodealigned_in_smp \ 123 -I ____cacheline_internodealigned_in_smp \
103 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ 124 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
125 -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
104 --extra=+f --c-kinds=+px \ 126 --extra=+f --c-kinds=+px \
105 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ 127 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \
106 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' 128 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
129 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
130 --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/'
107 131
108 all_kconfigs | xargs $1 -a \ 132 all_kconfigs | xargs $1 -a \
109 --langdef=kconfig --language-force=kconfig \ 133 --langdef=kconfig --language-force=kconfig \
diff --git a/scripts/tracing/power.pl b/scripts/tracing/power.pl
deleted file mode 100644
index 4f729b3501e0..000000000000
--- a/scripts/tracing/power.pl
+++ /dev/null
@@ -1,108 +0,0 @@
1#!/usr/bin/perl
2
3# Copyright 2008, Intel Corporation
4#
5# This file is part of the Linux kernel
6#
7# This program file is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the
9# Free Software Foundation; version 2 of the License.
10#
11# This program is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program in a file named COPYING; if not, write to the
18# Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor,
20# Boston, MA 02110-1301 USA
21#
22# Authors:
23# Arjan van de Ven <arjan@linux.intel.com>
24
25
26#
27# This script turns a cstate ftrace output into a SVG graphic that shows
28# historic C-state information
29#
30#
31# cat /sys/kernel/debug/tracing/trace | perl power.pl > out.svg
32#
33
34my @styles;
35my $base = 0;
36
37my @pstate_last;
38my @pstate_level;
39
40$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
41$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
42$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
43$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
44$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
45$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
46$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
47$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
48$styles[8] = "fill:rgb(0,25,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
49
50
51print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
52print "<svg width=\"10000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
53
54my $scale = 30000.0;
55while (<>) {
56 my $line = $_;
57 if ($line =~ /([0-9\.]+)\] CSTATE: Going to C([0-9]) on cpu ([0-9]+) for ([0-9\.]+)/) {
58 if ($base == 0) {
59 $base = $1;
60 }
61 my $time = $1 - $base;
62 $time = $time * $scale;
63 my $C = $2;
64 my $cpu = $3;
65 my $y = 400 * $cpu;
66 my $duration = $4 * $scale;
67 my $msec = int($4 * 100000)/100.0;
68 my $height = $C * 20;
69 $style = $styles[$C];
70
71 $y = $y + 140 - $height;
72
73 $x2 = $time + 4;
74 $y2 = $y + 4;
75
76
77 print "<rect x=\"$time\" width=\"$duration\" y=\"$y\" height=\"$height\" style=\"$style\"/>\n";
78 print "<text transform=\"translate($x2,$y2) rotate(90)\">C$C $msec</text>\n";
79 }
80 if ($line =~ /([0-9\.]+)\] PSTATE: Going to P([0-9]) on cpu ([0-9]+)/) {
81 my $time = $1 - $base;
82 my $state = $2;
83 my $cpu = $3;
84
85 if (defined($pstate_last[$cpu])) {
86 my $from = $pstate_last[$cpu];
87 my $oldstate = $pstate_state[$cpu];
88 my $duration = ($time-$from) * $scale;
89
90 $from = $from * $scale;
91 my $to = $from + $duration;
92 my $height = 140 - ($oldstate * (140/8));
93
94 my $y = 400 * $cpu + 200 + $height;
95 my $y2 = $y+4;
96 my $style = $styles[8];
97
98 print "<rect x=\"$from\" y=\"$y\" width=\"$duration\" height=\"5\" style=\"$style\"/>\n";
99 print "<text transform=\"translate($from,$y2)\">P$oldstate (cpu $cpu)</text>\n";
100 };
101
102 $pstate_last[$cpu] = $time;
103 $pstate_state[$cpu] = $state;
104 }
105}
106
107
108print "</svg>\n";
diff --git a/scripts/unifdef.c b/scripts/unifdef.c
index 30d459fb0709..44d39785e50d 100644
--- a/scripts/unifdef.c
+++ b/scripts/unifdef.c
@@ -1,13 +1,5 @@
1/* 1/*
2 * Copyright (c) 2002 - 2005 Tony Finch <dot@dotat.at>. All rights reserved. 2 * Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>
3 *
4 * This code is derived from software contributed to Berkeley by Dave Yost.
5 * It was rewritten to support ANSI C by Tony Finch. The original version of
6 * unifdef carried the following copyright notice. None of its code remains
7 * in this version (though some of the names remain).
8 *
9 * Copyright (c) 1985, 1993
10 * The Regents of the University of California. All rights reserved.
11 * 3 *
12 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -31,23 +23,20 @@
31 * SUCH DAMAGE. 23 * SUCH DAMAGE.
32 */ 24 */
33 25
34#include <sys/cdefs.h> 26/*
27 * This code was derived from software contributed to Berkeley by Dave Yost.
28 * It was rewritten to support ANSI C by Tony Finch. The original version
29 * of unifdef carried the 4-clause BSD copyright licence. None of its code
30 * remains in this version (though some of the names remain) so it now
31 * carries a more liberal licence.
32 *
33 * The latest version is available from http://dotat.at/prog/unifdef
34 */
35 35
36#ifndef lint 36static const char * const copyright[] = {
37#if 0 37 "@(#) Copyright (c) 2002 - 2009 Tony Finch <dot@dotat.at>\n",
38static const char copyright[] = 38 "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $",
39"@(#) Copyright (c) 1985, 1993\n\ 39};
40 The Regents of the University of California. All rights reserved.\n";
41#endif
42#ifdef __IDSTRING
43__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93");
44__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $");
45__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $");
46#endif
47#endif /* not lint */
48#ifdef __FBSDID
49__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $");
50#endif
51 40
52/* 41/*
53 * unifdef - remove ifdef'ed lines 42 * unifdef - remove ifdef'ed lines
@@ -72,8 +61,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05
72#include <string.h> 61#include <string.h>
73#include <unistd.h> 62#include <unistd.h>
74 63
75size_t strlcpy(char *dst, const char *src, size_t siz);
76
77/* types of input lines: */ 64/* types of input lines: */
78typedef enum { 65typedef enum {
79 LT_TRUEI, /* a true #if with ignore flag */ 66 LT_TRUEI, /* a true #if with ignore flag */
@@ -90,6 +77,7 @@ typedef enum {
90 LT_DODGY_LAST = LT_DODGY + LT_ENDIF, 77 LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
91 LT_PLAIN, /* ordinary line */ 78 LT_PLAIN, /* ordinary line */
92 LT_EOF, /* end of file */ 79 LT_EOF, /* end of file */
80 LT_ERROR, /* unevaluable #if */
93 LT_COUNT 81 LT_COUNT
94} Linetype; 82} Linetype;
95 83
@@ -100,7 +88,7 @@ static char const * const linetype_name[] = {
100 "DODGY IF", "DODGY TRUE", "DODGY FALSE", 88 "DODGY IF", "DODGY TRUE", "DODGY FALSE",
101 "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE", 89 "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
102 "DODGY ELSE", "DODGY ENDIF", 90 "DODGY ELSE", "DODGY ENDIF",
103 "PLAIN", "EOF" 91 "PLAIN", "EOF", "ERROR"
104}; 92};
105 93
106/* state of #if processing */ 94/* state of #if processing */
@@ -168,11 +156,13 @@ static char const * const linestate_name[] = {
168 * Globals. 156 * Globals.
169 */ 157 */
170 158
159static bool compblank; /* -B: compress blank lines */
160static bool lnblank; /* -b: blank deleted lines */
171static bool complement; /* -c: do the complement */ 161static bool complement; /* -c: do the complement */
172static bool debugging; /* -d: debugging reports */ 162static bool debugging; /* -d: debugging reports */
173static bool iocccok; /* -e: fewer IOCCC errors */ 163static bool iocccok; /* -e: fewer IOCCC errors */
164static bool strictlogic; /* -K: keep ambiguous #ifs */
174static bool killconsts; /* -k: eval constant #ifs */ 165static bool killconsts; /* -k: eval constant #ifs */
175static bool lnblank; /* -l: blank deleted lines */
176static bool lnnum; /* -n: add #line directives */ 166static bool lnnum; /* -n: add #line directives */
177static bool symlist; /* -s: output symbol list */ 167static bool symlist; /* -s: output symbol list */
178static bool text; /* -t: this is a text file */ 168static bool text; /* -t: this is a text file */
@@ -196,7 +186,9 @@ static bool ignoring[MAXDEPTH]; /* ignore comments state */
196static int stifline[MAXDEPTH]; /* start of current #if */ 186static int stifline[MAXDEPTH]; /* start of current #if */
197static int depth; /* current #if nesting */ 187static int depth; /* current #if nesting */
198static int delcount; /* count of deleted lines */ 188static int delcount; /* count of deleted lines */
199static bool keepthis; /* don't delete constant #if */ 189static unsigned blankcount; /* count of blank lines */
190static unsigned blankmax; /* maximum recent blankcount */
191static bool constexpr; /* constant #if expression */
200 192
201static int exitstat; /* program exit status */ 193static int exitstat; /* program exit status */
202 194
@@ -206,13 +198,14 @@ static void done(void);
206static void error(const char *); 198static void error(const char *);
207static int findsym(const char *); 199static int findsym(const char *);
208static void flushline(bool); 200static void flushline(bool);
209static Linetype get_line(void); 201static Linetype parseline(void);
210static Linetype ifeval(const char **); 202static Linetype ifeval(const char **);
211static void ignoreoff(void); 203static void ignoreoff(void);
212static void ignoreon(void); 204static void ignoreon(void);
213static void keywordedit(const char *); 205static void keywordedit(const char *);
214static void nest(void); 206static void nest(void);
215static void process(void); 207static void process(void);
208static const char *skipargs(const char *);
216static const char *skipcomment(const char *); 209static const char *skipcomment(const char *);
217static const char *skipsym(const char *); 210static const char *skipsym(const char *);
218static void state(Ifstate); 211static void state(Ifstate);
@@ -220,7 +213,7 @@ static int strlcmp(const char *, const char *, size_t);
220static void unnest(void); 213static void unnest(void);
221static void usage(void); 214static void usage(void);
222 215
223#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') 216#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
224 217
225/* 218/*
226 * The main program. 219 * The main program.
@@ -230,7 +223,7 @@ main(int argc, char *argv[])
230{ 223{
231 int opt; 224 int opt;
232 225
233 while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) 226 while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1)
234 switch (opt) { 227 switch (opt) {
235 case 'i': /* treat stuff controlled by these symbols as text */ 228 case 'i': /* treat stuff controlled by these symbols as text */
236 /* 229 /*
@@ -255,6 +248,13 @@ main(int argc, char *argv[])
255 case 'I': 248 case 'I':
256 /* no-op for compatibility with cpp */ 249 /* no-op for compatibility with cpp */
257 break; 250 break;
251 case 'B': /* compress blank lines around removed section */
252 compblank = true;
253 break;
254 case 'b': /* blank deleted lines instead of omitting them */
255 case 'l': /* backwards compatibility */
256 lnblank = true;
257 break;
258 case 'c': /* treat -D as -U and vice versa */ 258 case 'c': /* treat -D as -U and vice versa */
259 complement = true; 259 complement = true;
260 break; 260 break;
@@ -264,12 +264,12 @@ main(int argc, char *argv[])
264 case 'e': /* fewer errors from dodgy lines */ 264 case 'e': /* fewer errors from dodgy lines */
265 iocccok = true; 265 iocccok = true;
266 break; 266 break;
267 case 'K': /* keep ambiguous #ifs */
268 strictlogic = true;
269 break;
267 case 'k': /* process constant #ifs */ 270 case 'k': /* process constant #ifs */
268 killconsts = true; 271 killconsts = true;
269 break; 272 break;
270 case 'l': /* blank deleted lines instead of omitting them */
271 lnblank = true;
272 break;
273 case 'n': /* add #line directive after deleted lines */ 273 case 'n': /* add #line directive after deleted lines */
274 lnnum = true; 274 lnnum = true;
275 break; 275 break;
@@ -284,6 +284,8 @@ main(int argc, char *argv[])
284 } 284 }
285 argc -= optind; 285 argc -= optind;
286 argv += optind; 286 argv += optind;
287 if (compblank && lnblank)
288 errx(2, "-B and -b are mutually exclusive");
287 if (argc > 1) { 289 if (argc > 1) {
288 errx(2, "can only do one file"); 290 errx(2, "can only do one file");
289 } else if (argc == 1 && strcmp(*argv, "-") != 0) { 291 } else if (argc == 1 && strcmp(*argv, "-") != 0) {
@@ -302,7 +304,7 @@ main(int argc, char *argv[])
302static void 304static void
303usage(void) 305usage(void)
304{ 306{
305 fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" 307 fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]"
306 " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); 308 " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
307 exit(2); 309 exit(2);
308} 310}
@@ -383,46 +385,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
383/* IS_OUTSIDE */ 385/* IS_OUTSIDE */
384{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif, 386{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
385 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif, 387 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif,
386 print, done }, 388 print, done, abort },
387/* IS_FALSE_PREFIX */ 389/* IS_FALSE_PREFIX */
388{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif, 390{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
389 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, 391 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
390 drop, Eeof }, 392 drop, Eeof, abort },
391/* IS_TRUE_PREFIX */ 393/* IS_TRUE_PREFIX */
392{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif, 394{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
393 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, 395 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
394 print, Eeof }, 396 print, Eeof, abort },
395/* IS_PASS_MIDDLE */ 397/* IS_PASS_MIDDLE */
396{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif, 398{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
397 Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif, 399 Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif,
398 print, Eeof }, 400 print, Eeof, abort },
399/* IS_FALSE_MIDDLE */ 401/* IS_FALSE_MIDDLE */
400{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif, 402{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
401 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, 403 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
402 drop, Eeof }, 404 drop, Eeof, abort },
403/* IS_TRUE_MIDDLE */ 405/* IS_TRUE_MIDDLE */
404{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif, 406{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
405 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif, 407 Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
406 print, Eeof }, 408 print, Eeof, abort },
407/* IS_PASS_ELSE */ 409/* IS_PASS_ELSE */
408{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif, 410{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
409 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif, 411 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif,
410 print, Eeof }, 412 print, Eeof, abort },
411/* IS_FALSE_ELSE */ 413/* IS_FALSE_ELSE */
412{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif, 414{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
413 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, 415 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
414 drop, Eeof }, 416 drop, Eeof, abort },
415/* IS_TRUE_ELSE */ 417/* IS_TRUE_ELSE */
416{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif, 418{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
417 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc, 419 Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc,
418 print, Eeof }, 420 print, Eeof, abort },
419/* IS_FALSE_TRAILER */ 421/* IS_FALSE_TRAILER */
420{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif, 422{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
421 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, 423 Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
422 drop, Eeof } 424 drop, Eeof, abort }
423/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF 425/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF
424 TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY) 426 TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY)
425 PLAIN EOF */ 427 PLAIN EOF ERROR */
426}; 428};
427 429
428/* 430/*
@@ -463,9 +465,11 @@ keywordedit(const char *replacement)
463static void 465static void
464nest(void) 466nest(void)
465{ 467{
466 depth += 1; 468 if (depth > MAXDEPTH-1)
467 if (depth >= MAXDEPTH) 469 abort(); /* bug */
470 if (depth == MAXDEPTH-1)
468 error("Too many levels of nesting"); 471 error("Too many levels of nesting");
472 depth += 1;
469 stifline[depth] = linenum; 473 stifline[depth] = linenum;
470} 474}
471static void 475static void
@@ -490,15 +494,23 @@ flushline(bool keep)
490 if (symlist) 494 if (symlist)
491 return; 495 return;
492 if (keep ^ complement) { 496 if (keep ^ complement) {
493 if (lnnum && delcount > 0) 497 bool blankline = tline[strspn(tline, " \t\n")] == '\0';
494 printf("#line %d\n", linenum); 498 if (blankline && compblank && blankcount != blankmax) {
495 fputs(tline, stdout); 499 delcount += 1;
496 delcount = 0; 500 blankcount += 1;
501 } else {
502 if (lnnum && delcount > 0)
503 printf("#line %d\n", linenum);
504 fputs(tline, stdout);
505 delcount = 0;
506 blankmax = blankcount = blankline ? blankcount + 1 : 0;
507 }
497 } else { 508 } else {
498 if (lnblank) 509 if (lnblank)
499 putc('\n', stdout); 510 putc('\n', stdout);
500 exitstat = 1; 511 exitstat = 1;
501 delcount += 1; 512 delcount += 1;
513 blankcount = 0;
502 } 514 }
503} 515}
504 516
@@ -510,9 +522,12 @@ process(void)
510{ 522{
511 Linetype lineval; 523 Linetype lineval;
512 524
525 /* When compressing blank lines, act as if the file
526 is preceded by a large number of blank lines. */
527 blankmax = blankcount = 1000;
513 for (;;) { 528 for (;;) {
514 linenum++; 529 linenum++;
515 lineval = get_line(); 530 lineval = parseline();
516 trans_table[ifstate[depth]][lineval](); 531 trans_table[ifstate[depth]][lineval]();
517 debug("process %s -> %s depth %d", 532 debug("process %s -> %s depth %d",
518 linetype_name[lineval], 533 linetype_name[lineval],
@@ -526,7 +541,7 @@ process(void)
526 * help from skipcomment(). 541 * help from skipcomment().
527 */ 542 */
528static Linetype 543static Linetype
529get_line(void) 544parseline(void)
530{ 545{
531 const char *cp; 546 const char *cp;
532 int cursym; 547 int cursym;
@@ -595,9 +610,21 @@ get_line(void)
595 if (incomment) 610 if (incomment)
596 linestate = LS_DIRTY; 611 linestate = LS_DIRTY;
597 } 612 }
598 /* skipcomment should have changed the state */ 613 /* skipcomment normally changes the state, except
599 if (linestate == LS_HASH) 614 if the last line of the file lacks a newline, or
600 abort(); /* bug */ 615 if there is too much whitespace in a directive */
616 if (linestate == LS_HASH) {
617 size_t len = cp - tline;
618 if (fgets(tline + len, MAXLINE - len, input) == NULL) {
619 /* append the missing newline */
620 tline[len+0] = '\n';
621 tline[len+1] = '\0';
622 cp++;
623 linestate = LS_START;
624 } else {
625 linestate = LS_DIRTY;
626 }
627 }
601 } 628 }
602 if (linestate == LS_DIRTY) { 629 if (linestate == LS_DIRTY) {
603 while (*cp != '\0') 630 while (*cp != '\0')
@@ -610,17 +637,40 @@ get_line(void)
610 637
611/* 638/*
612 * These are the binary operators that are supported by the expression 639 * These are the binary operators that are supported by the expression
613 * evaluator. Note that if support for division is added then we also 640 * evaluator.
614 * need short-circuiting booleans because of divide-by-zero.
615 */ 641 */
616static int op_lt(int a, int b) { return (a < b); } 642static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) {
617static int op_gt(int a, int b) { return (a > b); } 643 if(at == LT_IF || bt == LT_IF) return (LT_IF);
618static int op_le(int a, int b) { return (a <= b); } 644 return (*p = v, v ? LT_TRUE : LT_FALSE);
619static int op_ge(int a, int b) { return (a >= b); } 645}
620static int op_eq(int a, int b) { return (a == b); } 646static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) {
621static int op_ne(int a, int b) { return (a != b); } 647 return op_strict(p, a < b, at, bt);
622static int op_or(int a, int b) { return (a || b); } 648}
623static int op_and(int a, int b) { return (a && b); } 649static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) {
650 return op_strict(p, a > b, at, bt);
651}
652static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) {
653 return op_strict(p, a <= b, at, bt);
654}
655static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) {
656 return op_strict(p, a >= b, at, bt);
657}
658static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) {
659 return op_strict(p, a == b, at, bt);
660}
661static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) {
662 return op_strict(p, a != b, at, bt);
663}
664static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) {
665 if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE))
666 return (*p = 1, LT_TRUE);
667 return op_strict(p, a || b, at, bt);
668}
669static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) {
670 if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE))
671 return (*p = 0, LT_FALSE);
672 return op_strict(p, a && b, at, bt);
673}
624 674
625/* 675/*
626 * An evaluation function takes three arguments, as follows: (1) a pointer to 676 * An evaluation function takes three arguments, as follows: (1) a pointer to
@@ -629,8 +679,8 @@ static int op_and(int a, int b) { return (a && b); }
629 * value of the expression; and (3) a pointer to a char* that points to the 679 * value of the expression; and (3) a pointer to a char* that points to the
630 * expression to be evaluated and that is updated to the end of the expression 680 * expression to be evaluated and that is updated to the end of the expression
631 * when evaluation is complete. The function returns LT_FALSE if the value of 681 * when evaluation is complete. The function returns LT_FALSE if the value of
632 * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the 682 * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression
633 * expression could not be evaluated. 683 * depends on an unknown symbol, or LT_ERROR if there is a parse failure.
634 */ 684 */
635struct ops; 685struct ops;
636 686
@@ -649,7 +699,7 @@ static const struct ops {
649 eval_fn *inner; 699 eval_fn *inner;
650 struct op { 700 struct op {
651 const char *str; 701 const char *str;
652 int (*fn)(int, int); 702 Linetype (*fn)(int *, Linetype, int, Linetype, int);
653 } op[5]; 703 } op[5];
654} eval_ops[] = { 704} eval_ops[] = {
655 { eval_table, { { "||", op_or } } }, 705 { eval_table, { { "||", op_or } } },
@@ -664,8 +714,8 @@ static const struct ops {
664 714
665/* 715/*
666 * Function for evaluating the innermost parts of expressions, 716 * Function for evaluating the innermost parts of expressions,
667 * viz. !expr (expr) defined(symbol) symbol number 717 * viz. !expr (expr) number defined(symbol) symbol
668 * We reset the keepthis flag when we find a non-constant subexpression. 718 * We reset the constexpr flag in the last two cases.
669 */ 719 */
670static Linetype 720static Linetype
671eval_unary(const struct ops *ops, int *valp, const char **cpp) 721eval_unary(const struct ops *ops, int *valp, const char **cpp)
@@ -673,68 +723,83 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
673 const char *cp; 723 const char *cp;
674 char *ep; 724 char *ep;
675 int sym; 725 int sym;
726 bool defparen;
727 Linetype lt;
676 728
677 cp = skipcomment(*cpp); 729 cp = skipcomment(*cpp);
678 if (*cp == '!') { 730 if (*cp == '!') {
679 debug("eval%d !", ops - eval_ops); 731 debug("eval%d !", ops - eval_ops);
680 cp++; 732 cp++;
681 if (eval_unary(ops, valp, &cp) == LT_IF) { 733 lt = eval_unary(ops, valp, &cp);
682 *cpp = cp; 734 if (lt == LT_ERROR)
683 return (LT_IF); 735 return (LT_ERROR);
736 if (lt != LT_IF) {
737 *valp = !*valp;
738 lt = *valp ? LT_TRUE : LT_FALSE;
684 } 739 }
685 *valp = !*valp;
686 } else if (*cp == '(') { 740 } else if (*cp == '(') {
687 cp++; 741 cp++;
688 debug("eval%d (", ops - eval_ops); 742 debug("eval%d (", ops - eval_ops);
689 if (eval_table(eval_ops, valp, &cp) == LT_IF) 743 lt = eval_table(eval_ops, valp, &cp);
690 return (LT_IF); 744 if (lt == LT_ERROR)
745 return (LT_ERROR);
691 cp = skipcomment(cp); 746 cp = skipcomment(cp);
692 if (*cp++ != ')') 747 if (*cp++ != ')')
693 return (LT_IF); 748 return (LT_ERROR);
694 } else if (isdigit((unsigned char)*cp)) { 749 } else if (isdigit((unsigned char)*cp)) {
695 debug("eval%d number", ops - eval_ops); 750 debug("eval%d number", ops - eval_ops);
696 *valp = strtol(cp, &ep, 0); 751 *valp = strtol(cp, &ep, 0);
752 if (ep == cp)
753 return (LT_ERROR);
754 lt = *valp ? LT_TRUE : LT_FALSE;
697 cp = skipsym(cp); 755 cp = skipsym(cp);
698 } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { 756 } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) {
699 cp = skipcomment(cp+7); 757 cp = skipcomment(cp+7);
700 debug("eval%d defined", ops - eval_ops); 758 debug("eval%d defined", ops - eval_ops);
701 if (*cp++ != '(') 759 if (*cp == '(') {
702 return (LT_IF); 760 cp = skipcomment(cp+1);
703 cp = skipcomment(cp); 761 defparen = true;
762 } else {
763 defparen = false;
764 }
704 sym = findsym(cp); 765 sym = findsym(cp);
705 cp = skipsym(cp); 766 if (sym < 0) {
706 cp = skipcomment(cp); 767 lt = LT_IF;
707 if (*cp++ != ')') 768 } else {
708 return (LT_IF);
709 if (sym >= 0)
710 *valp = (value[sym] != NULL); 769 *valp = (value[sym] != NULL);
711 else { 770 lt = *valp ? LT_TRUE : LT_FALSE;
712 *cpp = cp;
713 return (LT_IF);
714 } 771 }
715 keepthis = false; 772 cp = skipsym(cp);
773 cp = skipcomment(cp);
774 if (defparen && *cp++ != ')')
775 return (LT_ERROR);
776 constexpr = false;
716 } else if (!endsym(*cp)) { 777 } else if (!endsym(*cp)) {
717 debug("eval%d symbol", ops - eval_ops); 778 debug("eval%d symbol", ops - eval_ops);
718 sym = findsym(cp); 779 sym = findsym(cp);
719 if (sym < 0) 780 cp = skipsym(cp);
720 return (LT_IF); 781 if (sym < 0) {
721 if (value[sym] == NULL) 782 lt = LT_IF;
783 cp = skipargs(cp);
784 } else if (value[sym] == NULL) {
722 *valp = 0; 785 *valp = 0;
723 else { 786 lt = LT_FALSE;
787 } else {
724 *valp = strtol(value[sym], &ep, 0); 788 *valp = strtol(value[sym], &ep, 0);
725 if (*ep != '\0' || ep == value[sym]) 789 if (*ep != '\0' || ep == value[sym])
726 return (LT_IF); 790 return (LT_ERROR);
791 lt = *valp ? LT_TRUE : LT_FALSE;
792 cp = skipargs(cp);
727 } 793 }
728 cp = skipsym(cp); 794 constexpr = false;
729 keepthis = false;
730 } else { 795 } else {
731 debug("eval%d bad expr", ops - eval_ops); 796 debug("eval%d bad expr", ops - eval_ops);
732 return (LT_IF); 797 return (LT_ERROR);
733 } 798 }
734 799
735 *cpp = cp; 800 *cpp = cp;
736 debug("eval%d = %d", ops - eval_ops, *valp); 801 debug("eval%d = %d", ops - eval_ops, *valp);
737 return (*valp ? LT_TRUE : LT_FALSE); 802 return (lt);
738} 803}
739 804
740/* 805/*
@@ -746,11 +811,13 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
746 const struct op *op; 811 const struct op *op;
747 const char *cp; 812 const char *cp;
748 int val; 813 int val;
749 Linetype lhs, rhs; 814 Linetype lt, rt;
750 815
751 debug("eval%d", ops - eval_ops); 816 debug("eval%d", ops - eval_ops);
752 cp = *cpp; 817 cp = *cpp;
753 lhs = ops->inner(ops+1, valp, &cp); 818 lt = ops->inner(ops+1, valp, &cp);
819 if (lt == LT_ERROR)
820 return (LT_ERROR);
754 for (;;) { 821 for (;;) {
755 cp = skipcomment(cp); 822 cp = skipcomment(cp);
756 for (op = ops->op; op->str != NULL; op++) 823 for (op = ops->op; op->str != NULL; op++)
@@ -760,32 +827,16 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
760 break; 827 break;
761 cp += strlen(op->str); 828 cp += strlen(op->str);
762 debug("eval%d %s", ops - eval_ops, op->str); 829 debug("eval%d %s", ops - eval_ops, op->str);
763 rhs = ops->inner(ops+1, &val, &cp); 830 rt = ops->inner(ops+1, &val, &cp);
764 if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) { 831 if (rt == LT_ERROR)
765 debug("eval%d: and always false", ops - eval_ops); 832 return (LT_ERROR);
766 if (lhs == LT_IF) 833 lt = op->fn(valp, lt, *valp, rt, val);
767 *valp = val;
768 lhs = LT_FALSE;
769 continue;
770 }
771 if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) {
772 debug("eval%d: or always true", ops - eval_ops);
773 if (lhs == LT_IF)
774 *valp = val;
775 lhs = LT_TRUE;
776 continue;
777 }
778 if (rhs == LT_IF)
779 lhs = LT_IF;
780 if (lhs != LT_IF)
781 *valp = op->fn(*valp, val);
782 } 834 }
783 835
784 *cpp = cp; 836 *cpp = cp;
785 debug("eval%d = %d", ops - eval_ops, *valp); 837 debug("eval%d = %d", ops - eval_ops, *valp);
786 if (lhs != LT_IF) 838 debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]);
787 lhs = (*valp ? LT_TRUE : LT_FALSE); 839 return (lt);
788 return lhs;
789} 840}
790 841
791/* 842/*
@@ -796,17 +847,14 @@ eval_table(const struct ops *ops, int *valp, const char **cpp)
796static Linetype 847static Linetype
797ifeval(const char **cpp) 848ifeval(const char **cpp)
798{ 849{
799 const char *cp = *cpp;
800 int ret; 850 int ret;
801 int val; 851 int val = 0;
802 852
803 debug("eval %s", *cpp); 853 debug("eval %s", *cpp);
804 keepthis = killconsts ? false : true; 854 constexpr = killconsts ? false : true;
805 ret = eval_table(eval_ops, &val, &cp); 855 ret = eval_table(eval_ops, &val, cpp);
806 if (ret != LT_IF)
807 *cpp = cp;
808 debug("eval = %d", val); 856 debug("eval = %d", val);
809 return (keepthis ? LT_IF : ret); 857 return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
810} 858}
811 859
812/* 860/*
@@ -918,6 +966,31 @@ skipcomment(const char *cp)
918} 966}
919 967
920/* 968/*
969 * Skip macro arguments.
970 */
971static const char *
972skipargs(const char *cp)
973{
974 const char *ocp = cp;
975 int level = 0;
976 cp = skipcomment(cp);
977 if (*cp != '(')
978 return (cp);
979 do {
980 if (*cp == '(')
981 level++;
982 if (*cp == ')')
983 level--;
984 cp = skipcomment(cp+1);
985 } while (level != 0 && *cp != '\0');
986 if (level == 0)
987 return (cp);
988 else
989 /* Rewind and re-detect the syntax error later. */
990 return (ocp);
991}
992
993/*
921 * Skip over an identifier. 994 * Skip over an identifier.
922 */ 995 */
923static const char * 996static const char *
@@ -929,7 +1002,7 @@ skipsym(const char *cp)
929} 1002}
930 1003
931/* 1004/*
932 * Look for the symbol in the symbol table. If is is found, we return 1005 * Look for the symbol in the symbol table. If it is found, we return
933 * the symbol table index, else we return -1. 1006 * the symbol table index, else we return -1.
934 */ 1007 */
935static int 1008static int