• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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