| OLD | NEW |
| 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 """Generates .h and .rc files for installer strings. Run "python | 6 """Generates .h and .rc files for installer strings. Run "python |
| 7 create_string_rc.py" for usage details. | 7 create_string_rc.py" for usage details. |
| 8 | 8 |
| 9 This script generates an rc file and header (NAME.{rc,h}) to be included in | 9 This script generates an rc file and header (NAME.{rc,h}) to be included in |
| 10 setup.exe. The rc file includes translations for strings pulled from the given | 10 setup.exe. The rc file includes translations for strings pulled from the given |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 import sys | 37 import sys |
| 38 from xml import sax | 38 from xml import sax |
| 39 | 39 |
| 40 BASEDIR = os.path.dirname(os.path.abspath(__file__)) | 40 BASEDIR = os.path.dirname(os.path.abspath(__file__)) |
| 41 sys.path.append(os.path.join(BASEDIR, '../../../../tools/grit')) | 41 sys.path.append(os.path.join(BASEDIR, '../../../../tools/grit')) |
| 42 sys.path.append(os.path.join(BASEDIR, '../../../../tools/python')) | 42 sys.path.append(os.path.join(BASEDIR, '../../../../tools/python')) |
| 43 | 43 |
| 44 from grit.extern import tclib | 44 from grit.extern import tclib |
| 45 | 45 |
| 46 # The IDs of strings we want to import from the .grd files and include in | 46 # The IDs of strings we want to import from the .grd files and include in |
| 47 # setup.exe's resources. These strings are universal for all brands. | 47 # setup.exe's resources. |
| 48 STRING_IDS = [ | 48 STRING_IDS = [ |
| 49 'IDS_ABOUT_VERSION_COMPANY_NAME', | 49 'IDS_ABOUT_VERSION_COMPANY_NAME', |
| 50 'IDS_APP_SHORTCUTS_SUBDIR_NAME', | 50 'IDS_APP_SHORTCUTS_SUBDIR_NAME', |
| 51 'IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY', |
| 51 'IDS_INBOUND_MDNS_RULE_DESCRIPTION', | 52 'IDS_INBOUND_MDNS_RULE_DESCRIPTION', |
| 53 'IDS_INBOUND_MDNS_RULE_DESCRIPTION_CANARY', |
| 52 'IDS_INBOUND_MDNS_RULE_NAME', | 54 'IDS_INBOUND_MDNS_RULE_NAME', |
| 55 'IDS_INBOUND_MDNS_RULE_NAME_CANARY', |
| 53 'IDS_INSTALL_EXISTING_VERSION_LAUNCHED', | 56 'IDS_INSTALL_EXISTING_VERSION_LAUNCHED', |
| 54 'IDS_INSTALL_FAILED', | 57 'IDS_INSTALL_FAILED', |
| 55 'IDS_INSTALL_HIGHER_VERSION', | 58 'IDS_INSTALL_HIGHER_VERSION', |
| 56 'IDS_INSTALL_INSUFFICIENT_RIGHTS', | 59 'IDS_INSTALL_INSUFFICIENT_RIGHTS', |
| 57 'IDS_INSTALL_INVALID_ARCHIVE', | 60 'IDS_INSTALL_INVALID_ARCHIVE', |
| 58 'IDS_INSTALL_OS_ERROR', | 61 'IDS_INSTALL_OS_ERROR', |
| 59 'IDS_INSTALL_OS_NOT_SUPPORTED', | 62 'IDS_INSTALL_OS_NOT_SUPPORTED', |
| 60 'IDS_INSTALL_SINGLETON_ACQUISITION_FAILED', | 63 'IDS_INSTALL_SINGLETON_ACQUISITION_FAILED', |
| 61 'IDS_INSTALL_TEMP_DIR_FAILED', | 64 'IDS_INSTALL_TEMP_DIR_FAILED', |
| 62 'IDS_INSTALL_UNCOMPRESSION_FAILED', | 65 'IDS_INSTALL_UNCOMPRESSION_FAILED', |
| 63 'IDS_PRODUCT_DESCRIPTION', | 66 'IDS_PRODUCT_DESCRIPTION', |
| 64 'IDS_PRODUCT_NAME', | 67 'IDS_PRODUCT_NAME', |
| 65 'IDS_SAME_VERSION_REPAIR_FAILED', | 68 'IDS_SAME_VERSION_REPAIR_FAILED', |
| 66 'IDS_SETUP_PATCH_FAILED', | 69 'IDS_SETUP_PATCH_FAILED', |
| 67 'IDS_SHORTCUT_NEW_WINDOW', | 70 'IDS_SHORTCUT_NEW_WINDOW', |
| 68 'IDS_SHORTCUT_TOOLTIP', | 71 'IDS_SHORTCUT_TOOLTIP', |
| 72 'IDS_SXS_SHORTCUT_NAME', |
| 69 ] | 73 ] |
| 70 | 74 |
| 71 # Certain strings are conditional on a brand's install mode (see | 75 # Certain strings are conditional on a brand's install mode (see |
| 72 # chrome/install_static/install_modes.h for details). This allows | 76 # chrome/install_static/install_modes.h for details). This allows |
| 73 # installer::GetLocalizedString to return a resource specific to the current | 77 # installer::GetLocalizedString to return a resource specific to the current |
| 74 # install mode at runtime (e.g., "Google Chrome SxS" as IDS_SHORTCUT_NAME for | 78 # install mode at runtime (e.g., "Google Chrome SxS" as IDS_SHORTCUT_NAME for |
| 75 # the localized shortcut name for Google Chrome's canary channel). | 79 # the localized shortcut name for Google Chrome's canary channel). |
| 76 # l10n_util::GetStringUTF16 (used within the rest of Chrome) is unaffected, and | 80 # l10n_util::GetStringUTF16 (used within the rest of Chrome) is unaffected, and |
| 77 # will always return the requested string. | 81 # will always return the requested string. |
| 78 # | 82 # |
| (...skipping 16 matching lines...) Expand all Loading... |
| 95 # 'resource_id_1' names an existing string ID. All calls to | 99 # 'resource_id_1' names an existing string ID. All calls to |
| 96 # installer::GetLocalizedString with this string ID will map to the | 100 # installer::GetLocalizedString with this string ID will map to the |
| 97 # mode-specific string. | 101 # mode-specific string. |
| 98 # | 102 # |
| 99 # Note: Update the test expectations in GetBaseMessageIdForMode.GoogleStringIds | 103 # Note: Update the test expectations in GetBaseMessageIdForMode.GoogleStringIds |
| 100 # when adding to/modifying this structure. | 104 # when adding to/modifying this structure. |
| 101 MODE_SPECIFIC_STRINGS = { | 105 MODE_SPECIFIC_STRINGS = { |
| 102 'IDS_APP_SHORTCUTS_SUBDIR_NAME': { | 106 'IDS_APP_SHORTCUTS_SUBDIR_NAME': { |
| 103 'google_chrome': [ | 107 'google_chrome': [ |
| 104 'IDS_APP_SHORTCUTS_SUBDIR_NAME', | 108 'IDS_APP_SHORTCUTS_SUBDIR_NAME', |
| 105 'IDS_APP_SHORTCUTS_SUBDIR_NAME_BETA', | |
| 106 'IDS_APP_SHORTCUTS_SUBDIR_NAME_DEV', | |
| 107 'IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY', | 109 'IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY', |
| 108 ], | 110 ], |
| 109 'chromium': [ | 111 'chromium': [ |
| 110 'IDS_APP_SHORTCUTS_SUBDIR_NAME', | 112 'IDS_APP_SHORTCUTS_SUBDIR_NAME', |
| 111 ], | 113 ], |
| 112 }, | 114 }, |
| 113 'IDS_INBOUND_MDNS_RULE_DESCRIPTION': { | 115 'IDS_INBOUND_MDNS_RULE_DESCRIPTION': { |
| 114 'google_chrome': [ | 116 'google_chrome': [ |
| 115 'IDS_INBOUND_MDNS_RULE_DESCRIPTION', | 117 'IDS_INBOUND_MDNS_RULE_DESCRIPTION', |
| 116 'IDS_INBOUND_MDNS_RULE_DESCRIPTION_BETA', | |
| 117 'IDS_INBOUND_MDNS_RULE_DESCRIPTION_DEV', | |
| 118 'IDS_INBOUND_MDNS_RULE_DESCRIPTION_CANARY', | 118 'IDS_INBOUND_MDNS_RULE_DESCRIPTION_CANARY', |
| 119 ], | 119 ], |
| 120 'chromium': [ | 120 'chromium': [ |
| 121 'IDS_INBOUND_MDNS_RULE_DESCRIPTION', | 121 'IDS_INBOUND_MDNS_RULE_DESCRIPTION', |
| 122 ], | 122 ], |
| 123 }, | 123 }, |
| 124 'IDS_INBOUND_MDNS_RULE_NAME': { | 124 'IDS_INBOUND_MDNS_RULE_NAME': { |
| 125 'google_chrome': [ | 125 'google_chrome': [ |
| 126 'IDS_INBOUND_MDNS_RULE_NAME', | 126 'IDS_INBOUND_MDNS_RULE_NAME', |
| 127 'IDS_INBOUND_MDNS_RULE_NAME_BETA', | |
| 128 'IDS_INBOUND_MDNS_RULE_NAME_DEV', | |
| 129 'IDS_INBOUND_MDNS_RULE_NAME_CANARY', | 127 'IDS_INBOUND_MDNS_RULE_NAME_CANARY', |
| 130 ], | 128 ], |
| 131 'chromium': [ | 129 'chromium': [ |
| 132 'IDS_INBOUND_MDNS_RULE_NAME', | 130 'IDS_INBOUND_MDNS_RULE_NAME', |
| 133 ], | 131 ], |
| 134 }, | 132 }, |
| 135 # In contrast to the strings above, this one (IDS_PRODUCT_NAME) is used | 133 # In contrast to the strings above, this one (IDS_PRODUCT_NAME) is used |
| 136 # throughout Chrome in mode-independent contexts. Within the installer (the | 134 # throughout Chrome in mode-independent contexts. Within the installer (the |
| 137 # place where this mapping matters), it is only used for mode-specific strings | 135 # place where this mapping matters), it is only used for mode-specific strings |
| 138 # such as the name of Chrome's shortcut. | 136 # such as the name of Chrome's shortcut. |
| 139 'IDS_PRODUCT_NAME': { | 137 'IDS_PRODUCT_NAME': { |
| 140 'google_chrome': [ | 138 'google_chrome': [ |
| 141 'IDS_PRODUCT_NAME', | 139 'IDS_PRODUCT_NAME', |
| 142 'IDS_SHORTCUT_NAME_BETA', | |
| 143 'IDS_SHORTCUT_NAME_DEV', | |
| 144 'IDS_SXS_SHORTCUT_NAME', | 140 'IDS_SXS_SHORTCUT_NAME', |
| 145 ], | 141 ], |
| 146 'chromium': [ | 142 'chromium': [ |
| 147 'IDS_PRODUCT_NAME', | 143 'IDS_PRODUCT_NAME', |
| 148 ], | 144 ], |
| 149 }, | 145 }, |
| 150 } | 146 } |
| 151 # Note: Update the test expectations in GetBaseMessageIdForMode.GoogleStringIds | 147 # Note: Update the test expectations in GetBaseMessageIdForMode.GoogleStringIds |
| 152 # when adding to/modifying the above structure. | 148 # when adding to/modifying the above structure. |
| 153 | 149 |
| 154 # The ID of the first resource string. | 150 # The ID of the first resource string. |
| 155 FIRST_RESOURCE_ID = 1600 | 151 FIRST_RESOURCE_ID = 1600 |
| 156 | 152 |
| 157 | 153 |
| 158 class GrdHandler(sax.handler.ContentHandler): | 154 class GrdHandler(sax.handler.ContentHandler): |
| 159 """Extracts selected strings from a .grd file. | 155 """Extracts selected strings from a .grd file. |
| 160 | 156 |
| 161 Attributes: | 157 Attributes: |
| 162 messages: A dict mapping string identifiers to their corresponding messages. | 158 messages: A dict mapping string identifiers to their corresponding messages. |
| 163 """ | 159 """ |
| 164 def __init__(self, string_id_set): | 160 def __init__(self, string_ids): |
| 165 """Constructs a handler that reads selected strings from a .grd file. | 161 """Constructs a handler that reads selected strings from a .grd file. |
| 166 | 162 |
| 167 The dict attribute |messages| is populated with the strings that are read. | 163 The dict attribute |messages| is populated with the strings that are read. |
| 168 | 164 |
| 169 Args: | 165 Args: |
| 170 string_id_set: A set of message identifiers to extract. | 166 string_ids: A list of message identifiers to extract. |
| 171 """ | 167 """ |
| 172 sax.handler.ContentHandler.__init__(self) | 168 sax.handler.ContentHandler.__init__(self) |
| 173 self.messages = {} | 169 self.messages = {} |
| 174 self.__id_set = string_id_set | 170 self.__id_set = set(string_ids) |
| 175 self.__message_name = None | 171 self.__message_name = None |
| 176 self.__element_stack = [] | 172 self.__element_stack = [] |
| 177 self.__text_scraps = [] | 173 self.__text_scraps = [] |
| 178 self.__characters_callback = None | 174 self.__characters_callback = None |
| 179 | 175 |
| 180 def startElement(self, name, attrs): | 176 def startElement(self, name, attrs): |
| 181 self.__element_stack.append(name) | 177 self.__element_stack.append(name) |
| 182 if name == 'message': | 178 if name == 'message': |
| 183 self.__OnOpenMessage(attrs.getValue('name')) | 179 self.__OnOpenMessage(attrs.getValue('name')) |
| 184 | 180 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 'installer_util_strings'). | 299 'installer_util_strings'). |
| 304 inputs: A list of (grd_file, xtb_dir) pairs containing the source data. | 300 inputs: A list of (grd_file, xtb_dir) pairs containing the source data. |
| 305 outdir: The directory into which the files will be generated. | 301 outdir: The directory into which the files will be generated. |
| 306 """ | 302 """ |
| 307 self.name = name | 303 self.name = name |
| 308 self.inputs = inputs | 304 self.inputs = inputs |
| 309 self.outdir = outdir | 305 self.outdir = outdir |
| 310 self.brand = brand | 306 self.brand = brand |
| 311 | 307 |
| 312 def MakeFiles(self): | 308 def MakeFiles(self): |
| 313 string_id_set = self.__BuildStringIds() | 309 translated_strings = self.__ReadSourceAndTranslatedStrings() |
| 314 translated_strings = self.__ReadSourceAndTranslatedStrings(string_id_set) | |
| 315 self.__WriteRCFile(translated_strings) | 310 self.__WriteRCFile(translated_strings) |
| 316 self.__WriteHeaderFile(string_id_set, translated_strings) | 311 self.__WriteHeaderFile(translated_strings) |
| 317 | 312 |
| 318 class __TranslationData(object): | 313 class __TranslationData(object): |
| 319 """A container of information about a single translation.""" | 314 """A container of information about a single translation.""" |
| 320 def __init__(self, resource_id_str, language, translation): | 315 def __init__(self, resource_id_str, language, translation): |
| 321 self.resource_id_str = resource_id_str | 316 self.resource_id_str = resource_id_str |
| 322 self.language = language | 317 self.language = language |
| 323 self.translation = translation | 318 self.translation = translation |
| 324 | 319 |
| 325 def __cmp__(self, other): | 320 def __cmp__(self, other): |
| 326 """Allow __TranslationDatas to be sorted by id then by language.""" | 321 """Allow __TranslationDatas to be sorted by id then by language.""" |
| 327 id_result = cmp(self.resource_id_str, other.resource_id_str) | 322 id_result = cmp(self.resource_id_str, other.resource_id_str) |
| 328 return cmp(self.language, other.language) if id_result == 0 else id_result | 323 return cmp(self.language, other.language) if id_result == 0 else id_result |
| 329 | 324 |
| 330 def __BuildStringIds(self): | 325 def __ReadSourceAndTranslatedStrings(self): |
| 331 """Returns the set of string IDs to extract from the grd and xtb files.""" | |
| 332 # Start with the strings that apply to all brands. | |
| 333 string_id_set = set(STRING_IDS) | |
| 334 # Add in the strings for the current brand. | |
| 335 for string_id, brands in MODE_SPECIFIC_STRINGS.iteritems(): | |
| 336 brand_strings = brands.get(self.brand) | |
| 337 if not brand_strings: | |
| 338 raise exceptions.RuntimeError( | |
| 339 'No strings declared for brand \'%s\' in MODE_SPECIFIC_STRINGS for ' | |
| 340 'message %s' % (self.brand, string_id)) | |
| 341 string_id_set.update(brand_strings) | |
| 342 return string_id_set | |
| 343 | |
| 344 def __ReadSourceAndTranslatedStrings(self, string_id_set): | |
| 345 """Reads the source strings and translations from all inputs.""" | 326 """Reads the source strings and translations from all inputs.""" |
| 346 translated_strings = [] | 327 translated_strings = [] |
| 347 for grd_file, xtb_dir in self.inputs: | 328 for grd_file, xtb_dir in self.inputs: |
| 348 # Get the name of the grd file sans extension. | 329 # Get the name of the grd file sans extension. |
| 349 source_name = os.path.splitext(os.path.basename(grd_file))[0] | 330 source_name = os.path.splitext(os.path.basename(grd_file))[0] |
| 350 # Compute a glob for the translation files. | 331 # Compute a glob for the translation files. |
| 351 xtb_pattern = os.path.join(os.path.dirname(grd_file), xtb_dir, | 332 xtb_pattern = os.path.join(os.path.dirname(grd_file), xtb_dir, |
| 352 '%s*.xtb' % source_name) | 333 '%s*.xtb' % source_name) |
| 353 translated_strings.extend( | 334 translated_strings.extend( |
| 354 self.__ReadSourceAndTranslationsFrom(string_id_set, grd_file, | 335 self.__ReadSourceAndTranslationsFrom(grd_file, glob.glob(xtb_pattern))) |
| 355 glob.glob(xtb_pattern))) | |
| 356 translated_strings.sort() | 336 translated_strings.sort() |
| 357 return translated_strings | 337 return translated_strings |
| 358 | 338 |
| 359 def __ReadSourceAndTranslationsFrom(self, string_id_set, grd_file, xtb_files): | 339 def __ReadSourceAndTranslationsFrom(self, grd_file, xtb_files): |
| 360 """Reads source strings and translations for a .grd file. | 340 """Reads source strings and translations for a .grd file. |
| 361 | 341 |
| 362 Reads the source strings and all available translations for the messages | 342 Reads the source strings and all available translations for the messages |
| 363 identified by string_id_set. The source string is used where translations | 343 identified by STRING_IDS. The source string is used where translations are |
| 364 are missing. | 344 missing. |
| 365 | 345 |
| 366 Args: | 346 Args: |
| 367 string_id_set: The identifiers of the strings to read. | |
| 368 grd_file: Path to a .grd file. | 347 grd_file: Path to a .grd file. |
| 369 xtb_files: List of paths to .xtb files. | 348 xtb_files: List of paths to .xtb files. |
| 370 | 349 |
| 371 Returns: | 350 Returns: |
| 372 An unsorted list of __TranslationData instances. | 351 An unsorted list of __TranslationData instances. |
| 373 """ | 352 """ |
| 374 sax_parser = sax.make_parser() | 353 sax_parser = sax.make_parser() |
| 375 | 354 |
| 376 # Read the source (en-US) string from the .grd file. | 355 # Read the source (en-US) string from the .grd file. |
| 377 grd_handler = GrdHandler(string_id_set) | 356 grd_handler = GrdHandler(STRING_IDS) |
| 378 sax_parser.setContentHandler(grd_handler) | 357 sax_parser.setContentHandler(grd_handler) |
| 379 sax_parser.parse(grd_file) | 358 sax_parser.parse(grd_file) |
| 380 source_strings = grd_handler.messages | 359 source_strings = grd_handler.messages |
| 381 | 360 |
| 382 # Manually put the source strings as en-US in the list of translated | 361 # Manually put the source strings as en-US in the list of translated |
| 383 # strings. | 362 # strings. |
| 384 translated_strings = [] | 363 translated_strings = [] |
| 385 for string_id, message_text in source_strings.iteritems(): | 364 for string_id, message_text in source_strings.iteritems(): |
| 386 translated_strings.append(self.__TranslationData(string_id, | 365 translated_strings.append(self.__TranslationData(string_id, |
| 387 'EN_US', | 366 'EN_US', |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 for translation in translated_strings: | 410 for translation in translated_strings: |
| 432 # Escape special characters for the rc file. | 411 # Escape special characters for the rc file. |
| 433 escaped_text = (translation.translation.replace('"', '""') | 412 escaped_text = (translation.translation.replace('"', '""') |
| 434 .replace('\t', '\\t') | 413 .replace('\t', '\\t') |
| 435 .replace('\n', '\\n')) | 414 .replace('\n', '\\n')) |
| 436 outfile.write(u' %s "%s"\n' % | 415 outfile.write(u' %s "%s"\n' % |
| 437 (translation.resource_id_str + '_' + translation.language, | 416 (translation.resource_id_str + '_' + translation.language, |
| 438 escaped_text)) | 417 escaped_text)) |
| 439 outfile.write(FOOTER_TEXT) | 418 outfile.write(FOOTER_TEXT) |
| 440 | 419 |
| 441 def __WriteHeaderFile(self, string_id_set, translated_strings): | 420 def __WriteHeaderFile(self, translated_strings): |
| 442 """Writes a .h file with resource ids.""" | 421 """Writes a .h file with resource ids.""" |
| 443 # TODO(grt): Stream the lines to the file rather than building this giant | 422 # TODO(grt): Stream the lines to the file rather than building this giant |
| 444 # list of lines first. | 423 # list of lines first. |
| 445 lines = [] | 424 lines = [] |
| 446 do_languages_lines = ['\n#define DO_LANGUAGES'] | 425 do_languages_lines = ['\n#define DO_LANGUAGES'] |
| 447 installer_string_mapping_lines = ['\n#define DO_INSTALLER_STRING_MAPPING'] | 426 installer_string_mapping_lines = ['\n#define DO_INSTALLER_STRING_MAPPING'] |
| 448 do_mode_strings_lines = ['\n#define DO_MODE_STRINGS'] | 427 do_mode_strings_lines = ['\n#define DO_MODE_STRINGS'] |
| 449 | 428 |
| 450 # Write the values for how the languages ids are offset. | 429 # Write the values for how the languages ids are offset. |
| 451 seen_languages = set() | 430 seen_languages = set() |
| (...skipping 23 matching lines...) Expand all Loading... |
| 475 brand_strings = brands.get(self.brand) | 454 brand_strings = brands.get(self.brand) |
| 476 if not brand_strings: | 455 if not brand_strings: |
| 477 raise exceptions.RuntimeError( | 456 raise exceptions.RuntimeError( |
| 478 'No strings declared for brand \'%s\' in MODE_SPECIFIC_STRINGS for ' | 457 'No strings declared for brand \'%s\' in MODE_SPECIFIC_STRINGS for ' |
| 479 'message %s' % (self.brand, string_id)) | 458 'message %s' % (self.brand, string_id)) |
| 480 do_mode_strings_lines.append( | 459 do_mode_strings_lines.append( |
| 481 ' HANDLE_MODE_STRING(%s_BASE, %s)' | 460 ' HANDLE_MODE_STRING(%s_BASE, %s)' |
| 482 % (string_id, ', '.join([ ('%s_BASE' % s) for s in brand_strings]))) | 461 % (string_id, ', '.join([ ('%s_BASE' % s) for s in brand_strings]))) |
| 483 | 462 |
| 484 # Write out base ID values. | 463 # Write out base ID values. |
| 485 for string_id in sorted(string_id_set): | 464 for string_id in STRING_IDS: |
| 486 lines.append('#define %s_BASE %s_%s' % (string_id, | 465 lines.append('#define %s_BASE %s_%s' % (string_id, |
| 487 string_id, | 466 string_id, |
| 488 translated_strings[0].language)) | 467 translated_strings[0].language)) |
| 489 installer_string_mapping_lines.append(' HANDLE_STRING(%s_BASE, %s)' | 468 installer_string_mapping_lines.append(' HANDLE_STRING(%s_BASE, %s)' |
| 490 % (string_id, string_id)) | 469 % (string_id, string_id)) |
| 491 | 470 |
| 492 with open(os.path.join(self.outdir, self.name + '.h'), 'wb') as outfile: | 471 with open(os.path.join(self.outdir, self.name + '.h'), 'wb') as outfile: |
| 493 outfile.write('\n'.join(lines)) | 472 outfile.write('\n'.join(lines)) |
| 494 outfile.write('\n#ifndef RC_INVOKED') | 473 outfile.write('\n#ifndef RC_INVOKED') |
| 495 outfile.write(' \\\n'.join(do_languages_lines)) | 474 outfile.write(' \\\n'.join(do_languages_lines)) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 | 513 |
| 535 | 514 |
| 536 def main(): | 515 def main(): |
| 537 args = ParseCommandLine() | 516 args = ParseCommandLine() |
| 538 StringRcMaker(args.name, args.inputs, args.outdir, args.brand).MakeFiles() | 517 StringRcMaker(args.name, args.inputs, args.outdir, args.brand).MakeFiles() |
| 539 return 0 | 518 return 0 |
| 540 | 519 |
| 541 | 520 |
| 542 if '__main__' == __name__: | 521 if '__main__' == __name__: |
| 543 sys.exit(main()) | 522 sys.exit(main()) |
| OLD | NEW |