diff options
author | noelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 20:53:44 +0000 |
---|---|---|
committer | noelallen@google.com <noelallen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 20:53:44 +0000 |
commit | a7f58e82ef240c8c88af43bbac5d2bc4eccd9297 (patch) | |
tree | 1f5217be7642b6242b429c86d38a352f653c5035 /ppapi/generators | |
parent | 7a30d51a2b00651fb5d62d5e4e31145daff2fad4 (diff) | |
download | chromium_src-a7f58e82ef240c8c88af43bbac5d2bc4eccd9297.zip chromium_src-a7f58e82ef240c8c88af43bbac5d2bc4eccd9297.tar.gz chromium_src-a7f58e82ef240c8c88af43bbac5d2bc4eccd9297.tar.bz2 |
Update the IDL Generator to use Release instead of Version
This CL adds the blob_t type for referencing memory pointers. This is a trivial change to idl_c_proto.
The man change for this CL is to fix the version mismatch between types in different files. Since each source file can have it's own Label mapping, using the version of one object to index into a version of another can fail between sources.
This CL removes the use of version and the LABEL property, and instead converts the Node's version information immediately as it's added into the versioned namespace. Now namespace objects reference via Release (str M14) instead of Version (float 1.0). This allows the Nodes to compare against each other with a global value.
1- Remove lint warning for missing "LABEL" property
2- Convert Version references to Release references such as vmin to rmin, etc...
3- Remove Version interfaces which are no longer needed
4- Move VersionList and VersionMap in namespace to ReleaseList and ReleaseMap in idl_release.py
5- Added tests to idl_release
BUG= http://code.google.com/p/chromium/issues/detail?id=97708
TEST= python idl_release && ./generate
Review URL: http://codereview.chromium.org/8045001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102793 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/generators')
-rwxr-xr-x | ppapi/generators/generator.py | 2 | ||||
-rw-r--r-- | ppapi/generators/idl_ast.py | 45 | ||||
-rw-r--r-- | ppapi/generators/idl_c_proto.py | 9 | ||||
-rw-r--r-- | ppapi/generators/idl_generator.py | 2 | ||||
-rw-r--r-- | ppapi/generators/idl_lint.py | 3 | ||||
-rw-r--r-- | ppapi/generators/idl_namespace.py | 204 | ||||
-rw-r--r-- | ppapi/generators/idl_node.py | 60 | ||||
-rw-r--r-- | ppapi/generators/idl_release.py | 320 | ||||
-rw-r--r-- | ppapi/generators/idl_version.py | 147 | ||||
-rw-r--r-- | ppapi/generators/test_cgen/interface.idl | 10 | ||||
-rw-r--r-- | ppapi/generators/test_cgen/stdint.idl | 5 |
11 files changed, 428 insertions, 379 deletions
diff --git a/ppapi/generators/generator.py b/ppapi/generators/generator.py index 59cc421..00e85ac 100755 --- a/ppapi/generators/generator.py +++ b/ppapi/generators/generator.py @@ -26,7 +26,7 @@ if __name__ == '__main__': # If no arguments are provided, assume we are tring to rebuild the # C headers with warnings off. - if not args: args = ['--wnone', '--cgen', '--range=M13,M14'] + if not args: args = ['--wnone', '--cgen', '--range=M13,M16'] sys.exit(Main(args)) diff --git a/ppapi/generators/idl_ast.py b/ppapi/generators/idl_ast.py index 95eae32..f215dbb 100644 --- a/ppapi/generators/idl_ast.py +++ b/ppapi/generators/idl_ast.py @@ -6,10 +6,11 @@ """Nodes for PPAPI IDL AST.""" -from idl_namespace import IDLNamespace, IDLVersionMap +from idl_namespace import IDLNamespace from idl_node import IDLAttribute, IDLFile, IDLNode from idl_option import GetOption from idl_visitor import IDLVisitor +from idl_release import IDLReleaseList, IDLReleaseMap # # IDL Predefined types @@ -32,10 +33,8 @@ class IDLNamespaceLabelResolver(IDLVisitor): # node is named, then place it in the appropriate namespace. # def Arrive(self, node, parent_namespace): - # Set version min and max based on properties - vmin = node.GetProperty('version') - vmax = node.GetProperty('deprecate') - node.SetVersionRange(vmin, vmax) + # If we are entering a parent, clear the local Label\ + if node.IsA('File'): self.release_map = None # If this object is not a namespace aware object, use the parent's one if node.cls not in self.NamespaceSet: @@ -47,6 +46,13 @@ class IDLNamespaceLabelResolver(IDLVisitor): # 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('version') + vmax = node.GetProperty('deprecate') + 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 @@ -62,10 +68,11 @@ class IDLNamespaceLabelResolver(IDLVisitor): if node.IsA('LabelItem'): return (node.GetName(), node.GetProperty('VALUE')) if node.IsA('Label') and node.GetName() == GetOption('label'): - vmap = IDLVersionMap() - for release, version in childdata: - vmap.AddReleaseVersionMapping(release, float(version)) - node.parent.SetProperty("LABEL", vmap) + try: + self.release_map = IDLReleaseMap(childdata) + node.parent.release_map = self.release_map + except Exception as err: + node.Error('Unable to build release map: %s' % str(err)) return None @@ -89,22 +96,6 @@ class IDLFileTypeResolver(IDLVisitor): return filenode -class IDLReleaseResolver(IDLVisitor): - def VisitFilter(self, node, data): - return node.IsA('AST','File', 'Label') - - def Depart(self, node, data, childdata): - if node.IsA('Label'): - return set([child.name for child in GetListOf('LabelItem')]) - return childdata - -class IDLVersionMapDefault(IDLVersionMap): - def GetRelease(self, version): - return 'M13' - - def GetVersion(self, release): - return float(0.0) - # # IDLAst # @@ -124,7 +115,6 @@ class IDLAst(IDLNode): break IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, extranodes + children) - self.SetProperty('LABEL', IDLVersionMapDefault()) self.Resolve() def Resolve(self): @@ -136,8 +126,7 @@ class IDLAst(IDLNode): # Build an ordered list of all releases self.releases = set() for filenode in self.GetListOf('File'): - vmap = filenode.GetProperty('LABEL') - self.releases |= set(vmap.releases) + self.releases |= set(filenode.release_map.GetReleases()) self.releases = sorted(self.releases) def SetTypeInfo(self, name, properties): diff --git a/ppapi/generators/idl_c_proto.py b/ppapi/generators/idl_c_proto.py index 1ea8e03..fb3a576 100644 --- a/ppapi/generators/idl_c_proto.py +++ b/ppapi/generators/idl_c_proto.py @@ -103,6 +103,13 @@ class CGen(object): 'return': ' %s*', 'store': '%s' }, + 'blob_t': { + 'in': 'const %s', + 'inout': '%s', + 'out': '%s', + 'return': '%s', + 'store': '%s' + }, 'mem_t': { 'in': 'const %s', 'inout': '%s', @@ -134,6 +141,7 @@ class CGen(object): # types before being returned by by the C generator # RemapName = { + 'blob_t': 'void**', 'float_t': 'float', 'double_t': 'double', 'handle_t': 'int', @@ -567,4 +575,3 @@ def Main(args): if __name__ == '__main__': sys.exit(Main(sys.argv[1:])) - diff --git a/ppapi/generators/idl_generator.py b/ppapi/generators/idl_generator.py index bd77e07..d438808 100644 --- a/ppapi/generators/idl_generator.py +++ b/ppapi/generators/idl_generator.py @@ -12,7 +12,7 @@ from idl_option import GetOption, Option, ParseOptions GeneratorList = [] Option('release', 'Which release to generate.', default='') -Option('range', 'Which ranges in the form of MIN,MAX.', default='M13,M14') +Option('range', 'Which ranges in the form of MIN,MAX.', default='M13,M16') # diff --git a/ppapi/generators/idl_lint.py b/ppapi/generators/idl_lint.py index c5f1a3f..2c425c6 100644 --- a/ppapi/generators/idl_lint.py +++ b/ppapi/generators/idl_lint.py @@ -64,9 +64,6 @@ class IDLLinter(IDLVisitor): warnings += 1 if node.IsA('Interface'): - if not node.GetLabel(): - node.Warning('Expecting label.') - warnings += 1 macro = node.GetProperty('macro') if macro and not node.GetProperty('wname'): node.Warning('Interface name inconsistent: %s' % macro) diff --git a/ppapi/generators/idl_namespace.py b/ppapi/generators/idl_namespace.py index ee9c151..29ac6c0 100644 --- a/ppapi/generators/idl_namespace.py +++ b/ppapi/generators/idl_namespace.py @@ -8,131 +8,25 @@ 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 version or range of versions. +a symbol as one or more AST nodes given a release or range of releases. """ import sys from idl_option import GetOption, Option, ParseOptions from idl_log import ErrOut, InfoOut, WarnOut -from idl_version import IDLVersion +from idl_release import IDLRelease, IDLReleaseList Option('label', 'Use the specifed label blocks.', default='Chrome') -Option('namespace_debug', 'Use the specified version') - - -# -# IDLVersionList -# -# IDLVersionList is a list based container for holding IDLVersion -# objects in order. The IDLVersionList can be added to, and searched by -# range. Objects are stored in order, and must be added in order. -# -class IDLVersionList(object): - def __init__(self): - self.nodes = [] - - def FindVersion(self, version): - assert type(version) == float - - for node in self.nodes: - if node.IsVersion(version): - return node - return None - - def FindRange(self, vmin, vmax): - assert type(vmin) == float - assert type(vmax) == float - assert vmin != vmax - - out = [] - for node in self.nodes: - if node.InRange(vmin, vmax): - out.append(node) - return out - - def AddNode(self, node): - if GetOption('version_debug'): - InfoOut.Log('\nAdding %s %s' % (node.Location(), node)) - last = None - - # Check current versions in that namespace - for cver in self.nodes: - if GetOption('version_debug'): InfoOut.Log(' Checking %s' % cver) - - # We should only be missing a 'version' tag for the first item. - if not node.vmin: - raise RuntimeError('Missing version') - node.Error('Missing version on overload of previous %s.' % - cver.Location()) - return False - - # If the node has no max, then set it to this one - if not cver.vmax: - cver.vmax = node.vmin - if GetOption('version_debug'): InfoOut.Log(' Update %s' % cver) - - # if the max and min overlap, than's an error - if cver.vmax > node.vmin: - if node.vmax and cver.vmin >= node.vmax: - node.Error('Declarations out of order.') - else: - node.Error('Overlap in versions.') - 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.vmax != node.vmin: - node.Warn('Gap in version 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('version_debug'): InfoOut.Log('Done %s' % node) - self.nodes.append(node) - return True - -# -# IDLVersionMap -# -# A version map, can map from an float interface version, to a global -# release string. -# -class IDLVersionMap(object): - def __init__(self): - self.version_to_release = {} - self.release_to_version = {} - self.versions = [] - self.releases = [] - - def AddReleaseVersionMapping(self, release, version): - self.version_to_release[version] = release - self.release_to_version[release] = version - self.versions = sorted(self.version_to_release.keys()) - self.releases = sorted(self.release_to_version.keys()) - - def GetRelease(self, version): - # Check for exact match - if version in self.versions: - return self.version_to_release[version] - - def GetVersion(self, release): - if release > self.releases[-1]: - release = self.releases[-1] - elif release < self.releases[0]: - release = self.releases[0] - return self.release_to_version[release] - +Option('namespace_debug', 'Use the specified release') # # IDLNamespace # -# IDLNamespace provides a mapping between a symbol name and an IDLVersionList -# which contains IDLVersion objects. It provides an interface for fetching -# one or more IDLNodes based on a version or range of versions. +# 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): @@ -142,27 +36,27 @@ class IDLNamespace(object): def Dump(self): for name in self.namespace: InfoOut.Log('NAME=%s' % name) - for cver in self.namespace[name]: + for cver in self.namespace[name].nodes: InfoOut.Log(' %s' % cver) InfoOut.Log('') - def FindVersion(self, name, version): + def FindRelease(self, name, release): verlist = self.namespace.get(name, None) if verlist == None: if self.parent: - return self.parent.FindVersion(name, version) + return self.parent.FindRelease(name, release) else: return None - return verlist.FindVersion(version) + return verlist.FindRelease(release) - def FindRange(self, name, vmin, vmax): + def FindRange(self, name, rmin, rmax): verlist = self.namespace.get(name, None) if verlist == None: if self.parent: - return self.parent.FindRange(name, vmin, vmax) + return self.parent.FindRange(name, rmin, rmax) else: return [] - return verlist.FindRange(vmin, vmax) + return verlist.FindRange(rmin, rmax) def FindList(self, name): verlist = self.namespace.get(name, None) @@ -173,7 +67,7 @@ class IDLNamespace(object): def AddNode(self, node): name = node.GetName() - verlist = self.namespace.setdefault(name,IDLVersionList()) + verlist = self.namespace.setdefault(name,IDLReleaseList()) if GetOption('namespace_debug'): print "Adding to namespace: %s" % node return verlist.AddNode(node) @@ -189,31 +83,31 @@ class IDLNamespace(object): # # Mocks the IDLNode to support error, warning handling, and string functions. # -class MockNode(IDLVersion): - def __init__(self, name, vmin, vmax): +class MockNode(IDLRelease): + def __init__(self, name, rmin, rmax): self.name = name - self.vmin = vmin - self.vmax = vmax + self.rmin = rmin + self.rmax = rmax self.errors = [] self.warns = [] self.properties = { 'NAME': name, - 'version': vmin, - 'deprecate' : vmax + 'release': rmin, + 'deprecate' : rmax } def __str__(self): - return '%s (%s : %s)' % (self.name, self.vmin, self.vmax) + return '%s (%s : %s)' % (self.name, self.rmin, self.rmax) def GetName(self): return self.name def Error(self, msg): - if GetOption('version_debug'): print 'Error: %s' % msg + if GetOption('release_debug'): print 'Error: %s' % msg self.errors.append(msg) def Warn(self, msg): - if GetOption('version_debug'): print 'Warn: %s' % msg + if GetOption('release_debug'): print 'Warn: %s' % msg self.warns.append(msg) def GetProperty(self, name): @@ -225,17 +119,17 @@ errors = 0 # # 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 + 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): @@ -258,26 +152,27 @@ def AddError(namespace, node, msg): 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 FindVersion call on the namespace returns the expected node. -def VerifyFindOne(namespace, name, version, node): +# Verify that a FindRelease call on the namespace returns the expected node. +def VerifyFindOne(namespace, name, release, node): global errors - if (namespace.FindVersion(name, version) != node): - print "Failed to find %s as version %f of %s" % (node, version, name) + 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, vmin, vmax, nodes): +def VerifyFindAll(namespace, name, rmin, rmax, nodes): global errors - out = namespace.FindRange(name, vmin, vmax) + out = namespace.FindRange(name, rmin, rmax) if (out != nodes): - print "Found [%s] instead of[%s] for versions %f to %f of %s" % ( + 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]), - vmin, - vmax, + rmin, + rmax, name) namespace.Dump() print "\n" @@ -300,8 +195,9 @@ def Main(args): AddOkay(namespace, FooXX) AddOkay(namespace, Foo1X) AddOkay(namespace, Foo3X) - # Verify we fail to add a node between undeprecated versions - AddError(namespace, Foo2X, 'Overlap in versions.') + # 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) @@ -309,12 +205,12 @@ def Main(args): Bar34 = MockNode('bar', 3.0, 4.0) - # Verify we succeed with fully qualified versions + # 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 version numbers.') + 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.') @@ -323,7 +219,7 @@ def Main(args): VerifyFindOne(namespace, 'bar', 0.0, BarXX) VerifyFindAll(namespace, 'bar', 0.5, 1.5, [BarXX, Bar12]) - # Verify the correct version of the object is found recursively + # 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) diff --git a/ppapi/generators/idl_node.py b/ppapi/generators/idl_node.py index b146ba3..3ae4021 100644 --- a/ppapi/generators/idl_node.py +++ b/ppapi/generators/idl_node.py @@ -23,7 +23,7 @@ import sys from idl_log import ErrOut, InfoOut, WarnOut from idl_propertynode import IDLPropertyNode from idl_namespace import IDLNamespace -from idl_version import IDLVersion +from idl_release import IDLRelease, IDLReleaseMap # IDLAttribute @@ -46,10 +46,10 @@ class IDLAttribute(object): # # This class implements the AST tree, providing the associations between # parents and children. It also contains a namepsace and propertynode to -# allow for look-ups. IDLNode is derived from IDLVersion, so it is +# allow for look-ups. IDLNode is derived from IDLRelease, so it is # version aware. # -class IDLNode(IDLVersion): +class IDLNode(IDLRelease): # Set of object IDLNode types which have a name and belong in the namespace. NamedSet = set(['Enum', 'EnumItem', 'File', 'Function', 'Interface', @@ -58,7 +58,7 @@ class IDLNode(IDLVersion): show_versions = False def __init__(self, cls, filename, lineno, pos, children=None): # Initialize with no starting or ending Version - IDLVersion.__init__(self, None, None) + IDLRelease.__init__(self, None, None) self.cls = cls self.lineno = lineno @@ -91,7 +91,7 @@ class IDLNode(IDLVersion): # Return a string representation of this node def __str__(self): name = self.GetName() - ver = IDLVersion.__str__(self) + ver = IDLRelease.__str__(self) if name is None: name = '' if not IDLNode.show_versions: ver = '' return '%s(%s%s)' % (self.cls, name, ver) @@ -117,7 +117,7 @@ class IDLNode(IDLVersion): def GetNameVersion(self): name = self.GetProperty('NAME', default='') - ver = IDLVersion.__str__(self) + ver = IDLRelease.__str__(self) return '%s%s' % (name, ver) # Dump this object and its children @@ -204,34 +204,9 @@ class IDLNode(IDLVersion): nodes = self.parent.FindVersion(name, vmin, vmax) return nodes - def IsRelease(self, release): - label = self.GetLabel() - # Assume object is always available if there is no Label - if not label: - return True - - version = label.GetVersion(release) - out = self.IsVersion(version) - return out - - def InReleases(self, releases): - for rel in releases: - if self.IsRelease(rel): return True - return False - - def GetLabel(self): - label = self.GetProperty('LABEL') - if not label: - self.Error('No label availible.') - return None - return label - def GetType(self, release): - label = self.GetLabel() - if not label: return None if not self.typelist: return None - version = label.GetVersion(release) - return self.typelist.FindVersion(version) + return self.typelist.FindRelease(release) def GetHash(self, release): hashval = self.hashes.get(release, None) @@ -263,21 +238,23 @@ class IDLNode(IDLVersion): self.deps[release] = deps return deps - def GetRelease(self, version): - label = self.GetLabel() - if not label: return None - return label.GetRelease(version) - def GetVersion(self, release): - label = self.GetLabel() - if not label: return None - return label.GetVersion(release) + filenode = self.GetProperty('FILE') + if not filenode: + return None + return filenode.release_map.GetVersion(release) def GetUniqueReleases(self, releases): - # Given a list of release, return a subset of releases that change. + # Given a list of global release, return a subset of releases + # for this object that change. last_hash = None build_list = [] + filenode = self.GetProperty('FILE') + my_releases = filenode.release_map.GetReleases() for rel in releases: + if not self.IsRelease(rel): continue + # Only check releases used by this source file + if rel not in my_releases: continue cur_hash = self.GetHash(rel) if last_hash != cur_hash: build_list.append(rel) @@ -307,6 +284,7 @@ class IDLFile(IDLNode): IDLAttribute('ERRORS', errors)] if not children: children = [] IDLNode.__init__(self, 'File', name, 1, 0, attrs + children) + self.release_map = IDLReleaseMap([('M13', 1.0)]) # diff --git a/ppapi/generators/idl_release.py b/ppapi/generators/idl_release.py new file mode 100644 index 0000000..a6670a2 --- /dev/null +++ b/ppapi/generators/idl_release.py @@ -0,0 +1,320 @@ +#!/usr/bin/python +# +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +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. +""" + +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 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 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 = {} + for release, version in release_info: + self.version_to_release[version] = release + self.release_to_version[release] = version + 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 + +# +# 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/ppapi/generators/idl_version.py b/ppapi/generators/idl_version.py deleted file mode 100644 index a67abd5c..0000000 --- a/ppapi/generators/idl_version.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -IDLVersion 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 version or range of versions. -""" - -import sys - -from idl_log import ErrOut, InfoOut, WarnOut -from idl_option import GetOption, Option, ParseOptions - -Option('version_debug', 'Debug version data') -Option('wgap', 'Ignore version gap warning') - - -# -# Module level functions and data used for testing. -# -error = None -warning = None -def ReportVersionError(msg): - global error - error = msg - -def ReportVersionWarning(msg): - global warning - warning = msg - -def ReportClear(): - global error, warning - error = None - warning = None - -# -# IDLVersion -# -# IDLVersion is an object which stores the association of a given symbol -# name, with an AST node for a range of versions for that object. -# -# A vmin value of None indicates that the object begins at the earliest -# available version 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 version. -# The value of vmax is always exclusive, representing the first version -# on which the object is no longer valid. -class IDLVersion(object): - def __init__(self, vmin, vmax): - self.vmin = vmin - self.vmax = vmax - - def __str__(self): - if not self.vmin: - vmin = '0' - else: - vmin = str(self.vmin) - if not self.vmax: - vmax = '+oo' - else: - vmax = str(self.vmax) - return '[%s,%s)' % (vmin, vmax) - - def SetVersionRange(self, vmin, vmax): - if vmin is not None: vmin = float(vmin) - if vmax is not None: vmax = float(vmax) - self.vmin = vmin - self.vmax = vmax - - # True, if version falls within the interval [self.vmin, self.vmax) - def IsVersion(self, version): - assert type(version) == float - - if self.vmax and self.vmax <= version: - return False - if self.vmin and self.vmin > version: - return False - if GetOption('version_debug'): - InfoOut.Log('%f is in %s' % (version, self)) - return True - - # True, if interval [vmin, vmax) overlaps interval [self.vmin, self.vmax) - def InRange(self, vmin, vmax): - assert type(vmin) == float - assert type(vmax) == float - assert vmin != vmax - - if self.vmax and self.vmax <= vmin: - return False - if self.vmin and self.vmin >= vmax: - return False - - if GetOption('version_debug'): - InfoOut.Log('%f to %f is in %s' % (vmin, vmax, self)) - return True - - def Error(self, msg): - ReportVersionError(msg) - - def Warning(self, msg): - ReportVersionWarning(msg) - - -# -# Test Code -# -def Main(args): - global errors - - FooXX = IDLVersion(None, None) - Foo1X = IDLVersion(1.0, None) - Foo23 = IDLVersion(2.0, 3.0) - - assert FooXX.IsVersion(0.0) - assert FooXX.IsVersion(1.0) - assert FooXX.InRange(0.0, 0.1) - assert FooXX.InRange(1.0,2.0) - - assert not Foo1X.IsVersion(0.0) - assert Foo1X.IsVersion(1.0) - assert Foo1X.IsVersion(2.0) - - assert not Foo1X.InRange(0.0, 1.0) - assert not Foo1X.InRange(0.5, 1.0) - assert Foo1X.InRange(1.0, 2.0) - assert Foo1X.InRange(2.0, 3.0) - - assert not Foo23.InRange(0.0, 1.0) - assert not Foo23.InRange(0.5, 1.0) - assert not Foo23.InRange(1.0, 2.0) - assert Foo23.InRange(2.0, 3.0) - assert Foo23.InRange(1.0, 2.1) - assert Foo23.InRange(2.9, 4.0) - assert not Foo23.InRange(3.0, 4.0) - - print "Passed" - return 0 - -if __name__ == '__main__': - sys.exit(Main(sys.argv[1:])) - diff --git a/ppapi/generators/test_cgen/interface.idl b/ppapi/generators/test_cgen/interface.idl index e017daf..2072532 100644 --- a/ppapi/generators/test_cgen/interface.idl +++ b/ppapi/generators/test_cgen/interface.idl @@ -5,7 +5,7 @@ */ /** - * This file will test that the IDL snippet matches the comment. + * This file will test that the IDL snippet matches the comment. */ /* struct ist { void* X; }; */ @@ -14,15 +14,21 @@ struct ist { }; /* - * struct iface1 { + * struct iface1 { * 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); + * int32_t (*mem6)(void** ptr); * }; */ interface iface1 { 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); + int32_t mem6([inout] blob_t ptr); }; diff --git a/ppapi/generators/test_cgen/stdint.idl b/ppapi/generators/test_cgen/stdint.idl index 9a8e00b..f63a66a 100644 --- a/ppapi/generators/test_cgen/stdint.idl +++ b/ppapi/generators/test_cgen/stdint.idl @@ -41,11 +41,14 @@ describe { /** 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; }; |