diff options
Diffstat (limited to 'scripts')
| -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..0896d64445 --- /dev/null +++ b/scripts/contrib/bbvars.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python + +# 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 (errno, strerror): +        print 'WARNING: Failed to open recipe ', recipe +        print strerror + +    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)).iterkeys(): +                    if bbvars.has_key(key): +                        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 (errno, strerror): +            print 'WARNING: Failed to open doc ', doc +            print strerror +        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 (errno, strerror): +        return strerror + +    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, 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).iteritems(): +            if bbvars.has_key(key): +                bbvars[key] = bbvars[key] + cnt +            else: +                bbvars[key] = cnt + +    # Check each var for documentation +    varlen = 0 +    for v in bbvars.iterkeys(): +        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() | 
