aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/checkkconfigsymbols.py57
1 files changed, 27 insertions, 30 deletions
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py
index f9440891d048..e9cc689033fe 100644
--- a/scripts/checkkconfigsymbols.py
+++ b/scripts/checkkconfigsymbols.py
@@ -1,36 +1,31 @@
1#!/usr/bin/env python 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> 5# (c) 2014 Valentin Rothberg <valentinrothberg@gmail.com>
6# Copyright (C) 2014 Stefan Hengelein <stefan.hengelein@fau.de> 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 8# Licensed under the terms of the GNU GPL License version 2
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.
16 9
17 10
18import os 11import os
19import re 12import re
20from subprocess import Popen, PIPE, STDOUT 13from subprocess import Popen, PIPE, STDOUT
21 14
22# REGEX EXPRESSIONS 15
16# regex expressions
23OPERATORS = r"&|\(|\)|\||\!" 17OPERATORS = r"&|\(|\)|\||\!"
24FEATURE = r"\w*[A-Z]{1}\w*" 18FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}"
25CONFIG_DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" 19DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*"
26EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" 20EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+"
27STMT = r"^\s*(?:if|select|depends\s+on)\s+" + EXPR 21STMT = r"^\s*(?:if|select|depends\s+on)\s+" + EXPR
22SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")"
28 23
29# REGEX OBJECTS 24# regex objects
30REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") 25REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$")
31REGEX_FEATURE = re.compile(r"(" + FEATURE + r")") 26REGEX_FEATURE = re.compile(r"(" + FEATURE + r")")
32REGEX_SOURCE_FEATURE = re.compile(r"(?:D|\W|\b)+CONFIG_(" + FEATURE + r")") 27REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE)
33REGEX_KCONFIG_DEF = re.compile(CONFIG_DEF) 28REGEX_KCONFIG_DEF = re.compile(DEF)
34REGEX_KCONFIG_EXPR = re.compile(EXPR) 29REGEX_KCONFIG_EXPR = re.compile(EXPR)
35REGEX_KCONFIG_STMT = re.compile(STMT) 30REGEX_KCONFIG_STMT = re.compile(STMT)
36REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") 31REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
@@ -42,7 +37,7 @@ def main():
42 source_files = [] 37 source_files = []
43 kconfig_files = [] 38 kconfig_files = []
44 defined_features = set() 39 defined_features = set()
45 referenced_features = dict() 40 referenced_features = dict() # {feature: [files]}
46 41
47 # use 'git ls-files' to get the worklist 42 # use 'git ls-files' to get the worklist
48 pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True) 43 pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True)
@@ -52,12 +47,12 @@ def main():
52 47
53 for gitfile in stdout.rsplit("\n"): 48 for gitfile in stdout.rsplit("\n"):
54 if ".git" in gitfile or "ChangeLog" in gitfile or \ 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 continue 51 continue
57 if REGEX_FILE_KCONFIG.match(gitfile): 52 if REGEX_FILE_KCONFIG.match(gitfile):
58 kconfig_files.append(gitfile) 53 kconfig_files.append(gitfile)
59 else: 54 else:
60 # All non-Kconfig files are checked for consistency 55 # all non-Kconfig files are checked for consistency
61 source_files.append(gitfile) 56 source_files.append(gitfile)
62 57
63 for sfile in source_files: 58 for sfile in source_files:
@@ -68,15 +63,17 @@ def main():
68 63
69 print "Undefined symbol used\tFile list" 64 print "Undefined symbol used\tFile list"
70 for feature in sorted(referenced_features): 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 if feature not in defined_features: 70 if feature not in defined_features:
72 if feature.endswith("_MODULE"): 71 if feature.endswith("_MODULE"):
73 # Avoid false positives for kernel modules 72 # avoid false positives for kernel modules
74 if feature[:-len("_MODULE")] in defined_features: 73 if feature[:-len("_MODULE")] in defined_features:
75 continue 74 continue
76 if "FOO" in feature or "BAR" in feature:
77 continue
78 files = referenced_features.get(feature) 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
82def parse_source_file(sfile, referenced_features): 79def parse_source_file(sfile, referenced_features):
@@ -92,9 +89,9 @@ def parse_source_file(sfile, referenced_features):
92 for feature in features: 89 for feature in features:
93 if not REGEX_FILTER_FEATURES.search(feature): 90 if not REGEX_FILTER_FEATURES.search(feature):
94 continue 91 continue
95 paths = referenced_features.get(feature, set()) 92 sfiles = referenced_features.get(feature, set())
96 paths.add(sfile) 93 sfiles.add(sfile)
97 referenced_features[feature] = paths 94 referenced_features[feature] = sfiles
98 95
99 96
100def get_features_in_line(line): 97def get_features_in_line(line):
@@ -113,7 +110,7 @@ def parse_kconfig_file(kfile, defined_features, referenced_features):
113 for i in range(len(lines)): 110 for i in range(len(lines)):
114 line = lines[i] 111 line = lines[i]
115 line = line.strip('\n') 112 line = line.strip('\n')
116 line = line.split("#")[0] # Ignore Kconfig comments 113 line = line.split("#")[0] # ignore comments
117 114
118 if REGEX_KCONFIG_DEF.match(line): 115 if REGEX_KCONFIG_DEF.match(line):
119 feature_def = REGEX_KCONFIG_DEF.findall(line) 116 feature_def = REGEX_KCONFIG_DEF.findall(line)
@@ -122,11 +119,11 @@ def parse_kconfig_file(kfile, defined_features, referenced_features):
122 elif REGEX_KCONFIG_HELP.match(line): 119 elif REGEX_KCONFIG_HELP.match(line):
123 skip = True 120 skip = True
124 elif skip: 121 elif skip:
125 # Ignore content of help messages 122 # ignore content of help messages
126 pass 123 pass
127 elif REGEX_KCONFIG_STMT.match(line): 124 elif REGEX_KCONFIG_STMT.match(line):
128 features = get_features_in_line(line) 125 features = get_features_in_line(line)
129 # Multi-line statements 126 # multi-line statements
130 while line.endswith("\\"): 127 while line.endswith("\\"):
131 i += 1 128 i += 1
132 line = lines[i] 129 line = lines[i]