mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 00:50:22 +00:00
050ffddff3
The `gn` build did not generate the CMake configuration file for the backtrace module. Update the rules to configure the generated macros mirroring the CMake build.
121 lines
4.1 KiB
Python
121 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
r"""Emulates the bits of CMake's configure_file() function needed in serenity.
|
|
|
|
The CMake build uses configure_file() for several things. This emulates that
|
|
function for the GN build. In the GN build, this runs at build time instead
|
|
of at generator time.
|
|
|
|
Takes a list of KEY=VALUE pairs (where VALUE can be empty).
|
|
|
|
The sequence `\` `n` in each VALUE is replaced by a newline character.
|
|
|
|
On each line, replaces '${KEY}' or '@KEY@' with VALUE.
|
|
|
|
Then, handles these special cases (note that FOO= sets the value of FOO to the
|
|
empty string, which is falsy, but FOO=0 sets it to '0' which is truthy):
|
|
|
|
1.) #cmakedefine01 FOO
|
|
Checks if key FOO is set to a truthy value, and depending on that prints
|
|
one of the following two lines:
|
|
|
|
#define FOO 1
|
|
#define FOO 0
|
|
|
|
2.) #cmakedefine FOO [...]
|
|
Checks if key FOO is set to a truthy value, and depending on that prints
|
|
one of the following two lines:
|
|
|
|
#define FOO [...]
|
|
/* #undef FOO */
|
|
|
|
Fails if any of the KEY=VALUE arguments aren't needed for processing the
|
|
input file, or if the input file references keys that weren't passed in.
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
epilog=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
parser.add_argument('input', help='input file')
|
|
parser.add_argument('values', nargs='*', help='several KEY=VALUE pairs')
|
|
parser.add_argument('-o', '--output', required=True,
|
|
help='output file')
|
|
args = parser.parse_args()
|
|
|
|
values = {}
|
|
for value in args.values:
|
|
key, val = value.split('=', 1)
|
|
if key in values:
|
|
print('duplicate key "%s" in args' % key, file=sys.stderr)
|
|
return 1
|
|
values[key] = val.replace('\\n', '\n')
|
|
unused_values = set(values.keys())
|
|
|
|
# Matches e.g. '${FOO}' or '@FOO@' and captures FOO in group 1 or 2.
|
|
var_re = re.compile(r'\$\{([^}]*)\}|@([^@]*)@')
|
|
|
|
with open(args.input) as f:
|
|
in_lines = f.readlines()
|
|
out_lines = []
|
|
for in_line in in_lines:
|
|
def repl(m):
|
|
key = m.group(1) or m.group(2)
|
|
unused_values.discard(key)
|
|
return values[key]
|
|
in_line = var_re.sub(repl, in_line)
|
|
if in_line.startswith('#cmakedefine01 ') or in_line.startswith("# cmakedefine01"):
|
|
in_line = in_line.replace('# cmakedefine01', '#cmakedefine01')
|
|
_, var = in_line.split()
|
|
if values[var] == '0':
|
|
print('error: "%s=0" used with #cmakedefine01 %s' % (var, var))
|
|
print(" '0' evaluates as truthy with #cmakedefine01")
|
|
print(' use "%s=" instead' % var)
|
|
return 1
|
|
in_line = '#define %s %d\n' % (var, 1 if values[var] else 0)
|
|
unused_values.discard(var)
|
|
elif in_line.startswith('#cmakedefine '):
|
|
_, var = in_line.split(None, 1)
|
|
try:
|
|
var, val = var.split(None, 1)
|
|
in_line = '#define %s %s' % (var, val) # val ends in \n.
|
|
except ValueError:
|
|
var = var.rstrip()
|
|
in_line = '#define %s\n' % var
|
|
if not values[var]:
|
|
in_line = '/* #undef %s */\n' % var
|
|
unused_values.discard(var)
|
|
out_lines.append(in_line)
|
|
|
|
if unused_values:
|
|
print('unused values args:', file=sys.stderr)
|
|
print(' ' + '\n '.join(unused_values), file=sys.stderr)
|
|
return 1
|
|
|
|
output = ''.join(out_lines)
|
|
|
|
leftovers = var_re.findall(output)
|
|
if leftovers:
|
|
print(
|
|
'unprocessed values:\n',
|
|
'\n'.join([x[0] or x[1] for x in leftovers]),
|
|
file=sys.stderr)
|
|
return 1
|
|
|
|
def read(filename):
|
|
with open(filename) as f:
|
|
return f.read()
|
|
|
|
if not os.path.exists(args.output) or read(args.output) != output:
|
|
with open(args.output, 'w') as f:
|
|
f.write(output)
|
|
os.chmod(args.output, os.stat(args.input).st_mode & 0o777)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|