| 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 |