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

Unified Diff: third_party/chrome/ppapi/generators/idl_c_header.py

Issue 12300042: Update idlsync.py to pull in dependencies required for chrome api generation. (Closed) Base URL: git://github.com/dart-lang/bleeding_edge.git@master
Patch Set: From another checkout Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/chrome/ppapi/generators/idl_ast.py ('k') | third_party/chrome/ppapi/generators/idl_c_proto.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/chrome/ppapi/generators/idl_c_header.py
diff --git a/third_party/chrome/ppapi/generators/idl_c_header.py b/third_party/chrome/ppapi/generators/idl_c_header.py
new file mode 100755
index 0000000000000000000000000000000000000000..2c3cf2cb3a2755a3d14e78ad4c7033449255de79
--- /dev/null
+++ b/third_party/chrome/ppapi/generators/idl_c_header.py
@@ -0,0 +1,299 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+""" Generator for C style prototypes and definitions """
+
+import glob
+import os
+import re
+import sys
+
+from idl_log import ErrOut, InfoOut, WarnOut
+from idl_node import IDLAttribute, IDLNode
+from idl_ast import IDLAst
+from idl_option import GetOption, Option, ParseOptions
+from idl_outfile import IDLOutFile
+from idl_parser import ParseFiles
+from idl_c_proto import CGen, GetNodeComments, CommentLines, Comment
+from idl_generator import Generator, GeneratorByFile
+from idl_visitor import IDLVisitor
+
+Option('dstroot', 'Base directory of output', default=os.path.join('..', 'c'))
+Option('guard', 'Include guard prefix', default=os.path.join('ppapi', 'c'))
+
+
+#
+# PrototypeResolver
+#
+# A specialized visitor which traverses the AST, building a mapping of
+# Release names to Versions numbers and calculating a min version.
+# The mapping is applied to the File nodes within the AST.
+#
+class ProtoResolver(IDLVisitor):
+ def __init__(self):
+ IDLVisitor.__init__(self)
+ self.struct_map = {}
+ self.interface_map = {}
+
+ def Arrive(self, node, ignore):
+ if node.IsA('Member') and node.GetProperty('ref'):
+ typeref = node.typelist.GetReleases()[0]
+ if typeref.IsA('Struct'):
+ nodelist = self.struct_map.get(typeref.GetName(), [])
+ nodelist.append(node)
+ self.struct_map[typeref.GetName()] = nodelist
+
+ if node.IsA('Param'):
+ typeref = node.typelist.GetReleases()[0]
+ if typeref.IsA('Interface'):
+ nodelist = self.struct_map.get(typeref.GetName(), [])
+ nodelist.append(node)
+ self.interface_map[typeref.GetName()] = nodelist
+
+ return None
+
+
+def GetPathFromNode(filenode, relpath=None, ext=None):
+ path, name = os.path.split(filenode.GetProperty('NAME'))
+ if ext: name = os.path.splitext(name)[0] + ext
+ if path: name = os.path.join(path, name)
+ if relpath: name = os.path.join(relpath, name)
+ name = os.path.normpath(name)
+ return name
+
+
+def GetHeaderFromNode(filenode, relpath=None):
+ return GetPathFromNode(filenode, relpath, ext='.h')
+
+
+def WriteGroupMarker(out, node, last_group):
+ # If we are part of a group comment marker...
+ if last_group and last_group != node.cls:
+ pre = CommentLines(['*',' @}', '']) + '\n'
+ else:
+ pre = '\n'
+
+ if node.cls in ['Typedef', 'Interface', 'Struct', 'Enum']:
+ if last_group != node.cls:
+ pre += CommentLines(['*',' @addtogroup %ss' % node.cls, ' @{', ''])
+ last_group = node.cls
+ else:
+ last_group = None
+ out.Write(pre)
+ return last_group
+
+
+def GenerateHeader(out, filenode, releases):
+ cgen = CGen()
+ pref = ''
+ do_comments = True
+
+ # Generate definitions.
+ last_group = None
+ top_types = ['Typedef', 'Interface', 'Struct', 'Enum', 'Inline']
+ for node in filenode.GetListOf(*top_types):
+ # Skip if this node is not in this release
+ if not node.InReleases(releases):
+ print "Skiping %s" % node
+ continue
+
+ # End/Start group marker
+ if do_comments:
+ last_group = WriteGroupMarker(out, node, last_group)
+
+ if node.IsA('Inline'):
+ item = node.GetProperty('VALUE')
+ # If 'C++' use __cplusplus wrapper
+ if node.GetName() == 'cc':
+ item = '#ifdef __cplusplus\n%s\n#endif /* __cplusplus */\n\n' % item
+ # If not C++ or C, then skip it
+ elif not node.GetName() == 'c':
+ continue
+ if item: out.Write(item)
+ continue
+
+ #
+ # Otherwise we are defining a file level object, so generate the
+ # correct document notation.
+ #
+ item = cgen.Define(node, releases, prefix=pref, comment=True)
+ if not item: continue
+ asize = node.GetProperty('assert_size()')
+ if asize:
+ name = '%s%s' % (pref, node.GetName())
+ if node.IsA('Struct'):
+ form = 'PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(%s, %s);\n'
+ elif node.IsA('Enum'):
+ if node.GetProperty('notypedef'):
+ form = 'PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(%s, %s);\n'
+ else:
+ form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n'
+ else:
+ form = 'PP_COMPILE_ASSERT_SIZE_IN_BYTES(%s, %s);\n'
+ item += form % (name, asize[0])
+
+ if item: out.Write(item)
+ if last_group:
+ out.Write(CommentLines(['*',' @}', '']) + '\n')
+
+
+class HGen(GeneratorByFile):
+ def __init__(self):
+ Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.')
+
+ def GenerateFile(self, filenode, releases, options):
+ savename = GetHeaderFromNode(filenode, GetOption('dstroot'))
+ my_min, my_max = filenode.GetMinMax(releases)
+ if my_min > releases[-1] or my_max < releases[0]:
+ if os.path.isfile(savename):
+ print "Removing stale %s for this range." % filenode.GetName()
+ os.remove(os.path.realpath(savename))
+ return False
+
+ out = IDLOutFile(savename)
+ self.GenerateHead(out, filenode, releases, options)
+ self.GenerateBody(out, filenode, releases, options)
+ self.GenerateTail(out, filenode, releases, options)
+ return out.Close()
+
+ def GenerateHead(self, out, filenode, releases, options):
+ __pychecker__ = 'unusednames=options'
+
+ proto = ProtoResolver()
+ proto.Visit(filenode, None)
+
+ cgen = CGen()
+ gpath = GetOption('guard')
+ def_guard = GetHeaderFromNode(filenode, relpath=gpath)
+ def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_'
+
+ cright_node = filenode.GetChildren()[0]
+ assert(cright_node.IsA('Copyright'))
+ fileinfo = filenode.GetChildren()[1]
+ assert(fileinfo.IsA('Comment'))
+
+ out.Write('%s\n' % cgen.Copyright(cright_node))
+
+ # Wrap the From ... modified ... comment if it would be >80 characters.
+ from_text = 'From %s' % GetPathFromNode(filenode).replace(os.sep, '/')
+ modified_text = 'modified %s.' % (
+ filenode.GetProperty('DATETIME'))
+ if len(from_text) + len(modified_text) < 74:
+ out.Write('/* %s %s */\n\n' % (from_text, modified_text))
+ else:
+ out.Write('/* %s,\n * %s\n */\n\n' % (from_text, modified_text))
+
+ out.Write('#ifndef %s\n#define %s\n\n' % (def_guard, def_guard))
+ # Generate set of includes
+
+ deps = set()
+ for release in releases:
+ deps |= filenode.GetDeps(release)
+
+ includes = set([])
+ for dep in deps:
+ depfile = dep.GetProperty('FILE')
+ if depfile:
+ includes.add(depfile)
+ includes = [GetHeaderFromNode(
+ include, relpath=gpath).replace(os.sep, '/') for include in includes]
+ includes.append('ppapi/c/pp_macros.h')
+
+ # Assume we need stdint if we "include" C or C++ code
+ if filenode.GetListOf('Include'):
+ includes.append('ppapi/c/pp_stdint.h')
+
+ includes = sorted(set(includes))
+ cur_include = GetHeaderFromNode(filenode,
+ relpath=gpath).replace(os.sep, '/')
+ for include in includes:
+ if include == cur_include: continue
+ out.Write('#include "%s"\n' % include)
+
+ # Generate Prototypes
+ if proto.struct_map:
+ out.Write('\n/* Struct prototypes */\n')
+ for struct in proto.struct_map:
+ out.Write('struct %s;\n' % struct)
+
+ # Create a macro for the highest available release number.
+ if filenode.GetProperty('NAME').endswith('pp_macros.idl'):
+ releasestr = ' '.join(releases)
+ if releasestr:
+ release_numbers = re.findall('[\d\_]+', releasestr)
+ release = re.findall('\d+', release_numbers[-1])[0]
+ if release:
+ out.Write('\n#define PPAPI_RELEASE %s\n' % release)
+
+ # Generate all interface defines
+ out.Write('\n')
+ for node in filenode.GetListOf('Interface'):
+ idefs = ''
+ macro = cgen.GetInterfaceMacro(node)
+ unique = node.GetUniqueReleases(releases)
+
+ # Skip this interface if there are no matching versions
+ if not unique: continue
+
+ for rel in unique:
+ version = node.GetVersion(rel)
+ name = cgen.GetInterfaceString(node, version)
+ strver = str(version).replace('.', '_')
+ idefs += cgen.GetDefine('%s_%s' % (macro, strver), '"%s"' % name)
+ idefs += cgen.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n'
+ out.Write(idefs)
+
+ # Generate the @file comment
+ out.Write('%s\n' % Comment(fileinfo, prefix='*\n @file'))
+
+ def GenerateBody(self, out, filenode, releases, options):
+ __pychecker__ = 'unusednames=options'
+ GenerateHeader(out, filenode, releases)
+
+ def GenerateTail(self, out, filenode, releases, options):
+ __pychecker__ = 'unusednames=options,releases'
+ gpath = GetOption('guard')
+ def_guard = GetPathFromNode(filenode, relpath=gpath, ext='.h')
+ def_guard = def_guard.replace(os.sep,'_').replace('.','_').upper() + '_'
+ out.Write('#endif /* %s */\n\n' % def_guard)
+
+
+hgen = HGen()
+
+def main(args):
+ # Default invocation will verify the golden files are unchanged.
+ failed = 0
+ if not args:
+ args = ['--wnone', '--diff', '--test', '--dstroot=.']
+
+ ParseOptions(args)
+
+ idldir = os.path.split(sys.argv[0])[0]
+ idldir = os.path.join(idldir, 'test_cgen', '*.idl')
+ filenames = glob.glob(idldir)
+ ast = ParseFiles(filenames)
+ if hgen.GenerateRelease(ast, 'M14', {}):
+ print "Golden file for M14 failed."
+ failed = 1
+ else:
+ print "Golden file for M14 passed."
+
+
+ idldir = os.path.split(sys.argv[0])[0]
+ idldir = os.path.join(idldir, 'test_cgen_range', '*.idl')
+ filenames = glob.glob(idldir)
+
+ ast = ParseFiles(filenames)
+ if hgen.GenerateRange(ast, ['M13', 'M14', 'M15'], {}):
+ print "Golden file for M13-M15 failed."
+ failed =1
+ else:
+ print "Golden file for M13-M15 passed."
+
+ return failed
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
+
« no previous file with comments | « third_party/chrome/ppapi/generators/idl_ast.py ('k') | third_party/chrome/ppapi/generators/idl_c_proto.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698