zephyr/scripts/kconfig/checkconfig.py
Ulf Magnusson a449c98db2 scripts: Fix risky uses of non-raw regex strings in Python scripts
Fixes pylint warnings like this one:

    doc/conf.py:325:0: W1401: Anomalous backslash in string: '\s'.
    String constant might be missing an r prefix.
    (anomalous-backslash-in-string)

The reason for this warning is that backslash escapes are interpreted in
non-raw (non-r-prefixed) strings. For example, '\a' and r'\a' are not
the same string (first one has a single ASCII bell character, second one
has two characters).

It just happens that there's no \s (or \., or \/) escape for example,
and '\s' turns into two characters (as needed for a regex). It's risky
to rely on stuff like that regexes though. Best to make them raw strings
unless they're super trivial.

Also note that '\s' and '\\s' turn into the same string.

Another tip: A literal ' can be put into a string with "blah'blah"
instead of 'blah\'blah'.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-03-28 14:41:32 -05:00

150 lines
5.6 KiB
Python
Executable File

#!/usr/bin/env python3
# NOTE: This script has not been updated for Kconfiglib 2 and will not run
"""Zephyr Check kconfigs Definitions
Check all CONFIG_* in the code are defined into a Kconfig file
usage: checkconfig.py [-h] [-k KCONFIG] [-c] [-e EXCLUDE]
"""
import sys
import os
import re
import argparse
from argparse import SUPPRESS
help_text="""
Checkconfig script scans all '*.c', '*.h' and '*.S' looking for all kconfig
items used in the Zephyr Code and validates if they are defined in any
'*.kconfig*' file.
To run script use command:
checkconfig.py [-h|--help] [-c|--complete-log] [-k|--kconfig <kconfig>]
[-e|--exclude <dir_to_exclude>]
It will send to output:
-config name
-location where config is used
-full line where the config is being used
-location were config is being defined (there could be multiple declarations)
[-c|--complete-log] is an optional parameter.
If it is not given it will print only the kconfigs not defined
If given, it will print all the kconfigs found
[-s|--subdir <subdir>] is an optional parameter.
When a directory is given it will start scan from that specific directorywith .
By default it scans from zephyr base tree
[-e|--exclude <subdir_to_exclude>] is an optional parameter.
When a subdirectory is given it will be appended to defaut exclude dirs list.
Default exclude dirs are: "doc", "sanity-out" and "outdir"
"""
#the genrest dir contains kconfiglib.py
zephyrbase = os.environ.get('ZEPHYR_BASE')
if zephyrbase == None:
print ("env. variable ZEPHYR_BASE is not set, "
"ensure you have source zephyr-env.sh")
exit(1)
elif not os.path.exists(zephyrbase):
print ("env. variable ZEPHYR_BASE \""+ zephyrbase +
"\" does not exist as a valid zephyr base directory")
exit(1)
os.environ['srctree'] = os.path.join(zephyrbase + os.path.sep)
sys.path.append(os.path.join(zephyrbase,'doc','scripts','genrest'))
import kconfiglib
def separate_location_lines(dirs):
for dir in dirs:
print(" ", dir)
def search_kconfig_items(items, name, completelog):
findConfig = False
for item in items:
if item.is_symbol():
if item.get_name() == name:
if completelog:
separate_location_lines(item.get_def_locations())
findConfig = True
break
elif item.is_menu():
if search_kconfig_items(item.get_items(), name, completelog):
return True
elif item.is_choice():
if search_kconfig_items(item.get_items(), name, completelog):
return True
elif item.is_comment():
if item.get_text() == name:
print(completelog)
if completelog:
separate_location_lines(item.get_location())
findConfig = True
break
return findConfig
def search_config_in_file(tree, items, completelog, exclude):
configs = 0
notdefConfig = 0
for dirName, subdirs, files in os.walk(tree, topdown=True):
subdirs[:] = [d for d in subdirs if d not in exclude]
for fname in files:
if (fname.endswith(".c") or
fname.endswith(".h") or
fname.endswith(".S")):
with open(os.path.join(dirName, fname), "r", encoding="utf-8", errors="ignore") as f:
searchConf = f.readlines()
for line in searchConf:
if re.search(r'(^|[\s|(])CONFIG_([a-zA-Z0-9_]+)', line) :
configName = re.search(r'(^|[\s|(])'
+ r'CONFIG_([a-zA-Z0-9_]+)', line)
configs = configs + 1
if completelog:
print('\n' + configName.group(2) + ' at '
+ os.path.join(dirName, fname))
print('line: ' + line.rstrip())
find = search_kconfig_items(items, configName.group(2),
completelog)
if not find:
print('\n' + configName.group(2) + ' at '
+ os.path.join(dirName, fname)
+ ' IS NOT DEFINED')
print('line: ' + line.rstrip())
notdefConfig = notdefConfig + 1
if completelog:
print("\n{} Kconfigs evaluated".format(configs))
print("{} Kconfigs not defined".format(notdefConfig))
parser = argparse.ArgumentParser(description = help_text,
usage = SUPPRESS,
formatter_class = argparse.RawTextHelpFormatter)
parser.add_argument('-s', '--subdir', action='store', dest='subdir',
default="",
help='sub directory to be scanned')
parser.add_argument('-c', '--complete-log', action='store_true',
dest='completelog', default=False,
help='Prints all the kconfigs found')
parser.add_argument('-e', '--exclude', action='append', dest='exclude',
default=["doc", "sanity-out", "outdir"],
help='Dirs to be excluded for verification')
args= parser.parse_args()
if args.completelog:
print('sub dir = ', os.path.join(zephyrbase + args.subdir))
print('complete-log = ', args.completelog)
print('exclude dirs = ', args.exclude)
conf = kconfiglib.Config(os.path.join(zephyrbase,'Kconfig'))
search_config_in_file(os.path.join(zephyrbase + os.path.sep + args.subdir),
conf.get_top_level_items(), args.completelog, args.exclude)