OLD | NEW |
---|---|
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 """ Generator for C style prototypes and definitions """ | 7 """ Generator for C style prototypes and definitions """ |
8 | 8 |
9 import glob | 9 import glob |
10 import os | 10 import os |
11 import sys | 11 import sys |
12 | 12 |
13 from idl_log import ErrOut, InfoOut, WarnOut | 13 from idl_log import ErrOut, InfoOut, WarnOut |
14 from idl_node import IDLNode | 14 from idl_node import IDLNode |
15 from idl_ast import IDLAst | 15 from idl_ast import IDLAst |
16 from idl_option import GetOption, Option, ParseOptions | 16 from idl_option import GetOption, Option, ParseOptions |
17 from idl_parser import ParseFiles | 17 from idl_parser import ParseFiles |
18 | 18 |
19 Option('cgen_debug', 'Debug generate.') | 19 Option('cgen_debug', 'Debug generate.') |
20 | 20 |
21 class CGenError(Exception): | 21 class CGenError(Exception): |
22 def __init__(self, msg): | 22 def __init__(self, msg): |
23 self.value = value | 23 self.value = value |
24 | 24 |
25 def __str__(self): | 25 def __str__(self): |
26 return repr(self.value) | 26 return repr(self.value) |
27 | 27 |
28 | 28 |
29 def CommentLines(lines, tabs=0): | |
30 tab = ' ' * tabs | |
31 if lines[-1] == '': | |
dmichael (off chromium)
2011/08/24 20:49:11
I guess my python-fu is weak. What does indexing a
noelallen1
2011/08/24 22:43:06
[-n] is the standard way to notate the 'nth' to la
| |
32 out = '%s/*' % tab + ('\n%s *' % tab).join(lines) + '/\n' | |
33 else: | |
34 out = '%s/*' % tab + ('\n%s *' % tab).join(lines) + ' */\n' | |
dmichael (off chromium)
2011/08/24 20:49:11
Maybe a comment on what's going on here? And maybe
noelallen1
2011/08/24 22:43:06
Done.
| |
35 return out | |
36 | |
37 def Comment(node, prefix=None, tabs=0): | |
dmichael (off chromium)
2011/08/24 20:49:11
Speaking of comments... Could we have some here?
noelallen1
2011/08/24 22:43:06
Done.
| |
38 comment = node.GetName() | |
39 lines = comment.split('\n') | |
40 if prefix: | |
41 prefix = prefix.split('\n') | |
dmichael (off chromium)
2011/08/24 20:49:11
I'd prefer you use a different variable name for t
noelallen1
2011/08/24 22:43:06
Done.
| |
42 if prefix[0] == '*' and lines[0] == '*': | |
43 lines = prefix + lines[1:] | |
44 else: | |
45 lines = prefix + lines; | |
46 return CommentLines(lines, tabs) | |
47 | |
48 def GetNodeComments(node, prefix=None, tabs=0): | |
49 comment_txt = '' | |
50 for doc in node.GetListOf('Comment'): | |
51 comment_txt += Comment(doc, tabs=tabs) | |
52 return comment_txt | |
53 | |
54 | |
29 class CGen(object): | 55 class CGen(object): |
30 # TypeMap | 56 # TypeMap |
31 # | 57 # |
32 # TypeMap modifies how an object is stored or passed, for example pointers | 58 # TypeMap modifies how an object is stored or passed, for example pointers |
33 # are passed as 'const' if they are 'in' parameters, and structures are | 59 # are passed as 'const' if they are 'in' parameters, and structures are |
34 # preceeded by the keyword 'struct' as well as using a pointer. | 60 # preceeded by the keyword 'struct' as well as using a pointer. |
35 # | 61 # |
36 TypeMap = { | 62 TypeMap = { |
37 'Array': { | 63 'Array': { |
38 'in': 'const %s', | 64 'in': 'const %s', |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 'float_t': 'float', | 122 'float_t': 'float', |
97 'double_t': 'double', | 123 'double_t': 'double', |
98 'handle_t': 'int', | 124 'handle_t': 'int', |
99 'mem_t': 'void*', | 125 'mem_t': 'void*', |
100 'str_t': 'char*', | 126 'str_t': 'char*', |
101 'interface_t' : 'const void*' | 127 'interface_t' : 'const void*' |
102 } | 128 } |
103 | 129 |
104 def __init__(self): | 130 def __init__(self): |
105 self.dbg_depth = 0 | 131 self.dbg_depth = 0 |
106 self.vmin = 0.0 | 132 # self.vmin = 0.0 |
107 self.vmax = 1e100 | 133 # self.vmax = 1e100 |
108 self.release = GetOption('release') | 134 # self.release = GetOption('release') |
dmichael (off chromium)
2011/08/24 20:49:11
Why are these just commented out? If they're dead,
noelallen1
2011/08/24 22:43:06
Done.
| |
109 | 135 |
110 def SetVersionMap(self, node): | 136 def SetVersionMap(self, node): pass |
111 self.vmin = 0.0 | 137 # self.vmin = 0.0 |
112 self.vmax = 1e100 | 138 # self.vmax = 1e100 |
113 for version in node.GetListOf('LabelItem'): | 139 # for version in node.GetListOf('LabelItem'): |
114 if version.GetName() == GetOption('release'): | 140 # if version.GetName() == GetOption('release'): |
115 self.vmin = float(version.GetProperty('VALUE')) | 141 # self.vmin = float(version.GetProperty('VALUE')) |
116 self.vmax = float(version.GetProperty('VALUE')) | 142 # self.vmax = float(version.GetProperty('VALUE')) |
117 | 143 |
118 # | 144 # |
119 # Debug Logging functions | 145 # Debug Logging functions |
120 # | 146 # |
121 def Log(self, txt): | 147 def Log(self, txt): |
122 if not GetOption('cgen_debug'): return | 148 if not GetOption('cgen_debug'): return |
123 tabs = '' | 149 tabs = '' |
124 for tab in range(self.dbg_depth): tabs += ' ' | 150 for tab in range(self.dbg_depth): tabs += ' ' |
125 print '%s%s' % (tabs, txt) | 151 print '%s%s' % (tabs, txt) |
126 | 152 |
(...skipping 18 matching lines...) Expand all Loading... | |
145 return '[]' | 171 return '[]' |
146 | 172 |
147 # | 173 # |
148 # GetTypeName | 174 # GetTypeName |
149 # | 175 # |
150 # For any valid 'typed' object such as Member or Typedef | 176 # For any valid 'typed' object such as Member or Typedef |
151 # the typenode object contains the typename | 177 # the typenode object contains the typename |
152 # | 178 # |
153 # For a given node return the type name by passing mode. | 179 # For a given node return the type name by passing mode. |
154 # | 180 # |
155 def GetTypeName(self, node, prefix=''): | 181 def GetTypeName(self, node, release, prefix=''): |
156 self.LogEnter('GetTypeName of %s' % node) | 182 self.LogEnter('GetTypeName of %s rel=%s' % (node, release)) |
157 | 183 |
158 # For Members, Params, and Typedef's your want type it refers to | 184 # For Members, Params, and Typedef's your want type it refers to |
dmichael (off chromium)
2011/08/24 20:49:11
Typedef's->Typedefs
and not sure what 'your want t
noelallen1
2011/08/24 22:43:06
Done.
| |
159 if node.IsA('Member', 'Param', 'Typedef'): | 185 if node.IsA('Member', 'Param', 'Typedef'): |
160 typeref = node.GetType(self.release) | 186 typeref = node.GetType(release) |
161 else: | 187 else: |
162 typeref = node | 188 typeref = node |
163 | 189 |
164 if typeref is None: | 190 if typeref is None: |
165 raise CGenError('No type for %s' % node) | 191 raise CGenError('No type for %s' % node) |
166 | 192 |
167 # If the type is a (BuiltIn) Type then return it's name | 193 # If the type is a (BuiltIn) Type then return it's name |
168 # remapping as needed | 194 # remapping as needed |
169 if typeref.IsA('Type'): | 195 if typeref.IsA('Type'): |
170 name = CGen.RemapName.get(typeref.GetName(), None) | 196 name = CGen.RemapName.get(typeref.GetName(), None) |
(...skipping 16 matching lines...) Expand all Loading... | |
187 self.LogExit('GetTypeName %s is %s' % (node, name)) | 213 self.LogExit('GetTypeName %s is %s' % (node, name)) |
188 return name | 214 return name |
189 | 215 |
190 | 216 |
191 # | 217 # |
192 # GetRootType | 218 # GetRootType |
193 # | 219 # |
194 # For a given node return basic type of that object. This is | 220 # For a given node return basic type of that object. This is |
195 # either a 'Type', 'Callspec', or 'Array' | 221 # either a 'Type', 'Callspec', or 'Array' |
196 # | 222 # |
197 def GetRootTypeMode(self, node, mode): | 223 def GetRootTypeMode(self, node, release, mode): |
198 self.LogEnter('GetRootType of %s' % node) | 224 self.LogEnter('GetRootType of %s' % node) |
199 # If it has an array spec, then treat it as an array regardless of type | 225 # If it has an array spec, then treat it as an array regardless of type |
200 if node.GetOneOf('Array'): | 226 if node.GetOneOf('Array'): |
201 rootType = 'Array' | 227 rootType = 'Array' |
202 # Or if it has a callspec, treat it as a function | 228 # Or if it has a callspec, treat it as a function |
203 elif node.GetOneOf('Callspec'): | 229 elif node.GetOneOf('Callspec'): |
204 rootType, mode = self.GetRootTypeMode(node.GetType(self.release), | 230 rootType, mode = self.GetRootTypeMode(node.GetType(release), release, |
205 'return') | 231 'return') |
206 | 232 |
207 # If it's a plain typedef, try that object's root type | 233 # If it's a plain typedef, try that object's root type |
208 elif node.IsA('Member', 'Param', 'Typedef'): | 234 elif node.IsA('Member', 'Param', 'Typedef'): |
209 rootType, mode = self.GetRootTypeMode(node.GetType(self.release), mode) | 235 rootType, mode = self.GetRootTypeMode(node.GetType(release), |
236 release, mode) | |
210 | 237 |
211 # If it's an Enum, then it's normal passing rules | 238 # If it's an Enum, then it's normal passing rules |
212 elif node.IsA('Enum'): | 239 elif node.IsA('Enum'): |
213 rootType = node.cls | 240 rootType = node.cls |
214 | 241 |
215 # If it's an Interface or Struct, we may be passing by value | 242 # If it's an Interface or Struct, we may be passing by value |
216 elif node.IsA('Interface', 'Struct'): | 243 elif node.IsA('Interface', 'Struct'): |
217 if mode == 'return': | 244 if mode == 'return': |
218 if node.GetProperty('returnByValue'): | 245 if node.GetProperty('returnByValue'): |
219 rootType = 'TypeValue' | 246 rootType = 'TypeValue' |
(...skipping 10 matching lines...) Expand all Loading... | |
230 if node.GetName() in CGen.TypeMap: | 257 if node.GetName() in CGen.TypeMap: |
231 rootType = node.GetName() | 258 rootType = node.GetName() |
232 else: | 259 else: |
233 rootType = 'TypeValue' | 260 rootType = 'TypeValue' |
234 else: | 261 else: |
235 raise RuntimeError('Getting root type of non-type %s.' % node) | 262 raise RuntimeError('Getting root type of non-type %s.' % node) |
236 self.LogExit('RootType is "%s"' % rootType) | 263 self.LogExit('RootType is "%s"' % rootType) |
237 return rootType, mode | 264 return rootType, mode |
238 | 265 |
239 | 266 |
240 def GetTypeByMode(self, node, mode): | 267 def GetTypeByMode(self, node, release, mode): |
241 self.LogEnter('GetTypeByMode of %s mode=%s' % (node, mode)) | 268 self.LogEnter('GetTypeByMode of %s mode=%s release=%s' % |
242 name = self.GetTypeName(node) | 269 (node, mode, release)) |
243 ntype, mode = self.GetRootTypeMode(node, mode) | 270 name = self.GetTypeName(node, release) |
271 ntype, mode = self.GetRootTypeMode(node, release, mode) | |
244 out = CGen.TypeMap[ntype][mode] % name | 272 out = CGen.TypeMap[ntype][mode] % name |
245 self.LogExit('GetTypeByMode %s = %s' % (node, out)) | 273 self.LogExit('GetTypeByMode %s = %s' % (node, out)) |
246 return out | 274 return out |
247 | 275 |
248 | 276 |
249 # Get the passing mode of the object (in, out, inout). | 277 # Get the passing mode of the object (in, out, inout). |
250 def GetParamMode(self, node): | 278 def GetParamMode(self, node): |
251 self.Log('GetParamMode for %s' % node) | 279 self.Log('GetParamMode for %s' % node) |
252 if node.GetProperty('in'): return 'in' | 280 if node.GetProperty('in'): return 'in' |
253 if node.GetProperty('out'): return 'out' | 281 if node.GetProperty('out'): return 'out' |
254 if node.GetProperty('inout'): return 'inout' | 282 if node.GetProperty('inout'): return 'inout' |
255 return 'return' | 283 return 'return' |
256 | 284 |
257 # | 285 # |
258 # GetComponents | 286 # GetComponents |
259 # | 287 # |
260 # Returns the signature components of an object as a tuple of | 288 # Returns the signature components of an object as a tuple of |
261 # (rtype, name, arrays, callspec) where: | 289 # (rtype, name, arrays, callspec) where: |
262 # rtype - The store or return type of the object. | 290 # rtype - The store or return type of the object. |
263 # name - The name of the object. | 291 # name - The name of the object. |
264 # arrays - A list of array dimensions as [] or [<fixed_num>]. | 292 # arrays - A list of array dimensions as [] or [<fixed_num>]. |
265 # args - None of not a function, otherwise a list of parameters. | 293 # args - None of not a function, otherwise a list of parameters. |
266 # | 294 # |
267 def GetComponents(self, node, mode): | 295 def GetComponents(self, node, release, mode): |
268 self.LogEnter('GetComponents mode %s for %s' % (mode, node)) | 296 self.LogEnter('GetComponents mode %s for %s %s' % (mode, node, release)) |
269 | 297 |
270 # Generate passing type by modifying root type | 298 # Generate passing type by modifying root type |
271 rtype = self.GetTypeByMode(node, mode) | 299 rtype = self.GetTypeByMode(node, release, mode) |
272 if node.IsA('Enum', 'Interface', 'Struct'): | 300 if node.IsA('Enum', 'Interface', 'Struct'): |
273 rname = node.GetName() | 301 rname = node.GetName() |
274 else: | 302 else: |
275 rname = node.GetType(self.release).GetName() | 303 rname = node.GetType(release).GetName() |
276 | 304 |
277 if rname in CGen.RemapName: | 305 if rname in CGen.RemapName: |
278 rname = CGen.RemapName[rname] | 306 rname = CGen.RemapName[rname] |
279 if '%' in rtype: | 307 if '%' in rtype: |
280 rtype = rtype % rname | 308 rtype = rtype % rname |
281 name = node.GetName() | 309 name = node.GetName() |
282 arrayspec = [self.GetArraySpec(array) for array in node.GetListOf('Array')] | 310 arrayspec = [self.GetArraySpec(array) for array in node.GetListOf('Array')] |
283 callnode = node.GetOneOf('Callspec') | 311 callnode = node.GetOneOf('Callspec') |
284 if callnode: | 312 if callnode: |
285 callspec = [] | 313 callspec = [] |
286 for param in callnode.GetListOf('Param'): | 314 for param in callnode.GetListOf('Param'): |
287 mode = self.GetParamMode(param) | 315 mode = self.GetParamMode(param) |
288 ptype, pname, parray, pspec = self.GetComponents(param, mode) | 316 ptype, pname, parray, pspec = self.GetComponents(param, release, mode) |
289 callspec.append((ptype, pname, parray, pspec)) | 317 callspec.append((ptype, pname, parray, pspec)) |
290 else: | 318 else: |
291 callspec = None | 319 callspec = None |
292 | 320 |
293 self.LogExit('GetComponents: %s, %s, %s, %s' % | 321 self.LogExit('GetComponents: %s, %s, %s, %s' % |
294 (rtype, name, arrayspec, callspec)) | 322 (rtype, name, arrayspec, callspec)) |
295 return (rtype, name, arrayspec, callspec) | 323 return (rtype, name, arrayspec, callspec) |
296 | 324 |
297 | 325 |
298 def Compose(self, rtype, name, arrayspec, callspec, prefix, func_as_ptr): | 326 def Compose(self, rtype, name, arrayspec, callspec, prefix, func_as_ptr): |
(...skipping 11 matching lines...) Expand all Loading... | |
310 self.LogExit('Exit Compose: %s' % out) | 338 self.LogExit('Exit Compose: %s' % out) |
311 return out | 339 return out |
312 | 340 |
313 # | 341 # |
314 # GetSignature | 342 # GetSignature |
315 # | 343 # |
316 # Returns the 'C' style signature of the object | 344 # Returns the 'C' style signature of the object |
317 # prefix - A prefix for the object's name | 345 # prefix - A prefix for the object's name |
318 # func_as_ptr - Formats a function as a function pointer | 346 # func_as_ptr - Formats a function as a function pointer |
319 # | 347 # |
320 def GetSignature(self, node, mode, prefix='', func_as_ptr=True): | 348 def GetSignature(self, node, release, mode, prefix='', func_as_ptr=True): |
321 self.LogEnter('GetSignature %s %s as func=%s' % (node, mode, func_as_ptr)) | 349 self.LogEnter('GetSignature %s %s as func=%s' % (node, mode, func_as_ptr)) |
322 rtype, name, arrayspec, callspec = self.GetComponents(node, mode) | 350 rtype, name, arrayspec, callspec = self.GetComponents(node, release, mode) |
323 out = self.Compose(rtype, name, arrayspec, callspec, prefix, func_as_ptr) | 351 out = self.Compose(rtype, name, arrayspec, callspec, prefix, func_as_ptr) |
324 self.LogExit('Exit GetSignature: %s' % out) | 352 self.LogExit('Exit GetSignature: %s' % out) |
325 return out | 353 return out |
326 | 354 |
327 def GetMacro(self, node): | |
328 name = node.GetName() | |
329 name = name.upper() | |
330 return "%s_INTERFACE" % name | |
331 | |
332 def GetDefine(self, name, value): | |
333 out = '#define %s %s' % (name, value) | |
334 if len(out) > 80: | |
335 out = '#define %s \\\n %s' % (name, value) | |
336 return '%s\n' % out | |
337 | |
338 # Define an Typedef. | 355 # Define an Typedef. |
dmichael (off chromium)
2011/08/24 20:49:11
nit: an->a
| |
339 def DefineTypedef(self, node, prefix='', comment=False): | 356 def DefineTypedef(self, node, releases, prefix='', comment=False): |
dmichael (off chromium)
2011/08/24 20:49:11
Why are you passing an array here if you only use
noelallen1
2011/08/24 22:43:06
Yes. This is waiting on name mangling based on ve
| |
340 out = 'typedef %s;\n' % self.GetSignature(node, 'return', prefix, True) | 357 release = releases[0] |
358 out = 'typedef %s;\n' % self.GetSignature(node, release, 'return', | |
359 prefix, True) | |
341 self.Log('DefineTypedef: %s' % out) | 360 self.Log('DefineTypedef: %s' % out) |
342 return out | 361 return out |
343 | 362 |
344 # Define an Enum. | 363 # Define an Enum. |
345 def DefineEnum(self, node, prefix='', comment=False): | 364 def DefineEnum(self, node, releases, prefix='', comment=False): |
dmichael (off chromium)
2011/08/24 20:49:11
releases appears to be unused here
noelallen1
2011/08/24 22:43:06
Transitional (same as above)
| |
346 self.LogEnter('DefineEnum %s' % node) | 365 self.LogEnter('DefineEnum %s' % node) |
347 unnamed = node.GetProperty('unnamed') | 366 unnamed = node.GetProperty('unnamed') |
348 if unnamed: | 367 if unnamed: |
349 out = 'enum {' | 368 out = 'enum {' |
350 else: | 369 else: |
351 out = 'typedef enum {' | 370 out = 'typedef enum {' |
352 name = '%s%s' % (prefix, node.GetName()) | 371 name = '%s%s' % (prefix, node.GetName()) |
353 enumlist = [] | 372 enumlist = [] |
354 for child in node.GetListOf('EnumItem'): | 373 for child in node.GetListOf('EnumItem'): |
355 value = child.GetProperty('VALUE') | 374 value = child.GetProperty('VALUE') |
356 comment_txt = '' | 375 comment_txt = GetNodeComments(child, tabs=1) |
357 if comment: | |
358 for comment_node in child.GetListOf('Comment'): | |
359 comment_txt += self.Comment(comment_node, tabs=1) | |
360 if comment_txt: | |
361 comment_txt = '%s' % comment_txt | |
362 if value: | 376 if value: |
363 item_txt = '%s%s = %s' % (prefix, child.GetName(), value) | 377 item_txt = '%s%s = %s' % (prefix, child.GetName(), value) |
364 else: | 378 else: |
365 item_txt = '%s%s' % (prefix, child.GetName()) | 379 item_txt = '%s%s' % (prefix, child.GetName()) |
366 enumlist.append('%s %s' % (comment_txt, item_txt)) | 380 enumlist.append('%s %s' % (comment_txt, item_txt)) |
367 self.LogExit('Exit DefineEnum') | 381 self.LogExit('Exit DefineEnum') |
368 | 382 |
369 if unnamed: | 383 if unnamed: |
370 out = '%s\n%s\n};\n' % (out, ',\n'.join(enumlist)) | 384 out = '%s\n%s\n};\n' % (out, ',\n'.join(enumlist)) |
371 else: | 385 else: |
372 out = '%s\n%s\n} %s;\n' % (out, ',\n'.join(enumlist), name) | 386 out = '%s\n%s\n} %s;\n' % (out, ',\n'.join(enumlist), name) |
373 return out | 387 return out |
374 | 388 |
375 def DefineMember(self, node, prefix='', comment=False): | 389 def DefineMember(self, node, releases, prefix='', comment=False): |
390 release = releases[0] | |
dmichael (off chromium)
2011/08/24 20:49:11
Again, is this just temporary?
noelallen1
2011/08/24 22:43:06
Yes. All Define<X> functions take an array of re
| |
376 self.LogEnter('DefineMember %s' % node) | 391 self.LogEnter('DefineMember %s' % node) |
377 | 392 out = '%s;' % self.GetSignature(node, release, 'store', '', True) |
378 # out = '' | |
379 # if comment: | |
380 # for doc in node.GetListOf('Comment'): | |
381 # out += self.Comment(doc) | |
382 out = '%s;' % self.GetSignature(node, 'store', '', True) | |
383 self.LogExit('Exit DefineMember') | 393 self.LogExit('Exit DefineMember') |
384 return out | 394 return out |
385 | 395 |
386 def InterfaceDefs(self, node): | |
387 out = '' | |
388 name = node.GetName() | |
389 macro = node.GetProperty('macro') | |
390 if not macro: | |
391 macro = self.GetMacro(node) | |
392 label = node.GetLabel() | |
393 if label: | |
394 for vers in label.versions: | |
395 strver = str(vers).replace('.', '_') | |
396 out += self.GetDefine('%s_%s' % (macro, strver), | |
397 '"%s;%s"' % (name, vers)) | |
398 if label.GetRelease(vers) == self.release: | |
399 out += self.GetDefine(macro, '%s_%s' % (macro, strver)) | |
400 out += '\n' | |
401 return out | |
402 | |
403 # Define a Struct. | 396 # Define a Struct. |
404 def DefineStruct(self, node, prefix='', comment=False): | 397 def DefineStruct(self, node, releases, prefix='', comment=False): |
405 out = '' | 398 out = '' |
406 | 399 |
407 self.LogEnter('DefineStruct %s' % node) | 400 self.LogEnter('DefineStruct %s' % node) |
408 if node.GetProperty('union'): | 401 if node.GetProperty('union'): |
409 out += 'union %s%s {\n' % (prefix, node.GetName()) | 402 out += 'union %s%s {\n' % (prefix, node.GetName()) |
410 else: | 403 else: |
411 out += 'struct %s%s {\n' % (prefix, node.GetName()) | 404 out += 'struct %s%s {\n' % (prefix, node.GetName()) |
412 | 405 |
413 # Generate Member Functions | 406 # Generate Member Functions |
414 members = [] | 407 members = [] |
415 for child in node.GetListOf('Member'): | 408 for child in node.GetListOf('Member'): |
416 member = self.Define(child, tabs=1, comment=comment) | 409 member = self.Define(child, releases, tabs=1, comment=comment) |
417 if not member: | 410 if not member: |
418 continue | 411 continue |
419 members.append(member) | 412 members.append(member) |
420 out += '%s\n};\n' % '\n'.join(members) | 413 out += '%s\n};\n' % '\n'.join(members) |
421 self.LogExit('Exit DefineStruct') | 414 self.LogExit('Exit DefineStruct') |
422 return out | 415 return out |
423 | 416 |
424 def DefineType(self, node, prefix='', comment=False): | 417 def DefineType(self, node, releases, prefix='', comment=False): |
dmichael (off chromium)
2011/08/24 20:49:11
Why the trivial function? Is this speculative codi
noelallen1
2011/08/24 22:43:06
A 'type' doesn't have anything to emit for C heade
| |
425 return '' | 418 return '' |
426 | 419 |
427 # | 420 # |
428 # Copyright and Comment | 421 # Copyright and Comment |
429 # | 422 # |
430 # Generate a comment or copyright block | 423 # Generate a comment or copyright block |
431 # | 424 # |
432 def Copyright(self, node, tabs=0): | 425 def Copyright(self, node, tabs=0): |
433 lines = node.GetName().split('\n') | 426 lines = node.GetName().split('\n') |
434 return self.CommentLines(lines, tabs) | 427 return CommentLines(lines, tabs) |
435 | |
436 def Comment(self, node, prefix=None, tabs=0): | |
437 comment = node.GetName() | |
438 | |
439 # Ignore comments that do not have a '*' marker | |
440 # if comment[0] != '*' and not prefix: return '' | |
441 | |
442 lines = comment.split('\n') | |
443 if prefix: | |
444 prefix = prefix.split('\n') | |
445 if prefix[0] == '*' and lines[0] == '*': | |
446 lines = prefix + lines[1:] | |
447 else: | |
448 lines = prefix + lines; | |
449 return self.CommentLines(lines, tabs) | |
450 | |
451 def CommentLines(self, lines, tabs=0): | |
452 tab = ''.join([' ' for i in range(tabs)]) | |
453 if lines[-1] == '': | |
454 return '%s/*' % tab + ('\n%s *' % tab).join(lines) + '/\n' | |
455 else: | |
456 return '%s/*' % tab + ('\n%s *' % tab).join(lines) + ' */\n' | |
457 | 428 |
458 | 429 |
459 # Define a top level object. | 430 # Define a top level object. |
460 def Define(self, node, tabs=0, prefix='', comment=False): | 431 def Define(self, node, releases, tabs=0, prefix='', comment=False): |
461 if True: | 432 if not node.InReleases(releases): |
462 # try: | 433 return '' |
463 self.LogEnter('Define %s tab=%d prefix="%s"' % (node,tabs,prefix)) | |
464 | 434 |
465 node_nim = node.GetProperty('version') | 435 self.LogEnter('Define %s tab=%d prefix="%s"' % (node,tabs,prefix)) |
466 node_max = node.GetProperty('deprecate') | 436 declmap = { |
437 'Describe' : CGen.DefineType, | |
438 'Enum' : CGen.DefineEnum, | |
439 'Function' : CGen.DefineMember, | |
440 'Interface' : CGen.DefineStruct, | |
441 'Member' : CGen.DefineMember, | |
442 'Struct' : CGen.DefineStruct, | |
443 'Type' : CGen.DefineType, | |
444 'Typedef' : CGen.DefineTypedef, | |
445 } | |
467 | 446 |
468 if node_nim is not None: | 447 out = '' |
469 node_nim = float(node_nim) | 448 func = declmap.get(node.cls) |
449 if not func: | |
450 ErrOut.Log('Failed to define %s named %s' % (node.cls, node.GetName())) | |
451 define_txt = func(self, node, releases, prefix=prefix, comment=comment) | |
452 | |
453 comment_txt = GetNodeComments(node, tabs=0) | |
454 if comment_txt and comment: | |
455 out += '%s%s' % (comment_txt, define_txt) | |
dmichael (off chromium)
2011/08/24 20:49:11
Doesn't the % operator seem like overkill here?
ou
noelallen1
2011/08/24 22:43:06
Done.
| |
456 else: | |
457 out += define_txt | |
458 | |
459 tab = ' ' * tabs | |
460 lines = [] | |
461 for line in out.split('\n'): | |
462 # Add indentation | |
463 line = '%s%s' % (tab, line) | |
dmichael (off chromium)
2011/08/24 20:49:11
again with the percent operator for just concatena
noelallen1
2011/08/24 22:43:06
Done.
| |
464 if len(line) > 80: | |
465 left = line.rfind('(') + 1 | |
466 args = line[left:].split(',') | |
467 line_max = 0 | |
468 for arg in args: | |
469 if len(arg) > line_max: line_max = len(arg) | |
470 | |
471 if left + line_max >= 80: | |
472 space = '%s ' % tab | |
473 args = (',\n%s' % space).join([arg.strip() for arg in args]) | |
474 lines.append('%s\n%s%s' % (line[:left], space, args)) | |
475 else: | |
476 space = ' '.join(['' for i in range(left)]) | |
dmichael (off chromium)
2011/08/24 20:49:11
Why not just
' ' * (left-1)
Seems clearer to me, a
| |
477 args = (',\n%s' % space).join(args) | |
478 lines.append('%s%s' % (line[:left], args)) | |
470 else: | 479 else: |
471 node_nim = 0.0 | 480 lines.append(line.rstrip()) |
472 | 481 self.LogExit('Exit Define') |
473 if node_max is not None: | 482 return '\n'.join(lines) |
474 node_max = float(node_max) | |
475 else: | |
476 node_max = 1.0e100 | |
477 | |
478 label = node.GetLabel() | |
479 if label: | |
480 lver = label.GetVersion(self.release) | |
481 | |
482 # Verify that we are in a valid version. | |
483 if node_max <= lver: return '' | |
484 if node_nim > lver: return '' | |
485 | |
486 declmap = { | |
487 'Describe' : CGen.DefineType, | |
488 'Enum' : CGen.DefineEnum, | |
489 'Function' : CGen.DefineMember, | |
490 'Interface' : CGen.DefineStruct, | |
491 'Member' : CGen.DefineMember, | |
492 'Struct' : CGen.DefineStruct, | |
493 'Type' : CGen.DefineType, | |
494 'Typedef' : CGen.DefineTypedef, | |
495 } | |
496 | |
497 if node.cls == 'Inline': | |
498 return node.GetProperty('VALUE') | |
499 | |
500 if node.cls == 'Label': | |
501 return '' | |
502 | |
503 out = '' | |
504 comment_txt = '' | |
505 if comment: | |
506 for doc in node.GetListOf('Comment'): | |
507 comment_txt += self.Comment(doc) | |
508 | |
509 func = declmap.get(node.cls) | |
510 if not func: | |
511 ErrOut.Log('Failed to define %s named %s' % (node.cls, node.GetName())) | |
512 | |
513 define_txt = func(self, node, prefix=prefix, comment=comment) | |
514 if comment_txt: | |
515 out += '%s%s' % (comment_txt, define_txt) | |
516 else: | |
517 out += define_txt | |
518 | |
519 tab = '' | |
520 for i in range(tabs): | |
521 tab += ' ' | |
522 | |
523 lines = [] | |
524 for line in out.split('\n'): | |
525 # Add indentation | |
526 line = '%s%s' % (tab, line) | |
527 if len(line) > 80: | |
528 left = line.rfind('(') + 1 | |
529 args = line[left:].split(',') | |
530 line_max = 0 | |
531 for arg in args: | |
532 if len(arg) > line_max: line_max = len(arg) | |
533 | |
534 if left + line_max >= 80: | |
535 space = '%s ' % tab | |
536 args = (',\n%s' % space).join([arg.strip() for arg in args]) | |
537 lines.append('%s\n%s%s' % (line[:left], space, args)) | |
538 else: | |
539 space = ' '.join(['' for i in range(left)]) | |
540 args = (',\n%s' % space).join(args) | |
541 lines.append('%s%s' % (line[:left], args)) | |
542 else: | |
543 lines.append(line.rstrip()) | |
544 | |
545 # out = tab + ('\n%s' % tab).join(out.split('\n')) + '\n' | |
546 self.LogExit('Exit Define') | |
547 return '\n'.join(lines) | |
548 # except: | |
549 if False: | |
550 node.Error('Failed to resolve.') | |
551 return '' | |
552 | 483 |
553 # Clean a string representing an object definition and return then string | 484 # Clean a string representing an object definition and return then string |
554 # as a single space delimited set of tokens. | 485 # as a single space delimited set of tokens. |
555 def CleanString(instr): | 486 def CleanString(instr): |
556 instr = instr.strip() | 487 instr = instr.strip() |
557 instr = instr.split() | 488 instr = instr.split() |
558 return ' '.join(instr) | 489 return ' '.join(instr) |
559 | 490 |
560 | 491 |
561 # Test a file, by comparing all it's objects, with their comments. | 492 # Test a file, by comparing all it's objects, with their comments. |
562 def TestFile(filenode): | 493 def TestFile(filenode): |
563 cgen = CGen() | 494 cgen = CGen() |
564 | 495 |
565 errors = 0 | 496 errors = 0 |
566 for node in filenode.GetChildren()[2:]: | 497 for node in filenode.GetChildren()[2:]: |
567 instr = node.GetOneOf('Comment') | 498 instr = node.GetOneOf('Comment') |
568 if not instr: continue | 499 if not instr: continue |
569 instr.Dump() | 500 instr.Dump() |
570 instr = CleanString(instr.GetName()) | 501 instr = CleanString(instr.GetName()) |
571 | 502 |
572 outstr = cgen.Define(node) | 503 outstr = cgen.Define(node, releases=['M14']) |
573 if GetOption('verbose'): | 504 if GetOption('verbose'): |
574 print outstr + '\n' | 505 print outstr + '\n' |
575 outstr = CleanString(outstr) | 506 outstr = CleanString(outstr) |
576 | 507 |
577 if instr != outstr: | 508 if instr != outstr: |
578 ErrOut.Log('Failed match of\n>>%s<<\n>>%s<<\nto:' % (instr, outstr)) | 509 ErrOut.Log('Failed match of\n>>%s<<\n>>%s<<\nto:' % (instr, outstr)) |
579 node.Dump(1, comments=True) | 510 node.Dump(1, comments=True) |
580 errors += 1 | 511 errors += 1 |
581 return errors | 512 return errors |
582 | 513 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
615 print 'Skipping %s' % f.GetName() | 546 print 'Skipping %s' % f.GetName() |
616 continue | 547 continue |
617 print DefineDepends(node) | 548 print DefineDepends(node) |
618 for node in f.GetChildren()[2:]: | 549 for node in f.GetChildren()[2:]: |
619 print Define(node, comment=True, prefix='tst_') | 550 print Define(node, comment=True, prefix='tst_') |
620 | 551 |
621 | 552 |
622 if __name__ == '__main__': | 553 if __name__ == '__main__': |
623 sys.exit(Main(sys.argv[1:])) | 554 sys.exit(Main(sys.argv[1:])) |
624 | 555 |
OLD | NEW |