diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-21 19:42:58 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-21 19:42:58 +0300 |
commit | 1fc149933fd49a5b0e7738dc0853dbfbac4ae0e1 (patch) | |
tree | dfe99751c21aaf39e49765379d0b9b32114c757d /scripts | |
parent | 41d5e08ea86af3359239d5a6f7021cdc61beaa49 (diff) | |
parent | ea5505fabd3b59608750bfd3721d0f8bc5c8b0bb (diff) | |
download | linux-1fc149933fd49a5b0e7738dc0853dbfbac4ae0e1.tar.xz |
Merge tag 'char-misc-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here's the big char/misc driver patchset for 4.1-rc1.
Lots of different driver subsystem updates here, nothing major, full
details are in the shortlog.
All of this has been in linux-next for a while"
* tag 'char-misc-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (133 commits)
mei: trace: remove unused TRACE_SYSTEM_STRING
DTS: ARM: OMAP3-N900: Add lis3lv02d support
Documentation: DT: lis302: update wakeup binding
lis3lv02d: DT: add wakeup unit 2 and wakeup threshold
lis3lv02d: DT: use s32 to support negative values
Drivers: hv: hv_balloon: correctly handle num_pages>INT_MAX case
Drivers: hv: hv_balloon: correctly handle val.freeram<num_pages case
mei: replace check for connection instead of transitioning
mei: use mei_cl_is_connected consistently
mei: fix mei_poll operation
hv_vmbus: Add gradually increased delay for retries in vmbus_post_msg()
Drivers: hv: hv_balloon: survive ballooning request with num_pages=0
Drivers: hv: hv_balloon: eliminate jumps in piecewiese linear floor function
Drivers: hv: hv_balloon: do not online pages in offline blocks
hv: remove the per-channel workqueue
hv: don't schedule new works in vmbus_onoffer()/vmbus_onoffer_rescind()
hv: run non-blocking message handlers in the dispatch tasklet
coresight: moving to new "hwtracing" directory
coresight-tmc: Adding a status interface to sysfs
coresight: remove the unnecessary configuration coresight-default-sink
...
Diffstat (limited to 'scripts')
-rwxr-xr-x[-rw-r--r--] | scripts/checkkconfigsymbols.py | 147 |
1 files changed, 138 insertions, 9 deletions
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index e9cc689033fe..74086a583d8d 100644..100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -1,8 +1,8 @@ #!/usr/bin/env python -"""Find Kconfig identifiers that are referenced but not defined.""" +"""Find Kconfig symbols that are referenced but not defined.""" -# (c) 2014 Valentin Rothberg <valentinrothberg@gmail.com> +# (c) 2014-2015 Valentin Rothberg <Valentin.Rothberg@lip6.fr> # (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de> # # Licensed under the terms of the GNU GPL License version 2 @@ -10,7 +10,9 @@ import os import re +import sys from subprocess import Popen, PIPE, STDOUT +from optparse import OptionParser # regex expressions @@ -32,22 +34,149 @@ REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") +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('', '--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: + sys.exit("Please specify only one option at once.") + + if opts.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", opts.diff): + sys.exit("Please specify valid input in the following format: " + "\'commmit1..commit2\'") + + if opts.commit or opts.diff: + if not opts.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. " + " Please run this script in a clean Git tree or pass " + "'--force' if you\nwant to ignore this warning and " + "continue.") + + return opts + + def main(): """Main function of this module.""" + opts = parse_options() + + if opts.commit or opts.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("..") + 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() + + # get undefined items for the commit + execute("git reset --hard %s" % commit_b) + undefined_b = check_symbols() + + # 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)) + print "%s\t%s" % (feature, ", ".join(files)) + # check if there are new files that reference the undefined feature + else: + files = sorted(undefined_b.get(feature) - + undefined_a.get(feature)) + if files: + print "%s\t%s" % (feature, ", ".join(files)) + + # reset to head + execute("git reset --hard %s" % head) + + # default to check the entire tree + else: + undefined = check_symbols() + for feature in sorted(undefined): + files = sorted(undefined.get(feature)) + print "%s\t%s" % (feature, ", ".join(files)) + + +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) + return stdout + + +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") + for line in stdout: + if re.findall(r"[URMADC]{1}", line[:2]): + return True + return False + + +def get_head(): + """Return commit hash of current HEAD.""" + stdout = execute("git rev-parse HEAD") + return stdout.strip('\n') + + +def check_symbols(): + """Find undefined Kconfig symbols and return a dict with the symbol as key + and a list of referencing files as value.""" source_files = [] kconfig_files = [] defined_features = set() referenced_features = dict() # {feature: [files]} # use 'git ls-files' to get the worklist - pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True) - (stdout, _) = pop.communicate() # wait until finished + stdout = execute("git ls-files") if len(stdout) > 0 and stdout[-1] == "\n": stdout = stdout[:-1] for gitfile in stdout.rsplit("\n"): - if ".git" in gitfile or "ChangeLog" in gitfile or \ - ".log" in gitfile or os.path.isdir(gitfile): + if ".git" in gitfile or "ChangeLog" in gitfile or \ + ".log" in gitfile or os.path.isdir(gitfile) or \ + gitfile.startswith("tools/"): continue if REGEX_FILE_KCONFIG.match(gitfile): kconfig_files.append(gitfile) @@ -61,7 +190,7 @@ def main(): for kfile in kconfig_files: parse_kconfig_file(kfile, defined_features, referenced_features) - print "Undefined symbol used\tFile list" + undefined = {} # {feature: [files]} for feature in sorted(referenced_features): # filter some false positives if feature == "FOO" or feature == "BAR" or \ @@ -72,8 +201,8 @@ def main(): # avoid false positives for kernel modules if feature[:-len("_MODULE")] in defined_features: continue - files = referenced_features.get(feature) - print "%s\t%s" % (feature, ", ".join(files)) + undefined[feature] = referenced_features.get(feature) + return undefined def parse_source_file(sfile, referenced_features): |