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)"""
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IDLRelease for PPAPI
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)This file defines the behavior of the AST namespace which allows for resolving
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)a symbol as one or more AST nodes given a Release or range of Releases.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_log import ErrOut, InfoOut, WarnOut
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_option import GetOption, Option, ParseOptions
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('release_debug', 'Debug Release data')
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('wgap', 'Ignore Release gap warning')
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Module level functions and data used for testing.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error = None
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)warning = None
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ReportReleaseError(msg):
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global error
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = msg
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ReportReleaseWarning(msg):
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global warning
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  warning = msg
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ReportClear():
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global error, warning
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = None
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  warning = None
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLRelease
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLRelease is an object which stores the association of a given symbol
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# name, with an AST node for a range of Releases for that object.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A vmin value of None indicates that the object begins at the earliest
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# available Release number.  The value of vmin is always inclusive.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A vmax value of None indicates that the object is never deprecated, so
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# it exists until it is overloaded or until the latest available Release.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The value of vmax is always exclusive, representing the first Release
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# on which the object is no longer valid.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLRelease(object):
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, rmin, rmax):
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.rmin = rmin
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.rmax = rmax
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __str__(self):
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.rmin:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmin = '0'
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmin = str(self.rmin)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.rmax:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmax = '+oo'
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmax = str(self.rmax)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '[%s,%s)' % (rmin, rmax)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetReleaseRange(self, rmin, rmax):
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.rmin = rmin
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.rmax = rmax
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # True, if Release falls within the interval [self.vmin, self.vmax)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def IsRelease(self, release):
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.rmax and self.rmax <= release:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return False
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.rmin and self.rmin > release:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return False
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if GetOption('release_debug'):
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InfoOut.Log('%f is in %s' % (release, self))
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return True
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # True, if Release falls within the interval [self.vmin, self.vmax)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def InReleases(self, releases):
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not releases: return False
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check last release first, since InRange does not match last item
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.IsRelease(releases[-1]): return True
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if len(releases) > 1:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return self.InRange(releases[0], releases[-1])
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return False
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # True, if interval [vmin, vmax) overlaps interval [self.vmin, self.vmax)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def InRange(self, rmin, rmax):
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert (rmin == None) or rmin < rmax
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # An min of None always passes a min bound test
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # An max of None always passes a max bound test
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if rmin is not None and self.rmax is not None:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.rmax <= rmin:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return False
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if rmax is not None and self.rmin is not None:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.rmin >= rmax:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return False
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if GetOption('release_debug'):
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InfoOut.Log('%f to %f is in %s' % (rmin, rmax, self))
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return True
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetMinMax(self, releases = None):
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not releases:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return self.rmin, self.rmax
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.rmin:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmin = releases[0]
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmin = str(self.rmin)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not self.rmax:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmax = releases[-1]
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rmax = str(self.rmax)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (rmin, rmax)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetMin(self, release):
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert not self.rmin
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.rmin = release
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Error(self, msg):
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportReleaseError(msg)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Warn(self, msg):
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportReleaseWarning(msg)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLReleaseList
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLReleaseList is a list based container for holding IDLRelease
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# objects in order.  The IDLReleaseList can be added to, and searched by
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# range.  Objects are stored in order, and must be added in order.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLReleaseList(object):
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self):
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._nodes = []
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetReleases(self):
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self._nodes
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def FindRelease(self, release):
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for node in self._nodes:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if node.IsRelease(release):
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return node
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return None
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def FindRange(self, rmin, rmax):
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert (rmin == None) or rmin != rmax
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out = []
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for node in self._nodes:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if node.InRange(rmin, rmax):
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        out.append(node)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def AddNode(self, node):
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if GetOption('release_debug'):
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InfoOut.Log('\nAdding %s %s' % (node.Location(), node))
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last = None
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check current releases in that namespace
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for cver in self._nodes:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if GetOption('release_debug'): InfoOut.Log('  Checking %s' % cver)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # We should only be missing a 'release' tag for the first item.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if not node.rmin:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        node.Error('Missing release on overload of previous %s.' %
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   cver.Location())
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return False
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # If the node has no max, then set it to this one
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if not cver.rmax:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cver.rmax = node.rmin
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if GetOption('release_debug'): InfoOut.Log('  Update %s' % cver)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # if the max and min overlap, than's an error
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if cver.rmax > node.rmin:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if node.rmax and cver.rmin >= node.rmax:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          node.Error('Declarations out of order.')
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          node.Error('Overlap in releases: %s vs %s when adding %s' %
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (cver.rmax, node.rmin, node))
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return False
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last = cver
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Otherwise, the previous max and current min should match
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # unless this is the unlikely case of something being only
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # temporarily deprecated.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if last and last.rmax != node.rmin:
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      node.Warn('Gap in release numbers.')
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # If we made it here, this new node must be the 'newest'
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # and does not overlap with anything previously added, so
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # we can add it to the end of the list.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if GetOption('release_debug'): InfoOut.Log('Done %s' % node)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._nodes.append(node)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return True
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# IDLReleaseMap
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A release map, can map from an float interface release, to a global
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# release string.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IDLReleaseMap(object):
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, release_info):
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.version_to_release = {}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.release_to_version = {}
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    self.release_to_channel = {}
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for release, version, channel in release_info:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.version_to_release[version] = release
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.release_to_version[release] = version
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      self.release_to_channel[release] = channel
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.releases = sorted(self.release_to_version.keys())
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.versions = sorted(self.version_to_release.keys())
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetVersion(self, release):
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.release_to_version.get(release, None)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetVersions(self):
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.versions
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetRelease(self, version):
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.version_to_release.get(version, None)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetReleases(self):
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.releases
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetReleaseRange(self):
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (self.releases[0], self.releases[-1])
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetVersionRange(self):
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (self.versions[0], self.version[-1])
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def GetChannel(self, release):
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return self.release_to_channel.get(release, None)
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Test Code
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def TestReleaseNode():
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FooXX = IDLRelease(None, None)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo1X = IDLRelease('M14', None)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo23 = IDLRelease('M15', 'M16')
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert FooXX.IsRelease('M13')
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert FooXX.IsRelease('M14')
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert FooXX.InRange('M13', 'M13A')
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert FooXX.InRange('M14','M15')
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo1X.IsRelease('M13')
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo1X.IsRelease('M14')
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo1X.IsRelease('M15')
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo1X.InRange('M13', 'M14')
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo1X.InRange('M13A', 'M14')
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo1X.InRange('M14', 'M15')
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo1X.InRange('M15', 'M16')
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo23.InRange('M13', 'M14')
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo23.InRange('M13A', 'M14')
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo23.InRange('M14', 'M15')
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo23.InRange('M15', 'M16')
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo23.InRange('M14', 'M15A')
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert Foo23.InRange('M15B', 'M17')
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not Foo23.InRange('M16', 'M17')
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print "TestReleaseNode - Passed"
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def TestReleaseListWarning():
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FooXX = IDLRelease(None, None)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo1X = IDLRelease('M14', None)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo23 = IDLRelease('M15', 'M16')
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo45 = IDLRelease('M17', 'M18')
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Add nodes out of order should fail
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportClear()
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  releases = IDLReleaseList()
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(Foo23)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(Foo45)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert warning
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print "TestReleaseListWarning - Passed"
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def TestReleaseListError():
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FooXX = IDLRelease(None, None)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo1X = IDLRelease('M14', None)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo23 = IDLRelease('M15', 'M16')
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo45 = IDLRelease('M17', 'M18')
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Add nodes out of order should fail
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportClear()
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  releases = IDLReleaseList()
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(FooXX)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(Foo23)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not releases.AddNode(Foo1X)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert error
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print "TestReleaseListError - Passed"
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def TestReleaseListOK():
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FooXX = IDLRelease(None, None)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo1X = IDLRelease('M14', None)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo23 = IDLRelease('M15', 'M16')
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Foo45 = IDLRelease('M17', 'M18')
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Add nodes in order should work
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportClear()
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  releases = IDLReleaseList()
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(FooXX)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(Foo1X)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(Foo23)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert not error and not warning
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.AddNode(Foo45)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert warning
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRelease('M13') == FooXX
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRelease('M14') == Foo1X
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRelease('M15') == Foo23
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRelease('M16') == None
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRelease('M17') == Foo45
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRelease('M18') == None
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRange('M13','M14') == [FooXX]
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRange('M13','M17') == [FooXX, Foo1X, Foo23]
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRange('M16','M17') == []
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert releases.FindRange(None, None) == [FooXX, Foo1X, Foo23, Foo45]
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Verify we can find the correct versions
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print "TestReleaseListOK - Passed"
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def TestReleaseMap():
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print "TestReleaseMap- Passed"
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(args):
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestReleaseNode()
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestReleaseListWarning()
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestReleaseListError()
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestReleaseListOK()
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print "Passed"
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sys.exit(Main(sys.argv[1:]))
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357