Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: ppapi/generators/idl_generator.py

Issue 8538029: Cleanup IDL Generator (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/generators/idl_c_proto.py ('k') | ppapi/generators/idl_node.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 import sys 7 import sys
8 8
9 from idl_log import ErrOut, InfoOut, WarnOut 9 from idl_log import ErrOut, InfoOut, WarnOut
10 from idl_option import GetOption, Option, ParseOptions 10 from idl_option import GetOption, Option, ParseOptions
11 from idl_parser import ParseFiles
11 12
12 GeneratorList = [] 13 GeneratorList = []
13 14
14 Option('release', 'Which release to generate.', default='') 15 Option('release', 'Which release to generate.', default='')
15 Option('range', 'Which ranges in the form of MIN,MAX.', default='start,end') 16 Option('range', 'Which ranges in the form of MIN,MAX.', default='start,end')
16 17
17 18
18 # 19 #
19 # Generator 20 # Generator
20 # 21 #
(...skipping 11 matching lines...) Expand all
32 # NOTE: Generators still have access to global options 33 # NOTE: Generators still have access to global options
33 34
34 class Generator(object): 35 class Generator(object):
35 def __init__(self, name, sname, desc): 36 def __init__(self, name, sname, desc):
36 self.name = name 37 self.name = name
37 self.run_switch = Option(sname, desc) 38 self.run_switch = Option(sname, desc)
38 self.opt_switch = Option(sname + '_opt', 'Options for %s.' % sname, 39 self.opt_switch = Option(sname + '_opt', 'Options for %s.' % sname,
39 default='') 40 default='')
40 GeneratorList.append(self) 41 GeneratorList.append(self)
41 self.errors = 0 42 self.errors = 0
43 self.skip_list = []
42 44
43 def Error(self, msg): 45 def Error(self, msg):
44 ErrOut.Log('Error %s : %s' % (self.name, msg)) 46 ErrOut.Log('Error %s : %s' % (self.name, msg))
45 self.errors += 1 47 self.errors += 1
46 48
47 def GetRunOptions(self): 49 def GetRunOptions(self):
48 options = {} 50 options = {}
49 option_list = self.opt_switch.Get() 51 option_list = self.opt_switch.Get()
50 if option_list: 52 if option_list:
51 option_list = option_list.split(',') 53 option_list = option_list.split(',')
52 for opt in option_list: 54 for opt in option_list:
53 offs = opt.find('=') 55 offs = opt.find('=')
54 if offs > 0: 56 if offs > 0:
55 options[opt[:offs]] = opt[offs+1:] 57 options[opt[:offs]] = opt[offs+1:]
56 else: 58 else:
57 options[opt] = True 59 options[opt] = True
58 return options 60 return options
59 if self.run_switch.Get(): 61 if self.run_switch.Get():
60 return options 62 return options
61 return None 63 return None
62 64
63 def Generate(self, ast, options): 65 def Generate(self, ast, options):
64 self.errors = 0 66 self.errors = 0
65 67
66 rangestr = GetOption('range') 68 rangestr = GetOption('range')
67 releasestr = GetOption('release') 69 releasestr = GetOption('release')
68 70
69 print "Found releases: %s" % ast.releases 71 print "Found releases: %s" % ast.releases
70 72
73 # Generate list of files to ignore due to errors
74 for filenode in ast.GetListOf('File'):
75 # If this file has errors, skip it
76 if filenode.GetProperty('ERRORS') > 0:
77 self.skip_list.append(filenode)
78 continue
79
71 # Check for a range option which over-rides a release option 80 # Check for a range option which over-rides a release option
72 if not releasestr and rangestr: 81 if not releasestr and rangestr:
73 range_list = rangestr.split(',') 82 range_list = rangestr.split(',')
74 if len(range_list) != 2: 83 if len(range_list) != 2:
75 self.Error('Failed to generate for %s, incorrect range: "%s"' % 84 self.Error('Failed to generate for %s, incorrect range: "%s"' %
76 (self.name, rangestr)) 85 (self.name, rangestr))
77 else: 86 else:
78 vmin = range_list[0] 87 vmin = range_list[0]
79 vmax = range_list[1] 88 vmax = range_list[1]
80 89
81 # Generate 'start' and 'end' represent first and last found. 90 # Generate 'start' and 'end' represent first and last found.
82 if vmin == 'start': 91 if vmin == 'start':
83 vmin = ast.releases[0] 92 vmin = ast.releases[0]
84 if vmax == 'end': 93 if vmax == 'end':
85 vmax = ast.releases[-1] 94 vmax = ast.releases[-1]
86 95
87 vmin = ast.releases.index(vmin) 96 vmin = ast.releases.index(vmin)
88 vmax = ast.releases.index(vmax) + 1 97 vmax = ast.releases.index(vmax) + 1
89 range = ast.releases[vmin:vmax] 98 releases = ast.releases[vmin:vmax]
90 InfoOut.Log('Generate range %s of %s.' % (range, self.name)) 99 InfoOut.Log('Generate range %s of %s.' % (range, self.name))
91 ret = self.GenerateRange(ast, range, options) 100 ret = self.GenerateRange(ast, releases, options)
92 if ret < 0: 101 if ret < 0:
93 self.Error('Failed to generate range %s : %s.' %(vmin, vmax)) 102 self.Error('Failed to generate range %s : %s.' %(vmin, vmax))
94 else: 103 else:
95 InfoOut.Log('%s wrote %d files.' % (self.name, ret)) 104 InfoOut.Log('%s wrote %d files.' % (self.name, ret))
96 # Otherwise this should be a single release generation 105 # Otherwise this should be a single release generation
97 else: 106 else:
98 if releasestr: 107 if releasestr:
99 InfoOut.Log('Generate release %s of %s.' % (releasestr, self.name)) 108 InfoOut.Log('Generate release %s of %s.' % (releasestr, self.name))
100 ret = self.GenerateRelease(ast, releasestr, options) 109 ret = self.GenerateRelease(ast, releasestr, options)
101 if ret < 0: 110 if ret < 0:
102 self.Error('Failed to generate release %s.' % releasestr) 111 self.Error('Failed to generate release %s.' % releasestr)
103 else: 112 else:
104 InfoOut.Log('%s wrote %d files.' % (self.name, ret)) 113 InfoOut.Log('%s wrote %d files.' % (self.name, ret))
105 114
106 else: 115 else:
107 self.Error('No range or release specified for %s.' % releasestr) 116 self.Error('No range or release specified for %s.' % releasestr)
108 return self.errors 117 return self.errors
109 118
110 def GenerateRelease(self, ast, release, options): 119 def GenerateRelease(self, ast, release, options):
111 __pychecker__ = 'unusednames=ast,release,options' 120 __pychecker__ = 'unusednames=ast,release,options'
112 self.Error("Undefined release generator.") 121 self.Error("Undefined release generator.")
113 return 0 122 return 0
114 123
115 def GenerateRange(self, ast, vmin, vmax, options): 124 def GenerateRange(self, ast, releases, options):
116 __pychecker__ = 'unusednames=ast,vmin,vmax,options' 125 __pychecker__ = 'unusednames=ast,releases,options'
117 self.Error("Undefined range generator.") 126 self.Error("Undefined range generator.")
118 return 0 127 return 0
119 128
120 @staticmethod 129 @staticmethod
121 def Run(ast): 130 def Run(ast):
122 fail_count = 0 131 fail_count = 0
123 132
124 # Check all registered generators if they should run. 133 # Check all registered generators if they should run.
125 for gen in GeneratorList: 134 for gen in GeneratorList:
126 options = gen.GetRunOptions() 135 options = gen.GetRunOptions()
127 if options is not None: 136 if options is not None:
128 if gen.Generate(ast, options): 137 if gen.Generate(ast, options):
129 fail_count += 1 138 fail_count += 1
130 return fail_count 139 return fail_count
131 140
132 141
133 # 142 #
134 # GeneratorByFile 143 # GeneratorByFile
135 # 144 #
136 # A subclass of Generator for use of generators which have a one to one 145 # A subclass of Generator for use of generators which have a one to one
137 # mapping between IDL sources and output files. To use, derive a new class 146 # mapping between IDL sources and output files. To use, derive a new class
138 # which defines: 147 # which defines:
139 # 148 #
140 # GetOutFile - Returns an IDLOutFile based on filenode (name) and options 149 # GetOutFile - Returns an IDLOutFile based on filenode (name) and options
141 # GenerateHead - Writes the first part of the file (includes, etc...) 150 # GenerateHead - Writes the first part of the file (includes, etc...)
142 # GenerateBody - Writes the body of the file (definitions) 151 # GenerateBody - Writes the body of the file (definitions)
143 # GenerateTail - Writes the end of the file (closing include guard, etc...) 152 # GenerateTail - Writes the end of the file (closing include guard, etc...)
144 # 153 #
145 class GeneratorByFile(Generator): 154 class GeneratorByFile(Generator):
155 def GenerateFile(self, filenode, releases, options):
156 __pychecker__ = 'unusednames=filenode,releases,options'
157 self.Error("Undefined release generator.")
158 return 0
159
146 def GenerateRelease(self, ast, release, options): 160 def GenerateRelease(self, ast, release, options):
147 return self.GenerateRange(ast, [release], options) 161 return self.GenerateRange(ast, [release], options)
148 162
149 def GenerateRange(self, ast, releases, options): 163 def GenerateRange(self, ast, releases, options):
150 # Get list of out files 164 # Get list of out files
151 outlist = GetOption('out') 165 outlist = GetOption('out')
152 if outlist: outlist = outlist.split(',') 166 if outlist: outlist = outlist.split(',')
153 167
154 skipList = [] 168 skipList = []
155 cnt = 0 169 cnt = 0
156 for filenode in ast.GetListOf('File'): 170 for filenode in ast.GetListOf('File'):
171 # Ignore files with errors
172 if filenode in self.skip_list:
173 continue
174
157 # Skip this file if not required 175 # Skip this file if not required
158 if outlist and filenode.GetName() not in outlist: 176 if outlist and filenode.GetName() not in outlist:
159 continue 177 continue
160 178
161 # If this file has errors, skip it 179 # Create the output file and increment out count if there was a delta
162 if filenode.GetProperty('ERRORS') > 0: 180 if self.GenerateFile(filenode, releases, options):
163 skipList.append(filenode) 181 cnt = cnt + 1
164 continue
165
166 # Create output file
167 out = self.GetOutFile(filenode, options)
168 self.GenerateHead(out, filenode, releases, options)
169 self.GenerateBody(out, filenode, releases, options)
170 self.GenerateTail(out, filenode, releases, options)
171
172 if out.Close(): cnt = cnt + 1
173 182
174 for filenode in skipList: 183 for filenode in skipList:
175 errcnt = filenode.GetProperty('ERRORS') 184 errcnt = filenode.GetProperty('ERRORS')
176 ErrOut.Log('%s : Skipped because of %d errors.' % ( 185 ErrOut.Log('%s : Skipped because of %d errors.' % (
177 filenode.GetName(), errcnt)) 186 filenode.GetName(), errcnt))
178 187
179 if skipList: 188 if skipList:
180 return -len(skipList) 189 return -len(skipList)
181 190
182 if GetOption('diff'): 191 if GetOption('diff'):
(...skipping 18 matching lines...) Expand all
201 check_item = check_map[item] 210 check_item = check_map[item]
202 option_item = options.get(item, None) 211 option_item = options.get(item, None)
203 if check_item != option_item: 212 if check_item != option_item:
204 print 'Option %s is %s, expecting %s' % (item, option_item, check_item) 213 print 'Option %s is %s, expecting %s' % (item, option_item, check_item)
205 check_release = 0 214 check_release = 0
206 215
207 if release != 'M14': 216 if release != 'M14':
208 check_release = 0 217 check_release = 0
209 return check_release == 1 218 return check_release == 1
210 219
211 def GenerateRange(self, ast, vmin, vmax, options = {}): 220 def GenerateRange(self, ast, releases, options):
212 __pychecker__ = 'unusednames=ast,vmin,vmax,options' 221 __pychecker__ = 'unusednames=ast,releases,options'
213 global check_range 222 global check_range
214 check_range = 1 223 check_range = 1
215 return True 224 return True
216 225
217 def Test(): 226 def Test():
218 __pychecker__ = 'unusednames=args' 227 __pychecker__ = 'unusednames=args'
219 global check_release 228 global check_release
220 global check_range 229 global check_range
221 230
222 ParseOptions(['--testgen_opt=so_long,MyOpt=XYZ,goodbye']) 231 ParseOptions(['--testgen_opt=so_long,MyOpt=XYZ,goodbye'])
(...skipping 14 matching lines...) Expand all
237 if check_release != 0 or check_range != 1: 246 if check_release != 0 or check_range != 1:
238 print 'Gererate range: Failed to run.\n' 247 print 'Gererate range: Failed to run.\n'
239 return -1 248 return -1
240 249
241 print 'Generator test: Pass' 250 print 'Generator test: Pass'
242 return 0 251 return 0
243 252
244 253
245 def Main(args): 254 def Main(args):
246 if not args: return Test() 255 if not args: return Test()
247
248 filenames = ParseOptions(args) 256 filenames = ParseOptions(args)
249 ast = ParseFiles(filenames) 257 ast = ParseFiles(filenames)
250 258
251 return Generator.Run(ast) 259 return Generator.Run(ast)
252 260
253 261
254 if __name__ == '__main__': 262 if __name__ == '__main__':
255 GeneratorReleaseTest('Test Gen', 'testgen', 'Generator Class Test.') 263 GeneratorReleaseTest('Test Gen', 'testgen', 'Generator Class Test.')
256 sys.exit(Main(sys.argv[1:])) 264 sys.exit(Main(sys.argv[1:]))
257 265
OLDNEW
« no previous file with comments | « ppapi/generators/idl_c_proto.py ('k') | ppapi/generators/idl_node.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698