diff options
Diffstat (limited to 'scripts/contrib/bbvars.py')
| -rwxr-xr-x | scripts/contrib/bbvars.py | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/scripts/contrib/bbvars.py b/scripts/contrib/bbvars.py new file mode 100755 index 0000000000..d8d0594776 --- /dev/null +++ b/scripts/contrib/bbvars.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Copyright (C) Darren Hart <dvhart@linux.intel.com>, 2010 + + +import sys +import getopt +import os +import os.path +import re + +def usage(): + print('Usage: %s -d FILENAME [-d FILENAME]* -m METADIR [-m MATADIR]*' % os.path.basename(sys.argv[0])) + print(' -d FILENAME documentation file to search') + print(' -h, --help display this help and exit') + print(' -m METADIR meta directory to search for recipes') + print(' -t FILENAME documentation config file (for doc tags)') + print(' -T Only display variables with doc tags (requires -t)') + +def recipe_bbvars(recipe): + ''' Return a unique set of every bbvar encountered in the recipe ''' + prog = re.compile("[A-Z_]+") + vset = set() + try: + r = open(recipe) + except IOError as err: + print('WARNING: Failed to open recipe ', recipe) + print(err.args[1]) + + for line in r: + # Strip any comments from the line + line = line.rsplit('#')[0] + vset = vset.union(set(prog.findall(line))) + r.close() + + bbvars = {} + for v in vset: + bbvars[v] = 1 + + return bbvars + +def collect_bbvars(metadir): + ''' Walk the metadir and collect the bbvars from each recipe found ''' + bbvars = {} + for root,dirs,files in os.walk(metadir): + for name in files: + if name.find(".bb") >= 0: + for key in recipe_bbvars(os.path.join(root,name)).keys(): + if key in bbvars: + bbvars[key] = bbvars[key] + 1 + else: + bbvars[key] = 1 + return bbvars + +def bbvar_is_documented(var, docfiles): + prog = re.compile(".*($|[^A-Z_])%s([^A-Z_]|$)" % (var)) + for doc in docfiles: + try: + f = open(doc) + except IOError as err: + print('WARNING: Failed to open doc ', doc) + print(err.args[1]) + for line in f: + if prog.match(line): + return True + f.close() + return False + +def bbvar_doctag(var, docconf): + prog = re.compile('^%s\[doc\] *= *"(.*)"' % (var)) + if docconf == "": + return "?" + + try: + f = open(docconf) + except IOError as err: + return err.args[1] + + for line in f: + m = prog.search(line) + if m: + return m.group(1) + + f.close() + return "" + +def main(): + docfiles = [] + metadirs = [] + bbvars = {} + undocumented = [] + docconf = "" + onlydoctags = False + + # Collect and validate input + try: + opts, args = getopt.getopt(sys.argv[1:], "d:hm:t:T", ["help"]) + except getopt.GetoptError as err: + print('%s' % str(err)) + usage() + sys.exit(2) + + for o, a in opts: + if o in ('-h', '--help'): + usage() + sys.exit(0) + elif o == '-d': + if os.path.isfile(a): + docfiles.append(a) + else: + print('ERROR: documentation file %s is not a regular file' % a) + sys.exit(3) + elif o == '-m': + if os.path.isdir(a): + metadirs.append(a) + else: + print('ERROR: meta directory %s is not a directory' % a) + sys.exit(4) + elif o == "-t": + if os.path.isfile(a): + docconf = a + elif o == "-T": + onlydoctags = True + else: + assert False, "unhandled option" + + if len(docfiles) == 0: + print('ERROR: no docfile specified') + usage() + sys.exit(5) + + if len(metadirs) == 0: + print('ERROR: no metadir specified') + usage() + sys.exit(6) + + if onlydoctags and docconf == "": + print('ERROR: no docconf specified') + usage() + sys.exit(7) + + # Collect all the variable names from the recipes in the metadirs + for m in metadirs: + for key,cnt in collect_bbvars(m).items(): + if key in bbvars: + bbvars[key] = bbvars[key] + cnt + else: + bbvars[key] = cnt + + # Check each var for documentation + varlen = 0 + for v in bbvars.keys(): + if len(v) > varlen: + varlen = len(v) + if not bbvar_is_documented(v, docfiles): + undocumented.append(v) + undocumented.sort() + varlen = varlen + 1 + + # Report all undocumented variables + print('Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars))) + header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7)) + print(header) + print(str("").ljust(len(header), '=')) + for v in undocumented: + doctag = bbvar_doctag(v, docconf) + if not onlydoctags or not doctag == "": + print('%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag)) + + +if __name__ == "__main__": + main() |
