Remove ppapi/generators This is a reland of https://crrev.com/c/6729535 It was reverted in https://crrev.com/c/6729435 because there was a dependency on these files from the extensions API schema compiler. The relevant files have now been copied over to //tools/json_schema_compiler in https://crrev.com/c/6730496, so this change can reland. Bug: 40511454 Change-Id: I63e74ae58fc43108b67436df281f33bb5228fa67 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6757842 Reviewed-by: Tim <tjudkins@chromium.org> Auto-Submit: Derek Schuff <dschuff@chromium.org> Commit-Queue: Derek Schuff <dschuff@chromium.org> Cr-Commit-Position: refs/heads/main@{#1487220} NOKEYCHECK=True GitOrigin-RevId: 47940ab8bb9439cf20299d54a7f70fe584d9c73b
diff --git a/generators/OWNERS b/generators/OWNERS deleted file mode 100644 index 12e5779..0000000 --- a/generators/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -bradnelson@chromium.org
diff --git a/generators/generator.py b/generators/generator.py deleted file mode 100755 index 0fc5ba5..0000000 --- a/generators/generator.py +++ /dev/null
@@ -1,60 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from __future__ import print_function - -import os -import sys -import traceback - -# Note: some of these files are imported to register cmdline options. -from idl_generator import Generator -from idl_option import ParseOptions -from idl_outfile import IDLOutFile -from idl_parser import ParseFiles -from idl_c_header import HGen -from idl_thunk import TGen -from idl_gen_pnacl import PnaclGen - - -def Main(args): - # If no arguments are provided, assume we are trying to rebuild the - # C headers with warnings off. - try: - if not args: - args = [ - '--wnone', '--cgen', '--range=start,end', - '--pnacl', '--pnaclshim', - '../native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c', - '--tgen', - ] - current_dir = os.path.abspath(os.getcwd()) - script_dir = os.path.abspath(os.path.dirname(__file__)) - if current_dir != script_dir: - print('\nIncorrect CWD, default run skipped.') - print( - 'When running with no arguments set CWD to the scripts directory:') - print('\t' + script_dir + '\n') - print('This ensures correct default paths and behavior.\n') - return 1 - - filenames = ParseOptions(args) - ast = ParseFiles(filenames) - if ast.errors: - print('Found %d errors. Aborting build.\n' % ast.errors) - return 1 - return Generator.Run(ast) - except SystemExit as ec: - print('Exiting with %d' % ec.code) - sys.exit(ec.code) - - except: - typeinfo, value, tb = sys.exc_info() - traceback.print_exception(typeinfo, value, tb) - print('Called with: ' + ' '.join(sys.argv)) - - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_ast.py b/generators/idl_ast.py deleted file mode 100644 index 72f4172..0000000 --- a/generators/idl_ast.py +++ /dev/null
@@ -1,182 +0,0 @@ -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Nodes for PPAPI IDL AST.""" - -from __future__ import print_function - -from idl_namespace import IDLNamespace -from idl_node import IDLNode -from idl_option import GetOption -from idl_visitor import IDLVisitor -from idl_release import IDLReleaseMap - -# -# IDLLabelResolver -# -# 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 IDLLabelResolver(IDLVisitor): - def Depart(self, node, ignore, childdata): - # Build list of Release=Version - if node.IsA('LabelItem'): - channel = node.GetProperty('channel') - if not channel: - channel = 'stable' - return (node.GetName(), node.GetProperty('VALUE'), channel) - - # On completion of the Label, apply to the parent File if the - # name of the label matches the generation label. - if node.IsA('Label') and node.GetName() == GetOption('label'): - try: - node.parent.release_map = IDLReleaseMap(childdata) - except Exception as err: - node.Error('Unable to build release map: %s' % str(err)) - - # For File objects, set the minimum version - if node.IsA('File'): - file_min, _ = node.release_map.GetReleaseRange() - node.SetMin(file_min) - - return None - - -# -# IDLNamespaceVersionResolver -# -# A specialized visitor which traverses the AST, building a namespace tree -# as it goes. The namespace tree is mapping from a name to a version list. -# Labels must already be resolved to use. -# -class IDLNamespaceVersionResolver(IDLVisitor): - NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct']) - # - # When we arrive at a node we must assign it a namespace and if the - # node is named, then place it in the appropriate namespace. - # - def Arrive(self, node, parent_namespace): - # If we are a File, grab the Min version and replease mapping - if node.IsA('File'): - self.rmin = node.GetMinMax()[0] - self.release_map = node.release_map - - # Set the min version on any non Label within the File - if not node.IsA('AST', 'File', 'Label', 'LabelItem'): - my_min, _ = node.GetMinMax() - if not my_min: - node.SetMin(self.rmin) - - # If this object is not a namespace aware object, use the parent's one - if node.cls not in self.NamespaceSet: - node.namespace = parent_namespace - else: - # otherwise create one. - node.namespace = IDLNamespace(parent_namespace) - - # If this node is named, place it in its parent's namespace - if parent_namespace and node.cls in IDLNode.NamedSet: - # Set version min and max based on properties - if self.release_map: - vmin = node.GetProperty('dev_version') - if vmin == None: - vmin = node.GetProperty('version') - vmax = node.GetProperty('deprecate') - # If no min is available, the use the parent File's min - if vmin == None: - rmin = self.rmin - else: - rmin = self.release_map.GetRelease(vmin) - rmax = self.release_map.GetRelease(vmax) - node.SetReleaseRange(rmin, rmax) - parent_namespace.AddNode(node) - - # Pass this namespace to each child in case they inherit it - return node.namespace - - -# -# IDLFileTypeRessolver -# -# A specialized visitor which traverses the AST and sets a FILE property -# on all file nodes. In addition, searches the namespace resolving all -# type references. The namespace tree must already have been populated -# before this visitor is used. -# -class IDLFileTypeResolver(IDLVisitor): - def VisitFilter(self, node, data): - return not node.IsA('Comment', 'Copyright') - - def Arrive(self, node, filenode): - # Track the file node to update errors - if node.IsA('File'): - node.SetProperty('FILE', node) - filenode = node - - if not node.IsA('AST'): - file_min, _ = filenode.release_map.GetReleaseRange() - if not file_min: - print('Resetting min on %s to %s' % (node, file_min)) - node.SetMinRange(file_min) - - # If this node has a TYPEREF, resolve it to a version list - typeref = node.GetPropertyLocal('TYPEREF') - if typeref: - node.typelist = node.parent.namespace.FindList(typeref) - if not node.typelist: - node.Error('Could not resolve %s.' % typeref) - else: - node.typelist = None - return filenode - -# -# IDLReleaseResolver -# -# A specialized visitor which will traverse the AST, and generate a mapping -# from any release to the first release in which that version of the object -# was generated. Types must already be resolved to use. -# -class IDLReleaseResolver(IDLVisitor): - def Arrive(self, node, releases): - node.BuildReleaseMap(releases) - return releases - - -# -# IDLAst -# -# A specialized version of the IDLNode for containing the whole of the -# AST. Construction of the AST object will cause resolution of the -# tree including versions, types, etc... Errors counts will be collected -# both per file, and on the AST itself. -# -class IDLAst(IDLNode): - def __init__(self, children): - IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, children) - self.Resolve() - - def Resolve(self): - # Set the appropriate Release=Version mapping for each File - IDLLabelResolver().Visit(self, None) - - # Generate the Namesapce Tree - self.namespace = IDLNamespace(None) - IDLNamespaceVersionResolver().Visit(self, self.namespace) - - # Using the namespace, resolve type references - IDLFileTypeResolver().Visit(self, None) - - # Build an ordered list of all releases - releases = set() - for filenode in self.GetListOf('File'): - releases |= set(filenode.release_map.GetReleases()) - - # Generate a per node list of releases and release mapping - IDLReleaseResolver().Visit(self, sorted(releases)) - - for filenode in self.GetListOf('File'): - errors = filenode.GetProperty('ERRORS') - if errors: - self.errors += errors
diff --git a/generators/idl_c_header.py b/generators/idl_c_header.py deleted file mode 100755 index ae59b12..0000000 --- a/generators/idl_c_header.py +++ /dev/null
@@ -1,375 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# 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 """ - -from __future__ import print_function - -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') - - -def CheckTypedefs(filenode, releases): - """Checks that typedefs don't specify callbacks that take some structs. - - See http://crbug.com/233439 for details. - """ - cgen = CGen() - for node in filenode.GetListOf('Typedef'): - build_list = node.GetUniqueReleases(releases) - callnode = node.GetOneOf('Callspec') - if callnode: - for param in callnode.GetListOf('Param'): - if param.GetListOf('Array'): - continue - if cgen.GetParamMode(param) != 'in': - continue - t = param.GetType(build_list[0]) - while t.IsA('Typedef'): - t = t.GetType(build_list[0]) - if t.IsA('Struct') and t.GetProperty('passByValue'): - raise Exception('%s is a struct in callback %s. ' - 'See http://crbug.com/233439' % - (t.GetName(), node.GetName())) - - -def CheckPassByValue(filenode, releases): - """Checks that new pass-by-value structs are not introduced. - - See http://crbug.com/233439 for details. - """ - cgen = CGen() - # DO NOT add any more entries to this whitelist. - # http://crbug.com/233439 - type_whitelist = ['PP_ArrayOutput', 'PP_CompletionCallback', - 'PP_Ext_EventListener', 'PP_FloatPoint', - 'PP_Point', 'PP_TouchPoint', 'PP_Var'] - nodes_to_check = filenode.GetListOf('Struct') - nodes_to_check.extend(filenode.GetListOf('Union')) - for node in nodes_to_check: - if node.GetName() in type_whitelist: - continue - build_list = node.GetUniqueReleases(releases) - if node.GetProperty('passByValue'): - raise Exception('%s is a new passByValue struct or union. ' - 'See http://crbug.com/233439' % node.GetName()) - if node.GetProperty('returnByValue'): - raise Exception('%s is a new returnByValue struct or union. ' - 'See http://crbug.com/233439' % node.GetName()) - - -class HGen(GeneratorByFile): - def __init__(self): - Generator.__init__(self, 'C Header', 'cgen', 'Generate the C headers.') - - def GenerateFile(self, filenode, releases, options): - CheckTypedefs(filenode, releases) - CheckPassByValue(filenode, releases) - 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('#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 - - # Skip this interface if it should have no interface string. - if node.GetProperty('no_interface_string'): continue - - last_stable_ver = None - last_dev_rel = None - for rel in unique: - channel = node.GetProperty('FILE').release_map.GetChannel(rel) - if channel == 'dev': - last_dev_rel = rel - - for rel in unique: - version = node.GetVersion(rel) - name = cgen.GetInterfaceString(node, version) - strver = str(version).replace('.', '_') - channel = node.GetProperty('FILE').release_map.GetChannel(rel) - if channel == 'dev': - # Skip dev channel interface versions that are - # Not the newest version, and - # Don't have an equivalent stable version. - if rel != last_dev_rel and not node.DevInterfaceMatchesStable(rel): - continue - value_string = '"%s" /* dev */' % name - else: - value_string = '"%s"' % name - last_stable_ver = strver - idefs += cgen.GetDefine('%s_%s' % (macro, strver), value_string) - if last_stable_ver: - idefs += cgen.GetDefine(macro, '%s_%s' % (macro, last_stable_ver)) - idefs += '\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', 'M16', 'M17'], {}): - print("Golden file for M13-M17 failed.") - failed =1 - else: - print("Golden file for M13-M17 passed.") - - return failed - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:]))
diff --git a/generators/idl_c_proto.py b/generators/idl_c_proto.py deleted file mode 100755 index cb82888..0000000 --- a/generators/idl_c_proto.py +++ /dev/null
@@ -1,821 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# 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 """ - -from __future__ import print_function - -import glob -import os -import sys - -from idl_log import ErrOut, InfoOut, WarnOut -from idl_node import IDLNode -from idl_ast import IDLAst -from idl_option import GetOption, Option, ParseOptions -from idl_parser import ParseFiles - -Option('cgen_debug', 'Debug generate.') - -class CGenError(Exception): - def __init__(self, msg): - self.value = msg - - def __str__(self): - return repr(self.value) - - -def CommentLines(lines, tabs=0): - # Generate a C style comment block by prepending the block with '<tab>/*' - # and adding a '<tab> *' per line. - tab = ' ' * tabs - - out = '%s/*' % tab + ('\n%s *' % tab).join(lines) - - # Add a terminating ' */' unless the last line is blank which would mean it - # already has ' *' - if not lines[-1]: - out += '/\n' - else: - out += ' */\n' - return out - -def Comment(node, prefix=None, tabs=0): - # Generate a comment block from the provided Comment node. - comment = node.GetName() - lines = comment.split('\n') - - # If an option prefix is provided, then prepend that to the comment - # for this node. - if prefix: - prefix_lines = prefix.split('\n') - # If both the prefix and comment start with a blank line ('*') remove - # the extra one. - if prefix_lines[0] == '*' and lines[0] == '*': - lines = prefix_lines + lines[1:] - else: - lines = prefix_lines + lines; - return CommentLines(lines, tabs) - -def GetNodeComments(node, tabs=0): - # Generate a comment block joining all comment nodes which are children of - # the provided node. - comment_txt = '' - for doc in node.GetListOf('Comment'): - comment_txt += Comment(doc, tabs=tabs) - return comment_txt - - -class CGen(object): - # TypeMap - # - # TypeMap modifies how an object is stored or passed, for example pointers - # are passed as 'const' if they are 'in' parameters, and structures are - # preceeded by the keyword 'struct' as well as using a pointer. - # - TypeMap = { - 'Array': { - 'in': 'const %s', - 'inout': '%s', - 'out': '%s*', - 'store': '%s', - 'return': '%s', - 'ref': '%s*' - }, - 'Callspec': { - 'in': '%s', - 'inout': '%s', - 'out': '%s', - 'store': '%s', - 'return': '%s' - }, - 'Enum': { - 'in': '%s', - 'inout': '%s*', - 'out': '%s*', - 'store': '%s', - 'return': '%s' - }, - 'Interface': { - 'in': 'const %s*', - 'inout': '%s*', - 'out': '%s**', - 'return': '%s*', - 'store': '%s*' - }, - 'Struct': { - 'in': 'const %s*', - 'inout': '%s*', - 'out': '%s*', - 'return': ' %s*', - 'store': '%s', - 'ref': '%s*' - }, - 'blob_t': { - 'in': 'const %s', - 'inout': '%s', - 'out': '%s', - 'return': '%s', - 'store': '%s' - }, - 'mem_t': { - 'in': 'const %s', - 'inout': '%s', - 'out': '%s', - 'return': '%s', - 'store': '%s' - }, - 'mem_ptr_t': { - 'in': 'const %s', - 'inout': '%s', - 'out': '%s', - 'return': '%s', - 'store': '%s' - }, - 'str_t': { - 'in': 'const %s', - 'inout': '%s', - 'out': '%s', - 'return': 'const %s', - 'store': '%s' - }, - 'cstr_t': { - 'in': '%s', - 'inout': '%s*', - 'out': '%s*', - 'return': '%s', - 'store': '%s' - }, - 'TypeValue': { - 'in': '%s', - 'constptr_in': 'const %s*', # So we can use const* for PP_Var sometimes. - 'inout': '%s*', - 'out': '%s*', - 'return': '%s', - 'store': '%s' - }, - } - - - # - # RemapName - # - # A diction array of PPAPI types that are converted to language specific - # types before being returned by by the C generator - # - RemapName = { - 'blob_t': 'void**', - 'float_t': 'float', - 'double_t': 'double', - 'handle_t': 'int', - 'mem_t': 'void*', - 'mem_ptr_t': 'void**', - 'str_t': 'char*', - 'cstr_t': 'const char*', - 'interface_t' : 'const void*' - } - - # Tell how to handle pointers to GL types. - for gltype in ['GLbitfield', 'GLboolean', 'GLbyte', 'GLclampf', - 'GLclampx', 'GLenum', 'GLfixed', 'GLfloat', 'GLint', - 'GLintptr', 'GLshort', 'GLsizei', 'GLsizeiptr', - 'GLubyte', 'GLuint', 'GLushort']: - ptrtype = gltype + '_ptr_t' - TypeMap[ptrtype] = { - 'in': 'const %s', - 'inout': '%s', - 'out': '%s', - 'return': 'const %s', - 'store': '%s' - } - RemapName[ptrtype] = '%s*' % gltype - - def __init__(self): - self.dbg_depth = 0 - - # - # Debug Logging functions - # - def Log(self, txt): - if not GetOption('cgen_debug'): return - tabs = ' ' * self.dbg_depth - print('%s%s' % (tabs, txt)) - - def LogEnter(self, txt): - if txt: self.Log(txt) - self.dbg_depth += 1 - - def LogExit(self, txt): - self.dbg_depth -= 1 - if txt: self.Log(txt) - - - def GetDefine(self, name, value): - out = '#define %s %s' % (name, value) - if len(out) > 80: - out = '#define %s \\\n %s' % (name, value) - return '%s\n' % out - - # - # Interface strings - # - def GetMacroHelper(self, node): - macro = node.GetProperty('macro') - if macro: return macro - name = node.GetName() - name = name.upper() - return "%s_INTERFACE" % name - - def GetInterfaceMacro(self, node, version = None): - name = self.GetMacroHelper(node) - if version is None: - return name - return '%s_%s' % (name, str(version).replace('.', '_')) - - def GetInterfaceString(self, node, version = None): - # If an interface name is specified, use that - name = node.GetProperty('iname') - if not name: - # Otherwise, the interface name is the object's name - # With '_Dev' replaced by '(Dev)' if it's a Dev interface. - name = node.GetName() - if name.endswith('_Dev'): - name = '%s(Dev)' % name[:-4] - if version is None: - return name - return "%s;%s" % (name, version) - - - # - # Return the array specification of the object. - # - def GetArraySpec(self, node): - assert(node.cls == 'Array') - fixed = node.GetProperty('FIXED') - if fixed: - return '[%s]' % fixed - else: - return '[]' - - # - # GetTypeName - # - # For any valid 'typed' object such as Member or Typedef - # the typenode object contains the typename - # - # For a given node return the type name by passing mode. - # - def GetTypeName(self, node, release, prefix=''): - self.LogEnter('GetTypeName of %s rel=%s' % (node, release)) - - # For Members, Params, and Typedefs get the type it refers to otherwise - # the node in question is it's own type (struct, union etc...) - if node.IsA('Member', 'Param', 'Typedef'): - typeref = node.GetType(release) - else: - typeref = node - - if typeref is None: - node.Error('No type at release %s.' % release) - raise CGenError('No type for %s' % node) - - # If the type is a (BuiltIn) Type then return it's name - # remapping as needed - if typeref.IsA('Type'): - name = CGen.RemapName.get(typeref.GetName(), None) - if name is None: name = typeref.GetName() - name = '%s%s' % (prefix, name) - - # For Interfaces, use the name + version - elif typeref.IsA('Interface'): - rel = typeref.first_release[release] - name = 'struct %s%s' % (prefix, self.GetStructName(typeref, rel, True)) - - # For structures, preceed with 'struct' or 'union' as appropriate - elif typeref.IsA('Struct'): - if typeref.GetProperty('union'): - name = 'union %s%s' % (prefix, typeref.GetName()) - else: - name = 'struct %s%s' % (prefix, typeref.GetName()) - - # If it's an enum, or typedef then return the Enum's name - elif typeref.IsA('Enum', 'Typedef'): - if not typeref.LastRelease(release): - first = node.first_release[release] - ver = '_' + node.GetVersion(first).replace('.','_') - else: - ver = '' - # The enum may have skipped having a typedef, we need prefix with 'enum'. - if typeref.GetProperty('notypedef'): - name = 'enum %s%s%s' % (prefix, typeref.GetName(), ver) - else: - name = '%s%s%s' % (prefix, typeref.GetName(), ver) - - else: - raise RuntimeError('Getting name of non-type %s.' % node) - self.LogExit('GetTypeName %s is %s' % (node, name)) - return name - - - # - # GetRootType - # - # For a given node return basic type of that object. This is - # either a 'Type', 'Callspec', or 'Array' - # - def GetRootTypeMode(self, node, release, mode): - self.LogEnter('GetRootType of %s' % node) - # If it has an array spec, then treat it as an array regardless of type - if node.GetOneOf('Array'): - rootType = 'Array' - # Or if it has a callspec, treat it as a function - elif node.GetOneOf('Callspec'): - rootType, mode = self.GetRootTypeMode(node.GetType(release), release, - 'return') - - # If it's a plain typedef, try that object's root type - elif node.IsA('Member', 'Param', 'Typedef'): - rootType, mode = self.GetRootTypeMode(node.GetType(release), - release, mode) - - # If it's an Enum, then it's normal passing rules - elif node.IsA('Enum'): - rootType = node.cls - - # If it's an Interface or Struct, we may be passing by value - elif node.IsA('Interface', 'Struct'): - if mode == 'return': - if node.GetProperty('returnByValue'): - rootType = 'TypeValue' - else: - rootType = node.cls - else: - if node.GetProperty('passByValue'): - rootType = 'TypeValue' - else: - rootType = node.cls - - # If it's an Basic Type, check if it's a special type - elif node.IsA('Type'): - if node.GetName() in CGen.TypeMap: - rootType = node.GetName() - else: - rootType = 'TypeValue' - else: - raise RuntimeError('Getting root type of non-type %s.' % node) - self.LogExit('RootType is "%s"' % rootType) - return rootType, mode - - - def GetTypeByMode(self, node, release, mode): - self.LogEnter('GetTypeByMode of %s mode=%s release=%s' % - (node, mode, release)) - name = self.GetTypeName(node, release) - ntype, mode = self.GetRootTypeMode(node, release, mode) - out = CGen.TypeMap[ntype][mode] % name - self.LogExit('GetTypeByMode %s = %s' % (node, out)) - return out - - - # Get the passing mode of the object (in, out, inout). - def GetParamMode(self, node): - self.Log('GetParamMode for %s' % node) - if node.GetProperty('in'): return 'in' - if node.GetProperty('out'): return 'out' - if node.GetProperty('inout'): return 'inout' - if node.GetProperty('constptr_in'): return 'constptr_in' - return 'return' - - # - # GetComponents - # - # Returns the signature components of an object as a tuple of - # (rtype, name, arrays, callspec) where: - # rtype - The store or return type of the object. - # name - The name of the object. - # arrays - A list of array dimensions as [] or [<fixed_num>]. - # args - None if not a function, otherwise a list of parameters. - # - def GetComponents(self, node, release, mode): - self.LogEnter('GetComponents mode %s for %s %s' % (mode, node, release)) - - # Generate passing type by modifying root type - rtype = self.GetTypeByMode(node, release, mode) - # If this is an array output, change it from type* foo[] to type** foo. - # type* foo[] means an array of pointers to type, which is confusing. - arrayspec = [self.GetArraySpec(array) for array in node.GetListOf('Array')] - if mode == 'out' and len(arrayspec) == 1 and arrayspec[0] == '[]': - rtype += '*' - del arrayspec[0] - - if node.IsA('Enum', 'Interface', 'Struct'): - rname = node.GetName() - else: - rname = node.GetType(release).GetName() - - if rname in CGen.RemapName: - rname = CGen.RemapName[rname] - if '%' in rtype: - rtype = rtype % rname - name = node.GetName() - callnode = node.GetOneOf('Callspec') - if callnode: - callspec = [] - for param in callnode.GetListOf('Param'): - if not param.IsRelease(release): - continue - mode = self.GetParamMode(param) - ptype, pname, parray, pspec = self.GetComponents(param, release, mode) - callspec.append((ptype, pname, parray, pspec)) - else: - callspec = None - - self.LogExit('GetComponents: %s, %s, %s, %s' % - (rtype, name, arrayspec, callspec)) - return (rtype, name, arrayspec, callspec) - - - def Compose(self, rtype, name, arrayspec, callspec, prefix, func_as_ptr, - include_name, unsized_as_ptr): - self.LogEnter('Compose: %s %s' % (rtype, name)) - arrayspec = ''.join(arrayspec) - - # Switch unsized array to a ptr. NOTE: Only last element can be unsized. - if unsized_as_ptr and arrayspec[-2:] == '[]': - prefix += '*' - arrayspec=arrayspec[:-2] - - if not include_name: - name = prefix + arrayspec - else: - name = prefix + name + arrayspec - if callspec is None: - out = '%s %s' % (rtype, name) - else: - params = [] - for ptype, pname, parray, pspec in callspec: - params.append(self.Compose(ptype, pname, parray, pspec, '', True, - include_name=True, - unsized_as_ptr=unsized_as_ptr)) - if func_as_ptr: - name = '(*%s)' % name - if not params: - params = ['void'] - out = '%s %s(%s)' % (rtype, name, ', '.join(params)) - self.LogExit('Exit Compose: %s' % out) - return out - - # - # GetSignature - # - # Returns the 'C' style signature of the object - # prefix - A prefix for the object's name - # func_as_ptr - Formats a function as a function pointer - # include_name - If true, include member name in the signature. - # If false, leave it out. In any case, prefix is always - # included. - # include_version - if True, include version in the member name - # - def GetSignature(self, node, release, mode, prefix='', func_as_ptr=True, - include_name=True, include_version=False): - self.LogEnter('GetSignature %s %s as func=%s' % - (node, mode, func_as_ptr)) - rtype, name, arrayspec, callspec = self.GetComponents(node, release, mode) - if include_version: - name = self.GetStructName(node, release, True) - - # If not a callspec (such as a struct) use a ptr instead of [] - unsized_as_ptr = not callspec - - out = self.Compose(rtype, name, arrayspec, callspec, prefix, - func_as_ptr, include_name, unsized_as_ptr) - - self.LogExit('Exit GetSignature: %s' % out) - return out - - # Define a Typedef. - def DefineTypedef(self, node, releases, prefix='', comment=False): - __pychecker__ = 'unusednames=comment' - build_list = node.GetUniqueReleases(releases) - - out = 'typedef %s;\n' % self.GetSignature(node, build_list[-1], 'return', - prefix, True, - include_version=False) - # Version mangle any other versions - for index, rel in enumerate(build_list[:-1]): - out += '\n' - out += 'typedef %s;\n' % self.GetSignature(node, rel, 'return', - prefix, True, - include_version=True) - self.Log('DefineTypedef: %s' % out) - return out - - # Define an Enum. - def DefineEnum(self, node, releases, prefix='', comment=False): - __pychecker__ = 'unusednames=comment,releases' - self.LogEnter('DefineEnum %s' % node) - name = '%s%s' % (prefix, node.GetName()) - notypedef = node.GetProperty('notypedef') - unnamed = node.GetProperty('unnamed') - - if unnamed: - out = 'enum {' - elif notypedef: - out = 'enum %s {' % name - else: - out = 'typedef enum {' - enumlist = [] - for child in node.GetListOf('EnumItem'): - value = child.GetProperty('VALUE') - comment_txt = GetNodeComments(child, tabs=1) - if value: - item_txt = '%s%s = %s' % (prefix, child.GetName(), value) - else: - item_txt = '%s%s' % (prefix, child.GetName()) - enumlist.append('%s %s' % (comment_txt, item_txt)) - self.LogExit('Exit DefineEnum') - - if unnamed or notypedef: - out = '%s\n%s\n};\n' % (out, ',\n'.join(enumlist)) - else: - out = '%s\n%s\n} %s;\n' % (out, ',\n'.join(enumlist), name) - return out - - def DefineMember(self, node, releases, prefix='', comment=False): - __pychecker__ = 'unusednames=prefix,comment' - release = releases[0] - self.LogEnter('DefineMember %s' % node) - if node.GetProperty('ref'): - out = '%s;' % self.GetSignature(node, release, 'ref', '', True) - else: - out = '%s;' % self.GetSignature(node, release, 'store', '', True) - self.LogExit('Exit DefineMember') - return out - - def GetStructName(self, node, release, include_version=False): - suffix = '' - if include_version: - ver_num = node.GetVersion(release) - suffix = ('_%s' % ver_num).replace('.', '_') - return node.GetName() + suffix - - def DefineStructInternals(self, node, release, - include_version=False, comment=True): - channel = node.GetProperty('FILE').release_map.GetChannel(release) - if channel == 'dev': - channel_comment = ' /* dev */' - else: - channel_comment = '' - out = '' - if node.GetProperty('union'): - out += 'union %s {%s\n' % ( - self.GetStructName(node, release, include_version), channel_comment) - else: - out += 'struct %s {%s\n' % ( - self.GetStructName(node, release, include_version), channel_comment) - - channel = node.GetProperty('FILE').release_map.GetChannel(release) - # Generate Member Functions - members = [] - for child in node.GetListOf('Member'): - if channel == 'stable' and child.NodeIsDevOnly(): - continue - member = self.Define(child, [release], tabs=1, comment=comment) - if not member: - continue - members.append(member) - out += '%s\n};\n' % '\n'.join(members) - return out - - - def DefineUnversionedInterface(self, node, rel): - out = '\n' - if node.GetProperty('force_struct_namespace'): - # Duplicate the definition to put it in struct namespace. This - # attribute is only for legacy APIs like OpenGLES2 and new APIs - # must not use this. See http://crbug.com/411799 - out += self.DefineStructInternals(node, rel, - include_version=False, comment=True) - else: - # Define an unversioned typedef for the most recent version - out += 'typedef struct %s %s;\n' % ( - self.GetStructName(node, rel, include_version=True), - self.GetStructName(node, rel, include_version=False)) - return out - - - def DefineStruct(self, node, releases, prefix='', comment=False): - __pychecker__ = 'unusednames=comment,prefix' - self.LogEnter('DefineStruct %s' % node) - out = '' - build_list = node.GetUniqueReleases(releases) - - newest_stable = None - newest_dev = None - for rel in build_list: - channel = node.GetProperty('FILE').release_map.GetChannel(rel) - if channel == 'stable': - newest_stable = rel - if channel == 'dev': - newest_dev = rel - last_rel = build_list[-1] - - # TODO(bradnelson) : Bug 157017 finish multiversion support - if node.IsA('Struct'): - if len(build_list) != 1: - node.Error('Can not support multiple versions of node.') - assert len(build_list) == 1 - # Build the most recent one versioned, with comments - out = self.DefineStructInternals(node, last_rel, - include_version=False, comment=True) - - if node.IsA('Interface'): - # Build the most recent one versioned, with comments - out = self.DefineStructInternals(node, last_rel, - include_version=True, comment=True) - if last_rel == newest_stable: - out += self.DefineUnversionedInterface(node, last_rel) - - # Build the rest without comments and with the version number appended - for rel in build_list[0:-1]: - channel = node.GetProperty('FILE').release_map.GetChannel(rel) - # Skip dev channel interface versions that are - # Not the newest version, and - # Don't have an equivalent stable version. - if channel == 'dev' and rel != newest_dev: - if not node.DevInterfaceMatchesStable(rel): - continue - out += '\n' + self.DefineStructInternals(node, rel, - include_version=True, - comment=False) - if rel == newest_stable: - out += self.DefineUnversionedInterface(node, rel) - - self.LogExit('Exit DefineStruct') - return out - - - # - # Copyright and Comment - # - # Generate a comment or copyright block - # - def Copyright(self, node, cpp_style=False): - lines = node.GetName().split('\n') - if cpp_style: - return '//' + '\n//'.join(filter(lambda f: f != '', lines)) + '\n' - return CommentLines(lines) - - - def Indent(self, data, tabs=0): - """Handles indentation and 80-column line wrapping.""" - tab = ' ' * tabs - lines = [] - for line in data.split('\n'): - # Add indentation - line = tab + line - space_break = line.rfind(' ', 0, 80) - if len(line) <= 80 or 'http://' in line: - # Ignore normal line and URLs permitted by the style guide. - lines.append(line.rstrip()) - elif not '(' in line and space_break >= 0: - # Break long typedefs on nearest space. - lines.append(line[0:space_break]) - lines.append(' ' + line[space_break + 1:]) - else: - left = line.rfind('(') + 1 - args = line[left:].split(',') - orig_args = args - orig_left = left - # Try to split on '(arg1)' or '(arg1, arg2)', not '()' - while args[0][0] == ')': - left = line.rfind('(', 0, left - 1) + 1 - if left == 0: # No more parens, take the original option - args = orig_args - left = orig_left - break - args = line[left:].split(',') - - line_max = 0 - for arg in args: - if len(arg) > line_max: line_max = len(arg) - - if left + line_max >= 80: - indent = '%s ' % tab - args = (',\n%s' % indent).join([arg.strip() for arg in args]) - lines.append('%s\n%s%s' % (line[:left], indent, args)) - else: - indent = ' ' * (left - 1) - args = (',\n%s' % indent).join(args) - lines.append('%s%s' % (line[:left], args)) - return '\n'.join(lines) - - - # Define a top level object. - def Define(self, node, releases, tabs=0, prefix='', comment=False): - # If this request does not match unique release, or if the release is not - # available (possibly deprecated) then skip. - unique = node.GetUniqueReleases(releases) - if not unique or not node.InReleases(releases): - return '' - - self.LogEnter('Define %s tab=%d prefix="%s"' % (node,tabs,prefix)) - declmap = dict({ - 'Enum': CGen.DefineEnum, - 'Function': CGen.DefineMember, - 'Interface': CGen.DefineStruct, - 'Member': CGen.DefineMember, - 'Struct': CGen.DefineStruct, - 'Typedef': CGen.DefineTypedef - }) - - out = '' - func = declmap.get(node.cls, None) - if not func: - ErrOut.Log('Failed to define %s named %s' % (node.cls, node.GetName())) - define_txt = func(self, node, releases, prefix=prefix, comment=comment) - - comment_txt = GetNodeComments(node, tabs=0) - if comment_txt and comment: - out += comment_txt - out += define_txt - - indented_out = self.Indent(out, tabs) - self.LogExit('Exit Define') - return indented_out - - -# Clean a string representing an object definition and return then string -# as a single space delimited set of tokens. -def CleanString(instr): - instr = instr.strip() - instr = instr.split() - return ' '.join(instr) - - -# Test a file, by comparing all it's objects, with their comments. -def TestFile(filenode): - cgen = CGen() - - errors = 0 - for node in filenode.GetChildren()[2:]: - instr = node.GetOneOf('Comment') - if not instr: continue - instr.Dump() - instr = CleanString(instr.GetName()) - - outstr = cgen.Define(node, releases=['M14']) - if GetOption('verbose'): - print(outstr + '\n') - outstr = CleanString(outstr) - - if instr != outstr: - ErrOut.Log('Failed match of\n>>%s<<\nto:\n>>%s<<\nFor:\n' % - (instr, outstr)) - node.Dump(1, comments=True) - errors += 1 - return errors - - -# Build and resolve the AST and compare each file individual. -def TestFiles(filenames): - if not filenames: - idldir = os.path.split(sys.argv[0])[0] - idldir = os.path.join(idldir, 'test_cgen', '*.idl') - filenames = glob.glob(idldir) - - filenames = sorted(filenames) - ast = ParseFiles(filenames) - - total_errs = 0 - for filenode in ast.GetListOf('File'): - errs = TestFile(filenode) - if errs: - ErrOut.Log('%s test failed with %d error(s).' % - (filenode.GetName(), errs)) - total_errs += errs - - if total_errs: - ErrOut.Log('Failed generator test.') - else: - InfoOut.Log('Passed generator test.') - return total_errs - -def main(args): - filenames = ParseOptions(args) - if GetOption('test'): - return TestFiles(filenames) - ast = ParseFiles(filenames) - cgen = CGen() - for f in ast.GetListOf('File'): - if f.GetProperty('ERRORS') > 0: - print('Skipping %s' % f.GetName()) - continue - for node in f.GetChildren()[2:]: - print(cgen.Define(node, ast.releases, comment=True, prefix='tst_')) - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:]))
diff --git a/generators/idl_diff.py b/generators/idl_diff.py deleted file mode 100755 index 70d61c9..0000000 --- a/generators/idl_diff.py +++ /dev/null
@@ -1,357 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from __future__ import print_function - -import glob -import os -import subprocess -import sys - -from idl_option import GetOption, Option, ParseOptions -from idl_outfile import IDLOutFile -# -# IDLDiff -# -# IDLDiff is a tool for comparing sets of IDL generated header files -# with the standard checked in headers. It does this by capturing the -# output of the standard diff tool, parsing it into separate changes, then -# ignoring changes that are know to be safe, such as adding or removing -# blank lines, etc... -# - -Option('gen', 'IDL generated files', default='hdir') -Option('src', 'Original ".h" files', default='../c') -Option('halt', 'Stop if a difference is found') -Option('diff', 'Directory holding acceptable diffs', default='diff') -Option('ok', 'Write out the diff file.') -# Change -# -# A Change object contains the previous lines, new news and change type. -# -class Change(object): - def __init__(self, mode, was, now): - self.mode = mode - self.was = was - self.now = now - - def Dump(self): - if not self.was: - print('Adding %s' % self.mode) - elif not self.now: - print('Missing %s' % self.mode) - else: - print('Modifying %s' % self.mode) - - for line in self.was: - print('src: >>%s<<' % line) - for line in self.now: - print('gen: >>%s<<' % line) - print - -# -# IsCopyright -# -# Return True if this change is only a one line change in the copyright notice -# such as non-matching years. -# -def IsCopyright(change): - if len(change.now) != 1 or len(change.was) != 1: return False - if 'Copyright (c)' not in change.now[0]: return False - if 'Copyright (c)' not in change.was[0]: return False - return True - -# -# IsBlankComment -# -# Return True if this change only removes a blank line from a comment -# -def IsBlankComment(change): - if change.now: return False - if len(change.was) != 1: return False - if change.was[0].strip() != '*': return False - return True - -# -# IsBlank -# -# Return True if this change only adds or removes blank lines -# -def IsBlank(change): - for line in change.now: - if line: return False - for line in change.was: - if line: return False - return True - - -# -# IsCppComment -# -# Return True if this change only going from C++ to C style -# -def IsToCppComment(change): - if not len(change.now) or len(change.now) != len(change.was): - return False - for index in range(len(change.now)): - was = change.was[index].strip() - if was[:2] != '//': - return False - was = was[2:].strip() - now = change.now[index].strip() - if now[:2] != '/*': - return False - now = now[2:-2].strip() - if now != was: - return False - return True - - - return True - -def IsMergeComment(change): - if len(change.was) != 1: return False - if change.was[0].strip() != '*': return False - for line in change.now: - stripped = line.strip() - if stripped != '*' and stripped[:2] != '/*' and stripped[-2:] != '*/': - return False - return True -# -# IsSpacing -# -# Return True if this change is only different in the way 'words' are spaced -# such as in an enum: -# ENUM_XXX = 1, -# ENUM_XYY_Y = 2, -# vs -# ENUM_XXX = 1, -# ENUM_XYY_Y = 2, -# -def IsSpacing(change): - if len(change.now) != len(change.was): return False - for i in range(len(change.now)): - # Also ignore right side comments - line = change.was[i] - offs = line.find('//') - if offs == -1: - offs = line.find('/*') - if offs >-1: - line = line[:offs-1] - - words1 = change.now[i].split() - words2 = line.split() - if words1 != words2: return False - return True - -# -# IsInclude -# -# Return True if change has extra includes -# -def IsInclude(change): - for line in change.was: - if line.strip().find('struct'): return False - for line in change.now: - if line and '#include' not in line: return False - return True - -# -# IsCppComment -# -# Return True if the change is only missing C++ comments -# -def IsCppComment(change): - if len(change.now): return False - for line in change.was: - line = line.strip() - if line[:2] != '//': return False - return True -# -# ValidChange -# -# Return True if none of the changes does not patch an above "bogus" change. -# -def ValidChange(change): - if IsToCppComment(change): return False - if IsCopyright(change): return False - if IsBlankComment(change): return False - if IsMergeComment(change): return False - if IsBlank(change): return False - if IsSpacing(change): return False - if IsInclude(change): return False - if IsCppComment(change): return False - return True - - -# -# Swapped -# -# Check if the combination of last + next change signals they are both -# invalid such as swap of line around an invalid block. -# -def Swapped(last, next): - if not last.now and not next.was and len(last.was) == len(next.now): - cnt = len(last.was) - for i in range(cnt): - match = True - for j in range(cnt): - if last.was[j] != next.now[(i + j) % cnt]: - match = False - break; - if match: return True - if not last.was and not next.now and len(last.now) == len(next.was): - cnt = len(last.now) - for i in range(cnt): - match = True - for j in range(cnt): - if last.now[i] != next.was[(i + j) % cnt]: - match = False - break; - if match: return True - return False - - -def FilterLinesIn(output): - was = [] - now = [] - filter = [] - for index in range(len(output)): - filter.append(False) - line = output[index] - if len(line) < 2: continue - if line[0] == '<': - if line[2:].strip() == '': continue - was.append((index, line[2:])) - elif line[0] == '>': - if line[2:].strip() == '': continue - now.append((index, line[2:])) - for windex, wline in was: - for nindex, nline in now: - if filter[nindex]: continue - if filter[windex]: continue - if wline == nline: - filter[nindex] = True - filter[windex] = True - if GetOption('verbose'): - print("Found %d, %d >>%s<<" % (windex + 1, nindex + 1, wline)) - out = [] - for index in range(len(output)): - if not filter[index]: - out.append(output[index]) - - return out -# -# GetChanges -# -# Parse the output into discrete change blocks. -# -def GetChanges(output): - # Split on lines, adding an END marker to simply add logic - lines = output.split('\n') - lines = FilterLinesIn(lines) - lines.append('END') - - changes = [] - was = [] - now = [] - mode = '' - last = None - - for line in lines: - #print("LINE=%s" % line) - if not line: continue - - elif line[0] == '<': - if line[2:].strip() == '': continue - # Ignore prototypes - if len(line) > 10: - words = line[2:].split() - if len(words) == 2 and words[1][-1] == ';': - if words[0] == 'struct' or words[0] == 'union': - continue - was.append(line[2:]) - elif line[0] == '>': - if line[2:].strip() == '': continue - if line[2:10] == '#include': continue - now.append(line[2:]) - elif line[0] == '-': - continue - else: - change = Change(line, was, now) - was = [] - now = [] - if ValidChange(change): - changes.append(change) - if line == 'END': - break - - return FilterChanges(changes) - -def FilterChanges(changes): - if len(changes) < 2: return changes - out = [] - filter = [False for change in changes] - for cur in range(len(changes)): - for cmp in range(cur+1, len(changes)): - if filter[cmp]: - continue - if Swapped(changes[cur], changes[cmp]): - filter[cur] = True - filter[cmp] = True - for cur in range(len(changes)): - if filter[cur]: continue - out.append(changes[cur]) - return out - -def Main(args): - filenames = ParseOptions(args) - if not filenames: - gendir = os.path.join(GetOption('gen'), '*.h') - filenames = sorted(glob.glob(gendir)) - srcdir = os.path.join(GetOption('src'), '*.h') - srcs = sorted(glob.glob(srcdir)) - for name in srcs: - name = os.path.split(name)[1] - name = os.path.join(GetOption('gen'), name) - if name not in filenames: - print('Missing: %s' % name) - - for filename in filenames: - gen = filename - filename = filename[len(GetOption('gen')) + 1:] - src = os.path.join(GetOption('src'), filename) - diff = os.path.join(GetOption('diff'), filename) - p = subprocess.Popen(['diff', src, gen], stdout=subprocess.PIPE) - output, errors = p.communicate() - - try: - input = open(diff, 'rt').read() - except: - input = '' - - if input != output: - changes = GetChanges(output) - else: - changes = [] - - if changes: - print("\n\nDelta between:\n src=%s\n gen=%s\n" % (src, gen)) - for change in changes: - change.Dump() - print('Done with %s\n\n' % src) - if GetOption('ok'): - open(diff, 'wt').write(output) - if GetOption('halt'): - return 1 - else: - print("\nSAME:\n src=%s\n gen=%s" % (src, gen)) - if input: - print(' ** Matched expected diff. **') - print('\n') - - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_gen_pnacl.py b/generators/idl_gen_pnacl.py deleted file mode 100755 index fabf1c7..0000000 --- a/generators/idl_gen_pnacl.py +++ /dev/null
@@ -1,284 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Generator for Pnacl Shim functions that bridges the calling conventions -between GCC and PNaCl. """ - -from datetime import datetime -import difflib -import glob -import os -import sys - -from idl_c_proto import CGen -from idl_gen_wrapper import Interface, WrapperGen -from idl_log import ErrOut, InfoOut, WarnOut -from idl_option import GetOption, Option, ParseOptions -from idl_parser import ParseFiles - -Option('pnaclshim', 'Name of the pnacl shim file.', - default='temp_pnacl_shim.c') - -Option('disable_pnacl_opt', 'Turn off optimization of pnacl shim.') - - -class PnaclGen(WrapperGen): - """PnaclGen generates shim code to bridge the Gcc ABI with PNaCl. - - This subclass of WrapperGenerator takes the IDL sources and - generates shim methods for bridging the calling conventions between GCC - and PNaCl (LLVM). Some of the PPAPI methods do not need shimming, so - this will also detect those situations and provide direct access to the - original PPAPI methods (rather than the shim methods). - """ - - def __init__(self): - WrapperGen.__init__(self, - 'Pnacl', - 'Pnacl Shim Gen', - 'pnacl', - 'Generate the PNaCl shim.') - self.cgen = CGen() - self._skip_opt = False - - ############################################################ - - def OwnHeaderFile(self): - """Return the header file that specifies the API of this wrapper. - We do not generate the header files. """ - return 'ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h' - - - def InterfaceVersionNeedsWrapping(self, iface, version): - """Return true if the interface+version has ANY methods that - need wrapping. - """ - if self._skip_opt: - return True - if iface.GetName().endswith('Trusted'): - return False - # TODO(dmichael): We have no way to wrap PPP_ interfaces without an - # interface string. If any ever need wrapping, we'll need to figure out a - # way to get the plugin-side of the Pepper proxy (within the IRT) to access - # and use the wrapper. - if iface.GetProperty("no_interface_string"): - return False - for member in iface.GetListOf('Member'): - release = member.GetRelease(version) - if self.MemberNeedsWrapping(member, release): - return True - return False - - - def MemberNeedsWrapping(self, member, release): - """Return true if a particular member function at a particular - release needs wrapping. - """ - if self._skip_opt: - return True - if not member.InReleases([release]): - return False - ret, name, array, args_spec = self.cgen.GetComponents(member, - release, - 'store') - return self.TypeNeedsWrapping(ret, []) or self.ArgsNeedWrapping(args_spec) - - - def ArgsNeedWrapping(self, args): - """Return true if any parameter in the list needs wrapping. - """ - for arg in args: - (type_str, name, array_dims, more_args) = arg - if self.TypeNeedsWrapping(type_str, array_dims): - return True - return False - - - def TypeNeedsWrapping(self, type_node, array_dims): - """Return true if a parameter type needs wrapping. - Currently, this is true for byval aggregates. - """ - is_aggregate = type_node.startswith('struct') or \ - type_node.startswith('union') - is_reference = (type_node.find('*') != -1 or array_dims != []) - return is_aggregate and not is_reference - - ############################################################ - - - def ConvertByValueReturnType(self, ret, args_spec): - if self.TypeNeedsWrapping(ret, array_dims=[]): - args_spec = [(ret, '_struct_result', [], None)] + args_spec - ret2 = 'void' - wrap_return = True - else: - ret2 = ret - wrap_return = False - return wrap_return, ret2, args_spec - - - def ConvertByValueArguments(self, args_spec): - args = [] - for type_str, name, array_dims, more_args in args_spec: - if self.TypeNeedsWrapping(type_str, array_dims): - type_str += '*' - args.append((type_str, name, array_dims, more_args)) - return args - - - def FormatArgs(self, c_operator, args_spec): - args = [] - for type_str, name, array_dims, more_args in args_spec: - if self.TypeNeedsWrapping(type_str, array_dims): - args.append(c_operator + name) - else: - args.append(name) - return ', '.join(args) - - - def GenerateWrapperForPPBMethod(self, iface, member): - result = [] - func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) - ret, name, array, cspec = self.cgen.GetComponents(member, - iface.release, - 'store') - wrap_return, ret2, cspec2 = self.ConvertByValueReturnType(ret, cspec) - cspec2 = self.ConvertByValueArguments(cspec2) - sig = self.cgen.Compose(ret2, name, array, cspec2, - prefix=func_prefix, - func_as_ptr=False, - include_name=True, - unsized_as_ptr=False) - result.append('static %s {\n' % sig) - result.append(' const struct %s *iface = %s.real_iface;\n' % - (iface.struct_name, self.GetWrapperInfoName(iface))) - - return_prefix = '' - if wrap_return: - return_prefix = '*_struct_result = ' - elif ret != 'void': - return_prefix = 'return ' - - result.append(' %siface->%s(%s);\n}\n\n' % (return_prefix, - member.GetName(), - self.FormatArgs('*', cspec))) - return result - - - def GenerateWrapperForPPPMethod(self, iface, member): - result = [] - func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) - sig = self.cgen.GetSignature(member, iface.release, 'store', - func_prefix, False) - result.append('static %s {\n' % sig) - result.append(' const struct %s *iface = %s.real_iface;\n' % - (iface.struct_name, self.GetWrapperInfoName(iface))) - ret, name, array, cspec = self.cgen.GetComponents(member, - iface.release, - 'store') - wrap_return, ret2, cspec = self.ConvertByValueReturnType(ret, cspec) - cspec2 = self.ConvertByValueArguments(cspec) - temp_fp = self.cgen.Compose(ret2, name, array, cspec2, - prefix='temp_fp', - func_as_ptr=True, - include_name=False, - unsized_as_ptr=False) - cast = self.cgen.Compose(ret2, name, array, cspec2, - prefix='', - func_as_ptr=True, - include_name=False, - unsized_as_ptr=False) - result.append(' %s =\n ((%s)iface->%s);\n' % (temp_fp, - cast, - member.GetName())) - return_prefix = '' - if wrap_return: - result.append(' %s _struct_result;\n' % ret) - elif ret != 'void': - return_prefix = 'return ' - - result.append(' %stemp_fp(%s);\n' % (return_prefix, - self.FormatArgs('&', cspec))) - if wrap_return: - result.append(' return _struct_result;\n') - result.append('}\n\n') - return result - - - def GenerateRange(self, ast, releases, options): - """Generate shim code for a range of releases. - """ - self._skip_opt = GetOption('disable_pnacl_opt') - self.SetOutputFile(GetOption('pnaclshim')) - return WrapperGen.GenerateRange(self, ast, releases, options) - -pnaclgen = PnaclGen() - -###################################################################### -# Tests. - -# Clean a string representing an object definition and return then string -# as a single space delimited set of tokens. -def CleanString(instr): - instr = instr.strip() - instr = instr.split() - return ' '.join(instr) - - -def PrintErrorDiff(old, new): - oldlines = old.split(';') - newlines = new.split(';') - d = difflib.Differ() - diff = d.compare(oldlines, newlines) - ErrOut.Log('Diff is:\n%s' % '\n'.join(diff)) - - -def GetOldTestOutput(ast): - # Scan the top-level comments in the IDL file for comparison. - old = [] - for filenode in ast.GetListOf('File'): - for node in filenode.GetChildren(): - instr = node.GetOneOf('Comment') - if not instr: continue - instr.Dump() - old.append(instr.GetName()) - return CleanString(''.join(old)) - - -def TestFiles(filenames, test_releases): - ast = ParseFiles(filenames) - iface_releases = pnaclgen.DetermineInterfaces(ast, test_releases) - new_output = CleanString(pnaclgen.GenerateWrapperForMethods( - iface_releases, comments=False)) - old_output = GetOldTestOutput(ast) - if new_output != old_output: - PrintErrorDiff(old_output, new_output) - ErrOut.Log('Failed pnacl generator test.') - return 1 - else: - InfoOut.Log('Passed pnacl generator test.') - return 0 - - -def Main(args): - filenames = ParseOptions(args) - test_releases = ['M13', 'M14', 'M15'] - if not filenames: - idldir = os.path.split(sys.argv[0])[0] - idldir = os.path.join(idldir, 'test_gen_pnacl', '*.idl') - filenames = glob.glob(idldir) - filenames = sorted(filenames) - if GetOption('test'): - # Run the tests. - return TestFiles(filenames, test_releases) - - # Otherwise, generate the output file (for potential use as golden file). - ast = ParseFiles(filenames) - return pnaclgen.GenerateRange(ast, test_releases, filenames) - - -if __name__ == '__main__': - retval = Main(sys.argv[1:]) - sys.exit(retval)
diff --git a/generators/idl_gen_wrapper.py b/generators/idl_gen_wrapper.py deleted file mode 100644 index 6b662b9..0000000 --- a/generators/idl_gen_wrapper.py +++ /dev/null
@@ -1,438 +0,0 @@ -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Base class for generating wrapper functions for PPAPI methods. -""" - -from datetime import datetime -import os -import sys - -from idl_c_proto import CGen -from idl_generator import Generator -from idl_log import ErrOut, InfoOut, WarnOut -from idl_option import GetOption -from idl_outfile import IDLOutFile - - -class PPKind(object): - @staticmethod - def ChoosePPFunc(iface, ppb_func, ppp_func): - name = iface.node.GetName() - if name.startswith("PPP"): - return ppp_func - elif name.startswith("PPB"): - return ppb_func - else: - raise Exception('Unknown PPKind for ' + name) - - -class Interface(object): - """Tracks information about a particular interface version. - - - struct_name: the struct type used by the ppapi headers to hold the - method pointers (the vtable). - - needs_wrapping: True if a method in the interface needs wrapping. - - header_file: the name of the header file that defined this interface. - """ - def __init__(self, interface_node, release, version, - struct_name, needs_wrapping, header_file): - self.node = interface_node - self.release = release - self.version = version - self.struct_name = struct_name - # We may want finer grained filtering (method level), but it is not - # yet clear how to actually do that. - self.needs_wrapping = needs_wrapping - self.header_file = header_file - - -class WrapperGen(Generator): - """WrapperGen - An abstract class that generates wrappers for PPAPI methods. - - This generates a wrapper PPB and PPP GetInterface, which directs users - to wrapper PPAPI methods. Wrapper PPAPI methods may perform arbitrary - work before invoking the real PPAPI method (supplied by the original - GetInterface functions). - - Subclasses must implement GenerateWrapperForPPBMethod (and PPP). - """ - - def __init__(self, wrapper_prefix, s1, s2, s3): - Generator.__init__(self, s1, s2, s3) - self.wrapper_prefix = wrapper_prefix - self._skip_opt = False - self.output_file = None - self.cgen = CGen() - - def SetOutputFile(self, fname): - self.output_file = fname - - - def GenerateRelease(self, ast, release, options): - return self.GenerateRange(ast, [release], options) - - - @staticmethod - def GetHeaderName(name): - """Get the corresponding ppapi .h file from each IDL filename. - """ - name = os.path.splitext(name)[0] + '.h' - name = name.replace(os.sep, '/') - return 'ppapi/c/' + name - - - def WriteCopyright(self, out): - now = datetime.now() - c = """/* Copyright %s The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* NOTE: this is auto-generated from IDL */ -""" % now.year - out.Write(c) - - def GetWrapperMetadataName(self): - return '__%sWrapperInfo' % self.wrapper_prefix - - - def GenerateHelperFunctions(self, out): - """Generate helper functions to avoid dependencies on libc. - """ - out.Write("""/* Use local strcmp to avoid dependency on libc. */ -static int mystrcmp(const char* s1, const char *s2) { - while (1) { - if (*s1 == 0) break; - if (*s2 == 0) break; - if (*s1 != *s2) break; - ++s1; - ++s2; - } - return (int)(*s1) - (int)(*s2); -}\n -""") - - - def GenerateFixedFunctions(self, out): - """Write out the set of constant functions (those that do not depend on - the current Pepper IDL). - """ - out.Write(""" - -static PPB_GetInterface __real_PPBGetInterface; -static PPP_GetInterface_Type __real_PPPGetInterface; - -void __set_real_%(wrapper_prefix)s_PPBGetInterface(PPB_GetInterface real) { - __real_PPBGetInterface = real; -} - -void __set_real_%(wrapper_prefix)s_PPPGetInterface(PPP_GetInterface_Type real) { - __real_PPPGetInterface = real; -} - -/* Map interface string -> wrapper metadata */ -static struct %(wrapper_struct)s *%(wrapper_prefix)sPPBShimIface( - const char *name) { - struct %(wrapper_struct)s **next = s_ppb_wrappers; - while (*next != NULL) { - if (mystrcmp(name, (*next)->iface_macro) == 0) return *next; - ++next; - } - return NULL; -} - -/* Map interface string -> wrapper metadata */ -static struct %(wrapper_struct)s *%(wrapper_prefix)sPPPShimIface( - const char *name) { - struct %(wrapper_struct)s **next = s_ppp_wrappers; - while (*next != NULL) { - if (mystrcmp(name, (*next)->iface_macro) == 0) return *next; - ++next; - } - return NULL; -} - -const void *__%(wrapper_prefix)s_PPBGetInterface(const char *name) { - struct %(wrapper_struct)s *wrapper = %(wrapper_prefix)sPPBShimIface(name); - if (wrapper == NULL) { - /* We did not generate a wrapper for this, so return the real interface. */ - return (*__real_PPBGetInterface)(name); - } - - /* Initialize the real_iface if it hasn't been. The wrapper depends on it. */ - if (wrapper->real_iface == NULL) { - const void *iface = (*__real_PPBGetInterface)(name); - if (NULL == iface) return NULL; - wrapper->real_iface = iface; - } - - return wrapper->wrapped_iface; -} - -const void *__%(wrapper_prefix)s_PPPGetInterface(const char *name) { - struct %(wrapper_struct)s *wrapper = %(wrapper_prefix)sPPPShimIface(name); - if (wrapper == NULL) { - /* We did not generate a wrapper for this, so return the real interface. */ - return (*__real_PPPGetInterface)(name); - } - - /* Initialize the real_iface if it hasn't been. The wrapper depends on it. */ - if (wrapper->real_iface == NULL) { - const void *iface = (*__real_PPPGetInterface)(name); - if (NULL == iface) return NULL; - wrapper->real_iface = iface; - } - - return wrapper->wrapped_iface; -} -""" % { 'wrapper_struct' : self.GetWrapperMetadataName(), - 'wrapper_prefix' : self.wrapper_prefix, - } ) - - - ############################################################ - - def OwnHeaderFile(self): - """Return the header file that specifies the API of this wrapper. - We do not generate the header files. """ - raise Exception('Child class must implement this') - - - ############################################################ - - def DetermineInterfaces(self, ast, releases): - """Get a list of interfaces along with whatever metadata we need. - """ - iface_releases = [] - for filenode in ast.GetListOf('File'): - # If this file has errors, skip it - if filenode in self.skip_list: - if GetOption('verbose'): - InfoOut.Log('WrapperGen: Skipping %s due to errors\n' % - filenode.GetName()) - continue - - file_name = self.GetHeaderName(filenode.GetName()) - ifaces = filenode.GetListOf('Interface') - for iface in ifaces: - releases_for_iface = iface.GetUniqueReleases(releases) - for release in releases_for_iface: - version = iface.GetVersion(release) - struct_name = self.cgen.GetStructName(iface, release, - include_version=True) - needs_wrap = self.InterfaceVersionNeedsWrapping(iface, version) - if not needs_wrap: - if GetOption('verbose'): - InfoOut.Log('Interface %s ver %s does not need wrapping' % - (struct_name, version)) - iface_releases.append( - Interface(iface, release, version, - struct_name, needs_wrap, file_name)) - return iface_releases - - - def GenerateIncludes(self, iface_releases, out): - """Generate the list of #include that define the original interfaces. - """ - self.WriteCopyright(out) - # First include own header. - out.Write('#include "%s"\n\n' % self.OwnHeaderFile()) - - # Get typedefs for PPB_GetInterface. - out.Write('#include "%s"\n' % self.GetHeaderName('ppb.h')) - - # Only include headers where *some* interface needs wrapping. - header_files = set() - for iface in iface_releases: - if iface.needs_wrapping: - header_files.add(iface.header_file) - for header in sorted(header_files): - out.Write('#include "%s"\n' % header) - out.Write('\n') - - - def WrapperMethodPrefix(self, iface, release): - return '%s_%s_%s_' % (self.wrapper_prefix, release, iface.GetName()) - - - def GenerateWrapperForPPBMethod(self, iface, member): - result = [] - func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) - sig = self.cgen.GetSignature(member, iface.release, 'store', - func_prefix, False) - result.append('static %s {\n' % sig) - result.append(' while(1) { /* Not implemented */ } \n') - result.append('}\n') - return result - - - def GenerateWrapperForPPPMethod(self, iface, member): - result = [] - func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) - sig = self.cgen.GetSignature(member, iface.release, 'store', - func_prefix, False) - result.append('static %s {\n' % sig) - result.append(' while(1) { /* Not implemented */ } \n') - result.append('}\n') - return result - - - def GenerateWrapperForMethods(self, iface_releases, comments=True): - """Return a string representing the code for each wrapper method - (using a string rather than writing to the file directly for testing.) - """ - result = [] - for iface in iface_releases: - if not iface.needs_wrapping: - if comments: - result.append('/* Not generating wrapper methods for %s */\n\n' % - iface.struct_name) - continue - if comments: - result.append('/* Begin wrapper methods for %s */\n\n' % - iface.struct_name) - generator = PPKind.ChoosePPFunc(iface, - self.GenerateWrapperForPPBMethod, - self.GenerateWrapperForPPPMethod) - for member in iface.node.GetListOf('Member'): - # Skip the method if it's not actually in the release. - if not member.InReleases([iface.release]): - continue - result.extend(generator(iface, member)) - if comments: - result.append('/* End wrapper methods for %s */\n\n' % - iface.struct_name) - return ''.join(result) - - - def GenerateWrapperInterfaces(self, iface_releases, out): - for iface in iface_releases: - if not iface.needs_wrapping: - out.Write('/* Not generating wrapper interface for %s */\n\n' % - iface.struct_name) - continue - - out.Write('static const struct %s %s_Wrappers_%s = {\n' % ( - iface.struct_name, self.wrapper_prefix, iface.struct_name)) - methods = [] - for member in iface.node.GetListOf('Member'): - # Skip the method if it's not actually in the release. - if not member.InReleases([iface.release]): - continue - prefix = self.WrapperMethodPrefix(iface.node, iface.release) - # Casts are necessary for the PPB_* wrappers because we must - # cast away "__attribute__((pnaclcall))". The PPP_* wrappers - # must match the default calling conventions and so don't have - # the attribute, so omitting casts for them provides a little - # extra type checking. - if iface.node.GetName().startswith('PPB_'): - cast = '(%s)' % self.cgen.GetSignature( - member, iface.release, 'return', - prefix='', - func_as_ptr=True, - include_name=False) - else: - cast = '' - methods.append(' .%s = %s&%s%s' % (member.GetName(), - cast, - prefix, - member.GetName())) - out.Write(' ' + ',\n '.join(methods) + '\n') - out.Write('};\n\n') - - - def GetWrapperInfoName(self, iface): - return '%s_WrapperInfo_%s' % (self.wrapper_prefix, iface.struct_name) - - - def GenerateWrapperInfoAndCollection(self, iface_releases, out): - for iface in iface_releases: - iface_macro = self.cgen.GetInterfaceMacro(iface.node, iface.version) - if iface.needs_wrapping: - wrap_iface = '(const void *) &%s_Wrappers_%s' % (self.wrapper_prefix, - iface.struct_name) - out.Write("""static struct %s %s = { - .iface_macro = %s, - .wrapped_iface = %s, - .real_iface = NULL -};\n\n""" % (self.GetWrapperMetadataName(), - self.GetWrapperInfoName(iface), - iface_macro, - wrap_iface)) - - # Now generate NULL terminated arrays of the above wrapper infos. - ppb_wrapper_infos = [] - ppp_wrapper_infos = [] - for iface in iface_releases: - if iface.needs_wrapping: - appender = PPKind.ChoosePPFunc(iface, - ppb_wrapper_infos.append, - ppp_wrapper_infos.append) - appender(' &%s' % self.GetWrapperInfoName(iface)) - ppb_wrapper_infos.append(' NULL') - ppp_wrapper_infos.append(' NULL') - out.Write( - 'static struct %s *s_ppb_wrappers[] = {\n%s\n};\n\n' % - (self.GetWrapperMetadataName(), ',\n'.join(ppb_wrapper_infos))) - out.Write( - 'static struct %s *s_ppp_wrappers[] = {\n%s\n};\n\n' % - (self.GetWrapperMetadataName(), ',\n'.join(ppp_wrapper_infos))) - - - def DeclareWrapperInfos(self, iface_releases, out): - """The wrapper methods usually need access to the real_iface, so we must - declare these wrapper infos ahead of time (there is a circular dependency). - """ - out.Write('/* BEGIN Declarations for all Wrapper Infos */\n\n') - for iface in iface_releases: - if iface.needs_wrapping: - out.Write('static struct %s %s;\n' % - (self.GetWrapperMetadataName(), - self.GetWrapperInfoName(iface))) - out.Write('/* END Declarations for all Wrapper Infos. */\n\n') - - - def GenerateRange(self, ast, releases, options): - """Generate shim code for a range of releases. - """ - - # Remember to set the output filename before running this. - out_filename = self.output_file - if out_filename is None: - ErrOut.Log('Did not set filename for writing out wrapper\n') - return 1 - - InfoOut.Log("Generating %s for %s" % (out_filename, self.wrapper_prefix)) - - out = IDLOutFile(out_filename) - - # Get a list of all the interfaces along with metadata. - iface_releases = self.DetermineInterfaces(ast, releases) - - # Generate the includes. - self.GenerateIncludes(iface_releases, out) - - # Write out static helper functions (mystrcmp). - self.GenerateHelperFunctions(out) - - # Declare list of WrapperInfo before actual wrapper methods, since - # they reference each other. - self.DeclareWrapperInfos(iface_releases, out) - - # Generate wrapper functions for each wrapped method in the interfaces. - result = self.GenerateWrapperForMethods(iface_releases) - out.Write(result) - - # Collect all the wrapper functions into interface structs. - self.GenerateWrapperInterfaces(iface_releases, out) - - # Generate a table of the wrapped interface structs that can be looked up. - self.GenerateWrapperInfoAndCollection(iface_releases, out) - - # Write out the IDL-invariant functions. - self.GenerateFixedFunctions(out) - - out.Close() - return 0
diff --git a/generators/idl_generator.py b/generators/idl_generator.py deleted file mode 100755 index a8f210c..0000000 --- a/generators/idl_generator.py +++ /dev/null
@@ -1,279 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from __future__ import print_function - -import sys - -from idl_log import ErrOut, InfoOut, WarnOut -from idl_option import GetOption, Option, ParseOptions -from idl_parser import ParseFiles - -GeneratorList = [] - -Option('out', 'List of output files', default='') -Option('release', 'Which release to generate.', default='') -Option('range', 'Which ranges in the form of MIN,MAX.', default='start,end') - -class Generator(object): - """Base class for generators. - - This class provides a mechanism for adding new generator objects to the IDL - driver. To use this class override the GenerateRelease and GenerateRange - members, and instantiate one copy of the class in the same module which - defines it to register the generator. After the AST is generated, call the - static Run member which will check every registered generator to see which - ones have been enabled through command-line options. To enable a generator - use the switches: - --<sname> : To enable with defaults - --<sname>_opt=<XXX,YYY=y> : To enable with generator specific options. - - NOTE: Generators still have access to global options - """ - - def __init__(self, name, sname, desc): - self.name = name - self.run_switch = Option(sname, desc) - self.opt_switch = Option(sname + '_opt', 'Options for %s.' % sname, - default='') - GeneratorList.append(self) - self.errors = 0 - self.skip_list = [] - - def Error(self, msg): - ErrOut.Log('Error %s : %s' % (self.name, msg)) - self.errors += 1 - - def GetRunOptions(self): - options = {} - option_list = self.opt_switch.Get() - if option_list: - option_list = option_list.split(',') - for opt in option_list: - offs = opt.find('=') - if offs > 0: - options[opt[:offs]] = opt[offs+1:] - else: - options[opt] = True - return options - if self.run_switch.Get(): - return options - return None - - def Generate(self, ast, options): - self.errors = 0 - - rangestr = GetOption('range') - releasestr = GetOption('release') - - print("Found releases: %s" % ast.releases) - - # Generate list of files to ignore due to errors - for filenode in ast.GetListOf('File'): - # If this file has errors, skip it - if filenode.GetProperty('ERRORS') > 0: - self.skip_list.append(filenode) - continue - - # Check for a range option which over-rides a release option - if not releasestr and rangestr: - range_list = rangestr.split(',') - if len(range_list) != 2: - self.Error('Failed to generate for %s, incorrect range: "%s"' % - (self.name, rangestr)) - else: - vmin = range_list[0] - vmax = range_list[1] - - # Generate 'start' and 'end' represent first and last found. - if vmin == 'start': - vmin = ast.releases[0] - if vmax == 'end': - vmax = ast.releases[-1] - - vmin = ast.releases.index(vmin) - vmax = ast.releases.index(vmax) + 1 - releases = ast.releases[vmin:vmax] - InfoOut.Log('Generate range %s of %s.' % (rangestr, self.name)) - ret = self.GenerateRange(ast, releases, options) - if ret < 0: - self.Error('Failed to generate range %s : %s.' %(vmin, vmax)) - else: - InfoOut.Log('%s wrote %d files.' % (self.name, ret)) - # Otherwise this should be a single release generation - else: - if releasestr == 'start': - releasestr = ast.releases[0] - if releasestr == 'end': - releasestr = ast.releases[-1] - - if releasestr > ast.releases[-1]: - InfoOut.Log('There is no unique release for %s, using last release.' % - releasestr) - releasestr = ast.releases[-1] - - if releasestr not in ast.releases: - self.Error('Release %s not in [%s].' % - (releasestr, ', '.join(ast.releases))) - - if releasestr: - InfoOut.Log('Generate release %s of %s.' % (releasestr, self.name)) - ret = self.GenerateRelease(ast, releasestr, options) - if ret < 0: - self.Error('Failed to generate release %s.' % releasestr) - else: - InfoOut.Log('%s wrote %d files.' % (self.name, ret)) - - else: - self.Error('No range or release specified for %s.' % releasestr) - return self.errors - - def GenerateRelease(self, ast, release, options): - __pychecker__ = 'unusednames=ast,release,options' - self.Error("Undefined release generator.") - return 0 - - def GenerateRange(self, ast, releases, options): - __pychecker__ = 'unusednames=ast,releases,options' - self.Error("Undefined range generator.") - return 0 - - @staticmethod - def Run(ast): - fail_count = 0 - - # Check all registered generators if they should run. - for gen in GeneratorList: - options = gen.GetRunOptions() - if options is not None: - if gen.Generate(ast, options): - fail_count += 1 - return fail_count - - -class GeneratorByFile(Generator): - """A simplified generator that generates one output file per IDL source file. - - A subclass of Generator for use of generators which have a one to one - mapping between IDL sources and output files. - - Derived classes should define GenerateFile. - """ - - def GenerateFile(self, filenode, releases, options): - """Generates an output file from the IDL source. - - Returns true if the generated file is different than the previously - generated file. - """ - __pychecker__ = 'unusednames=filenode,releases,options' - self.Error("Undefined release generator.") - return 0 - - def GenerateRelease(self, ast, release, options): - return self.GenerateRange(ast, [release], options) - - def GenerateRange(self, ast, releases, options): - # Get list of out files - outlist = GetOption('out') - if outlist: outlist = outlist.split(',') - - skipList = [] - cnt = 0 - for filenode in ast.GetListOf('File'): - # Ignore files with errors - if filenode in self.skip_list: - continue - - # Skip this file if not required - if outlist and filenode.GetName() not in outlist: - continue - - # Create the output file and increment out count if there was a delta - if self.GenerateFile(filenode, releases, options): - cnt = cnt + 1 - - for filenode in skipList: - errcnt = filenode.GetProperty('ERRORS') - ErrOut.Log('%s : Skipped because of %d errors.' % ( - filenode.GetName(), errcnt)) - - if skipList: - return -len(skipList) - - if GetOption('diff'): - return -cnt - return cnt - - -check_release = 0 -check_range = 0 - -class GeneratorReleaseTest(Generator): - def GenerateRelease(self, ast, release, options = {}): - __pychecker__ = 'unusednames=ast,release,options' - global check_release - check_map = { - 'so_long': True, - 'MyOpt': 'XYZ', - 'goodbye': True - } - check_release = 1 - for item in check_map: - check_item = check_map[item] - option_item = options.get(item, None) - if check_item != option_item: - print('Option %s is %s, expecting %s' % (item, option_item, check_item)) - check_release = 0 - - if release != 'M14': - check_release = 0 - return check_release == 1 - - def GenerateRange(self, ast, releases, options): - __pychecker__ = 'unusednames=ast,releases,options' - global check_range - check_range = 1 - return True - -def Test(): - __pychecker__ = 'unusednames=args' - global check_release - global check_range - - ParseOptions(['--testgen_opt=so_long,MyOpt=XYZ,goodbye']) - if Generator.Run('AST') != 0: - print('Generate release: Failed.\n') - return -1 - - if check_release != 1 or check_range != 0: - print('Gererate release: Failed to run.\n') - return -1 - - check_release = 0 - ParseOptions(['--testgen_opt="HELLO"', '--range=M14,M16']) - if Generator.Run('AST') != 0: - print('Generate range: Failed.\n') - return -1 - - if check_release != 0 or check_range != 1: - print('Gererate range: Failed to run.\n') - return -1 - - print('Generator test: Pass') - return 0 - - -def Main(args): - if not args: return Test() - filenames = ParseOptions(args) - ast = ParseFiles(filenames) - - return Generator.Run(ast) - - -if __name__ == '__main__': - GeneratorReleaseTest('Test Gen', 'testgen', 'Generator Class Test.') - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_lexer.py b/generators/idl_lexer.py deleted file mode 100755 index 6de38b3..0000000 --- a/generators/idl_lexer.py +++ /dev/null
@@ -1,354 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Lexer for PPAPI IDL """ - -# -# IDL Lexer -# -# The lexer is uses the PLY lex library to build a tokenizer which understands -# WebIDL tokens. -# -# WebIDL, and WebIDL regular expressions can be found at: -# http://dev.w3.org/2006/webapi/WebIDL/ -# PLY can be found at: -# http://www.dabeaz.com/ply/ - -from __future__ import print_function - -import os.path -import re -import sys - -# -# Try to load the ply module, if not, then assume it is in the third_party -# directory, relative to ppapi -# -try: - from ply import lex -except: - module_path, module_name = os.path.split(__file__) - third_party = os.path.join(module_path, '..', '..', 'third_party') - sys.path.append(third_party) - from ply import lex - -from idl_option import GetOption, Option, ParseOptions - - -Option('output', 'Generate output.') - -# -# IDL Lexer -# -class IDLLexer(object): - # 'tokens' is a value required by lex which specifies the complete list - # of valid token types. - tokens = [ - # Symbol and keywords types - 'COMMENT', - 'DESCRIBE', - 'ENUM', - 'LABEL', - 'SYMBOL', - 'INLINE', - 'INTERFACE', - 'STRUCT', - 'TYPEDEF', - 'OR', - - # Extra WebIDL keywords - 'CALLBACK', - 'DICTIONARY', - 'OPTIONAL', - 'STATIC', - - # Invented for apps use - 'NAMESPACE', - - # Data types - 'FLOAT', - 'OCT', - 'INT', - 'HEX', - 'STRING', - - # Operators - 'LSHIFT', - 'RSHIFT' - ] - - # 'keywords' is a map of string to token type. All SYMBOL tokens are - # matched against keywords, to determine if the token is actually a keyword. - keywords = { - 'describe' : 'DESCRIBE', - 'enum' : 'ENUM', - 'label' : 'LABEL', - 'interface' : 'INTERFACE', - 'readonly' : 'READONLY', - 'struct' : 'STRUCT', - 'typedef' : 'TYPEDEF', - - 'callback' : 'CALLBACK', - 'dictionary' : 'DICTIONARY', - 'optional' : 'OPTIONAL', - 'static' : 'STATIC', - 'namespace' : 'NAMESPACE', - - 'or' : 'OR', - } - - # 'literals' is a value expected by lex which specifies a list of valid - # literal tokens, meaning the token type and token value are identical. - literals = '"*.(){}[],;:=+-/~|&^?' - - # Token definitions - # - # Lex assumes any value or function in the form of 't_<TYPE>' represents a - # regular expression where a match will emit a token of type <TYPE>. In the - # case of a function, the function is called when a match is made. These - # definitions come from WebIDL. - - # 't_ignore' is a special match of items to ignore - t_ignore = ' \t' - - # Constant values - t_FLOAT = r'-?(\d+\.\d*|\d*\.\d+)([Ee][+-]?\d+)?|-?\d+[Ee][+-]?\d+' - t_INT = r'-?[0-9]+[uU]?' - t_OCT = r'-?0[0-7]+' - t_HEX = r'-?0[Xx][0-9A-Fa-f]+' - t_LSHIFT = r'<<' - t_RSHIFT = r'>>' - - # A line ending '\n', we use this to increment the line number - def t_LINE_END(self, t): - r'\n+' - self.AddLines(len(t.value)) - - # We do not process escapes in the IDL strings. Strings are exclusively - # used for attributes, and not used as typical 'C' constants. - def t_STRING(self, t): - r'"[^"]*"' - t.value = t.value[1:-1] - self.AddLines(t.value.count('\n')) - return t - - # A C or C++ style comment: /* xxx */ or // - def t_COMMENT(self, t): - r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)' - self.AddLines(t.value.count('\n')) - return t - - # Return a "preprocessor" inline block - def t_INLINE(self, t): - r'\#inline (.|\n)*?\#endinl.*' - self.AddLines(t.value.count('\n')) - return t - - # A symbol or keyword. - def t_KEYWORD_SYMBOL(self, t): - r'_?[A-Za-z][A-Za-z_0-9]*' - - # All non-keywords are assumed to be symbols - t.type = self.keywords.get(t.value, 'SYMBOL') - - # We strip leading underscores so that you can specify symbols with the same - # value as a keywords (E.g. a dictionary named 'interface'). - if t.value[0] == '_': - t.value = t.value[1:] - return t - - def t_ANY_error(self, t): - msg = "Unrecognized input" - line = self.lexobj.lineno - - # If that line has not been accounted for, then we must have hit - # EoF, so compute the beginning of the line that caused the problem. - if line >= len(self.index): - # Find the offset in the line of the first word causing the issue - word = t.value.split()[0] - offs = self.lines[line - 1].find(word) - # Add the computed line's starting position - self.index.append(self.lexobj.lexpos - offs) - msg = "Unexpected EoF reached after" - - pos = self.lexobj.lexpos - self.index[line] - file = self.lexobj.filename - out = self.ErrorMessage(file, line, pos, msg) - sys.stderr.write(out + '\n') - self.lex_errors += 1 - - - def AddLines(self, count): - # Set the lexer position for the beginning of the next line. In the case - # of multiple lines, tokens can not exist on any of the lines except the - # last one, so the recorded value for previous lines are unused. We still - # fill the array however, to make sure the line count is correct. - self.lexobj.lineno += count - for i in range(count): - self.index.append(self.lexobj.lexpos) - - def FileLineMsg(self, file, line, msg): - if file: return "%s(%d) : %s" % (file, line + 1, msg) - return "<BuiltIn> : %s" % msg - - def SourceLine(self, file, line, pos): - caret = '\t^'.expandtabs(pos) - # We decrement the line number since the array is 0 based while the - # line numbers are 1 based. - return "%s\n%s" % (self.lines[line - 1], caret) - - def ErrorMessage(self, file, line, pos, msg): - return "\n%s\n%s" % ( - self.FileLineMsg(file, line, msg), - self.SourceLine(file, line, pos)) - - def SetData(self, filename, data): - # Start with line 1, not zero - self.lexobj.lineno = 1 - self.lexobj.filename = filename - self.lines = data.split('\n') - self.index = [0] - self.lexobj.input(data) - self.lex_errors = 0 - - def __init__(self): - self.lexobj = lex.lex(object=self, lextab=None, optimize=0) - - - -# -# FilesToTokens -# -# From a set of source file names, generate a list of tokens. -# -def FilesToTokens(filenames, verbose=False): - lexer = IDLLexer() - outlist = [] - for filename in filenames: - data = open(filename).read() - lexer.SetData(filename, data) - if verbose: sys.stdout.write(' Loaded %s...\n' % filename) - while 1: - t = lexer.lexobj.token() - if t is None: break - outlist.append(t) - return outlist - - -def TokensFromText(text): - lexer = IDLLexer() - lexer.SetData('unknown', text) - outlist = [] - while 1: - t = lexer.lexobj.token() - if t is None: break - outlist.append(t.value) - return outlist - -# -# TextToTokens -# -# From a block of text, generate a list of tokens -# -def TextToTokens(source): - lexer = IDLLexer() - outlist = [] - lexer.SetData('AUTO', source) - while 1: - t = lexer.lexobj.token() - if t is None: break - outlist.append(t.value) - return outlist - - -# -# TestSame -# -# From a set of token values, generate a new source text by joining with a -# single space. The new source is then tokenized and compared against the -# old set. -# -def TestSame(values1): - # Recreate the source from the tokens. We use newline instead of whitespace - # since the '//' and #inline regex are line sensitive. - text = '\n'.join(values1) - values2 = TextToTokens(text) - - count1 = len(values1) - count2 = len(values2) - if count1 != count2: - print("Size mismatch original %d vs %d\n" % (count1, count2)) - if count1 > count2: count1 = count2 - - for i in range(count1): - if values1[i] != values2[i]: - print("%d >>%s<< >>%s<<" % (i, values1[i], values2[i])) - - if GetOption('output'): - sys.stdout.write('Generating original.txt and tokenized.txt\n') - open('original.txt', 'w').write(values1) - open('tokenized.txt', 'w').write(values2) - - if values1 == values2: - sys.stdout.write('Same: Pass\n') - return 0 - - print("****************\n%s\n%s***************\n" % (values1, values2)) - sys.stdout.write('Same: Failed\n') - return -1 - - -# -# TestExpect -# -# From a set of tokens pairs, verify the type field of the second matches -# the value of the first, so that: -# INT 123 FLOAT 1.1 -# will generate a passing test, where the first token is the SYMBOL INT, -# and the second token is the INT 123, third token is the SYMBOL FLOAT and -# the fourth is the FLOAT 1.1, etc... -def TestExpect(tokens): - count = len(tokens) - index = 0 - errors = 0 - while index < count: - type = tokens[index].value - token = tokens[index + 1] - index += 2 - - if type != token.type: - sys.stderr.write('Mismatch: Expected %s, but got %s = %s.\n' % - (type, token.type, token.value)) - errors += 1 - - if not errors: - sys.stdout.write('Expect: Pass\n') - return 0 - - sys.stdout.write('Expect: Failed\n') - return -1 - - -def Main(args): - filenames = ParseOptions(args) - - try: - tokens = FilesToTokens(filenames, GetOption('verbose')) - values = [tok.value for tok in tokens] - if GetOption('output'): sys.stdout.write(' <> '.join(values) + '\n') - if GetOption('test'): - if TestSame(values): - return -1 - if TestExpect(tokens): - return -1 - return 0 - - except lex.LexError as le: - sys.stderr.write('%s\n' % str(le)) - return -1 - - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_lint.py b/generators/idl_lint.py deleted file mode 100644 index df163c9..0000000 --- a/generators/idl_lint.py +++ /dev/null
@@ -1,122 +0,0 @@ -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Lint for IDL """ - -import os -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_visitor import IDLVisitor - - -Option('wcomment', 'Disable warning for missing comment.') -Option('wenum', 'Disable warning for missing enum value.') -Option('winline', 'Disable warning for inline blocks.') -Option('wname', 'Disable warning for inconsistent interface name.') -Option('wnone', 'Disable all warnings.') -Option('wparam', 'Disable warning for missing [in|out|inout] on param.') -Option('wpass', 'Disable warning for mixed passByValue and returnByValue.') - -# -# IDLLinter -# -# Once the AST is build, we need to resolve the namespace and version -# information. -# -class IDLLinter(IDLVisitor): - def VisitFilter(self, node, data): - __pychecker__ = 'unusednames=node,data' - return not node.IsA('Comment', 'Copyright') - - def Arrive(self, node, errors): - __pychecker__ = 'unusednames=node,errors' - warnings = 0 - if node.IsA('Interface', 'Member', 'Struct', 'Enum', 'EnumItem', 'Typedef'): - comments = node.GetListOf('Comment') - if not comments and not node.GetProperty('wcomment'): - node.Warning('Expecting a comment.') - warnings += 1 - - if node.IsA('File'): - labels = node.GetListOf('Label') - interfaces = node.GetListOf('Interface') - if interfaces and not labels: - node.Warning('Expecting a label in a file containing interfaces.') - - if node.IsA('Struct', 'Typedef') and not node.GetProperty('wpass'): - if node.GetProperty('passByValue'): - pbv = 'is' - else: - pbv = 'is not' - if node.GetProperty('returnByValue'): - ret = 'is' - else: - ret = 'is not' - if pbv != ret: - node.Warning('%s passByValue but %s returnByValue.' % (pbv, ret)) - warnings += 1 - - if node.IsA('EnumItem'): - if not node.GetProperty('VALUE') and not node.GetProperty('wenum'): - node.Warning('Expecting value for enumeration.') - warnings += 1 - - if node.IsA('Interface'): - macro = node.GetProperty('macro') - if macro and not node.GetProperty('wname'): - node.Warning('Interface name inconsistent: %s' % macro) - warnings += 1 - - if node.IsA('Inline') and not node.GetProperty('winline'): - inline_type = node.GetProperty('NAME') - node.parent.Warning('Requires an inline %s block.' % inline_type) - warnings += 1 - - if node.IsA('Callspec') and not node.GetProperty('wparam'): - out = False - for arg in node.GetListOf('Param'): - if arg.GetProperty('out'): - out = True - if arg.GetProperty('in') and out: - arg.Warning('[in] parameter after [out] parameter') - warnings += 1 - - if node.IsA('Param') and not node.GetProperty('wparam'): - found = False; - for form in ['in', 'inout', 'out']: - if node.GetProperty(form): found = True - if not found: - node.Warning('Missing argument type: [in|out|inout]') - warnings += 1 - - return warnings - - def Depart(self, node, warnings, childdata): - __pychecker__ = 'unusednames=node' - for child in childdata: - warnings += child - return warnings - -def Lint(ast): - options = ['wcomment', 'wenum', 'winline', 'wparam', 'wpass', 'wname'] - wnone = GetOption('wnone') - for opt in options: - if wnone or GetOption(opt): ast.SetProperty(opt, True) - - skipList = [] - for filenode in ast.GetListOf('File'): - name = filenode.GetProperty('NAME') - if filenode.GetProperty('ERRORS') > 0: - ErrOut.Log('%s : Skipped due to errors.' % name) - skipList.append(filenode) - continue - warnings = IDLLinter().Visit(filenode, 0) - if warnings: - WarnOut.Log('%s warning(s) for %s\n' % (warnings, name)) - return skipList
diff --git a/generators/idl_log.py b/generators/idl_log.py deleted file mode 100644 index 7a65683..0000000 --- a/generators/idl_log.py +++ /dev/null
@@ -1,54 +0,0 @@ -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Error and information logging for IDL """ - -import sys - - -class IDLLog(object): - """Captures and routes logging output. - - Caputres logging output and/or sends out via a file handle, typically - stdout or stderr. - """ - def __init__(self, name, out): - if name: - self._name = '%s : ' % name - else: - self._name = '' - - self._out = out - self._capture = False - self._console = True - self._log = [] - - def Log(self, msg): - if self._console: - line = "%s\n" % (msg) - self._out.write(line) - if self._capture: - self._log.append(msg) - - def LogLine(self, filename, lineno, pos, msg): - if self._console: - line = "%s(%d) : %s%s\n" % (filename, lineno, self._name, msg) - self._out.write(line) - if self._capture: - self._log.append(msg) - - def SetConsole(self, enable): - self._console = enable - - def SetCapture(self, enable): - self._capture = enable - - def DrainLog(self): - out = self._log - self._log = [] - return out - -ErrOut = IDLLog('Error', sys.stderr) -WarnOut = IDLLog('Warning', sys.stdout) -InfoOut = IDLLog('', sys.stdout)
diff --git a/generators/idl_namespace.py b/generators/idl_namespace.py deleted file mode 100755 index 5eae431..0000000 --- a/generators/idl_namespace.py +++ /dev/null
@@ -1,249 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -IDLNamespace for PPAPI - -This file defines the behavior of the AST namespace which allows for resolving -a symbol as one or more AST nodes given a release or range of releases. -""" - -from __future__ import print_function - -import sys - -from idl_option import GetOption, Option, ParseOptions -from idl_log import ErrOut, InfoOut, WarnOut -from idl_release import IDLRelease, IDLReleaseList - -Option('label', 'Use the specifed label blocks.', default='Chrome') -Option('namespace_debug', 'Use the specified release') - - -# -# IDLNamespace -# -# IDLNamespace provides a mapping between a symbol name and an IDLReleaseList -# which contains IDLRelease objects. It provides an interface for fetching -# one or more IDLNodes based on a release or range of releases. -# -class IDLNamespace(object): - def __init__(self, parent): - self._name_to_releases = {} - self._parent = parent - - def Dump(self): - for name in self._name_to_releases: - InfoOut.Log('NAME=%s' % name) - for cver in self._name_to_releases[name].GetReleases(): - InfoOut.Log(' %s' % cver) - InfoOut.Log('') - - def FindRelease(self, name, release): - verlist = self._name_to_releases.get(name, None) - if verlist == None: - if self._parent: - return self._parent.FindRelease(name, release) - else: - return None - return verlist.FindRelease(release) - - def FindRange(self, name, rmin, rmax): - verlist = self._name_to_releases.get(name, None) - if verlist == None: - if self._parent: - return self._parent.FindRange(name, rmin, rmax) - else: - return [] - return verlist.FindRange(rmin, rmax) - - def FindList(self, name): - verlist = self._name_to_releases.get(name, None) - if verlist == None: - if self._parent: - return self._parent.FindList(name) - return verlist - - def AddNode(self, node): - name = node.GetName() - verlist = self._name_to_releases.setdefault(name,IDLReleaseList()) - if GetOption('namespace_debug'): - print("Adding to namespace: %s" % node) - return verlist.AddNode(node) - - -# -# Testing Code -# - -# -# MockNode -# -# Mocks the IDLNode to support error, warning handling, and string functions. -# -class MockNode(IDLRelease): - def __init__(self, name, rmin, rmax): - self.name = name - self.rmin = rmin - self.rmax = rmax - self.errors = [] - self.warns = [] - self.properties = { - 'NAME': name, - 'release': rmin, - 'deprecate' : rmax - } - - def __str__(self): - return '%s (%s : %s)' % (self.name, self.rmin, self.rmax) - - def GetName(self): - return self.name - - def Error(self, msg): - if GetOption('release_debug'): - print('Error: %s' % msg) - self.errors.append(msg) - - def Warn(self, msg): - if GetOption('release_debug'): - print('Warn: %s' % msg) - self.warns.append(msg) - - def GetProperty(self, name): - return self.properties.get(name, None) - -errors = 0 -# -# DumpFailure -# -# Dumps all the information relevant to an add failure. -def DumpFailure(namespace, node, msg): - global errors - print('\n******************************') - print('Failure: %s %s' % (node, msg)) - for warn in node.warns: - print(' WARN: %s' % warn) - for err in node.errors: - print(' ERROR: %s' % err) - print('\n') - namespace.Dump() - print('******************************\n') - errors += 1 - -# Add expecting no errors or warnings -def AddOkay(namespace, node): - okay = namespace.AddNode(node) - if not okay or node.errors or node.warns: - DumpFailure(namespace, node, 'Expected success') - -# Add expecting a specific warning -def AddWarn(namespace, node, msg): - okay = namespace.AddNode(node) - if not okay or node.errors or not node.warns: - DumpFailure(namespace, node, 'Expected warnings') - if msg not in node.warns: - DumpFailure(namespace, node, 'Expected warning: %s' % msg) - -# Add expecting a specific error any any number of warnings -def AddError(namespace, node, msg): - okay = namespace.AddNode(node) - if okay or not node.errors: - DumpFailure(namespace, node, 'Expected errors') - if msg not in node.errors: - DumpFailure(namespace, node, 'Expected error: %s' % msg) - print(">>%s<<\n>>%s<<\n" % (node.errors[0], msg)) - -# Verify that a FindRelease call on the namespace returns the expected node. -def VerifyFindOne(namespace, name, release, node): - global errors - if (namespace.FindRelease(name, release) != node): - print("Failed to find %s as release %f of %s" % (node, release, name)) - namespace.Dump() - print("\n") - errors += 1 - -# Verify that a FindRage call on the namespace returns a set of expected nodes. -def VerifyFindAll(namespace, name, rmin, rmax, nodes): - global errors - out = namespace.FindRange(name, rmin, rmax) - if (out != nodes): - print("Found [%s] instead of[%s] for releases %f to %f of %s" % (' '.join([ - str(x) for x in out - ]), ' '.join([str(x) for x in nodes]), rmin, rmax, name)) - namespace.Dump() - print("\n") - errors += 1 - -def Main(args): - global errors - ParseOptions(args) - - InfoOut.SetConsole(True) - - namespace = IDLNamespace(None) - - FooXX = MockNode('foo', None, None) - Foo1X = MockNode('foo', 1.0, None) - Foo2X = MockNode('foo', 2.0, None) - Foo3X = MockNode('foo', 3.0, None) - - # Verify we succeed with undeprecated adds - AddOkay(namespace, FooXX) - AddOkay(namespace, Foo1X) - AddOkay(namespace, Foo3X) - # Verify we fail to add a node between undeprecated releases - AddError(namespace, Foo2X, - 'Overlap in releases: 3.0 vs 2.0 when adding foo (2.0 : None)') - - BarXX = MockNode('bar', None, None) - Bar12 = MockNode('bar', 1.0, 2.0) - Bar23 = MockNode('bar', 2.0, 3.0) - Bar34 = MockNode('bar', 3.0, 4.0) - - - # Verify we succeed with fully qualified releases - namespace = IDLNamespace(namespace) - AddOkay(namespace, BarXX) - AddOkay(namespace, Bar12) - # Verify we warn when detecting a gap - AddWarn(namespace, Bar34, 'Gap in release numbers.') - # Verify we fail when inserting into this gap - # (NOTE: while this could be legal, it is sloppy so we disallow it) - AddError(namespace, Bar23, 'Declarations out of order.') - - # Verify local namespace - VerifyFindOne(namespace, 'bar', 0.0, BarXX) - VerifyFindAll(namespace, 'bar', 0.5, 1.5, [BarXX, Bar12]) - - # Verify the correct release of the object is found recursively - VerifyFindOne(namespace, 'foo', 0.0, FooXX) - VerifyFindOne(namespace, 'foo', 0.5, FooXX) - VerifyFindOne(namespace, 'foo', 1.0, Foo1X) - VerifyFindOne(namespace, 'foo', 1.5, Foo1X) - VerifyFindOne(namespace, 'foo', 3.0, Foo3X) - VerifyFindOne(namespace, 'foo', 100.0, Foo3X) - - # Verify the correct range of objects is found - VerifyFindAll(namespace, 'foo', 0.0, 1.0, [FooXX]) - VerifyFindAll(namespace, 'foo', 0.5, 1.0, [FooXX]) - VerifyFindAll(namespace, 'foo', 1.0, 1.1, [Foo1X]) - VerifyFindAll(namespace, 'foo', 0.5, 1.5, [FooXX, Foo1X]) - VerifyFindAll(namespace, 'foo', 0.0, 3.0, [FooXX, Foo1X]) - VerifyFindAll(namespace, 'foo', 3.0, 100.0, [Foo3X]) - - FooBar = MockNode('foobar', 1.0, 2.0) - namespace = IDLNamespace(namespace) - AddOkay(namespace, FooBar) - - if errors: - print('Test failed with %d errors.' % errors) - else: - print('Passed.') - return errors - - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_node.py b/generators/idl_node.py deleted file mode 100755 index 10a491a..0000000 --- a/generators/idl_node.py +++ /dev/null
@@ -1,446 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Nodes for PPAPI IDL AST""" - -# -# IDL Node -# -# IDL Node defines the IDLAttribute and IDLNode objects which are constructed -# by the parser as it processes the various 'productions'. The IDLAttribute -# objects are assigned to the IDLNode's property dictionary instead of being -# applied as children of The IDLNodes, so they do not exist in the final tree. -# The AST of IDLNodes is the output from the parsing state and will be used -# as the source data by the various generators. -# - -import sys - -from idl_log import ErrOut, InfoOut, WarnOut -from idl_propertynode import IDLPropertyNode -from idl_release import IDLRelease, IDLReleaseMap - - -# IDLAttribute -# -# A temporary object used by the parsing process to hold an Extended Attribute -# which will be passed as a child to a standard IDLNode. -# -class IDLAttribute(object): - def __init__(self, name, value): - self.cls = 'ExtAttribute' - self.name = name - self.value = value - - def __str__(self): - return '%s=%s' % (self.name, self.value) - -# -# IDLNode -# -# This class implements the AST tree, providing the associations between -# parents and children. It also contains a namespace and propertynode to -# allow for look-ups. IDLNode is derived from IDLRelease, so it is -# version aware. -# -class IDLNode(IDLRelease): - - # Set of object IDLNode types which have a name and belong in the namespace. - NamedSet = set(['Enum', 'EnumItem', 'File', 'Function', 'Interface', - 'Member', 'Param', 'Struct', 'Type', 'Typedef']) - - def __init__(self, cls, filename, lineno, pos, children=None): - # Initialize with no starting or ending Version - IDLRelease.__init__(self, None, None) - - self.cls = cls - self.lineno = lineno - self.pos = pos - self._filename = filename - self._deps = {} - self.errors = 0 - self.namespace = None - self.typelist = None - self.parent = None - self._property_node = IDLPropertyNode() - self._unique_releases = None - - # A list of unique releases for this node - self.releases = None - - # A map from any release, to the first unique release - self.first_release = None - - # self._children is a list of children ordered as defined - self._children = [] - # Process the passed in list of children, placing ExtAttributes into the - # property dictionary, and nodes into the local child list in order. In - # addition, add nodes to the namespace if the class is in the NamedSet. - if children: - for child in children: - if child.cls == 'ExtAttribute': - self.SetProperty(child.name, child.value) - else: - self.AddChild(child) - - def __str__(self): - name = self.GetName() - if name is None: - name = '' - return '%s(%s)' % (self.cls, name) - - def Location(self): - """Return a file and line number for where this node was defined.""" - return '%s(%d)' % (self._filename, self.lineno) - - def Error(self, msg): - """Log an error for this object.""" - self.errors += 1 - ErrOut.LogLine(self._filename, self.lineno, 0, ' %s %s' % - (str(self), msg)) - filenode = self.GetProperty('FILE') - if filenode: - errcnt = filenode.GetProperty('ERRORS') - if not errcnt: - errcnt = 0 - filenode.SetProperty('ERRORS', errcnt + 1) - - def Warning(self, msg): - """Log a warning for this object.""" - WarnOut.LogLine(self._filename, self.lineno, 0, ' %s %s' % - (str(self), msg)) - - def GetName(self): - return self.GetProperty('NAME') - - def Dump(self, depth=0, comments=False, out=sys.stdout): - """Dump this object and its children""" - if self.cls in ['Comment', 'Copyright']: - is_comment = True - else: - is_comment = False - - # Skip this node if it's a comment, and we are not printing comments - if not comments and is_comment: - return - - tab = ''.rjust(depth * 2) - if is_comment: - out.write('%sComment\n' % tab) - for line in self.GetName().split('\n'): - out.write('%s "%s"\n' % (tab, line)) - else: - ver = IDLRelease.__str__(self) - if self.releases: - release_list = ': ' + ' '.join(self.releases) - else: - release_list = ': undefined' - out.write('%s%s%s%s\n' % (tab, self, ver, release_list)) - if self.typelist: - out.write('%s Typelist: %s\n' % (tab, self.typelist.GetReleases()[0])) - properties = self._property_node.GetPropertyList() - if properties: - out.write('%s Properties\n' % tab) - for p in properties: - if is_comment and p == 'NAME': - # Skip printing the name for comments, since we printed above already - continue - out.write('%s %s : %s\n' % (tab, p, self.GetProperty(p))) - for child in self._children: - child.Dump(depth+1, comments=comments, out=out) - - def IsA(self, *typelist): - """Check if node is of a given type.""" - return self.cls in typelist - - def GetListOf(self, *keys): - """Get a list of objects for the given key(s).""" - out = [] - for child in self._children: - if child.cls in keys: - out.append(child) - return out - - def GetOneOf(self, *keys): - """Get an object for the given key(s).""" - out = self.GetListOf(*keys) - if out: - return out[0] - return None - - def SetParent(self, parent): - self._property_node.AddParent(parent) - self.parent = parent - - def AddChild(self, node): - node.SetParent(self) - self._children.append(node) - - # Get a list of all children - def GetChildren(self): - return self._children - - def GetType(self, release): - if not self.typelist: - return None - return self.typelist.FindRelease(release) - - def GetDeps(self, release, visited=None): - visited = visited or set() - - # If this release is not valid for this object, then done. - if not self.IsRelease(release) or self.IsA('Comment', 'Copyright'): - return set([]) - - # If we have cached the info for this release, return the cached value - deps = self._deps.get(release, None) - if deps is not None: - return deps - - # If we are already visited, then return - if self in visited: - return set([self]) - - # Otherwise, build the dependency list - visited |= set([self]) - deps = set([self]) - - # Get child deps - for child in self.GetChildren(): - deps |= child.GetDeps(release, visited) - visited |= set(deps) - - # Get type deps - typeref = self.GetType(release) - if typeref: - deps |= typeref.GetDeps(release, visited) - - self._deps[release] = deps - return deps - - def GetVersion(self, release): - filenode = self.GetProperty('FILE') - if not filenode: - return None - return filenode.release_map.GetVersion(release) - - def GetUniqueReleases(self, releases): - """Return the unique set of first releases corresponding to input - - Since we are returning the corresponding 'first' version for a - release, we may return a release version prior to the one in the list.""" - my_min, my_max = self.GetMinMax(releases) - if my_min > releases[-1] or my_max < releases[0]: - return [] - - out = set() - for rel in releases: - remapped = self.first_release[rel] - if not remapped: - continue - out |= set([remapped]) - - # Cache the most recent set of unique_releases - self._unique_releases = sorted(out) - return self._unique_releases - - def LastRelease(self, release): - # Get the most recent release from the most recently generated set of - # cached unique releases. - if self._unique_releases and self._unique_releases[-1] > release: - return False - return True - - def GetRelease(self, version): - filenode = self.GetProperty('FILE') - if not filenode: - return None - return filenode.release_map.GetRelease(version) - - def _GetReleaseList(self, releases, visited=None): - visited = visited or set() - if not self.releases: - # If we are unversionable, then return first available release - if self.IsA('Comment', 'Copyright', 'Label'): - self.releases = [] - return self.releases - - # Generate the first and if deprecated within this subset, the - # last release for this node - my_min, my_max = self.GetMinMax(releases) - - if my_max != releases[-1]: - my_releases = set([my_min, my_max]) - else: - my_releases = set([my_min]) - - r = self.GetRelease(self.GetProperty('version')) - if r is not None and r not in my_releases: - my_releases.add(r) - - # Break cycle if we reference ourselves - if self in visited: - return [my_min] - - visited |= set([self]) - - # Files inherit all their releases from items in the file - if self.IsA('AST', 'File'): - my_releases = set() - - # Visit all children - child_releases = set() - - # Exclude sibling results from parent visited set - cur_visits = visited - - for child in self._children: - child_releases |= set(child._GetReleaseList(releases, cur_visits)) - visited |= set(child_releases) - - # Visit my type - type_releases = set() - if self.typelist: - type_list = self.typelist.GetReleases() - for typenode in type_list: - type_releases |= set(typenode._GetReleaseList(releases, cur_visits)) - - type_release_list = sorted(type_releases) - if my_min < type_release_list[0]: - type_node = type_list[0] - self.Error('requires %s in %s which is undefined at %s.' % ( - type_node, type_node._filename, my_min)) - - for rel in child_releases | type_releases: - if rel >= my_min and rel <= my_max: - my_releases.add(rel) - - self.releases = sorted(my_releases) - return self.releases - - def BuildReleaseMap(self, releases): - unique_list = self._GetReleaseList(releases) - _, my_max = self.GetMinMax(releases) - - self.first_release = {} - last_rel = None - for rel in releases: - if rel in unique_list: - last_rel = rel - self.first_release[rel] = last_rel - if rel == my_max: - last_rel = None - - def SetProperty(self, name, val): - self._property_node.SetProperty(name, val) - - def GetProperty(self, name): - return self._property_node.GetProperty(name) - - def GetPropertyLocal(self, name): - return self._property_node.GetPropertyLocal(name) - - def NodeIsDevOnly(self): - """Returns true iff a node is only in dev channel.""" - return self.GetProperty('dev_version') and not self.GetProperty('version') - - def DevInterfaceMatchesStable(self, release): - """Returns true if an interface has an equivalent stable version.""" - assert(self.IsA('Interface')) - for child in self.GetListOf('Member'): - unique = child.GetUniqueReleases([release]) - if not unique or not child.InReleases([release]): - continue - if child.NodeIsDevOnly(): - return False - return True - - -# -# IDLFile -# -# A specialized version of IDLNode which tracks errors and warnings. -# -class IDLFile(IDLNode): - def __init__(self, name, children, errors=0): - attrs = [IDLAttribute('NAME', name), - IDLAttribute('ERRORS', errors)] - if not children: - children = [] - IDLNode.__init__(self, 'File', name, 1, 0, attrs + children) - # TODO(teravest): Why do we set release map like this here? This looks - # suspicious... - self.release_map = IDLReleaseMap([('M13', 1.0, 'stable')]) - - -# -# Tests -# -def StringTest(): - errors = 0 - name_str = 'MyName' - text_str = 'MyNode(%s)' % name_str - name_node = IDLAttribute('NAME', name_str) - node = IDLNode('MyNode', 'no file', 1, 0, [name_node]) - if node.GetName() != name_str: - ErrOut.Log('GetName returned >%s< not >%s<' % (node.GetName(), name_str)) - errors += 1 - if node.GetProperty('NAME') != name_str: - ErrOut.Log('Failed to get name property.') - errors += 1 - if str(node) != text_str: - ErrOut.Log('str() returned >%s< not >%s<' % (str(node), text_str)) - errors += 1 - if not errors: - InfoOut.Log('Passed StringTest') - return errors - - -def ChildTest(): - errors = 0 - child = IDLNode('child', 'no file', 1, 0) - parent = IDLNode('parent', 'no file', 1, 0, [child]) - - if child.parent != parent: - ErrOut.Log('Failed to connect parent.') - errors += 1 - - if [child] != parent.GetChildren(): - ErrOut.Log('Failed GetChildren.') - errors += 1 - - if child != parent.GetOneOf('child'): - ErrOut.Log('Failed GetOneOf(child)') - errors += 1 - - if parent.GetOneOf('bogus'): - ErrOut.Log('Failed GetOneOf(bogus)') - errors += 1 - - if not parent.IsA('parent'): - ErrOut.Log('Expecting parent type') - errors += 1 - - parent = IDLNode('parent', 'no file', 1, 0, [child, child]) - if [child, child] != parent.GetChildren(): - ErrOut.Log('Failed GetChildren2.') - errors += 1 - - if not errors: - InfoOut.Log('Passed ChildTest') - return errors - - -def Main(): - errors = StringTest() - errors += ChildTest() - - if errors: - ErrOut.Log('IDLNode failed with %d errors.' % errors) - return -1 - return 0 - -if __name__ == '__main__': - sys.exit(Main())
diff --git a/generators/idl_option.py b/generators/idl_option.py deleted file mode 100644 index fc0ff88..0000000 --- a/generators/idl_option.py +++ /dev/null
@@ -1,108 +0,0 @@ -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import getopt -import sys - -from idl_log import ErrOut, InfoOut, WarnOut - -OptionMap = { } - - -def GetOption(name): - if name not in OptionMap: - raise RuntimeError('Could not find option "%s".' % name) - return OptionMap[name].Get() - -class Option(object): - def __init__(self, name, desc, default = None, callfunc = None, - testfunc = None, cookie = None): - - # Verify this option is not a duplicate - if name in OptionMap: - raise RuntimeError('Option "%s" already exists.' % name) - self.name = name - self.desc = desc - self.default = default - self.value = default - self.callfunc = callfunc - self.testfunc = testfunc - self.cookie = cookie - OptionMap[name] = self - - def Set(self, value): - if self.testfunc: - if not self.testfunc(self, value): return False - # If this is a boolean option, set it to true - if self.default is None: - self.value = True - else: - self.value = value - if self.callfunc: - self.callfunc(self) - return True - - def Get(self): - return self.value - - -def DumpOption(option): - if len(option.name) > 1: - out = ' --%-15.15s\t%s' % (option.name, option.desc) - else: - out = ' -%-15.15s\t%s' % (option.name, option.desc) - if option.default: - out = '%s\n\t\t\t(Default: %s)\n' % (out, option.default) - InfoOut.Log(out) - -def DumpHelp(option=None): - InfoOut.Log('Usage:') - for opt in sorted(OptionMap.keys()): - DumpOption(OptionMap[opt]) - sys.exit(0) - -# -# Default IDL options -# -# -h : Help, prints options -# --verbose : use verbose output -# --test : test this module -# -Option('h', 'Help', callfunc=DumpHelp) -Option('help', 'Help', callfunc=DumpHelp) -Option('verbose', 'Verbose') -Option('test', 'Test the IDL scripts') - -def ParseOptions(args): - short_opts= "" - long_opts = [] - - # Build short and long option lists - for name in sorted(OptionMap.keys()): - option = OptionMap[name] - if len(name) > 1: - if option.default is None: - long_opts.append('%s' % name) - else: - long_opts.append('%s=' % name) - else: - if option.default is None: - short_opts += name - else: - short_opts += '%s:' % name - - try: - opts, filenames = getopt.getopt(args, short_opts, long_opts) - - for opt, val in opts: - if len(opt) == 2: opt = opt[1:] - if opt[0:2] == '--': opt = opt[2:] - OptionMap[opt].Set(val) - - except getopt.error as e: - ErrOut.Log('Illegal option: %s\n' % str(e)) - DumpHelp() - sys.exit(-1) - - return filenames
diff --git a/generators/idl_outfile.py b/generators/idl_outfile.py deleted file mode 100755 index cc145fe..0000000 --- a/generators/idl_outfile.py +++ /dev/null
@@ -1,209 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Output file objects for generator. """ - -import difflib -import os -import time -import subprocess -import sys - -from idl_log import ErrOut, InfoOut, WarnOut -from idl_option import GetOption, Option, ParseOptions -from stat import * - -Option('diff', 'Generate a DIFF when saving the file.') - - -# -# IDLOutFile -# -# IDLOutFile provides a temporary output file. By default, the object will -# not write the output if the file already exists, and matches what will be -# written. This prevents the timestamp from changing to optimize cases where -# the output files are used by a timestamp dependent build system -# -class IDLOutFile(object): - def __init__(self, filename, always_write = False, create_dir = True): - self.filename = filename - self.always_write = always_write - self.create_dir = create_dir - self.outlist = [] - self.open = True - - # Compare the old text to the current list of output lines. - def IsEquivalent_(self, oldtext): - if not oldtext: return False - - oldlines = oldtext.split('\n') - curlines = (''.join(self.outlist)).split('\n') - - # If number of lines don't match, it's a mismatch - if len(oldlines) != len(curlines): - return False - - for index in range(len(oldlines)): - oldline = oldlines[index] - curline = curlines[index] - - if oldline == curline: continue - - curwords = curline.split() - oldwords = oldline.split() - - # It wasn't a perfect match. Check for changes we should ignore. - # Unmatched lines must be the same length - if len(curwords) != len(oldwords): - return False - - # If it's not a comment then it's a mismatch - if curwords[0] not in ['*', '/*', '//']: - return False - - # Ignore changes to the Copyright year which is autogenerated - # /* Copyright 2011 The Chromium Authors - if len(curwords) > 4 and curwords[1] == 'Copyright': - if curwords[4:] == oldwords[4:]: continue - - # Ignore changes to auto generation timestamp. - # // From FILENAME.idl modified DAY MON DATE TIME YEAR. - # /* From FILENAME.idl modified DAY MON DATE TIME YEAR. */ - # The line may be wrapped, so first deal with the first "From" line. - if curwords[1] == 'From': - if curwords[0:4] == oldwords[0:4]: continue - - # Ignore changes to auto generation timestamp when line is wrapped - if index > 0: - two_line_oldwords = oldlines[index - 1].split() + oldwords[1:] - two_line_curwords = curlines[index - 1].split() + curwords[1:] - if len(two_line_curwords) > 8 and two_line_curwords[1] == 'From': - if two_line_curwords[0:4] == two_line_oldwords[0:4]: continue - - return False - return True - - # Return the file name - def Filename(self): - return self.filename - - # Append to the output if the file is still open - def Write(self, string): - if not self.open: - raise RuntimeError('Could not write to closed file %s.' % self.filename) - self.outlist.append(string) - - # Run clang-format on the buffered file contents. - def ClangFormat(self): - clang_format = subprocess.Popen(['clang-format', '-style=Chromium'], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - new_output = clang_format.communicate("".join(self.outlist))[0] - self.outlist = [new_output] - - # Close the file, flushing it to disk - def Close(self): - filename = os.path.realpath(self.filename) - self.open = False - outtext = ''.join(self.outlist) - oldtext = '' - - if not self.always_write: - if os.path.isfile(filename): - with open(filename, 'r', encoding='utf-8') as fin: - oldtext = fin.read() - if self.IsEquivalent_(oldtext): - if GetOption('verbose'): - InfoOut.Log('Output %s unchanged.' % self.filename) - return False - - if GetOption('diff'): - for line in difflib.unified_diff(oldtext.split('\n'), outtext.split('\n'), - 'OLD ' + self.filename, - 'NEW ' + self.filename, - n=1, lineterm=''): - ErrOut.Log(line) - - try: - # If the directory does not exit, try to create it, if we fail, we - # still get the exception when the file is openned. - basepath, leafname = os.path.split(filename) - if basepath and not os.path.isdir(basepath) and self.create_dir: - InfoOut.Log('Creating directory: %s\n' % basepath) - os.makedirs(basepath) - - if not GetOption('test'): - with open(filename, 'w', newline='\n', encoding='utf=8') as fout: - fout.write(outtext) - InfoOut.Log('Output %s written.' % self.filename) - return True - - except IOError as e: - ErrOut.Log("I/O error(%d): %s" % (e.errno, e.strerror)) - except: - ErrOut.Log("Unexpected error: %s" % sys.exc_info()[0]) - raise - - return False - - -def TestFile(name, stringlist, force, update): - errors = 0 - - # Get the old timestamp - if os.path.exists(name): - old_time = os.stat(filename)[ST_MTIME] - else: - old_time = 'NONE' - - # Create the file and write to it - out = IDLOutFile(filename, force) - for item in stringlist: - out.Write(item) - - # We wait for flush to force the timestamp to change - time.sleep(2) - - wrote = out.Close() - cur_time = os.stat(filename)[ST_MTIME] - if update: - if not wrote: - ErrOut.Log('Failed to write output %s.' % filename) - return 1 - if cur_time == old_time: - ErrOut.Log('Failed to update timestamp for %s.' % filename) - return 1 - else: - if wrote: - ErrOut.Log('Should not have writen output %s.' % filename) - return 1 - if cur_time != old_time: - ErrOut.Log('Should not have modified timestamp for %s.' % filename) - return 1 - return 0 - - -def main(): - errors = 0 - stringlist = ['Test', 'Testing\n', 'Test'] - filename = 'outtest.txt' - - # Test forcibly writing a file - errors += TestFile(filename, stringlist, force=True, update=True) - - # Test conditionally writing the file skipping - errors += TestFile(filename, stringlist, force=False, update=False) - - # Test conditionally writing the file updating - errors += TestFile(filename, stringlist + ['X'], force=False, update=True) - - # Clean up file - os.remove(filename) - if not errors: InfoOut.Log('All tests pass.') - return errors - - -if __name__ == '__main__': - sys.exit(main())
diff --git a/generators/idl_parser.py b/generators/idl_parser.py deleted file mode 100755 index f5aa1f6..0000000 --- a/generators/idl_parser.py +++ /dev/null
@@ -1,1295 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Parser for PPAPI IDL """ - -# -# IDL Parser -# -# The parser is uses the PLY yacc library to build a set of parsing rules based -# on WebIDL. -# -# WebIDL, and WebIDL regular expressions can be found at: -# http://dev.w3.org/2006/webapi/WebIDL/ -# PLY can be found at: -# http://www.dabeaz.com/ply/ -# -# The parser generates a tree by recursively matching sets of items against -# defined patterns. When a match is made, that set of items is reduced -# to a new item. The new item can provide a match for parent patterns. -# In this way an AST is built (reduced) depth first. - - -import getopt -import glob -import os.path -import re -import sys -import time - -from idl_ast import IDLAst -from idl_log import ErrOut, InfoOut, WarnOut -from idl_lexer import IDLLexer -from idl_node import IDLAttribute, IDLFile, IDLNode -from idl_option import GetOption, Option, ParseOptions -from idl_lint import Lint - -from ply import lex -from ply import yacc - -Option('build_debug', 'Debug tree building.') -Option('parse_debug', 'Debug parse reduction steps.') -Option('token_debug', 'Debug token generation.') -Option('dump_tree', 'Dump the tree.') -Option('srcroot', 'Working directory.', default=os.path.join('..', 'api')) -Option('include_private', 'Include private IDL directory in default API paths.') - -# -# ERROR_REMAP -# -# Maps the standard error formula into a more friendly error message. -# -ERROR_REMAP = { - 'Unexpected ")" after "(".' : 'Empty argument list.', - 'Unexpected ")" after ",".' : 'Missing argument.', - 'Unexpected "}" after ",".' : 'Trailing comma in block.', - 'Unexpected "}" after "{".' : 'Unexpected empty block.', - 'Unexpected comment after "}".' : 'Unexpected trailing comment.', - 'Unexpected "{" after keyword "enum".' : 'Enum missing name.', - 'Unexpected "{" after keyword "struct".' : 'Struct missing name.', - 'Unexpected "{" after keyword "interface".' : 'Interface missing name.', -} - -# DumpReduction -# -# Prints out the set of items which matched a particular pattern and the -# new item or set it was reduced to. -def DumpReduction(cls, p): - if p[0] is None: - InfoOut.Log("OBJ: %s(%d) - None\n" % (cls, len(p))) - InfoOut.Log(" [%s]\n" % [str(x) for x in p[1:]]) - else: - out = "" - for index in range(len(p) - 1): - out += " >%s< " % str(p[index + 1]) - InfoOut.Log("OBJ: %s(%d) - %s : %s\n" % (cls, len(p), str(p[0]), out)) - - -# CopyToList -# -# Takes an input item, list, or None, and returns a new list of that set. -def CopyToList(item): - # If the item is 'Empty' make it an empty list - if not item: item = [] - - # If the item is not a list - if type(item) is not type([]): item = [item] - - # Make a copy we can modify - return list(item) - - - -# ListFromConcat -# -# Generate a new List by joining of two sets of inputs which can be an -# individual item, a list of items, or None. -def ListFromConcat(*items): - itemsout = [] - for item in items: - itemlist = CopyToList(item) - itemsout.extend(itemlist) - - return itemsout - - -# TokenTypeName -# -# Generate a string which has the type and value of the token. -def TokenTypeName(t): - if t.type == 'SYMBOL': return 'symbol %s' % t.value - if t.type in ['HEX', 'INT', 'OCT', 'FLOAT']: - return 'value %s' % t.value - if t.type == 'STRING' : return 'string "%s"' % t.value - if t.type == 'COMMENT' : return 'comment' - if t.type == t.value: return '"%s"' % t.value - return 'keyword "%s"' % t.value - - -# -# IDL Parser -# -# The Parser inherits the from the Lexer to provide PLY with the tokenizing -# definitions. Parsing patterns are encoded as function where p_<name> is -# is called any time a patern matching the function documentation is found. -# Paterns are expressed in the form of: -# """ <new item> : <item> .... -# | <item> ....""" -# -# Where new item is the result of a match against one or more sets of items -# separated by the "|". -# -# The function is called with an object 'p' where p[0] is the output object -# and p[n] is the set of inputs for positive values of 'n'. Len(p) can be -# used to distinguish between multiple item sets in the pattern. -# -# For more details on parsing refer to the PLY documentation at -# http://www.dabeaz.com/ply/ -# -# -# The parser uses the following conventions: -# a <type>_block defines a block of <type> definitions in the form of: -# [comment] [ext_attr_block] <type> <name> '{' <type>_list '}' ';' -# A block is reduced by returning an object of <type> with a name of <name> -# which in turn has <type>_list as children. -# -# A [comment] is a optional C style comment block enclosed in /* ... */ which -# is appended to the adjacent node as a child. -# -# A [ext_attr_block] is an optional list of Extended Attributes which is -# appended to the adjacent node as a child. -# -# a <type>_list defines a list of <type> items which will be passed as a -# list of children to the parent pattern. A list is in the form of: -# [comment] [ext_attr_block] <...DEF...> ';' <type>_list | (empty) -# or -# [comment] [ext_attr_block] <...DEF...> <type>_cont -# -# In the first form, the list is reduced recursively, where the right side -# <type>_list is first reduced then joined with pattern currently being -# matched. The list is terminated with the (empty) pattern is matched. -# -# In the second form the list is reduced recursively, where the right side -# <type>_cont is first reduced then joined with the pattern currently being -# matched. The type_<cont> is in the form of: -# ',' <type>_list | (empty) -# The <type>_cont form is used to consume the ',' which only occurs when -# there is more than one object in the list. The <type>_cont also provides -# the terminating (empty) definition. -# - - -class IDLParser(IDLLexer): -# TOP -# -# This pattern defines the top of the parse tree. The parse tree is in the -# the form of: -# -# top -# *modifiers -# *comments -# *ext_attr_block -# ext_attr_list -# attr_arg_list -# *integer, value -# *param_list -# *typeref -# -# top_list -# describe_block -# describe_list -# enum_block -# enum_item -# interface_block -# member -# label_block -# label_item -# struct_block -# member -# typedef_decl -# typedef_data -# typedef_func -# -# (* sub matches found at multiple levels and are not truly children of top) -# -# We force all input files to start with two comments. The first comment is a -# Copyright notice followed by a set of file wide Extended Attributes, followed -# by the file comment and finally by file level patterns. -# - # Find the Copyright, File comment, and optional file wide attributes. We - # use a match with COMMENT instead of comments to force the token to be - # present. The extended attributes and the top_list become siblings which - # in turn are children of the file object created from the results of top. - def p_top(self, p): - """top : COMMENT COMMENT ext_attr_block top_list""" - - Copyright = self.BuildComment('Copyright', p, 1) - Filedoc = self.BuildComment('Comment', p, 2) - - p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4]) - if self.parse_debug: DumpReduction('top', p) - - def p_top_short(self, p): - """top : COMMENT ext_attr_block top_list""" - Copyright = self.BuildComment('Copyright', p, 1) - Filedoc = IDLNode('Comment', self.lexobj.filename, p.lineno(2)-1, - p.lexpos(2)-1, [self.BuildAttribute('NAME', ''), - self.BuildAttribute('FORM', 'cc')]) - p[0] = ListFromConcat(Copyright, Filedoc, p[2], p[3]) - if self.parse_debug: DumpReduction('top', p) - - # Build a list of top level items. - def p_top_list(self, p): - """top_list : callback_decl top_list - | describe_block top_list - | dictionary_block top_list - | enum_block top_list - | inline top_list - | interface_block top_list - | label_block top_list - | namespace top_list - | struct_block top_list - | typedef_decl top_list - | bad_decl top_list - | """ - if len(p) > 2: - p[0] = ListFromConcat(p[1], p[2]) - if self.parse_debug: DumpReduction('top_list', p) - - # Recover from error and continue parsing at the next top match. - def p_top_error(self, p): - """top_list : error top_list""" - p[0] = p[2] - - # Recover from error and continue parsing at the next top match. - def p_bad_decl(self, p): - """bad_decl : modifiers SYMBOL error '}' ';'""" - p[0] = [] - -# -# Modifier List -# -# - def p_modifiers(self, p): - """modifiers : comments ext_attr_block""" - p[0] = ListFromConcat(p[1], p[2]) - if self.parse_debug: DumpReduction('modifiers', p) - -# -# Scoped name is a name with an optional scope. -# -# Used for types and namespace names. eg. foo_bar.hello_world, or -# foo_bar.hello_world.SomeType. -# - def p_scoped_name(self, p): - """scoped_name : SYMBOL scoped_name_rest""" - p[0] = ''.join(p[1:]) - if self.parse_debug: DumpReduction('scoped_name', p) - - def p_scoped_name_rest(self, p): - """scoped_name_rest : '.' scoped_name - |""" - p[0] = ''.join(p[1:]) - if self.parse_debug: DumpReduction('scoped_name_rest', p) - -# -# Type reference -# -# - def p_typeref(self, p): - """typeref : scoped_name""" - p[0] = p[1] - if self.parse_debug: DumpReduction('typeref', p) - - -# -# Comments -# -# Comments are optional list of C style comment objects. Comments are returned -# as a list or None. -# - def p_comments(self, p): - """comments : COMMENT comments - | """ - if len(p) > 1: - child = self.BuildComment('Comment', p, 1) - p[0] = ListFromConcat(child, p[2]) - if self.parse_debug: DumpReduction('comments', p) - else: - if self.parse_debug: DumpReduction('no comments', p) - - -# -# Namespace -# -# A namespace provides a named scope to an enclosed top_list. -# - def p_namespace(self, p): - """namespace : modifiers NAMESPACE namespace_name '{' top_list '}' ';'""" - children = ListFromConcat(p[1], p[5]) - p[0] = self.BuildNamed('Namespace', p, 3, children) - - # We allow namespace names of the form foo.bar.baz. - def p_namespace_name(self, p): - """namespace_name : scoped_name""" - p[0] = p[1] - - -# -# Dictionary -# -# A dictionary is a named list of optional and required members. -# - def p_dictionary_block(self, p): - """dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'""" - p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[1], p[5])) - - def p_dictionary_errorA(self, p): - """dictionary_block : modifiers DICTIONARY error ';'""" - p[0] = [] - - def p_dictionary_errorB(self, p): - """dictionary_block : modifiers DICTIONARY error '{' struct_list '}' ';'""" - p[0] = [] - -# -# Callback -# -# A callback is essentially a single function declaration (outside of an -# Interface). -# - def p_callback_decl(self, p): - """callback_decl : modifiers CALLBACK SYMBOL '=' SYMBOL param_list ';'""" - children = ListFromConcat(p[1], p[6]) - p[0] = self.BuildNamed('Callback', p, 3, children) - - -# -# Inline -# -# Inline blocks define option code to be emitted based on language tag, -# in the form of: -# #inline <LANGUAGE> -# <CODE> -# #endinl -# - def p_inline(self, p): - """inline : modifiers INLINE""" - words = p[2].split() - name = self.BuildAttribute('NAME', words[1]) - lines = p[2].split('\n') - value = self.BuildAttribute('VALUE', '\n'.join(lines[1:-1]) + '\n') - children = ListFromConcat(name, value, p[1]) - p[0] = self.BuildProduction('Inline', p, 2, children) - if self.parse_debug: DumpReduction('inline', p) - -# Extended Attributes -# -# Extended Attributes denote properties which will be applied to a node in the -# AST. A list of extended attributes are denoted by a brackets '[' ... ']' -# enclosing a comma separated list of extended attributes in the form of: -# -# Name -# Name=HEX | INT | OCT | FLOAT -# Name="STRING" -# Name=Function(arg ...) -# TODO(bradnelson) -Not currently supported: -# ** Name(arg ...) ... -# ** Name=Scope::Value -# -# Extended Attributes are returned as a list or None. - - def p_ext_attr_block(self, p): - """ext_attr_block : '[' ext_attr_list ']' - | """ - if len(p) > 1: - p[0] = p[2] - if self.parse_debug: DumpReduction('ext_attr_block', p) - else: - if self.parse_debug: DumpReduction('no ext_attr_block', p) - - def p_ext_attr_list(self, p): - """ext_attr_list : SYMBOL '=' SYMBOL ext_attr_cont - | SYMBOL '=' value ext_attr_cont - | SYMBOL '=' SYMBOL param_list ext_attr_cont - | SYMBOL ext_attr_cont""" - # If there are 4 tokens plus a return slot, this must be in the form - # SYMBOL = SYMBOL|value ext_attr_cont - if len(p) == 5: - p[0] = ListFromConcat(self.BuildAttribute(p[1], p[3]), p[4]) - # If there are 5 tokens plus a return slot, this must be in the form - # SYMBOL = SYMBOL (param_list) ext_attr_cont - elif len(p) == 6: - member = self.BuildNamed('Member', p, 3, [p[4]]) - p[0] = ListFromConcat(self.BuildAttribute(p[1], member), p[5]) - # Otherwise, this must be: SYMBOL ext_attr_cont - else: - p[0] = ListFromConcat(self.BuildAttribute(p[1], 'True'), p[2]) - if self.parse_debug: DumpReduction('ext_attribute_list', p) - - def p_ext_attr_list_values(self, p): - """ext_attr_list : SYMBOL '=' '(' values ')' ext_attr_cont - | SYMBOL '=' '(' symbols ')' ext_attr_cont""" - p[0] = ListFromConcat(self.BuildAttribute(p[1], p[4]), p[6]) - - def p_values(self, p): - """values : value values_cont""" - p[0] = ListFromConcat(p[1], p[2]) - - def p_symbols(self, p): - """symbols : SYMBOL symbols_cont""" - p[0] = ListFromConcat(p[1], p[2]) - - def p_symbols_cont(self, p): - """symbols_cont : ',' SYMBOL symbols_cont - | """ - if len(p) > 1: p[0] = ListFromConcat(p[2], p[3]) - - def p_values_cont(self, p): - """values_cont : ',' value values_cont - | """ - if len(p) > 1: p[0] = ListFromConcat(p[2], p[3]) - - def p_ext_attr_cont(self, p): - """ext_attr_cont : ',' ext_attr_list - |""" - if len(p) > 1: p[0] = p[2] - if self.parse_debug: DumpReduction('ext_attribute_cont', p) - - def p_ext_attr_func(self, p): - """ext_attr_list : SYMBOL '(' attr_arg_list ')' ext_attr_cont""" - p[0] = ListFromConcat(self.BuildAttribute(p[1] + '()', p[3]), p[5]) - if self.parse_debug: DumpReduction('attr_arg_func', p) - - def p_ext_attr_arg_list(self, p): - """attr_arg_list : SYMBOL attr_arg_cont - | value attr_arg_cont""" - p[0] = ListFromConcat(p[1], p[2]) - - def p_attr_arg_cont(self, p): - """attr_arg_cont : ',' attr_arg_list - | """ - if self.parse_debug: DumpReduction('attr_arg_cont', p) - if len(p) > 1: p[0] = p[2] - - def p_attr_arg_error(self, p): - """attr_arg_cont : error attr_arg_cont""" - p[0] = p[2] - if self.parse_debug: DumpReduction('attr_arg_error', p) - - -# -# Describe -# -# A describe block is defined at the top level. It provides a mechanism for -# attributing a group of ext_attr to a describe_list. Members of the -# describe list are language specific 'Type' declarations -# - def p_describe_block(self, p): - """describe_block : modifiers DESCRIBE '{' describe_list '}' ';'""" - children = ListFromConcat(p[1], p[4]) - p[0] = self.BuildProduction('Describe', p, 2, children) - if self.parse_debug: DumpReduction('describe_block', p) - - # Recover from describe error and continue parsing at the next top match. - def p_describe_error(self, p): - """describe_list : error describe_list""" - p[0] = [] - - def p_describe_list(self, p): - """describe_list : modifiers SYMBOL ';' describe_list - | modifiers ENUM ';' describe_list - | modifiers STRUCT ';' describe_list - | modifiers TYPEDEF ';' describe_list - | """ - if len(p) > 1: - Type = self.BuildNamed('Type', p, 2, p[1]) - p[0] = ListFromConcat(Type, p[4]) - -# -# Constant Values (integer, value) -# -# Constant values can be found at various levels. A Constant value is returns -# as the string value after validated against a FLOAT, HEX, INT, OCT or -# STRING pattern as appropriate. -# - def p_value(self, p): - """value : FLOAT - | HEX - | INT - | OCT - | STRING""" - p[0] = p[1] - if self.parse_debug: DumpReduction('value', p) - - def p_value_lshift(self, p): - """value : integer LSHIFT INT""" - p[0] = "%s << %s" % (p[1], p[3]) - if self.parse_debug: DumpReduction('value', p) - -# Integers are numbers which may not be floats used in cases like array sizes. - def p_integer(self, p): - """integer : HEX - | INT - | OCT""" - p[0] = p[1] - if self.parse_debug: DumpReduction('integer', p) - -# -# Expression -# -# A simple arithmetic expression. -# - precedence = ( - ('left','|','&','^'), - ('left','LSHIFT','RSHIFT'), - ('left','+','-'), - ('left','*','/'), - ('right','UMINUS','~'), - ) - - def p_expression_binop(self, p): - """expression : expression LSHIFT expression - | expression RSHIFT expression - | expression '|' expression - | expression '&' expression - | expression '^' expression - | expression '+' expression - | expression '-' expression - | expression '*' expression - | expression '/' expression""" - p[0] = "%s %s %s" % (str(p[1]), str(p[2]), str(p[3])) - if self.parse_debug: DumpReduction('expression_binop', p) - - def p_expression_unop(self, p): - """expression : '-' expression %prec UMINUS - | '~' expression %prec '~'""" - p[0] = "%s%s" % (str(p[1]), str(p[2])) - if self.parse_debug: DumpReduction('expression_unop', p) - - def p_expression_term(self, p): - """expression : '(' expression ')'""" - p[0] = "%s%s%s" % (str(p[1]), str(p[2]), str(p[3])) - if self.parse_debug: DumpReduction('expression_term', p) - - def p_expression_symbol(self, p): - """expression : SYMBOL""" - p[0] = p[1] - if self.parse_debug: DumpReduction('expression_symbol', p) - - def p_expression_integer(self, p): - """expression : integer""" - p[0] = p[1] - if self.parse_debug: DumpReduction('expression_integer', p) - -# -# Array List -# -# Defined a list of array sizes (if any). -# - def p_arrays(self, p): - """arrays : '[' ']' arrays - | '[' integer ']' arrays - | """ - # If there are 3 tokens plus a return slot it is an unsized array - if len(p) == 4: - array = self.BuildProduction('Array', p, 1) - p[0] = ListFromConcat(array, p[3]) - # If there are 4 tokens plus a return slot it is a fixed array - elif len(p) == 5: - count = self.BuildAttribute('FIXED', p[2]) - array = self.BuildProduction('Array', p, 2, [count]) - p[0] = ListFromConcat(array, p[4]) - # If there is only a return slot, do not fill it for this terminator. - elif len(p) == 1: return - if self.parse_debug: DumpReduction('arrays', p) - - -# An identifier is a legal value for a parameter or attribute name. Lots of -# existing IDL files use "callback" as a parameter/attribute name, so we allow -# a SYMBOL or the CALLBACK keyword. - def p_identifier(self, p): - """identifier : SYMBOL - | CALLBACK""" - p[0] = p[1] - # Save the line number of the underlying token (otherwise it gets - # discarded), since we use it in the productions with an identifier in - # them. - p.set_lineno(0, p.lineno(1)) - - -# -# Union -# -# A union allows multiple choices of types for a parameter or member. -# - - def p_union_option(self, p): - """union_option : modifiers SYMBOL arrays""" - typeref = self.BuildAttribute('TYPEREF', p[2]) - children = ListFromConcat(p[1], typeref, p[3]) - p[0] = self.BuildProduction('Option', p, 2, children) - - def p_union_list(self, p): - """union_list : union_option OR union_list - | union_option""" - if len(p) > 2: - p[0] = ListFromConcat(p[1], p[3]) - else: - p[0] = p[1] - -# -# Parameter List -# -# A parameter list is a collection of arguments which are passed to a -# function. -# - def p_param_list(self, p): - """param_list : '(' param_item param_cont ')' - | '(' ')' """ - if len(p) > 3: - args = ListFromConcat(p[2], p[3]) - else: - args = [] - p[0] = self.BuildProduction('Callspec', p, 1, args) - if self.parse_debug: DumpReduction('param_list', p) - - def p_param_item(self, p): - """param_item : modifiers optional typeref arrays identifier""" - typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1], p[2], typeref, p[4]) - p[0] = self.BuildNamed('Param', p, 5, children) - if self.parse_debug: DumpReduction('param_item', p) - - def p_param_item_union(self, p): - """param_item : modifiers optional '(' union_list ')' identifier""" - union = self.BuildAttribute('Union', True) - children = ListFromConcat(p[1], p[2], p[4], union) - p[0] = self.BuildNamed('Param', p, 6, children) - if self.parse_debug: DumpReduction('param_item', p) - - def p_optional(self, p): - """optional : OPTIONAL - | """ - if len(p) == 2: - p[0] = self.BuildAttribute('OPTIONAL', True) - - - def p_param_cont(self, p): - """param_cont : ',' param_item param_cont - | """ - if len(p) > 1: - p[0] = ListFromConcat(p[2], p[3]) - if self.parse_debug: DumpReduction('param_cont', p) - - def p_param_error(self, p): - """param_cont : error param_cont""" - p[0] = p[2] - - -# -# Typedef -# -# A typedef creates a new referencable type. The typedef can specify an array -# definition as well as a function declaration. -# - def p_typedef_data(self, p): - """typedef_decl : modifiers TYPEDEF SYMBOL SYMBOL ';' """ - typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1], typeref) - p[0] = self.BuildNamed('Typedef', p, 4, children) - if self.parse_debug: DumpReduction('typedef_data', p) - - def p_typedef_array(self, p): - """typedef_decl : modifiers TYPEDEF SYMBOL arrays SYMBOL ';' """ - typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1], typeref, p[4]) - p[0] = self.BuildNamed('Typedef', p, 5, children) - if self.parse_debug: DumpReduction('typedef_array', p) - - def p_typedef_func(self, p): - """typedef_decl : modifiers TYPEDEF SYMBOL SYMBOL param_list ';' """ - typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1], typeref, p[5]) - p[0] = self.BuildNamed('Typedef', p, 4, children) - if self.parse_debug: DumpReduction('typedef_func', p) - -# -# Enumeration -# -# An enumeration is a set of named integer constants. An enumeration -# is valid type which can be referenced in other definitions. -# - def p_enum_block(self, p): - """enum_block : modifiers ENUM SYMBOL '{' enum_list '}' ';'""" - p[0] = self.BuildNamed('Enum', p, 3, ListFromConcat(p[1], p[5])) - if self.parse_debug: DumpReduction('enum_block', p) - - # Recover from enum error and continue parsing at the next top match. - def p_enum_errorA(self, p): - """enum_block : modifiers ENUM error '{' enum_list '}' ';'""" - p[0] = [] - - def p_enum_errorB(self, p): - """enum_block : modifiers ENUM error ';'""" - p[0] = [] - - def p_enum_list(self, p): - """enum_list : modifiers SYMBOL '=' expression enum_cont - | modifiers SYMBOL enum_cont""" - if len(p) > 4: - val = self.BuildAttribute('VALUE', p[4]) - enum = self.BuildNamed('EnumItem', p, 2, ListFromConcat(val, p[1])) - p[0] = ListFromConcat(enum, p[5]) - else: - enum = self.BuildNamed('EnumItem', p, 2, p[1]) - p[0] = ListFromConcat(enum, p[3]) - if self.parse_debug: DumpReduction('enum_list', p) - - def p_enum_cont(self, p): - """enum_cont : ',' enum_list - |""" - if len(p) > 1: p[0] = p[2] - if self.parse_debug: DumpReduction('enum_cont', p) - - def p_enum_cont_error(self, p): - """enum_cont : error enum_cont""" - p[0] = p[2] - if self.parse_debug: DumpReduction('enum_error', p) - - -# -# Label -# -# A label is a special kind of enumeration which allows us to go from a -# set of labels -# - def p_label_block(self, p): - """label_block : modifiers LABEL SYMBOL '{' label_list '}' ';'""" - p[0] = self.BuildNamed('Label', p, 3, ListFromConcat(p[1], p[5])) - if self.parse_debug: DumpReduction('label_block', p) - - def p_label_list(self, p): - """label_list : modifiers SYMBOL '=' FLOAT label_cont""" - val = self.BuildAttribute('VALUE', p[4]) - label = self.BuildNamed('LabelItem', p, 2, ListFromConcat(val, p[1])) - p[0] = ListFromConcat(label, p[5]) - if self.parse_debug: DumpReduction('label_list', p) - - def p_label_cont(self, p): - """label_cont : ',' label_list - |""" - if len(p) > 1: p[0] = p[2] - if self.parse_debug: DumpReduction('label_cont', p) - - def p_label_cont_error(self, p): - """label_cont : error label_cont""" - p[0] = p[2] - if self.parse_debug: DumpReduction('label_error', p) - - -# -# Members -# -# A member attribute or function of a struct or interface. -# - def p_member_attribute(self, p): - """member_attribute : modifiers typeref arrays questionmark identifier""" - typeref = self.BuildAttribute('TYPEREF', p[2]) - children = ListFromConcat(p[1], typeref, p[3], p[4]) - p[0] = self.BuildNamed('Member', p, 5, children) - if self.parse_debug: DumpReduction('attribute', p) - - def p_member_attribute_union(self, p): - """member_attribute : modifiers '(' union_list ')' questionmark identifier""" - union = self.BuildAttribute('Union', True) - children = ListFromConcat(p[1], p[3], p[5], union) - p[0] = self.BuildNamed('Member', p, 6, children) - if self.parse_debug: DumpReduction('attribute', p) - - def p_member_function(self, p): - """member_function : modifiers static typeref arrays SYMBOL param_list""" - typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1], p[2], typeref, p[4], p[6]) - p[0] = self.BuildNamed('Member', p, 5, children) - if self.parse_debug: DumpReduction('function', p) - - def p_static(self, p): - """static : STATIC - | """ - if len(p) == 2: - p[0] = self.BuildAttribute('STATIC', True) - - def p_questionmark(self, p): - """questionmark : '?' - | """ - if len(p) == 2: - p[0] = self.BuildAttribute('OPTIONAL', True) - -# -# Interface -# -# An interface is a named collection of functions. -# - def p_interface_block(self, p): - """interface_block : modifiers INTERFACE SYMBOL '{' interface_list '}' ';'""" - p[0] = self.BuildNamed('Interface', p, 3, ListFromConcat(p[1], p[5])) - if self.parse_debug: DumpReduction('interface_block', p) - - def p_interface_error(self, p): - """interface_block : modifiers INTERFACE error '{' interface_list '}' ';'""" - p[0] = [] - - def p_interface_list(self, p): - """interface_list : member_function ';' interface_list - | """ - if len(p) > 1 : - p[0] = ListFromConcat(p[1], p[3]) - if self.parse_debug: DumpReduction('interface_list', p) - - -# -# Struct -# -# A struct is a named collection of members which in turn reference other -# types. The struct is a referencable type. -# - def p_struct_block(self, p): - """struct_block : modifiers STRUCT SYMBOL '{' struct_list '}' ';'""" - children = ListFromConcat(p[1], p[5]) - p[0] = self.BuildNamed('Struct', p, 3, children) - if self.parse_debug: DumpReduction('struct_block', p) - - # Recover from struct error and continue parsing at the next top match. - def p_struct_error(self, p): - """enum_block : modifiers STRUCT error '{' struct_list '}' ';'""" - p[0] = [] - - def p_struct_list(self, p): - """struct_list : member_attribute ';' struct_list - | member_function ';' struct_list - |""" - if len(p) > 1: p[0] = ListFromConcat(p[1], p[3]) - - -# -# Parser Errors -# -# p_error is called whenever the parser can not find a pattern match for -# a set of items from the current state. The p_error function defined here -# is triggered logging an error, and parsing recover happens as the -# p_<type>_error functions defined above are called. This allows the parser -# to continue so as to capture more than one error per file. -# - def p_error(self, t): - filename = self.lexobj.filename - self.parse_errors += 1 - if t: - lineno = t.lineno - pos = t.lexpos - prev = self.yaccobj.symstack[-1] - if type(prev) == lex.LexToken: - msg = "Unexpected %s after %s." % ( - TokenTypeName(t), TokenTypeName(prev)) - else: - msg = "Unexpected %s." % (t.value) - else: - lineno = self.last.lineno - pos = self.last.lexpos - msg = "Unexpected end of file after %s." % TokenTypeName(self.last) - self.yaccobj.restart() - - # Attempt to remap the error to a friendlier form - if msg in ERROR_REMAP: - msg = ERROR_REMAP[msg] - - # Log the error - ErrOut.LogLine(filename, lineno, pos, msg) - - def Warn(self, node, msg): - WarnOut.LogLine(node.filename, node.lineno, node.pos, msg) - self.parse_warnings += 1 - - def __init__(self): - IDLLexer.__init__(self) - self.yaccobj = yacc.yacc(module=self, tabmodule=None, debug=False, - optimize=0, write_tables=0) - - self.build_debug = GetOption('build_debug') - self.parse_debug = GetOption('parse_debug') - self.token_debug = GetOption('token_debug') - self.verbose = GetOption('verbose') - self.parse_errors = 0 - -# -# Tokenizer -# -# The token function returns the next token provided by IDLLexer for matching -# against the leaf paterns. -# - def token(self): - tok = self.lexobj.token() - if tok: - self.last = tok - if self.token_debug: - InfoOut.Log("TOKEN %s(%s)" % (tok.type, tok.value)) - return tok - -# -# BuildProduction -# -# Production is the set of items sent to a grammar rule resulting in a new -# item being returned. -# -# p - Is the Yacc production object containing the stack of items -# index - Index into the production of the name for the item being produced. -# cls - The type of item being producted -# childlist - The children of the new item - def BuildProduction(self, cls, p, index, childlist=None): - if not childlist: childlist = [] - filename = self.lexobj.filename - lineno = p.lineno(index) - pos = p.lexpos(index) - out = IDLNode(cls, filename, lineno, pos, childlist) - if self.build_debug: - InfoOut.Log("Building %s" % out) - return out - - def BuildNamed(self, cls, p, index, childlist=None): - if not childlist: childlist = [] - childlist.append(self.BuildAttribute('NAME', p[index])) - return self.BuildProduction(cls, p, index, childlist) - - def BuildComment(self, cls, p, index): - name = p[index] - - # Remove comment markers - lines = [] - if name[:2] == '//': - # For C++ style, remove any leading whitespace and the '//' marker from - # each line. - form = 'cc' - for line in name.split('\n'): - start = line.find('//') - lines.append(line[start+2:]) - else: - # For C style, remove ending '*/'' - form = 'c' - for line in name[:-2].split('\n'): - # Remove characters until start marker for this line '*' if found - # otherwise it should be blank. - offs = line.find('*') - if offs >= 0: - line = line[offs + 1:].rstrip() - else: - line = '' - lines.append(line) - name = '\n'.join(lines) - - childlist = [self.BuildAttribute('NAME', name), - self.BuildAttribute('FORM', form)] - return self.BuildProduction(cls, p, index, childlist) - -# -# BuildAttribute -# -# An ExtendedAttribute is a special production that results in a property -# which is applied to the adjacent item. Attributes have no children and -# instead represent key/value pairs. -# - def BuildAttribute(self, key, val): - return IDLAttribute(key, val) - - -# -# ParseData -# -# Attempts to parse the current data loaded in the lexer. -# - def ParseData(self, data, filename='<Internal>'): - self.SetData(filename, data) - try: - self.parse_errors = 0 - self.parse_warnings = 0 - return self.yaccobj.parse(lexer=self) - - except lex.LexError as le: - ErrOut.Log(str(le)) - return [] - -# -# ParseFile -# -# Loads a new file into the lexer and attemps to parse it. -# - def ParseFile(self, filename): - date = time.ctime(os.path.getmtime(filename)) - data = open(filename).read() - if self.verbose: - InfoOut.Log("Parsing %s" % filename) - try: - out = self.ParseData(data, filename) - - # If we have a src root specified, remove it from the path - srcroot = GetOption('srcroot') - if srcroot and filename.find(srcroot) == 0: - filename = filename[len(srcroot) + 1:] - filenode = IDLFile(filename, out, self.parse_errors + self.lex_errors) - filenode.SetProperty('DATETIME', date) - return filenode - - except Exception as e: - ErrOut.LogLine(filename, self.last.lineno, self.last.lexpos, - 'Internal parsing error - %s.' % str(e)) - raise - - - -# -# Flatten Tree -# -# Flattens the tree of IDLNodes for use in testing. -# -def FlattenTree(node): - add_self = False - out = [] - for child in node.GetChildren(): - if child.IsA('Comment'): - add_self = True - else: - out.extend(FlattenTree(child)) - - if add_self: - out = [str(node)] + out - return out - - -def TestErrors(filename, filenode): - nodelist = filenode.GetChildren() - - lexer = IDLLexer() - data = open(filename).read() - lexer.SetData(filename, data) - - pass_comments = [] - fail_comments = [] - while True: - tok = lexer.lexobj.token() - if tok == None: break - if tok.type == 'COMMENT': - args = tok.value[3:-3].split() - if args[0] == 'OK': - pass_comments.append((tok.lineno, ' '.join(args[1:]))) - else: - if args[0] == 'FAIL': - fail_comments.append((tok.lineno, ' '.join(args[1:]))) - obj_list = [] - for node in nodelist: - obj_list.extend(FlattenTree(node)) - - errors = 0 - - # - # Check for expected successes - # - obj_cnt = len(obj_list) - pass_cnt = len(pass_comments) - if obj_cnt != pass_cnt: - InfoOut.Log("Mismatched pass (%d) vs. nodes built (%d)." - % (pass_cnt, obj_cnt)) - InfoOut.Log("PASS: %s" % [x[1] for x in pass_comments]) - InfoOut.Log("OBJS: %s" % obj_list) - errors += 1 - if pass_cnt > obj_cnt: pass_cnt = obj_cnt - - for i in range(pass_cnt): - line, comment = pass_comments[i] - if obj_list[i] != comment: - ErrOut.LogLine(filename, line, None, "OBJ %s : EXPECTED %s\n" % - (obj_list[i], comment)) - errors += 1 - - # - # Check for expected errors - # - err_list = ErrOut.DrainLog() - err_cnt = len(err_list) - fail_cnt = len(fail_comments) - if err_cnt != fail_cnt: - InfoOut.Log("Mismatched fail (%d) vs. errors seen (%d)." - % (fail_cnt, err_cnt)) - InfoOut.Log("FAIL: %s" % [x[1] for x in fail_comments]) - InfoOut.Log("ERRS: %s" % err_list) - errors += 1 - if fail_cnt > err_cnt: fail_cnt = err_cnt - - for i in range(fail_cnt): - line, comment = fail_comments[i] - err = err_list[i].strip() - - if err_list[i] != comment: - ErrOut.Log("%s(%d) Error\n\tERROR : %s\n\tEXPECT: %s" % ( - filename, line, err_list[i], comment)) - errors += 1 - - # Clear the error list for the next run - err_list = [] - return errors - - -def TestFile(parser, filename): - # Capture errors instead of reporting them so we can compare them - # with the expected errors. - ErrOut.SetConsole(False) - ErrOut.SetCapture(True) - - filenode = parser.ParseFile(filename) - - # Renable output - ErrOut.SetConsole(True) - ErrOut.SetCapture(False) - - # Compare captured errors - return TestErrors(filename, filenode) - - -def TestErrorFiles(filter): - idldir = os.path.split(sys.argv[0])[0] - idldir = os.path.join(idldir, 'test_parser', '*.idl') - filenames = glob.glob(idldir) - parser = IDLParser() - total_errs = 0 - for filename in filenames: - if filter and filename not in filter: continue - errs = TestFile(parser, filename) - if errs: - ErrOut.Log("%s test failed with %d error(s)." % (filename, errs)) - total_errs += errs - - if total_errs: - ErrOut.Log("Failed parsing test.") - else: - InfoOut.Log("Passed parsing test.") - return total_errs - - -def TestNamespaceFiles(filter): - idldir = os.path.split(sys.argv[0])[0] - idldir = os.path.join(idldir, 'test_namespace', '*.idl') - filenames = glob.glob(idldir) - testnames = [] - - for filename in filenames: - if filter and filename not in filter: continue - testnames.append(filename) - - # If we have no files to test, then skip this test - if not testnames: - InfoOut.Log('No files to test for namespace.') - return 0 - - InfoOut.SetConsole(False) - ast = ParseFiles(testnames) - InfoOut.SetConsole(True) - - errs = ast.GetProperty('ERRORS') - if errs: - ErrOut.Log("Failed namespace test.") - else: - InfoOut.Log("Passed namespace test.") - return errs - - - -def FindVersionError(releases, node): - err_cnt = 0 - if node.IsA('Interface', 'Struct'): - comment_list = [] - comment = node.GetOneOf('Comment') - if comment and comment.GetName()[:4] == 'REL:': - comment_list = comment.GetName()[5:].strip().split(' ') - - first_list = [node.first_release[rel] for rel in releases] - first_list = sorted(set(first_list)) - if first_list != comment_list: - node.Error("Mismatch in releases: %s vs %s." % ( - comment_list, first_list)) - err_cnt += 1 - - for child in node.GetChildren(): - err_cnt += FindVersionError(releases, child) - return err_cnt - - -def TestVersionFiles(filter): - idldir = os.path.split(sys.argv[0])[0] - idldir = os.path.join(idldir, 'test_version', '*.idl') - filenames = glob.glob(idldir) - testnames = [] - - for filename in filenames: - if filter and filename not in filter: continue - testnames.append(filename) - - # If we have no files to test, then skip this test - if not testnames: - InfoOut.Log('No files to test for version.') - return 0 - - ast = ParseFiles(testnames) - errs = FindVersionError(ast.releases, ast) - errs += ast.errors - - if errs: - ErrOut.Log("Failed version test.") - else: - InfoOut.Log("Passed version test.") - return errs - - -default_dirs = ['.', 'trusted', 'dev', 'private'] -def ParseFiles(filenames): - parser = IDLParser() - filenodes = [] - - if not filenames: - filenames = [] - srcroot = GetOption('srcroot') - dirs = default_dirs - if GetOption('include_private'): - dirs += ['private'] - for dirname in dirs: - srcdir = os.path.join(srcroot, dirname, '*.idl') - srcdir = os.path.normpath(srcdir) - filenames += sorted(glob.glob(srcdir)) - - if not filenames: - ErrOut.Log('No sources provided.') - - for filename in filenames: - filenode = parser.ParseFile(filename) - filenodes.append(filenode) - - ast = IDLAst(filenodes) - if GetOption('dump_tree'): ast.Dump(0) - - Lint(ast) - return ast - - -def Main(args): - filenames = ParseOptions(args) - - # If testing... - if GetOption('test'): - errs = TestErrorFiles(filenames) - errs = TestNamespaceFiles(filenames) - errs = TestVersionFiles(filenames) - if errs: - ErrOut.Log("Parser failed with %d errors." % errs) - return -1 - return 0 - - # Otherwise, build the AST - ast = ParseFiles(filenames) - errs = ast.GetProperty('ERRORS') - if errs: - ErrOut.Log('Found %d error(s).' % errs); - InfoOut.Log("%d files processed." % len(filenames)) - return errs - - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_propertynode.py b/generators/idl_propertynode.py deleted file mode 100755 index 8739453..0000000 --- a/generators/idl_propertynode.py +++ /dev/null
@@ -1,113 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Hierarchical property system for IDL AST """ -import re -import sys - -from idl_log import ErrOut, InfoOut, WarnOut - -# -# IDLPropertyNode -# -# A property node is a hierarchically aware system for mapping -# keys to values, such that a local dictionary is search first, -# followed by parent dictionaries in order. -# -class IDLPropertyNode(object): - def __init__(self): - self.parents = [] - self.property_map = {} - - def AddParent(self, parent): - assert parent - self.parents.append(parent) - - def SetProperty(self, name, val): - self.property_map[name] = val - - def GetProperty(self, name): - # Check locally for the property, and return it if found. - prop = self.property_map.get(name, None) - if prop is not None: - return prop - # If not, seach parents in order - for parent in self.parents: - prop = parent.GetProperty(name) - if prop is not None: - return prop - # Otherwise, it can not be found. - return None - - def GetPropertyLocal(self, name): - # Search for the property, but only locally. - return self.property_map.get(name, None) - - def GetPropertyList(self): - return self.property_map.keys() - -# -# Testing functions -# - -# Build a property node, setting the properties including a name, and -# associate the children with this new node. -# -def BuildNode(name, props, children=None, parents=None): - node = IDLPropertyNode() - node.SetProperty('NAME', name) - for prop in props: - toks = prop.split('=') - node.SetProperty(toks[0], toks[1]) - if children: - for child in children: - child.AddParent(node) - if parents: - for parent in parents: - node.AddParent(parent) - return node - -def ExpectProp(node, name, val): - found = node.GetProperty(name) - if found != val: - ErrOut.Log('Got property %s expecting %s' % (found, val)) - return 1 - return 0 - -# -# Verify property inheritance -# -def PropertyTest(): - errors = 0 - left = BuildNode('Left', ['Left=Left']) - right = BuildNode('Right', ['Right=Right']) - top = BuildNode('Top', ['Left=Top', 'Right=Top'], [left, right]) - - errors += ExpectProp(top, 'Left', 'Top') - errors += ExpectProp(top, 'Right', 'Top') - - errors += ExpectProp(left, 'Left', 'Left') - errors += ExpectProp(left, 'Right', 'Top') - - errors += ExpectProp(right, 'Left', 'Top') - errors += ExpectProp(right, 'Right', 'Right') - - if not errors: - InfoOut.Log('Passed PropertyTest') - return errors - - -def Main(): - errors = 0 - errors += PropertyTest() - - if errors: - ErrOut.Log('IDLNode failed with %d errors.' % errors) - return -1 - return 0 - - -if __name__ == '__main__': - sys.exit(Main())
diff --git a/generators/idl_release.py b/generators/idl_release.py deleted file mode 100755 index 9a93054..0000000 --- a/generators/idl_release.py +++ /dev/null
@@ -1,357 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -IDLRelease for PPAPI - -This file defines the behavior of the AST namespace which allows for resolving -a symbol as one or more AST nodes given a Release or range of Releases. -""" - -from __future__ import print_function - -import sys - -from idl_log import ErrOut, InfoOut, WarnOut -from idl_option import GetOption, Option, ParseOptions - -Option('release_debug', 'Debug Release data') -Option('wgap', 'Ignore Release gap warning') - - -# -# Module level functions and data used for testing. -# -error = None -warning = None -def ReportReleaseError(msg): - global error - error = msg - -def ReportReleaseWarning(msg): - global warning - warning = msg - -def ReportClear(): - global error, warning - error = None - warning = None - -# -# IDLRelease -# -# IDLRelease is an object which stores the association of a given symbol -# name, with an AST node for a range of Releases for that object. -# -# A vmin value of None indicates that the object begins at the earliest -# available Release number. The value of vmin is always inclusive. - -# A vmax value of None indicates that the object is never deprecated, so -# it exists until it is overloaded or until the latest available Release. -# The value of vmax is always exclusive, representing the first Release -# on which the object is no longer valid. -class IDLRelease(object): - def __init__(self, rmin, rmax): - self.rmin = rmin - self.rmax = rmax - - def __str__(self): - if not self.rmin: - rmin = '0' - else: - rmin = str(self.rmin) - if not self.rmax: - rmax = '+oo' - else: - rmax = str(self.rmax) - return '[%s,%s)' % (rmin, rmax) - - def SetReleaseRange(self, rmin, rmax): - self.rmin = rmin - self.rmax = rmax - - # True, if Release falls within the interval [self.vmin, self.vmax) - def IsRelease(self, release): - if self.rmax and self.rmax <= release: - return False - if self.rmin and self.rmin > release: - return False - if GetOption('release_debug'): - InfoOut.Log('%f is in %s' % (release, self)) - return True - - # True, if Release falls within the interval [self.vmin, self.vmax) - def InReleases(self, releases): - if not releases: return False - - # Check last release first, since InRange does not match last item - if self.IsRelease(releases[-1]): return True - if len(releases) > 1: - return self.InRange(releases[0], releases[-1]) - return False - - # True, if interval [vmin, vmax) overlaps interval [self.vmin, self.vmax) - def InRange(self, rmin, rmax): - assert (rmin == None) or rmin < rmax - - # An min of None always passes a min bound test - # An max of None always passes a max bound test - if rmin is not None and self.rmax is not None: - if self.rmax <= rmin: - return False - if rmax is not None and self.rmin is not None: - if self.rmin >= rmax: - return False - - if GetOption('release_debug'): - InfoOut.Log('%f to %f is in %s' % (rmin, rmax, self)) - return True - - def GetMinMax(self, releases = None): - if not releases: - return self.rmin, self.rmax - - if not self.rmin: - rmin = releases[0] - else: - rmin = str(self.rmin) - if not self.rmax: - rmax = releases[-1] - else: - rmax = str(self.rmax) - return (rmin, rmax) - - def SetMin(self, release): - assert not self.rmin - self.rmin = release - - def Error(self, msg): - ReportReleaseError(msg) - - def Warn(self, msg): - ReportReleaseWarning(msg) - - -# -# IDLReleaseList -# -# IDLReleaseList is a list based container for holding IDLRelease -# objects in order. The IDLReleaseList can be added to, and searched by -# range. Objects are stored in order, and must be added in order. -# -class IDLReleaseList(object): - def __init__(self): - self._nodes = [] - - def GetReleases(self): - return self._nodes - - def FindRelease(self, release): - for node in self._nodes: - if node.IsRelease(release): - return node - return None - - def FindRange(self, rmin, rmax): - assert (rmin == None) or rmin != rmax - - out = [] - for node in self._nodes: - if node.InRange(rmin, rmax): - out.append(node) - return out - - def AddNode(self, node): - if GetOption('release_debug'): - InfoOut.Log('\nAdding %s %s' % (node.Location(), node)) - last = None - - # Check current releases in that namespace - for cver in self._nodes: - if GetOption('release_debug'): InfoOut.Log(' Checking %s' % cver) - - # We should only be missing a 'release' tag for the first item. - if not node.rmin: - node.Error('Missing release on overload of previous %s.' % - cver.Location()) - return False - - # If the node has no max, then set it to this one - if not cver.rmax: - cver.rmax = node.rmin - if GetOption('release_debug'): InfoOut.Log(' Update %s' % cver) - - # if the max and min overlap, than's an error - if cver.rmax > node.rmin: - if node.rmax and cver.rmin >= node.rmax: - node.Error('Declarations out of order.') - else: - node.Error('Overlap in releases: %s vs %s when adding %s' % - (cver.rmax, node.rmin, node)) - return False - last = cver - - # Otherwise, the previous max and current min should match - # unless this is the unlikely case of something being only - # temporarily deprecated. - if last and last.rmax != node.rmin: - node.Warn('Gap in release numbers.') - - # If we made it here, this new node must be the 'newest' - # and does not overlap with anything previously added, so - # we can add it to the end of the list. - if GetOption('release_debug'): InfoOut.Log('Done %s' % node) - self._nodes.append(node) - return True - -# -# IDLReleaseMap -# -# A release map, can map from an float interface release, to a global -# release string. -# -class IDLReleaseMap(object): - def __init__(self, release_info): - self.version_to_release = {} - self.release_to_version = {} - self.release_to_channel = {} - for release, version, channel in release_info: - self.version_to_release[version] = release - self.release_to_version[release] = version - self.release_to_channel[release] = channel - self.releases = sorted(self.release_to_version.keys()) - self.versions = sorted(self.version_to_release.keys()) - - def GetVersion(self, release): - return self.release_to_version.get(release, None) - - def GetVersions(self): - return self.versions - - def GetRelease(self, version): - return self.version_to_release.get(version, None) - - def GetReleases(self): - return self.releases - - def GetReleaseRange(self): - return (self.releases[0], self.releases[-1]) - - def GetVersionRange(self): - return (self.versions[0], self.version[-1]) - - def GetChannel(self, release): - return self.release_to_channel.get(release, None) - -# -# Test Code -# -def TestReleaseNode(): - FooXX = IDLRelease(None, None) - Foo1X = IDLRelease('M14', None) - Foo23 = IDLRelease('M15', 'M16') - - assert FooXX.IsRelease('M13') - assert FooXX.IsRelease('M14') - assert FooXX.InRange('M13', 'M13A') - assert FooXX.InRange('M14','M15') - - assert not Foo1X.IsRelease('M13') - assert Foo1X.IsRelease('M14') - assert Foo1X.IsRelease('M15') - - assert not Foo1X.InRange('M13', 'M14') - assert not Foo1X.InRange('M13A', 'M14') - assert Foo1X.InRange('M14', 'M15') - assert Foo1X.InRange('M15', 'M16') - - assert not Foo23.InRange('M13', 'M14') - assert not Foo23.InRange('M13A', 'M14') - assert not Foo23.InRange('M14', 'M15') - assert Foo23.InRange('M15', 'M16') - assert Foo23.InRange('M14', 'M15A') - assert Foo23.InRange('M15B', 'M17') - assert not Foo23.InRange('M16', 'M17') - print("TestReleaseNode - Passed") - - -def TestReleaseListWarning(): - FooXX = IDLRelease(None, None) - Foo1X = IDLRelease('M14', None) - Foo23 = IDLRelease('M15', 'M16') - Foo45 = IDLRelease('M17', 'M18') - - # Add nodes out of order should fail - ReportClear() - releases = IDLReleaseList() - assert releases.AddNode(Foo23) - assert releases.AddNode(Foo45) - assert warning - print("TestReleaseListWarning - Passed") - - -def TestReleaseListError(): - FooXX = IDLRelease(None, None) - Foo1X = IDLRelease('M14', None) - Foo23 = IDLRelease('M15', 'M16') - Foo45 = IDLRelease('M17', 'M18') - - # Add nodes out of order should fail - ReportClear() - releases = IDLReleaseList() - assert releases.AddNode(FooXX) - assert releases.AddNode(Foo23) - assert not releases.AddNode(Foo1X) - assert error - print("TestReleaseListError - Passed") - - -def TestReleaseListOK(): - FooXX = IDLRelease(None, None) - Foo1X = IDLRelease('M14', None) - Foo23 = IDLRelease('M15', 'M16') - Foo45 = IDLRelease('M17', 'M18') - - # Add nodes in order should work - ReportClear() - releases = IDLReleaseList() - assert releases.AddNode(FooXX) - assert releases.AddNode(Foo1X) - assert releases.AddNode(Foo23) - assert not error and not warning - assert releases.AddNode(Foo45) - assert warning - - assert releases.FindRelease('M13') == FooXX - assert releases.FindRelease('M14') == Foo1X - assert releases.FindRelease('M15') == Foo23 - assert releases.FindRelease('M16') == None - assert releases.FindRelease('M17') == Foo45 - assert releases.FindRelease('M18') == None - - assert releases.FindRange('M13','M14') == [FooXX] - assert releases.FindRange('M13','M17') == [FooXX, Foo1X, Foo23] - assert releases.FindRange('M16','M17') == [] - assert releases.FindRange(None, None) == [FooXX, Foo1X, Foo23, Foo45] - - # Verify we can find the correct versions - print("TestReleaseListOK - Passed") - - -def TestReleaseMap(): - print("TestReleaseMap- Passed") - - -def Main(args): - TestReleaseNode() - TestReleaseListWarning() - TestReleaseListError() - TestReleaseListOK() - print("Passed") - return 0 - - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:]))
diff --git a/generators/idl_tests.py b/generators/idl_tests.py deleted file mode 100755 index 5bf61bc..0000000 --- a/generators/idl_tests.py +++ /dev/null
@@ -1,46 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Test runner for IDL Generator changes """ - -from __future__ import print_function - -import subprocess -import sys - -def TestIDL(testname, args): - print('\nRunning unit tests for %s.' % testname) - try: - args = [sys.executable, testname] + args - subprocess.check_call(args) - return 0 - except subprocess.CalledProcessError as err: - print('Failed with %s.' % str(err)) - return 1 - -def main(args): - errors = 0 - errors += TestIDL('idl_lexer.py', ['--test']) - assert errors == 0 - errors += TestIDL('idl_parser.py', ['--test']) - assert errors == 0 - errors += TestIDL('idl_c_header.py', []) - assert errors == 0 - errors += TestIDL('idl_c_proto.py', ['--wnone', '--test']) - assert errors == 0 - errors += TestIDL('idl_gen_pnacl.py', ['--wnone', '--test']) - assert errors == 0 - errors += TestIDL('idl_namespace.py', []) - assert errors == 0 - errors += TestIDL('idl_node.py', []) - assert errors == 0 - - if errors: - print('\nFailed tests.') - return errors - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:]))
diff --git a/generators/idl_thunk.py b/generators/idl_thunk.py deleted file mode 100755 index 3d5d731..0000000 --- a/generators/idl_thunk.py +++ /dev/null
@@ -1,586 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Generator for C++ style thunks """ - -from __future__ import print_function - -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 - -Option('thunkroot', 'Base directory of output', - default=os.path.join('..', 'thunk')) - - -class TGenError(Exception): - def __init__(self, msg): - self.value = msg - - def __str__(self): - return repr(self.value) - - -class ThunkBodyMetadata(object): - """Metadata about thunk body. Used for selecting which headers to emit.""" - def __init__(self): - self._apis = set() - self._builtin_includes = set() - self._includes = set() - - def AddApi(self, api): - self._apis.add(api) - - def Apis(self): - return self._apis - - def AddInclude(self, include): - self._includes.add(include) - - def Includes(self): - return self._includes - - def AddBuiltinInclude(self, include): - self._builtin_includes.add(include) - - def BuiltinIncludes(self): - return self._builtin_includes - - -def _GetBaseFileName(filenode): - """Returns the base name for output files, given the filenode. - - Examples: - 'dev/ppb_find_dev.h' -> 'ppb_find_dev' - 'trusted/ppb_buffer_trusted.h' -> 'ppb_buffer_trusted' - """ - path, name = os.path.split(filenode.GetProperty('NAME')) - name = os.path.splitext(name)[0] - return name - - -def _GetHeaderFileName(filenode): - """Returns the name for the header for this file.""" - path, name = os.path.split(filenode.GetProperty('NAME')) - name = os.path.splitext(name)[0] - if path: - header = "ppapi/c/%s/%s.h" % (path, name) - else: - header = "ppapi/c/%s.h" % name - return header - - -def _GetThunkFileName(filenode, relpath): - """Returns the thunk file name.""" - path = os.path.split(filenode.GetProperty('NAME'))[0] - name = _GetBaseFileName(filenode) - # We don't reattach the path for thunk. - if relpath: name = os.path.join(relpath, name) - name = '%s%s' % (name, '_thunk.cc') - return name - - -def _StripFileName(filenode): - """Strips path and dev, trusted, and private suffixes from the file name.""" - api_basename = _GetBaseFileName(filenode) - if api_basename.endswith('_dev'): - api_basename = api_basename[:-len('_dev')] - if api_basename.endswith('_trusted'): - api_basename = api_basename[:-len('_trusted')] - if api_basename.endswith('_private'): - api_basename = api_basename[:-len('_private')] - return api_basename - - -def _StripApiName(api_name): - """Strips Dev, Private, and Trusted suffixes from the API name.""" - if api_name.endswith('Trusted'): - api_name = api_name[:-len('Trusted')] - if api_name.endswith('_Dev'): - api_name = api_name[:-len('_Dev')] - if api_name.endswith('_Private'): - api_name = api_name[:-len('_Private')] - return api_name - - -def _MakeEnterLine(filenode, interface, member, arg, handle_errors, callback, - meta): - """Returns an EnterInstance/EnterResource string for a function.""" - api_name = _StripApiName(interface.GetName()) + '_API' - if member.GetProperty('api'): # Override API name. - manually_provided_api = True - # TODO(teravest): Automatically guess the API header file. - api_name = member.GetProperty('api') - else: - manually_provided_api = False - - if arg[0] == 'PP_Instance': - if callback is None: - arg_string = arg[1] - else: - arg_string = '%s, %s' % (arg[1], callback) - if interface.GetProperty('singleton') or member.GetProperty('singleton'): - if not manually_provided_api: - meta.AddApi('ppapi/thunk/%s_api.h' % _StripFileName(filenode)) - return 'EnterInstanceAPI<%s> enter(%s);' % (api_name, arg_string) - else: - return 'EnterInstance enter(%s);' % arg_string - elif arg[0] == 'PP_Resource': - enter_type = 'EnterResource<%s>' % api_name - if not manually_provided_api: - meta.AddApi('ppapi/thunk/%s_api.h' % _StripFileName(filenode)) - if callback is None: - return '%s enter(%s, %s);' % (enter_type, arg[1], - str(handle_errors).lower()) - else: - return '%s enter(%s, %s, %s);' % (enter_type, arg[1], - callback, - str(handle_errors).lower()) - else: - raise TGenError("Unknown type for _MakeEnterLine: %s" % arg[0]) - - -def _GetShortName(interface, filter_suffixes): - """Return a shorter interface name that matches Is* and Create* functions.""" - parts = interface.GetName().split('_')[1:] - tail = parts[len(parts) - 1] - if tail in filter_suffixes: - parts = parts[:-1] - return ''.join(parts) - - -def _IsTypeCheck(interface, node, args): - """Returns true if node represents a type-checking function.""" - if len(args) == 0 or args[0][0] != 'PP_Resource': - return False - return node.GetName() == 'Is%s' % _GetShortName(interface, ['Dev', 'Private']) - - -def _GetCreateFuncName(interface): - """Returns the creation function name for an interface.""" - return 'Create%s' % _GetShortName(interface, ['Dev']) - - -def _GetDefaultFailureValue(t): - """Returns the default failure value for a given type. - - Returns None if no default failure value exists for the type. - """ - values = { - 'PP_Bool': 'PP_FALSE', - 'PP_Resource': '0', - 'struct PP_Var': 'PP_MakeUndefined()', - 'float': '0.0f', - 'int32_t': 'enter.retval()', - 'uint16_t': '0', - 'uint32_t': '0', - 'uint64_t': '0', - 'void*': 'NULL' - } - if t in values: - return values[t] - return None - - -def _MakeCreateMemberBody(interface, member, args): - """Returns the body of a Create() function. - - Args: - interface - IDLNode for the interface - member - IDLNode for member function - args - List of arguments for the Create() function - """ - if args[0][0] == 'PP_Resource': - body = 'Resource* object =\n' - body += ' PpapiGlobals::Get()->GetResourceTracker()->' - body += 'GetResource(%s);\n' % args[0][1] - body += 'if (!object)\n' - body += ' return 0;\n' - body += 'EnterResourceCreation enter(object->pp_instance());\n' - elif args[0][0] == 'PP_Instance': - body = 'EnterResourceCreation enter(%s);\n' % args[0][1] - else: - raise TGenError('Unknown arg type for Create(): %s' % args[0][0]) - - body += 'if (enter.failed())\n' - body += ' return 0;\n' - arg_list = ', '.join([a[1] for a in args]) - if member.GetProperty('create_func'): - create_func = member.GetProperty('create_func') - else: - create_func = _GetCreateFuncName(interface) - body += 'return enter.functions()->%s(%s);' % (create_func, - arg_list) - return body - - -def _GetOutputParams(member, release): - """Returns output parameters (and their types) for a member function. - - Args: - member - IDLNode for the member function - release - Release to get output parameters for - Returns: - A list of name strings for all output parameters of the member - function. - """ - out_params = [] - callnode = member.GetOneOf('Callspec') - if callnode: - cgen = CGen() - for param in callnode.GetListOf('Param'): - mode = cgen.GetParamMode(param) - if mode == 'out': - # We use the 'store' mode when getting the parameter type, since we - # need to call sizeof() for memset(). - _, pname, _, _ = cgen.GetComponents(param, release, 'store') - out_params.append(pname) - return out_params - - -def _MakeNormalMemberBody(filenode, release, node, member, rtype, args, - include_version, meta): - """Returns the body of a typical function. - - Args: - filenode - IDLNode for the file - release - release to generate body for - node - IDLNode for the interface - member - IDLNode for the member function - rtype - Return type for the member function - args - List of 4-tuple arguments for the member function - include_version - whether to include the version in the invocation - meta - ThunkBodyMetadata for header hints - """ - if len(args) == 0: - # Calling into the "Shared" code for the interface seems like a reasonable - # heuristic when we don't have any arguments; some thunk code follows this - # convention today. - meta.AddApi('ppapi/shared_impl/%s_shared.h' % _StripFileName(filenode)) - return 'return %s::%s();' % (_StripApiName(node.GetName()) + '_Shared', - member.GetName()) - - is_callback_func = args[len(args) - 1][0] == 'struct PP_CompletionCallback' - - if is_callback_func: - call_args = args[:-1] + [('', 'enter.callback()', '', '')] - meta.AddInclude('ppapi/c/pp_completion_callback.h') - else: - call_args = args - - if args[0][0] == 'PP_Instance': - call_arglist = ', '.join(a[1] for a in call_args) - function_container = 'functions' - elif args[0][0] == 'PP_Resource': - call_arglist = ', '.join(a[1] for a in call_args[1:]) - function_container = 'object' - else: - # Calling into the "Shared" code for the interface seems like a reasonable - # heuristic when the first argument isn't a PP_Instance or a PP_Resource; - # some thunk code follows this convention today. - meta.AddApi('ppapi/shared_impl/%s_shared.h' % _StripFileName(filenode)) - return 'return %s::%s(%s);' % (_StripApiName(node.GetName()) + '_Shared', - member.GetName(), - ', '.join(a[1] for a in args)) - - function_name = member.GetName() - if include_version: - version = node.GetVersion(release).replace('.', '_') - function_name += version - - invocation = 'enter.%s()->%s(%s)' % (function_container, - function_name, - call_arglist) - - handle_errors = not (member.GetProperty('report_errors') == 'False') - out_params = _GetOutputParams(member, release) - if is_callback_func: - body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], - handle_errors, args[len(args) - 1][1], meta) - failure_value = member.GetProperty('on_failure') - if failure_value is None: - failure_value = 'enter.retval()' - failure_return = 'return %s;' % failure_value - success_return = 'return enter.SetResult(%s);' % invocation - elif rtype == 'void': - body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], - handle_errors, None, meta) - failure_return = 'return;' - success_return = '%s;' % invocation # We don't return anything for void. - else: - body = '%s\n' % _MakeEnterLine(filenode, node, member, args[0], - handle_errors, None, meta) - failure_value = member.GetProperty('on_failure') - if failure_value is None: - failure_value = _GetDefaultFailureValue(rtype) - if failure_value is None: - raise TGenError('There is no default value for rtype %s. ' - 'Maybe you should provide an on_failure attribute ' - 'in the IDL file.' % rtype) - failure_return = 'return %s;' % failure_value - success_return = 'return %s;' % invocation - - if member.GetProperty('always_set_output_parameters'): - body += 'if (enter.failed()) {\n' - for param in out_params: - body += ' memset(%s, 0, sizeof(*%s));\n' % (param, param) - body += ' %s\n' % failure_return - body += '}\n' - body += '%s' % success_return - meta.AddBuiltinInclude('string.h') - else: - body += 'if (enter.failed())\n' - body += ' %s\n' % failure_return - body += '%s' % success_return - return body - - -def DefineMember(filenode, node, member, release, include_version, meta): - """Returns a definition for a member function of an interface. - - Args: - filenode - IDLNode for the file - node - IDLNode for the interface - member - IDLNode for the member function - release - release to generate - include_version - include the version in emitted function name. - meta - ThunkMetadata for header hints - Returns: - A string with the member definition. - """ - cgen = CGen() - rtype, name, arrays, args = cgen.GetComponents(member, release, 'return') - log_body = '\"%s::%s()\";' % (node.GetName(), - cgen.GetStructName(member, release, - include_version)) - if len(log_body) > 69: # Prevent lines over 80 characters. - body = 'VLOG(4) <<\n' - body += ' %s\n' % log_body - else: - body = 'VLOG(4) << %s\n' % log_body - - if _IsTypeCheck(node, member, args): - body += '%s\n' % _MakeEnterLine(filenode, node, member, args[0], False, - None, meta) - body += 'return PP_FromBool(enter.succeeded());' - elif member.GetName() == 'Create' or member.GetName() == 'CreateTrusted': - body += _MakeCreateMemberBody(node, member, args) - else: - body += _MakeNormalMemberBody(filenode, release, node, member, rtype, args, - include_version, meta) - - signature = cgen.GetSignature(member, release, 'return', func_as_ptr=False, - include_version=include_version) - return '%s\n%s\n}' % (cgen.Indent('%s {' % signature, tabs=0), - cgen.Indent(body, tabs=1)) - - -def _IsNewestMember(member, members, releases): - """Returns true if member is the newest node with its name in members. - - Currently, every node in the AST only has one version. This means that we - will have two sibling nodes with the same name to represent different - versions. - See http://crbug.com/157017 . - - Special handling is required for nodes which share their name with others, - but aren't the newest version in the IDL. - - Args: - member - The member which is checked if it's newest - members - The list of members to inspect - releases - The set of releases to check for versions in. - """ - build_list = member.GetUniqueReleases(releases) - release = build_list[0] # Pick the oldest release. - same_name_siblings = filter( - lambda n: str(n) == str(member) and n != member, members) - - for s in same_name_siblings: - sibling_build_list = s.GetUniqueReleases(releases) - sibling_release = sibling_build_list[0] - if sibling_release > release: - return False - return True - - -class TGen(GeneratorByFile): - def __init__(self): - Generator.__init__(self, 'Thunk', 'tgen', 'Generate the C++ thunk.') - - def GenerateFile(self, filenode, releases, options): - savename = _GetThunkFileName(filenode, GetOption('thunkroot')) - 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 - do_generate = filenode.GetProperty('generate_thunk') - if not do_generate: - return False - - thunk_out = IDLOutFile(savename) - body, meta = self.GenerateBody(thunk_out, filenode, releases, options) - # TODO(teravest): How do we handle repeated values? - if filenode.GetProperty('thunk_include'): - meta.AddInclude(filenode.GetProperty('thunk_include')) - self.WriteHead(thunk_out, filenode, releases, options, meta) - thunk_out.Write('\n\n'.join(body)) - self.WriteTail(thunk_out, filenode, releases, options) - thunk_out.ClangFormat() - return thunk_out.Close() - - def WriteHead(self, out, filenode, releases, options, meta): - __pychecker__ = 'unusednames=options' - cgen = CGen() - - cright_node = filenode.GetChildren()[0] - assert(cright_node.IsA('Copyright')) - out.Write('%s\n' % cgen.Copyright(cright_node, cpp_style=True)) - - from_text = 'From %s' % ( - filenode.GetProperty('NAME').replace(os.sep,'/')) - modified_text = 'modified %s.' % ( - filenode.GetProperty('DATETIME')) - out.Write('// %s %s\n\n' % (from_text, modified_text)) - - meta.AddBuiltinInclude('stdint.h') - if meta.BuiltinIncludes(): - for include in sorted(meta.BuiltinIncludes()): - out.Write('#include <%s>\n' % include) - out.Write('\n') - - # TODO(teravest): Don't emit includes we don't need. - includes = ['ppapi/c/pp_errors.h', - 'ppapi/shared_impl/tracked_callback.h', - 'ppapi/thunk/enter.h', - 'ppapi/thunk/ppapi_thunk_export.h'] - includes.append(_GetHeaderFileName(filenode)) - for api in meta.Apis(): - includes.append('%s' % api.lower()) - for i in meta.Includes(): - includes.append(i) - for include in sorted(includes): - out.Write('#include "%s"\n' % include) - out.Write('\n') - out.Write('namespace ppapi {\n') - out.Write('namespace thunk {\n') - out.Write('\n') - out.Write('namespace {\n') - out.Write('\n') - - def GenerateBody(self, out, filenode, releases, options): - """Generates a member function lines to be written and metadata. - - Returns a tuple of (body, meta) where: - body - a list of lines with member function bodies - meta - a ThunkMetadata instance for hinting which headers are needed. - """ - __pychecker__ = 'unusednames=options' - out_members = [] - meta = ThunkBodyMetadata() - for node in filenode.GetListOf('Interface'): - # Skip if this node is not in this release - if not node.InReleases(releases): - print("Skipping %s" % node) - continue - - # Generate Member functions - if node.IsA('Interface'): - members = node.GetListOf('Member') - for child in members: - build_list = child.GetUniqueReleases(releases) - # We have to filter out releases this node isn't in. - build_list = filter(lambda r: child.InReleases([r]), build_list) - if len(build_list) == 0: - continue - release = build_list[-1] - include_version = not _IsNewestMember(child, members, releases) - member = DefineMember(filenode, node, child, release, include_version, - meta) - if not member: - continue - out_members.append(member) - return (out_members, meta) - - def WriteTail(self, out, filenode, releases, options): - __pychecker__ = 'unusednames=options' - cgen = CGen() - - version_list = [] - out.Write('\n\n') - for node in filenode.GetListOf('Interface'): - build_list = node.GetUniqueReleases(releases) - for build in build_list: - version = node.GetVersion(build).replace('.', '_') - thunk_name = 'g_' + node.GetName().lower() + '_thunk_' + \ - version - thunk_type = '_'.join((node.GetName(), version)) - version_list.append((thunk_type, thunk_name)) - - out.Write('const %s %s = {\n' % (thunk_type, thunk_name)) - generated_functions = [] - members = node.GetListOf('Member') - for child in members: - rtype, name, arrays, args = cgen.GetComponents( - child, build, 'return') - if child.InReleases([build]): - if not _IsNewestMember(child, members, releases): - version = child.GetVersion( - child.first_release[build]).replace('.', '_') - name += '_' + version - generated_functions.append(name) - out.Write(',\n'.join([' &%s' % f for f in generated_functions])) - out.Write('\n};\n\n') - - out.Write('} // namespace\n') - out.Write('\n') - for thunk_type, thunk_name in version_list: - out.Write('PPAPI_THUNK_EXPORT const %s* Get%s_Thunk() {\n' % - (thunk_type, thunk_type)) - out.Write(' return &%s;\n' % thunk_name) - out.Write('}\n') - out.Write('\n') - out.Write('} // namespace thunk\n') - out.Write('} // namespace ppapi\n') - - -tgen = TGen() - - -def Main(args): - # Default invocation will verify the golden files are unchanged. - failed = 0 - if not args: - args = ['--wnone', '--diff', '--test', '--thunkroot=.'] - - ParseOptions(args) - - idldir = os.path.split(sys.argv[0])[0] - idldir = os.path.join(idldir, 'test_thunk', '*.idl') - filenames = glob.glob(idldir) - ast = ParseFiles(filenames) - if tgen.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:]))
diff --git a/generators/idl_visitor.py b/generators/idl_visitor.py deleted file mode 100644 index 605cd86..0000000 --- a/generators/idl_visitor.py +++ /dev/null
@@ -1,45 +0,0 @@ -# Copyright 2012 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" Visitor Object for traversing AST """ - -# -# IDLVisitor -# -# The IDLVisitor class will traverse an AST truncating portions of the tree -# when 'VisitFilter' returns false. After the filter returns true, for each -# node, the visitor will call the 'Arrive' member passing in the node and -# and generic data object from the parent call. The returned value is then -# passed to all children who's results are aggregated into a list. The child -# results along with the original Arrive result are passed to the Depart -# function which returns the final result of the Visit. By default this is -# the exact value that was return from the original arrive. -# - -class IDLVisitor(object): - def __init__(self): - pass - - # Return TRUE if the node should be visited - def VisitFilter(self, node, data): - return True - - def Visit(self, node, data): - if not self.VisitFilter(node, data): return None - - childdata = [] - newdata = self.Arrive(node, data) - for child in node.GetChildren(): - ret = self.Visit(child, newdata) - if ret is not None: - childdata.append(ret) - return self.Depart(node, newdata, childdata) - - def Arrive(self, node, data): - __pychecker__ = 'unusednames=node' - return data - - def Depart(self, node, data, childdata): - __pychecker__ = 'unusednames=node,childdata' - return data
diff --git a/generators/test_cgen/enum_typedef.h b/generators/test_cgen/enum_typedef.h deleted file mode 100644 index 5399f59..0000000 --- a/generators/test_cgen/enum_typedef.h +++ /dev/null
@@ -1,69 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From test_cgen/enum_typedef.idl modified Wed Dec 5 13:08:05 2012. */ - -#ifndef PPAPI_C_TEST_CGEN_ENUM_TYPEDEF_H_ -#define PPAPI_C_TEST_CGEN_ENUM_TYPEDEF_H_ - -#include "ppapi/c/pp_macros.h" -#include "ppapi/c/test_cgen/stdint.h" - -/** - * @file - * This file will test that the IDL snippet matches the comment. - */ - - -/** - * @addtogroup Enums - * @{ - */ -/* typedef enum { A = 1, B = 2, C = 3, D = A + B, E = ~D } et1; */ -typedef enum { - A = 1, - B = 2, - C = 3, - D = A + B, - E = ~D -} et1; -/** - * @} - */ - -/** - * @addtogroup Typedefs - * @{ - */ -/* typedef int32_t i; */ -typedef int32_t i; - -/* typedef int32_t i2[3]; */ -typedef int32_t i2[3]; - -/* typedef int32_t (*i_func)(void); */ -typedef int32_t (*i_func)(void); - -/* typedef int32_t (*i_func_i)(int32_t i); */ -typedef int32_t (*i_func_i)(int32_t i); - -/* typedef et1 et4[4]; */ -typedef et1 et4[4]; - -/* - * typedef int8_t (*PPB_Audio_Callback)(const void* sample_buffer, - * uint32_t buffer_size_in_bytes, - * const void* user_data); - */ -typedef int8_t (*PPB_Audio_Callback)(const void* sample_buffer, - uint32_t buffer_size_in_bytes, - const void* user_data); -/** - * @} - */ - -#endif /* PPAPI_C_TEST_CGEN_ENUM_TYPEDEF_H_ */ -
diff --git a/generators/test_cgen/enum_typedef.idl b/generators/test_cgen/enum_typedef.idl deleted file mode 100644 index de508fa..0000000 --- a/generators/test_cgen/enum_typedef.idl +++ /dev/null
@@ -1,37 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file will test that the IDL snippet matches the comment. - */ - -/* typedef enum { A = 1, B = 2, C = 3, D = A + B, E = ~D } et1; */ -enum et1 { A=1, B=2, C=3, D=A+B, E=~D }; - -/* typedef int32_t i; */ -typedef int32_t i; - -/* typedef int32_t i2[3]; */ -typedef int32_t[3] i2; - -/* typedef int32_t (*i_func)(void); */ -typedef int32_t i_func(); - -/* typedef int32_t (*i_func_i)(int32_t i); */ -typedef int32_t i_func_i([in] int32_t i); - -/* typedef et1 et4[4]; */ -typedef et1[4] et4; - -/* - * typedef int8_t (*PPB_Audio_Callback)(const void* sample_buffer, - * uint32_t buffer_size_in_bytes, - * const void* user_data); - */ -typedef int8_t PPB_Audio_Callback([in] mem_t sample_buffer, - [in] uint32_t buffer_size_in_bytes, - [in] mem_t user_data); -
diff --git a/generators/test_cgen/interface.h b/generators/test_cgen/interface.h deleted file mode 100644 index 9486a0c..0000000 --- a/generators/test_cgen/interface.h +++ /dev/null
@@ -1,91 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From test_cgen/interface.idl modified Wed Nov 21 14:22:50 2012. */ - -#ifndef PPAPI_C_TEST_CGEN_INTERFACE_H_ -#define PPAPI_C_TEST_CGEN_INTERFACE_H_ - -#include "ppapi/c/pp_macros.h" -#include "ppapi/c/test_cgen/stdint.h" - -#define IFACEFOO_INTERFACE_1_0 "ifaceFoo;1.0" -#define IFACEFOO_INTERFACE IFACEFOO_INTERFACE_1_0 - -#define IFACEBAR_INTERFACE_1_0 "ifaceBar;1.0" -#define IFACEBAR_INTERFACE IFACEBAR_INTERFACE_1_0 - -/** - * @file - * This file will test that the IDL snippet matches the comment. - */ - - -/** - * @addtogroup Structs - * @{ - */ -/* struct ist { void* X; }; */ -struct ist { - void* X; -}; -/** - * @} - */ - -/** - * @addtogroup Interfaces - * @{ - */ -/* - * struct ifaceFoo_1_0 { - * int8_t (*mem1)(int16_t x, int32_t y); - * int32_t (*mem2)(const struct ist* a); - * int32_t (*mem3)(struct ist* b); - * int32_t (*mem4)(const void** ptr); - * int32_t (*mem5)(void** ptr); - * }; - * typedef struct ifaceFoo_1_0 ifaceFoo; - */ -struct ifaceFoo_1_0 { - int8_t (*mem1)(int16_t x, int32_t y); - int32_t (*mem2)(const struct ist* a); - int32_t (*mem3)(struct ist* b); - int32_t (*mem4)(const void** ptr); - int32_t (*mem5)(void** ptr); -}; - -typedef struct ifaceFoo_1_0 ifaceFoo; - -struct ifaceBar_1_0 { - int8_t (*testIface)(const struct ifaceFoo_1_0* foo, int32_t y); - struct ifaceFoo_1_0* (*createIface)(const char* name); -}; - -typedef struct ifaceBar_1_0 ifaceBar; - -struct ifaceNoString_1_0 { - void (*mem)(void); -}; - -typedef struct ifaceNoString_1_0 ifaceNoString; -/** - * @} - */ - -/** - * @addtogroup Structs - * @{ - */ -struct struct2 { - struct ifaceBar_1_0* bar; -}; -/** - * @} - */ - -#endif /* PPAPI_C_TEST_CGEN_INTERFACE_H_ */ -
diff --git a/generators/test_cgen/interface.idl b/generators/test_cgen/interface.idl deleted file mode 100644 index 66eb848..0000000 --- a/generators/test_cgen/interface.idl +++ /dev/null
@@ -1,52 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file will test that the IDL snippet matches the comment. - */ - -label Chrome { - M14 = 1.0, - M15 = 2.0 -}; -/* struct ist { void* X; }; */ -struct ist { - mem_t X; -}; - -/* - * struct ifaceFoo_1_0 { - * int8_t (*mem1)(int16_t x, int32_t y); - * int32_t (*mem2)(const struct ist* a); - * int32_t (*mem3)(struct ist* b); - * int32_t (*mem4)(const void** ptr); - * int32_t (*mem5)(void** ptr); - * }; - * typedef struct ifaceFoo_1_0 ifaceFoo; - */ -interface ifaceFoo { - int8_t mem1([in] int16_t x, [in] int32_t y); - int32_t mem2([in] ist a); - int32_t mem3([out] ist b); - int32_t mem4([in] blob_t ptr); - int32_t mem5([out] blob_t ptr); - [version=2.0] int32_t mem6([inout] blob_t ptr); -}; - -interface ifaceBar { - int8_t testIface([in] ifaceFoo foo, [in] int32_t y); - ifaceFoo createIface([in] str_t name); -}; - -[no_interface_string] -interface ifaceNoString { - void mem(); -}; - -struct struct2 { - ifaceBar bar; -}; -
diff --git a/generators/test_cgen/stdint.h b/generators/test_cgen/stdint.h deleted file mode 100644 index ca4ee07..0000000 --- a/generators/test_cgen/stdint.h +++ /dev/null
@@ -1,21 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From test_cgen/stdint.idl modified Thu Aug 18 16:20:46 2011. */ - -#ifndef PPAPI_C_TEST_CGEN_STDINT_H_ -#define PPAPI_C_TEST_CGEN_STDINT_H_ - -#include "ppapi/c/pp_macros.h" - -/** - * @file - * This file provides a definition of C99 sized types - * for Microsoft compilers. These definitions only apply - * for trusted modules. - */ - -#endif /* PPAPI_C_TEST_CGEN_STDINT_H_ */ -
diff --git a/generators/test_cgen/stdint.idl b/generators/test_cgen/stdint.idl deleted file mode 100644 index 6e4bd2c..0000000 --- a/generators/test_cgen/stdint.idl +++ /dev/null
@@ -1,54 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file provides a definition of C99 sized types - * for Microsoft compilers. These definitions only apply - * for trusted modules. - */ - -label Chrome { - M13 = 0.0, - M14 = 1.0, - M15 = 2.0 -}; - -[version=0.0] -describe { - /** Standard Ints. */ - int8_t; - int16_t; - int32_t; - int64_t; - uint8_t; - uint16_t; - uint32_t; - uint64_t; - /** Small and large floats. */ - double_t; - float_t; - - /** Native file handle (int). */ - handle_t; - - /** Interface object (void *). */ - interface_t; - - /** Used for padding, should be (u)int8_t */ - char; - - /** Pointer to memory (void *). */ - mem_t; - - /** Pointer to null terminated string (char *). */ - str_t; - - /** No return value. */ - void; - - /** Pointer to pointer to memory (void **). */ - blob_t; -}; -
diff --git a/generators/test_cgen/structs.h b/generators/test_cgen/structs.h deleted file mode 100644 index f16d55f..0000000 --- a/generators/test_cgen/structs.h +++ /dev/null
@@ -1,94 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From test_cgen/structs.idl modified Wed Nov 21 11:02:50 2012. */ - -#ifndef PPAPI_C_TEST_CGEN_STRUCTS_H_ -#define PPAPI_C_TEST_CGEN_STRUCTS_H_ - -#include "ppapi/c/pp_macros.h" -#include "ppapi/c/test_cgen/stdint.h" - -/** - * @file - * This file will test that the IDL snippet matches the comment. - */ - - -/** - * @addtogroup Typedefs - * @{ - */ -/* typedef uint8_t s_array[3]; */ -typedef uint8_t s_array[3]; -/** - * @} - */ - -/** - * @addtogroup Enums - * @{ - */ -/* typedef enum { esv1 = 1, esv2 = 2 } senum; */ -typedef enum { - esv1 = 1, - esv2 = 2 -} senum; -/** - * @} - */ - -/** - * @addtogroup Structs - * @{ - */ -/* struct st1 { int32_t i; senum j; }; */ -struct st1 { - int32_t i; - senum j; -}; - -/* struct st2 { s_array pixels[640][480]; }; */ -struct st2 { - s_array pixels[640][480]; -}; -/** - * @} - */ - -/** - * @addtogroup Typedefs - * @{ - */ -/* typedef float (*func_t)(const s_array data); */ -typedef float (*func_t)(const s_array data); - -/* typedef func_t (*findfunc_t)(const char* x); */ -typedef func_t (*findfunc_t)(const char* x); -/** - * @} - */ - -/** - * @addtogroup Structs - * @{ - */ -/* - * struct sfoo { - * s_array screen[480][640]; - * findfunc_t myfunc; - * }; - */ -struct sfoo { - s_array screen[480][640]; - findfunc_t myfunc; -}; -/** - * @} - */ - -#endif /* PPAPI_C_TEST_CGEN_STRUCTS_H_ */ -
diff --git a/generators/test_cgen/structs.idl b/generators/test_cgen/structs.idl deleted file mode 100644 index e0219d0..0000000 --- a/generators/test_cgen/structs.idl +++ /dev/null
@@ -1,50 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file will test that the IDL snippet matches the comment. - */ - -label Chrome { - M14=1.0 -}; - -/* typedef uint8_t s_array[3]; */ -typedef uint8_t[3] s_array; - -/* typedef enum { esv1 = 1, esv2 = 2 } senum; */ -enum senum { - esv1=1, - esv2=2 -}; - -/* struct st1 { int32_t i; senum j; }; */ -struct st1 { - int32_t i; - senum j; -}; - -/* struct st2 { s_array pixels[640][480]; }; */ -struct st2 { - s_array[640][480] pixels; -}; - -/* typedef float (*func_t)(const s_array data); */ -typedef float_t func_t([in] s_array data); - -/* typedef func_t (*findfunc_t)(const char* x); */ -typedef func_t findfunc_t([in] str_t x); - -/* - * struct sfoo { - * s_array screen[480][640]; - * findfunc_t myfunc; - * }; - */ -struct sfoo { - s_array[480][640] screen; - findfunc_t myfunc; -};
diff --git a/generators/test_cgen_range/dev_channel_interface.h b/generators/test_cgen_range/dev_channel_interface.h deleted file mode 100644 index 6abf32a..0000000 --- a/generators/test_cgen_range/dev_channel_interface.h +++ /dev/null
@@ -1,101 +0,0 @@ -/* Copyright 2013 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From test_cgen_range/dev_channel_interface.idl, - * modified Tue Dec 3 14:58:15 2013. - */ - -#ifndef PPAPI_C_TEST_CGEN_RANGE_DEV_CHANNEL_INTERFACE_H_ -#define PPAPI_C_TEST_CGEN_RANGE_DEV_CHANNEL_INTERFACE_H_ - -#include "ppapi/c/pp_macros.h" - -#define TESTDEV_INTERFACE_1_0 "TestDev;1.0" -#define TESTDEV_INTERFACE_1_2 "TestDev;1.2" -#define TESTDEV_INTERFACE_1_3 "TestDev;1.3" /* dev */ -#define TESTDEV_INTERFACE TESTDEV_INTERFACE_1_2 - -#define TESTDEVTOSTABLE_INTERFACE_1_0 "TestDevToStable;1.0" -#define TESTDEVTOSTABLE_INTERFACE_1_1 "TestDevToStable;1.1" /* dev */ -#define TESTDEVTOSTABLE_INTERFACE_1_2 "TestDevToStable;1.2" -#define TESTDEVTOSTABLE_INTERFACE TESTDEVTOSTABLE_INTERFACE_1_2 - -/** - * @file - */ - - -/** - * @addtogroup Interfaces - * @{ - */ -/** - * TestDev - */ -struct TestDev_1_3 { /* dev */ - /** - * TestDev1() - */ - void (*TestDev1)(void); - /** - * TestDev2() - */ - void (*TestDev2)(void); - /** - * TestDev3() - */ - void (*TestDev3)(void); - /** - * TestDev4() - */ - void (*TestDev4)(void); -}; - -struct TestDev_1_0 { - void (*TestDev1)(void); -}; - -struct TestDev_1_2 { - void (*TestDev1)(void); - void (*TestDev3)(void); -}; - -typedef struct TestDev_1_2 TestDev; - -/** - * TestDevToStable - */ -struct TestDevToStable_1_2 { - /** - * Foo() comment. - */ - void (*Foo)(int32_t x); - /** - * Bar() comment. - */ - void (*Bar)(int32_t x); - /** - * Baz() comment. - */ - void (*Baz)(int32_t x); -}; - -typedef struct TestDevToStable_1_2 TestDevToStable; - -struct TestDevToStable_1_0 { - void (*Foo)(int32_t x); -}; - -struct TestDevToStable_1_1 { /* dev */ - void (*Foo)(int32_t x); - void (*Bar)(int32_t x); - void (*Baz)(int32_t x); -}; -/** - * @} - */ - -#endif /* PPAPI_C_TEST_CGEN_RANGE_DEV_CHANNEL_INTERFACE_H_ */ -
diff --git a/generators/test_cgen_range/dev_channel_interface.idl b/generators/test_cgen_range/dev_channel_interface.idl deleted file mode 100644 index 3b41af2..0000000 --- a/generators/test_cgen_range/dev_channel_interface.idl +++ /dev/null
@@ -1,67 +0,0 @@ -/* Copyright 2013 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -label Chrome { - M13 = 1.0, - [channel=dev] M14 = 1.1, - M15 = 1.2, - [channel=dev] M16 = 1.3, - M17 = 1.4 -}; - -describe { - int32_t; - void; -}; - -/** - * TestDev - */ -interface TestDev { - /** - * TestDev1() - */ - void TestDev1(); - - /** - * TestDev2() - */ - [dev_version=1.1] - void TestDev2(); - - /** - * TestDev3() - */ - [version=1.2] - void TestDev3(); - - /** - * TestDev4() - */ - [dev_version=1.3] - void TestDev4(); -}; - -/** - * TestDevToStable - */ -interface TestDevToStable { - /** - * Foo() comment. - */ - void Foo([in] int32_t x); - - /** - * Bar() comment. - */ - [dev_version=1.1, version=1.2] - void Bar([in] int32_t x); - - /** - * Baz() comment. - */ - [dev_version=1.1, version=1.2] - void Baz([in] int32_t x); -};
diff --git a/generators/test_cgen_range/versions.h b/generators/test_cgen_range/versions.h deleted file mode 100644 index 138f052..0000000 --- a/generators/test_cgen_range/versions.h +++ /dev/null
@@ -1,50 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* From test_cgen_range/versions.idl modified Wed Nov 21 15:18:23 2012. */ - -#ifndef PPAPI_C_TEST_CGEN_RANGE_VERSIONS_H_ -#define PPAPI_C_TEST_CGEN_RANGE_VERSIONS_H_ - -#include "ppapi/c/pp_macros.h" -#include "ppapi/c/test_cgen_range/dev_channel_interface.h" - -#define FOO_INTERFACE_0_0 "Foo;0.0" -#define FOO_INTERFACE_1_0 "Foo;1.0" -#define FOO_INTERFACE_2_0 "Foo;2.0" -#define FOO_INTERFACE FOO_INTERFACE_2_0 - -/** - * @file - * File Comment. */ - - -/** - * @addtogroup Interfaces - * @{ - */ -/* Bogus Interface Foo */ -struct Foo_2_0 { - /** - * Comment for function x,y,z - */ - int32_t (*Bar)(int32_t x, int32_t y, int32_t z); -}; - -typedef struct Foo_2_0 Foo; - -struct Foo_0_0 { - int32_t (*Bar)(int32_t x); -}; - -struct Foo_1_0 { - int32_t (*Bar)(int32_t x, int32_t y); -}; -/** - * @} - */ - -#endif /* PPAPI_C_TEST_CGEN_RANGE_VERSIONS_H_ */ -
diff --git a/generators/test_cgen_range/versions.idl b/generators/test_cgen_range/versions.idl deleted file mode 100644 index c447c9c..0000000 --- a/generators/test_cgen_range/versions.idl +++ /dev/null
@@ -1,32 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* File Comment. */ - -label Chrome { - M13 = 0.0, - M14 = 1.0, - M15 = 2.0, - M16 = 3.0, - M17 = 4.0 -}; - -/* Bogus Interface Foo */ -[version=0.0] -interface Foo { - /** - * Comment for function x - */ - [version=0.0] int32_t Bar(int32_t x); - /** - * Comment for function x,y - */ - [version=1.0] int32_t Bar(int32_t x, int32_t y); - /** - * Comment for function x,y,z - */ - [version=2.0] int32_t Bar(int32_t x, int32_t y, int32_t z); -}; -
diff --git a/generators/test_gen_pnacl/test_interfaces.idl b/generators/test_gen_pnacl/test_interfaces.idl deleted file mode 100644 index 5ea2a8e..0000000 --- a/generators/test_gen_pnacl/test_interfaces.idl +++ /dev/null
@@ -1,161 +0,0 @@ -/* - * Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file will test that the pnacl-generated wrapper functions match - * the comments in this IDL. - */ - -label Chrome { - M13 = 0.0, - M14 = 1.0, - M15 = 2.0 -}; - -describe { - void; - mem_t; - int32_t; -}; - -[passByValue, returnByValue] struct some_struct { - mem_t X; - int32_t Y; -}; - -struct some_struct2 { - mem_t X; - int32_t Y; -}; - -[union, passByValue, returnByValue] struct some_union { - mem_t X; - int32_t Y; -}; - -/* - * static int32_t - * Pnacl_M15_PPB_Iface_struct_wrap_foo1(int32_t a, struct some_struct* b) { - * const struct PPB_Iface_struct_wrap_2_0 *iface = - * Pnacl_WrapperInfo_PPB_Iface_struct_wrap_2_0.real_iface; - * return iface->foo1(a, *b); - * } - */ -[version=2.0] -interface PPB_Iface_struct_wrap { - int32_t foo1(int32_t a, [in] some_struct b); -}; - -/* - * static int32_t - * Pnacl_M15_PPB_Iface_union_wrap_foo1(int32_t a, union some_union* b) { - * const struct PPB_Iface_union_wrap_2_0 *iface = - * Pnacl_WrapperInfo_PPB_Iface_union_wrap_2_0.real_iface; - * return iface->foo1(a, *b); - * } - */ -[version=2.0] -interface PPB_Iface_union_wrap { - int32_t foo1(int32_t a, [in] some_union b); -}; - - -[version=2.0] -interface PPB_Iface_nowrap { - int32_t foo1(int32_t a, [in] some_struct2 b); -}; - - -/* - * static - * int32_t Pnacl_M13_PPB_SomeWrap_foo1(struct some_struct* a) { - * const struct PPB_SomeWrap_0_0 *iface = - * Pnacl_WrapperInfo_PPB_SomeWrap_0_0.real_iface; - * return iface->foo1(*a); - * } - * - * static - * void Pnacl_M13_PPB_SomeWrap_foo2(struct some_struct* _struct_result, - * int32_t a) { - * const struct PPB_SomeWrap_0_0 *iface = - * Pnacl_WrapperInfo_PPB_SomeWrap_0_0.real_iface; - * *_struct_result = iface->foo2(a); - * } - */ -[version=0.0] -interface PPB_SomeWrap { - int32_t foo1([in] some_struct a); - some_struct foo2([in] int32_t a); - - /* Not generating wrapper methods for PPB_SomeWrap_1_0 */ - [version=1.0] - int32_t foo1([in] some_struct[] a); - [version=1.0] - void foo2([in] int32_t a, [out] some_struct b); - - /* Not generating wrapper methods for PPB_SomeWrap */ - [version=2.0] - int32_t foo1([in] some_struct2 a); -}; - - -/* - * static int32_t Pnacl_M13_PPP_SomeWrap_foo1(struct some_struct a) { - * const struct PPP_SomeWrap_0_0 *iface = - * Pnacl_WrapperInfo_PPP_SomeWrap_0_0.real_iface; - * int32_t (*temp_fp)(struct some_struct* a) = - * ((int32_t (*)(struct some_struct* a))iface->foo1); - * return temp_fp(&a); - * } - * - * static struct some_struct Pnacl_M13_PPP_SomeWrap_foo2(int32_t a) { - * const struct PPP_SomeWrap_0_0 *iface = - * Pnacl_WrapperInfo_PPP_SomeWrap_0_0.real_iface; - * void (*temp_fp)(struct some_struct* _struct_result, int32_t a) = - * ((void (*)(struct some_struct* _struct_result, int32_t a))iface->foo2); - * struct some_struct _struct_result; - * temp_fp(&_struct_result, a); - * return _struct_result; - * } - * - * static struct some_struct Pnacl_M14_PPP_SomeWrap_foo2(int32_t a) { - * const struct PPP_SomeWrap_1_0 *iface = - * Pnacl_WrapperInfo_PPP_SomeWrap_1_0.real_iface; - * void (*temp_fp)(struct some_struct* _struct_result, int32_t a) = - * ((void (*)(struct some_struct* _struct_result, int32_t a))iface->foo2); - * struct some_struct _struct_result; - * temp_fp(&_struct_result, a); - * return _struct_result; - * } - * - * static int32_t Pnacl_M14_PPP_SomeWrap_foo1(const struct some_struct a[]) { - * const struct PPP_SomeWrap_1_0 *iface = - * Pnacl_WrapperInfo_PPP_SomeWrap_1_0.real_iface; - * int32_t (*temp_fp)(const struct some_struct a[]) = - * ((int32_t (*)(const struct some_struct a[]))iface->foo1); - * return temp_fp(a); - * } - */ -[version=0.0] -interface PPP_SomeWrap { - int32_t foo1([in] some_struct a); - some_struct foo2([in] int32_t a); - - [version=1.0] - int32_t foo1([in] some_struct[] a); - - /* Not generating wrapper interface for PPP_SomeWrap */ - [version=2.0] - int32_t foo1([in] some_struct2 a); - [version=2.0] - void foo2([in] int32_t a); -}; - -[no_interface_string] -interface PPP_NoIFString { - int32_t Dummy([in] some_struct a); -}; -
diff --git a/generators/test_namespace/bar.idl b/generators/test_namespace/bar.idl deleted file mode 100644 index c74388f..0000000 --- a/generators/test_namespace/bar.idl +++ /dev/null
@@ -1,33 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* This file tests the namespace functions in the parser. */ - -label Chrome { - M14 = 1.0 -}; - -/* PPAPI ID */ -typedef int32_t PP_Instance; - -/* PPAPI ID */ -typedef int32_t PP_Resource; - -/* Interface test */ -interface PPB_Bar_0_3 { - /* Face create */ - PP_Resource Create( - [in] PP_Instance instance, - [in] PP_Size size, - [in] PP_Bool is_always_opaque); - - /* Returns PP_TRUE if the given resource is a valid Graphics2D, PP_FALSE if it - * is an invalid resource or is a resource of another type. - */ - PP_Bool IsGraphics2D( - [in] PP_Resource resource); -}; - -
diff --git a/generators/test_namespace/foo.idl b/generators/test_namespace/foo.idl deleted file mode 100644 index a7bcc0e..0000000 --- a/generators/test_namespace/foo.idl +++ /dev/null
@@ -1,26 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* File Comment */ - -describe { - int32_t; -}; - -/* PPAPI Structure */ -struct PP_Size { - /* This value represents the width of the rectangle. */ - int32_t width; - /* This value represents the height of the rectangle. */ - int32_t height; -}; - -/* PPAPI Enum */ -enum PP_Bool { - /* Decalare False */ - PP_FALSE = 0, - /* Decalare True */ - PP_TRUE = 1 -};
diff --git a/generators/test_parser/dictionary.idl b/generators/test_parser/dictionary.idl deleted file mode 100644 index b73c257..0000000 --- a/generators/test_parser/dictionary.idl +++ /dev/null
@@ -1,17 +0,0 @@ -/* Copyright 2013 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -dictionary MyDict { - /* OK Member(setString) */ - DOMString setString; - /* OK Member(unsetLong) */ - long unsetLong; -}; - -/* FAIL Unexpected "}" after symbol unsetLong. */ -dictionary MyDict { - DOMString setString; - long unsetLong -};
diff --git a/generators/test_parser/enum.idl b/generators/test_parser/enum.idl deleted file mode 100644 index 36b2859..0000000 --- a/generators/test_parser/enum.idl +++ /dev/null
@@ -1,108 +0,0 @@ -/* Copyright 2011 The Chromium Authors - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. */ - -/* This file tests parsing of enumerations under different conditions */ - -/* OK Enum(Es1) */ -enum Es1 { - /* OK EnumItem(E1) */ - E1 = 1, - /* OK EnumItem(E2) */ - E2 = 2 -}; - -/* FAIL Enum missing name. */ -enum { - E3 = 3, - E4 = 4 -}; - -/* OK Enum(Es3) */ -enum Es3 { - E5 = 1 << 1, - E6 = 3 << 2 -}; - -/* FAIL Unexpected empty block. */ -enum Es4 { -}; - -/* OK Enum(Es5) */ -enum Es5 { - /* OK EnumItem(E9) */ - E9 = 9, - /* OK EnumItem(E10) */ - /* FAIL Trailing comma in block. */ - E10 = 10, -}; - -/* FAIL Unexpected trailing comment. */ -enum Es6 { - E5 = 11, - E6 = 12 -} - -/* Bad comment because of Es6 */ -enum Es7 { - E11 = 11 -}; - - -/* OK Enum(Es8) */ -enum Es8 { - /* OK EnumItem(E12) */ - E12 = 12, - /* OK EnumItem(E13) */ - /* FAIL Unexpected value 13.0 after "=". */ - E13 = 13.0, - /* FAIL Unexpected string "hello" after "=". */ - /* OK EnumItem(E14) */ - E14 = "hello", - /* OK EnumItem(E15) */ - E15 = 0x400 -}; - -/* OK Enum(Es9) */ -enum Es9 { - /* OK EnumItem(Es9_1) */ - Es9_1 = 0, - /* OK EnumItem(Es9_2) */ - Es9_2 = Es9_1, - /* OK EnumItem(Es9_3) */ - Es9_3 = Es9_1 << Es9_2, - /* OK EnumItem(Es9_3a) */ - /* FAIL Unexpected symbol Es9_2 after symbol Es9_1. */ - Es9_3a = Es9_1 Es9_2, - /* OK EnumItem(Es9_4) */ - Es9_4 = Es9_1 >> Es9_2, - /* OK EnumItem(Es9_5) */ - Es9_5 = Es9_1 | Es9_2, - /* OK EnumItem(Es9_6) */ - Es9_6 = Es9_1 & Es9_2, - /* OK EnumItem(Es9_7) */ - Es9_7 = Es9_1 ^ Es9_2, - /* OK EnumItem(Es9_8) */ - Es9_8 = Es9_1 + Es9_2, - /* OK EnumItem(Es9_9) */ - Es9_9 = Es9_1 - Es9_2, - /* OK EnumItem(Es9_10) */ - Es9_10 = Es9_1 * Es9_2, - /* OK EnumItem(Es9_11) */ - Es9_11 = Es9_1 / Es9_2, - /* OK EnumItem(Es9_12) */ - Es9_12 = -Es9_1, - /* OK EnumItem(Es9_13) */ - Es9_13 = ~Es9_1, - /* OK EnumItem(Es9_14) */ - Es9_14 = (Es9_1), - /* OK EnumItem(Es9_14a) */ - /* FAIL Unexpected ,. */ - Es9_14a = (Es9_1, - /* OK EnumItem(Es9_15) */ - Es9_15 = (Es9_1 + Es9_2) << Es9_3 + 1, - /* OK EnumItem(Es9_16) */ - Es9_16 = Es9_1 + -Es9_2 -}; - -
diff --git a/generators/test_parser/interface.idl b/generators/test_parser/interface.idl deleted file mode 100644 index d3e38ae..0000000 --- a/generators/test_parser/interface.idl +++ /dev/null
@@ -1,59 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Tests for interface */ - -/* OK Interface(Interface1) */ -interface Interface1 { - /* OK Member(OneParam) */ - PP_Bool OneParam( - /* OK Param(resource) */ - [in] PP_Resource resource); - - /* OK Member(TwoParam) */ - PP_Resource TwoParam( - /* OK Param(instance) */ - [in] PP_Instance instance, - /* OK Param(size) */ - [in] PP_Size size); - - /* OK Member(ThreeParam) */ - PP_Bool ThreeParam( - /* OK Param(graphics_2d) */ - [in] PP_Resource graphics_2d, - /* OK Param(size) */ - [out] PP_Size size, - /* OK Param(is_always_opaque) */ - [out] PP_Bool is_always_opaque); - - /* OK Member(ReturnArray) */ - PP_Resource[] ReturnArray(); -}; - - -/* OK Interface(Interface2) */ -interface Interface2 { - /* OK Member(OneParam) */ - PP_Bool OneParam( - /* OK Param(resource) */ - [in] PP_Resource resource); - - /* OK Member(TwoParam) */ - PP_Resource TwoParam( - /* OK Param(instance) */ - [in] PP_Instance instance, - /* OK Param(size) */ - /* FAIL Missing argument. */ - [in] PP_Size size, ); - - /* OK Member(ThreeParam) */ - PP_Bool ThreeParam( - /* OK Param(graphics_2d) */ - [in] PP_Resource graphics_2d, - /* FAIL Unexpected "," after symbol PP_Size. */ - [out] PP_Size, - /* OK Param(is_always_opaque) */ - [out] PP_Bool is_always_opaque); -};
diff --git a/generators/test_parser/struct.idl b/generators/test_parser/struct.idl deleted file mode 100644 index 57b752f..0000000 --- a/generators/test_parser/struct.idl +++ /dev/null
@@ -1,34 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Tests for structures */ - -/* OK Struct(S1) */ -struct S1 { - /* OK Member(Mem1) */ - PP_Bool Mem1; - /* OK Member(Mem2) */ - PP_Resource Mem2; -}; - -typedef int func([in] int x, [in] int y); - -/* OK Struct(S2) */ -struct S2 { - /* OK Member(Mem1) */ - PP_Bool Mem1; - /* OK Member(Mem2) */ - PP_Resource Mem2; - /* OK Member(Mem3) */ - [attr1, attr2] PP_Resource Mem3; - /* OK Member(foo) */ - FuncFoo foo; -}; - -/* FAIL Struct missing name. */ -struct { - PP_Bool Mem1; - PP_Resource Mem2; -}; \ No newline at end of file
diff --git a/generators/test_parser/typedef.idl b/generators/test_parser/typedef.idl deleted file mode 100644 index f0e02d9..0000000 --- a/generators/test_parser/typedef.idl +++ /dev/null
@@ -1,46 +0,0 @@ -/* Copyright 2011 The Chromium Authors - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. */ - -/* This file tests parsing of typedefs under different conditions */ - -/* OK Typedef(T1) */ -typedef int32_t T1; - -/* FAIL Unexpected comment after symbol T2. */ -typedef int32_t T2 - -/* OK Typedef(T3) */ -typedef int32_t[] T3; - -/* OK Typedef(T4) */ -typedef int32_t[][4] T4; - -/* FAIL Unexpected "(" after symbol T5. */ -typedef int32_t[4] T5(); - -/* OK Typedef(T6) */ -typedef int32_t T6([in] int32_t x); - -/* OK Typedef(T7) */ -typedef int32_t T7( - /* OK Param(x) */ - [in] int32_t x, - /* OK Param(y) */ - [in] int32_t y); - -/* OK Typedef(T8) */ -typedef T3 T8( - /* OK Param(x) */ - [in] int x, - /* OK Param(y) */ - [in] int y, - /* OK Param(z) */ - /* FAIL Missing argument. */ - [in] int z,); - -/* FAIL Unexpected keyword "enum" after symbol int32_t. */ -typedef int32_t enum; - -/* FAIL Unexpected ";" after symbol foo. */ -typedef foo;
diff --git a/generators/test_thunk/basic_test_types.idl b/generators/test_thunk/basic_test_types.idl deleted file mode 100644 index ea41edb..0000000 --- a/generators/test_thunk/basic_test_types.idl +++ /dev/null
@@ -1,58 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * This file defines some basic types for use in testing. - */ - -label Chrome { - M13 = 0.0, - M14 = 1.0, - M15 = 2.0 -}; - -[version=0.0] -describe { - /** Standard Ints. */ - int8_t; - int16_t; - int32_t; - int64_t; - uint8_t; - uint16_t; - uint32_t; - uint64_t; - /** Small and large floats. */ - double_t; - float_t; - - /** Native file handle (int). */ - handle_t; - - /** Interface object (void *). */ - interface_t; - - /** Used for padding, should be (u)int8_t */ - char; - - /** Pointer to memory (void *). */ - mem_t; - - /** Pointer to null terminated string (char *). */ - str_t; - - /** No return value. */ - void; - - /** Pointer to pointer to memory (void **). */ - blob_t; - - /** Pepper types */ - PP_Bool; - PP_Instance; - PP_Resource; - PP_Var; -}; -
diff --git a/generators/test_thunk/simple.idl b/generators/test_thunk/simple.idl deleted file mode 100644 index 3f64ce2..0000000 --- a/generators/test_thunk/simple.idl +++ /dev/null
@@ -1,39 +0,0 @@ -/* Copyright 2012 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -[generate_thunk] - -/** - * This file defines the <code>PPB_Simple</code> interface. - */ - -label Chrome { - M13 = 0.5, - M14 = 1.0, - M15 = 1.5 -}; - -interface PPB_Simple { - PP_Resource Create([in] PP_Instance instance); - - PP_Bool IsSimple([in] PP_Resource resource); - - [deprecate=1.0] - void PostMessage([in] PP_Instance instance, [in] PP_Var message); - - uint32_t DoUint32Instance([in] PP_Instance instance); - - [version=1.5] - uint32_t DoUint32Instance([in] PP_Instance instance, - [in] PP_Resource resource); - - uint32_t DoUint32Resource([in] PP_Resource instance); - - [report_errors=False] - uint32_t DoUint32ResourceNoErrors([in] PP_Resource instance); - - [version=1.0, on_failure="12"] - int32_t OnFailure12([in] PP_Instance instance); -};
diff --git a/generators/test_thunk/simple_thunk.cc b/generators/test_thunk/simple_thunk.cc deleted file mode 100644 index 4a896c2..0000000 --- a/generators/test_thunk/simple_thunk.cc +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// From ../test_thunk/simple.idl modified Fri Nov 16 11:26:06 2012. - -#include <stdint.h> - -#include "ppapi/c/../test_thunk/simple.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/shared_impl/tracked_callback.h" -#include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_instance_api.h" -#include "ppapi/thunk/resource_creation_api.h" -#include "ppapi/thunk/simple_api.h" -#include "ppapi/thunk/thunk.h" - -namespace ppapi { -namespace thunk { - -namespace { - -PP_Resource Create(PP_Instance instance) { - VLOG(4) << "PPB_Simple::Create()"; - EnterResourceCreation enter(instance); - if (enter.failed()) - return 0; - return enter.functions()->CreateSimple(instance); -} - -PP_Bool IsSimple(PP_Resource resource) { - VLOG(4) << "PPB_Simple::IsSimple()"; - EnterResource<PPB_Simple_API> enter(resource, false); - return PP_FromBool(enter.succeeded()); -} - -void PostMessage(PP_Instance instance, PP_Var message) { - VLOG(4) << "PPB_Simple::PostMessage()"; - EnterInstance enter(instance); - if (enter.failed()) - return; - enter.functions()->PostMessage(instance, message); -} - -uint32_t DoUint32Instance_0_5(PP_Instance instance) { - VLOG(4) << "PPB_Simple::DoUint32Instance()"; - EnterInstance enter(instance); - if (enter.failed()) - return 0; - return enter.functions()->DoUint32Instance0_5(instance); -} - -uint32_t DoUint32Instance(PP_Instance instance, PP_Resource resource) { - VLOG(4) << "PPB_Simple::DoUint32Instance()"; - EnterInstance enter(instance); - if (enter.failed()) - return 0; - return enter.functions()->DoUint32Instance(instance, resource); -} - -uint32_t DoUint32Resource(PP_Resource instance) { - VLOG(4) << "PPB_Simple::DoUint32Resource()"; - EnterResource<PPB_Simple_API> enter(instance, true); - if (enter.failed()) - return 0; - return enter.object()->DoUint32Resource(); -} - -uint32_t DoUint32ResourceNoErrors(PP_Resource instance) { - VLOG(4) << "PPB_Simple::DoUint32ResourceNoErrors()"; - EnterResource<PPB_Simple_API> enter(instance, false); - if (enter.failed()) - return 0; - return enter.object()->DoUint32ResourceNoErrors(); -} - -int32_t OnFailure12(PP_Instance instance) { - VLOG(4) << "PPB_Simple::OnFailure12()"; - EnterInstance enter(instance); - if (enter.failed()) - return 12; - return enter.functions()->OnFailure12(instance); -} - -const PPB_Simple_0_5 g_ppb_simple_thunk_0_5 = { - &Create, - &IsSimple, - &PostMessage, - &DoUint32Instance_0_5, - &DoUint32Resource, - &DoUint32ResourceNoErrors -}; - -const PPB_Simple_1_0 g_ppb_simple_thunk_1_0 = { - &Create, - &IsSimple, - &DoUint32Instance_0_5, - &DoUint32Resource, - &DoUint32ResourceNoErrors, - &OnFailure12 -}; - -const PPB_Simple_1_5 g_ppb_simple_thunk_1_5 = { - &Create, - &IsSimple, - &DoUint32Instance, - &DoUint32Resource, - &DoUint32ResourceNoErrors, - &OnFailure12 -}; - -} // namespace - -const PPB_Simple_0_5* GetPPB_Simple_0_5_Thunk() { - return &g_ppb_simple_thunk_0_5; -} - -const PPB_Simple_1_0* GetPPB_Simple_1_0_Thunk() { - return &g_ppb_simple_thunk_1_0; -} - -const PPB_Simple_1_5* GetPPB_Simple_1_5_Thunk() { - return &g_ppb_simple_thunk_1_5; -} - -} // namespace thunk -} // namespace ppapi
diff --git a/generators/test_version/versions.idl b/generators/test_version/versions.idl deleted file mode 100644 index 04f7945..0000000 --- a/generators/test_version/versions.idl +++ /dev/null
@@ -1,66 +0,0 @@ -/* Copyright 2011 The Chromium Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* File Comment. */ - -label Chrome { - M13 = 0.0, - M14 = 1.0, - M15 = 2.0 -}; - -describe { - int32_t; -}; - -/*REL: M13 M15 */ -[version=0.0] -interface iFoo { - /** - * Comment for function x - */ - [version=0.0] int32_t Bar([in] int32_t x); - /** - * Comment for function x,y,z - */ - [version=2.0] int32_t Bar([in] int32_t x, [in] int32_t y, [in] int32_t z); -}; - - -/*REL: M13 M15 */ -[version=0.0] -struct iBar { - /** - * Comment for function x - */ - [version=0.0] iFoo x; -}; - -/*REL: M13 M14 M15 */ -[version=0.0] -struct iX { - /** - * Comment for function x - */ - [version=0.0] iFoo x; - /** - * Comment for member y - */ - [version=1.0] int32_t y; -}; - - -/** - * Typedef to generate M13-M14, M15 - */ -typedef int32_t callback_t([in] int32_t x, [in, version=2.0] int32_t y); - -/*REL: M13 M14 M15 */ -interface iFooX { - /** - * Comment for function Bar - */ - int32_t Bar([in, version=1.0] callback_t cb); -}; \ No newline at end of file