summaryrefslogtreecommitdiffstats
path: root/llvm/utils/gn/build/write_cmake_config.py
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/gn/build/write_cmake_config.py')
-rw-r--r--llvm/utils/gn/build/write_cmake_config.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/llvm/utils/gn/build/write_cmake_config.py b/llvm/utils/gn/build/write_cmake_config.py
new file mode 100644
index 00000000000..408ffcdbfc0
--- /dev/null
+++ b/llvm/utils/gn/build/write_cmake_config.py
@@ -0,0 +1,109 @@
+"""Processes a foo.h.cmake file and writes foo.h.
+
+Takes a list of KEY=VALUE pairs (where VALUE can be empty).
+
+Handles these types of lines (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 in value, and depending on that prints
+ one of the following two lines:
+
+ #define FOO
+ /* #undef FOO */
+
+3.) #cmakedefine FOO asdf${BAR}jkl
+ Checks if key FOO is set to a truthy values, and if so replaces all
+ variable references in `asdf${BAR}jkl` with their value and prints that
+ (else it prints the same undef line as the previous form):
+
+ #define FOO asdfBAR_VALjkl
+ /* #undef FOO */
+
+4.) #define FOO asdf{BAR}jkl
+ Always gets its variable values filled in, independent of FOO's value being
+ set:
+
+ #define FOO asdfBAR_VALjkl
+
+Fails if any of the KEY=VALUE arguments aren't needed for processing the
+.h.cmake file, or if the .h.cmake file has unreplaces ${VAR} references after
+processing all values.
+"""
+
+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)
+ values[key] = val
+ unused_values = set(values.keys())
+
+ # Matches e.g. '${CLANG_FOO}' and captures CLANG_FOO in group 1.
+ var_re = re.compile(r'\$\{([^}]*)\}')
+
+ in_lines = open(args.input).readlines()
+ out_lines = []
+ for in_line in in_lines:
+ def repl(m):
+ unused_values.discard(m.group(1))
+ return values[m.group(1)]
+ if in_line.startswith('#cmakedefine01 '):
+ _, var = in_line.split()
+ out_lines.append('#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)
+ except:
+ var, val = var.rstrip(), '\n'
+ if values[var]:
+ out_lines.append('#define %s %s' % (var,
+ var_re.sub(repl, val)))
+ else:
+ out_lines.append('/* #undef %s */\n' % var)
+ unused_values.discard(var)
+ else:
+ # In particular, handles `#define FOO ${FOO}` lines.
+ out_lines.append(var_re.sub(repl, in_line))
+
+ if unused_values:
+ print >>sys.stderr, 'Unused --values args:'
+ print >>sys.stderr, ' ', '\n '.join(unused_values)
+ return 1
+
+ output = ''.join(out_lines)
+
+ leftovers = var_re.findall(output)
+ if leftovers:
+ print >>sys.stderr, 'unprocessed values:\n', '\n'.join(leftovers)
+ return 1
+
+ if not os.path.exists(args.output) or open(args.output).read() != output:
+ open(args.output, 'w').write(output)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
OpenPOWER on IntegriCloud