Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 2 | |
| 3 | # This program is free software; you can redistribute it and/or modify |
| 4 | # it under the terms of the GNU General Public License as published by |
| 5 | # the Free Software Foundation; either version 2 of the License, or |
| 6 | # (at your option) any later version. |
| 7 | # |
| 8 | # This program is distributed in the hope that it will be useful, |
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | # GNU General Public License for more details. |
| 12 | # |
| 13 | # You should have received a copy of the GNU General Public License |
| 14 | # along with this program; if not, write to the Free Software |
| 15 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 16 | # |
| 17 | # Copyright (C) Darren Hart <dvhart@linux.intel.com>, 2010 |
| 18 | |
| 19 | |
| 20 | import sys |
| 21 | import getopt |
| 22 | import os |
| 23 | import os.path |
| 24 | import re |
| 25 | |
| 26 | def usage(): |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 27 | print('Usage: %s -d FILENAME [-d FILENAME]* -m METADIR [-m MATADIR]*' % os.path.basename(sys.argv[0])) |
| 28 | print(' -d FILENAME documentation file to search') |
| 29 | print(' -h, --help display this help and exit') |
| 30 | print(' -m METADIR meta directory to search for recipes') |
| 31 | print(' -t FILENAME documentation config file (for doc tags)') |
| 32 | print(' -T Only display variables with doc tags (requires -t)') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 33 | |
| 34 | def recipe_bbvars(recipe): |
| 35 | ''' Return a unique set of every bbvar encountered in the recipe ''' |
| 36 | prog = re.compile("[A-Z_]+") |
| 37 | vset = set() |
| 38 | try: |
| 39 | r = open(recipe) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 40 | except IOError as err: |
| 41 | print('WARNING: Failed to open recipe ', recipe) |
| 42 | print(err.args[1]) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 43 | |
| 44 | for line in r: |
| 45 | # Strip any comments from the line |
| 46 | line = line.rsplit('#')[0] |
| 47 | vset = vset.union(set(prog.findall(line))) |
| 48 | r.close() |
| 49 | |
| 50 | bbvars = {} |
| 51 | for v in vset: |
| 52 | bbvars[v] = 1 |
| 53 | |
| 54 | return bbvars |
| 55 | |
| 56 | def collect_bbvars(metadir): |
| 57 | ''' Walk the metadir and collect the bbvars from each recipe found ''' |
| 58 | bbvars = {} |
| 59 | for root,dirs,files in os.walk(metadir): |
| 60 | for name in files: |
| 61 | if name.find(".bb") >= 0: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 62 | for key in recipe_bbvars(os.path.join(root,name)).keys(): |
| 63 | if key in bbvars: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 64 | bbvars[key] = bbvars[key] + 1 |
| 65 | else: |
| 66 | bbvars[key] = 1 |
| 67 | return bbvars |
| 68 | |
| 69 | def bbvar_is_documented(var, docfiles): |
| 70 | prog = re.compile(".*($|[^A-Z_])%s([^A-Z_]|$)" % (var)) |
| 71 | for doc in docfiles: |
| 72 | try: |
| 73 | f = open(doc) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 74 | except IOError as err: |
| 75 | print('WARNING: Failed to open doc ', doc) |
| 76 | print(err.args[1]) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 77 | for line in f: |
| 78 | if prog.match(line): |
| 79 | return True |
| 80 | f.close() |
| 81 | return False |
| 82 | |
| 83 | def bbvar_doctag(var, docconf): |
| 84 | prog = re.compile('^%s\[doc\] *= *"(.*)"' % (var)) |
| 85 | if docconf == "": |
| 86 | return "?" |
| 87 | |
| 88 | try: |
| 89 | f = open(docconf) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 90 | except IOError as err: |
| 91 | return err.args[1] |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 92 | |
| 93 | for line in f: |
| 94 | m = prog.search(line) |
| 95 | if m: |
| 96 | return m.group(1) |
| 97 | |
| 98 | f.close() |
| 99 | return "" |
| 100 | |
| 101 | def main(): |
| 102 | docfiles = [] |
| 103 | metadirs = [] |
| 104 | bbvars = {} |
| 105 | undocumented = [] |
| 106 | docconf = "" |
| 107 | onlydoctags = False |
| 108 | |
| 109 | # Collect and validate input |
| 110 | try: |
| 111 | opts, args = getopt.getopt(sys.argv[1:], "d:hm:t:T", ["help"]) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 112 | except getopt.GetoptError as err: |
| 113 | print('%s' % str(err)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 114 | usage() |
| 115 | sys.exit(2) |
| 116 | |
| 117 | for o, a in opts: |
| 118 | if o in ('-h', '--help'): |
| 119 | usage() |
| 120 | sys.exit(0) |
| 121 | elif o == '-d': |
| 122 | if os.path.isfile(a): |
| 123 | docfiles.append(a) |
| 124 | else: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 125 | print('ERROR: documentation file %s is not a regular file' % a) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 126 | sys.exit(3) |
| 127 | elif o == '-m': |
| 128 | if os.path.isdir(a): |
| 129 | metadirs.append(a) |
| 130 | else: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 131 | print('ERROR: meta directory %s is not a directory' % a) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 132 | sys.exit(4) |
| 133 | elif o == "-t": |
| 134 | if os.path.isfile(a): |
| 135 | docconf = a |
| 136 | elif o == "-T": |
| 137 | onlydoctags = True |
| 138 | else: |
| 139 | assert False, "unhandled option" |
| 140 | |
| 141 | if len(docfiles) == 0: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 142 | print('ERROR: no docfile specified') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 143 | usage() |
| 144 | sys.exit(5) |
| 145 | |
| 146 | if len(metadirs) == 0: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 147 | print('ERROR: no metadir specified') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 148 | usage() |
| 149 | sys.exit(6) |
| 150 | |
| 151 | if onlydoctags and docconf == "": |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 152 | print('ERROR: no docconf specified') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 153 | usage() |
| 154 | sys.exit(7) |
| 155 | |
| 156 | # Collect all the variable names from the recipes in the metadirs |
| 157 | for m in metadirs: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 158 | for key,cnt in collect_bbvars(m).items(): |
| 159 | if key in bbvars: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 160 | bbvars[key] = bbvars[key] + cnt |
| 161 | else: |
| 162 | bbvars[key] = cnt |
| 163 | |
| 164 | # Check each var for documentation |
| 165 | varlen = 0 |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 166 | for v in bbvars.keys(): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 167 | if len(v) > varlen: |
| 168 | varlen = len(v) |
| 169 | if not bbvar_is_documented(v, docfiles): |
| 170 | undocumented.append(v) |
| 171 | undocumented.sort() |
| 172 | varlen = varlen + 1 |
| 173 | |
| 174 | # Report all undocumented variables |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 175 | print('Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars))) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 176 | header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7)) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 177 | print(header) |
| 178 | print(str("").ljust(len(header), '=')) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 179 | for v in undocumented: |
| 180 | doctag = bbvar_doctag(v, docconf) |
| 181 | if not onlydoctags or not doctag == "": |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 182 | print('%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 183 | |
| 184 | |
| 185 | if __name__ == "__main__": |
| 186 | main() |