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.
7 # Usage: generate_localizer [xib_path] [output_dot_h_path] [output_dot_mm_path]
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.
17 generate_localizer
= "me"
19 localizer_template_h
= \
20 '''// ---------- WARNING ----------
21 // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY!
23 // This header includes the table used by ui_localizer.mm. Nothing else should
24 // be including this file.
26 // Generated by %(generate_localizer)s.
31 #ifndef UI_LOCALIZER_TABLE_H_
32 #define UI_LOCALIZER_TABLE_H_
34 static const UILocalizerResourceMap kUIResources[] = {
35 %(resource_map_list)s };
36 static const size_t kUIResourcesSize = arraysize(kUIResources);
38 #endif // UI_LOCALIZER_TABLE_H_
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')
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']
53 ibtool_env
= os
.environ
55 ibtool_cmd
= subprocess
.Popen([tool_path
, '--localizable-strings', xib_path
],
56 stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
,
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
,
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."""
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'):
76 '%s:0: warning: %s found a string with questionable prefix, "%s"\n'
77 % (xib_path
, generate_localizer
, item_value
));
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)
90 label_arg_id
= parts
[1]
93 constant_list_str
+= ' { "%s", %s, %s },\n' % \
94 ( item
, label_id
[1:], label_arg_id
)
95 # Assemble the contents from the templates.
97 'resource_map_list': constant_list_str
,
98 'generate_localizer': generate_localizer
,
99 'xib_files': "\n// ".join(xib_paths
),
101 h_file
= localizer_template_h
% values_dict
106 global generate_localizer
107 generate_localizer
= os
.path
.basename(argv
[0])
111 sys
.stderr
.write('%s:0: error: Expected output file and then xibs\n' %
114 output_path
= argv
[1];
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
)
123 plist
= plistlib
.readPlistFromString(plist_string
)
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
)
133 # Generate our file contents
135 generate_file_contents(full_constants_list
, xib_paths
)
138 file_fd
= open(output_path
, 'w')
139 file_fd
.write(h_file_content
)
144 if __name__
== '__main__':
145 sys
.exit(Main(sys
.argv
))