• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright (c) 2013 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import copy
7import cStringIO
8import optparse
9import os
10import re
11import sys
12
13
14STATEMENT_RE = "\[\[(.*?)\]\]"  # [[...]]
15EXPR_RE = "\{\{(.*?)\}\}"  # {{...}}
16
17def TemplateToPython(template, statement_re, expr_re):
18  output = cStringIO.StringIO()
19  indent_re = re.compile(r'\s*')
20  indent_string = ''
21  for line in template.splitlines(1):  # 1 => keep line ends
22    m = statement_re.match(line)
23    if m:
24      statement = m.group(1)
25      indent_string = indent_re.match(statement).group()
26      if statement.rstrip()[-1:] == ':':
27        indent_string += '  '
28      output.write(statement + '\n')
29    else:
30      line_ending = ''
31      while line and line[-1] in '\\"\n\r':
32        line_ending = line[-1] + line_ending
33        line = line[:-1]
34
35      ms = list(expr_re.finditer(line))
36      if ms:
37        # Only replace % with %% outside of the expr matches.
38        new_line = ''
39        start = 0
40        for m in ms:
41          new_line += line[start:m.start()].replace('%', '%%')
42          new_line += line[m.start():m.end()]
43          start = m.end()
44        new_line += line[start:].replace('%', '%%')
45        line = new_line
46
47        subst_line = r'r"""%s""" %% (%s,)' % (
48            re.sub(expr_re, '%s', line),
49            ', '.join(re.findall(expr_re, line)))
50      else:
51        subst_line = r'r"""%s"""' % line
52
53      out_string = r'%s__outfile__.write(%s + %s)' % (
54          indent_string,
55          subst_line,
56          repr(line_ending))
57      output.write(out_string + '\n')
58
59  return output.getvalue()
60
61
62def RunTemplate(srcfile, dstfile, template_dict, statement_re=None,
63                expr_re=None):
64  statement_re = statement_re or re.compile(STATEMENT_RE)
65  expr_re = expr_re or re.compile(EXPR_RE)
66  script = TemplateToPython(srcfile.read(), statement_re, expr_re)
67  template_dict = copy.copy(template_dict)
68  template_dict['__outfile__'] = dstfile
69  exec script in template_dict
70
71
72def RunTemplateFile(srcpath, dstpath, template_dict, statement_re=None,
73                    expr_re=None):
74  with open(srcpath) as srcfile:
75    with open(dstpath, 'w') as dstfile:
76      RunTemplate(srcfile, dstfile, template_dict, statement_re, expr_re)
77
78
79def RunTemplateFileIfChanged(srcpath, dstpath, replace):
80  dststr = cStringIO.StringIO()
81  with open(srcpath) as srcfile:
82    RunTemplate(srcfile, dststr, replace)
83
84  if os.path.exists(dstpath):
85    with open(dstpath) as dstfile:
86      if dstfile.read() == dststr.getvalue():
87        return
88
89  with open(dstpath, 'w') as dstfile:
90    dstfile.write(dststr.getvalue())
91
92
93def RunTemplateString(src, template_dict, statement_re=None, expr_re=None):
94  srcstr = cStringIO.StringIO(src)
95  dststr = cStringIO.StringIO()
96  RunTemplate(srcstr, dststr, template_dict, statement_re, expr_re)
97  return dststr.getvalue()
98
99
100def main(args):
101  parser = optparse.OptionParser()
102  _, args = parser.parse_args(args)
103  if not args:
104    return
105
106  with open(args[0]) as f:
107    print TemplateToPython(
108        f.read(), re.compile(STATEMENT_RE), re.compile(EXPR_RE))
109
110if __name__ == '__main__':
111  sys.exit(main(sys.argv[1:]))
112