aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/checkkconfigsymbols.py
diff options
context:
space:
mode:
authorValentin Rothberg <valentinrothberg@gmail.com>2016-08-28 02:51:31 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-08-28 05:08:34 -0400
commitef3f55438d95f0bfc5d4730db6e59058647832e2 (patch)
tree08b622cbc214d17b0be4bb9160a820234f515d59 /scripts/checkkconfigsymbols.py
parent36c79c7face54ca10e2b57f42cfc956a53246c10 (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-xscripts/checkkconfigsymbols.py134
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
22OPERATORS = r"&|\(|\)|\||\!" 22OPERATORS = r"&|\(|\)|\||\!"
23FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}" 23SYMBOL = r"(?:\w*[A-Z0-9]\w*){2,}"
24DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" 24DEF = r"^\s*(?:menu){,1}config\s+(" + SYMBOL + r")\s*"
25EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" 25EXPR = r"(?:" + OPERATORS + r"|\s|" + SYMBOL + r")+"
26DEFAULT = r"default\s+.*?(?:if\s.+){,1}" 26DEFAULT = r"default\s+.*?(?:if\s.+){,1}"
27STMT = r"^\s*(?:if|select|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR 27STMT = r"^\s*(?:if|select|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR
28SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" 28SOURCE_SYMBOL = r"(?:\W|\b)+[D]{,1}CONFIG_(" + SYMBOL + r")"
29 29
30# regex objects 30# regex objects
31REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") 31REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$")
32REGEX_FEATURE = re.compile(r'(?!\B)' + FEATURE + r'(?!\B)') 32REGEX_SYMBOL = re.compile(r'(?!\B)' + SYMBOL + r'(?!\B)')
33REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) 33REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL)
34REGEX_KCONFIG_DEF = re.compile(DEF) 34REGEX_KCONFIG_DEF = re.compile(DEF)
35REGEX_KCONFIG_EXPR = re.compile(EXPR) 35REGEX_KCONFIG_EXPR = re.compile(EXPR)
36REGEX_KCONFIG_STMT = re.compile(STMT) 36REGEX_KCONFIG_STMT = re.compile(STMT)
37REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") 37REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
38REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") 38REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$")
39REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+") 39REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+")
40REGEX_QUOTES = re.compile("(\"(.*?)\")") 40REGEX_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
369def parse_source_files(source_files): 369def 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
378def parse_source_file(sfile): 378def 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
401def get_features_in_line(line): 401def 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
406def parse_kconfig_files(args): 406def 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
425def parse_kconfig_file(kfile): 425def 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