VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200   1) #!/usr/bin/env python3
4f19048fd0a00 (Thomas Gleixner   2019-05-27 08:55:14 +0200   2) # SPDX-License-Identifier: GPL-2.0-only
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200   3) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100   4) """Find Kconfig symbols that are referenced but not defined."""
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200   5) 
8e8e333179d6e (Valentin Rothberg 2017-01-18 13:08:19 +0100   6) # (c) 2014-2017 Valentin Rothberg <valentinrothberg@gmail.com>
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100   7) # (c) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200   8) #
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200   9) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  10) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  11) import argparse
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100  12) import difflib
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  13) import os
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  14) import re
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200  15) import signal
f175ba174ef3c (Valentin Rothberg 2016-08-27 10:59:07 +0200  16) import subprocess
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  17) import sys
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200  18) from multiprocessing import Pool, cpu_count
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  19) 
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100  20) 
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100  21) # regex expressions
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  22) OPERATORS = r"&|\(|\)|\||\!"
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  23) SYMBOL = r"(?:\w*[A-Z0-9]\w*){2,}"
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  24) DEF = r"^\s*(?:menu){,1}config\s+(" + SYMBOL + r")\s*"
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  25) EXPR = r"(?:" + OPERATORS + r"|\s|" + SYMBOL + r")+"
0bd38ae355227 (Valentin Rothberg 2015-07-27 12:33:05 +0200  26) DEFAULT = r"default\s+.*?(?:if\s.+){,1}"
3b28f4f2c2c7f (Valentin Rothberg 2017-02-02 18:00:44 +0100  27) STMT = r"^\s*(?:if|select|imply|depends\s+on|(?:" + DEFAULT + r"))\s+" + EXPR
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  28) SOURCE_SYMBOL = r"(?:\W|\b)+[D]{,1}CONFIG_(" + SYMBOL + r")"
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  29) 
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100  30) # regex objects
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  31) REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$")
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  32) REGEX_SYMBOL = re.compile(r'(?!\B)' + SYMBOL + r'(?!\B)')
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  33) REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL)
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100  34) REGEX_KCONFIG_DEF = re.compile(DEF)
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  35) REGEX_KCONFIG_EXPR = re.compile(EXPR)
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  36) REGEX_KCONFIG_STMT = re.compile(STMT)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200  37) REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$")
0bd38ae355227 (Valentin Rothberg 2015-07-27 12:33:05 +0200  38) REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+")
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200  39) REGEX_QUOTES = re.compile("(\"(.*?)\")")
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  40) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200  41) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  42) def parse_options():
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  43)     """The user interface of this module."""
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  44)     usage = "Run this tool to detect Kconfig symbols that are referenced but " \
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  45)             "not defined in Kconfig.  If no option is specified, "             \
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  46)             "checkkconfigsymbols defaults to check your current tree.  "       \
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  47)             "Please note that specifying commits will 'git reset --hard\' "    \
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  48)             "your current tree!  You may save uncommitted changes to avoid "   \
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  49)             "losing data."
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  50) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  51)     parser = argparse.ArgumentParser(description=usage)
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  52) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  53)     parser.add_argument('-c', '--commit', dest='commit', action='store',
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  54)                         default="",
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  55)                         help="check if the specified commit (hash) introduces "
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  56)                              "undefined Kconfig symbols")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  57) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  58)     parser.add_argument('-d', '--diff', dest='diff', action='store',
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  59)                         default="",
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  60)                         help="diff undefined symbols between two commits "
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  61)                              "(e.g., -d commmit1..commit2)")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  62) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  63)     parser.add_argument('-f', '--find', dest='find', action='store_true',
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  64)                         default=False,
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  65)                         help="find and show commits that may cause symbols to be "
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  66)                              "missing (required to run with --diff)")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  67) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  68)     parser.add_argument('-i', '--ignore', dest='ignore', action='store',
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  69)                         default="",
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  70)                         help="ignore files matching this Python regex "
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  71)                              "(e.g., -i '.*defconfig')")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  72) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  73)     parser.add_argument('-s', '--sim', dest='sim', action='store', default="",
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  74)                         help="print a list of max. 10 string-similar symbols")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  75) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  76)     parser.add_argument('--force', dest='force', action='store_true',
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  77)                         default=False,
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  78)                         help="reset current Git tree even when it's dirty")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  79) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  80)     parser.add_argument('--no-color', dest='color', action='store_false',
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  81)                         default=True,
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  82)                         help="don't print colored output (default when not "
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  83)                              "outputting to a terminal)")
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  84) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  85)     args = parser.parse_args()
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  86) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  87)     if args.commit and args.diff:
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  88)         sys.exit("Please specify only one option at once.")
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  89) 
0d18c19288601 (Valentin Rothberg 2016-10-27 14:34:57 +0200  90)     if args.diff and not re.match(r"^[\w\-\.\^]+\.\.[\w\-\.\^]+$", args.diff):
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  91)         sys.exit("Please specify valid input in the following format: "
38cbfe4fe8071 (Andreas Ziegler   2016-03-31 09:24:29 +0200  92)                  "\'commit1..commit2\'")
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  93) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  94)     if args.commit or args.diff:
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200  95)         if not args.force and tree_is_dirty():
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  96)             sys.exit("The current Git tree is dirty (see 'git status').  "
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  97)                      "Running this script may\ndelete important data since it "
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  98)                      "calls 'git reset --hard' for some performance\nreasons. "
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100  99)                      " Please run this script in a clean Git tree or pass "
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 100)                      "'--force' if you\nwant to ignore this warning and "
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 101)                      "continue.")
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 102) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 103)     if args.commit:
d62d5aed3354a (Ariel Marcovitch  2021-09-01 17:52:12 +0300 104)         if args.commit.startswith('HEAD'):
d62d5aed3354a (Ariel Marcovitch  2021-09-01 17:52:12 +0300 105)             sys.exit("The --commit option can't use the HEAD ref")
d62d5aed3354a (Ariel Marcovitch  2021-09-01 17:52:12 +0300 106) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 107)         args.find = False
a42fa92ce77a9 (Valentin Rothberg 2015-06-01 16:00:19 +0200 108) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 109)     if args.ignore:
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 110)         try:
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 111)             re.match(args.ignore, "this/is/just/a/test.c")
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 112)         except:
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 113)             sys.exit("Please specify a valid Python regex.")
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 114) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 115)     return args
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 116) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 117) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 118) def main():
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 119)     """Main function of this module."""
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 120)     args = parse_options()
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 121) 
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 122)     global COLOR
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 123)     COLOR = args.color and sys.stdout.isatty()
4c73c0882b34d (Andrew Donnellan  2016-07-05 17:47:37 +1000 124) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 125)     if args.sim and not args.commit and not args.diff:
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 126)         sims = find_sims(args.sim, args.ignore)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 127)         if sims:
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 128)             print("%s: %s" % (yel("Similar symbols"), ', '.join(sims)))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 129)         else:
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 130)             print("%s: no similar symbols found" % yel("Similar symbols"))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 131)         sys.exit(0)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 132) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 133)     # dictionary of (un)defined symbols
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 134)     defined = {}
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 135)     undefined = {}
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 136) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 137)     if args.commit or args.diff:
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 138)         head = get_head()
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 139) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 140)         # get commit range
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 141)         commit_a = None
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 142)         commit_b = None
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 143)         if args.commit:
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 144)             commit_a = args.commit + "~"
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 145)             commit_b = args.commit
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 146)         elif args.diff:
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 147)             split = args.diff.split("..")
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 148)             commit_a = split[0]
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 149)             commit_b = split[1]
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 150)             undefined_a = {}
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 151)             undefined_b = {}
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 152) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 153)         # get undefined items before the commit
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 154)         reset(commit_a)
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 155)         undefined_a, _ = check_symbols(args.ignore)
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 156) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 157)         # get undefined items for the commit
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 158)         reset(commit_b)
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 159)         undefined_b, defined = check_symbols(args.ignore)
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 160) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 161)         # report cases that are present for the commit but not before
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 162)         for symbol in sorted(undefined_b):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 163)             # symbol has not been undefined before
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 164)             if symbol not in undefined_a:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 165)                 files = sorted(undefined_b.get(symbol))
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 166)                 undefined[symbol] = files
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 167)             # check if there are new files that reference the undefined symbol
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 168)             else:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 169)                 files = sorted(undefined_b.get(symbol) -
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 170)                                undefined_a.get(symbol))
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 171)                 if files:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 172)                     undefined[symbol] = files
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 173) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 174)         # reset to head
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 175)         reset(head)
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 176) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 177)     # default to check the entire tree
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 178)     else:
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 179)         undefined, defined = check_symbols(args.ignore)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 180) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 181)     # now print the output
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 182)     for symbol in sorted(undefined):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 183)         print(red(symbol))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 184) 
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 185)         files = sorted(undefined.get(symbol))
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 186)         print("%s: %s" % (yel("Referencing files"), ", ".join(files)))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 187) 
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 188)         sims = find_sims(symbol, args.ignore, defined)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 189)         sims_out = yel("Similar symbols")
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 190)         if sims:
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 191)             print("%s: %s" % (sims_out, ', '.join(sims)))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 192)         else:
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 193)             print("%s: %s" % (sims_out, "no similar symbols found"))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 194) 
14390e31641e6 (Valentin Rothberg 2016-08-28 08:51:29 +0200 195)         if args.find:
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 196)             print("%s:" % yel("Commits changing symbol"))
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 197)             commits = find_commits(symbol, args.diff)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 198)             if commits:
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 199)                 for commit in commits:
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 200)                     commit = commit.split(" ", 1)
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 201)                     print("\t- %s (\"%s\")" % (yel(commit[0]), commit[1]))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 202)             else:
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 203)                 print("\t- no commit found")
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 204)         print()  # new line
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 205) 
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 206) 
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 207) def reset(commit):
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 208)     """Reset current git tree to %commit."""
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 209)     execute(["git", "reset", "--hard", commit])
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 210) 
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 211) 
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 212) def yel(string):
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 213)     """
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 214)     Color %string yellow.
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 215)     """
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 216)     return "\033[33m%s\033[0m" % string if COLOR else string
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 217) 
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 218) 
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 219) def red(string):
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 220)     """
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 221)     Color %string red.
c745566306e36 (Valentin Rothberg 2015-06-01 16:00:20 +0200 222)     """
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 223)     return "\033[31m%s\033[0m" % string if COLOR else string
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 224) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 225) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 226) def execute(cmd):
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 227)     """Execute %cmd and return stdout.  Exit in case of error."""
f175ba174ef3c (Valentin Rothberg 2016-08-27 10:59:07 +0200 228)     try:
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 229)         stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 230)         stdout = stdout.decode(errors='replace')
f175ba174ef3c (Valentin Rothberg 2016-08-27 10:59:07 +0200 231)     except subprocess.CalledProcessError as fail:
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 232)         exit(fail)
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 233)     return stdout
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 234) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 235) 
a42fa92ce77a9 (Valentin Rothberg 2015-06-01 16:00:19 +0200 236) def find_commits(symbol, diff):
a42fa92ce77a9 (Valentin Rothberg 2015-06-01 16:00:19 +0200 237)     """Find commits changing %symbol in the given range of %diff."""
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 238)     commits = execute(["git", "log", "--pretty=oneline",
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 239)                        "--abbrev-commit", "-G",
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 240)                        symbol, diff])
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 241)     return [x for x in commits.split("\n") if x]
a42fa92ce77a9 (Valentin Rothberg 2015-06-01 16:00:19 +0200 242) 
a42fa92ce77a9 (Valentin Rothberg 2015-06-01 16:00:19 +0200 243) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 244) def tree_is_dirty():
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 245)     """Return true if the current working tree is dirty (i.e., if any file has
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 246)     been added, deleted, modified, renamed or copied but not committed)."""
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 247)     stdout = execute(["git", "status", "--porcelain"])
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 248)     for line in stdout:
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 249)         if re.findall(r"[URMADC]{1}", line[:2]):
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 250)             return True
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 251)     return False
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 252) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 253) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 254) def get_head():
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 255)     """Return commit hash of current HEAD."""
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 256)     stdout = execute(["git", "rev-parse", "HEAD"])
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 257)     return stdout.strip('\n')
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 258) 
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 259) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 260) def partition(lst, size):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 261)     """Partition list @lst into eveni-sized lists of size @size."""
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 262)     return [lst[i::size] for i in range(size)]
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 263) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 264) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 265) def init_worker():
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 266)     """Set signal handler to ignore SIGINT."""
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 267)     signal.signal(signal.SIGINT, signal.SIG_IGN)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 268) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 269) 
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 270) def find_sims(symbol, ignore, defined=[]):
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 271)     """Return a list of max. ten Kconfig symbols that are string-similar to
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 272)     @symbol."""
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 273)     if defined:
8e8e333179d6e (Valentin Rothberg 2017-01-18 13:08:19 +0100 274)         return difflib.get_close_matches(symbol, set(defined), 10)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 275) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 276)     pool = Pool(cpu_count(), init_worker)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 277)     kfiles = []
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 278)     for gitfile in get_files():
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 279)         if REGEX_FILE_KCONFIG.match(gitfile):
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 280)             kfiles.append(gitfile)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 281) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 282)     arglist = []
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 283)     for part in partition(kfiles, cpu_count()):
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 284)         arglist.append((part, ignore))
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 285) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 286)     for res in pool.map(parse_kconfig_files, arglist):
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 287)         defined.extend(res[0])
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 288) 
8e8e333179d6e (Valentin Rothberg 2017-01-18 13:08:19 +0100 289)     return difflib.get_close_matches(symbol, set(defined), 10)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 290) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 291) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 292) def get_files():
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 293)     """Return a list of all files in the current git directory."""
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 294)     # use 'git ls-files' to get the worklist
2f9cc12bb34a4 (Valentin Rothberg 2016-08-28 08:51:32 +0200 295)     stdout = execute(["git", "ls-files"])
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 296)     if len(stdout) > 0 and stdout[-1] == "\n":
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 297)         stdout = stdout[:-1]
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 298) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 299)     files = []
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 300)     for gitfile in stdout.rsplit("\n"):
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 301)         if ".git" in gitfile or "ChangeLog" in gitfile or      \
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 302)                 ".log" in gitfile or os.path.isdir(gitfile) or \
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 303)                 gitfile.startswith("tools/"):
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 304)             continue
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 305)         files.append(gitfile)
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 306)     return files
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 307) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 308) 
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 309) def check_symbols(ignore):
b1a3f243485fa (Valentin Rothberg 2015-03-16 12:16:14 +0100 310)     """Find undefined Kconfig symbols and return a dict with the symbol as key
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 311)     and a list of referencing files as value.  Files matching %ignore are not
cf132e4a8e070 (Valentin Rothberg 2015-04-29 16:58:27 +0200 312)     checked for undefined symbols."""
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 313)     pool = Pool(cpu_count(), init_worker)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 314)     try:
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 315)         return check_symbols_helper(pool, ignore)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 316)     except KeyboardInterrupt:
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 317)         pool.terminate()
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 318)         pool.join()
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 319)         sys.exit(1)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 320) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 321) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 322) def check_symbols_helper(pool, ignore):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 323)     """Helper method for check_symbols().  Used to catch keyboard interrupts in
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 324)     check_symbols() in order to properly terminate running worker processes."""
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 325)     source_files = []
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 326)     kconfig_files = []
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 327)     defined_symbols = []
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 328)     referenced_symbols = dict()  # {file: [symbols]}
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 329) 
1b2c841467515 (Valentin Rothberg 2015-11-26 14:17:15 +0100 330)     for gitfile in get_files():
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 331)         if REGEX_FILE_KCONFIG.match(gitfile):
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 332)             kconfig_files.append(gitfile)
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 333)         else:
1439ebd2ce772 (Ariel Marcovitch  2021-08-22 22:22:01 +0300 334)             if ignore and re.match(ignore, gitfile):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 335)                 continue
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 336)             # add source files that do not match the ignore pattern
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 337)             source_files.append(gitfile)
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 338) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 339)     # parse source files
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 340)     arglist = partition(source_files, cpu_count())
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 341)     for res in pool.map(parse_source_files, arglist):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 342)         referenced_symbols.update(res)
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 343) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 344)     # parse kconfig files
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 345)     arglist = []
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 346)     for part in partition(kconfig_files, cpu_count()):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 347)         arglist.append((part, ignore))
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 348)     for res in pool.map(parse_kconfig_files, arglist):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 349)         defined_symbols.extend(res[0])
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 350)         referenced_symbols.update(res[1])
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 351)     defined_symbols = set(defined_symbols)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 352) 
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 353)     # inverse mapping of referenced_symbols to dict(symbol: [files])
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 354)     inv_map = dict()
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 355)     for _file, symbols in referenced_symbols.items():
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 356)         for symbol in symbols:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 357)             inv_map[symbol] = inv_map.get(symbol, set())
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 358)             inv_map[symbol].add(_file)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 359)     referenced_symbols = inv_map
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 360) 
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 361)     undefined = {}  # {symbol: [files]}
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 362)     for symbol in sorted(referenced_symbols):
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100 363)         # filter some false positives
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 364)         if symbol == "FOO" or symbol == "BAR" or \
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 365)                 symbol == "FOO_BAR" or symbol == "XXX":
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100 366)             continue
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 367)         if symbol not in defined_symbols:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 368)             if symbol.endswith("_MODULE"):
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100 369)                 # avoid false positives for kernel modules
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 370)                 if symbol[:-len("_MODULE")] in defined_symbols:
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 371)                     continue
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 372)             undefined[symbol] = referenced_symbols.get(symbol)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 373)     return undefined, defined_symbols
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 374) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 375) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 376) def parse_source_files(source_files):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 377)     """Parse each source file in @source_files and return dictionary with source
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 378)     files as keys and lists of references Kconfig symbols as values."""
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 379)     referenced_symbols = dict()
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 380)     for sfile in source_files:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 381)         referenced_symbols[sfile] = parse_source_file(sfile)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 382)     return referenced_symbols
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 383) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 384) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 385) def parse_source_file(sfile):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 386)     """Parse @sfile and return a list of referenced Kconfig symbols."""
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 387)     lines = []
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 388)     references = []
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 389) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 390)     if not os.path.exists(sfile):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 391)         return references
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 392) 
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 393)     with open(sfile, "r", encoding='utf-8', errors='replace') as stream:
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 394)         lines = stream.readlines()
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 395) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 396)     for line in lines:
36c79c7face54 (Valentin Rothberg 2016-08-28 08:51:30 +0200 397)         if "CONFIG_" not in line:
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 398)             continue
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 399)         symbols = REGEX_SOURCE_SYMBOL.findall(line)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 400)         for symbol in symbols:
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 401)             if not REGEX_FILTER_SYMBOLS.search(symbol):
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 402)                 continue
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 403)             references.append(symbol)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 404) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 405)     return references
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 406) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 407) 
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 408) def get_symbols_in_line(line):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 409)     """Return mentioned Kconfig symbols in @line."""
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 410)     return REGEX_SYMBOL.findall(line)
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 411) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 412) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 413) def parse_kconfig_files(args):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 414)     """Parse kconfig files and return tuple of defined and references Kconfig
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 415)     symbols.  Note, @args is a tuple of a list of files and the @ignore
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 416)     pattern."""
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 417)     kconfig_files = args[0]
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 418)     ignore = args[1]
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 419)     defined_symbols = []
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 420)     referenced_symbols = dict()
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 421) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 422)     for kfile in kconfig_files:
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 423)         defined, references = parse_kconfig_file(kfile)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 424)         defined_symbols.extend(defined)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 425)         if ignore and re.match(ignore, kfile):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 426)             # do not collect references for files that match the ignore pattern
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 427)             continue
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 428)         referenced_symbols[kfile] = references
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 429)     return (defined_symbols, referenced_symbols)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 430) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 431) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 432) def parse_kconfig_file(kfile):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 433)     """Parse @kfile and update symbol definitions and references."""
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 434)     lines = []
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 435)     defined = []
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 436)     references = []
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 437) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 438)     if not os.path.exists(kfile):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 439)         return defined, references
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 440) 
7c5227af25a1b (Valentin Rothberg 2016-08-28 08:51:28 +0200 441)     with open(kfile, "r", encoding='utf-8', errors='replace') as stream:
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 442)         lines = stream.readlines()
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 443) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 444)     for i in range(len(lines)):
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 445)         line = lines[i]
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 446)         line = line.strip('\n')
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100 447)         line = line.split("#")[0]  # ignore comments
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 448) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 449)         if REGEX_KCONFIG_DEF.match(line):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 450)             symbol_def = REGEX_KCONFIG_DEF.findall(line)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 451)             defined.append(symbol_def[0])
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 452)         elif REGEX_KCONFIG_STMT.match(line):
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 453)             line = REGEX_QUOTES.sub("", line)
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 454)             symbols = get_symbols_in_line(line)
cc641d5529965 (Valentin Rothberg 2014-11-08 20:56:35 +0100 455)             # multi-line statements
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 456)             while line.endswith("\\"):
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 457)                 i += 1
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 458)                 line = lines[i]
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 459)                 line = line.strip('\n')
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 460)                 symbols.extend(get_symbols_in_line(line))
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 461)             for symbol in set(symbols):
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 462)                 if REGEX_NUMERIC.match(symbol):
0bd38ae355227 (Valentin Rothberg 2015-07-27 12:33:05 +0200 463)                     # ignore numeric values
0bd38ae355227 (Valentin Rothberg 2015-07-27 12:33:05 +0200 464)                     continue
ef3f55438d95f (Valentin Rothberg 2016-08-28 08:51:31 +0200 465)                 references.append(symbol)
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 466) 
e2042a8a80ab5 (Valentin Rothberg 2015-10-15 10:37:47 +0200 467)     return defined, references
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 468) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 469) 
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 470) if __name__ == "__main__":
24fe1f03e4ef8 (Valentin Rothberg 2014-09-27 16:30:45 +0200 471)     main()