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/.
5 from __future__
import absolute_import
9 from system_header_util
import header_path
11 comment_re
= re
.compile(r
'//[^\n]*\n|/\*.*\*/', re
.S
)
12 decl_re
= re
.compile(r
'''^(.+)\s+ # type
14 (?:\((.*)\))?$ # optional param tys
18 def read_decls(filename
):
19 """Parse & yield C-style decls from an input file"""
20 with
open(filename
, 'r') as fd
:
21 # Strip comments from the source text.
22 text
= comment_re
.sub('', fd
.read())
24 # Parse individual declarations.
25 raw_decls
= [d
.strip() for d
in text
.split(';') if d
.strip()]
27 match
= decl_re
.match(raw
)
29 raise "Invalid decl: %s" % raw
31 ty
, name
, params
= match
.groups()
32 if params
is not None:
33 params
= [a
.strip() for a
in params
.split(',') if a
.strip()]
34 yield ty
, name
, params
37 def generate(fd
, consts_path
, unicodes_path
, template_path
, compiler
):
39 with
open(template_path
, 'r') as template_fd
:
40 template
= string
.Template(template_fd
.read())
44 # Each constant should be saved to a temporary, and then re-assigned to a
45 # constant with the correct name, allowing the value to be determined by
46 # the actual definition.
47 for ty
, name
, args
in read_decls(consts_path
):
48 assert args
is None, "parameters in const decl!"
50 decls
+= textwrap
.dedent("""
52 constexpr {ty} _tmp_{name} = {name};
54 constexpr {ty} {name} = _tmp_{name};
56 """.format(ty
=ty
, name
=name
))
58 # Each unicode declaration defines a static inline function with the
59 # correct types which calls the 'A' or 'W'-suffixed versions of the
60 # function. Full types are required here to ensure that '0' to 'nullptr'
61 # coersions are preserved.
62 for ty
, name
, args
in read_decls(unicodes_path
):
63 assert args
is not None, "argument list required for unicode decl"
65 # Parameter & argument string list
66 params
= ', '.join('%s a%d' % (ty
, i
) for i
, ty
in enumerate(args
))
67 args
= ', '.join('a%d' % i
for i
in range(len(args
)))
69 decls
+= textwrap
.dedent("""
72 static inline {ty} WINAPI
76 return {name}W({args});
78 return {name}A({args});
82 """.format(ty
=ty
, name
=name
, params
=params
, args
=args
))
84 path
= header_path('windows.h', compiler
)
86 # Write out the resulting file
87 fd
.write(template
.substitute(header_path
=path
, decls
=decls
))