Commit cc641d5529965fbd01edbdf289951fb95d3de1b8

Authored by Valentin Rothberg
Committed by Greg Kroah-Hartman
1 parent 184901a06a

checkkconfigsymbols.py: improve detection of defects

This patch improves the detection of defects by updating the
regular expression to find Kconfig identifiers in the source
code, and fixes some cases of false positives. The following
changes are made:
- improve regex to find Kconfig identifiers in the source
- exclude .log files from analysis
- improve filtering of false positives (e.g, CONFIG_XXX)
- change output format from (feature:\tlist) to (feature\tlist)

Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 27 additions and 30 deletions Side-by-side Diff

scripts/checkkconfigsymbols.py
1 1 #!/usr/bin/env python
2 2  
3   -"""Find Kconfig identifieres that are referenced but not defined."""
  3 +"""Find Kconfig identifiers that are referenced but not defined."""
4 4  
5   -# Copyright (C) 2014 Valentin Rothberg <valentinrothberg@gmail.com>
6   -# Copyright (C) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
  5 +# (c) 2014 Valentin Rothberg <valentinrothberg@gmail.com>
  6 +# (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
7 7 #
8   -# This program is free software; you can redistribute it and/or modify it
9   -# under the terms and conditions of the GNU General Public License,
10   -# version 2, as published by the Free Software Foundation.
11   -#
12   -# This program is distributed in the hope it will be useful, but WITHOUT
13   -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15   -# more details.
  8 +# Licensed under the terms of the GNU GPL License version 2
16 9  
17 10  
18 11 import os
19 12 import re
20 13 from subprocess import Popen, PIPE, STDOUT
21 14  
22   -# REGEX EXPRESSIONS
  15 +
  16 +# regex expressions
23 17 OPERATORS = r"&|\(|\)|\||\!"
24   -FEATURE = r"\w*[A-Z]{1}\w*"
25   -CONFIG_DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*"
  18 +FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}"
  19 +DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*"
26 20 EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+"
27 21 STMT = r"^\s*(?:if|select|depends\s+on)\s+" + EXPR
  22 +SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")"
28 23  
29   -# REGEX OBJECTS
  24 +# regex objects
30 25 REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$")
31 26 REGEX_FEATURE = re.compile(r"(" + FEATURE + r")")
32   -REGEX_SOURCE_FEATURE = re.compile(r"(?:D|\W|\b)+CONFIG_(" + FEATURE + r")")
33   -REGEX_KCONFIG_DEF = re.compile(CONFIG_DEF)
  27 +REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE)
  28 +REGEX_KCONFIG_DEF = re.compile(DEF)
34 29 REGEX_KCONFIG_EXPR = re.compile(EXPR)
35 30 REGEX_KCONFIG_STMT = re.compile(STMT)
36 31 REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
... ... @@ -42,7 +37,7 @@
42 37 source_files = []
43 38 kconfig_files = []
44 39 defined_features = set()
45   - referenced_features = dict()
  40 + referenced_features = dict() # {feature: [files]}
46 41  
47 42 # use 'git ls-files' to get the worklist
48 43 pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True)
49 44  
... ... @@ -52,12 +47,12 @@
52 47  
53 48 for gitfile in stdout.rsplit("\n"):
54 49 if ".git" in gitfile or "ChangeLog" in gitfile or \
55   - os.path.isdir(gitfile):
  50 + ".log" in gitfile or os.path.isdir(gitfile):
56 51 continue
57 52 if REGEX_FILE_KCONFIG.match(gitfile):
58 53 kconfig_files.append(gitfile)
59 54 else:
60   - # All non-Kconfig files are checked for consistency
  55 + # all non-Kconfig files are checked for consistency
61 56 source_files.append(gitfile)
62 57  
63 58 for sfile in source_files:
64 59  
65 60  
66 61  
... ... @@ -68,15 +63,17 @@
68 63  
69 64 print "Undefined symbol used\tFile list"
70 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
71 70 if feature not in defined_features:
72 71 if feature.endswith("_MODULE"):
73   - # Avoid false positives for kernel modules
  72 + # avoid false positives for kernel modules
74 73 if feature[:-len("_MODULE")] in defined_features:
75 74 continue
76   - if "FOO" in feature or "BAR" in feature:
77   - continue
78 75 files = referenced_features.get(feature)
79   - print "%s:\t%s" % (feature, ", ".join(files))
  76 + print "%s\t%s" % (feature, ", ".join(files))
80 77  
81 78  
82 79 def parse_source_file(sfile, referenced_features):
... ... @@ -92,9 +89,9 @@
92 89 for feature in features:
93 90 if not REGEX_FILTER_FEATURES.search(feature):
94 91 continue
95   - paths = referenced_features.get(feature, set())
96   - paths.add(sfile)
97   - referenced_features[feature] = paths
  92 + sfiles = referenced_features.get(feature, set())
  93 + sfiles.add(sfile)
  94 + referenced_features[feature] = sfiles
98 95  
99 96  
100 97 def get_features_in_line(line):
... ... @@ -113,7 +110,7 @@
113 110 for i in range(len(lines)):
114 111 line = lines[i]
115 112 line = line.strip('\n')
116   - line = line.split("#")[0] # Ignore Kconfig comments
  113 + line = line.split("#")[0] # ignore comments
117 114  
118 115 if REGEX_KCONFIG_DEF.match(line):
119 116 feature_def = REGEX_KCONFIG_DEF.findall(line)
120 117  
... ... @@ -122,11 +119,11 @@
122 119 elif REGEX_KCONFIG_HELP.match(line):
123 120 skip = True
124 121 elif skip:
125   - # Ignore content of help messages
  122 + # ignore content of help messages
126 123 pass
127 124 elif REGEX_KCONFIG_STMT.match(line):
128 125 features = get_features_in_line(line)
129   - # Multi-line statements
  126 + # multi-line statements
130 127 while line.endswith("\\"):
131 128 i += 1
132 129 line = lines[i]