123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- # 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()
|