diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 13:23:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 13:23:36 -0500 |
commit | 4c257ec37bc365614933c7f0a7fe9b0688dfd1e7 (patch) | |
tree | 37df4c3e0e963df9b87729c19f7c337e2f53008e /scripts | |
parent | 39272dde8ffcfd1322209e05f3f8fa4d14f796de (diff) | |
parent | ed6dc538e5a36a331b6256d54f435c80f6715460 (diff) |
Merge tag 'char-misc-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc updates from Greg KH:
"Here's the big set of char/misc patches for 4.5-rc1.
Nothing major, lots of different driver subsystem updates, full
details in the shortlog. All of these have been in linux-next for a
while"
* tag 'char-misc-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (71 commits)
mei: fix fasync return value on error
parport: avoid assignment in if
parport: remove unneeded space
parport: change style of NULL comparison
parport: remove unnecessary out of memory message
parport: remove braces
parport: quoted strings should not be split
parport: code indent should use tabs
parport: fix coding style
parport: EXPORT_SYMBOL should follow function
parport: remove trailing white space
parport: fix a trivial typo
coresight: Fix a typo in Kconfig
coresight: checking for NULL string in coresight_name_match()
Drivers: hv: vmbus: Treat Fibre Channel devices as performance critical
Drivers: hv: utils: fix hvt_op_poll() return value on transport destroy
Drivers: hv: vmbus: fix the building warning with hyperv-keyboard
extcon: add Maxim MAX3355 driver
Drivers: hv: ring_buffer: eliminate hv_ringbuffer_peek()
Drivers: hv: remove code duplication between vmbus_recvpacket()/vmbus_recvpacket_raw()
...
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/checkkconfigsymbols.py | 234 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 2 |
2 files changed, 187 insertions, 49 deletions
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index 2f4b7ffd5570..d8f6c094cce5 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py | |||
@@ -8,11 +8,14 @@ | |||
8 | # Licensed under the terms of the GNU GPL License version 2 | 8 | # Licensed under the terms of the GNU GPL License version 2 |
9 | 9 | ||
10 | 10 | ||
11 | import difflib | ||
11 | import os | 12 | import os |
12 | import re | 13 | import re |
14 | import signal | ||
13 | import sys | 15 | import sys |
14 | from subprocess import Popen, PIPE, STDOUT | 16 | from multiprocessing import Pool, cpu_count |
15 | from optparse import OptionParser | 17 | from optparse import OptionParser |
18 | from subprocess import Popen, PIPE, STDOUT | ||
16 | 19 | ||
17 | 20 | ||
18 | # regex expressions | 21 | # regex expressions |
@@ -26,7 +29,7 @@ SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" | |||
26 | 29 | ||
27 | # regex objects | 30 | # regex objects |
28 | REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") | 31 | REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") |
29 | REGEX_FEATURE = re.compile(r'(?!\B"[^"]*)' + FEATURE + r'(?![^"]*"\B)') | 32 | REGEX_FEATURE = re.compile(r'(?!\B)' + FEATURE + r'(?!\B)') |
30 | REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) | 33 | REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) |
31 | REGEX_KCONFIG_DEF = re.compile(DEF) | 34 | REGEX_KCONFIG_DEF = re.compile(DEF) |
32 | REGEX_KCONFIG_EXPR = re.compile(EXPR) | 35 | REGEX_KCONFIG_EXPR = re.compile(EXPR) |
@@ -34,6 +37,7 @@ REGEX_KCONFIG_STMT = re.compile(STMT) | |||
34 | REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") | 37 | REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") |
35 | REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") | 38 | REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") |
36 | REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+") | 39 | REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+") |
40 | REGEX_QUOTES = re.compile("(\"(.*?)\")") | ||
37 | 41 | ||
38 | 42 | ||
39 | def parse_options(): | 43 | def parse_options(): |
@@ -71,6 +75,9 @@ def parse_options(): | |||
71 | "the pattern needs to be a Python regex. To " | 75 | "the pattern needs to be a Python regex. To " |
72 | "ignore defconfigs, specify -i '.*defconfig'.") | 76 | "ignore defconfigs, specify -i '.*defconfig'.") |
73 | 77 | ||
78 | parser.add_option('-s', '--sim', dest='sim', action='store', default="", | ||
79 | help="Print a list of maximum 10 string-similar symbols.") | ||
80 | |||
74 | parser.add_option('', '--force', dest='force', action='store_true', | 81 | parser.add_option('', '--force', dest='force', action='store_true', |
75 | default=False, | 82 | default=False, |
76 | help="Reset current Git tree even when it's dirty.") | 83 | help="Reset current Git tree even when it's dirty.") |
@@ -109,6 +116,18 @@ def main(): | |||
109 | """Main function of this module.""" | 116 | """Main function of this module.""" |
110 | opts = parse_options() | 117 | opts = parse_options() |
111 | 118 | ||
119 | if opts.sim and not opts.commit and not opts.diff: | ||
120 | sims = find_sims(opts.sim, opts.ignore) | ||
121 | if sims: | ||
122 | print "%s: %s" % (yel("Similar symbols"), ', '.join(sims)) | ||
123 | else: | ||
124 | print "%s: no similar symbols found" % yel("Similar symbols") | ||
125 | sys.exit(0) | ||
126 | |||
127 | # dictionary of (un)defined symbols | ||
128 | defined = {} | ||
129 | undefined = {} | ||
130 | |||
112 | if opts.commit or opts.diff: | 131 | if opts.commit or opts.diff: |
113 | head = get_head() | 132 | head = get_head() |
114 | 133 | ||
@@ -127,40 +146,56 @@ def main(): | |||
127 | 146 | ||
128 | # get undefined items before the commit | 147 | # get undefined items before the commit |
129 | execute("git reset --hard %s" % commit_a) | 148 | execute("git reset --hard %s" % commit_a) |
130 | undefined_a = check_symbols(opts.ignore) | 149 | undefined_a, _ = check_symbols(opts.ignore) |
131 | 150 | ||
132 | # get undefined items for the commit | 151 | # get undefined items for the commit |
133 | execute("git reset --hard %s" % commit_b) | 152 | execute("git reset --hard %s" % commit_b) |
134 | undefined_b = check_symbols(opts.ignore) | 153 | undefined_b, defined = check_symbols(opts.ignore) |
135 | 154 | ||
136 | # report cases that are present for the commit but not before | 155 | # report cases that are present for the commit but not before |
137 | for feature in sorted(undefined_b): | 156 | for feature in sorted(undefined_b): |
138 | # feature has not been undefined before | 157 | # feature has not been undefined before |
139 | if not feature in undefined_a: | 158 | if not feature in undefined_a: |
140 | files = sorted(undefined_b.get(feature)) | 159 | files = sorted(undefined_b.get(feature)) |
141 | print "%s\t%s" % (yel(feature), ", ".join(files)) | 160 | undefined[feature] = files |
142 | if opts.find: | ||
143 | commits = find_commits(feature, opts.diff) | ||
144 | print red(commits) | ||
145 | # check if there are new files that reference the undefined feature | 161 | # check if there are new files that reference the undefined feature |
146 | else: | 162 | else: |
147 | files = sorted(undefined_b.get(feature) - | 163 | files = sorted(undefined_b.get(feature) - |
148 | undefined_a.get(feature)) | 164 | undefined_a.get(feature)) |
149 | if files: | 165 | if files: |
150 | print "%s\t%s" % (yel(feature), ", ".join(files)) | 166 | undefined[feature] = files |
151 | if opts.find: | ||
152 | commits = find_commits(feature, opts.diff) | ||
153 | print red(commits) | ||
154 | 167 | ||
155 | # reset to head | 168 | # reset to head |
156 | execute("git reset --hard %s" % head) | 169 | execute("git reset --hard %s" % head) |
157 | 170 | ||
158 | # default to check the entire tree | 171 | # default to check the entire tree |
159 | else: | 172 | else: |
160 | undefined = check_symbols(opts.ignore) | 173 | undefined, defined = check_symbols(opts.ignore) |
161 | for feature in sorted(undefined): | 174 | |
162 | files = sorted(undefined.get(feature)) | 175 | # now print the output |
163 | print "%s\t%s" % (yel(feature), ", ".join(files)) | 176 | for feature in sorted(undefined): |
177 | print red(feature) | ||
178 | |||
179 | files = sorted(undefined.get(feature)) | ||
180 | print "%s: %s" % (yel("Referencing files"), ", ".join(files)) | ||
181 | |||
182 | sims = find_sims(feature, opts.ignore, defined) | ||
183 | sims_out = yel("Similar symbols") | ||
184 | if sims: | ||
185 | print "%s: %s" % (sims_out, ', '.join(sims)) | ||
186 | else: | ||
187 | print "%s: %s" % (sims_out, "no similar symbols found") | ||
188 | |||
189 | if opts.find: | ||
190 | print "%s:" % yel("Commits changing symbol") | ||
191 | commits = find_commits(feature, opts.diff) | ||
192 | if commits: | ||
193 | for commit in commits: | ||
194 | commit = commit.split(" ", 1) | ||
195 | print "\t- %s (\"%s\")" % (yel(commit[0]), commit[1]) | ||
196 | else: | ||
197 | print "\t- no commit found" | ||
198 | print # new line | ||
164 | 199 | ||
165 | 200 | ||
166 | def yel(string): | 201 | def yel(string): |
@@ -190,7 +225,7 @@ def find_commits(symbol, diff): | |||
190 | """Find commits changing %symbol in the given range of %diff.""" | 225 | """Find commits changing %symbol in the given range of %diff.""" |
191 | commits = execute("git log --pretty=oneline --abbrev-commit -G %s %s" | 226 | commits = execute("git log --pretty=oneline --abbrev-commit -G %s %s" |
192 | % (symbol, diff)) | 227 | % (symbol, diff)) |
193 | return commits | 228 | return [x for x in commits.split("\n") if x] |
194 | 229 | ||
195 | 230 | ||
196 | def tree_is_dirty(): | 231 | def tree_is_dirty(): |
@@ -209,43 +244,107 @@ def get_head(): | |||
209 | return stdout.strip('\n') | 244 | return stdout.strip('\n') |
210 | 245 | ||
211 | 246 | ||
212 | def check_symbols(ignore): | 247 | def partition(lst, size): |
213 | """Find undefined Kconfig symbols and return a dict with the symbol as key | 248 | """Partition list @lst into eveni-sized lists of size @size.""" |
214 | and a list of referencing files as value. Files matching %ignore are not | 249 | return [lst[i::size] for i in xrange(size)] |
215 | checked for undefined symbols.""" | 250 | |
216 | source_files = [] | 251 | |
217 | kconfig_files = [] | 252 | def init_worker(): |
218 | defined_features = set() | 253 | """Set signal handler to ignore SIGINT.""" |
219 | referenced_features = dict() # {feature: [files]} | 254 | signal.signal(signal.SIGINT, signal.SIG_IGN) |
255 | |||
256 | |||
257 | def find_sims(symbol, ignore, defined = []): | ||
258 | """Return a list of max. ten Kconfig symbols that are string-similar to | ||
259 | @symbol.""" | ||
260 | if defined: | ||
261 | return sorted(difflib.get_close_matches(symbol, set(defined), 10)) | ||
262 | |||
263 | pool = Pool(cpu_count(), init_worker) | ||
264 | kfiles = [] | ||
265 | for gitfile in get_files(): | ||
266 | if REGEX_FILE_KCONFIG.match(gitfile): | ||
267 | kfiles.append(gitfile) | ||
220 | 268 | ||
269 | arglist = [] | ||
270 | for part in partition(kfiles, cpu_count()): | ||
271 | arglist.append((part, ignore)) | ||
272 | |||
273 | for res in pool.map(parse_kconfig_files, arglist): | ||
274 | defined.extend(res[0]) | ||
275 | |||
276 | return sorted(difflib.get_close_matches(symbol, set(defined), 10)) | ||
277 | |||
278 | |||
279 | def get_files(): | ||
280 | """Return a list of all files in the current git directory.""" | ||
221 | # use 'git ls-files' to get the worklist | 281 | # use 'git ls-files' to get the worklist |
222 | stdout = execute("git ls-files") | 282 | stdout = execute("git ls-files") |
223 | if len(stdout) > 0 and stdout[-1] == "\n": | 283 | if len(stdout) > 0 and stdout[-1] == "\n": |
224 | stdout = stdout[:-1] | 284 | stdout = stdout[:-1] |
225 | 285 | ||
286 | files = [] | ||
226 | for gitfile in stdout.rsplit("\n"): | 287 | for gitfile in stdout.rsplit("\n"): |
227 | if ".git" in gitfile or "ChangeLog" in gitfile or \ | 288 | if ".git" in gitfile or "ChangeLog" in gitfile or \ |
228 | ".log" in gitfile or os.path.isdir(gitfile) or \ | 289 | ".log" in gitfile or os.path.isdir(gitfile) or \ |
229 | gitfile.startswith("tools/"): | 290 | gitfile.startswith("tools/"): |
230 | continue | 291 | continue |
292 | files.append(gitfile) | ||
293 | return files | ||
294 | |||
295 | |||
296 | def check_symbols(ignore): | ||
297 | """Find undefined Kconfig symbols and return a dict with the symbol as key | ||
298 | and a list of referencing files as value. Files matching %ignore are not | ||
299 | checked for undefined symbols.""" | ||
300 | pool = Pool(cpu_count(), init_worker) | ||
301 | try: | ||
302 | return check_symbols_helper(pool, ignore) | ||
303 | except KeyboardInterrupt: | ||
304 | pool.terminate() | ||
305 | pool.join() | ||
306 | sys.exit(1) | ||
307 | |||
308 | |||
309 | def check_symbols_helper(pool, ignore): | ||
310 | """Helper method for check_symbols(). Used to catch keyboard interrupts in | ||
311 | check_symbols() in order to properly terminate running worker processes.""" | ||
312 | source_files = [] | ||
313 | kconfig_files = [] | ||
314 | defined_features = [] | ||
315 | referenced_features = dict() # {file: [features]} | ||
316 | |||
317 | for gitfile in get_files(): | ||
231 | if REGEX_FILE_KCONFIG.match(gitfile): | 318 | if REGEX_FILE_KCONFIG.match(gitfile): |
232 | kconfig_files.append(gitfile) | 319 | kconfig_files.append(gitfile) |
233 | else: | 320 | else: |
234 | # all non-Kconfig files are checked for consistency | 321 | if ignore and not re.match(ignore, gitfile): |
322 | continue | ||
323 | # add source files that do not match the ignore pattern | ||
235 | source_files.append(gitfile) | 324 | source_files.append(gitfile) |
236 | 325 | ||
237 | for sfile in source_files: | 326 | # parse source files |
238 | if ignore and re.match(ignore, sfile): | 327 | arglist = partition(source_files, cpu_count()) |
239 | # do not check files matching %ignore | 328 | for res in pool.map(parse_source_files, arglist): |
240 | continue | 329 | referenced_features.update(res) |
241 | parse_source_file(sfile, referenced_features) | ||
242 | 330 | ||
243 | for kfile in kconfig_files: | 331 | |
244 | if ignore and re.match(ignore, kfile): | 332 | # parse kconfig files |
245 | # do not collect references for files matching %ignore | 333 | arglist = [] |
246 | parse_kconfig_file(kfile, defined_features, dict()) | 334 | for part in partition(kconfig_files, cpu_count()): |
247 | else: | 335 | arglist.append((part, ignore)) |
248 | parse_kconfig_file(kfile, defined_features, referenced_features) | 336 | for res in pool.map(parse_kconfig_files, arglist): |
337 | defined_features.extend(res[0]) | ||
338 | referenced_features.update(res[1]) | ||
339 | defined_features = set(defined_features) | ||
340 | |||
341 | # inverse mapping of referenced_features to dict(feature: [files]) | ||
342 | inv_map = dict() | ||
343 | for _file, features in referenced_features.iteritems(): | ||
344 | for feature in features: | ||
345 | inv_map[feature] = inv_map.get(feature, set()) | ||
346 | inv_map[feature].add(_file) | ||
347 | referenced_features = inv_map | ||
249 | 348 | ||
250 | undefined = {} # {feature: [files]} | 349 | undefined = {} # {feature: [files]} |
251 | for feature in sorted(referenced_features): | 350 | for feature in sorted(referenced_features): |
@@ -259,12 +358,26 @@ def check_symbols(ignore): | |||
259 | if feature[:-len("_MODULE")] in defined_features: | 358 | if feature[:-len("_MODULE")] in defined_features: |
260 | continue | 359 | continue |
261 | undefined[feature] = referenced_features.get(feature) | 360 | undefined[feature] = referenced_features.get(feature) |
262 | return undefined | 361 | return undefined, defined_features |
263 | 362 | ||
264 | 363 | ||
265 | def parse_source_file(sfile, referenced_features): | 364 | def parse_source_files(source_files): |
266 | """Parse @sfile for referenced Kconfig features.""" | 365 | """Parse each source file in @source_files and return dictionary with source |
366 | files as keys and lists of references Kconfig symbols as values.""" | ||
367 | referenced_features = dict() | ||
368 | for sfile in source_files: | ||
369 | referenced_features[sfile] = parse_source_file(sfile) | ||
370 | return referenced_features | ||
371 | |||
372 | |||
373 | def parse_source_file(sfile): | ||
374 | """Parse @sfile and return a list of referenced Kconfig features.""" | ||
267 | lines = [] | 375 | lines = [] |
376 | references = [] | ||
377 | |||
378 | if not os.path.exists(sfile): | ||
379 | return references | ||
380 | |||
268 | with open(sfile, "r") as stream: | 381 | with open(sfile, "r") as stream: |
269 | lines = stream.readlines() | 382 | lines = stream.readlines() |
270 | 383 | ||
@@ -275,9 +388,9 @@ def parse_source_file(sfile, referenced_features): | |||
275 | for feature in features: | 388 | for feature in features: |
276 | if not REGEX_FILTER_FEATURES.search(feature): | 389 | if not REGEX_FILTER_FEATURES.search(feature): |
277 | continue | 390 | continue |
278 | sfiles = referenced_features.get(feature, set()) | 391 | references.append(feature) |
279 | sfiles.add(sfile) | 392 | |
280 | referenced_features[feature] = sfiles | 393 | return references |
281 | 394 | ||
282 | 395 | ||
283 | def get_features_in_line(line): | 396 | def get_features_in_line(line): |
@@ -285,11 +398,35 @@ def get_features_in_line(line): | |||
285 | return REGEX_FEATURE.findall(line) | 398 | return REGEX_FEATURE.findall(line) |
286 | 399 | ||
287 | 400 | ||
288 | def parse_kconfig_file(kfile, defined_features, referenced_features): | 401 | def parse_kconfig_files(args): |
402 | """Parse kconfig files and return tuple of defined and references Kconfig | ||
403 | symbols. Note, @args is a tuple of a list of files and the @ignore | ||
404 | pattern.""" | ||
405 | kconfig_files = args[0] | ||
406 | ignore = args[1] | ||
407 | defined_features = [] | ||
408 | referenced_features = dict() | ||
409 | |||
410 | for kfile in kconfig_files: | ||
411 | defined, references = parse_kconfig_file(kfile) | ||
412 | defined_features.extend(defined) | ||
413 | if ignore and re.match(ignore, kfile): | ||
414 | # do not collect references for files that match the ignore pattern | ||
415 | continue | ||
416 | referenced_features[kfile] = references | ||
417 | return (defined_features, referenced_features) | ||
418 | |||
419 | |||
420 | def parse_kconfig_file(kfile): | ||
289 | """Parse @kfile and update feature definitions and references.""" | 421 | """Parse @kfile and update feature definitions and references.""" |
290 | lines = [] | 422 | lines = [] |
423 | defined = [] | ||
424 | references = [] | ||
291 | skip = False | 425 | skip = False |
292 | 426 | ||
427 | if not os.path.exists(kfile): | ||
428 | return defined, references | ||
429 | |||
293 | with open(kfile, "r") as stream: | 430 | with open(kfile, "r") as stream: |
294 | lines = stream.readlines() | 431 | lines = stream.readlines() |
295 | 432 | ||
@@ -300,7 +437,7 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): | |||
300 | 437 | ||
301 | if REGEX_KCONFIG_DEF.match(line): | 438 | if REGEX_KCONFIG_DEF.match(line): |
302 | feature_def = REGEX_KCONFIG_DEF.findall(line) | 439 | feature_def = REGEX_KCONFIG_DEF.findall(line) |
303 | defined_features.add(feature_def[0]) | 440 | defined.append(feature_def[0]) |
304 | skip = False | 441 | skip = False |
305 | elif REGEX_KCONFIG_HELP.match(line): | 442 | elif REGEX_KCONFIG_HELP.match(line): |
306 | skip = True | 443 | skip = True |
@@ -308,6 +445,7 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): | |||
308 | # ignore content of help messages | 445 | # ignore content of help messages |
309 | pass | 446 | pass |
310 | elif REGEX_KCONFIG_STMT.match(line): | 447 | elif REGEX_KCONFIG_STMT.match(line): |
448 | line = REGEX_QUOTES.sub("", line) | ||
311 | features = get_features_in_line(line) | 449 | features = get_features_in_line(line) |
312 | # multi-line statements | 450 | # multi-line statements |
313 | while line.endswith("\\"): | 451 | while line.endswith("\\"): |
@@ -319,9 +457,9 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): | |||
319 | if REGEX_NUMERIC.match(feature): | 457 | if REGEX_NUMERIC.match(feature): |
320 | # ignore numeric values | 458 | # ignore numeric values |
321 | continue | 459 | continue |
322 | paths = referenced_features.get(feature, set()) | 460 | references.append(feature) |
323 | paths.add(kfile) | 461 | |
324 | referenced_features[feature] = paths | 462 | return defined, references |
325 | 463 | ||
326 | 464 | ||
327 | if __name__ == "__main__": | 465 | if __name__ == "__main__": |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5b96206e9aab..8adca4406198 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -917,7 +917,7 @@ static int do_vmbus_entry(const char *filename, void *symval, | |||
917 | char guid_name[(sizeof(*guid) + 1) * 2]; | 917 | char guid_name[(sizeof(*guid) + 1) * 2]; |
918 | 918 | ||
919 | for (i = 0; i < (sizeof(*guid) * 2); i += 2) | 919 | for (i = 0; i < (sizeof(*guid) * 2); i += 2) |
920 | sprintf(&guid_name[i], "%02x", TO_NATIVE((*guid)[i/2])); | 920 | sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); |
921 | 921 | ||
922 | strcpy(alias, "vmbus:"); | 922 | strcpy(alias, "vmbus:"); |
923 | strcat(alias, guid_name); | 923 | strcat(alias, guid_name); |