1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# 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/.
import sys
import string
import argparse
import subprocess
import buildconfig
from mozbuild import shellutil
def get_properties(preprocessorHeader):
cpp = list(buildconfig.substs['CPP'])
cpp += shellutil.split(buildconfig.substs['ACDEFINES'])
cpp.append(preprocessorHeader)
preprocessed = subprocess.check_output(cpp)
properties = [{"name":p[0], "prop":p[1], "id":p[2],
"flags":p[3], "pref":p[4], "proptype":p[5]}
for (i, p) in enumerate(eval(preprocessed))]
# Sort the list so that longhand and logical properties are intermingled
# first, shorthand properties follow, then aliases appear last. This matches
# the order of the nsCSSPropertyID enum.
def property_compare(x, y):
property_order = {"longhand": 0, "logical": 0, "shorthand": 1, "alias": 2}
return property_order[x["proptype"]] - property_order[y["proptype"]]
properties = sorted(properties, cmp=property_compare)
for i, p in enumerate(properties):
p["index"] = i
# Record each property's IDL name.
for p in properties:
if "CSS_PROPERTY_INTERNAL" in p["flags"]:
p["idlname"] = None
else:
idl_name = p["prop"]
if not idl_name.startswith("Moz"):
idl_name = idl_name[0].lower() + idl_name[1:]
p["idlname"] = idl_name
return properties
def generate_idl_names(properties):
names = []
for p in properties:
if p["proptype"] is "alias":
continue
if p["idlname"] is None:
names.append(" nullptr, // %s" % p["name"])
else:
names.append(' "%s",' % p["idlname"])
return "\n".join(names)
def generate_assertions(properties):
def enum(p):
if p["proptype"] is "alias":
return "eCSSPropertyAlias_%s" % p["prop"]
else:
return "eCSSProperty_%s" % p["id"]
msg = ('static_assert(%s == %d, "GenerateCSSPropsGenerated.py did not list '
'properties in nsCSSPropertyID order");')
return "\n".join(map(lambda p: msg % (enum(p), p["index"]), properties))
def generate_idl_name_positions(properties):
# Skip aliases.
ps = filter(lambda p: p["proptype"] is not "alias", properties)
# Sort alphabetically by IDL name.
ps = sorted(ps, key=lambda p: p["idlname"])
# Annotate entries with the sorted position.
ps = [(p, position) for position, p in enumerate(ps)]
# Sort back to nsCSSPropertyID order.
ps = sorted(ps, key=lambda (p, position): p["index"])
return ",\n".join(map(lambda (p, position): " %d" % position, ps))
def generate(output, cppTemplate, preprocessorHeader):
cppFile = open(cppTemplate, "r")
cppTemplate = cppFile.read()
cppFile.close()
properties = get_properties(preprocessorHeader)
substitutions = {
"idl_names": generate_idl_names(properties),
"assertions": generate_assertions(properties),
"idl_name_positions": generate_idl_name_positions(properties),
}
output.write("/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT */\n\n" +
string.Template(cppTemplate).substitute(substitutions) + "\n")
def main():
parser = argparse.ArgumentParser()
parser.add_argument('cppTemplate', help='CSS property file template')
parser.add_argument('preprocessorHeader', help='Header file to pass through the preprocessor')
args = parser.parse_args()
generate(sys.stdout, args.cppTemplate, args.preprocessorHeader)
if __name__ == '__main__':
main()
|