aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 22:57:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 22:57:49 -0400
commit7a53eea1f7b527fd3b6d7ca992914840981afe99 (patch)
tree35dfd7e14d5c44ae2d34e470aaaa68dbfec39324 /scripts
parent597f03f9d133e9837d00965016170271d4f87dcf (diff)
parentc9fef1cc3dd3677633e6fd6ea5bd7ef3b741fab3 (diff)
Merge tag 'char-misc-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here's the "big" char and misc driver update for 4.9-rc1. Lots of little things here, all over the driver tree for subsystems that flow through me. Nothing major that I can discern, full details are in the shortlog. All have been in the linux-next tree with no reported issues" * tag 'char-misc-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (144 commits) drivers/misc/hpilo: Changes to support new security states in iLO5 FW at25: fix debug and error messaging misc/genwqe: ensure zero initialization vme: fake: remove unexpected unlock in fake_master_set() vme: fake: mark symbols static where possible spmi: pmic-arb: Return an error code if sanity check fails Drivers: hv: get rid of id in struct vmbus_channel Drivers: hv: make VMBus bus ids persistent mcb: Add a dma_device to mcb_device mcb: Enable PCI bus mastering by default mei: stop the stall timer worker if not needed clk: probe common clock drivers earlier vme: fake: fix build for 64-bit dma_addr_t ttyprintk: Neaten and simplify printing mei: me: add kaby point device ids coresight: tmc: mark symbols static where possible coresight: perf: deal with error condition properly Drivers: hv: hv_util: Avoid dynamic allocation in time synch fpga manager: Add hardware dependency to Zynq driver Drivers: hv: utils: Support TimeSync version 4.0 protocol samples. ...
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/checkkconfigsymbols.py338
-rwxr-xr-xscripts/ver_linux260
2 files changed, 252 insertions, 346 deletions
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py
index df643f60bb41..a32e4da4c117 100755
--- a/scripts/checkkconfigsymbols.py
+++ b/scripts/checkkconfigsymbols.py
@@ -1,98 +1,99 @@
1#!/usr/bin/env python2 1#!/usr/bin/env python3
2 2
3"""Find Kconfig symbols that are referenced but not defined.""" 3"""Find Kconfig symbols that are referenced but not defined."""
4 4
5# (c) 2014-2015 Valentin Rothberg <valentinrothberg@gmail.com> 5# (c) 2014-2016 Valentin Rothberg <valentinrothberg@gmail.com>
6# (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de> 6# (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
7# 7#
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
11import argparse
11import difflib 12import difflib
12import os 13import os
13import re 14import re
14import signal 15import signal
16import subprocess
15import sys 17import sys
16from multiprocessing import Pool, cpu_count 18from multiprocessing import Pool, cpu_count
17from optparse import OptionParser
18from subprocess import Popen, PIPE, STDOUT
19 19
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
42 42
43def parse_options(): 43def parse_options():
44 """The user interface of this module.""" 44 """The user interface of this module."""
45 usage = "%prog [options]\n\n" \ 45 usage = "Run this tool to detect Kconfig symbols that are referenced but " \
46 "Run this tool to detect Kconfig symbols that are referenced but " \ 46 "not defined in Kconfig. If no option is specified, " \
47 "not defined in\nKconfig. The output of this tool has the " \ 47 "checkkconfigsymbols defaults to check your current tree. " \
48 "format \'Undefined symbol\\tFile list\'\n\n" \ 48 "Please note that specifying commits will 'git reset --hard\' " \
49 "If no option is specified, %prog will default to check your\n" \ 49 "your current tree! You may save uncommitted changes to avoid " \
50 "current tree. Please note that specifying commits will " \ 50 "losing data."
51 "\'git reset --hard\'\nyour current tree! You may save " \ 51
52 "uncommitted changes to avoid losing data." 52 parser = argparse.ArgumentParser(description=usage)
53 53
54 parser = OptionParser(usage=usage) 54 parser.add_argument('-c', '--commit', dest='commit', action='store',
55 55 default="",
56 parser.add_option('-c', '--commit', dest='commit', action='store', 56 help="check if the specified commit (hash) introduces "
57 default="", 57 "undefined Kconfig symbols")
58 help="Check if the specified commit (hash) introduces " 58
59 "undefined Kconfig symbols.") 59 parser.add_argument('-d', '--diff', dest='diff', action='store',
60 60 default="",
61 parser.add_option('-d', '--diff', dest='diff', action='store', 61 help="diff undefined symbols between two commits "
62 default="", 62 "(e.g., -d commmit1..commit2)")
63 help="Diff undefined symbols between two commits. The " 63
64 "input format bases on Git log's " 64 parser.add_argument('-f', '--find', dest='find', action='store_true',
65 "\'commmit1..commit2\'.") 65 default=False,
66 66 help="find and show commits that may cause symbols to be "
67 parser.add_option('-f', '--find', dest='find', action='store_true', 67 "missing (required to run with --diff)")
68 default=False, 68
69 help="Find and show commits that may cause symbols to be " 69 parser.add_argument('-i', '--ignore', dest='ignore', action='store',
70 "missing. Required to run with --diff.") 70 default="",
71 71 help="ignore files matching this Python regex "
72 parser.add_option('-i', '--ignore', dest='ignore', action='store', 72 "(e.g., -i '.*defconfig')")
73 default="", 73
74 help="Ignore files matching this pattern. Note that " 74 parser.add_argument('-s', '--sim', dest='sim', action='store', default="",
75 "the pattern needs to be a Python regex. To " 75 help="print a list of max. 10 string-similar symbols")
76 "ignore defconfigs, specify -i '.*defconfig'.") 76
77 77 parser.add_argument('--force', dest='force', action='store_true',
78 parser.add_option('-s', '--sim', dest='sim', action='store', default="", 78 default=False,
79 help="Print a list of maximum 10 string-similar symbols.") 79 help="reset current Git tree even when it's dirty")
80 80
81 parser.add_option('', '--force', dest='force', action='store_true', 81 parser.add_argument('--no-color', dest='color', action='store_false',
82 default=False, 82 default=True,
83 help="Reset current Git tree even when it's dirty.") 83 help="don't print colored output (default when not "
84 84 "outputting to a terminal)")
85 (opts, _) = parser.parse_args() 85
86 86 args = parser.parse_args()
87 if opts.commit and opts.diff: 87
88 if args.commit and args.diff:
88 sys.exit("Please specify only one option at once.") 89 sys.exit("Please specify only one option at once.")
89 90
90 if opts.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", opts.diff): 91 if args.diff and not re.match(r"^[\w\-\.]+\.\.[\w\-\.]+$", args.diff):
91 sys.exit("Please specify valid input in the following format: " 92 sys.exit("Please specify valid input in the following format: "
92 "\'commit1..commit2\'") 93 "\'commit1..commit2\'")
93 94
94 if opts.commit or opts.diff: 95 if args.commit or args.diff:
95 if not opts.force and tree_is_dirty(): 96 if not args.force and tree_is_dirty():
96 sys.exit("The current Git tree is dirty (see 'git status'). " 97 sys.exit("The current Git tree is dirty (see 'git status'). "
97 "Running this script may\ndelete important data since it " 98 "Running this script may\ndelete important data since it "
98 "calls 'git reset --hard' for some performance\nreasons. " 99 "calls 'git reset --hard' for some performance\nreasons. "
@@ -100,138 +101,148 @@ def parse_options():
100 "'--force' if you\nwant to ignore this warning and " 101 "'--force' if you\nwant to ignore this warning and "
101 "continue.") 102 "continue.")
102 103
103 if opts.commit: 104 if args.commit:
104 opts.find = False 105 args.find = False
105 106
106 if opts.ignore: 107 if args.ignore:
107 try: 108 try:
108 re.match(opts.ignore, "this/is/just/a/test.c") 109 re.match(args.ignore, "this/is/just/a/test.c")
109 except: 110 except:
110 sys.exit("Please specify a valid Python regex.") 111 sys.exit("Please specify a valid Python regex.")
111 112
112 return opts 113 return args
113 114
114 115
115def main(): 116def main():
116 """Main function of this module.""" 117 """Main function of this module."""
117 opts = parse_options() 118 args = parse_options()
118 119
119 if opts.sim and not opts.commit and not opts.diff: 120 global COLOR
120 sims = find_sims(opts.sim, opts.ignore) 121 COLOR = args.color and sys.stdout.isatty()
122
123 if args.sim and not args.commit and not args.diff:
124 sims = find_sims(args.sim, args.ignore)
121 if sims: 125 if sims:
122 print "%s: %s" % (yel("Similar symbols"), ', '.join(sims)) 126 print("%s: %s" % (yel("Similar symbols"), ', '.join(sims)))
123 else: 127 else:
124 print "%s: no similar symbols found" % yel("Similar symbols") 128 print("%s: no similar symbols found" % yel("Similar symbols"))
125 sys.exit(0) 129 sys.exit(0)
126 130
127 # dictionary of (un)defined symbols 131 # dictionary of (un)defined symbols
128 defined = {} 132 defined = {}
129 undefined = {} 133 undefined = {}
130 134
131 if opts.commit or opts.diff: 135 if args.commit or args.diff:
132 head = get_head() 136 head = get_head()
133 137
134 # get commit range 138 # get commit range
135 commit_a = None 139 commit_a = None
136 commit_b = None 140 commit_b = None
137 if opts.commit: 141 if args.commit:
138 commit_a = opts.commit + "~" 142 commit_a = args.commit + "~"
139 commit_b = opts.commit 143 commit_b = args.commit
140 elif opts.diff: 144 elif args.diff:
141 split = opts.diff.split("..") 145 split = args.diff.split("..")
142 commit_a = split[0] 146 commit_a = split[0]
143 commit_b = split[1] 147 commit_b = split[1]
144 undefined_a = {} 148 undefined_a = {}
145 undefined_b = {} 149 undefined_b = {}
146 150
147 # get undefined items before the commit 151 # get undefined items before the commit
148 execute("git reset --hard %s" % commit_a) 152 reset(commit_a)
149 undefined_a, _ = check_symbols(opts.ignore) 153 undefined_a, _ = check_symbols(args.ignore)
150 154
151 # get undefined items for the commit 155 # get undefined items for the commit
152 execute("git reset --hard %s" % commit_b) 156 reset(commit_b)
153 undefined_b, defined = check_symbols(opts.ignore) 157 undefined_b, defined = check_symbols(args.ignore)
154 158
155 # report cases that are present for the commit but not before 159 # report cases that are present for the commit but not before
156 for feature in sorted(undefined_b): 160 for symbol in sorted(undefined_b):
157 # feature has not been undefined before 161 # symbol has not been undefined before
158 if not feature in undefined_a: 162 if symbol not in undefined_a:
159 files = sorted(undefined_b.get(feature)) 163 files = sorted(undefined_b.get(symbol))
160 undefined[feature] = files 164 undefined[symbol] = files
161 # check if there are new files that reference the undefined feature 165 # check if there are new files that reference the undefined symbol
162 else: 166 else:
163 files = sorted(undefined_b.get(feature) - 167 files = sorted(undefined_b.get(symbol) -
164 undefined_a.get(feature)) 168 undefined_a.get(symbol))
165 if files: 169 if files:
166 undefined[feature] = files 170 undefined[symbol] = files
167 171
168 # reset to head 172 # reset to head
169 execute("git reset --hard %s" % head) 173 reset(head)
170 174
171 # default to check the entire tree 175 # default to check the entire tree
172 else: 176 else:
173 undefined, defined = check_symbols(opts.ignore) 177 undefined, defined = check_symbols(args.ignore)
174 178
175 # now print the output 179 # now print the output
176 for feature in sorted(undefined): 180 for symbol in sorted(undefined):
177 print red(feature) 181 print(red(symbol))
178 182
179 files = sorted(undefined.get(feature)) 183 files = sorted(undefined.get(symbol))
180 print "%s: %s" % (yel("Referencing files"), ", ".join(files)) 184 print("%s: %s" % (yel("Referencing files"), ", ".join(files)))
181 185
182 sims = find_sims(feature, opts.ignore, defined) 186 sims = find_sims(symbol, args.ignore, defined)
183 sims_out = yel("Similar symbols") 187 sims_out = yel("Similar symbols")
184 if sims: 188 if sims:
185 print "%s: %s" % (sims_out, ', '.join(sims)) 189 print("%s: %s" % (sims_out, ', '.join(sims)))
186 else: 190 else:
187 print "%s: %s" % (sims_out, "no similar symbols found") 191 print("%s: %s" % (sims_out, "no similar symbols found"))
188 192
189 if opts.find: 193 if args.find:
190 print "%s:" % yel("Commits changing symbol") 194 print("%s:" % yel("Commits changing symbol"))
191 commits = find_commits(feature, opts.diff) 195 commits = find_commits(symbol, args.diff)
192 if commits: 196 if commits:
193 for commit in commits: 197 for commit in commits:
194 commit = commit.split(" ", 1) 198 commit = commit.split(" ", 1)
195 print "\t- %s (\"%s\")" % (yel(commit[0]), commit[1]) 199 print("\t- %s (\"%s\")" % (yel(commit[0]), commit[1]))
196 else: 200 else:
197 print "\t- no commit found" 201 print("\t- no commit found")
198 print # new line 202 print() # new line
203
204
205def reset(commit):
206 """Reset current git tree to %commit."""
207 execute(["git", "reset", "--hard", commit])
199 208
200 209
201def yel(string): 210def yel(string):
202 """ 211 """
203 Color %string yellow. 212 Color %string yellow.
204 """ 213 """
205 return "\033[33m%s\033[0m" % string 214 return "\033[33m%s\033[0m" % string if COLOR else string
206 215
207 216
208def red(string): 217def red(string):
209 """ 218 """
210 Color %string red. 219 Color %string red.
211 """ 220 """
212 return "\033[31m%s\033[0m" % string 221 return "\033[31m%s\033[0m" % string if COLOR else string
213 222
214 223
215def execute(cmd): 224def execute(cmd):
216 """Execute %cmd and return stdout. Exit in case of error.""" 225 """Execute %cmd and return stdout. Exit in case of error."""
217 pop = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True) 226 try:
218 (stdout, _) = pop.communicate() # wait until finished 227 stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
219 if pop.returncode != 0: 228 stdout = stdout.decode(errors='replace')
220 sys.exit(stdout) 229 except subprocess.CalledProcessError as fail:
230 exit(fail)
221 return stdout 231 return stdout
222 232
223 233
224def find_commits(symbol, diff): 234def find_commits(symbol, diff):
225 """Find commits changing %symbol in the given range of %diff.""" 235 """Find commits changing %symbol in the given range of %diff."""
226 commits = execute("git log --pretty=oneline --abbrev-commit -G %s %s" 236 commits = execute(["git", "log", "--pretty=oneline",
227 % (symbol, diff)) 237 "--abbrev-commit", "-G",
238 symbol, diff])
228 return [x for x in commits.split("\n") if x] 239 return [x for x in commits.split("\n") if x]
229 240
230 241
231def tree_is_dirty(): 242def tree_is_dirty():
232 """Return true if the current working tree is dirty (i.e., if any file has 243 """Return true if the current working tree is dirty (i.e., if any file has
233 been added, deleted, modified, renamed or copied but not committed).""" 244 been added, deleted, modified, renamed or copied but not committed)."""
234 stdout = execute("git status --porcelain") 245 stdout = execute(["git", "status", "--porcelain"])
235 for line in stdout: 246 for line in stdout:
236 if re.findall(r"[URMADC]{1}", line[:2]): 247 if re.findall(r"[URMADC]{1}", line[:2]):
237 return True 248 return True
@@ -240,13 +251,13 @@ def tree_is_dirty():
240 251
241def get_head(): 252def get_head():
242 """Return commit hash of current HEAD.""" 253 """Return commit hash of current HEAD."""
243 stdout = execute("git rev-parse HEAD") 254 stdout = execute(["git", "rev-parse", "HEAD"])
244 return stdout.strip('\n') 255 return stdout.strip('\n')
245 256
246 257
247def partition(lst, size): 258def partition(lst, size):
248 """Partition list @lst into eveni-sized lists of size @size.""" 259 """Partition list @lst into eveni-sized lists of size @size."""
249 return [lst[i::size] for i in xrange(size)] 260 return [lst[i::size] for i in range(size)]
250 261
251 262
252def init_worker(): 263def init_worker():
@@ -254,7 +265,7 @@ def init_worker():
254 signal.signal(signal.SIGINT, signal.SIG_IGN) 265 signal.signal(signal.SIGINT, signal.SIG_IGN)
255 266
256 267
257def find_sims(symbol, ignore, defined = []): 268def find_sims(symbol, ignore, defined=[]):
258 """Return a list of max. ten Kconfig symbols that are string-similar to 269 """Return a list of max. ten Kconfig symbols that are string-similar to
259 @symbol.""" 270 @symbol."""
260 if defined: 271 if defined:
@@ -279,7 +290,7 @@ def find_sims(symbol, ignore, defined = []):
279def get_files(): 290def get_files():
280 """Return a list of all files in the current git directory.""" 291 """Return a list of all files in the current git directory."""
281 # use 'git ls-files' to get the worklist 292 # use 'git ls-files' to get the worklist
282 stdout = execute("git ls-files") 293 stdout = execute(["git", "ls-files"])
283 if len(stdout) > 0 and stdout[-1] == "\n": 294 if len(stdout) > 0 and stdout[-1] == "\n":
284 stdout = stdout[:-1] 295 stdout = stdout[:-1]
285 296
@@ -311,8 +322,8 @@ def check_symbols_helper(pool, ignore):
311 check_symbols() in order to properly terminate running worker processes.""" 322 check_symbols() in order to properly terminate running worker processes."""
312 source_files = [] 323 source_files = []
313 kconfig_files = [] 324 kconfig_files = []
314 defined_features = [] 325 defined_symbols = []
315 referenced_features = dict() # {file: [features]} 326 referenced_symbols = dict() # {file: [symbols]}
316 327
317 for gitfile in get_files(): 328 for gitfile in get_files():
318 if REGEX_FILE_KCONFIG.match(gitfile): 329 if REGEX_FILE_KCONFIG.match(gitfile):
@@ -326,76 +337,75 @@ def check_symbols_helper(pool, ignore):
326 # parse source files 337 # parse source files
327 arglist = partition(source_files, cpu_count()) 338 arglist = partition(source_files, cpu_count())
328 for res in pool.map(parse_source_files, arglist): 339 for res in pool.map(parse_source_files, arglist):
329 referenced_features.update(res) 340 referenced_symbols.update(res)
330
331 341
332 # parse kconfig files 342 # parse kconfig files
333 arglist = [] 343 arglist = []
334 for part in partition(kconfig_files, cpu_count()): 344 for part in partition(kconfig_files, cpu_count()):
335 arglist.append((part, ignore)) 345 arglist.append((part, ignore))
336 for res in pool.map(parse_kconfig_files, arglist): 346 for res in pool.map(parse_kconfig_files, arglist):
337 defined_features.extend(res[0]) 347 defined_symbols.extend(res[0])
338 referenced_features.update(res[1]) 348 referenced_symbols.update(res[1])
339 defined_features = set(defined_features) 349 defined_symbols = set(defined_symbols)
340 350
341 # inverse mapping of referenced_features to dict(feature: [files]) 351 # inverse mapping of referenced_symbols to dict(symbol: [files])
342 inv_map = dict() 352 inv_map = dict()
343 for _file, features in referenced_features.iteritems(): 353 for _file, symbols in referenced_symbols.items():
344 for feature in features: 354 for symbol in symbols:
345 inv_map[feature] = inv_map.get(feature, set()) 355 inv_map[symbol] = inv_map.get(symbol, set())
346 inv_map[feature].add(_file) 356 inv_map[symbol].add(_file)
347 referenced_features = inv_map 357 referenced_symbols = inv_map
348 358
349 undefined = {} # {feature: [files]} 359 undefined = {} # {symbol: [files]}
350 for feature in sorted(referenced_features): 360 for symbol in sorted(referenced_symbols):
351 # filter some false positives 361 # filter some false positives
352 if feature == "FOO" or feature == "BAR" or \ 362 if symbol == "FOO" or symbol == "BAR" or \
353 feature == "FOO_BAR" or feature == "XXX": 363 symbol == "FOO_BAR" or symbol == "XXX":
354 continue 364 continue
355 if feature not in defined_features: 365 if symbol not in defined_symbols:
356 if feature.endswith("_MODULE"): 366 if symbol.endswith("_MODULE"):
357 # avoid false positives for kernel modules 367 # avoid false positives for kernel modules
358 if feature[:-len("_MODULE")] in defined_features: 368 if symbol[:-len("_MODULE")] in defined_symbols:
359 continue 369 continue
360 undefined[feature] = referenced_features.get(feature) 370 undefined[symbol] = referenced_symbols.get(symbol)
361 return undefined, defined_features 371 return undefined, defined_symbols
362 372
363 373
364def parse_source_files(source_files): 374def parse_source_files(source_files):
365 """Parse each source file in @source_files and return dictionary with source 375 """Parse each source file in @source_files and return dictionary with source
366 files as keys and lists of references Kconfig symbols as values.""" 376 files as keys and lists of references Kconfig symbols as values."""
367 referenced_features = dict() 377 referenced_symbols = dict()
368 for sfile in source_files: 378 for sfile in source_files:
369 referenced_features[sfile] = parse_source_file(sfile) 379 referenced_symbols[sfile] = parse_source_file(sfile)
370 return referenced_features 380 return referenced_symbols
371 381
372 382
373def parse_source_file(sfile): 383def parse_source_file(sfile):
374 """Parse @sfile and return a list of referenced Kconfig features.""" 384 """Parse @sfile and return a list of referenced Kconfig symbols."""
375 lines = [] 385 lines = []
376 references = [] 386 references = []
377 387
378 if not os.path.exists(sfile): 388 if not os.path.exists(sfile):
379 return references 389 return references
380 390
381 with open(sfile, "r") as stream: 391 with open(sfile, "r", encoding='utf-8', errors='replace') as stream:
382 lines = stream.readlines() 392 lines = stream.readlines()
383 393
384 for line in lines: 394 for line in lines:
385 if not "CONFIG_" in line: 395 if "CONFIG_" not in line:
386 continue 396 continue
387 features = REGEX_SOURCE_FEATURE.findall(line) 397 symbols = REGEX_SOURCE_SYMBOL.findall(line)
388 for feature in features: 398 for symbol in symbols:
389 if not REGEX_FILTER_FEATURES.search(feature): 399 if not REGEX_FILTER_SYMBOLS.search(symbol):
390 continue 400 continue
391 references.append(feature) 401 references.append(symbol)
392 402
393 return references 403 return references
394 404
395 405
396def get_features_in_line(line): 406def get_symbols_in_line(line):
397 """Return mentioned Kconfig features in @line.""" 407 """Return mentioned Kconfig symbols in @line."""
398 return REGEX_FEATURE.findall(line) 408 return REGEX_SYMBOL.findall(line)
399 409
400 410
401def parse_kconfig_files(args): 411def parse_kconfig_files(args):
@@ -404,21 +414,21 @@ def parse_kconfig_files(args):
404 pattern.""" 414 pattern."""
405 kconfig_files = args[0] 415 kconfig_files = args[0]
406 ignore = args[1] 416 ignore = args[1]
407 defined_features = [] 417 defined_symbols = []
408 referenced_features = dict() 418 referenced_symbols = dict()
409 419
410 for kfile in kconfig_files: 420 for kfile in kconfig_files:
411 defined, references = parse_kconfig_file(kfile) 421 defined, references = parse_kconfig_file(kfile)
412 defined_features.extend(defined) 422 defined_symbols.extend(defined)
413 if ignore and re.match(ignore, kfile): 423 if ignore and re.match(ignore, kfile):
414 # do not collect references for files that match the ignore pattern 424 # do not collect references for files that match the ignore pattern
415 continue 425 continue
416 referenced_features[kfile] = references 426 referenced_symbols[kfile] = references
417 return (defined_features, referenced_features) 427 return (defined_symbols, referenced_symbols)
418 428
419 429
420def parse_kconfig_file(kfile): 430def parse_kconfig_file(kfile):
421 """Parse @kfile and update feature definitions and references.""" 431 """Parse @kfile and update symbol definitions and references."""
422 lines = [] 432 lines = []
423 defined = [] 433 defined = []
424 references = [] 434 references = []
@@ -427,7 +437,7 @@ def parse_kconfig_file(kfile):
427 if not os.path.exists(kfile): 437 if not os.path.exists(kfile):
428 return defined, references 438 return defined, references
429 439
430 with open(kfile, "r") as stream: 440 with open(kfile, "r", encoding='utf-8', errors='replace') as stream:
431 lines = stream.readlines() 441 lines = stream.readlines()
432 442
433 for i in range(len(lines)): 443 for i in range(len(lines)):
@@ -436,8 +446,8 @@ def parse_kconfig_file(kfile):
436 line = line.split("#")[0] # ignore comments 446 line = line.split("#")[0] # ignore comments
437 447
438 if REGEX_KCONFIG_DEF.match(line): 448 if REGEX_KCONFIG_DEF.match(line):
439 feature_def = REGEX_KCONFIG_DEF.findall(line) 449 symbol_def = REGEX_KCONFIG_DEF.findall(line)
440 defined.append(feature_def[0]) 450 defined.append(symbol_def[0])
441 skip = False 451 skip = False
442 elif REGEX_KCONFIG_HELP.match(line): 452 elif REGEX_KCONFIG_HELP.match(line):
443 skip = True 453 skip = True
@@ -446,18 +456,18 @@ def parse_kconfig_file(kfile):
446 pass 456 pass
447 elif REGEX_KCONFIG_STMT.match(line): 457 elif REGEX_KCONFIG_STMT.match(line):
448 line = REGEX_QUOTES.sub("", line) 458 line = REGEX_QUOTES.sub("", line)
449 features = get_features_in_line(line) 459 symbols = get_symbols_in_line(line)
450 # multi-line statements 460 # multi-line statements
451 while line.endswith("\\"): 461 while line.endswith("\\"):
452 i += 1 462 i += 1
453 line = lines[i] 463 line = lines[i]
454 line = line.strip('\n') 464 line = line.strip('\n')
455 features.extend(get_features_in_line(line)) 465 symbols.extend(get_symbols_in_line(line))
456 for feature in set(features): 466 for symbol in set(symbols):
457 if REGEX_NUMERIC.match(feature): 467 if REGEX_NUMERIC.match(symbol):
458 # ignore numeric values 468 # ignore numeric values
459 continue 469 continue
460 references.append(feature) 470 references.append(symbol)
461 471
462 return defined, references 472 return defined, references
463 473
diff --git a/scripts/ver_linux b/scripts/ver_linux
index 0d8bd29b1bd6..430b201f3e25 100755
--- a/scripts/ver_linux
+++ b/scripts/ver_linux
@@ -1,193 +1,89 @@
1#!/bin/sh 1#!/bin/awk -f
2# Before running this script please ensure that your PATH is 2# Before running this script please ensure that your PATH is
3# typical as you use for compilation/installation. I use 3# typical as you use for compilation/installation. I use
4# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may 4# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
5# differ on your system. 5# differ on your system.
6#
7echo 'If some fields are empty or look unusual you may have an old version.'
8echo 'Compare to the current minimal requirements in Documentation/Changes.'
9echo ' '
10 6
11uname -a 7BEGIN {
12echo ' ' 8 usage = "If some fields are empty or look unusual you may have an old version.\n"
13 9 usage = usage "Compare to the current minimal requirements in Documentation/Changes.\n"
14gcc -dumpversion 2>&1 | 10 print usage
15awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{ 11
16 match($0, /[0-9]+([.]?[0-9]+)+/) 12 system("uname -a")
17 printf("GNU C\t\t\t%s\n", 13 printf("\n")
18 substr($0,RSTART,RLENGTH)) 14
19}' 15 printversion("GNU C", version("gcc -dumpversion 2>&1"))
20 16 printversion("GNU Make", version("make --version 2>&1"))
21make --version 2>&1 | 17 printversion("Binutils", version("ld -v 2>&1"))
22awk '/GNU Make/{ 18 printversion("Util-linux", version("mount --version 2>&1"))
23 match($0, /[0-9]+([.]?[0-9]+)+/) 19 printversion("Mount", version("mount --version 2>&1"))
24 printf("GNU Make\t\t%s\n", 20 printversion("Module-init-tools", version("depmod -V 2>&1"))
25 substr($0,RSTART,RLENGTH)) 21 printversion("E2fsprogs", version("tune2fs 2>&1"))
26}' 22 printversion("Jfsutils", version("fsck.jfs -V 2>&1"))
27 23 printversion("Reiserfsprogs", version("reiserfsck -V 2>&1"))
28ld -v 2>&1 | 24 printversion("Reiser4fsprogs", version("fsck.reiser4 -V 2>&1"))
29awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{ 25 printversion("Xfsprogs", version("xfs_db -V 2>&1"))
30 match($0, /[0-9]+([.]?[0-9]+)+/) 26 printversion("Pcmciautils", version("pccardctl -V 2>&1"))
31 printf("Binutils\t\t%s\n", 27 printversion("Pcmcia-cs", version("cardmgr -V 2>&1"))
32 substr($0,RSTART,RLENGTH)) 28 printversion("Quota-tools", version("quota -V 2>&1"))
33}' 29 printversion("PPP", version("pppd --version 2>&1"))
34 30 printversion("Isdn4k-utils", version("isdnctrl 2>&1"))
35mount --version 2>&1 | 31 printversion("Nfs-utils", version("showmount --version 2>&1"))
36awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{ 32
37 match($0, /[0-9]+([.]?[0-9]+)+/) 33 if (system("test -r /proc/self/maps") == 0) {
38 $0 = substr($0,RSTART,RLENGTH) 34 while (getline <"/proc/self/maps" > 0) {
39 printf("Util-linux\t\t%s\nMount\t\t\t%s\n",$0,$0) 35 n = split($0, procmaps, "/")
40}' 36 if (/libc.*so$/ && match(procmaps[n], /[0-9]+([.]?[0-9]+)+/)) {
41 37 ver = substr(procmaps[n], RSTART, RLENGTH)
42depmod -V 2>&1 | 38 printversion("Linux C Library", ver)
43awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{ 39 break
44 match($0, /[0-9]+([.]?[0-9]+)+/) 40 }
45 printf("Module-init-tools\t%s\n", 41 }
46 substr($0,RSTART,RLENGTH))
47}'
48
49tune2fs 2>&1 |
50awk '/^tune2fs/{
51 match($0, /[0-9]+([.]?[0-9]+)+/)
52 printf("E2fsprogs\t\t%s\n",
53 substr($0,RSTART,RLENGTH))
54}'
55
56fsck.jfs -V 2>&1 |
57awk '/version/{
58 match($0, /[0-9]+([.]?[0-9]+)+/)
59 printf("Jfsutils\t\t%s\n",
60 substr($0,RSTART,RLENGTH))
61}'
62
63reiserfsck -V 2>&1 |
64awk '/^reiserfsck/{
65 match($0, /[0-9]+([.]?[0-9]+)+/)
66 printf("Reiserfsprogs\t\t%s\n",
67 substr($0,RSTART,RLENGTH))
68}'
69
70fsck.reiser4 -V 2>&1 | grep ^fsck.reiser4 | awk \
71'NR==1{print "reiser4progs ", $2}'
72
73xfs_db -V 2>&1 |
74awk '/version/{
75 match($0, /[0-9]+([.]?[0-9]+)+/)
76 printf("Xfsprogs\t\t%s\n",
77 substr($0,RSTART,RLENGTH))
78}'
79
80pccardctl -V 2>&1 |
81awk '/pcmciautils/{
82 match($0, /[0-9]+([.]?[0-9]+)+/)
83 printf("Pcmciautils\t\t%s\n",
84 substr($0,RSTART,RLENGTH))
85}'
86
87cardmgr -V 2>&1| grep version | awk \
88'NR==1{print "pcmcia-cs ", $3}'
89
90quota -V 2>&1 |
91awk '/version/{
92 match($0, /[0-9]+([.]?[0-9]+)+/)
93 printf("Quota-tools\t\t%s\n",
94 substr($0,RSTART,RLENGTH))
95}'
96
97pppd --version 2>&1 |
98awk '/version/{
99 match($0, /[0-9]+([.]?[0-9]+)+/)
100 printf("PPP\t\t\t%s\n",
101 substr($0,RSTART,RLENGTH))
102}'
103
104isdnctrl 2>&1 | grep version | awk \
105'NR==1{print "isdn4k-utils ", $NF}'
106
107showmount --version 2>&1 | grep nfs-utils | awk \
108'NR==1{print "nfs-utils ", $NF}'
109
110test -r /proc/self/maps &&
111sed '
112 /.*libc-\(.*\)\.so$/!d
113 s//Linux C Library\t\t\1/
114 q
115' /proc/self/maps
116
117ldd --version 2>&1 |
118awk '/^ldd/{
119 match($0, /[0-9]+([.]?[0-9]+)+/)
120 printf("Dynamic linker (ldd)\t%s\n",
121 substr($0,RSTART,RLENGTH))
122}'
123
124libcpp=`ldconfig -p 2>/dev/null |
125 awk '/(libg|stdc)[+]+\.so/ {
126 print $NF
127 exit
128 } 42 }
129'`
130test -r "$libcpp" &&
131ls -l $libcpp |
132sed '
133 s!.*so\.!!
134 s!^!Linux C++ Library\t!
135'
136ps --version 2>&1 |
137awk '/version/{
138 match($0, /[0-9]+([.]?[0-9]+)+/)
139 printf("Procps\t\t\t%s\n",
140 substr($0,RSTART,RLENGTH))
141}'
142
143ifconfig --version 2>&1 |
144awk '/tools/{
145 match($0, /[0-9]+([.]?[0-9]+)+/)
146 printf("Net-tools\t\t%s\n",
147 substr($0,RSTART,RLENGTH))
148}'
149
150loadkeys -V 2>&1 |
151awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{
152 match($0, /[0-9]+([.]?[0-9]+)+/)
153 $0 = substr($0,RSTART,RLENGTH)
154 printf("Kbd\t\t\t%s\nConsole-tools\t\t%s\n",$0,$0)
155}'
156 43
157oprofiled --version 2>&1 | awk \ 44 printversion("Dynamic linker (ldd)", version("ldd --version 2>&1"))
158'(NR==1 && ($2 == "oprofile")) {print "oprofile ", $3}'
159 45
160expr --v 2>&1 | 46 while ("ldconfig -p 2>/dev/null" | getline > 0) {
161awk '/^expr/{ 47 if (/(libg|stdc)[+]+\.so/) {
162 match($0, /[0-9]+([.]?[0-9]+)+/) 48 libcpp = $NF
163 printf("Sh-utils\t\t%s\n", 49 break
164 substr($0,RSTART,RLENGTH)) 50 }
165}' 51 }
166 52 if (system("test -r " libcpp) == 0)
167udevadm --version 2>&1 | 53 printversion("Linux C++ Library", version("readlink " libcpp))
168awk '/[0-9]+([.]?[0-9]+)+/ && !/not found$/{ 54
169 match($0, /[0-9]+([.]?[0-9]+)+/) 55 printversion("Procps", version("ps --version 2>&1"))
170 printf("Udev\t\t\t%s\n", 56 printversion("Net-tools", version("ifconfig --version 2>&1"))
171 substr($0,RSTART,RLENGTH)) 57 printversion("Kbd", version("loadkeys -V 2>&1"))
172}' 58 printversion("Console-tools", version("loadkeys -V 2>&1"))
59 printversion("Oprofile", version("oprofiled --version 2>&1"))
60 printversion("Sh-utils", version("expr --v 2>&1"))
61 printversion("Udev", version("udevadm --version 2>&1"))
62 printversion("Wireless-tools", version("iwconfig --version 2>&1"))
63
64 if (system("test -r /proc/modules") == 0) {
65 while ("sort /proc/modules" | getline > 0) {
66 mods = mods sep $1
67 sep = " "
68 }
69 printversion("Modules Loaded", mods)
70 }
71}
173 72
174iwconfig --version 2>&1 | 73function version(cmd, ver) {
175awk '/version/{ 74 while (cmd | getline > 0) {
176 match($0, /[0-9]+([.]?[0-9]+)+/) 75 if (!/ver_linux/ && match($0, /[0-9]+([.]?[0-9]+)+/)) {
177 printf("Wireless-tools\t\t%s\n", 76 ver = substr($0, RSTART, RLENGTH)
178 substr($0,RSTART,RLENGTH)) 77 break
179}' 78 }
79 }
80 close(cmd)
81 return ver
82}
180 83
181test -e /proc/modules && 84function printversion(name, value, ofmt) {
182sort /proc/modules | 85 if (value != "") {
183sed ' 86 ofmt = "%-20s\t%s\n"
184 s/ .*// 87 printf(ofmt, name, value)
185 H 88 }
186${
187 g
188 s/^\n/Modules Loaded\t\t/
189 y/\n/ /
190 q
191} 89}
192 d
193'