| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 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 | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Formats as a .C file for compilation. | |
| 7 """ | |
| 8 | |
| 9 import os | |
| 10 import re | |
| 11 import types | |
| 12 | |
| 13 from grit import util | |
| 14 | |
| 15 | |
| 16 def _FormatHeader(root, output_dir): | |
| 17 """Returns the required preamble for C files.""" | |
| 18 # Find the location of the resource header file, so that we can include | |
| 19 # it. | |
| 20 resource_header = 'resource.h' # fall back to this | |
| 21 for output in root.GetOutputFiles(): | |
| 22 if output.attrs['type'] == 'rc_header': | |
| 23 resource_header = os.path.abspath(output.GetOutputFilename()) | |
| 24 resource_header = util.MakeRelativePath(output_dir, resource_header) | |
| 25 return """// This file is automatically generated by GRIT. Do not edit. | |
| 26 | |
| 27 #include "%s" | |
| 28 | |
| 29 // All strings are UTF-8 | |
| 30 """ % (resource_header) | |
| 31 # end _FormatHeader() function | |
| 32 | |
| 33 | |
| 34 def Format(root, lang='en', output_dir='.'): | |
| 35 """Outputs a C switch statement representing the string table.""" | |
| 36 from grit.node import message | |
| 37 assert isinstance(lang, types.StringTypes) | |
| 38 | |
| 39 yield _FormatHeader(root, output_dir) | |
| 40 | |
| 41 yield 'const char* GetString(int id) {\n switch (id) {' | |
| 42 | |
| 43 for item in root.ActiveDescendants(): | |
| 44 with item: | |
| 45 if isinstance(item, message.MessageNode): | |
| 46 yield _FormatMessage(item, lang) | |
| 47 | |
| 48 yield '\n default:\n return 0;\n }\n}' | |
| 49 | |
| 50 | |
| 51 def _HexToOct(match): | |
| 52 "Return the octal form of the hex numbers" | |
| 53 hex = match.group("hex") | |
| 54 result = "" | |
| 55 while len(hex): | |
| 56 next_num = int(hex[2:4], 16) | |
| 57 result += "\\" + '%03d' % int(oct(next_num), 10) | |
| 58 hex = hex[4:] | |
| 59 return match.group("escaped_backslashes") + result | |
| 60 | |
| 61 | |
| 62 def _FormatMessage(item, lang): | |
| 63 """Format a single <message> element.""" | |
| 64 | |
| 65 message = item.ws_at_start + item.Translate(lang) + item.ws_at_end | |
| 66 # output message with non-ascii chars escaped as octal numbers | |
| 67 # C's grammar allows escaped hexadecimal numbers to be infinite, | |
| 68 # but octal is always of the form \OOO | |
| 69 message = message.encode('utf-8').encode('string_escape') | |
| 70 # an escaped char is (\xHH)+ but only if the initial | |
| 71 # backslash is not escaped. | |
| 72 not_a_backslash = r"(^|[^\\])" # beginning of line or a non-backslash char | |
| 73 escaped_backslashes = not_a_backslash + r"(\\\\)*" | |
| 74 hex_digits = r"((\\x)[0-9a-f]{2})+" | |
| 75 two_digit_hex_num = re.compile( | |
| 76 r"(?P<escaped_backslashes>%s)(?P<hex>%s)" | |
| 77 % (escaped_backslashes, hex_digits)) | |
| 78 message = two_digit_hex_num.sub(_HexToOct, message) | |
| 79 # unescape \ (convert \\ back to \) | |
| 80 message = message.replace('\\\\', '\\') | |
| 81 message = message.replace('"', '\\"') | |
| 82 message = util.LINEBREAKS.sub(r'\\n', message) | |
| 83 | |
| 84 name_attr = item.GetTextualIds()[0] | |
| 85 | |
| 86 return '\n case %s:\n return "%s";' % (name_attr, message) | |
| OLD | NEW |