15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Nodes for PPAPI IDL AST"""
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDL Node
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDL Node defines the IDLAttribute and IDLNode objects which are constructed
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# by the parser as it processes the various 'productions'.  The IDLAttribute
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# objects are assigned to the IDLNode's property dictionary instead of being
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# applied as children of The IDLNodes, so they do not exist in the final tree.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The AST of IDLNodes is the output from the parsing state and will be used
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# as the source data by the various generators.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import hashlib
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_log import ErrOut, InfoOut, WarnOut
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_propertynode import IDLPropertyNode
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_namespace import IDLNamespace
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_release import IDLRelease, IDLReleaseMap
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLAttribute
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A temporary object used by the parsing process to hold an Extended Attribute
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# which will be passed as a child to a standard IDLNode.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLAttribute(object):
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, name, value):
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.cls = 'ExtAttribute'
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.name = name
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.value = value
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __str__(self):
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '%s=%s' % (self.name, self.value)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLNode
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This class implements the AST tree, providing the associations between
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# parents and children.  It also contains a namepsace and propertynode to
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# allow for look-ups.  IDLNode is derived from IDLRelease, so it is
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# version aware.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLNode(IDLRelease):
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Set of object IDLNode types which have a name and belong in the namespace.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NamedSet = set(['Enum', 'EnumItem', 'File', 'Function', 'Interface',
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  'Member', 'Param', 'Struct', 'Type', 'Typedef'])
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  show_versions = False
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, cls, filename, lineno, pos, children=None):
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Initialize with no starting or ending Version
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDLRelease.__init__(self, None, None)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.cls = cls
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.lineno = lineno
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.pos = pos
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.filename = filename
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.filenode = None
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.hashes = {}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.deps = {}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.errors = 0
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.namespace = None
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.typelist = None
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.parent = None
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.property_node = IDLPropertyNode()
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    self.unique_releases = None
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # A list of unique releases for this node
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.releases = None
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # A map from any release, to the first unique release
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.first_release = None
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # self.children is a list of children ordered as defined
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.children = []
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Process the passed in list of children, placing ExtAttributes into the
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # property dictionary, and nodes into the local child list in order.  In
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # addition, add nodes to the namespace if the class is in the NamedSet.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not children: children = []
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in children:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if child.cls == 'ExtAttribute':
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.SetProperty(child.name, child.value)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.AddChild(child)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# String related functions
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Return a string representation of this node
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __str__(self):
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = self.GetName()
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ver = IDLRelease.__str__(self)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name is None: name = ''
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not IDLNode.show_versions: ver = ''
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '%s(%s%s)' % (self.cls, name, ver)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Return file and line number for where node was defined
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Location(self):
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '%s(%d)' % (self.filename, self.lineno)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Log an error for this object
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Error(self, msg):
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.errors += 1
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.LogLine(self.filename, self.lineno, 0, ' %s %s' %
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   (str(self), msg))
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.filenode:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      errcnt = self.filenode.GetProperty('ERRORS', 0)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.filenode.SetProperty('ERRORS', errcnt + 1)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Log a warning for this object
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Warning(self, msg):
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WarnOut.LogLine(self.filename, self.lineno, 0, ' %s %s' %
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    (str(self), msg))
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetName(self):
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.GetProperty('NAME')
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetNameVersion(self):
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = self.GetProperty('NAME', default='')
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ver = IDLRelease.__str__(self)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '%s%s' % (name, ver)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Dump this object and its children
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Dump(self, depth=0, comments=False, out=sys.stdout):
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.cls in ['Comment', 'Copyright']:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_comment = True
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_comment = False
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Skip this node if it's a comment, and we are not printing comments
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not comments and is_comment: return
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab = ''.rjust(depth * 2)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if is_comment:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.write('%sComment\n' % tab)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for line in self.GetName().split('\n'):
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        out.write('%s  "%s"\n' % (tab, line))
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ver = IDLRelease.__str__(self)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.releases:
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_list = ': ' + ' '.join(self.releases)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        release_list = ': undefined'
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.write('%s%s%s%s\n' % (tab, self, ver, release_list))
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.typelist:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.write('%s  Typelist: %s\n' % (tab, self.typelist.GetReleases()[0]))
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    properties = self.property_node.GetPropertyList()
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if properties:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.write('%s  Properties\n' % tab)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for p in properties:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if is_comment and p == 'NAME':
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          # Skip printing the name for comments, since we printed above already
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        out.write('%s    %s : %s\n' % (tab, p, self.GetProperty(p)))
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in self.children:
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      child.Dump(depth+1, comments=comments, out=out)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Search related functions
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Check if node is of a given type
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def IsA(self, *typelist):
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.cls in typelist: return True
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return False
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Get a list of objects for this key
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetListOf(self, *keys):
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out = []
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in self.children:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if child.cls in keys: out.append(child)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetOneOf(self, *keys):
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out = self.GetListOf(*keys)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if out: return out[0]
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return None
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetParent(self, parent):
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.property_node.AddParent(parent)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.parent = parent
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def AddChild(self, node):
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    node.SetParent(self)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.children.append(node)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Get a list of all children
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetChildren(self):
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.children
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Get a list of all children of a given version
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetChildrenVersion(self, version):
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out = []
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in self.children:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if child.IsVersion(version): out.append(child)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Get a list of all children in a given range
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetChildrenRange(self, vmin, vmax):
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out = []
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in self.children:
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if child.IsRange(vmin, vmax): out.append(child)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def FindVersion(self, name, version):
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    node = self.namespace.FindNode(name, version)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not node and self.parent:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      node = self.parent.FindVersion(name, version)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return node
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def FindRange(self, name, vmin, vmax):
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nodes = self.namespace.FindNodes(name, vmin, vmax)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not nodes and self.parent:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nodes = self.parent.FindVersion(name, vmin, vmax)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return nodes
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetType(self, release):
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.typelist: return None
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.typelist.FindRelease(release)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetHash(self, release):
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hashval = self.hashes.get(release, None)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if hashval is None:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hashval = hashlib.sha1()
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hashval.update(self.cls)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for key in self.property_node.GetPropertyList():
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        val = self.GetProperty(key)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hashval.update('%s=%s' % (key, str(val)))
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typeref = self.GetType(release)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if typeref:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hashval.update(typeref.GetHash(release))
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for child in self.GetChildren():
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.IsA('Copyright', 'Comment', 'Label'): continue
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not child.IsRelease(release):
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hashval.update( child.GetHash(release) )
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.hashes[release] = hashval
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hashval.hexdigest()
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetDeps(self, release, visited=None):
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visited = visited or set()
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # If this release is not valid for this object, then done.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.IsRelease(release) or self.IsA('Comment', 'Copyright'):
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return set([])
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # If we have cached the info for this release, return the cached value
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    deps = self.deps.get(release, None)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if deps is not None:
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return deps
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # If we are already visited, then return
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self in visited:
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return set([self])
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Otherwise, build the dependency list
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visited |= set([self])
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    deps = set([self])
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Get child deps
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in self.GetChildren():
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      deps |= child.GetDeps(release, visited)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visited |= set(deps)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Get type deps
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typeref = self.GetType(release)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if typeref:
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      deps |= typeref.GetDeps(release, visited)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.deps[release] = deps
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return deps
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetVersion(self, release):
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filenode = self.GetProperty('FILE')
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not filenode:
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return None
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return filenode.release_map.GetVersion(release)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetUniqueReleases(self, releases):
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Return the unique set of first releases corresponding to input
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Since we are returning the corresponding 'first' version for a
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    release, we may return a release version prior to the one in the list."""
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_min, my_max = self.GetMinMax(releases)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if my_min > releases[-1] or my_max < releases[0]:
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return []
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out = set()
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for rel in releases:
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      remapped = self.first_release[rel]
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if not remapped: continue
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out |= set([remapped])
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    # Cache the most recent set of unique_releases
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    self.unique_releases = sorted(out)
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return self.unique_releases
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  def LastRelease(self, release):
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    # Get the most recent release from the most recently generated set of
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    # cached unique releases.
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if self.unique_releases and self.unique_releases[-1] > release:
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return False
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return True
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetRelease(self, version):
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filenode = self.GetProperty('FILE')
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not filenode:
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return None
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return filenode.release_map.GetRelease(version)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _GetReleases(self, releases):
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.releases:
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      my_min, my_max = self.GetMinMax(releases)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      my_releases = [my_min]
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if my_max != releases[-1]:
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        my_releases.append(my_max)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      my_releases = set(my_releases)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for child in self.GetChildren():
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.IsA('Copyright', 'Comment', 'Label'):
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        my_releases |= child.GetReleases(releases)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.releases = my_releases
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.releases
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _GetReleaseList(self, releases, visited=None):
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visited = visited or set()
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.releases:
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # If we are unversionable, then return first available release
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.IsA('Comment', 'Copyright', 'Label'):
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.releases = []
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self.releases
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Generate the first and if deprecated within this subset, the
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # last release for this node
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      my_min, my_max = self.GetMinMax(releases)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if my_max != releases[-1]:
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        my_releases = set([my_min, my_max])
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        my_releases = set([my_min])
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Break cycle if we reference ourselves
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self in visited:
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return [my_min]
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visited |= set([self])
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # Files inherit all their releases from items in the file
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.IsA('AST', 'File'):
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        my_releases = set()
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Visit all children
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      child_releases = set()
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      # Exclude sibling results from parent visited set
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cur_visits = visited
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for child in self.children:
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        child_releases |= set(child._GetReleaseList(releases, cur_visits))
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        visited |= set(child_releases)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Visit my type
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type_releases = set()
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.typelist:
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type_list = self.typelist.GetReleases()
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for typenode in type_list:
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          type_releases |= set(typenode._GetReleaseList(releases, cur_visits))
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type_release_list = sorted(type_releases)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if my_min < type_release_list[0]:
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          type_node = type_list[0]
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          self.Error('requires %s in %s which is undefined at %s.' % (
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              type_node, type_node.filename, my_min))
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for rel in child_releases | type_releases:
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if rel >= my_min and rel <= my_max:
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          my_releases |= set([rel])
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.releases = sorted(my_releases)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.releases
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetReleaseList(self):
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.releases
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def BuildReleaseMap(self, releases):
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unique_list = self._GetReleaseList(releases)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    my_min, my_max = self.GetMinMax(releases)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.first_release = {}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_rel = None
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for rel in releases:
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if rel in unique_list:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_rel = rel
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.first_release[rel] = last_rel
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if rel == my_max:
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_rel = None
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetProperty(self, name, val):
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.property_node.SetProperty(name, val)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetProperty(self, name, default=None):
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.property_node.GetProperty(name, default)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Traverse(self, data, func):
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    func(self, data)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for child in self.children:
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      child.Traverse(data, func)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLFile
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A specialized version of IDLNode which tracks errors and warnings.
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLFile(IDLNode):
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, name, children, errors=0):
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attrs = [IDLAttribute('NAME', name),
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             IDLAttribute('ERRORS', errors)]
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not children: children = []
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDLNode.__init__(self, 'File', name, 1, 0, attrs + children)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.release_map = IDLReleaseMap([('M13', 1.0)])
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Tests
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def StringTest():
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  errors = 0
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name_str = 'MyName'
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  text_str = 'MyNode(%s)' % name_str
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name_node = IDLAttribute('NAME', name_str)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  node = IDLNode('MyNode', 'no file', 1, 0, [name_node])
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if node.GetName() != name_str:
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('GetName returned >%s< not >%s<' % (node.GetName(), name_str))
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if node.GetProperty('NAME') != name_str:
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Failed to get name property.')
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if str(node) != text_str:
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('str() returned >%s< not >%s<' % (str(node), text_str))
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if not errors: InfoOut.Log('Passed StringTest')
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return errors
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ChildTest():
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  errors = 0
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child = IDLNode('child', 'no file', 1, 0)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent = IDLNode('parent', 'no file', 1, 0, [child])
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if child.parent != parent:
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Failed to connect parent.')
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [child] != parent.GetChildren():
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Failed GetChildren.')
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if child != parent.GetOneOf('child'):
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Failed GetOneOf(child)')
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if parent.GetOneOf('bogus'):
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Failed GetOneOf(bogus)')
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if not parent.IsA('parent'):
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Expecting parent type')
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent = IDLNode('parent', 'no file', 1, 0, [child, child])
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [child, child] != parent.GetChildren():
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Failed GetChildren2.')
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors += 1
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if not errors: InfoOut.Log('Passed ChildTest')
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return errors
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main():
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  errors = StringTest()
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  errors += ChildTest()
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if errors:
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('IDLNode failed with %d errors.' % errors)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return  -1
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sys.exit(Main())
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501