Module localisation |
[hide private]
[frames] | no frames]

# Source Code for Module localisation

      1  #============================================================================
      2  #Name        : localisation.py
      3  #Part of     : Helium
      4
      5  #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
      6  #All rights reserved.
      7  #This component and the accompanying materials are made available
      8  #under the terms of the License "Eclipse Public License v1.0"
      9  #which accompanies this distribution, and is available
     10  #at the URL "http://www.eclipse.org/legal/epl-v10.html".
     11  #
     12  #Initial Contributors:
     13  #Nokia Corporation - initial contribution.
     14  #
     15  #Contributors:
     16  #
     17  #Description:
     18  #===============================================================================
     19
     20  """ Localisation related function.
     21          * Parsing of languages.xml
     22  """
     23  import re
     24  import amara
     25  import os
     26  import bsf
     27  import os.path
     28
     29 -class Languages:
     30      """ Languages.xml file parser. """
     31
     32 -    def __init__(self, filename):
     33          self.__filename = filename
     34          self.__xml = amara.parse(open(filename,"r"))
     35
     36 -    def get_language_ids(self):
     37          """ returns languages id list """
     38          result = []
     39          for language in self.__xml.xml_xpath("/languages/language"):
     40              result.append(language.id.strip())
     41          return result
     42
     43
     44 -    def get_name(self, lid):
     45          """ returns languages id list """
     46          for language in self.__xml.xml_xpath("/languages/language[@id='%s']" % lid):
     47              return language.name.strip()
     48
     49 -    def get_attribute(self, lid, name, default=None):
     50          """ returns the value for a specific language attribute name. It returns default if not found. """
     51          for language in self.__xml.xml_xpath("/languages/language[@id='%s']/%s" % (lid, name)):
     52              return language.xml_child_text.strip()
     53          return default
     54
     55
     56 -    def get_fallbacks(self, lid):
     57          """ Return the list of available fallbacks
     58              None if not any.
     59          """
     60          string = self.get_attribute(lid, 'fallbacks')
     61          if (string != None):
     62              return string.split(',')
     63          return None
     64
     65 -    def find_first_fallback(self, lid, exists):
     66          """ Find recursively the first reasonable alternative
     67              lid the language id
     68              exists an existance function that takes a language id
     69              as parameter and return a boolean
     70          """
     71
     72          if (exists(lid)):
     73              return lid
     74
     75          # get fallback list
     76          fallbacks = self.get_fallbacks(lid)
     77          if fallbacks == None:
     78              return None
     79
     80          for fallback in fallbacks:
     81              if exists(fallback):
     82                  return fallback
     83
     84          for fallback in fallbacks:
     85              ffallback = self.find_first_fallback(fallback)
     86              if ffallback != None:
     87                  return ffallback
     88
     89          return None
     90
     91
     92
     93 -def get_all_variations(languages_xml):
     94      """ Returns a list of all regional variations supported by platform. """
     95      variations = {'western':1}
     96      xml = Languages(languages_xml)
     97      for lid in xml.get_language_ids():
     98          variations[xml.get_attribute(lid, 'core', 'western')] = 1
     99      return variations.keys()
    100
    101 -def get_languages_for_variation(languages_xml, variation='western'):
    102      """ Returns alist of all supported languages for a specific region. """
    103      xml = Languages(languages_xml)
    104      result = []
    105      for lid in xml.get_language_ids():
    106          if (xml.get_attribute(lid, 'core', 'western') == variation):
    107              result.append(lid)
    108      return result
    109
    110
    111 -def _apply_override(overrides, line):
    112      res = re.match(r'\s*(data|file)=\s*(\S+)\s+(\S+)', line)
    113      if res != None and overrides.has_key(res.group(3).lower()):
    114          print "OVERRIDE: %s => %s" % (res.group(2), overrides[res.group(3).lower()])
    115          return "%s=%s %s" % (res.group(1), overrides[res.group(3).lower()], res.group(3))
    116      return line
    117
    118
    119 -def create_locales_iby(product, lid, flags=None, prefix='', suffix=''):
    120      """ Function that generates locales_xx.iby into rom product folder.
    121      """
    122      if flags is None:
    123          flags = []
    124      bsfs = bsf.read_all()
    125      if not bsfs.has_key(product):
    126          raise Exception("Product not defined, could not find %s.bsf" % product)
    127
    128      variantpath = bsfs[product].get_path()
    129      if lid == "sc":
    130          return
    131      outputfile = "/epoc32/rom/%s/locales_%s.iby" % (variantpath, lid)
    132
    133      print ("Generating %s..." % outputfile)
    134
    135
    136      output = open (outputfile, "w+")
    137      output.write("#ifndef __LOCALES_%s_IBY__\n" % lid)
    138      output.write("#define __LOCALES_%s_IBY__\n" % lid)
    139
    140      args = ''
    141      configs = bsfs[product].get_path_as_array()
    142      configs.reverse()
    143      for customisation in configs:
    144          args += "-I \"./%s\" " % bsfs[customisation].get_path()
    145          args += "-I \"../include/%s\" " % bsfs[customisation].get_path()
    146
    147      args += "-I ..\\include\\oem"
    148      for flag in flags:
    149          args = args + " -D%s" % flag
    150
    151      cdir = os.curdir
    152      os.chdir ("/epoc32/rom")
    153      cmd = "cpp -nostdinc -u %s %s include\\locales_sc.iby -include .\\include\\header.iby %s" % (prefix, args, suffix)
    154      print ("Calling %s\n" % cmd)
    155      stdin, stdout, stderr = os.popen3(cmd)
    156      stdin.close()
    157      result = stdout.read()
    158      errors =  stderr.read()
    159      stderr.close()
    160      status = stdout.close() or 0
    161
    162      print errors
    163
    164      # parsing overrides first
    165      overrides = {}
    166      for line in result.splitlines():
    167          res = re.match(r'^\s*(?:ROM_IMAGE\[\d+\]\s+)?data-override\s*=\s*(\S+)\s+(\S+)', line)
    168          if res != None:
    169              print "Found override directive %s -> %s" % (res.group(2).lower(), res.group(1))
    170              overrides[res.group(2).lower()] = res.group(1)
    171
    172      for line in result.splitlines():
    173          if re.match(r'^\s*(ROM_IMAGE\[\d+\]\s+)?data-override\s*=\s*(\S+)\s+(\S+)', line):
    174              pass
    175          else:
    176              line = _apply_override(overrides, line)
    177              if re.match("^\\s*data\\s*=\\s*MULTI_LINGUIFY", line):
    178                  res = re.search(r"MULTI_LINGUIFY\s*\(\s*(\S+)\s+(\S+)\s+(\S+)\s*\)", line)
    179                  if res.group(1).lower() == "rsc":
    180                      ext = "r%s" % lid
    181                      output.write("data=%s.%s %s.%s\n" % (res.group(2), res.group(1), res.group(3), ext))
    182                  else:
    183                      print "WARNING: Cannot extract '%s'" % line
    184
    185              elif re.search(r"\.rsc", line, re.I) != None:
    186                  output.write(re.sub(r"\.[rR][sS][cC]", r".r%s" % lid, line) + "\n")
    187              elif re.search(r"\.dbz", line, re.I):
    188                  output.write(re.sub(r"\.[dD][bB][zZ]", r".d%s" % lid, line) + "\n")
    189              elif re.search(r"\.hlp", line, re.I):
    190                  output.write(re.sub(r"\.[hH][lL][pP]", r".h%s" % lid, line) + "\n")
    191              elif re.search(r"Content\\01", line, re.I):
    192                  #rename Content\01 to Content\xx (where xx is language id). This is for handlng DTD files
    193                  output.write(re.sub(r"Content\\01", r"Content\\%s" % lid, line) + "\n")
    194              elif re.search(r"\.o0001", line, re.I):
    195                  lang = lid
    196                  while (len(lang)<4):
    197                      lang = "0%s" % lang
    198                  output.write(re.sub(r"\.[oO]\d+", ".o%s" % lang, line) + "\n")
    199              elif re.search(r"elocl\.dll", line, re.I):
    200                  output.write(re.sub(r"\.[lL][oO][cC]|\.[dD][lL][lL]", ".%s" % lid, line) + "\n")
    201              elif re.search(r"^\s*(data|file)=", line, re.I):
    202                  print ("WARNING: This should not be included in resource.iby '%s'\nThis file should be included using an 'applicationnameVariant.iby' file.\n" % line)
    203      output.write("#endif\n")
    204      output.close()
    205      os.chdir(cdir)
    206      return status
    207
    208
    209
    210  VARIANT_ID_KEY = 'variant.id'
    211  VARIATION_DIR_KEY = 'variation.dir'
    212
    213 -def find_variant_path(config, key=VARIANT_ID_KEY):
    214      """ This function helps to find the variant directory
    215          using variant configuration
    216      """
    217      if config.has_key(VARIATION_DIR_KEY) and os.path.exists(config[VARIATION_DIR_KEY]):
    218          for directory in os.listdir(config[VARIATION_DIR_KEY]):
    219              if (config.has_key(key) and re.match(r".*_%s$" % config[key], directory) != None):
    220                  return os.path.join(config[VARIATION_DIR_KEY], directory)
    221      return None
    222