tenfourfox/ipc/ipdl/ipdl/__init__.py

75 lines
2.2 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified' ]
import os, sys
from cStringIO import StringIO
from ipdl.cgen import IPDLCodeGen
from ipdl.lower import LowerToCxx
from ipdl.parser import Parser
from ipdl.type import TypeCheck
from ipdl.cxx.cgen import CxxCodeGen
def parse(specstring, filename='/stdin', includedirs=[ ], errout=sys.stderr):
'''Return an IPDL AST if parsing was successful. Print errors to |errout|
if it is not.'''
# The file type and name are later enforced by the type checker.
# This is just a hint to the parser.
prefix, ext = os.path.splitext(filename)
name = os.path.basename(prefix)
if ext == '.ipdlh':
type = 'header'
else:
type = 'protocol'
return Parser(type, name).parse(specstring, os.path.abspath(filename), includedirs, errout)
def typecheck(ast, errout=sys.stderr):
'''Return True iff |ast| is well typed. Print errors to |errout| if
it is not.'''
return TypeCheck().check(ast, errout)
def gencxx(ipdlfilename, ast, outheadersdir, outcppdir):
headers, cpps = LowerToCxx().lower(ast)
def resolveHeader(hdr):
return [
hdr,
os.path.join(
outheadersdir,
*([ns.name for ns in ast.namespaces] + [hdr.name]))
]
def resolveCpp(cpp):
return [ cpp, os.path.join(outcppdir, cpp.name) ]
for ast, filename in ([ resolveHeader(hdr) for hdr in headers ]
+ [ resolveCpp(cpp) for cpp in cpps ]):
tempfile = StringIO()
CxxCodeGen(tempfile).cgen(ast)
writeifmodified(tempfile.getvalue(), filename)
def genipdl(ast, outdir):
return IPDLCodeGen().cgen(ast)
def writeifmodified(contents, file):
dir = os.path.dirname(file)
os.path.exists(dir) or os.makedirs(dir)
oldcontents = None
if os.path.exists(file):
fd = open(file, 'rb')
oldcontents = fd.read()
fd.close()
if oldcontents != contents:
fd = open(file, 'wb')
fd.write(contents)
fd.close()