1# Lint as: python2, python3 2# Copyright 2019 The TensorFlow Authors. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# ============================================================================== 16"""Generates a Keil uVision project file from a template.""" 17 18from __future__ import absolute_import 19from __future__ import division 20from __future__ import print_function 21 22import argparse 23import os.path 24import re 25 26import six 27 28 29def sanitize_xml(unsanitized): 30 """Uses a whitelist to avoid generating bad XML.""" 31 return re.sub(r'[^a-zA-Z0-9+_\-/\\.]', '', six.ensure_str(unsanitized)) 32 33 34def main(unused_args, flags): 35 """Generates a Keil project file from a template source.""" 36 with open(flags.input_template, 'r') as input_template_file: 37 template_file_text = input_template_file.read() 38 39 template_file_text = re.sub(r'%{EXECUTABLE}%', 40 six.ensure_str(flags.executable), 41 template_file_text) 42 43 srcs_list = six.ensure_str(flags.srcs).split(' ') 44 hdrs_list = six.ensure_str(flags.hdrs).split(' ') 45 all_srcs_list = srcs_list + hdrs_list 46 all_srcs_list.sort() 47 48 replace_srcs = '' 49 for src in all_srcs_list: 50 if not src: 51 continue 52 ext = os.path.splitext(src)[1] 53 # These extension indexes are used by uVision to keep track of the type 54 # of files. I determined them by experimentation, since the file format 55 # isn't documented. 56 if ext == '.h': 57 ext_index = '5' 58 elif ext == '.c': 59 ext_index = '1' 60 elif ext == '.cc' or ext == '.cpp': 61 ext_index = '8' 62 else: 63 ext_index = '5' 64 basename = sanitize_xml(os.path.basename(src)) 65 clean_src = sanitize_xml(src) 66 replace_srcs += ' <File>\n' 67 replace_srcs += ' <FileName>' + basename + '</FileName>\n' 68 replace_srcs += ' <FileType>' + ext_index + '</FileType>\n' 69 replace_srcs += ' <FilePath>' + clean_src + '</FilePath>\n' 70 replace_srcs += ' </File>\n' 71 template_file_text = re.sub(r'%{SRCS}%', replace_srcs, 72 six.ensure_str(template_file_text)) 73 74 include_paths = re.sub(' ', ';', six.ensure_str(flags.include_paths)) 75 template_file_text = re.sub(r'%{INCLUDE_PATHS}%', include_paths, 76 template_file_text) 77 78 with open(flags.output_file, 'w') as output_file: 79 output_file.write(template_file_text) 80 81 82def parse_args(): 83 """Converts the raw arguments into accessible flags.""" 84 parser = argparse.ArgumentParser() 85 parser.register('type', 'bool', lambda v: v.lower() == 'true') 86 parser.add_argument( 87 '--input_template', 88 type=str, 89 default='', 90 help='Path to template project file to build from.') 91 parser.add_argument( 92 '--output_file', 93 type=str, 94 default='', 95 help='Path to write the completed project file to.') 96 parser.add_argument( 97 '--executable', 98 type=str, 99 default='', 100 help='Name of the executable the project will build.') 101 parser.add_argument( 102 '--hdrs', 103 type=str, 104 default='', 105 help='Space-separated list of C or C++ source files to compile.') 106 parser.add_argument( 107 '--srcs', 108 type=str, 109 default='', 110 help='Space-separated list of C or C++ header files to include.') 111 parser.add_argument( 112 '--include_paths', 113 type=str, 114 default='', 115 help='Space-separated list of paths to look for header files on.') 116 flags, unparsed = parser.parse_known_args() 117 118 main(unparsed, flags) 119 120 121if __name__ == '__main__': 122 parse_args() 123