15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" Generator for C style prototypes and definitions """ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import glob 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_log import ErrOut, InfoOut, WarnOut 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_node import IDLAttribute, IDLNode 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_ast import IDLAst 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_option import GetOption, Option, ParseOptions 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_outfile import IDLOutFile 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_parser import ParseFiles 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_c_proto import CGen, GetNodeComments, CommentLines, Comment 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_generator import Generator, GeneratorByFile 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from idl_visitor import IDLVisitor 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('dstroot', 'Base directory of output', default=os.path.join('..', 'c')) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('guard', 'Include guard prefix', default=os.path.join('ppapi', 'c')) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# PrototypeResolver 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# A specialized visitor which traverses the AST, building a mapping of 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Release names to Versions numbers and calculating a min version. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# The mapping is applied to the File nodes within the AST. 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProtoResolver(IDLVisitor): 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def __init__(self): 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDLVisitor.__init__(self) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.struct_map = {} 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.interface_map = {} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def Arrive(self, node, ignore): 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.IsA('Member') and node.GetProperty('ref'): 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typeref = node.typelist.GetReleases()[0] 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if typeref.IsA('Struct'): 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nodelist = self.struct_map.get(typeref.GetName(), []) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nodelist.append(node) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.struct_map[typeref.GetName()] = nodelist 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if node.IsA('Param'): 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typeref = node.typelist.GetReleases()[0] 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if typeref.IsA('Interface'): 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nodelist = self.struct_map.get(typeref.GetName(), []) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nodelist.append(node) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.interface_map[typeref.GetName()] = nodelist 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return None 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def GetPathFromNode(filenode, relpath=None, ext=None): 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path, name = os.path.split(filenode.GetProperty('NAME')) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ext: name = os.path.splitext(name)[0] + ext 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if path: name = os.path.join(path, name) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if relpath: name = os.path.join(relpath, name) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name = os.path.normpath(name) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def GetHeaderFromNode(filenode, relpath=None): 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetPathFromNode(filenode, relpath, ext='.h') 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def WriteGroupMarker(out, node, last_group): 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If we are part of a group comment marker... 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if last_group and last_group != node.cls: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pre = CommentLines(['*',' @}', '']) + '\n' 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pre = '\n' 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if last_group != node.cls: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pre += CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', '']) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_group = node.cls 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_group = None 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write(pre) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return last_group 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GenerateHeader(out, filenode, releases): 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgen = CGen() 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref = '' 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do_comments = True 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate definitions. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_group = None 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline'] 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for node in filenode.GetListOf(*top_types): 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Skip if this node is not in this release 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not node.InReleases(releases): 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Skiping %s" % node 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # End/Start group marker 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if do_comments: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_group = WriteGroupMarker(out, node, last_group) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('Inline'): 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = node.GetProperty('VALUE') 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If 'C++' use __cplusplus wrapper 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.GetName() == 'cc': 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = '#ifdef __cplusplus\n%s\n#endif /* __cplusplus */\n\n' % item 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If not C++ or C, then skip it 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif not node.GetName() == 'c': 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if item: out.Write(item) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Otherwise we are defining a file level object, so generate the 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # correct document notation. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = cgen.Define(node, releases, prefix=pref, comment=True) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not item: continue 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asize = node.GetProperty('assert_size()') 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if asize: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = '%s%s' % (pref, node.GetName()) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.IsA('Struct'): 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n' 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif node.IsA('Enum'): 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.GetProperty('notypedef'): 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form = 'PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(%s, %s);\n' 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n' 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n' 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item += form % (name, asize[0]) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if item: out.Write(item) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if last_group: 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write(CommentLines(['*',' @}', '']) + '\n') 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def CheckTypedefs(filenode, releases): 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Checks that typedefs don't specify callbacks that take some structs. 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) See http://crbug.com/233439 for details. 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """ 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cgen = CGen() 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # TODO(teravest): Fix the following callback to pass PP_Var by pointer 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # instead of by value. 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) node_whitelist = ['PP_Ext_Alarms_OnAlarm_Func_Dev_0_1'] 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for node in filenode.GetListOf('Typedef'): 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if node.GetName() in node_whitelist: 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) build_list = node.GetUniqueReleases(releases) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callnode = node.GetOneOf('Callspec') 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if callnode: 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for param in callnode.GetListOf('Param'): 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if param.GetListOf('Array'): 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if cgen.GetParamMode(param) != 'in': 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) t = param.GetType(build_list[0]) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while t.IsA('Typedef'): 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) t = t.GetType(build_list[0]) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if t.IsA('Struct'): 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) raise Exception('%s is a struct in callback %s. ' 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'See http://crbug.com/233439' % 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (t.GetName(), node.GetName())) 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)def CheckPassByValue(filenode, releases): 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) """Checks that new pass-by-value structs are not introduced. 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) See http://crbug.com/233439 for details. 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) """ 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) cgen = CGen() 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) # DO NOT add any more entries to this whitelist. 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) # http://crbug.com/233439 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type_whitelist = ['PP_ArrayOutput', 'PP_CompletionCallback', 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 'PP_Ext_EventListener', 'PP_FloatPoint', 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 'PP_Point', 'PP_TouchPoint', 'PP_Var'] 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) nodes_to_check = filenode.GetListOf('Struct') 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) nodes_to_check.extend(filenode.GetListOf('Union')) 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for node in nodes_to_check: 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if node.GetName() in type_whitelist: 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) build_list = node.GetUniqueReleases(releases) 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if node.GetProperty('passByValue'): 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) raise Exception('%s is a new passByValue struct or union. ' 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 'See http://crbug.com/233439' % node.GetName()) 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if node.GetProperty('returnByValue'): 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) raise Exception('%s is a new returnByValue struct or union. ' 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 'See http://crbug.com/233439' % node.GetName()) 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HGen(GeneratorByFile): 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.') 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateFile(self, filenode, releases, options): 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckTypedefs(filenode, releases) 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CheckPassByValue(filenode, releases) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) savename = GetHeaderFromNode(filenode, GetOption('dstroot')) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) my_min, my_max = filenode.GetMinMax(releases) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if my_min > releases[-1] or my_max < releases[0]: 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if os.path.isfile(savename): 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Removing stale %s for this range." % filenode.GetName() 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.remove(os.path.realpath(savename)) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = IDLOutFile(savename) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.GenerateHead(out, filenode, releases, options) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.GenerateBody(out, filenode, releases, options) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.GenerateTail(out, filenode, releases, options) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return out.Close() 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateHead(self, out, filenode, releases, options): 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __pychecker__ = 'unusednames=options' 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proto = ProtoResolver() 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) proto.Visit(filenode, None) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cgen = CGen() 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpath = GetOption('guard') 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def_guard = GetHeaderFromNode(filenode, relpath=gpath) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_' 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cright_node = filenode.GetChildren()[0] 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(cright_node.IsA('Copyright')) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileinfo = filenode.GetChildren()[1] 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(fileinfo.IsA('Comment')) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('%s\n' % cgen.Copyright(cright_node)) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Wrap the From ... modified ... comment if it would be >80 characters. 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) from_text = 'From %s' % GetPathFromNode(filenode).replace(os.sep, '/') 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_text = 'modified %s.' % ( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenode.GetProperty('DATETIME')) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(from_text) + len(modified_text) < 74: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('/* %s %s */\n\n' % (from_text, modified_text)) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('/* %s,\n * %s\n */\n\n' % (from_text, modified_text)) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard)) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate set of includes 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deps = set() 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for release in releases: 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deps |= filenode.GetDeps(release) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) includes = set([]) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for dep in deps: 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depfile = dep.GetProperty('FILE') 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if depfile: 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) includes.add(depfile) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) includes = [GetHeaderFromNode( 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) include, relpath=gpath).replace(os.sep, '/') for include in includes] 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) includes.append('ppapi/c/pp_macros.h') 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Assume we need stdint if we "include" C or C++ code 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filenode.GetListOf('Include'): 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) includes.append('ppapi/c/pp_stdint.h') 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) includes = sorted(set(includes)) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cur_include = GetHeaderFromNode(filenode, 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) relpath=gpath).replace(os.sep, '/') 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for include in includes: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if include == cur_include: continue 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('#include "%s"\n' % include) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Generate Prototypes 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if proto.struct_map: 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out.Write('\n/* Struct prototypes */\n') 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for struct in proto.struct_map: 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out.Write('struct %s;\n' % struct) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) # Create a macro for the highest available release number. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filenode.GetProperty('NAME').endswith('pp_macros.idl'): 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) releasestr = ' '.join(releases) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if releasestr: 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) release_numbers = re.findall('[\d\_]+', releasestr) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) release = re.findall('\d+', release_numbers[-1])[0] 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if release: 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out.Write('\n#define PPAPI_RELEASE %s\n' % release) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate all interface defines 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('\n') 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for node in filenode.GetListOf('Interface'): 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idefs = '' 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macro = cgen.GetInterfaceMacro(node) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unique = node.GetUniqueReleases(releases) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Skip this interface if there are no matching versions 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not unique: continue 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for rel in unique: 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = node.GetVersion(rel) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = cgen.GetInterfaceString(node, version) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strver = str(version).replace('.', '_') 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idefs += cgen.GetDefine('%s_%s' % (macro, strver), '"%s"' % name) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idefs += cgen.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n' 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write(idefs) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate the @file comment 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file')) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateBody(self, out, filenode, releases, options): 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __pychecker__ = 'unusednames=options' 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateHeader(out, filenode, releases) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def GenerateTail(self, out, filenode, releases, options): 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __pychecker__ = 'unusednames=options,releases' 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpath = GetOption('guard') 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) def_guard = GetPathFromNode(filenode, relpath=gpath, ext='.h') 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_' 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.Write('#endif /* %s */\n\n' % def_guard) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hgen = HGen() 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def main(args): 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Default invocation will verify the golden files are unchanged. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 0 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not args: 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args = ['--wnone', '--diff', '--test', '--dstroot=.'] 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseOptions(args) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idldir = os.path.split(sys.argv[0])[0] 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idldir = os.path.join(idldir, 'test_cgen', '*.idl') 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = glob.glob(idldir) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ast = ParseFiles(filenames) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hgen.GenerateRelease(ast, 'M14', {}): 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Golden file for M14 failed." 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 1 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Golden file for M14 passed." 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idldir = os.path.split(sys.argv[0])[0] 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idldir = os.path.join(idldir, 'test_cgen_range', '*.idl') 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filenames = glob.glob(idldir) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ast = ParseFiles(filenames) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hgen.GenerateRange(ast, ['M13', 'M14', 'M15'], {}): 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Golden file for M13-M15 failed." 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed =1 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Golden file for M13-M15 passed." 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return failed 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sys.exit(main(sys.argv[1:])) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 356