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 # Generate a C style comment block by prepending the block with '<tab>/*' |
| 31 # and adding a '<tab> *' per line. |
| 32 tab = ' ' * tabs |
| 33 |
| 34 out = '%s/*' % tab + ('\n%s *' % tab).join(lines) |
| 35 |
| 36 # Add a terminating ' */' unless the last line is blank which would mean it |
| 37 # already has ' *' |
| 38 if not lines[-1]: |
| 39 out += '/\n' |
| 40 else: |
| 41 out += ' */\n' |
| 42 return out |
| 43 |
| 44 def Comment(node, prefix=None, tabs=0): |
| 45 # Generate a comment block from the provided Comment node. |
| 46 comment = node.GetName() |
| 47 lines = comment.split('\n') |
| 48 |
| 49 # If an option prefix is provided, then prepend that to the comment |
| 50 # for this node. |
| 51 if prefix: |
| 52 prefix_lines = prefix.split('\n') |
| 53 # If both the prefix and comment start with a blank line ('*') remove |
| 54 # the extra one. |
| 55 if prefix_lines[0] == '*' and lines[0] == '*': |
| 56 lines = prefix_lines + lines[1:] |
| 57 else: |
| 58 lines = prefix_lines + lines; |
| 59 return CommentLines(lines, tabs) |
| 60 |
| 61 def GetNodeComments(node, prefix=None, tabs=0): |
| 62 # Generate a comment block joining all comment nodes which are children of |
| 63 # the provided node. |
| 64 comment_txt = '' |
| 65 for doc in node.GetListOf('Comment'): |
| 66 comment_txt += Comment(doc, tabs=tabs) |
| 67 return comment_txt |
| 68 |
| 69 |
29 class CGen(object): | 70 class CGen(object): |
30 # TypeMap | 71 # TypeMap |
31 # | 72 # |
32 # TypeMap modifies how an object is stored or passed, for example pointers | 73 # 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 | 74 # are passed as 'const' if they are 'in' parameters, and structures are |
34 # preceeded by the keyword 'struct' as well as using a pointer. | 75 # preceeded by the keyword 'struct' as well as using a pointer. |
35 # | 76 # |
36 TypeMap = { | 77 TypeMap = { |
37 'Array': { | 78 'Array': { |
38 'in': 'const %s', | 79 'in': 'const %s', |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 'float_t': 'float', | 137 'float_t': 'float', |
97 'double_t': 'double', | 138 'double_t': 'double', |
98 'handle_t': 'int', | 139 'handle_t': 'int', |
99 'mem_t': 'void*', | 140 'mem_t': 'void*', |
100 'str_t': 'char*', | 141 'str_t': 'char*', |
101 'interface_t' : 'const void*' | 142 'interface_t' : 'const void*' |
102 } | 143 } |
103 | 144 |
104 def __init__(self): | 145 def __init__(self): |
105 self.dbg_depth = 0 | 146 self.dbg_depth = 0 |
106 self.vmin = 0.0 | |
107 self.vmax = 1e100 | |
108 self.release = GetOption('release') | |
109 | |
110 def SetVersionMap(self, node): | |
111 self.vmin = 0.0 | |
112 self.vmax = 1e100 | |
113 for version in node.GetListOf('LabelItem'): | |
114 if version.GetName() == GetOption('release'): | |
115 self.vmin = float(version.GetProperty('VALUE')) | |
116 self.vmax = float(version.GetProperty('VALUE')) | |
117 | 147 |
118 # | 148 # |
119 # Debug Logging functions | 149 # Debug Logging functions |
120 # | 150 # |
121 def Log(self, txt): | 151 def Log(self, txt): |
122 if not GetOption('cgen_debug'): return | 152 if not GetOption('cgen_debug'): return |
123 tabs = '' | 153 tabs = '' |
124 for tab in range(self.dbg_depth): tabs += ' ' | 154 for tab in range(self.dbg_depth): tabs += ' ' |
125 print '%s%s' % (tabs, txt) | 155 print '%s%s' % (tabs, txt) |
126 | 156 |
(...skipping 18 matching lines...) Expand all Loading... |
145 return '[]' | 175 return '[]' |
146 | 176 |
147 # | 177 # |
148 # GetTypeName | 178 # GetTypeName |
149 # | 179 # |
150 # For any valid 'typed' object such as Member or Typedef | 180 # For any valid 'typed' object such as Member or Typedef |
151 # the typenode object contains the typename | 181 # the typenode object contains the typename |
152 # | 182 # |
153 # For a given node return the type name by passing mode. | 183 # For a given node return the type name by passing mode. |
154 # | 184 # |
155 def GetTypeName(self, node, prefix=''): | 185 def GetTypeName(self, node, release, prefix=''): |
156 self.LogEnter('GetTypeName of %s' % node) | 186 self.LogEnter('GetTypeName of %s rel=%s' % (node, release)) |
157 | 187 |
158 # For Members, Params, and Typedef's your want type it refers to | 188 # For Members, Params, and Typedefs get the type it refers to otherwise |
| 189 # the node in question is it's own type (struct, union etc...) |
159 if node.IsA('Member', 'Param', 'Typedef'): | 190 if node.IsA('Member', 'Param', 'Typedef'): |
160 typeref = node.GetType(self.release) | 191 typeref = node.GetType(release) |
161 else: | 192 else: |
162 typeref = node | 193 typeref = node |
163 | 194 |
164 if typeref is None: | 195 if typeref is None: |
165 raise CGenError('No type for %s' % node) | 196 raise CGenError('No type for %s' % node) |
166 | 197 |
167 # If the type is a (BuiltIn) Type then return it's name | 198 # If the type is a (BuiltIn) Type then return it's name |
168 # remapping as needed | 199 # remapping as needed |
169 if typeref.IsA('Type'): | 200 if typeref.IsA('Type'): |
170 name = CGen.RemapName.get(typeref.GetName(), None) | 201 name = CGen.RemapName.get(typeref.GetName(), None) |
(...skipping 16 matching lines...) Expand all Loading... |
187 self.LogExit('GetTypeName %s is %s' % (node, name)) | 218 self.LogExit('GetTypeName %s is %s' % (node, name)) |
188 return name | 219 return name |
189 | 220 |
190 | 221 |
191 # | 222 # |
192 # GetRootType | 223 # GetRootType |
193 # | 224 # |
194 # For a given node return basic type of that object. This is | 225 # For a given node return basic type of that object. This is |
195 # either a 'Type', 'Callspec', or 'Array' | 226 # either a 'Type', 'Callspec', or 'Array' |
196 # | 227 # |
197 def GetRootTypeMode(self, node, mode): | 228 def GetRootTypeMode(self, node, release, mode): |
198 self.LogEnter('GetRootType of %s' % node) | 229 self.LogEnter('GetRootType of %s' % node) |
199 # If it has an array spec, then treat it as an array regardless of type | 230 # If it has an array spec, then treat it as an array regardless of type |
200 if node.GetOneOf('Array'): | 231 if node.GetOneOf('Array'): |
201 rootType = 'Array' | 232 rootType = 'Array' |
202 # Or if it has a callspec, treat it as a function | 233 # Or if it has a callspec, treat it as a function |
203 elif node.GetOneOf('Callspec'): | 234 elif node.GetOneOf('Callspec'): |
204 rootType, mode = self.GetRootTypeMode(node.GetType(self.release), | 235 rootType, mode = self.GetRootTypeMode(node.GetType(release), release, |
205 'return') | 236 'return') |
206 | 237 |
207 # If it's a plain typedef, try that object's root type | 238 # If it's a plain typedef, try that object's root type |
208 elif node.IsA('Member', 'Param', 'Typedef'): | 239 elif node.IsA('Member', 'Param', 'Typedef'): |
209 rootType, mode = self.GetRootTypeMode(node.GetType(self.release), mode) | 240 rootType, mode = self.GetRootTypeMode(node.GetType(release), |
| 241 release, mode) |
210 | 242 |
211 # If it's an Enum, then it's normal passing rules | 243 # If it's an Enum, then it's normal passing rules |
212 elif node.IsA('Enum'): | 244 elif node.IsA('Enum'): |
213 rootType = node.cls | 245 rootType = node.cls |
214 | 246 |
215 # If it's an Interface or Struct, we may be passing by value | 247 # If it's an Interface or Struct, we may be passing by value |
216 elif node.IsA('Interface', 'Struct'): | 248 elif node.IsA('Interface', 'Struct'): |
217 if mode == 'return': | 249 if mode == 'return': |
218 if node.GetProperty('returnByValue'): | 250 if node.GetProperty('returnByValue'): |
219 rootType = 'TypeValue' | 251 rootType = 'TypeValue' |
(...skipping 10 matching lines...) Expand all Loading... |
230 if node.GetName() in CGen.TypeMap: | 262 if node.GetName() in CGen.TypeMap: |
231 rootType = node.GetName() | 263 rootType = node.GetName() |
232 else: | 264 else: |
233 rootType = 'TypeValue' | 265 rootType = 'TypeValue' |
234 else: | 266 else: |
235 raise RuntimeError('Getting root type of non-type %s.' % node) | 267 raise RuntimeError('Getting root type of non-type %s.' % node) |
236 self.LogExit('RootType is "%s"' % rootType) | 268 self.LogExit('RootType is "%s"' % rootType) |
237 return rootType, mode | 269 return rootType, mode |
238 | 270 |
239 | 271 |
240 def GetTypeByMode(self, node, mode): | 272 def GetTypeByMode(self, node, release, mode): |
241 self.LogEnter('GetTypeByMode of %s mode=%s' % (node, mode)) | 273 self.LogEnter('GetTypeByMode of %s mode=%s release=%s' % |
242 name = self.GetTypeName(node) | 274 (node, mode, release)) |
243 ntype, mode = self.GetRootTypeMode(node, mode) | 275 name = self.GetTypeName(node, release) |
| 276 ntype, mode = self.GetRootTypeMode(node, release, mode) |
244 out = CGen.TypeMap[ntype][mode] % name | 277 out = CGen.TypeMap[ntype][mode] % name |
245 self.LogExit('GetTypeByMode %s = %s' % (node, out)) | 278 self.LogExit('GetTypeByMode %s = %s' % (node, out)) |
246 return out | 279 return out |
247 | 280 |
248 | 281 |
249 # Get the passing mode of the object (in, out, inout). | 282 # Get the passing mode of the object (in, out, inout). |
250 def GetParamMode(self, node): | 283 def GetParamMode(self, node): |
251 self.Log('GetParamMode for %s' % node) | 284 self.Log('GetParamMode for %s' % node) |
252 if node.GetProperty('in'): return 'in' | 285 if node.GetProperty('in'): return 'in' |
253 if node.GetProperty('out'): return 'out' | 286 if node.GetProperty('out'): return 'out' |
254 if node.GetProperty('inout'): return 'inout' | 287 if node.GetProperty('inout'): return 'inout' |
255 return 'return' | 288 return 'return' |
256 | 289 |
257 # | 290 # |
258 # GetComponents | 291 # GetComponents |
259 # | 292 # |
260 # Returns the signature components of an object as a tuple of | 293 # Returns the signature components of an object as a tuple of |
261 # (rtype, name, arrays, callspec) where: | 294 # (rtype, name, arrays, callspec) where: |
262 # rtype - The store or return type of the object. | 295 # rtype - The store or return type of the object. |
263 # name - The name of the object. | 296 # name - The name of the object. |
264 # arrays - A list of array dimensions as [] or [<fixed_num>]. | 297 # arrays - A list of array dimensions as [] or [<fixed_num>]. |
265 # args - None of not a function, otherwise a list of parameters. | 298 # args - None of not a function, otherwise a list of parameters. |
266 # | 299 # |
267 def GetComponents(self, node, mode): | 300 def GetComponents(self, node, release, mode): |
268 self.LogEnter('GetComponents mode %s for %s' % (mode, node)) | 301 self.LogEnter('GetComponents mode %s for %s %s' % (mode, node, release)) |
269 | 302 |
270 # Generate passing type by modifying root type | 303 # Generate passing type by modifying root type |
271 rtype = self.GetTypeByMode(node, mode) | 304 rtype = self.GetTypeByMode(node, release, mode) |
272 if node.IsA('Enum', 'Interface', 'Struct'): | 305 if node.IsA('Enum', 'Interface', 'Struct'): |
273 rname = node.GetName() | 306 rname = node.GetName() |
274 else: | 307 else: |
275 rname = node.GetType(self.release).GetName() | 308 rname = node.GetType(release).GetName() |
276 | 309 |
277 if rname in CGen.RemapName: | 310 if rname in CGen.RemapName: |
278 rname = CGen.RemapName[rname] | 311 rname = CGen.RemapName[rname] |
279 if '%' in rtype: | 312 if '%' in rtype: |
280 rtype = rtype % rname | 313 rtype = rtype % rname |
281 name = node.GetName() | 314 name = node.GetName() |
282 arrayspec = [self.GetArraySpec(array) for array in node.GetListOf('Array')] | 315 arrayspec = [self.GetArraySpec(array) for array in node.GetListOf('Array')] |
283 callnode = node.GetOneOf('Callspec') | 316 callnode = node.GetOneOf('Callspec') |
284 if callnode: | 317 if callnode: |
285 callspec = [] | 318 callspec = [] |
286 for param in callnode.GetListOf('Param'): | 319 for param in callnode.GetListOf('Param'): |
287 mode = self.GetParamMode(param) | 320 mode = self.GetParamMode(param) |
288 ptype, pname, parray, pspec = self.GetComponents(param, mode) | 321 ptype, pname, parray, pspec = self.GetComponents(param, release, mode) |
289 callspec.append((ptype, pname, parray, pspec)) | 322 callspec.append((ptype, pname, parray, pspec)) |
290 else: | 323 else: |
291 callspec = None | 324 callspec = None |
292 | 325 |
293 self.LogExit('GetComponents: %s, %s, %s, %s' % | 326 self.LogExit('GetComponents: %s, %s, %s, %s' % |
294 (rtype, name, arrayspec, callspec)) | 327 (rtype, name, arrayspec, callspec)) |
295 return (rtype, name, arrayspec, callspec) | 328 return (rtype, name, arrayspec, callspec) |
296 | 329 |
297 | 330 |
298 def Compose(self, rtype, name, arrayspec, callspec, prefix, func_as_ptr): | 331 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) | 343 self.LogExit('Exit Compose: %s' % out) |
311 return out | 344 return out |
312 | 345 |
313 # | 346 # |
314 # GetSignature | 347 # GetSignature |
315 # | 348 # |
316 # Returns the 'C' style signature of the object | 349 # Returns the 'C' style signature of the object |
317 # prefix - A prefix for the object's name | 350 # prefix - A prefix for the object's name |
318 # func_as_ptr - Formats a function as a function pointer | 351 # func_as_ptr - Formats a function as a function pointer |
319 # | 352 # |
320 def GetSignature(self, node, mode, prefix='', func_as_ptr=True): | 353 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)) | 354 self.LogEnter('GetSignature %s %s as func=%s' % (node, mode, func_as_ptr)) |
322 rtype, name, arrayspec, callspec = self.GetComponents(node, mode) | 355 rtype, name, arrayspec, callspec = self.GetComponents(node, release, mode) |
323 out = self.Compose(rtype, name, arrayspec, callspec, prefix, func_as_ptr) | 356 out = self.Compose(rtype, name, arrayspec, callspec, prefix, func_as_ptr) |
324 self.LogExit('Exit GetSignature: %s' % out) | 357 self.LogExit('Exit GetSignature: %s' % out) |
325 return out | 358 return out |
326 | 359 |
327 def GetMacro(self, node): | 360 # Define a Typedef. |
328 name = node.GetName() | 361 def DefineTypedef(self, node, releases, prefix='', comment=False): |
329 name = name.upper() | 362 release = releases[0] |
330 return "%s_INTERFACE" % name | 363 out = 'typedef %s;\n' % self.GetSignature(node, release, 'return', |
331 | 364 prefix, True) |
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. | |
339 def DefineTypedef(self, node, prefix='', comment=False): | |
340 out = 'typedef %s;\n' % self.GetSignature(node, 'return', prefix, True) | |
341 self.Log('DefineTypedef: %s' % out) | 365 self.Log('DefineTypedef: %s' % out) |
342 return out | 366 return out |
343 | 367 |
344 # Define an Enum. | 368 # Define an Enum. |
345 def DefineEnum(self, node, prefix='', comment=False): | 369 def DefineEnum(self, node, releases, prefix='', comment=False): |
346 self.LogEnter('DefineEnum %s' % node) | 370 self.LogEnter('DefineEnum %s' % node) |
347 unnamed = node.GetProperty('unnamed') | 371 unnamed = node.GetProperty('unnamed') |
348 if unnamed: | 372 if unnamed: |
349 out = 'enum {' | 373 out = 'enum {' |
350 else: | 374 else: |
351 out = 'typedef enum {' | 375 out = 'typedef enum {' |
352 name = '%s%s' % (prefix, node.GetName()) | 376 name = '%s%s' % (prefix, node.GetName()) |
353 enumlist = [] | 377 enumlist = [] |
354 for child in node.GetListOf('EnumItem'): | 378 for child in node.GetListOf('EnumItem'): |
355 value = child.GetProperty('VALUE') | 379 value = child.GetProperty('VALUE') |
356 comment_txt = '' | 380 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: | 381 if value: |
363 item_txt = '%s%s = %s' % (prefix, child.GetName(), value) | 382 item_txt = '%s%s = %s' % (prefix, child.GetName(), value) |
364 else: | 383 else: |
365 item_txt = '%s%s' % (prefix, child.GetName()) | 384 item_txt = '%s%s' % (prefix, child.GetName()) |
366 enumlist.append('%s %s' % (comment_txt, item_txt)) | 385 enumlist.append('%s %s' % (comment_txt, item_txt)) |
367 self.LogExit('Exit DefineEnum') | 386 self.LogExit('Exit DefineEnum') |
368 | 387 |
369 if unnamed: | 388 if unnamed: |
370 out = '%s\n%s\n};\n' % (out, ',\n'.join(enumlist)) | 389 out = '%s\n%s\n};\n' % (out, ',\n'.join(enumlist)) |
371 else: | 390 else: |
372 out = '%s\n%s\n} %s;\n' % (out, ',\n'.join(enumlist), name) | 391 out = '%s\n%s\n} %s;\n' % (out, ',\n'.join(enumlist), name) |
373 return out | 392 return out |
374 | 393 |
375 def DefineMember(self, node, prefix='', comment=False): | 394 def DefineMember(self, node, releases, prefix='', comment=False): |
| 395 release = releases[0] |
376 self.LogEnter('DefineMember %s' % node) | 396 self.LogEnter('DefineMember %s' % node) |
377 | 397 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') | 398 self.LogExit('Exit DefineMember') |
384 return out | 399 return out |
385 | 400 |
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. | 401 # Define a Struct. |
404 def DefineStruct(self, node, prefix='', comment=False): | 402 def DefineStruct(self, node, releases, prefix='', comment=False): |
405 out = '' | 403 out = '' |
406 | 404 |
407 self.LogEnter('DefineStruct %s' % node) | 405 self.LogEnter('DefineStruct %s' % node) |
408 if node.GetProperty('union'): | 406 if node.GetProperty('union'): |
409 out += 'union %s%s {\n' % (prefix, node.GetName()) | 407 out += 'union %s%s {\n' % (prefix, node.GetName()) |
410 else: | 408 else: |
411 out += 'struct %s%s {\n' % (prefix, node.GetName()) | 409 out += 'struct %s%s {\n' % (prefix, node.GetName()) |
412 | 410 |
413 # Generate Member Functions | 411 # Generate Member Functions |
414 members = [] | 412 members = [] |
415 for child in node.GetListOf('Member'): | 413 for child in node.GetListOf('Member'): |
416 member = self.Define(child, tabs=1, comment=comment) | 414 member = self.Define(child, releases, tabs=1, comment=comment) |
417 if not member: | 415 if not member: |
418 continue | 416 continue |
419 members.append(member) | 417 members.append(member) |
420 out += '%s\n};\n' % '\n'.join(members) | 418 out += '%s\n};\n' % '\n'.join(members) |
421 self.LogExit('Exit DefineStruct') | 419 self.LogExit('Exit DefineStruct') |
422 return out | 420 return out |
423 | 421 |
424 def DefineType(self, node, prefix='', comment=False): | |
425 return '' | |
426 | |
427 # | 422 # |
428 # Copyright and Comment | 423 # Copyright and Comment |
429 # | 424 # |
430 # Generate a comment or copyright block | 425 # Generate a comment or copyright block |
431 # | 426 # |
432 def Copyright(self, node, tabs=0): | 427 def Copyright(self, node, tabs=0): |
433 lines = node.GetName().split('\n') | 428 lines = node.GetName().split('\n') |
434 return self.CommentLines(lines, tabs) | 429 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 | 430 |
458 | 431 |
459 # Define a top level object. | 432 # Define a top level object. |
460 def Define(self, node, tabs=0, prefix='', comment=False): | 433 def Define(self, node, releases, tabs=0, prefix='', comment=False): |
461 if True: | 434 if not node.InReleases(releases): |
462 # try: | 435 return '' |
463 self.LogEnter('Define %s tab=%d prefix="%s"' % (node,tabs,prefix)) | |
464 | 436 |
465 node_nim = node.GetProperty('version') | 437 self.LogEnter('Define %s tab=%d prefix="%s"' % (node,tabs,prefix)) |
466 node_max = node.GetProperty('deprecate') | 438 declmap = { |
| 439 'Enum' : CGen.DefineEnum, |
| 440 'Function' : CGen.DefineMember, |
| 441 'Interface' : CGen.DefineStruct, |
| 442 'Member' : CGen.DefineMember, |
| 443 'Struct' : CGen.DefineStruct, |
| 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 += comment_txt |
| 456 out += define_txt |
| 457 |
| 458 tab = ' ' * tabs |
| 459 lines = [] |
| 460 for line in out.split('\n'): |
| 461 # Add indentation |
| 462 line = tab + line |
| 463 if len(line) > 80: |
| 464 left = line.rfind('(') + 1 |
| 465 args = line[left:].split(',') |
| 466 line_max = 0 |
| 467 for arg in args: |
| 468 if len(arg) > line_max: line_max = len(arg) |
| 469 |
| 470 if left + line_max >= 80: |
| 471 space = '%s ' % tab |
| 472 args = (',\n%s' % space).join([arg.strip() for arg in args]) |
| 473 lines.append('%s\n%s%s' % (line[:left], space, args)) |
| 474 else: |
| 475 space = ' ' * (left - 1) |
| 476 args = (',\n%s' % space).join(args) |
| 477 lines.append('%s%s' % (line[:left], args)) |
470 else: | 478 else: |
471 node_nim = 0.0 | 479 lines.append(line.rstrip()) |
472 | 480 self.LogExit('Exit Define') |
473 if node_max is not None: | 481 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 | 482 |
553 # Clean a string representing an object definition and return then string | 483 # Clean a string representing an object definition and return then string |
554 # as a single space delimited set of tokens. | 484 # as a single space delimited set of tokens. |
555 def CleanString(instr): | 485 def CleanString(instr): |
556 instr = instr.strip() | 486 instr = instr.strip() |
557 instr = instr.split() | 487 instr = instr.split() |
558 return ' '.join(instr) | 488 return ' '.join(instr) |
559 | 489 |
560 | 490 |
561 # Test a file, by comparing all it's objects, with their comments. | 491 # Test a file, by comparing all it's objects, with their comments. |
562 def TestFile(filenode): | 492 def TestFile(filenode): |
563 cgen = CGen() | 493 cgen = CGen() |
564 | 494 |
565 errors = 0 | 495 errors = 0 |
566 for node in filenode.GetChildren()[2:]: | 496 for node in filenode.GetChildren()[2:]: |
567 instr = node.GetOneOf('Comment') | 497 instr = node.GetOneOf('Comment') |
568 if not instr: continue | 498 if not instr: continue |
569 instr.Dump() | 499 instr.Dump() |
570 instr = CleanString(instr.GetName()) | 500 instr = CleanString(instr.GetName()) |
571 | 501 |
572 outstr = cgen.Define(node) | 502 outstr = cgen.Define(node, releases=['M14']) |
573 if GetOption('verbose'): | 503 if GetOption('verbose'): |
574 print outstr + '\n' | 504 print outstr + '\n' |
575 outstr = CleanString(outstr) | 505 outstr = CleanString(outstr) |
576 | 506 |
577 if instr != outstr: | 507 if instr != outstr: |
578 ErrOut.Log('Failed match of\n>>%s<<\n>>%s<<\nto:' % (instr, outstr)) | 508 ErrOut.Log('Failed match of\n>>%s<<\n>>%s<<\nto:' % (instr, outstr)) |
579 node.Dump(1, comments=True) | 509 node.Dump(1, comments=True) |
580 errors += 1 | 510 errors += 1 |
581 return errors | 511 return errors |
582 | 512 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 print 'Skipping %s' % f.GetName() | 545 print 'Skipping %s' % f.GetName() |
616 continue | 546 continue |
617 print DefineDepends(node) | 547 print DefineDepends(node) |
618 for node in f.GetChildren()[2:]: | 548 for node in f.GetChildren()[2:]: |
619 print Define(node, comment=True, prefix='tst_') | 549 print Define(node, comment=True, prefix='tst_') |
620 | 550 |
621 | 551 |
622 if __name__ == '__main__': | 552 if __name__ == '__main__': |
623 sys.exit(Main(sys.argv[1:])) | 553 sys.exit(Main(sys.argv[1:])) |
624 | 554 |
OLD | NEW |