ipc/ipdl/ipdl/__init__.py
author Mozilla Releng Treescript <release+treescript@mozilla.org>
Sun, 14 Aug 2022 06:58:56 +0000
changeset 627100 f15ce650cede3f50cc2712c1eb897526d9f34ed2
parent 554551 994ae8e4833c90447d91f0e26a718573cff5a514
permissions -rw-r--r--
no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD be -> f8d708ec976f0c6949dc5a7135570a79ebad5cb9 gd -> 1abaa21bbf83ec442f19e1dd2ae75e3fd6658ccd ja -> 9f2407ac297073bdf173c52fab5f6c0b151bfbd7 ja-JP-mac -> 404acecd735eac85d8c91b42e9bbf318c2bcaf2a kab -> 81aa9e5c8799985dc1e8b9de4e416f85c0b87044 ko -> 1b89af852b036b01f30c727eb391a367b05f8461 pa-IN -> 3addbcc315447474049b59494d85d19271dd1e93 pt-BR -> 48edfa2c0e2d0ff2ed1f195febe937baa0f056d1 tg -> 2d48aea8bfe21cda327804773236e244f604d7f2

# 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/.

from __future__ import print_function

__all__ = [
    "gencxx",
    "genipdl",
    "parse",
    "typecheck",
    "writeifmodified",
    "checkSyncMessage",
    "checkFixedSyncMessages",
]

import os
import sys
from io import StringIO

from ipdl.cgen import IPDLCodeGen
from ipdl.lower import LowerToCxx, msgenums
from ipdl.parser import Parser, ParseError
from ipdl.type import TypeCheck
from ipdl.checker import checkSyncMessage, checkFixedSyncMessages

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"

    try:
        return Parser(type, name).parse(
            specstring, os.path.abspath(filename), includedirs
        )
    except ParseError as p:
        print(p, file=errout)
        return None


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, segmentcapacitydict):
    headers, cpps = LowerToCxx().lower(ast, segmentcapacitydict)

    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 genmsgenum(ast):
    return msgenums(ast.protocol, pretty=True)


def writeifmodified(contents, file):
    contents = contents.encode("utf-8")
    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()