diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 19:43:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 19:43:47 -0500 |
commit | 6ae840e7cc4be0be3aa40d9f67c35c75cfc67d83 (patch) | |
tree | 9c83c87a8670ef678d95f8d6f76a07f24a09a49f /scripts | |
parent | e6b5be2be4e30037eb551e0ed09dd97bd00d85d3 (diff) | |
parent | 91905b6f4afe51e23a3f58df93e4cdc5e49cf40c (diff) |
Merge tag 'char-misc-3.19-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 update for 3.19-rc1
Lots of little things all over the place in different drivers, and a
new subsystem, "coresight" has been added. Full details are in the
shortlog"
* tag 'char-misc-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (73 commits)
parport: parport_pc, do not remove parent devices early
spmi: Remove shutdown/suspend/resume kernel-doc
carma-fpga-program: drop videobuf dependency
carma-fpga: drop videobuf dependency
carma-fpga-program.c: fix compile errors
i8k: Fix temperature bug handling in i8k_get_temp()
cxl: Name interrupts in /proc/interrupt
CXL: Return error to PSL if IRQ demultiplexing fails & print clearer warning
coresight-replicator: remove .owner field for driver
coresight: fixed comments in coresight.h
coresight: fix typo in comment in coresight-priv.h
coresight: bindings for coresight drivers
coresight: Adding ABI documentation
w1: support auto-load of w1_bq27000 module.
w1: avoid potential u16 overflow
cn: verify msg->len before making callback
mei: export fw status registers through sysfs
mei: read and print all six FW status registers
mei: txe: add cherrytrail device id
mei: kill cached host and me csr values
...
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/checkkconfigsymbols.py | 139 | ||||
-rwxr-xr-x | scripts/checkkconfigsymbols.sh | 59 |
2 files changed, 139 insertions, 59 deletions
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py new file mode 100644 index 000000000000..e9cc689033fe --- /dev/null +++ b/scripts/checkkconfigsymbols.py | |||
@@ -0,0 +1,139 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | """Find Kconfig identifiers that are referenced but not defined.""" | ||
4 | |||
5 | # (c) 2014 Valentin Rothberg <valentinrothberg@gmail.com> | ||
6 | # (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de> | ||
7 | # | ||
8 | # Licensed under the terms of the GNU GPL License version 2 | ||
9 | |||
10 | |||
11 | import os | ||
12 | import re | ||
13 | from subprocess import Popen, PIPE, STDOUT | ||
14 | |||
15 | |||
16 | # regex expressions | ||
17 | OPERATORS = r"&|\(|\)|\||\!" | ||
18 | FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}" | ||
19 | DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" | ||
20 | EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" | ||
21 | STMT = r"^\s*(?:if|select|depends\s+on)\s+" + EXPR | ||
22 | SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" | ||
23 | |||
24 | # regex objects | ||
25 | REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") | ||
26 | REGEX_FEATURE = re.compile(r"(" + FEATURE + r")") | ||
27 | REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) | ||
28 | REGEX_KCONFIG_DEF = re.compile(DEF) | ||
29 | REGEX_KCONFIG_EXPR = re.compile(EXPR) | ||
30 | REGEX_KCONFIG_STMT = re.compile(STMT) | ||
31 | REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") | ||
32 | REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") | ||
33 | |||
34 | |||
35 | def main(): | ||
36 | """Main function of this module.""" | ||
37 | source_files = [] | ||
38 | kconfig_files = [] | ||
39 | defined_features = set() | ||
40 | referenced_features = dict() # {feature: [files]} | ||
41 | |||
42 | # use 'git ls-files' to get the worklist | ||
43 | pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True) | ||
44 | (stdout, _) = pop.communicate() # wait until finished | ||
45 | if len(stdout) > 0 and stdout[-1] == "\n": | ||
46 | stdout = stdout[:-1] | ||
47 | |||
48 | for gitfile in stdout.rsplit("\n"): | ||
49 | if ".git" in gitfile or "ChangeLog" in gitfile or \ | ||
50 | ".log" in gitfile or os.path.isdir(gitfile): | ||
51 | continue | ||
52 | if REGEX_FILE_KCONFIG.match(gitfile): | ||
53 | kconfig_files.append(gitfile) | ||
54 | else: | ||
55 | # all non-Kconfig files are checked for consistency | ||
56 | source_files.append(gitfile) | ||
57 | |||
58 | for sfile in source_files: | ||
59 | parse_source_file(sfile, referenced_features) | ||
60 | |||
61 | for kfile in kconfig_files: | ||
62 | parse_kconfig_file(kfile, defined_features, referenced_features) | ||
63 | |||
64 | print "Undefined symbol used\tFile list" | ||
65 | for feature in sorted(referenced_features): | ||
66 | # filter some false positives | ||
67 | if feature == "FOO" or feature == "BAR" or \ | ||
68 | feature == "FOO_BAR" or feature == "XXX": | ||
69 | continue | ||
70 | if feature not in defined_features: | ||
71 | if feature.endswith("_MODULE"): | ||
72 | # avoid false positives for kernel modules | ||
73 | if feature[:-len("_MODULE")] in defined_features: | ||
74 | continue | ||
75 | files = referenced_features.get(feature) | ||
76 | print "%s\t%s" % (feature, ", ".join(files)) | ||
77 | |||
78 | |||
79 | def parse_source_file(sfile, referenced_features): | ||
80 | """Parse @sfile for referenced Kconfig features.""" | ||
81 | lines = [] | ||
82 | with open(sfile, "r") as stream: | ||
83 | lines = stream.readlines() | ||
84 | |||
85 | for line in lines: | ||
86 | if not "CONFIG_" in line: | ||
87 | continue | ||
88 | features = REGEX_SOURCE_FEATURE.findall(line) | ||
89 | for feature in features: | ||
90 | if not REGEX_FILTER_FEATURES.search(feature): | ||
91 | continue | ||
92 | sfiles = referenced_features.get(feature, set()) | ||
93 | sfiles.add(sfile) | ||
94 | referenced_features[feature] = sfiles | ||
95 | |||
96 | |||
97 | def get_features_in_line(line): | ||
98 | """Return mentioned Kconfig features in @line.""" | ||
99 | return REGEX_FEATURE.findall(line) | ||
100 | |||
101 | |||
102 | def parse_kconfig_file(kfile, defined_features, referenced_features): | ||
103 | """Parse @kfile and update feature definitions and references.""" | ||
104 | lines = [] | ||
105 | skip = False | ||
106 | |||
107 | with open(kfile, "r") as stream: | ||
108 | lines = stream.readlines() | ||
109 | |||
110 | for i in range(len(lines)): | ||
111 | line = lines[i] | ||
112 | line = line.strip('\n') | ||
113 | line = line.split("#")[0] # ignore comments | ||
114 | |||
115 | if REGEX_KCONFIG_DEF.match(line): | ||
116 | feature_def = REGEX_KCONFIG_DEF.findall(line) | ||
117 | defined_features.add(feature_def[0]) | ||
118 | skip = False | ||
119 | elif REGEX_KCONFIG_HELP.match(line): | ||
120 | skip = True | ||
121 | elif skip: | ||
122 | # ignore content of help messages | ||
123 | pass | ||
124 | elif REGEX_KCONFIG_STMT.match(line): | ||
125 | features = get_features_in_line(line) | ||
126 | # multi-line statements | ||
127 | while line.endswith("\\"): | ||
128 | i += 1 | ||
129 | line = lines[i] | ||
130 | line = line.strip('\n') | ||
131 | features.extend(get_features_in_line(line)) | ||
132 | for feature in set(features): | ||
133 | paths = referenced_features.get(feature, set()) | ||
134 | paths.add(kfile) | ||
135 | referenced_features[feature] = paths | ||
136 | |||
137 | |||
138 | if __name__ == "__main__": | ||
139 | main() | ||
diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh deleted file mode 100755 index ccb3391882d1..000000000000 --- a/scripts/checkkconfigsymbols.sh +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | # Find Kconfig variables used in source code but never defined in Kconfig | ||
3 | # Copyright (C) 2007, Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> | ||
4 | |||
5 | # Tested with dash. | ||
6 | paths="$@" | ||
7 | [ -z "$paths" ] && paths=. | ||
8 | |||
9 | # Doing this once at the beginning saves a lot of time, on a cache-hot tree. | ||
10 | Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`" | ||
11 | |||
12 | printf "File list \tundefined symbol used\n" | ||
13 | find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i | ||
14 | do | ||
15 | # Output the bare Kconfig variable and the filename; the _MODULE part at | ||
16 | # the end is not removed here (would need perl an not-hungry regexp for that). | ||
17 | sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i | ||
18 | done | \ | ||
19 | # Smart "sort|uniq" implemented in awk and tuned to collect the names of all | ||
20 | # files which use a given symbol | ||
21 | awk '{map[$1, count[$1]++] = $2; } | ||
22 | END { | ||
23 | for (combIdx in map) { | ||
24 | split(combIdx, separate, SUBSEP); | ||
25 | # The value may have been removed. | ||
26 | if (! ( (separate[1], separate[2]) in map ) ) | ||
27 | continue; | ||
28 | symb=separate[1]; | ||
29 | printf "%s ", symb; | ||
30 | #Use gawk extension to delete the names vector | ||
31 | delete names; | ||
32 | #Portably delete the names vector | ||
33 | #split("", names); | ||
34 | for (i=0; i < count[symb]; i++) { | ||
35 | names[map[symb, i]] = 1; | ||
36 | # Unfortunately, we may still encounter symb, i in the | ||
37 | # outside iteration. | ||
38 | delete map[symb, i]; | ||
39 | } | ||
40 | i=0; | ||
41 | for (name in names) { | ||
42 | if (i > 0) | ||
43 | printf ", %s", name; | ||
44 | else | ||
45 | printf "%s", name; | ||
46 | i++; | ||
47 | } | ||
48 | printf "\n"; | ||
49 | } | ||
50 | }' | | ||
51 | while read symb files; do | ||
52 | # Remove the _MODULE suffix when checking the variable name. This should | ||
53 | # be done only on tristate symbols, actually, but Kconfig parsing is | ||
54 | # beyond the purpose of this script. | ||
55 | symb_bare=`echo $symb | sed -e 's/_MODULE//'` | ||
56 | if ! grep -q "\<$symb_bare\>" $Kconfigs; then | ||
57 | printf "$files: \t$symb\n" | ||
58 | fi | ||
59 | done|sort | ||