15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2009 The Chromium Authors. All rights reserved. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Usage: generate_localizer [xib_path] [output_dot_h_path] [output_dot_mm_path] 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Extracts all the localizable strings that start with "^IDS" from the given 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# xib file, and then generates a localizer to process those strings. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import plistlib 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)generate_localizer = "me" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)localizer_template_h = \ 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)'''// ---------- WARNING ---------- 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This header includes the table used by ui_localizer.mm. Nothing else should 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be including this file. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generated by %(generate_localizer)s. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generated from: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// %(xib_files)s 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_LOCALIZER_TABLE_H_ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_LOCALIZER_TABLE_H_ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const UILocalizerResourceMap kUIResources[] = { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)%(resource_map_list)s }; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kUIResourcesSize = arraysize(kUIResources); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UI_LOCALIZER_TABLE_H_ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def xib_localizable_strings(xib_path): 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Runs ibtool to extract the localizable strings data from the xib.""" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools_dir = os.environ.get('DEVELOPER_BIN_DIR', '/usr/bin') 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tool_path = os.path.join(tools_dir, 'ibtool') 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Take SDKROOT out of the environment passed to ibtool. ibtool itself has 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # no need for it, but when ibtool runs via xcrun and Xcode isn't aware of 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the SDK in use, its presence causes an error. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if 'SDKROOT' in os.environ: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ibtool_env = os.environ.copy() 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del ibtool_env['SDKROOT'] 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ibtool_env = os.environ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ibtool_cmd = subprocess.Popen([tool_path, '--localizable-strings', xib_path], 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stdout=subprocess.PIPE, stderr=subprocess.PIPE, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env=ibtool_env) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cmd_out, cmd_err) = ibtool_cmd.communicate() 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ibtool_cmd.returncode: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stderr.write('%s:0: error: ibtool on "%s" failed (%d):\n%s\n' % 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (generate_localizer, xib_path, ibtool_cmd.returncode, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd_err)) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cmd_out 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def extract_resource_constants(plist_localizable_strings_dict, xib_path): 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Extracts all the values that start with ^IDS from the localizable 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings plist entry.""" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants_list = [] 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for item_dict in plist_localizable_strings_dict.itervalues(): 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for item_value in item_dict.itervalues(): 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if item_value.startswith('^IDS'): 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants_list.append(item_value) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif item_value.startswith('IDS'): 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stderr.write( 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '%s:0: warning: %s found a string with questionable prefix, "%s"\n' 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) % (xib_path, generate_localizer, item_value)); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return constants_list 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def generate_file_contents(constants_list, xib_paths): 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Generates the header listing the constants.""" 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Bounce through a set to uniq the strings, sort the list, then build the 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # values we need from it. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants_list = sorted(set(constants_list)) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constant_list_str = '' 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for item in constants_list: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parts = item.split('$', 1) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_id = parts[0] 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(parts) == 2: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_arg_id = parts[1] 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_arg_id = '0' 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constant_list_str += ' { "%s", %s, %s },\n' % \ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ( item, label_id[1:], label_arg_id) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Assemble the contents from the templates. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values_dict = { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'resource_map_list': constant_list_str, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'generate_localizer': generate_localizer, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'xib_files': "\n// ".join(xib_paths), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_file = localizer_template_h % values_dict 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return h_file 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(argv=None): 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) global generate_localizer 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generate_localizer = os.path.basename(argv[0]) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Args 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(argv) < 3: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stderr.write('%s:0: error: Expected output file and then xibs\n' % 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generate_localizer); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_path = argv[1]; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xib_paths = argv[2:] 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_constants_list = [] 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for xib_path in xib_paths: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Run ibtool and convert to something Python can deal with 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plist_string = xib_localizable_strings(xib_path) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not plist_string: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plist = plistlib.readPlistFromString(plist_string) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Extract the resource constant strings 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) localizable_strings = plist['com.apple.ibtool.document.localizable-strings'] 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants_list = extract_resource_constants(localizable_strings, xib_path) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not constants_list: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.stderr.write("%s:0: warning: %s didn't find any resource strings\n" % 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xib_path, generate_localizer)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_constants_list.extend(constants_list) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Generate our file contents 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_file_content = \ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generate_file_contents(full_constants_list, xib_paths) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Write out the file 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_fd = open(output_path, 'w') 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_fd.write(h_file_content) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_fd.close() 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(Main(sys.argv)) 146