tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

make-windows-h-wrapper.py (2938B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 import re
      6 import string
      7 import textwrap
      8 
      9 comment_re = re.compile(r"//[^\n]*\n|/\*.*\*/", re.S)
     10 decl_re = re.compile(
     11    r"""^(.+)\s+        # type
     12                         (\w+)\s*        # name
     13                         (?:\((.*)\))?$  # optional param tys
     14                         """,
     15    re.X | re.S,
     16 )
     17 
     18 
     19 def read_decls(filename):
     20    """Parse & yield C-style decls from an input file"""
     21    with open(filename) as fd:
     22        # Strip comments from the source text.
     23        text = comment_re.sub("", fd.read())
     24 
     25        # Parse individual declarations.
     26        raw_decls = [d.strip() for d in text.split(";") if d.strip()]
     27        for raw in raw_decls:
     28            match = decl_re.match(raw)
     29            if match is None:
     30                raise "Invalid decl: %s" % raw
     31 
     32            ty, name, params = match.groups()
     33            if params is not None:
     34                params = [a.strip() for a in params.split(",") if a.strip()]
     35            yield ty, name, params
     36 
     37 
     38 def generate(fd, consts_path, unicodes_path, template_path, compiler):
     39    # Parse the template
     40    with open(template_path) as template_fd:
     41        template = string.Template(template_fd.read())
     42 
     43    decls = ""
     44 
     45    # Each constant should be saved to a temporary, and then re-assigned to a
     46    # constant with the correct name, allowing the value to be determined by
     47    # the actual definition.
     48    for ty, name, args in read_decls(consts_path):
     49        assert args is None, "parameters in const decl!"
     50 
     51        decls += textwrap.dedent(
     52            f"""
     53            #ifdef {name}
     54            constexpr {ty} _tmp_{name} = {name};
     55            #undef {name}
     56            constexpr {ty} {name} = _tmp_{name};
     57            #endif
     58            """
     59        )
     60 
     61    # Each unicode declaration defines a static inline function with the
     62    # correct types which calls the 'A' or 'W'-suffixed versions of the
     63    # function. Full types are required here to ensure that '0' to 'nullptr'
     64    # coersions are preserved.
     65    for ty, name, args in read_decls(unicodes_path):
     66        assert args is not None, "argument list required for unicode decl"
     67 
     68        # Parameter & argument string list
     69        params = ", ".join("%s a%d" % (ty, i) for i, ty in enumerate(args))
     70        args = ", ".join("a%d" % i for i in range(len(args)))
     71 
     72        decls += textwrap.dedent(
     73            f"""
     74            #ifdef {name}
     75            #undef {name}
     76            static inline {ty} WINAPI
     77            {name}({params})
     78            #ifdef UNICODE
     79            {{
     80              return {name}W({args});
     81            }}
     82            #else
     83            = delete;
     84            #endif
     85            #endif
     86            """
     87        )
     88 
     89    # Write out the resulting file
     90    fd.write(template.substitute(decls=decls))