Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: grit/format/c_format.py

Issue 9965022: Allow substitution of messages as variables in other messages. (Closed) Base URL: https://grit-i18n.googlecode.com/svn/trunk
Patch Set: Fix unit tests for policy writers. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « grit/clique_unittest.py ('k') | grit/format/data_pack.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Formats as a .C file for compilation. 6 """Formats as a .C file for compilation.
7 """ 7 """
8 8
9 import os 9 import os
10 import re 10 import re
11 import types 11 import types
12 12
13 from grit import util 13 from grit import util
14 from grit.format import interface 14 from grit.format import interface
15 from grit.node import io 15 from grit.node import io
16 16
17 17
18 class TopLevel(interface.ItemFormatter): 18 class TopLevel(interface.ItemFormatter):
19 """Writes out the required preamble for C files.""" 19 """Writes out the required preamble for C files."""
20 20
21 def Format(self, item, lang='en', begin_item=True, output_dir='.'): 21 def Format(self, item, lang='en', output_dir='.'):
22 """Format the C file header."""
22 assert isinstance(lang, types.StringTypes) 23 assert isinstance(lang, types.StringTypes)
23 if not begin_item: 24 # Find the location of the resource header file, so that we can include
24 return '' 25 # it.
25 else: 26 resource_header = 'resource.h' # fall back to this
26 # Find the location of the resource header file, so that we can include 27 for output in item.GetRoot().GetOutputFiles():
27 # it. 28 if output.attrs['type'] == 'rc_header':
28 resource_header = 'resource.h' # fall back to this 29 resource_header = os.path.abspath(output.GetOutputFilename())
29 for output in item.GetRoot().GetOutputFiles(): 30 resource_header = util.MakeRelativePath(output_dir,
30 if output.attrs['type'] == 'rc_header': 31 resource_header)
31 resource_header = os.path.abspath(output.GetOutputFilename()) 32 return """// Copyright %d Google Inc. All Rights Reserved.
32 resource_header = util.MakeRelativePath(output_dir,
33 resource_header)
34 return """// Copyright %d Google Inc. All Rights Reserved.
35 // This file is automatically generated by GRIT. Do not edit. 33 // This file is automatically generated by GRIT. Do not edit.
36 34
37 #include "%s" 35 #include "%s"
38 36
39 // All strings are UTF-8 37 // All strings are UTF-8
40 """ % (util.GetCurrentYear(), resource_header) 38 """ % (util.GetCurrentYear(), resource_header)
41 # end Format() function 39 # end Format() function
42 40
43 41
44 class StringTable(interface.ItemFormatter): 42 class StringTable(interface.ItemFormatter):
45 """Outputs a C switch statement representing the string table.""" 43 """Outputs a C switch statement representing the string table."""
46 44
47 def Format(self, item, lang='en', begin_item=True, output_dir='.'): 45 def Format(self, item, lang='en', output_dir='.'):
46 """Format the start of the table."""
48 assert isinstance(lang, types.StringTypes) 47 assert isinstance(lang, types.StringTypes)
49 if begin_item: 48 return 'const char* GetString(int id) {\n switch (id) {'
50 return 'const char* GetString(int id) {\n switch (id) {' 49
51 else: 50 def FormatEnd(self, item, lang='en', output_dir='.'):
52 return '\n default:\n return 0;\n }\n}' 51 """Format the end of the table."""
52 assert isinstance(lang, types.StringTypes)
53 return '\n default:\n return 0;\n }\n}'
54
53 55
54 def _HexToOct(match): 56 def _HexToOct(match):
55 "Return the octal form of the hex numbers" 57 "Return the octal form of the hex numbers"
56 hex = match.group("hex") 58 hex = match.group("hex")
57 result = "" 59 result = ""
58 while len(hex): 60 while len(hex):
59 next_num = int(hex[2:4], 16) 61 next_num = int(hex[2:4], 16)
60 result += "\\" + '%03d' % int(oct(next_num), 10) 62 result += "\\" + '%03d' % int(oct(next_num), 10)
61 hex = hex[4:] 63 hex = hex[4:]
62 return match.group("escaped_backslashes") + result 64 return match.group("escaped_backslashes") + result
63 65
66
64 class Message(interface.ItemFormatter): 67 class Message(interface.ItemFormatter):
65 """Writes out a single message as part of the switch.""" 68 """Writes out a single message as part of the switch."""
66 69
67 def Format(self, item, lang='en', begin_item=True, output_dir='.'): 70 def Format(self, item, lang='en', output_dir='.'):
71 """Format a single message."""
68 from grit.node import message 72 from grit.node import message
69 if not begin_item:
70 return ''
71
72 assert isinstance(lang, types.StringTypes) 73 assert isinstance(lang, types.StringTypes)
73 assert isinstance(item, message.MessageNode) 74 assert isinstance(item, message.MessageNode)
74 75
75 message = item.ws_at_start + item.Translate(lang) + item.ws_at_end 76 message = item.ws_at_start + item.Translate(lang) + item.ws_at_end
76 # output message with non-ascii chars escaped as octal numbers 77 # output message with non-ascii chars escaped as octal numbers
77 # C's grammar allows escaped hexadecimal numbers to be infinite, 78 # C's grammar allows escaped hexadecimal numbers to be infinite,
78 # but octal is always of the form \OOO 79 # but octal is always of the form \OOO
79 message = message.encode('utf-8').encode('string_escape') 80 message = message.encode('utf-8').encode('string_escape')
80 # an escaped char is (\xHH)+ but only if the initial 81 # an escaped char is (\xHH)+ but only if the initial
81 # backslash is not escaped. 82 # backslash is not escaped.
82 not_a_backslash = r"(^|[^\\])" # beginning of line or a non-backslash char 83 not_a_backslash = r"(^|[^\\])" # beginning of line or a non-backslash char
83 escaped_backslashes = not_a_backslash + r"(\\\\)*" 84 escaped_backslashes = not_a_backslash + r"(\\\\)*"
84 hex_digits = r"((\\x)[0-9a-f]{2})+" 85 hex_digits = r"((\\x)[0-9a-f]{2})+"
85 two_digit_hex_num = re.compile( 86 two_digit_hex_num = re.compile(
86 r"(?P<escaped_backslashes>%s)(?P<hex>%s)" 87 r"(?P<escaped_backslashes>%s)(?P<hex>%s)"
87 % (escaped_backslashes, hex_digits)) 88 % (escaped_backslashes, hex_digits))
88 message = two_digit_hex_num.sub(_HexToOct, message) 89 message = two_digit_hex_num.sub(_HexToOct, message)
89 # unescape \ (convert \\ back to \) 90 # unescape \ (convert \\ back to \)
90 message = message.replace('\\\\', '\\') 91 message = message.replace('\\\\', '\\')
91 message = message.replace('"', '\\"') 92 message = message.replace('"', '\\"')
92 message = util.LINEBREAKS.sub(r'\\n', message) 93 message = util.LINEBREAKS.sub(r'\\n', message)
93 94
94 name_attr = item.GetTextualIds()[0] 95 name_attr = item.GetTextualIds()[0]
95 96
96 return '\n case %s:\n return "%s";' % (name_attr, message) 97 return '\n case %s:\n return "%s";' % (name_attr, message)
OLDNEW
« no previous file with comments | « grit/clique_unittest.py ('k') | grit/format/data_pack.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698