diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Kbuild.include | 10 | ||||
| -rw-r--r-- | scripts/Makefile.gcc-plugins | 39 | ||||
| -rw-r--r-- | scripts/Makefile.ubsan | 5 | ||||
| -rwxr-xr-x | scripts/checkkconfigsymbols.py | 338 | ||||
| -rwxr-xr-x | scripts/checkpatch.pl | 347 | ||||
| -rw-r--r-- | scripts/const_structs.checkpatch | 64 | ||||
| -rwxr-xr-x | scripts/faddr2line | 177 | ||||
| -rwxr-xr-x | scripts/gcc-plugin.sh | 14 | ||||
| -rw-r--r-- | scripts/gcc-plugins/Makefile | 12 | ||||
| -rwxr-xr-x | scripts/get_maintainer.pl | 6 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 2 | ||||
| -rwxr-xr-x | scripts/package/builddeb | 4 | ||||
| -rw-r--r-- | scripts/recordmcount.c | 2 | ||||
| -rwxr-xr-x | scripts/recordmcount.pl | 2 | ||||
| -rw-r--r-- | scripts/spelling.txt | 1 | ||||
| -rwxr-xr-x | scripts/tags.sh | 4 | ||||
| -rwxr-xr-x | scripts/tracing/ftrace-bisect.sh | 115 | ||||
| -rwxr-xr-x | scripts/ver_linux | 260 |
18 files changed, 927 insertions, 475 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 15b196fc2f49..179219845dfc 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -108,16 +108,20 @@ as-option = $(call try-run,\ as-instr = $(call try-run,\ printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) +# Do not attempt to build with gcc plugins during cc-option tests. +# (And this uses delayed resolution so the flags will be up to date.) +CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) + # cc-option # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) cc-option = $(call try-run,\ - $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) + $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) cc-option-yn = $(call try-run,\ - $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) # cc-option-align # Prefix align with either -falign or -malign @@ -127,7 +131,7 @@ cc-option-align = $(subst -functions=0,,\ # cc-disable-warning # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) cc-disable-warning = $(call try-run,\ - $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + $(CC) $(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 diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 5e22b60589c1..61f0e6db909b 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -19,25 +19,42 @@ ifdef CONFIG_GCC_PLUGINS endif endif - GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) + GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) - export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN + export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR SANCOV_PLUGIN + ifneq ($(PLUGINCC),) + # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication. + GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS)) + endif + + KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) + GCC_PLUGIN := $(gcc-plugin-y) + GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y) +endif + +# If plugins aren't supported, abort the build before hard-to-read compiler +# errors start getting spewed by the main build. +PHONY += gcc-plugins-check +gcc-plugins-check: FORCE +ifdef CONFIG_GCC_PLUGINS ifeq ($(PLUGINCC),) ifneq ($(GCC_PLUGINS_CFLAGS),) ifeq ($(call cc-ifversion, -ge, 0405, y), y) - PLUGINCC := $(shell $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") - $(warning warning: your gcc installation does not support plugins, perhaps the necessary headers are missing?) + $(Q)$(srctree)/scripts/gcc-plugin.sh --show-error "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" || true + @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc installation does not support plugins, perhaps the necessary headers are missing?" >&2 && exit 1 else - $(warning warning: your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least) + @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc version does not support plugins, you should upgrade it to at least gcc 4.5" >&2 && exit 1 endif endif - else - # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication. - GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS)) endif +endif + @: - KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) - GCC_PLUGIN := $(gcc-plugin-y) - +# Actually do the build, if requested. +PHONY += gcc-plugins +gcc-plugins: scripts_basic gcc-plugins-check +ifdef CONFIG_GCC_PLUGINS + $(Q)$(MAKE) $(build)=scripts/gcc-plugins endif + @: diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 8ab68679cfb5..dd779c40c8e6 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -3,7 +3,6 @@ ifdef CONFIG_UBSAN CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero) CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable) CFLAGS_UBSAN += $(call cc-option, -fsanitize=vla-bound) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=null) CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow) CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds) CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size) @@ -14,4 +13,8 @@ ifdef CONFIG_UBSAN ifdef CONFIG_UBSAN_ALIGNMENT CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment) endif + +ifdef CONFIG_UBSAN_NULL + CFLAGS_UBSAN += $(call cc-option, -fsanitize=null) +endif endif diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index df643f60bb41..a32e4da4c117 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -1,98 +1,99 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """Find Kconfig symbols that are referenced but not defined.""" -# (c) 2014-2015 Valentin Rothberg <valentinrothberg@gmail.com> +# (c) 2014-2016 Valentin Rothberg <valentinrothberg@gmail.com> # (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de> # # Licensed under the terms of the GNU GPL License version 2 +import argparse import difflib import os import re import signal +import subprocess import sys from multiprocessing import Pool, cpu_count -from optparse import OptionParser -from subprocess import Popen, PIPE, STDOUT # regex expressions OPERATORS = r"&|\(|\)|\||\!" -FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}" -DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" -EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" +SYMBOL = r"(?:\w*[A-Z0-9]\w*){2,}" +DEF = r"^\s*(?:menu){,1}config\s+(" + SYMBOL + r")\s*" +EXPR = r"(?:" + OPERATORS + r"|\s|" + SYMBOL + r")+" DEFAULT = r"default\s+.*?(?:if\s.+){,1}" STMT = r"^\s*(?:if|select|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR -SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" +SOURCE_SYMBOL = r"(?:\W|\b)+[D]{,1}CONFIG_(" + SYMBOL + r")" # regex objects REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") -REGEX_FEATURE = re.compile(r'(?!\B)' + FEATURE + r'(?!\B)') -REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) +REGEX_SYMBOL = re.compile(r'(?!\B)' + SYMBOL + r'(?!\B)') +REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL) REGEX_KCONFIG_DEF = re.compile(DEF) REGEX_KCONFIG_EXPR = re.compile(EXPR) REGEX_KCONFIG_STMT = re.compile(STMT) REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") -REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") +REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$") REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+") REGEX_QUOTES = re.compile("(\"(.*?)\")") def parse_options(): """The user interface of this module.""" - usage = "%prog [options]\n\n" \ - "Run this tool to detect Kconfig symbols that are referenced but " \ - "not defined in\nKconfig. The output of this tool has the " \ - "format \'Undefined symbol\\tFile list\'\n\n" \ - "If no option is specified, %prog will default to check your\n" \ - "current tree. Please note that specifying commits will " \ - "\'git reset --hard\'\nyour current tree! You may save " \ - "uncommitted changes to avoid losing data." - - parser = OptionParser(usage=usage) - - parser.add_option('-c', '--commit', dest='commit', action='store', - default="", - help="Check if the specified commit (hash) introduces " - "undefined Kconfig symbols.") - - parser.add_option('-d', '--diff', dest='diff', action='store', - default="", - help="Diff undefined symbols between two commits. The " - "input format bases on Git log's " - "\'commmit1..commit2\'.") - - parser.add_option('-f', '--find', dest='find', action='store_true', - default=False, - help="Find and show commits that may cause symbols to be " - "missing. Required to run with --diff.") - - parser.add_option('-i', '--ignore', dest='ignore', action='store', - default="", - help="Ignore files matching this pattern. Note that " - "the pattern needs to be a Python regex. To " - "ignore defconfigs, specify -i '.*defconfig'.") - - parser.add_option('-s', '--sim', dest='sim', action='store', default="", - help="Print a list of maximum 10 string-similar symbols.") - - parser.add_option('', '--force', dest='force', action='store_true', - default=False, - help="Reset current Git tree even when it's dirty.") - - (opts, _) = parser.parse_args() - - if opts.commit and opts.diff: + usage = "Run this tool to detect Kconfig symbols that are referenced but " \ + "not defined in Kconfig. If no option is specified, " \ + "checkkconfigsymbols defaults to check your current tree. " \ + "Please note that specifying commits will 'git reset --hard\' " \ + "your current tree! You may save uncommitted changes to avoid " \ + "losing data." + + parser = argparse.ArgumentParser(description=usage) + + parser.add_argument('-c', '--commit', dest='commit', action='store', + default="", + help="check if the specified commit (hash) introduces " + "undefined Kconfig symbols") + + parser.add_argument('-d', '--diff', dest='diff', action='store', + default="", + help="diff undefined symbols between two commits " + "(e.g., -d commmit1..commit2)") + + parser.add_argument('-f', '--find', dest='find', action='store_true', + default=False, + help="find and show commits that may cause symbols to be " + "missing (required to run with --diff)") + + parser.add_argument('-i', '--ignore', dest='ignore', action='store', + default="", + help="ignore files matching this Python regex " + "(e.g., -i '.*defconfig')") + + parser.add_argument('-s', '--sim', dest='sim', action='store', default="", + help="print a list of max. 10 string-similar symbols") + + parser.add_argument('--force', dest='force', action='store_true', + default=False, + help="reset current Git tree even when it's dirty") + + parser.add_argument('--no-color', dest='color', action='store_false', + default=True, + help="don't print colored output (default when not " + "outputting to a terminal)") + + args = parser.parse_args() + + if args.commit and args.diff: sys.exit("Please specify only one option at once.") - if opts.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", opts.diff): + if args.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", args.diff): sys.exit("Please specify valid input in the following format: " "\'commit1..commit2\'") - if opts.commit or opts.diff: - if not opts.force and tree_is_dirty(): + if args.commit or args.diff: + if not args.force and tree_is_dirty(): sys.exit("The current Git tree is dirty (see 'git status'). " "Running this script may\ndelete important data since it " "calls 'git reset --hard' for some performance\nreasons. " @@ -100,138 +101,148 @@ def parse_options(): "'--force' if you\nwant to ignore this warning and " "continue.") - if opts.commit: - opts.find = False + if args.commit: + args.find = False - if opts.ignore: + if args.ignore: try: - re.match(opts.ignore, "this/is/just/a/test.c") + re.match(args.ignore, "this/is/just/a/test.c") except: sys.exit("Please specify a valid Python regex.") - return opts + return args def main(): """Main function of this module.""" - opts = parse_options() + args = parse_options() - if opts.sim and not opts.commit and not opts.diff: - sims = find_sims(opts.sim, opts.ignore) + global COLOR + COLOR = args.color and sys.stdout.isatty() + + if args.sim and not args.commit and not args.diff: + sims = find_sims(args.sim, args.ignore) if sims: - print "%s: %s" % (yel("Similar symbols"), ', '.join(sims)) + print("%s: %s" % (yel("Similar symbols"), ', '.join(sims))) else: - print "%s: no similar symbols found" % yel("Similar symbols") + print("%s: no similar symbols found" % yel("Similar symbols")) sys.exit(0) # dictionary of (un)defined symbols defined = {} undefined = {} - if opts.commit or opts.diff: + if args.commit or args.diff: head = get_head() # get commit range commit_a = None commit_b = None - if opts.commit: - commit_a = opts.commit + "~" - commit_b = opts.commit - elif opts.diff: - split = opts.diff.split("..") + if args.commit: + commit_a = args.commit + "~" + commit_b = args.commit + elif args.diff: + split = args.diff.split("..") commit_a = split[0] commit_b = split[1] undefined_a = {} undefined_b = {} # get undefined items before the commit - execute("git reset --hard %s" % commit_a) - undefined_a, _ = check_symbols(opts.ignore) + reset(commit_a) + undefined_a, _ = check_symbols(args.ignore) # get undefined items for the commit - execute("git reset --hard %s" % commit_b) - undefined_b, defined = check_symbols(opts.ignore) + reset(commit_b) + undefined_b, defined = check_symbols(args.ignore) # report cases that are present for the commit but not before - for feature in sorted(undefined_b): - # feature has not been undefined before - if not feature in undefined_a: - files = sorted(undefined_b.get(feature)) - undefined[feature] = files - # check if there are new files that reference the undefined feature + for symbol in sorted(undefined_b): + # symbol has not been undefined before + if symbol not in undefined_a: + files = sorted(undefined_b.get(symbol)) + undefined[symbol] = files + # check if there are new files that reference the undefined symbol else: - files = sorted(undefined_b.get(feature) - - undefined_a.get(feature)) + files = sorted(undefined_b.get(symbol) - + undefined_a.get(symbol)) if files: - undefined[feature] = files + undefined[symbol] = files # reset to head - execute("git reset --hard %s" % head) + reset(head) # default to check the entire tree else: - undefined, defined = check_symbols(opts.ignore) + undefined, defined = check_symbols(args.ignore) # now print the output - for feature in sorted(undefined): - print red(feature) + for symbol in sorted(undefined): + print(red(symbol)) - files = sorted(undefined.get(feature)) - print "%s: %s" % (yel("Referencing files"), ", ".join(files)) + files = sorted(undefined.get(symbol)) + print("%s: %s" % (yel("Referencing files"), ", ".join(files))) - sims = find_sims(feature, opts.ignore, defined) + sims = find_sims(symbol, args.ignore, defined) sims_out = yel("Similar symbols") if sims: - print "%s: %s" % (sims_out, ', '.join(sims)) + print("%s: %s" % (sims_out, ', '.join(sims))) else: - print "%s: %s" % (sims_out, "no similar symbols found") + print("%s: %s" % (sims_out, "no similar symbols found")) - if opts.find: - print "%s:" % yel("Commits changing symbol") - commits = find_commits(feature, opts.diff) + if args.find: + print("%s:" % yel("Commits changing symbol")) + commits = find_commits(symbol, args.diff) if commits: for commit in commits: commit = commit.split(" ", 1) - print "\t- %s (\"%s\")" % (yel(commit[0]), commit[1]) + print("\t- %s (\"%s\")" % (yel(commit[0]), commit[1])) else: - print "\t- no commit found" - print # new line + print("\t- no commit found") + print() # new line + + +def reset(commit): + """Reset current git tree to %commit.""" + execute(["git", "reset", "--hard", commit]) def yel(string): """ Color %string yellow. """ - return "\033[33m%s\033[0m" % string + return "\033[33m%s\033[0m" % string if COLOR else string def red(string): """ Color %string red. """ - return "\033[31m%s\033[0m" % string + return "\033[31m%s\033[0m" % string if COLOR else string def execute(cmd): """Execute %cmd and return stdout. Exit in case of error.""" - pop = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True) - (stdout, _) = pop.communicate() # wait until finished - if pop.returncode != 0: - sys.exit(stdout) + try: + stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False) + stdout = stdout.decode(errors='replace') + except subprocess.CalledProcessError as fail: + exit(fail) return stdout def find_commits(symbol, diff): """Find commits changing %symbol in the given range of %diff.""" - commits = execute("git log --pretty=oneline --abbrev-commit -G %s %s" - % (symbol, diff)) + commits = execute(["git", "log", "--pretty=oneline", + "--abbrev-commit", "-G", + symbol, diff]) return [x for x in commits.split("\n") if x] def tree_is_dirty(): """Return true if the current working tree is dirty (i.e., if any file has been added, deleted, modified, renamed or copied but not committed).""" - stdout = execute("git status --porcelain") + stdout = execute(["git", "status", "--porcelain"]) for line in stdout: if re.findall(r"[URMADC]{1}", line[:2]): return True @@ -240,13 +251,13 @@ def tree_is_dirty(): def get_head(): """Return commit hash of current HEAD.""" - stdout = execute("git rev-parse HEAD") + stdout = execute(["git", "rev-parse", "HEAD"]) return stdout.strip('\n') def partition(lst, size): """Partition list @lst into eveni-sized lists of size @size.""" - return [lst[i::size] for i in xrange(size)] + return [lst[i::size] for i in range(size)] def init_worker(): @@ -254,7 +265,7 @@ def init_worker(): signal.signal(signal.SIGINT, signal.SIG_IGN) -def find_sims(symbol, ignore, defined = []): +def find_sims(symbol, ignore, defined=[]): """Return a list of max. ten Kconfig symbols that are string-similar to @symbol.""" if defined: @@ -279,7 +290,7 @@ def find_sims(symbol, ignore, defined = []): def get_files(): """Return a list of all files in the current git directory.""" # use 'git ls-files' to get the worklist - stdout = execute("git ls-files") + stdout = execute(["git", "ls-files"]) if len(stdout) > 0 and stdout[-1] == "\n": stdout = stdout[:-1] @@ -311,8 +322,8 @@ def check_symbols_helper(pool, ignore): check_symbols() in order to properly terminate running worker processes.""" source_files = [] kconfig_files = [] - defined_features = [] - referenced_features = dict() # {file: [features]} + defined_symbols = [] + referenced_symbols = dict() # {file: [symbols]} for gitfile in get_files(): if REGEX_FILE_KCONFIG.match(gitfile): @@ -326,76 +337,75 @@ def check_symbols_helper(pool, ignore): # parse source files arglist = partition(source_files, cpu_count()) for res in pool.map(parse_source_files, arglist): - referenced_features.update(res) - + referenced_symbols.update(res) # parse kconfig files arglist = [] for part in partition(kconfig_files, cpu_count()): arglist.append((part, ignore)) for res in pool.map(parse_kconfig_files, arglist): - defined_features.extend(res[0]) - referenced_features.update(res[1]) - defined_features = set(defined_features) + defined_symbols.extend(res[0]) + referenced_symbols.update(res[1]) + defined_symbols = set(defined_symbols) - # inverse mapping of referenced_features to dict(feature: [files]) + # inverse mapping of referenced_symbols to dict(symbol: [files]) inv_map = dict() - for _file, features in referenced_features.iteritems(): - for feature in features: - inv_map[feature] = inv_map.get(feature, set()) - inv_map[feature].add(_file) - referenced_features = inv_map - - undefined = {} # {feature: [files]} - for feature in sorted(referenced_features): + for _file, symbols in referenced_symbols.items(): + for symbol in symbols: + inv_map[symbol] = inv_map.get(symbol, set()) + inv_map[symbol].add(_file) + referenced_symbols = inv_map + + undefined = {} # {symbol: [files]} + for symbol in sorted(referenced_symbols): # filter some false positives - if feature == "FOO" or feature == "BAR" or \ - feature == "FOO_BAR" or feature == "XXX": + if symbol == "FOO" or symbol == "BAR" or \ + symbol == "FOO_BAR" or symbol == "XXX": continue - if feature not in defined_features: - if feature.endswith("_MODULE"): + if symbol not in defined_symbols: + if symbol.endswith("_MODULE"): # avoid false positives for kernel modules - if feature[:-len("_MODULE")] in defined_features: + if symbol[:-len("_MODULE")] in defined_symbols: continue - undefined[feature] = referenced_features.get(feature) - return undefined, defined_features + undefined[symbol] = referenced_symbols.get(symbol) + return undefined, defined_symbols def parse_source_files(source_files): """Parse each source file in @source_files and return dictionary with source files as keys and lists of references Kconfig symbols as values.""" - referenced_features = dict() + referenced_symbols = dict() for sfile in source_files: - referenced_features[sfile] = parse_source_file(sfile) - return referenced_features + referenced_symbols[sfile] = parse_source_file(sfile) + return referenced_symbols def parse_source_file(sfile): - """Parse @sfile and return a list of referenced Kconfig features.""" + """Parse @sfile and return a list of referenced Kconfig symbols.""" lines = [] references = [] if not os.path.exists(sfile): return references - with open(sfile, "r") as stream: + with open(sfile, "r", encoding='utf-8', errors='replace') as stream: lines = stream.readlines() for line in lines: - if not "CONFIG_" in line: + if "CONFIG_" not in line: continue - features = REGEX_SOURCE_FEATURE.findall(line) - for feature in features: - if not REGEX_FILTER_FEATURES.search(feature): + symbols = REGEX_SOURCE_SYMBOL.findall(line) + for symbol in symbols: + if not REGEX_FILTER_SYMBOLS.search(symbol): continue - references.append(feature) + references.append(symbol) return references -def get_features_in_line(line): - """Return mentioned Kconfig features in @line.""" - return REGEX_FEATURE.findall(line) +def get_symbols_in_line(line): + """Return mentioned Kconfig symbols in @line.""" + return REGEX_SYMBOL.findall(line) def parse_kconfig_files(args): @@ -404,21 +414,21 @@ def parse_kconfig_files(args): pattern.""" kconfig_files = args[0] ignore = args[1] - defined_features = [] - referenced_features = dict() + defined_symbols = [] + referenced_symbols = dict() for kfile in kconfig_files: defined, references = parse_kconfig_file(kfile) - defined_features.extend(defined) + defined_symbols.extend(defined) if ignore and re.match(ignore, kfile): # do not collect references for files that match the ignore pattern continue - referenced_features[kfile] = references - return (defined_features, referenced_features) + referenced_symbols[kfile] = references + return (defined_symbols, referenced_symbols) def parse_kconfig_file(kfile): - """Parse @kfile and update feature definitions and references.""" + """Parse @kfile and update symbol definitions and references.""" lines = [] defined = [] references = [] @@ -427,7 +437,7 @@ def parse_kconfig_file(kfile): if not os.path.exists(kfile): return defined, references - with open(kfile, "r") as stream: + with open(kfile, "r", encoding='utf-8', errors='replace') as stream: lines = stream.readlines() for i in range(len(lines)): @@ -436,8 +446,8 @@ def parse_kconfig_file(kfile): line = line.split("#")[0] # ignore comments if REGEX_KCONFIG_DEF.match(line): - feature_def = REGEX_KCONFIG_DEF.findall(line) - defined.append(feature_def[0]) + symbol_def = REGEX_KCONFIG_DEF.findall(line) + defined.append(symbol_def[0]) skip = False elif REGEX_KCONFIG_HELP.match(line): skip = True @@ -446,18 +456,18 @@ def parse_kconfig_file(kfile): pass elif REGEX_KCONFIG_STMT.match(line): line = REGEX_QUOTES.sub("", line) - features = get_features_in_line(line) + symbols = get_symbols_in_line(line) # multi-line statements while line.endswith("\\"): i += 1 line = lines[i] line = line.strip('\n') - features.extend(get_features_in_line(line)) - for feature in set(features): - if REGEX_NUMERIC.match(feature): + symbols.extend(get_symbols_in_line(line)) + for symbol in set(symbols): + if REGEX_NUMERIC.match(symbol): # ignore numeric values continue - references.append(feature) + references.append(symbol) return defined, references diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4de3cc42fc50..a8368d1c4348 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -54,6 +54,7 @@ my $min_conf_desc_length = 4; my $spelling_file = "$D/spelling.txt"; my $codespell = 0; my $codespellfile = "/usr/share/codespell/dictionary.txt"; +my $conststructsfile = "$D/const_structs.checkpatch"; my $color = 1; my $allow_c99_comments = 1; @@ -523,7 +524,11 @@ our @mode_permission_funcs = ( ["module_param_array_named", 5], ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], ["proc_create(?:_data|)", 2], - ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2], + ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], + ["IIO_DEV_ATTR_[A-Z_]+", 1], + ["SENSOR_(?:DEVICE_|)ATTR_2", 2], + ["SENSOR_TEMPLATE(?:_2|)", 3], + ["__ATTR", 2], ); #Create a search pattern for all these functions to speed up a loop below @@ -541,6 +546,32 @@ our $mode_perms_world_writable = qr{ 0[0-7][0-7][2367] }x; +our %mode_permission_string_types = ( + "S_IRWXU" => 0700, + "S_IRUSR" => 0400, + "S_IWUSR" => 0200, + "S_IXUSR" => 0100, + "S_IRWXG" => 0070, + "S_IRGRP" => 0040, + "S_IWGRP" => 0020, + "S_IXGRP" => 0010, + "S_IRWXO" => 0007, + "S_IROTH" => 0004, + "S_IWOTH" => 0002, + "S_IXOTH" => 0001, + "S_IRWXUGO" => 0777, + "S_IRUGO" => 0444, + "S_IWUGO" => 0222, + "S_IXUGO" => 0111, +); + +#Create a search pattern for all these strings to speed up a loop below +our $mode_perms_string_search = ""; +foreach my $entry (keys %mode_permission_string_types) { + $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); + $mode_perms_string_search .= $entry; +} + our $allowed_asm_includes = qr{(?x: irq| memory| @@ -598,6 +629,29 @@ if ($codespell) { $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; +my $const_structs = ""; +if (open(my $conststructs, '<', $conststructsfile)) { + while (<$conststructs>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + if ($line =~ /\s/) { + print("$conststructsfile: '$line' invalid - ignored\n"); + next; + } + + $const_structs .= '|' if ($const_structs ne ""); + $const_structs .= $line; + } + close($conststructsfile); +} else { + warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; +} + sub build_types { my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; @@ -704,6 +758,16 @@ sub seed_camelcase_file { } } +sub is_maintained_obsolete { + my ($filename) = @_; + + return 0 if (!(-e "$root/scripts/get_maintainer.pl")); + + my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; + + return $status =~ /obsolete/i; +} + my $camelcase_seeded = 0; sub seed_camelcase_includes { return if ($camelcase_seeded); @@ -2289,6 +2353,10 @@ sub process { } if ($found_file) { + if (is_maintained_obsolete($realfile)) { + WARN("OBSOLETE", + "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); + } if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { $check = 1; } else { @@ -2939,6 +3007,30 @@ sub process { "Block comments use a trailing */ on a separate line\n" . $herecurr); } +# Block comment * alignment + if ($prevline =~ /$;[ \t]*$/ && #ends in comment + $line =~ /^\+[ \t]*$;/ && #leading comment + $rawline =~ /^\+[ \t]*\*/ && #leading * + (($prevrawline =~ /^\+.*?\/\*/ && #leading /* + $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ + $prevrawline =~ /^\+[ \t]*\*/)) { #leading * + my $oldindent; + $prevrawline =~ m@^\+([ \t]*/?)\*@; |
