Source code
Revision control
Copy as Markdown
Other Tools
# 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
import argparse
import os
import re
import sys
import mozpack.path as mozpath
from buildconfig import topobjdir, topsrcdir
from mozbuild.backend.configenvironment import PartialConfigEnvironment
def process_define_file(output, input):
"""Creates the given config header. A config header is generated by
taking the corresponding source file and replacing some *#define/#undef*
occurences:
- "#undef NAME" is turned into "#define NAME VALUE"
- "#define NAME" is unchanged
- "#define NAME ORIGINAL_VALUE" is turned into "#define NAME VALUE"
- "#undef UNKNOWN_NAME" is turned into "/* #undef UNKNOWN_NAME */"
- Whitespaces are preserved.
As a special rule, "#undef ALLDEFINES" is turned into "#define NAME
VALUE" for all the defined variables.
"""
path = os.path.abspath(input)
config = PartialConfigEnvironment(topobjdir)
if mozpath.basedir(
path, [mozpath.join(topsrcdir, "js/src")]
) and not config.substs.get("JS_STANDALONE"):
config = PartialConfigEnvironment(mozpath.join(topobjdir, "js", "src"))
with open(path, "r") as input:
r = re.compile(
r"^\s*#\s*(?P<cmd>[a-z]+)(?:\s+(?P<name>\S+)(?:\s+(?P<value>\S+))?)?", re.U
)
for l in input:
m = r.match(l)
if m:
cmd = m.group("cmd")
name = m.group("name")
value = m.group("value")
if name:
if name == "ALLDEFINES":
if cmd == "define":
raise Exception(
"`#define ALLDEFINES` is not allowed in a "
"CONFIGURE_DEFINE_FILE"
)
def define_for_name(name, val):
"""WebRTC files like to define WINVER and _WIN32_WINNT
via the command line, which raises a mass of macro
redefinition warnings. Just handle those macros
specially here."""
define = "#define {name} {val}".format(name=name, val=val)
if name in ("_WIN32_IE", "_WIN32_WINNT", "WIN32", "WINVER"):
return "#if !defined({name})\n{define}\n#endif".format(
name=name, define=define
)
return define
defines = "\n".join(
sorted(
define_for_name(name, val)
for name, val in config.defines["ALLDEFINES"].items()
)
)
l = l[: m.start("cmd") - 1] + defines + l[m.end("name") :]
elif cmd == "define":
if value and name in config.defines:
l = (
l[: m.start("value")]
+ str(config.defines[name])
+ l[m.end("value") :]
)
elif cmd == "undef":
if name in config.defines:
l = (
l[: m.start("cmd")]
+ "define"
+ l[m.end("cmd") : m.end("name")]
+ " "
+ str(config.defines[name])
+ l[m.end("name") :]
)
else:
l = "/* " + l[: m.end("name")] + " */" + l[m.end("name") :]
output.write(l)
deps = {path}
deps.update(config.get_dependencies())
return deps
def main(argv):
parser = argparse.ArgumentParser(description="Process define files.")
parser.add_argument("input", help="Input define file.")
args = parser.parse_args(argv)
return process_define_file(sys.stdout, args.input)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))