Home | History | Annotate | Download | only in scripts
      1 #!/usr/bin/python
      2 #
      3 # Copyright (C) 2009 Google Inc. All rights reserved.
      4 # 
      5 # Redistribution and use in source and binary forms, with or without
      6 # modification, are permitted provided that the following conditions are
      7 # met:
      8 # 
      9 #     * Redistributions of source code must retain the above copyright
     10 # notice, this list of conditions and the following disclaimer.
     11 #     * Redistributions in binary form must reproduce the above
     12 # copyright notice, this list of conditions and the following disclaimer
     13 # in the documentation and/or other materials provided with the
     14 # distribution.
     15 #     * Neither the name of Google Inc. nor the names of its
     16 # contributors may be used to endorse or promote products derived from
     17 # this software without specific prior written permission.
     18 # 
     19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 #
     31 # Copyright (c) 2009 The Chromium Authors. All rights reserved.
     32 # Use of this source code is governed by a BSD-style license that can be
     33 # found in the LICENSE file.
     34 
     35 # usage: rule_bison.py INPUT_FILE OUTPUT_DIR
     36 # INPUT_FILE is a path to either CSSGrammar.y or XPathGrammar.y.
     37 # OUTPUT_DIR is where the bison-generated .cpp and .h files should be placed.
     38 
     39 import errno
     40 import os
     41 import os.path
     42 import subprocess
     43 import sys
     44 
     45 assert len(sys.argv) == 3
     46 
     47 inputFile = sys.argv[1]
     48 outputDir = sys.argv[2]
     49 
     50 inputName = os.path.basename(inputFile)
     51 assert inputName == 'CSSGrammar.y' or inputName == 'XPathGrammar.y'
     52 prefix = {'CSSGrammar.y': 'cssyy', 'XPathGrammar.y': 'xpathyy'}[inputName]
     53 
     54 (inputRoot, inputExt) = os.path.splitext(inputName)
     55 
     56 # The generated .h will be in a different location depending on the bison
     57 # version.
     58 outputHTries = [
     59     os.path.join(outputDir, inputRoot + '.cpp.h'),
     60     os.path.join(outputDir, inputRoot + '.hpp'),
     61 ]
     62 
     63 for outputHTry in outputHTries:
     64     try:
     65         os.unlink(outputHTry)
     66     except OSError, e:
     67         if e.errno != errno.ENOENT:
     68             raise
     69 
     70 outputCpp = os.path.join(outputDir, inputRoot + '.cpp')
     71 
     72 returnCode = subprocess.call(['bison', '-d', '-p', prefix, inputFile, '-o', outputCpp])
     73 assert returnCode == 0
     74 
     75 # Find the name that bison used for the generated header file.
     76 outputHTmp = None
     77 for outputHTry in outputHTries:
     78     try:
     79         os.stat(outputHTry)
     80         outputHTmp = outputHTry
     81         break
     82     except OSError, e:
     83         if e.errno != errno.ENOENT:
     84             raise
     85 
     86 assert outputHTmp != None
     87 
     88 # Read the header file in under the generated name and remove it.
     89 outputHFile = open(outputHTmp)
     90 outputHContents = outputHFile.read()
     91 outputHFile.close()
     92 os.unlink(outputHTmp)
     93 
     94 # Rewrite the generated header with #include guards.
     95 outputH = os.path.join(outputDir, inputRoot + '.h')
     96 
     97 outputHFile = open(outputH, 'w')
     98 print >>outputHFile, '#ifndef %sH' % inputRoot
     99 print >>outputHFile, '#define %sH' % inputRoot
    100 print >>outputHFile, outputHContents
    101 print >>outputHFile, '#endif'
    102 outputHFile.close()
    103