1# Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15 16"""Expands CMake variables in a text file.""" 17 18from __future__ import absolute_import 19from __future__ import division 20from __future__ import print_function 21 22import re 23import sys 24 25_CMAKE_DEFINE_REGEX = re.compile(r"\s*#cmakedefine\s+([A-Za-z_0-9]*)(\s.*)?$") 26_CMAKE_DEFINE01_REGEX = re.compile(r"\s*#cmakedefine01\s+([A-Za-z_0-9]*)") 27_CMAKE_VAR_REGEX = re.compile(r"\${([A-Za-z_0-9]*)}") 28_CMAKE_ATVAR_REGEX = re.compile(r"@([A-Za-z_0-9]*)@") 29 30 31def _parse_args(argv): 32 """Parses arguments with the form KEY=VALUE into a dictionary.""" 33 result = {} 34 for arg in argv: 35 k, v = arg.split("=") 36 result[k] = v 37 return result 38 39 40def _expand_variables(input_str, cmake_vars): 41 """Expands ${VARIABLE}s and @VARIABLE@s in 'input_str', using dictionary 'cmake_vars'. 42 43 Args: 44 input_str: the string containing ${VARIABLE} or @VARIABLE@ expressions to expand. 45 cmake_vars: a dictionary mapping variable names to their values. 46 47 Returns: 48 The expanded string. 49 """ 50 def replace(match): 51 if match.group(1) in cmake_vars: 52 return cmake_vars[match.group(1)] 53 return "" 54 return _CMAKE_ATVAR_REGEX.sub(replace,_CMAKE_VAR_REGEX.sub(replace, input_str)) 55 56 57def _expand_cmakedefines(line, cmake_vars): 58 """Expands #cmakedefine declarations, using a dictionary 'cmake_vars'.""" 59 60 # Handles #cmakedefine lines 61 match = _CMAKE_DEFINE_REGEX.match(line) 62 if match: 63 name = match.group(1) 64 suffix = match.group(2) or "" 65 if name in cmake_vars: 66 return "#define {}{}\n".format(name, 67 _expand_variables(suffix, cmake_vars)) 68 else: 69 return "/* #undef {} */\n".format(name) 70 71 # Handles #cmakedefine01 lines 72 match = _CMAKE_DEFINE01_REGEX.match(line) 73 if match: 74 name = match.group(1) 75 value = cmake_vars.get(name, "0") 76 return "#define {} {}\n".format(name, value) 77 78 # Otherwise return the line unchanged. 79 return _expand_variables(line, cmake_vars) 80 81 82def main(): 83 cmake_vars = _parse_args(sys.argv[1:]) 84 for line in sys.stdin: 85 sys.stdout.write(_expand_cmakedefines(line, cmake_vars)) 86 87 88if __name__ == "__main__": 89 main() 90