Home | History | Annotate | Download | only in mac
      1 #!/usr/bin/env 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   # Take SDKROOT out of the environment passed to ibtool. ibtool itself has
     44   # no need for it, but when ibtool runs via xcrun and Xcode isn't aware of
     45   # the SDK in use, its presence causes an error.
     46   if 'SDKROOT' in os.environ:
     47     ibtool_env = os.environ.copy()
     48     del ibtool_env['SDKROOT']
     49   else:
     50     ibtool_env = os.environ
     51 
     52   ibtool_cmd = subprocess.Popen(['xcrun', 'ibtool',
     53                                  '--localizable-strings', xib_path],
     54                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
     55                                 env=ibtool_env)
     56   (cmd_out, cmd_err) = ibtool_cmd.communicate()
     57   if ibtool_cmd.returncode:
     58     sys.stderr.write('%s:0: error: ibtool on "%s" failed (%d):\n%s\n' %
     59                      (generate_localizer, xib_path, ibtool_cmd.returncode,
     60                       cmd_err))
     61     return None
     62   return cmd_out
     63 
     64 def extract_resource_constants(plist_localizable_strings_dict, xib_path):
     65   """Extracts all the values that start with ^IDS from the localizable
     66   strings plist entry."""
     67   constants_list = []
     68   for item_dict in plist_localizable_strings_dict.itervalues():
     69     for item_value in item_dict.itervalues():
     70       if item_value.startswith('^IDS'):
     71         constants_list.append(item_value)
     72       elif item_value.startswith('IDS'):
     73         sys.stderr.write(
     74             '%s:0: warning: %s found a string with questionable prefix, "%s"\n'
     75             % (xib_path, generate_localizer, item_value));
     76   return constants_list
     77 
     78 def generate_file_contents(constants_list, xib_paths):
     79   """Generates the header listing the constants."""
     80   # Bounce through a set to uniq the strings, sort the list, then build the
     81   # values we need from it.
     82   constants_list = sorted(set(constants_list))
     83   constant_list_str = ''
     84   for item in constants_list:
     85     parts = item.split('$', 1)
     86     label_id = parts[0]
     87     if len(parts) == 2:
     88       label_arg_id = parts[1]
     89     else:
     90       label_arg_id = '0'
     91     constant_list_str += '    { "%s", %s, %s },\n' % \
     92         ( item, label_id[1:], label_arg_id)
     93   # Assemble the contents from the templates.
     94   values_dict = {
     95     'resource_map_list': constant_list_str,
     96     'generate_localizer': generate_localizer,
     97     'xib_files': "\n//     ".join(xib_paths),
     98   }
     99   h_file = localizer_template_h % values_dict
    100   return h_file
    101 
    102 
    103 def Main(argv=None):
    104   global generate_localizer
    105   generate_localizer = os.path.basename(argv[0])
    106 
    107   # Args
    108   if len(argv) < 3:
    109     sys.stderr.write('%s:0: error: Expected output file and then xibs\n' %
    110                      generate_localizer);
    111     return 1
    112   output_path = argv[1];
    113   xib_paths = argv[2:]
    114 
    115   full_constants_list = []
    116   for xib_path in xib_paths:
    117     # Run ibtool and convert to something Python can deal with
    118     plist_string = xib_localizable_strings(xib_path)
    119     if not plist_string:
    120       return 2
    121     plist = plistlib.readPlistFromString(plist_string)
    122 
    123     # Extract the resource constant strings
    124     localizable_strings = plist['com.apple.ibtool.document.localizable-strings']
    125     constants_list = extract_resource_constants(localizable_strings, xib_path)
    126     if not constants_list:
    127       sys.stderr.write("%s:0: warning: %s didn't find any resource strings\n" %
    128                        (xib_path, generate_localizer));
    129     full_constants_list.extend(constants_list)
    130 
    131   # Generate our file contents
    132   h_file_content = \
    133       generate_file_contents(full_constants_list, xib_paths)
    134 
    135   # Write out the file
    136   file_fd = open(output_path, 'w')
    137   file_fd.write(h_file_content)
    138   file_fd.close()
    139 
    140   return 0
    141 
    142 if __name__ == '__main__':
    143   sys.exit(Main(sys.argv))
    144