diff options
author | Valentin Rothberg <valentinrothberg@gmail.com> | 2016-08-28 02:51:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-08-28 05:08:34 -0400 |
commit | ef3f55438d95f0bfc5d4730db6e59058647832e2 (patch) | |
tree | 08b622cbc214d17b0be4bb9160a820234f515d59 /scripts/checkkconfigsymbols.py | |
parent | 36c79c7face54ca10e2b57f42cfc956a53246c10 (diff) |
checkkconfigsymblos: consistent symbol terminology
'symbol' and 'feature' are used synonymously to refer to Kconfig symbols
(configs, menus, etc.). Use the term 'symbol' to have a consistent
terminology and to make the code more comprehensible.
Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'scripts/checkkconfigsymbols.py')
-rwxr-xr-x | scripts/checkkconfigsymbols.py | 134 |
1 files changed, 67 insertions, 67 deletions
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index 4111746b5110..4b54aa342ac9 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py | |||
@@ -20,22 +20,22 @@ from multiprocessing import Pool, cpu_count | |||
20 | 20 | ||
21 | # regex expressions | 21 | # regex expressions |
22 | OPERATORS = r"&|\(|\)|\||\!" | 22 | OPERATORS = r"&|\(|\)|\||\!" |
23 | FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}" | 23 | SYMBOL = r"(?:\w*[A-Z0-9]\w*){2,}" |
24 | DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" | 24 | DEF = r"^\s*(?:menu){,1}config\s+(" + SYMBOL + r")\s*" |
25 | EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" | 25 | EXPR = r"(?:" + OPERATORS + r"|\s|" + SYMBOL + r")+" |
26 | DEFAULT = r"default\s+.*?(?:if\s.+){,1}" | 26 | DEFAULT = r"default\s+.*?(?:if\s.+){,1}" |
27 | STMT = r"^\s*(?:if|select|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR | 27 | STMT = r"^\s*(?:if|select|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR |
28 | SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" | 28 | SOURCE_SYMBOL = r"(?:\W|\b)+[D]{,1}CONFIG_(" + SYMBOL + r")" |
29 | 29 | ||
30 | # regex objects | 30 | # regex objects |
31 | REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") | 31 | REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") |
32 | REGEX_FEATURE = re.compile(r'(?!\B)' + FEATURE + r'(?!\B)') | 32 | REGEX_SYMBOL = re.compile(r'(?!\B)' + SYMBOL + r'(?!\B)') |
33 | REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) | 33 | REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL) |
34 | REGEX_KCONFIG_DEF = re.compile(DEF) | 34 | REGEX_KCONFIG_DEF = re.compile(DEF) |
35 | REGEX_KCONFIG_EXPR = re.compile(EXPR) | 35 | REGEX_KCONFIG_EXPR = re.compile(EXPR) |
36 | REGEX_KCONFIG_STMT = re.compile(STMT) | 36 | REGEX_KCONFIG_STMT = re.compile(STMT) |
37 | REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") | 37 | REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") |
38 | REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") | 38 | REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$") |
39 | 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("(\"(.*?)\")") | 40 | REGEX_QUOTES = re.compile("(\"(.*?)\")") |
41 | 41 | ||
@@ -157,17 +157,17 @@ def main(): | |||
157 | undefined_b, defined = check_symbols(args.ignore) | 157 | undefined_b, defined = check_symbols(args.ignore) |
158 | 158 | ||
159 | # report cases that are present for the commit but not before | 159 | # report cases that are present for the commit but not before |
160 | for feature in sorted(undefined_b): | 160 | for symbol in sorted(undefined_b): |
161 | # feature has not been undefined before | 161 | # symbol has not been undefined before |
162 | if feature not in undefined_a: | 162 | if symbol not in undefined_a: |
163 | files = sorted(undefined_b.get(feature)) | 163 | files = sorted(undefined_b.get(symbol)) |
164 | undefined[feature] = files | 164 | undefined[symbol] = files |
165 | # check if there are new files that reference the undefined feature | 165 | # check if there are new files that reference the undefined symbol |
166 | else: | 166 | else: |
167 | files = sorted(undefined_b.get(feature) - | 167 | files = sorted(undefined_b.get(symbol) - |
168 | undefined_a.get(feature)) | 168 | undefined_a.get(symbol)) |
169 | if files: | 169 | if files: |
170 | undefined[feature] = files | 170 | undefined[symbol] = files |
171 | 171 | ||
172 | # reset to head | 172 | # reset to head |
173 | execute("git reset --hard %s" % head) | 173 | execute("git reset --hard %s" % head) |
@@ -177,13 +177,13 @@ def main(): | |||
177 | undefined, defined = check_symbols(args.ignore) | 177 | undefined, defined = check_symbols(args.ignore) |
178 | 178 | ||
179 | # now print the output | 179 | # now print the output |
180 | for feature in sorted(undefined): | 180 | for symbol in sorted(undefined): |
181 | print(red(feature)) | 181 | print(red(symbol)) |
182 | 182 | ||
183 | files = sorted(undefined.get(feature)) | 183 | files = sorted(undefined.get(symbol)) |
184 | print("%s: %s" % (yel("Referencing files"), ", ".join(files))) | 184 | print("%s: %s" % (yel("Referencing files"), ", ".join(files))) |
185 | 185 | ||
186 | sims = find_sims(feature, args.ignore, defined) | 186 | sims = find_sims(symbol, args.ignore, defined) |
187 | sims_out = yel("Similar symbols") | 187 | sims_out = yel("Similar symbols") |
188 | if sims: | 188 | if sims: |
189 | print("%s: %s" % (sims_out, ', '.join(sims))) | 189 | print("%s: %s" % (sims_out, ', '.join(sims))) |
@@ -192,7 +192,7 @@ def main(): | |||
192 | 192 | ||
193 | if args.find: | 193 | if args.find: |
194 | print("%s:" % yel("Commits changing symbol")) | 194 | print("%s:" % yel("Commits changing symbol")) |
195 | commits = find_commits(feature, args.diff) | 195 | commits = find_commits(symbol, args.diff) |
196 | if commits: | 196 | if commits: |
197 | for commit in commits: | 197 | for commit in commits: |
198 | commit = commit.split(" ", 1) | 198 | commit = commit.split(" ", 1) |
@@ -317,8 +317,8 @@ def check_symbols_helper(pool, ignore): | |||
317 | check_symbols() in order to properly terminate running worker processes.""" | 317 | check_symbols() in order to properly terminate running worker processes.""" |
318 | source_files = [] | 318 | source_files = [] |
319 | kconfig_files = [] | 319 | kconfig_files = [] |
320 | defined_features = [] | 320 | defined_symbols = [] |
321 | referenced_features = dict() # {file: [features]} | 321 | referenced_symbols = dict() # {file: [symbols]} |
322 | 322 | ||
323 | for gitfile in get_files(): | 323 | for gitfile in get_files(): |
324 | if REGEX_FILE_KCONFIG.match(gitfile): | 324 | if REGEX_FILE_KCONFIG.match(gitfile): |
@@ -332,51 +332,51 @@ def check_symbols_helper(pool, ignore): | |||
332 | # parse source files | 332 | # parse source files |
333 | arglist = partition(source_files, cpu_count()) | 333 | arglist = partition(source_files, cpu_count()) |
334 | for res in pool.map(parse_source_files, arglist): | 334 | for res in pool.map(parse_source_files, arglist): |
335 | referenced_features.update(res) | 335 | referenced_symbols.update(res) |
336 | 336 | ||
337 | # parse kconfig files | 337 | # parse kconfig files |
338 | arglist = [] | 338 | arglist = [] |
339 | for part in partition(kconfig_files, cpu_count()): | 339 | for part in partition(kconfig_files, cpu_count()): |
340 | arglist.append((part, ignore)) | 340 | arglist.append((part, ignore)) |
341 | for res in pool.map(parse_kconfig_files, arglist): | 341 | for res in pool.map(parse_kconfig_files, arglist): |
342 | defined_features.extend(res[0]) | 342 | defined_symbols.extend(res[0]) |
343 | referenced_features.update(res[1]) | 343 | referenced_symbols.update(res[1]) |
344 | defined_features = set(defined_features) | 344 | defined_symbols = set(defined_symbols) |
345 | 345 | ||
346 | # inverse mapping of referenced_features to dict(feature: [files]) | 346 | # inverse mapping of referenced_symbols to dict(symbol: [files]) |
347 | inv_map = dict() | 347 | inv_map = dict() |
348 | for _file, features in referenced_features.items(): | 348 | for _file, symbols in referenced_symbols.items(): |
349 | for feature in features: | 349 | for symbol in symbols: |
350 | inv_map[feature] = inv_map.get(feature, set()) | 350 | inv_map[symbol] = inv_map.get(symbol, set()) |
351 | inv_map[feature].add(_file) | 351 | inv_map[symbol].add(_file) |
352 | referenced_features = inv_map | 352 | referenced_symbols = inv_map |
353 | 353 | ||
354 | undefined = {} # {feature: [files]} | 354 | undefined = {} # {symbol: [files]} |
355 | for feature in sorted(referenced_features): | 355 | for symbol in sorted(referenced_symbols): |
356 | # filter some false positives | 356 | # filter some false positives |
357 | if feature == "FOO" or feature == "BAR" or \ | 357 | if symbol == "FOO" or symbol == "BAR" or \ |
358 | feature == "FOO_BAR" or feature == "XXX": | 358 | symbol == "FOO_BAR" or symbol == "XXX": |
359 | continue | 359 | continue |
360 | if feature not in defined_features: | 360 | if symbol not in defined_symbols: |
361 | if feature.endswith("_MODULE"): | 361 | if symbol.endswith("_MODULE"): |
362 | # avoid false positives for kernel modules | 362 | # avoid false positives for kernel modules |
363 | if feature[:-len("_MODULE")] in defined_features: | 363 | if symbol[:-len("_MODULE")] in defined_symbols: |
364 | continue | 364 | continue |
365 | undefined[feature] = referenced_features.get(feature) | 365 | undefined[symbol] = referenced_symbols.get(symbol) |
366 | return undefined, defined_features | 366 | return undefined, defined_symbols |
367 | 367 | ||
368 | 368 | ||
369 | def parse_source_files(source_files): | 369 | def parse_source_files(source_files): |
370 | """Parse each source file in @source_files and return dictionary with source | 370 | """Parse each source file in @source_files and return dictionary with source |
371 | files as keys and lists of references Kconfig symbols as values.""" | 371 | files as keys and lists of references Kconfig symbols as values.""" |
372 | referenced_features = dict() | 372 | referenced_symbols = dict() |
373 | for sfile in source_files: | 373 | for sfile in source_files: |
374 | referenced_features[sfile] = parse_source_file(sfile) | 374 | referenced_symbols[sfile] = parse_source_file(sfile) |
375 | return referenced_features | 375 | return referenced_symbols |
376 | 376 | ||
377 | 377 | ||
378 | def parse_source_file(sfile): | 378 | def parse_source_file(sfile): |
379 | """Parse @sfile and return a list of referenced Kconfig features.""" | 379 | """Parse @sfile and return a list of referenced Kconfig symbols.""" |
380 | lines = [] | 380 | lines = [] |
381 | references = [] | 381 | references = [] |
382 | 382 | ||
@@ -389,18 +389,18 @@ def parse_source_file(sfile): | |||
389 | for line in lines: | 389 | for line in lines: |
390 | if "CONFIG_" not in line: | 390 | if "CONFIG_" not in line: |
391 | continue | 391 | continue |
392 | features = REGEX_SOURCE_FEATURE.findall(line) | 392 | symbols = REGEX_SOURCE_SYMBOL.findall(line) |
393 | for feature in features: | 393 | for symbol in symbols: |
394 | if not REGEX_FILTER_FEATURES.search(feature): | 394 | if not REGEX_FILTER_SYMBOLS.search(symbol): |
395 | continue | 395 | continue |
396 | references.append(feature) | 396 | references.append(symbol) |
397 | 397 | ||
398 | return references | 398 | return references |
399 | 399 | ||
400 | 400 | ||
401 | def get_features_in_line(line): | 401 | def get_symbols_in_line(line): |
402 | """Return mentioned Kconfig features in @line.""" | 402 | """Return mentioned Kconfig symbols in @line.""" |
403 | return REGEX_FEATURE.findall(line) | 403 | return REGEX_SYMBOL.findall(line) |
404 | 404 | ||
405 | 405 | ||
406 | def parse_kconfig_files(args): | 406 | def parse_kconfig_files(args): |
@@ -409,21 +409,21 @@ def parse_kconfig_files(args): | |||
409 | pattern.""" | 409 | pattern.""" |
410 | kconfig_files = args[0] | 410 | kconfig_files = args[0] |
411 | ignore = args[1] | 411 | ignore = args[1] |
412 | defined_features = [] | 412 | defined_symbols = [] |
413 | referenced_features = dict() | 413 | referenced_symbols = dict() |
414 | 414 | ||
415 | for kfile in kconfig_files: | 415 | for kfile in kconfig_files: |
416 | defined, references = parse_kconfig_file(kfile) | 416 | defined, references = parse_kconfig_file(kfile) |
417 | defined_features.extend(defined) | 417 | defined_symbols.extend(defined) |
418 | if ignore and re.match(ignore, kfile): | 418 | if ignore and re.match(ignore, kfile): |
419 | # do not collect references for files that match the ignore pattern | 419 | # do not collect references for files that match the ignore pattern |
420 | continue | 420 | continue |
421 | referenced_features[kfile] = references | 421 | referenced_symbols[kfile] = references |
422 | return (defined_features, referenced_features) | 422 | return (defined_symbols, referenced_symbols) |
423 | 423 | ||
424 | 424 | ||
425 | def parse_kconfig_file(kfile): | 425 | def parse_kconfig_file(kfile): |
426 | """Parse @kfile and update feature definitions and references.""" | 426 | """Parse @kfile and update symbol definitions and references.""" |
427 | lines = [] | 427 | lines = [] |
428 | defined = [] | 428 | defined = [] |
429 | references = [] | 429 | references = [] |
@@ -441,8 +441,8 @@ def parse_kconfig_file(kfile): | |||
441 | line = line.split("#")[0] # ignore comments | 441 | line = line.split("#")[0] # ignore comments |
442 | 442 | ||
443 | if REGEX_KCONFIG_DEF.match(line): | 443 | if REGEX_KCONFIG_DEF.match(line): |
444 | feature_def = REGEX_KCONFIG_DEF.findall(line) | 444 | symbol_def = REGEX_KCONFIG_DEF.findall(line) |
445 | defined.append(feature_def[0]) | 445 | defined.append(symbol_def[0]) |
446 | skip = False | 446 | skip = False |
447 | elif REGEX_KCONFIG_HELP.match(line): | 447 | elif REGEX_KCONFIG_HELP.match(line): |
448 | skip = True | 448 | skip = True |
@@ -451,18 +451,18 @@ def parse_kconfig_file(kfile): | |||
451 | pass | 451 | pass |
452 | elif REGEX_KCONFIG_STMT.match(line): | 452 | elif REGEX_KCONFIG_STMT.match(line): |
453 | line = REGEX_QUOTES.sub("", line) | 453 | line = REGEX_QUOTES.sub("", line) |
454 | features = get_features_in_line(line) | 454 | symbols = get_symbols_in_line(line) |
455 | # multi-line statements | 455 | # multi-line statements |
456 | while line.endswith("\\"): | 456 | while line.endswith("\\"): |
457 | i += 1 | 457 | i += 1 |
458 | line = lines[i] | 458 | line = lines[i] |
459 | line = line.strip('\n') | 459 | line = line.strip('\n') |
460 | features.extend(get_features_in_line(line)) | 460 | symbols.extend(get_symbols_in_line(line)) |
461 | for feature in set(features): | 461 | for symbol in set(symbols): |
462 | if REGEX_NUMERIC.match(feature): | 462 | if REGEX_NUMERIC.match(symbol): |
463 | # ignore numeric values | 463 | # ignore numeric values |
464 | continue | 464 | continue |
465 | references.append(feature) | 465 | references.append(symbol) |
466 | 466 | ||
467 | return defined, references | 467 | return defined, references |
468 | 468 | ||