1 #!/usr/bin/python 2 3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. 4 # Use of this source code is governed by a BSD-style license that can be 5 # found in the LICENSE file. 6 7 # Usage: generate_localizer [xib_path] [output_dot_h_path] [output_dot_mm_path] 8 # 9 # Extracts all the localizable strings that start with "^IDS" from the given 10 # xib file, and then generates a localizer to process those strings. 11 12 import os 13 import plistlib 14 import subprocess 15 import sys 16 17 generate_localizer = "me" 18 19 localizer_template_h = \ 20 '''// ---------- WARNING ---------- 21 // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! 22 // 23 // This header includes the table used by ui_localizer.mm. Nothing else should 24 // be including this file. 25 // 26 // Generated by %(generate_localizer)s. 27 // Generated from: 28 // %(xib_files)s 29 // 30 31 #ifndef UI_LOCALIZER_TABLE_H_ 32 #define UI_LOCALIZER_TABLE_H_ 33 34 static const UILocalizerResourceMap kUIResources[] = { 35 %(resource_map_list)s }; 36 static const size_t kUIResourcesSize = arraysize(kUIResources); 37 38 #endif // UI_LOCALIZER_TABLE_H_ 39 ''' 40 41 def xib_localizable_strings(xib_path): 42 """Runs ibtool to extract the localizable strings data from the xib.""" 43 tools_dir = os.environ.get('DEVELOPER_BIN_DIR', '/usr/bin') 44 tool_path = os.path.join(tools_dir, 'ibtool') 45 46 # Take SDKROOT out of the environment passed to ibtool. ibtool itself has 47 # no need for it, but when ibtool runs via xcrun and Xcode isn't aware of 48 # the SDK in use, its presence causes an error. 49 if 'SDKROOT' in os.environ: 50 ibtool_env = os.environ.copy() 51 del ibtool_env['SDKROOT'] 52 else: 53 ibtool_env = os.environ 54 55 ibtool_cmd = subprocess.Popen([tool_path, '--localizable-strings', xib_path], 56 stdout=subprocess.PIPE, stderr=subprocess.PIPE, 57 env=ibtool_env) 58 (cmd_out, cmd_err) = ibtool_cmd.communicate() 59 if ibtool_cmd.returncode: 60 sys.stderr.write('%s:0: error: ibtool on "%s" failed (%d):\n%s\n' % 61 (generate_localizer, xib_path, ibtool_cmd.returncode, 62 cmd_err)) 63 return None 64 return cmd_out 65 66 def extract_resource_constants(plist_localizable_strings_dict, xib_path): 67 """Extracts all the values that start with ^IDS from the localizable 68 strings plist entry.""" 69 constants_list = [] 70 for item_dict in plist_localizable_strings_dict.itervalues(): 71 for item_value in item_dict.itervalues(): 72 if item_value.startswith('^IDS'): 73 constants_list.append(item_value) 74 elif item_value.startswith('IDS'): 75 sys.stderr.write( 76 '%s:0: warning: %s found a string with questionable prefix, "%s"\n' 77 % (xib_path, generate_localizer, item_value)); 78 return constants_list 79 80 def generate_file_contents(constants_list, xib_paths): 81 """Generates the header listing the constants.""" 82 # Bounce through a set to uniq the strings, sort the list, then build the 83 # values we need from it. 84 constants_list = sorted(set(constants_list)) 85 constant_list_str = '' 86 for item in constants_list: 87 parts = item.split('$', 1) 88 label_id = parts[0] 89 if len(parts) == 2: 90 label_arg_id = parts[1] 91 else: 92 label_arg_id = '0' 93 constant_list_str += ' { "%s", %s, %s },\n' % \ 94 ( item, label_id[1:], label_arg_id) 95 # Assemble the contents from the templates. 96 values_dict = { 97 'resource_map_list': constant_list_str, 98 'generate_localizer': generate_localizer, 99 'xib_files': "\n// ".join(xib_paths), 100 } 101 h_file = localizer_template_h % values_dict 102 return h_file 103 104 105 def Main(argv=None): 106 global generate_localizer 107 generate_localizer = os.path.basename(argv[0]) 108 109 # Args 110 if len(argv) < 3: 111 sys.stderr.write('%s:0: error: Expected output file and then xibs\n' % 112 generate_localizer); 113 return 1 114 output_path = argv[1]; 115 xib_paths = argv[2:] 116 117 full_constants_list = [] 118 for xib_path in xib_paths: 119 # Run ibtool and convert to something Python can deal with 120 plist_string = xib_localizable_strings(xib_path) 121 if not plist_string: 122 return 2 123 plist = plistlib.readPlistFromString(plist_string) 124 125 # Extract the resource constant strings 126 localizable_strings = plist['com.apple.ibtool.document.localizable-strings'] 127 constants_list = extract_resource_constants(localizable_strings, xib_path) 128 if not constants_list: 129 sys.stderr.write("%s:0: warning: %s didn't find any resource strings\n" % 130 (xib_path, generate_localizer)); 131 full_constants_list.extend(constants_list) 132 133 # Generate our file contents 134 h_file_content = \ 135 generate_file_contents(full_constants_list, xib_paths) 136 137 # Write out the file 138 file_fd = open(output_path, 'w') 139 file_fd.write(h_file_content) 140 file_fd.close() 141 142 return 0 143 144 if __name__ == '__main__': 145 sys.exit(Main(sys.argv)) 146