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 m = expr_re.search(line) 36 if m: 37 line = line.replace('%', '%%') 38 subst_line = r'r"""%s""" %% (%s,)' % ( 39 re.sub(expr_re, '%s', line), 40 ', '.join(re.findall(expr_re, line))) 41 else: 42 subst_line = r'r"""%s"""' % line 43 44 out_string = r'%s__outfile__.write(%s + %s)' % ( 45 indent_string, 46 subst_line, 47 repr(line_ending)) 48 output.write(out_string + '\n') 49 50 return output.getvalue() 51 52 53def RunTemplate(srcfile, dstfile, template_dict, statement_re=None, 54 expr_re=None): 55 statement_re = statement_re or re.compile(STATEMENT_RE) 56 expr_re = expr_re or re.compile(EXPR_RE) 57 script = TemplateToPython(srcfile.read(), statement_re, expr_re) 58 template_dict = copy.copy(template_dict) 59 template_dict['__outfile__'] = dstfile 60 exec script in template_dict 61 62 63def RunTemplateFile(srcpath, dstpath, template_dict, statement_re=None, 64 expr_re=None): 65 with open(srcpath) as srcfile: 66 with open(dstpath, 'w') as dstfile: 67 RunTemplate(srcfile, dstfile, template_dict, statement_re, expr_re) 68 69 70def RunTemplateFileIfChanged(srcpath, dstpath, replace): 71 dststr = cStringIO.StringIO() 72 with open(srcpath) as srcfile: 73 RunTemplate(srcfile, dststr, replace) 74 75 if os.path.exists(dstpath): 76 with open(dstpath) as dstfile: 77 if dstfile.read() == dststr.getvalue(): 78 return 79 80 with open(dstpath, 'w') as dstfile: 81 dstfile.write(dststr.getvalue()) 82 83 84def RunTemplateString(src, template_dict, statement_re=None, expr_re=None): 85 srcstr = cStringIO.StringIO(src) 86 dststr = cStringIO.StringIO() 87 RunTemplate(srcstr, dststr, template_dict, statement_re, expr_re) 88 return dststr.getvalue() 89 90 91def main(args): 92 parser = optparse.OptionParser() 93 _, args = parser.parse_args(args) 94 if not args: 95 return 96 97 with open(args[0]) as f: 98 print TemplateToPython( 99 f.read(), re.compile(STATEMENT_RE), re.compile(EXPR_RE)) 100 101if __name__ == '__main__': 102 sys.exit(main(sys.argv[1:])) 103