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)import sys
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_log import ErrOut, InfoOut, WarnOut
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_option import GetOption, Option, ParseOptions
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from idl_parser import ParseFiles
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GeneratorList = []
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Option('out', 'List of output files', default='')
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('release', 'Which release to generate.', default='')
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Option('range', 'Which ranges in the form of MIN,MAX.', default='start,end')
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Generator(object):
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Base class for generators.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  This class provides a mechanism for adding new generator objects to the IDL
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  driver.  To use this class override the GenerateRelease and GenerateRange
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  members, and instantiate one copy of the class in the same module which
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  defines it to register the generator.  After the AST is generated, call the
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static Run member which will check every registered generator to see which
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ones have been enabled through command-line options.  To enable a generator
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  use the switches:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --<sname> : To enable with defaults
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --<sname>_opt=<XXX,YYY=y> : To enable with generator specific options.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTE:  Generators still have access to global options
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, name, sname, desc):
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.name = name
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.run_switch = Option(sname, desc)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.opt_switch = Option(sname + '_opt', 'Options for %s.' % sname,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             default='')
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GeneratorList.append(self)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.errors = 0
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.skip_list = []
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Error(self, msg):
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrOut.Log('Error %s : %s' % (self.name, msg))
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.errors += 1
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetRunOptions(self):
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    options = {}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    option_list = self.opt_switch.Get()
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if option_list:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      option_list = option_list.split(',')
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for opt in option_list:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        offs = opt.find('=')
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if offs > 0:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          options[opt[:offs]] = opt[offs+1:]
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          options[opt] = True
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return options
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.run_switch.Get():
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return options
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return None
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Generate(self, ast, options):
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.errors = 0
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rangestr = GetOption('range')
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    releasestr = GetOption('release')
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "Found releases: %s" % ast.releases
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Generate list of files to ignore due to errors
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for filenode in ast.GetListOf('File'):
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # If this file has errors, skip it
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if filenode.GetProperty('ERRORS') > 0:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.skip_list.append(filenode)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check for a range option which over-rides a release option
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not releasestr and rangestr:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      range_list = rangestr.split(',')
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if len(range_list) != 2:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.Error('Failed to generate for %s, incorrect range: "%s"' %
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   (self.name, rangestr))
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vmin = range_list[0]
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vmax = range_list[1]
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Generate 'start' and 'end' represent first and last found.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if vmin == 'start':
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            vmin = ast.releases[0]
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if vmax == 'end':
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            vmax = ast.releases[-1]
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vmin = ast.releases.index(vmin)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vmax = ast.releases.index(vmax) + 1
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        releases = ast.releases[vmin:vmax]
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InfoOut.Log('Generate range %s of %s.' % (rangestr, self.name))
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = self.GenerateRange(ast, releases, options)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ret < 0:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          self.Error('Failed to generate range %s : %s.' %(vmin, vmax))
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          InfoOut.Log('%s wrote %d files.' % (self.name, ret))
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Otherwise this should be a single release generation
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if releasestr == 'start':
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        releasestr = ast.releases[0]
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if releasestr == 'end':
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        releasestr = ast.releases[-1]
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if releasestr > ast.releases[-1]:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InfoOut.Log('There is no unique release for %s, using last release.' %
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    releasestr)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        releasestr = ast.releases[-1]
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if releasestr not in ast.releases:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.Error('Release %s not in [%s].' %
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   (releasestr, ', '.join(ast.releases)))
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if releasestr:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InfoOut.Log('Generate release %s of %s.' % (releasestr, self.name))
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = self.GenerateRelease(ast, releasestr, options)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ret < 0:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          self.Error('Failed to generate release %s.' % releasestr)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          InfoOut.Log('%s wrote %d files.' % (self.name, ret))
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.Error('No range or release specified for %s.' % releasestr)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.errors
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateRelease(self, ast, release, options):
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __pychecker__ = 'unusednames=ast,release,options'
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Error("Undefined release generator.")
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateRange(self, ast, releases, options):
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __pychecker__ = 'unusednames=ast,releases,options'
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Error("Undefined range generator.")
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  @staticmethod
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Run(ast):
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fail_count = 0
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Check all registered generators if they should run.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for gen in GeneratorList:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      options = gen.GetRunOptions()
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if options is not None:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if gen.Generate(ast, options):
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          fail_count += 1
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fail_count
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GeneratorByFile(Generator):
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """A simplified generator that generates one output file per IDL source file.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  A subclass of Generator for use of generators which have a one to one
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapping between IDL sources and output files.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Derived classes should define GenerateFile.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateFile(self, filenode, releases, options):
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Generates an output file from the IDL source.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns true if the generated file is different than the previously
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generated file.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __pychecker__ = 'unusednames=filenode,releases,options'
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Error("Undefined release generator.")
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateRelease(self, ast, release, options):
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.GenerateRange(ast, [release], options)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateRange(self, ast, releases, options):
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Get list of out files
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outlist = GetOption('out')
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if outlist: outlist = outlist.split(',')
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skipList = []
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cnt = 0
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for filenode in ast.GetListOf('File'):
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Ignore files with errors
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if filenode in self.skip_list:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Skip this file if not required
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if outlist and filenode.GetName() not in outlist:
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Create the output file and increment out count if there was a delta
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.GenerateFile(filenode, releases, options):
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cnt = cnt + 1
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for filenode in skipList:
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      errcnt = filenode.GetProperty('ERRORS')
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ErrOut.Log('%s : Skipped because of %d errors.' % (
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          filenode.GetName(), errcnt))
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if skipList:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return -len(skipList)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if GetOption('diff'):
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return -cnt
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cnt
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)check_release = 0
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)check_range = 0
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GeneratorReleaseTest(Generator):
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateRelease(self, ast, release, options = {}):
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __pychecker__ = 'unusednames=ast,release,options'
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global check_release
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    check_map = {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'so_long': True,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'MyOpt': 'XYZ',
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'goodbye': True
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    check_release = 1
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for item in check_map:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      check_item = check_map[item]
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      option_item = options.get(item, None)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if check_item != option_item:
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print 'Option %s is %s, expecting %s' % (item, option_item, check_item)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        check_release = 0
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if release != 'M14':
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      check_release = 0
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return check_release == 1
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GenerateRange(self, ast, releases, options):
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __pychecker__ = 'unusednames=ast,releases,options'
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global check_range
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    check_range = 1
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return True
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Test():
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __pychecker__ = 'unusednames=args'
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global check_release
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global check_range
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParseOptions(['--testgen_opt=so_long,MyOpt=XYZ,goodbye'])
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if Generator.Run('AST') != 0:
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print 'Generate release: Failed.\n'
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if check_release != 1 or check_range != 0:
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print 'Gererate release: Failed to run.\n'
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  check_release = 0
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParseOptions(['--testgen_opt="HELLO"', '--range=M14,M16'])
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if Generator.Run('AST') != 0:
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print 'Generate range: Failed.\n'
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if check_release != 0 or check_range != 1:
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print 'Gererate range: Failed to run.\n'
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  print 'Generator test: Pass'
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(args):
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if not args: return Test()
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filenames = ParseOptions(args)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ast = ParseFiles(filenames)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Generator.Run(ast)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GeneratorReleaseTest('Test Gen', 'testgen', 'Generator Class Test.')
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sys.exit(Main(sys.argv[1:]))
278