diff options
Diffstat (limited to 'scripts/contrib')
-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 @@ | |||
1 | #!/usr/bin/env python | ||
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(): | ||
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)' | ||
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) | ||
40 | except IOError as (errno, strerror): | ||
41 | print 'WARNING: Failed to open recipe ', recipe | ||
42 | print strerror | ||
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: | ||
62 | for key in recipe_bbvars(os.path.join(root,name)).iterkeys(): | ||
63 | if bbvars.has_key(key): | ||
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) | ||
74 | except IOError as (errno, strerror): | ||
75 | print 'WARNING: Failed to open doc ', doc | ||
76 | print strerror | ||
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) | ||
90 | except IOError as (errno, strerror): | ||
91 | return strerror | ||
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"]) | ||
112 | except getopt.GetoptError, err: | ||
113 | print '%s' % str(err) | ||
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: | ||
125 | print 'ERROR: documentation file %s is not a regular file' % (a) | ||
126 | sys.exit(3) | ||
127 | elif o == '-m': | ||
128 | if os.path.isdir(a): | ||
129 | metadirs.append(a) | ||
130 | else: | ||
131 | print 'ERROR: meta directory %s is not a directory' % (a) | ||
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: | ||
142 | print 'ERROR: no docfile specified' | ||
143 | usage() | ||
144 | sys.exit(5) | ||
145 | |||
146 | if len(metadirs) == 0: | ||
147 | print 'ERROR: no metadir specified' | ||
148 | usage() | ||
149 | sys.exit(6) | ||
150 | |||
151 | if onlydoctags and docconf == "": | ||
152 | print 'ERROR: no docconf specified' | ||
153 | usage() | ||
154 | sys.exit(7) | ||
155 | |||
156 | # Collect all the variable names from the recipes in the metadirs | ||
157 | for m in metadirs: | ||
158 | for key,cnt in collect_bbvars(m).iteritems(): | ||
159 | if bbvars.has_key(key): | ||
160 | bbvars[key] = bbvars[key] + cnt | ||
161 | else: | ||
162 | bbvars[key] = cnt | ||
163 | |||
164 | # Check each var for documentation | ||
165 | varlen = 0 | ||
166 | for v in bbvars.iterkeys(): | ||
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 | ||
175 | print 'Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars)) | ||
176 | header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7)) | ||
177 | print header | ||
178 | print str("").ljust(len(header), '=') | ||
179 | for v in undocumented: | ||
180 | doctag = bbvar_doctag(v, docconf) | ||
181 | if not onlydoctags or not doctag == "": | ||
182 | print '%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag) | ||
183 | |||
184 | |||
185 | if __name__ == "__main__": | ||
186 | main() | ||