diff --git a/scripts/checkconfig.py b/scripts/checkconfig.py new file mode 100755 index 0000000000..bcffd737e9 --- /dev/null +++ b/scripts/checkconfig.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python + +"""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 ] + [-e|--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 ] 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 ] 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 == True): + 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 == True): + 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") as f: + searchConf = f.readlines() + for i, line in enumerate(searchConf): + if re.search('(^|[\s|(])CONFIG_([a-zA-Z0-9_]+)', line) : + configName = re.search('(^|[\s|(])' + +'CONFIG_([a-zA-Z0-9_]+)', line) + configs = configs + 1 + if (completelog == True): + 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 (find == False): + print ('\n' + configName.group(2) + ' at ' + + os.path.join(dirName, fname) + + ' IS NOT DEFINED') + print 'line: ' + line.rstrip() + notdefConfig = notdefConfig + 1 + if (completelog == True): + 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)