diff options
Diffstat (limited to 'scripts')
27 files changed, 878 insertions, 356 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 9ffd3dda3889..065324a8046f 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -8,6 +8,8 @@ squote := ' empty := space := $(empty) $(empty) space_escape := _-_SPACE_-_ +right_paren := ) +left_paren := ( ### # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o @@ -80,6 +82,71 @@ cc-cross-prefix = \ echo $(c); \ fi))) +# Tools for caching Makefile variables that are "expensive" to compute. +# +# Here we want to help deal with variables that take a long time to compute +# by making it easy to store these variables in a cache. +# +# The canonical example here is testing for compiler flags. On a simple system +# each call to the compiler takes 10 ms, but on a system with a compiler that's +# called through various wrappers it can take upwards of 100 ms. If we have +# 100 calls to the compiler this can take 1 second (on a simple system) or 10 +# seconds (on a complicated system). +# +# The "cache" will be in Makefile syntax and can be directly included. +# Any time we try to reference a variable that's not in the cache we'll +# calculate it and store it in the cache for next time. + +# Include values from last time +make-cache := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/,$(if $(obj),$(obj)/)).cache.mk +$(make-cache): ; +-include $(make-cache) + +cached-data := $(filter __cached_%, $(.VARIABLES)) + +# If cache exceeds 1000 lines, shrink it down to 500. +ifneq ($(word 1000,$(cached-data)),) +$(shell tail -n 500 $(make-cache) > $(make-cache).tmp; \ + mv $(make-cache).tmp $(make-cache)) +endif + +create-cache-dir := $(if $(KBUILD_SRC),$(if $(cache-data),,1)) + +# Usage: $(call __sanitize-opt,Hello=Hola$(comma)Goodbye Adios) +# +# Convert all '$', ')', '(', '\', '=', ' ', ',', ':' to '_' +__sanitize-opt = $(subst $$,_,$(subst $(right_paren),_,$(subst $(left_paren),_,$(subst \,_,$(subst =,_,$(subst $(space),_,$(subst $(comma),_,$(subst :,_,$(1))))))))) + +# Usage: $(call shell-cached,shell_command) +# Example: $(call shell-cached,md5sum /usr/bin/gcc) +# +# If we've already seen a call to this exact shell command (even in a +# previous invocation of make!) we'll return the value. If not, we'll +# compute it and store the result for future runs. +# +# This is a bit of voodoo, but basic explanation is that if the variable +# was undefined then we'll evaluate the shell command and store the result +# into the variable. We'll then store that value in the cache and finally +# output the value. +# +# NOTE: The $$(2) here isn't actually a parameter to __run-and-store. We +# happen to know that the caller will have their shell command in $(2) so the +# result of "call"ing this will produce a reference to that $(2). The reason +# for this strangeness is to avoid an extra level of eval (and escaping) of +# $(2). +define __run-and-store +ifeq ($(origin $(1)),undefined) + $$(eval $(1) := $$(shell $$(2))) +ifeq ($(create-cache-dir),1) + $$(shell mkdir -p $(dir $(make-cache))) + $$(eval create-cache-dir :=) +endif + $$(shell echo '$(1) := $$($(1))' >> $(make-cache)) +endif +endef +__shell-cached = $(eval $(call __run-and-store,$(1)))$($(1)) +shell-cached = $(call __shell-cached,__cached_$(call __sanitize-opt,$(1)),$(1)) + # output directory for tests below TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) @@ -87,30 +154,36 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) # Exit code chooses option. "$$TMP" serves as a temporary file and is # automatically cleaned up. -try-run = $(shell set -e; \ +__try-run = set -e; \ TMP="$(TMPOUT).$$$$.tmp"; \ TMPO="$(TMPOUT).$$$$.o"; \ if ($(1)) >/dev/null 2>&1; \ then echo "$(2)"; \ else echo "$(3)"; \ fi; \ - rm -f "$$TMP" "$$TMPO") + rm -f "$$TMP" "$$TMPO" + +try-run = $(shell $(__try-run)) + +# try-run-cached +# This works like try-run, but the result is cached. +try-run-cached = $(call shell-cached,$(__try-run)) # as-option # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) -as-option = $(call try-run,\ +as-option = $(call try-run-cached,\ $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2)) # as-instr # Usage: cflags-y += $(call as-instr,instr,option1,option2) -as-instr = $(call try-run,\ +as-instr = $(call try-run-cached,\ printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) # __cc-option # Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) -__cc-option = $(call try-run,\ +__cc-option = $(call try-run-cached,\ $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) # Do not attempt to build with gcc plugins during cc-option tests. @@ -130,23 +203,23 @@ hostcc-option = $(call __cc-option, $(HOSTCC),\ # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) -cc-option-yn = $(call try-run,\ +cc-option-yn = $(call try-run-cached,\ $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) # cc-disable-warning # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) -cc-disable-warning = $(call try-run,\ +cc-disable-warning = $(call try-run-cached,\ $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) # cc-name # Expands to either gcc or clang -cc-name = $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc) +cc-name = $(call shell-cached,$(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc) # cc-version -cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) +cc-version = $(call shell-cached,$(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) # cc-fullversion -cc-fullversion = $(shell $(CONFIG_SHELL) \ +cc-fullversion = $(call shell-cached,$(CONFIG_SHELL) \ $(srctree)/scripts/gcc-version.sh -p $(CC)) # cc-ifversion @@ -159,22 +232,23 @@ cc-if-fullversion = $(shell [ $(cc-fullversion) $(1) $(2) ] && echo $(3) || echo # cc-ldoption # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) -cc-ldoption = $(call try-run,\ - $(CC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) +cc-ldoption = $(call try-run-cached,\ + $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) # ld-option # Usage: LDFLAGS += $(call ld-option, -X) -ld-option = $(call try-run,\ - $(CC) -x c /dev/null -c -o "$$TMPO" ; $(LD) $(1) "$$TMPO" -o "$$TMP",$(1),$(2)) +ld-option = $(call try-run-cached,\ + $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -x c /dev/null -c -o "$$TMPO"; \ + $(LD) $(LDFLAGS) $(1) "$$TMPO" -o "$$TMP",$(1),$(2)) # ar-option # Usage: KBUILD_ARFLAGS := $(call ar-option,D) # Important: no spaces around options -ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2)) +ar-option = $(call try-run-cached, $(AR) rc$(1) "$$TMP",$(1),$(2)) # ld-version # Note this is mainly for HJ Lu's 3 number binutil versions -ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh) +ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version.sh) # ld-ifversion # Usage: $(call ld-ifversion, -ge, 22252, y) diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic index 524eeedc8d25..32ad8e93fbe1 100644 --- a/scripts/Makefile.asm-generic +++ b/scripts/Makefile.asm-generic @@ -6,6 +6,9 @@ # and for each file listed in this file with generic-y creates # a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/$(src)) +PHONY := all +all: + kbuild-file := $(srctree)/arch/$(SRCARCH)/include/$(src)/Kbuild -include $(kbuild-file) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e63af4e19382..65ea1e6aaaf6 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -65,15 +65,6 @@ ifneq ($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(h include scripts/Makefile.host endif -ifneq ($(KBUILD_SRC),) -# Create output directory if not already present -_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) - -# Create directories for object files if directory does not exist -# Needed when obj-y := dir/file.o syntax is used -_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d))) -endif - ifndef obj $(warning kbuild: Makefile.build is included improperly) endif @@ -109,6 +100,10 @@ ifneq ($(KBUILD_CHECKSRC),0) endif endif +ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) + cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< ; +endif + # Do section mismatch analysis for each module/built-in.o ifdef CONFIG_DEBUG_SECTION_MISMATCH cmd_secanalysis = ; scripts/mod/modpost $@ @@ -292,6 +287,7 @@ define rule_cc_o_c $(call echo-cmd,checksrc) $(cmd_checksrc) \ $(call cmd_and_fixdep,cc_o_c) \ $(cmd_modversions_c) \ + $(cmd_checkdoc) \ $(call echo-cmd,objtool) $(cmd_objtool) \ $(call echo-cmd,record_mcount) $(cmd_record_mcount) endef @@ -563,7 +559,7 @@ $(multi-used-m): FORCE $(call multi_depend, $(multi-used-m), .o, -objs -y -m) targets += $(multi-used-y) $(multi-used-m) - +targets := $(filter-out $(PHONY), $(targets)) # Descending # --------------------------------------------------------------------------- @@ -584,13 +580,23 @@ FORCE: # optimization, we don't need to read them if the target does not # exist, we will rebuild anyway in that case. -targets := $(wildcard $(sort $(targets))) -cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) +cmd_files := $(wildcard $(foreach f,$(sort $(targets)),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) endif +ifneq ($(KBUILD_SRC),) +# Create directories for object files if they do not exist +obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets)))) +# If cmd_files exist, their directories apparently exist. Skip mkdir. +exist-dirs := $(sort $(patsubst %/,%, $(dir $(cmd_files)))) +obj-dirs := $(strip $(filter-out $(exist-dirs), $(obj-dirs))) +ifneq ($(obj-dirs),) +$(shell mkdir -p $(obj-dirs)) +endif +endif + # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable se we can use it in if_changed and friends. diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index 99967948d764..d5e131471131 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -27,11 +27,11 @@ subdirs := $(patsubst $(srcdir)/%/,%,\ # Recursion __headers: $(subdirs) -.PHONY: $(subdirs) +PHONY += $(subdirs) $(subdirs): $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(dst)/$@ -# Skip header install/check for include/uapi and arch/$(hdr-arch)/include/uapi. +# Skip header install/check for include/uapi and arch/$(SRCARCH)/include/uapi. # We have only sub-directories there. skip-inst := $(if $(filter %/uapi,$(obj)),1) @@ -115,9 +115,8 @@ $(check-file): scripts/headers_check.pl $(output-files) FORCE endif -targets := $(wildcard $(sort $(targets))) cmd_files := $(wildcard \ - $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + $(foreach f,$(sort $(targets)),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) @@ -125,6 +124,7 @@ endif endif # skip-inst -.PHONY: $(PHONY) PHONY += FORCE FORCE: ; + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.help b/scripts/Makefile.help deleted file mode 100644 index d03608f5db04..000000000000 --- a/scripts/Makefile.help +++ /dev/null @@ -1,3 +0,0 @@ - -checker-help: - @echo ' coccicheck - Check with Coccinelle.' diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 10e5c3cb89dc..e6dc6ae2d7c4 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -49,15 +49,6 @@ host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs)))) host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs)))) -# output directory for programs/.o files -# hostprogs-y := tools/build may have been specified. -# Retrieve also directory of .o files from prog-objs or prog-cxxobjs notation -host-objdirs := $(dir $(__hostprogs) $(host-cobjs) $(host-cxxobjs)) - -host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs)))) - - -__hostprogs := $(addprefix $(obj)/,$(__hostprogs)) host-csingle := $(addprefix $(obj)/,$(host-csingle)) host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) @@ -67,9 +58,6 @@ host-cshlib := $(addprefix $(obj)/,$(host-cshlib)) host-cxxshlib := $(addprefix $(obj)/,$(host-cxxshlib)) host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs)) host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs)) -host-objdirs := $(addprefix $(obj)/,$(host-objdirs)) - -obj-dirs += $(host-objdirs) ##### # Handle options to gcc. Support building with separate output directory diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov new file mode 100644 index 000000000000..5cc72037e423 --- /dev/null +++ b/scripts/Makefile.kcov @@ -0,0 +1,7 @@ +ifdef CONFIG_KCOV +CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) +ifeq ($(CONFIG_KCOV_ENABLE_COMPARISONS),y) +CFLAGS_KCOV += $(call cc-option,-fsanitize-coverage=trace-cmp,) +endif + +endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2278405cbc80..08eb40a7729f 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -5,24 +5,25 @@ ccflags-y += $(EXTRA_CFLAGS) cppflags-y += $(EXTRA_CPPFLAGS) ldflags-y += $(EXTRA_LDFLAGS) -# -# flags that take effect in sub directories -export KBUILD_SUBDIR_ASFLAGS := $(KBUILD_SUBDIR_ASFLAGS) $(subdir-asflags-y) -export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y) +# flags that take effect in current and sub directories +KBUILD_AFLAGS += $(subdir-asflags-y) +KBUILD_CFLAGS += $(subdir-ccflags-y) # Figure out what we need to build from the various variables # =========================================================================== # When an object is listed to be built compiled-in and modular, # only build the compiled-in version - obj-m := $(filter-out $(obj-y),$(obj-m)) # Libraries are always collected in one lib file. # Filter out objects already built-in - lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) +# Determine modorder. +# Unfortunately, we don't have information about ordering between -y +# and -m subdirs. Just put -y's first. +modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) # Handle objects in subdirs # --------------------------------------------------------------------------- @@ -30,12 +31,6 @@ lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) # and add the directory to the list of dirs to descend into: $(subdir-y) # o if we encounter foo/ in $(obj-m), remove it from $(obj-m) # and add the directory to the list of dirs to descend into: $(subdir-m) - -# Determine modorder. -# Unfortunately, we don't have information about ordering between -y -# and -m subdirs. Just put -y's first. -modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) - __subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) subdir-y += $(__subdir-y) __subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) @@ -44,10 +39,9 @@ obj-y := $(patsubst %/, %/built-in.o, $(obj-y)) obj-m := $(filter-out %/, $(obj-m)) # Subdirectories we need to descend into - subdir-ym := $(sort $(subdir-y) $(subdir-m)) -# if $(foo-objs) exists, foo.o is a composite object +# if $(foo-objs), $(foo-y), or $(foo-m) exists, foo.o is a composite object multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))), $(m)))) multi-used := $(multi-used-y) $(multi-used-m) @@ -57,15 +51,11 @@ single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) # objects depend on those (obviously) multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y))) multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y))) -multi-objs := $(multi-objs-y) $(multi-objs-m) # $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to # tell kbuild to descend subdir-obj-y := $(filter %/built-in.o, $(obj-y)) -# $(obj-dirs) is a list of directories that contain object files -obj-dirs := $(dir $(multi-objs) $(obj-y)) - # Replace multi-part objects by their individual parts, look at local dir only real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y) real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) @@ -93,11 +83,9 @@ multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y)) multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) -obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) # These flags are needed for modversions and compiling, so we define them here -# already -# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will +# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) # Note: Files that end up in two or more modules are compiled without the # KBUILD_MODNAME definition. The reason is that any made-up name would @@ -107,10 +95,10 @@ basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) modname_flags = $(if $(filter 1,$(words $(modname))),\ -DKBUILD_MODNAME=$(call name-fix,$(modname))) -orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ +orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) -orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ +orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \ $(asflags-y) $(AFLAGS_$(basetarget).o) _a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 991db7d6e4df..df4174405feb 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -143,8 +143,7 @@ FORCE: # optimization, we don't need to read them if the target does not # exist, we will rebuild anyway in that case. -targets := $(wildcard $(sort $(targets))) -cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) +cmd_files := $(wildcard $(foreach f,$(sort $(targets)),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8b80bac055e4..95cda3ecc66b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -454,6 +454,7 @@ our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; our $logFunctions = qr{(?x: printk(?:_ratelimited|_once|_deferred_once|_deferred|)| (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| + TP_printk| WARN(?:_RATELIMIT|_ONCE|)| panic| MODULE_[A-Z_]+| @@ -2900,8 +2901,9 @@ sub process { $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { $msg_type = ""; - # EFI_GUID is another special case - } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { + # More special cases + } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || + $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { $msg_type = ""; # Otherwise set the alternate message types @@ -3103,6 +3105,7 @@ sub process { $line =~ /^\+[a-z_]*init/ || $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || $line =~ /^\+\s*DECLARE/ || + $line =~ /^\+\s*builtin_[\w_]*driver/ || $line =~ /^\+\s*__setup/)) { if (CHK("LINE_SPACING", "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && @@ -3182,6 +3185,12 @@ sub process { # check we are in a valid C source file if not then ignore this hunk next if ($realfile !~ /\.(h|c)$/); +# check for unusual line ending [ or ( + if ($line =~ /^\+.*([\[\(])\s*$/) { + CHK("OPEN_ENDED_LINE", + "Lines should not end with a '$1'\n" . $herecurr); + } + # check if this appears to be the start function declaration, save the name if ($sline =~ /^\+\{\s*$/ && $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { @@ -3829,28 +3838,10 @@ sub process { "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); } -# printk should use KERN_* levels. Note that follow on printk's on the -# same line do not need a level, so we use the current block context -# to try and find and validate the current printk. In summary the current -# printk includes all preceding printk's which have no newline on the end. -# we assume the first bad printk is the one to report. - if ($line =~ /\bprintk\((?!KERN_)\s*"/) { - my $ok = 0; - for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { - #print "CHECK<$lines[$ln - 1]\n"; - # we have a preceding printk if it ends - # with "\n" ignore it, else it is to blame - if ($lines[$ln - 1] =~ m{\bprintk\(}) { - if ($rawlines[$ln - 1] !~ m{\\n"}) { - $ok = 1; - } - last; - } - } - if ($ok == 0) { - WARN("PRINTK_WITHOUT_KERN_LEVEL", - "printk() should include KERN_ facility level\n" . $herecurr); - } +# printk should use KERN_* levels + if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { + WARN("PRINTK_WITHOUT_KERN_LEVEL", + "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); } if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { @@ -5957,7 +5948,7 @@ sub process { # check for function declarations that have arguments without identifier names if (defined $stat && - $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && + $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && $1 ne "void") { my $args = trim($1); while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { @@ -6109,7 +6100,7 @@ sub process { next if ($fline =~ /^.[\s$;]*$/); $has_statement = 1; $count++; - $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); + $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); } if (!$has_break && $has_statement) { WARN("MISSING_BREAK", diff --git a/scripts/coccicheck b/scripts/coccicheck index 28ad1feff9e1..d5f28d5044e7 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -123,15 +123,8 @@ run_cmd_parmap() { if [ $VERBOSE -ne 0 ] ; then echo "Running ($NPROC in parallel): $@" fi - if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then - if [ -f $DEBUG_FILE ]; then - echo "Debug file $DEBUG_FILE exists, bailing" - exit - fi - else - DEBUG_FILE="/dev/null" - fi - $@ 2>$DEBUG_FILE + echo $@ >>$DEBUG_FILE + $@ 2>>$DEBUG_FILE if [[ $? -ne 0 ]]; then echo "coccicheck failed" exit $? @@ -176,8 +169,8 @@ OPTIONS="$OPTIONS $SPFLAGS" coccinelle () { COCCI="$1" - OPT=`grep "Option" $COCCI | cut -d':' -f2` - REQ=`grep "Requires" $COCCI | cut -d':' -f2 | sed "s| ||"` + OPT=`grep "Options:" $COCCI | cut -d':' -f2` + REQ=`grep "Requires:" $COCCI | cut -d':' -f2 | sed "s| ||"` REQ_NUM=$(echo $REQ | ${DIR}/scripts/ld-version.sh) if [ "$REQ_NUM" != "0" ] ; then if [ "$SPATCH_VERSION_NUM" -lt "$REQ_NUM" ] ; then @@ -194,7 +187,7 @@ coccinelle () { if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; then - FILE=`echo $COCCI | sed "s|$srctree/||"` + FILE=${COCCI#$srctree/} echo "Processing `basename $COCCI`" echo "with option(s) \"$OPT\"" @@ -247,6 +240,15 @@ coccinelle () { } +if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then + if [ -f $DEBUG_FILE ]; then + echo "Debug file $DEBUG_FILE exists, bailing" + exit + fi +else + DEBUG_FILE="/dev/null" +fi + if [ "$COCCI" = "" ] ; then for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do coccinelle $f diff --git a/scripts/coccinelle/api/check_bq27xxx_data.cocci b/scripts/coccinelle/api/check_bq27xxx_data.cocci new file mode 100644 index 000000000000..9212b85169d2 --- /dev/null +++ b/scripts/coccinelle/api/check_bq27xxx_data.cocci @@ -0,0 +1,161 @@ +/// Detect BQ27XXX_DATA structures with identical registers, dm registers or +/// properties. +//# Doesn't unfold macros used in register or property fields. +//# Requires OCaml scripting +/// +// Confidence: High +// Copyright: (C) 2017 Julia Lawall, Inria/LIP6, GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Requires: 1.0.7 +// Keywords: BQ27XXX_DATA + +virtual report + +@initialize:ocaml@ +@@ + +let print_report p msg = + let p = List.hd p in + Printf.printf "%s:%d:%d-%d: %s" p.file p.line p.col p.col_end msg + +@str depends on report@ +type t; +identifier i,i1,i2; +expression e1,e2; +@@ + +t i[] = { + ..., + [e1] = BQ27XXX_DATA(i1,...), + ..., + [e2] = BQ27XXX_DATA(i2,...), + ..., +}; + +@script:ocaml tocheck@ +i1 << str.i1; +i2 << str.i2; +i1regs; i2regs; +i1dmregs; i2dmregs; +i1props; i2props; +@@ + +if not(i1 = i2) +then + begin + i1regs := make_ident (i1 ^ "_regs"); + i2regs := make_ident (i2 ^ "_regs"); + i1dmregs := make_ident (i1 ^ "_dm_regs"); + i2dmregs := make_ident (i2 ^ "_dm_regs"); + i1props := make_ident (i1 ^ "_props"); + i2props := make_ident (i2 ^ "_props") + end + +(* ---------------------------------------------------------------- *) + +@getregs1@ +typedef u8; +identifier tocheck.i1regs; +initializer list i1regs_vals; +position p1; +@@ + +u8 i1regs@p1[...] = { i1regs_vals, }; + +@getregs2@ +identifier tocheck.i2regs; +initializer list i2regs_vals; +position p2; +@@ + +u8 i2regs@p2[...] = { i2regs_vals, }; + +@script:ocaml@ +(_,i1regs_vals) << getregs1.i1regs_vals; +(_,i2regs_vals) << getregs2.i2regs_vals; +i1regs << tocheck.i1regs; +i2regs << tocheck.i2regs; +p1 << getregs1.p1; +p2 << getregs2.p2; +@@ + +if i1regs < i2regs && + List.sort compare i1regs_vals = List.sort compare i2regs_vals +then + let msg = + Printf.sprintf + "WARNING %s and %s (line %d) are identical\n" + i1regs i2regs (List.hd p2).line in + print_report p1 msg + +(* ---------------------------------------------------------------- *) + +@getdmregs1@ +identifier tocheck.i1dmregs; +initializer list i1dmregs_vals; +position p1; +@@ + +struct bq27xxx_dm_reg i1dmregs@p1[] = { i1dmregs_vals, }; + +@getdmregs2@ +identifier tocheck.i2dmregs; +initializer list i2dmregs_vals; +position p2; +@@ + +struct bq27xxx_dm_reg i2dmregs@p2[] = { i2dmregs_vals, }; + +@script:ocaml@ +(_,i1dmregs_vals) << getdmregs1.i1dmregs_vals; +(_,i2dmregs_vals) << getdmregs2.i2dmregs_vals; +i1dmregs << tocheck.i1dmregs; +i2dmregs << tocheck.i2dmregs; +p1 << getdmregs1.p1; +p2 << getdmregs2.p2; +@@ + +if i1dmregs < i2dmregs && + List.sort compare i1dmregs_vals = List.sort compare i2dmregs_vals +then + let msg = + Printf.sprintf + "WARNING %s and %s (line %d) are identical\n" + i1dmregs i2dmregs (List.hd p2).line in + print_report p1 msg + +(* ---------------------------------------------------------------- *) + +@getprops1@ +identifier tocheck.i1props; +initializer list[n1] i1props_vals; +position p1; +@@ + +enum power_supply_property i1props@p1[] = { i1props_vals, }; + +@getprops2@ +identifier tocheck.i2props; +initializer list[n2] i2props_vals; +position p2; +@@ + +enum power_supply_property i2props@p2[] = { i2props_vals, }; + +@script:ocaml@ +(_,i1props_vals) << getprops1.i1props_vals; +(_,i2props_vals) << getprops2.i2props_vals; +i1props << tocheck.i1props; +i2props << tocheck.i2props; +p1 << getprops1.p1; +p2 << getprops2.p2; +@@ + +if i1props < i2props && + List.sort compare i1props_vals = List.sort compare i2props_vals +then + let msg = + Printf.sprintf + "WARNING %s and %s (line %d) are identical\n" + i1props i2props (List.hd p2).line in + print_report p1 msg diff --git a/scripts/coccinelle/api/setup_timer.cocci b/scripts/coccinelle/api/setup_timer.cocci index eb6bd9e4ab1a..e4577089dcb9 100644 --- a/scripts/coccinelle/api/setup_timer.cocci +++ b/scripts/coccinelle/api/setup_timer.cocci @@ -2,6 +2,7 @@ /// and data fields // Confidence: High // Copyright: (C) 2016 Vaishali Thakkar, Oracle. GPLv2 +// Copyright: (C) 2017 Kees Cook, Google. GPLv2 // Options: --no-includes --include-headers // Keywords: init_timer, setup_timer @@ -10,60 +11,123 @@ virtual context virtual org virtual report +// Match the common cases first to avoid Coccinelle parsing loops with +// "... when" clauses. + @match_immediate_function_data_after_init_timer depends on patch && !context && !org && !report@ expression e, func, da; @@ --init_timer (&e); -+setup_timer (&e, func, da); +-init_timer ++setup_timer + ( \(&e\|e\) ++, func, da + ); +( +-\(e.function\|e->function\) = func; +-\(e.data\|e->data\) = da; +| +-\(e.data\|e->data\) = da; +-\(e.function\|e->function\) = func; +) + +@match_immediate_function_data_before_init_timer +depends on patch && !context && !org && !report@ +expression e, func, da; +@@ + +( +-\(e.function\|e->function\) = func; +-\(e.data\|e->data\) = da; +| +-\(e.data\|e->data\) = da; +-\(e.function\|e->function\) = func; +) +-init_timer ++setup_timer + ( \(&e\|e\) ++, func, da + ); + +@match_function_and_data_after_init_timer +depends on patch && !context && !org && !report@ +expression e, e2, e3, e4, e5, func, da; +@@ +-init_timer ++setup_timer + ( \(&e\|e\) ++, func, da + ); + ... when != func = e2 + when != da = e3 ( -e.function = func; +... when != da = e4 -e.data = da; | +-e->function = func; +... when != da = e4 +-e->data = da; +| -e.data = da; +... when != func = e5 -e.function = func; +| +-e->data = da; +... when != func = e5 +-e->function = func; ) -@match_function_and_data_after_init_timer +@match_function_and_data_before_init_timer depends on patch && !context && !org && !report@ -expression e1, e2, e3, e4, e5, a, b; +expression e, e2, e3, e4, e5, func, da; @@ - --init_timer (&e1); -+setup_timer (&e1, a, b); - -... when != a = e2 - when != b = e3 ( --e1.function = a; -... when != b = e4 --e1.data = b; +-e.function = func; +... when != da = e4 +-e.data = da; | --e1.data = b; -... when != a = e5 --e1.function = a; +-e->function = func; +... when != da = e4 +-e->data = da; +| +-e.data = da; +... when != func = e5 +-e.function = func; +| +-e->data = da; +... when != func = e5 +-e->function = func; ) +... when != func = e2 + when != da = e3 +-init_timer ++setup_timer + ( \(&e\|e\) ++, func, da + ); @r1 exists@ +expression t; identifier f; position p; @@ f(...) { ... when any - init_timer@p(...) + init_timer@p(\(&t\|t\)) ... when any } @r2 exists@ +expression r1.t; identifier g != r1.f; -struct timer_list t; expression e8; @@ g(...) { ... when any - t.data = e8 + \(t.data\|t->data\) = e8 ... when any } @@ -77,14 +141,31 @@ p << r1.p; cocci.include_match(False) @r3 depends on patch && !context && !org && !report@ -expression e6, e7, c; +expression r1.t, func, e7; position r1.p; @@ --init_timer@p (&e6); -+setup_timer (&e6, c, 0UL); -... when != c = e7 --e6.function = c; +( +-init_timer@p(&t); ++setup_timer(&t, func, 0UL); +... when != func = e7 +-t.function = func; +| +-t.function = func; +... when != func = e7 +-init_timer@p(&t); ++setup_timer(&t, func, 0UL); +| +-init_timer@p(t); ++setup_timer(t, func, 0UL); +... when != func = e7 +-t->function = func; +| +-t->function = func; +... when != func = e7 +-init_timer@p(t); ++setup_timer(t, func, 0UL); +) // ---------------------------------------------------------------------------- @@ -104,11 +185,9 @@ position j0, j1, j2; ) @match_function_and_data_after_init_timer_context -depends on !patch && -!match_immediate_function_data_after_init_timer_context && - (context || org || report)@ +depends on !patch && (context || org || report)@ expression a, b, e1, e2, e3, e4, e5; -position j0, j1, j2; +position j0 != match_immediate_function_data_after_init_timer_context.j0,j1,j2; @@ * init_timer@j0 (&e1); @@ -124,13 +203,12 @@ position j0, j1, j2; * e1@j2.function = a; ) -@r3_context depends on !patch && -!match_immediate_function_data_after_init_timer_context && -!match_function_and_data_after_init_timer_context && - (context || org || report)@ +@r3_context depends on !patch && (context || org || report)@ expression c, e6, e7; position r1.p; -position j0, j1; +position j0 != + {match_immediate_function_data_after_init_timer_context.j0, + match_function_and_data_after_init_timer_context.j0}, j1; @@ * init_timer@j0@p (&e6); diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci index 873f444e7137..be6f9f1abb34 100644 --- a/scripts/coccinelle/iterators/list_entry_update.cocci +++ b/scripts/coccinelle/iterators/list_entry_update.cocci @@ -15,7 +15,7 @@ virtual context virtual org virtual report -@r@ +@r exists@ iterator name list_for_each_entry; expression x,E; position p1,p2; diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci index d0d00ef1f12a..ffe75407c5d2 100644 --- a/scripts/coccinelle/misc/ifcol.cocci +++ b/scripts/coccinelle/misc/ifcol.cocci @@ -3,10 +3,10 @@ /// Sometimes, code after an if that is indented is actually intended to be /// part of the if branch. /// -/// This has a high rate of false positives, because Coccinelle's column -/// calculation does not distinguish between spaces and tabs, so code that -/// is not visually aligned may be considered to be in the same column. -/// +//# This has a high rate of false positives, because Coccinelle's column +//# calculation does not distinguish between spaces and tabs, so code that +//# is not visually aligned may be considered to be in the same column. +// // Confidence: Low // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. diff --git a/scripts/coccinelle/misc/orplus.cocci b/scripts/coccinelle/misc/orplus.cocci index 81fabf379390..08de5be73693 100644 --- a/scripts/coccinelle/misc/orplus.cocci +++ b/scripts/coccinelle/misc/orplus.cocci @@ -14,7 +14,19 @@ virtual report virtual context @r@ -constant c; +constant c,c1; +identifier i,i1; +position p; +@@ + +( + c1 + c - 1 +| + c1@i1 +@p c@i +) + +@s@ +constant r.c, r.c1; identifier i; expression e; @@ @@ -27,28 +39,31 @@ e & c@i e |= c@i | e &= c@i +| +e | c1@i +| +e & c1@i +| +e |= c1@i +| +e &= c1@i ) -@s@ -constant r.c,c1; -identifier i1; -position p; +@depends on s@ +position r.p; +constant c1,c2; @@ -( - c1 + c - 1 -| -*c1@i1 +@p c -) +* c1 +@p c2 -@script:python depends on org@ -p << s.p; +@script:python depends on s && org@ +p << r.p; @@ cocci.print_main("sum of probable bitmasks, consider |",p) -@script:python depends on report@ -p << s.p; +@script:python depends on s && report@ +p << r.p; @@ msg = "WARNING: sum of probable bitmasks, consider |" diff --git a/scripts/coccinelle/null/badzero.cocci b/scripts/coccinelle/null/badzero.cocci index 5551da2b4fe3..f597c8007b76 100644 --- a/scripts/coccinelle/null/badzero.cocci +++ b/scripts/coccinelle/null/badzero.cocci @@ -10,7 +10,7 @@ // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ -// Comments: Requires Coccinelle version 1.0.0-rc20 or later +// Requires: 1.0.0 // Options: virtual patch diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index bc443201d3ef..99c96e86eccb 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -57,6 +57,7 @@ my $sections = 0; my $file_emails = 0; my $from_filename = 0; my $pattern_depth = 0; +my $self_test = undef; my $version = 0; my $help = 0; my $find_maintainer_files = 0; @@ -138,6 +139,7 @@ my %VCS_cmds_git = ( "subject_pattern" => "^GitSubject: (.*)", "stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$", "file_exists_cmd" => "git ls-files \$file", + "list_files_cmd" => "git ls-files \$file", ); my %VCS_cmds_hg = ( @@ -167,6 +169,7 @@ my %VCS_cmds_hg = ( "subject_pattern" => "^HgSubject: (.*)", "stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$", "file_exists_cmd" => "hg files \$file", + "list_files_cmd" => "hg manifest -R \$file", ); my $conf = which_conf(".get_maintainer.conf"); @@ -216,6 +219,14 @@ if (-f $ignore_file) { close($ignore); } +if ($#ARGV > 0) { + foreach (@ARGV) { + if ($_ =~ /^-{1,2}self-test(?:=|$)/) { + die "$P: using --self-test does not allow any other option or argument\n"; + } + } +} + if (!GetOptions( 'email!' => \$email, 'git!' => \$email_git, @@ -252,6 +263,7 @@ if (!GetOptions( 'fe|file-emails!' => \$file_emails, 'f|file' => \$from_filename, 'find-maintainer-files' => \$find_maintainer_files, + 'self-test:s' => \$self_test, 'v|version' => \$version, 'h|help|usage' => \$help, )) { @@ -268,6 +280,12 @@ if ($version != 0) { exit 0; } +if (defined $self_test) { + read_all_maintainer_files(); + self_test(); + exit 0; +} + if (-t STDIN && !@ARGV) { # We're talking to a terminal, but have no command line arguments. die "$P: missing patchfile or -f file - use --help if necessary\n"; @@ -311,14 +329,17 @@ if (!top_of_kernel_tree($lk_path)) { my @typevalue = (); my %keyword_hash; my @mfiles = (); +my @self_test_info = (); sub read_maintainer_file { my ($file) = @_; open (my $maint, '<', "$file") or die "$P: Can't open MAINTAINERS file '$file': $!\n"; + my $i = 1; while (<$maint>) { my $line = $_; + chomp $line; if ($line =~ m/^([A-Z]):\s*(.*)/) { my $type = $1; @@ -338,9 +359,12 @@ sub read_maintainer_file { } push(@typevalue, "$type:$value"); } elsif (!(/^\s*$/ || /^\s*\#/)) { - $line =~ s/\n$//g; push(@typevalue, $line); } + if (defined $self_test) { + push(@self_test_info, {file=>$file, linenr=>$i, line=>$line}); + } + $i++; } close($maint); } @@ -357,26 +381,30 @@ sub find_ignore_git { return grep { $_ !~ /^\.git$/; } @_; } -if (-d "${lk_path}MAINTAINERS") { - opendir(DIR, "${lk_path}MAINTAINERS") or die $!; - my @files = readdir(DIR); - closedir(DIR); - foreach my $file (@files) { - push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./); +read_all_maintainer_files(); + +sub read_all_maintainer_files { + if (-d "${lk_path}MAINTAINERS") { + opendir(DIR, "${lk_path}MAINTAINERS") or die $!; + my @files = readdir(DIR); + closedir(DIR); + foreach my $file (@files) { + push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./); + } } -} -if ($find_maintainer_files) { - find( { wanted => \&find_is_maintainer_file, - preprocess => \&find_ignore_git, - no_chdir => 1, - }, "${lk_path}"); -} else { - push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS"; -} + if ($find_maintainer_files) { + find( { wanted => \&find_is_maintainer_file, + preprocess => \&find_ignore_git, + no_chdir => 1, + }, "${lk_path}"); + } else { + push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS"; + } -foreach my $file (@mfiles) { - read_maintainer_file("$file"); + foreach my $file (@mfiles) { + read_maintainer_file("$file"); + } } # @@ -586,6 +614,135 @@ if ($web) { exit($exit); +sub self_test { + my @lsfiles = (); + my @good_links = (); + my @bad_links = (); + my @section_headers = (); + my $index = 0; + + @lsfiles = vcs_list_files($lk_path); + + for my $x (@self_test_info) { + $index++; + + ## Section header duplication and missing section content + if (($self_test eq "" || $self_test =~ /\bsections\b/) && + $x->{line} =~ /^\S[^:]/ && + defined $self_test_info[$index] && + $self_test_info[$index]->{line} =~ /^([A-Z]):\s*\S/) { + my $has_S = 0; + my $has_F = 0; + my $has_ML = 0; + my $status = ""; + if (grep(m@^\Q$x->{line}\E@, @section_headers)) { + print("$x->{file}:$x->{linenr}: warning: duplicate section header\t$x->{line}\n"); + } else { + push(@section_headers, $x->{line}); + } + my $nextline = $index; + while (defined $self_test_info[$nextline] && + $self_test_info[$nextline]->{line} =~ /^([A-Z]):\s*(\S.*)/) { + my $type = $1; + my $value = $2; + if ($type eq "S") { + $has_S = 1; + $status = $value; + } elsif ($type eq "F" || $type eq "N") { + $has_F = 1; + } elsif ($type eq "M" || $type eq "R" || $type eq "L") { + $has_ML = 1; + } + $nextline++; + } + if (!$has_ML && $status !~ /orphan|obsolete/i) { + print("$x->{file}:$x->{linenr}: warning: section without email address\t$x->{line}\n"); + } + if (!$has_S) { + print("$x->{file}:$x->{linenr}: warning: section without status \t$x->{line}\n"); + } + if (!$has_F) { + print("$x->{file}:$x->{linenr}: warning: section without file pattern\t$x->{line}\n"); + } + } + + next if ($x->{line} !~ /^([A-Z]):\s*(.*)/); + + my $type = $1; + my $value = $2; + + ## Filename pattern matching + if (($type eq "F" || $type eq "X") && + ($self_test eq "" || $self_test =~ /\bpatterns\b/)) { + $value =~ s@\.@\\\.@g; ##Convert . to \. + $value =~ s/\*/\.\*/g; ##Convert * to .* + $value =~ s/\?/\./g; ##Convert ? to . + ##if pattern is a directory and it lacks a trailing slash, add one + if ((-d $value)) { + $value =~ s@([^/])$@$1/@; + } + if (!grep(m@^$value@, @lsfiles)) { + print("$x->{file}:$x->{linenr}: warning: no file matches\t$x->{line}\n"); + } + + ## Link reachability + } elsif (($type eq "W" || $type eq "Q" || $type eq "B") && + $value =~ /^https?:/ && + ($self_test eq "" || $self_test =~ /\blinks\b/)) { + next if (grep(m@^\Q$value\E$@, @good_links)); + my $isbad = 0; + if (grep(m@^\Q$value\E$@, @bad_links)) { + $isbad = 1; + } else { + my $output = `wget --spider -q --no-check-certificate --timeout 10 --tries 1 $value`; + if ($? == 0) { + push(@good_links, $value); + } else { + push(@bad_links, $value); + $isbad = 1; + } + } + if ($isbad) { + print("$x->{file}:$x->{linenr}: warning: possible bad link\t$x->{line}\n"); + } + + ## SCM reachability + } elsif ($type eq "T" && + ($self_test eq "" || $self_test =~ /\bscm\b/)) { + next if (grep(m@^\Q$value\E$@, @good_links)); + my $isbad = 0; + if (grep(m@^\Q$value\E$@, @bad_links)) { + $isbad = 1; + } elsif ($value !~ /^(?:git|quilt|hg)\s+\S/) { + print("$x->{file}:$x->{linenr}: warning: malformed entry\t$x->{line}\n"); + } elsif ($value =~ /^git\s+(\S+)(\s+([^\(]+\S+))?/) { + my $url = $1; + my $branch = ""; + $branch = $3 if $3; + my $output = `git ls-remote --exit-code -h "$url" $branch > /dev/null 2>&1`; + if ($? == 0) { + push(@good_links, $value); + } else { + push(@bad_links, $value); + $isbad = 1; + } + } elsif ($value =~ /^(?:quilt|hg)\s+(https?:\S+)/) { + my $url = $1; + my $output = `wget --spider -q --no-check-certificate --timeout 10 --tries 1 $url`; + if ($? == 0) { + push(@good_links, $value); + } else { + push(@bad_links, $value); + $isbad = 1; + } + } + if ($isbad) { + print("$x->{file}:$x->{linenr}: warning: possible bad link\t$x->{line}\n"); + } + } + } +} + sub ignore_email_address { my ($address) = @_; @@ -863,6 +1020,7 @@ Other options: --sections => print all of the subsystem sections with pattern matches --letters => print all matching 'letter' types from all matching sections --mailmap => use .mailmap file (default: $email_use_mailmap) + --self-test => show potential issues with MAINTAINERS file content --version => show version --help => show this help information @@ -2192,6 +2350,23 @@ sub vcs_file_exists { return $exists; } +sub vcs_list_files { + my ($file) = @_; + + my @lsfiles = (); + + my $vcs_used = vcs_exists(); + return 0 if (!$vcs_used); + + my $cmd = $VCS_cmds{"list_files_cmd"}; + $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd + @lsfiles = &{$VCS_cmds{"execute_cmd"}}($cmd); + + return () if ($? != 0); + + return @lsfiles; +} + sub uniq { my (@parms) = @_; diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 7bd52b8f63d4..bd29a92b4b48 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -58,6 +58,7 @@ Output format selection (mutually exclusive): -man Output troff manual page format. This is the default. -rst Output reStructuredText format. -text Output plain text format. + -none Do not output documentation, only warnings. Output selection (mutually exclusive): -export Only output documentation for symbols that have been @@ -532,6 +533,8 @@ while ($ARGV[0] =~ m/^-(.*)/) { $output_mode = "gnome"; @highlights = @highlights_gnome; $blankline = $blankline_gnome; + } elsif ($cmd eq "-none") { + $output_mode = "none"; } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document $modulename = shift @ARGV; } elsif ($cmd eq "-function") { # to only output specific functions @@ -2117,6 +2120,24 @@ sub output_blockhead_list(%) { } } + +## none mode output functions + +sub output_function_none(%) { +} + +sub output_enum_none(%) { +} + +sub output_typedef_none(%) { +} + +sub output_struct_none(%) { +} + +sub output_blockhead_none(%) { +} + ## # generic output function for all types (function, struct/union, typedef, enum); # calls the generated, variable output_ function name based on @@ -3143,7 +3164,9 @@ sub process_file($) { } } if ($initial_section_counter == $section_counter) { - print STDERR "${file}:1: warning: no structured comments found\n"; + if ($output_mode ne "none") { + print STDERR "${file}:1: warning: no structured comments found\n"; + } if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { print STDERR " Was looking for '$_'.\n" for keys %function_table; } diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index e6818b8e7141..c0d129d7f430 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -188,10 +188,8 @@ sortextable() # Delete output files in case of error cleanup() { - rm -f .old_version rm -f .tmp_System.map rm -f .tmp_kallsyms* - rm -f .tmp_version rm -f .tmp_vmlinux* rm -f built-in.o rm -f System.map @@ -239,12 +237,12 @@ esac # Update version info GEN .version -if [ ! -r .version ]; then - rm -f .version; - echo 1 >.version; +if [ -r .version ]; then + VERSION=$(expr 0$(cat .version) + 1) + echo $VERSION > .version else - mv .version .old_version; - expr 0$(cat .old_version) + 1 >.version; + rm -f .version + echo 1 > .version fi; # final build of init/ @@ -332,6 +330,3 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then exit 1 fi fi - -# We made a new kernel - delete old version file -rm -f .old_version diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 959199c3147e..87f1fc9801d7 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -28,12 +28,7 @@ LC_ALL=C export LC_ALL if [ -z "$KBUILD_BUILD_VERSION" ]; then - if [ -r .version ]; then - VERSION=`cat .version` - else - VERSION=0 - echo 0 > .version - fi + VERSION=$(cat .version 2>/dev/null || echo 1) else VERSION=$KBUILD_BUILD_VERSION fi diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 73f9f3192b9f..9ed96aefc72d 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -50,17 +50,18 @@ rpm-pkg rpm: FORCE $(MAKE) clean $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec $(call cmd,src_tar,$(KERNELPATH),kernel.spec) - rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz - rm $(KERNELPATH).tar.gz kernel.spec + +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \ + --define='_smp_mflags %{nil}' # binrpm-pkg # --------------------------------------------------------------------------- binrpm-pkg: FORCE $(MAKE) KBUILD_SRC= $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec - rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ + +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ $(UTS_MACHINE) -bb $(objtree)/binkernel.spec - rm binkernel.spec + +clean-files += $(objtree)/*.spec # Deb target # --------------------------------------------------------------------------- diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 0bc87473f68f..b4f0f2b3f8d2 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -408,9 +408,9 @@ EOF dpkg-source -cdebian/control -ldebian/changelog --format="3.0 (custom)" --target-format="3.0 (quilt)" \ -b / ../${sourcename}_${version}.orig.tar.gz ../${sourcename}_${packageversion}.debian.tar.gz mv ${sourcename}_${packageversion}*dsc .. - dpkg-genchanges > ../${sourcename}_${packageversion}_${debarch}.changes + dpkg-genchanges -Vkernel:debarch="${debarch}" > ../${sourcename}_${packageversion}_${debarch}.changes else - dpkg-genchanges -b > ../${sourcename}_${packageversion}_${debarch}.changes + dpkg-genchanges -b -Vkernel:debarch="${debarch}" > ../${sourcename}_${packageversion}_${debarch}.changes fi exit 0 diff --git a/scripts/package/mkspec b/scripts/package/mkspec index f47f17aae135..280027fad991 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -10,156 +10,135 @@ # # how we were called determines which rpms we build and how we build them -if [ "$1" = "prebuilt" ]; then - PREBUILT=true +if [ "$1" = prebuilt ]; then + S=DEL else - PREBUILT=false + S= fi -# starting to output the spec -if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then - PROVIDES=kernel-drm -fi - -PROVIDES="$PROVIDES kernel-$KERNELRELEASE" -__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"` - -echo "Name: kernel" -echo "Summary: The Linux Kernel" -echo "Version: $__KERNELRELEASE" -echo "Release: $(cat .version 2>/dev/null || echo 1)" -echo "License: GPL" -echo "Group: System Environment/Kernel" -echo "Vendor: The Linux Community" -echo "URL: http://www.kernel.org" - -if ! $PREBUILT; then -echo "Source: kernel-$__KERNELRELEASE.tar.gz" -fi - -echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root" -echo "Provides: $PROVIDES" -echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" -echo "%define debug_package %{nil}" -echo "" -echo "%description" -echo "The Linux Kernel, the operating system core itself" -echo "" -echo "%package headers" -echo "Summary: Header files for the Linux kernel for use by glibc" -echo "Group: Development/System" -echo "Obsoletes: kernel-headers" -echo "Provides: kernel-headers = %{version}" -echo "%description headers" -echo "Kernel-headers includes the C header files that specify the interface" -echo "between the Linux kernel and userspace libraries and programs. The" -echo "header files define structures and constants that are needed for" -echo "building most standard programs and are also needed for rebuilding the" -echo "glibc package." -echo "" -echo "%package devel" -echo "Summary: Development package for building kernel modules to match the $__KERNELRELEASE kernel" -echo "Group: System Environment/Kernel" -echo "AutoReqProv: no" -echo "%description -n kernel-devel" -echo "This package provides kernel headers and makefiles sufficient to build modules" -echo "against the $__KERNELRELEASE kernel package." -echo "" - -if ! $PREBUILT; then -echo "%prep" -echo "%setup -q" -echo "" +if grep -q CONFIG_MODULES=y .config; then + M= +else + M=DEL fi -echo "%build" - -if ! $PREBUILT; then -echo "make clean && make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}" -echo "" +if grep -q CONFIG_DRM=y .config; then + PROVIDES=kernel-drm fi -echo "%install" -echo 'KBUILD_IMAGE=$(make image_name)' -echo "%ifarch ia64" -echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules' -echo "%else" -echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules' -echo "%endif" - -echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install' -echo "%ifarch ia64" -echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" -echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" -echo "%else" -echo "%ifarch ppc64" -echo "cp vmlinux arch/powerpc/boot" -echo "cp arch/powerpc/boot/"'$KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE" -echo "%else" -echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE" -echo "%endif" -echo "%endif" - -echo 'make %{?_smp_mflags} INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr KBUILD_SRC= headers_install' -echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" - -echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE" - -echo "%ifnarch ppc64" -echo 'bzip2 -9 --keep vmlinux' -echo 'mv vmlinux.bz2 $RPM_BUILD_ROOT'"/boot/vmlinux-$KERNELRELEASE.bz2" -echo "%endif" - -if ! $PREBUILT; then -echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/build" -echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/source" -echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE" -echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude .config.old --exclude .missing-syscalls.d\"" -echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)" -echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE" -echo "ln -sf /usr/src/kernels/$KERNELRELEASE build" -echo "ln -sf /usr/src/kernels/$KERNELRELEASE source" -fi +PROVIDES="$PROVIDES kernel-$KERNELRELEASE" +__KERNELRELEASE=$(echo $KERNELRELEASE | sed -e "s/-/_/g") +EXCLUDES="$RCS_TAR_IGNORE --exclude=.tmp_versions --exclude=*vmlinux* \ +--exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation \ +--exclude=.config.old --exclude=.missing-syscalls.d" -echo "" -echo "%clean" -echo 'rm -rf $RPM_BUILD_ROOT' -echo "" -echo "%post" -echo "if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then" -echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm" -echo "cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm" -echo "rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE" -echo "/sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm" -echo "rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm" -echo "fi" -echo "" -echo "%preun" -echo "if [ -x /sbin/new-kernel-pkg ]; then" -echo "new-kernel-pkg --remove $KERNELRELEASE --rminitrd --initrdfile=/boot/initramfs-$KERNELRELEASE.img" -echo "fi" -echo "" -echo "%postun" -echo "if [ -x /sbin/update-bootloader ]; then" -echo "/sbin/update-bootloader --remove $KERNELRELEASE" -echo "fi" -echo "" -echo "%files" -echo '%defattr (-, root, root)' -echo "/lib/modules/$KERNELRELEASE" -echo "%exclude /lib/modules/$KERNELRELEASE/build" -echo "%exclude /lib/modules/$KERNELRELEASE/source" -echo "/boot/*" -echo "" -echo "%files headers" -echo '%defattr (-, root, root)' -echo "/usr/include" -echo "" -if ! $PREBUILT; then -echo "%files devel" -echo '%defattr (-, root, root)' -echo "/usr/src/kernels/$KERNELRELEASE" -echo "/lib/modules/$KERNELRELEASE/build" -echo "/lib/modules/$KERNELRELEASE/source" -echo "" -fi +# We can label the here-doc lines for conditional output to the spec file +# +# Labels: +# $S: this line is enabled only when building source package +# $M: this line is enabled only when CONFIG_MODULES is enabled +sed -e '/^DEL/d' -e 's/^\t*//' <<EOF + Name: kernel + Summary: The Linux Kernel + Version: $__KERNELRELEASE + Release: $(cat .version 2>/dev/null || echo 1) + License: GPL + Group: System Environment/Kernel + Vendor: The Linux Community + URL: http://www.kernel.org +$S Source: kernel-$__KERNELRELEASE.tar.gz + Provides: $PROVIDES + %define __spec_install_post /usr/lib/rpm/brp-compress || : + %define debug_package %{nil} + + %description + The Linux Kernel, the operating system core itself + + %package headers + Summary: Header files for the Linux kernel for use by glibc + Group: Development/System + Obsoletes: kernel-headers + Provides: kernel-headers = %{version} + %description headers + Kernel-headers includes the C header files that specify the interface + between the Linux kernel and userspace libraries and programs. The + header files define structures and constants that are needed for + building most standard programs and are also needed for rebuilding the + glibc package. + +$S$M %package devel +$S$M Summary: Development package for building kernel modules to match the $__KERNELRELEASE kernel +$S$M Group: System Environment/Kernel +$S$M AutoReqProv: no +$S$M %description -n kernel-devel +$S$M This package provides kernel headers and makefiles sufficient to build modules +$S$M against the $__KERNELRELEASE kernel package. +$S$M +$S %prep +$S %setup -q +$S +$S %build +$S make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release} +$S + %install + mkdir -p %{buildroot}/boot + %ifarch ia64 + mkdir -p %{buildroot}/boot/efi + cp \$(make image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE + ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ + %else + cp \$(make image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE + %endif +$M make %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} KBUILD_SRC= modules_install + make %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr KBUILD_SRC= headers_install + cp System.map %{buildroot}/boot/System.map-$KERNELRELEASE + cp .config %{buildroot}/boot/config-$KERNELRELEASE + bzip2 -9 --keep vmlinux + mv vmlinux.bz2 %{buildroot}/boot/vmlinux-$KERNELRELEASE.bz2 +$S$M rm -f %{buildroot}/lib/modules/$KERNELRELEASE/build +$S$M rm -f %{buildroot}/lib/modules/$KERNELRELEASE/source +$S$M mkdir -p %{buildroot}/usr/src/kernels/$KERNELRELEASE +$S$M tar cf - . $EXCLUDES | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE +$S$M cd %{buildroot}/lib/modules/$KERNELRELEASE +$S$M ln -sf /usr/src/kernels/$KERNELRELEASE build +$S$M ln -sf /usr/src/kernels/$KERNELRELEASE source + + %clean + rm -rf %{buildroot} + + %post + if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then + cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm + cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm + rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE + /sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm + rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm + fi + + %preun + if [ -x /sbin/new-kernel-pkg ]; then + new-kernel-pkg --remove $KERNELRELEASE --rminitrd --initrdfile=/boot/initramfs-$KERNELRELEASE.img + fi + + %postun + if [ -x /sbin/update-bootloader ]; then + /sbin/update-bootloader --remove $KERNELRELEASE + fi + + %files + %defattr (-, root, root) +$M /lib/modules/$KERNELRELEASE +$M %exclude /lib/modules/$KERNELRELEASE/build +$M %exclude /lib/modules/$KERNELRELEASE/source + /boot/* + + %files headers + %defattr (-, root, root) + /usr/include +$S$M +$S$M %files devel +$S$M %defattr (-, root, root) +$S$M /usr/src/kernels/$KERNELRELEASE +$S$M /lib/modules/$KERNELRELEASE/build +$S$M /lib/modules/$KERNELRELEASE/source +EOF diff --git a/scripts/parse-maintainers.pl b/scripts/parse-maintainers.pl index 5dbd2faa2449..255cef1b098d 100644 --- a/scripts/parse-maintainers.pl +++ b/scripts/parse-maintainers.pl @@ -2,9 +2,44 @@ # SPDX-License-Identifier: GPL-2.0 use strict; +use Getopt::Long qw(:config no_auto_abbrev); + +my $input_file = "MAINTAINERS"; +my $output_file = "MAINTAINERS.new"; +my $output_section = "SECTION.new"; +my $help = 0; my $P = $0; +if (!GetOptions( + 'input=s' => \$input_file, + 'output=s' => \$output_file, + 'section=s' => \$output_section, + 'h|help|usage' => \$help, + )) { + die "$P: invalid argument - use --help if necessary\n"; +} + +if ($help != 0) { + usage(); + exit 0; +} + +sub usage { + print <<EOT; +usage: $P [options] <pattern matching regexes> + + --input => MAINTAINERS file to read (default: MAINTAINERS) + --output => sorted MAINTAINERS file to write (default: MAINTAINERS.new) + --section => new sorted MAINTAINERS file to write to (default: SECTION.new) + +If <pattern match regexes> exist, then the sections that match the +regexes are not written to the output file but are written to the +section file. + +EOT +} + # sort comparison functions sub by_category($$) { my ($a, $b) = @_; @@ -56,13 +91,20 @@ sub trim { sub alpha_output { my ($hashref, $filename) = (@_); + return if ! scalar(keys %$hashref); + open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n"; + my $separator; foreach my $key (sort by_category keys %$hashref) { if ($key eq " ") { - chomp $$hashref{$key}; print $file $$hashref{$key}; } else { - print $file "\n" . $key . "\n"; + if (! defined $separator) { + $separator = "\n"; + } else { + print $file $separator; + } + print $file $key . "\n"; foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) { print $file ($pattern . "\n"); } @@ -112,7 +154,7 @@ sub file_input { my %hash; my %new_hash; -file_input(\%hash, "MAINTAINERS"); +file_input(\%hash, $input_file); foreach my $type (@ARGV) { foreach my $key (keys %hash) { @@ -123,7 +165,7 @@ foreach my $type (@ARGV) { } } -alpha_output(\%hash, "MAINTAINERS.new"); -alpha_output(\%new_hash, "SECTION.new"); +alpha_output(\%hash, $output_file); +alpha_output(\%new_hash, $output_section); exit(0); diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile index e8049da1831f..b3048b894a39 100644 --- a/scripts/selinux/Makefile +++ b/scripts/selinux/Makefile @@ -1,2 +1 @@ subdir-y := mdp genheaders -subdir- += mdp genheaders diff --git a/scripts/spelling.txt b/scripts/spelling.txt index aa0cc49ad1ad..9a058cff49d4 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -1187,6 +1187,10 @@ unknonw||unknown unknow||unknown unkown||unknown unneded||unneeded +unneccecary||unnecessary +unneccesary||unnecessary +unneccessary||unnecessary +unnecesary||unnecessary unneedingly||unnecessarily unnsupported||unsupported unmached||unmatched |