imgtools/imaker/buildrom_plugins/localise.pm
author timothy.murphy@nokia.com
Sun, 28 Feb 2010 21:18:07 +0200
branchfix
changeset 279 733464eaac50
parent 1 be27ed110b50
child 584 56dd7656a965
permissions -rw-r--r--
fix: make sure host attribute is set rather than blank in logs on windows by using the env var 'COMPUTERNAME' instead of 'HOSTNAME'. Thus make it less difficult to order recipes in the log by time.

#
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "Symbian Foundation License v1.0"
# which accompanies this distribution, and is available
# at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
#
# Initial Contributors:
# Nokia Corporation - initial contribution.
#
# Contributors:
#
# Description:
# Adds a LOCALISE macro that enables configuration of localised files.
# The localised language selection is done with a ADD_LANGUAGE macro.
#



###############################################################################
#
# Syntax: LOCALISE
#   type=LOCALISE(source, target[, languages])
#   source => the source file. The section that needs to be localised should be marked with ??.
#   target => the target file. The section that needs to be localised should be marked with ??.
#   languages => a space delimited list of language codes
#
# Syntax: ADD_LANGUAGE
#   ADD_LANGUAGE lang
#
# Example:
# Add languages
# ADD_LANGUAGE 01
# ADD_LANGUAGE 02
# ADD_LANGUAGE 03
#
# Use Case 1:
# Localises a App resoure file.
#   data=LOCALISE(APP_RESOURCE_DIR\App.r??, RESOURCE_DIR\app.r??)
# Output:
#   data=APP_RESOURCE_DIR\App.r01 RESOURCE_DIR\app.r01
#   data=APP_RESOURCE_DIR\App.r02 RESOURCE_DIR\app.r02
#   data=APP_RESOURCE_DIR\App.r03 RESOURCE_DIR\app.r03
#
# Use Case 2:
# Localise all resource files under a section
# ADD_LANGUAGE 01
# ADD_LANGUAGE 02
# ADD_LANGUAGE 03
#
# LOCALISE_ALL_RESOURCES_BEGIN
# // All resource files will be localised
# data=APP_RESOURCE_DIR\App.rsc RESOURCE_DIR\app.rsc
# data=APP_RESOURCE_DIR\App2.rsc RESOURCE_DIR\app2.rsc
# LOCALISE_ALL_RESOURCES_END
# Output:
#   data=APP_RESOURCE_DIR\App.r01 RESOURCE_DIR\app.r01
#   data=APP_RESOURCE_DIR\App.r02 RESOURCE_DIR\app.r02
#   data=APP_RESOURCE_DIR\App.r03 RESOURCE_DIR\app.r03
#   data=APP_RESOURCE_DIR\App.r01 RESOURCE_DIR\app.r01
#   data=APP_RESOURCE_DIR\App.r02 RESOURCE_DIR\app.r02
#   data=APP_RESOURCE_DIR\App.r03 RESOURCE_DIR\app.r03
#
###############################################################################


package localise;
use strict;
use localise_all_resources;

BEGIN
  {
  use Exporter ();
  our ( $VERSION, @ISA, @EXPORT );
  # set the version for version checking
  $VERSION     = 1.00;

  @ISA         = qw( Exporter );
  @EXPORT      = qw( &localise_info
                     &do_localise_extension
                     &convert_lang
                     &trim
                     &is_addlanguage_entry
                     &get_lang_from_addlanguage_entry
                     &is_localise_entry
                     &get_type_from_localise_entry
                     &get_source_from_localise_entry
                     &get_target_from_localise_entry
                     &get_langs_from_localise_entry
                     &parse_component_langs
                     &expand_localise_macro
                     &is_language_in_component_langs
                      );
  }

my %localise_infostruct =
  (
  name => "localise",
  invocation => "InvocationPoint1",
  single => "localise::do_localise_extension"
  );

my $line;
my @newobydata;
my %languages;
my $verbose=0;
my $errors=0;
my $localise_all_resource=0;

sub localise_info
  {
  return \%localise_infostruct;
  }

# Entry point for the plugi
sub do_localise_extension
{
  print "========================== Begin do_localise_extension =======================\n" if $verbose;
  my $obydata = shift;
  do_localise_all_resources_extension(\@{$obydata});


  undef @newobydata;
  foreach $line (@{$obydata})
  {
    # Ignore REM statements, to avoid processing "REM __SCALABLE_IMAGE( ... )"
    if ($line =~ /^\s*REM/i)
    {
      push @newobydata, $line;
      next;
    }
    # ADD_LANGUAGE xx
    if (is_addlanguage_entry($line))
    {
      my $code = get_lang_from_addlanguage_entry($line);
      if ($code !~ /^\w\w+$/)
      {
        print "ERROR: bad default language code $code";
        #$errors++;
        next;
      }
      else
      {
        print "adding language $code\n" if $verbose;
        $languages{$code} = 1;
        push @newobydata, "REM handled $line";
        next;
      }
    }
    # LOCALISE macro
    if (is_localise_entry($line))
    {
      my @newdata = expand_localise_macro($line,\%languages);
      push @newobydata, @newdata;
      next;
    }
    # Default case
    push @newobydata, $line;
  }
  @{$obydata} = @newobydata;
  print "========================== End do_localise_extension =======================\n" if $verbose;
  #Stop image creation in error case
  #exit(1) if ($errors);
}

sub expand_localise_macro
{
  my $data         = $_[0];
  my %theLanguages = %{ $_[1] };
  my @localised = ();
  print "LOCALISE $data\n" if $verbose;

  my $type   = get_type_from_localise_entry($data);
  my $source = get_source_from_localise_entry($data);
  my $target = get_target_from_localise_entry($data);
  my %componentLangs = get_langs_from_localise_entry($data);

  my @languages = sort keys %theLanguages;
  foreach my $lang (@languages)
  {
    print "Language ".$lang."\n" if $verbose;
    my $sourcedata = convert_lang($source,$lang);
    my $targetdata = convert_lang($target,$lang);

    # Check does the component have overriding configurations
    # The component specific setting can define the component to ignore localisation
    if ( !is_language_in_component_langs($lang,\%componentLangs) )
    {
      #Component specific configuration overrides the global lang definitions
      print "WARNING: Component specific configuration removes this resource $source\n"  if $verbose;
      next;
    }

    my $data = "$type=$sourcedata $targetdata\n";
    print "lang data $data\n" if $verbose;
    #push the data to the new structure
    push @localised, $data;
  }
  return @localised;
}

sub is_language_in_component_langs($$)
{
  my $lang           = $_[0];
  my %componentLangs = %{ $_[1] };
  #Check whether the component langs is empty
  if ( (keys %componentLangs) > 0)
  {
    if (exists $componentLangs{ $lang })
    {
      return $componentLangs{ $lang };
    }
    else
    {
      return 0;
    }
  }
  else
  {
    return 1;
  }

}
# trim(string)
# Removes spaces from both ends of the string.
# Returns a trimmed string.
sub trim($)
{
  my $string = shift;
  $string =~ s/^\s+//;
  $string =~ s/\s+$//;
  return $string;
}

# convert_lang(string)
# convert the string ?? part to the lang specific
sub convert_lang($$)
{
  my $res = shift;
  my $lang= shift;
  my $count = ($res =~ tr/%//);
  #create array with count amount of time of lang
  my @data = ();
  for (my $i=0; $i<$count; $i++) {
    push(@data, $lang);
  }
  my $output = sprintf($res,@data);
  return $output;
}
# match ADD_LANGUAGE 01
sub is_addlanguage_entry($)
{
  my $entry = shift;
  if ( $entry =~ m/^\s*ADD_LANGUAGE\s+(\S+)\s*/i )
  {
    return 1;
  }
  return 0;
}
#
sub get_lang_from_addlanguage_entry($)
{
  my $entry = shift;
  if ( $entry =~ m/^\s*ADD_LANGUAGE\s+(\S+)/i )
  {
    return $1;
  }
  return "";
}

# match data=LOCALISE(foobar.rsc, resource/foobar.rsc)
sub is_localise_entry($)
{
  my $entry = shift;
  if ( $entry =~ m/^\s*\S+\s*=\s*LOCALISE(\s*(\S+),\s*(\S+))/i )
  {
    return 1;
  }
  return 0;
}
# get the type from an iby entry
sub get_type_from_localise_entry($)
{
  my $entry = shift;
  if ( $entry =~ m/^\s*(\S+)\s*=/i )
  {
    return $1;
  }
  return "";
}
# get the source file from an iby entry
sub get_source_from_localise_entry($)
{
  my $entry = shift;
  if ( $entry =~ m/^\s*(\S+)\s*=\s*LOCALISE\(\s*([^, ]+)\s*,/i )
  {
    return $2;
  }
  return "";
}
# get the target file from an iby entry
sub get_target_from_localise_entry($)
{
  my $entry = shift;
  if ( $entry =~ m/^\s*(\S+)\s*=\s*LOCALISE\(\s*([^, ]+)\s*,\s*([^, ]+)(,|\))/i )
  {
    return $3;
  }
  return "";
}
# get the target file from an iby entry
sub get_langs_from_localise_entry($)
{
  my $entry = shift;
  my %emptyhash;
  if ( $entry =~ m/^\s*(\S+)\s*=\s*LOCALISE\(\s*([^, ]+)\s*,\s*([^, ]+)\s*,\s*(.*?)\)/i )
  {
    if ($4)
    {
      return parse_component_langs($4);
    }
  }
  return %emptyhash;
}
sub parse_component_langs($)
{
  my $langs = shift;
  my %cLangs;
  foreach my $item (split(/ /,$langs))
  {
  print "lang item $item\n" if $verbose;
  if ($item =~ /^(\w\w+)$/)
    {
    print "include component specific language $1\n" if $verbose;
    $cLangs{$1} = 1;
    }
  elsif ($item =~ /^!(\w\w+)$/)
    {
    print "exclude component specific language $1\n" if $verbose;
    $cLangs{$1} = 0;
    }
  else
    {
    print "ERROR: bad default language code in $item localise macro $langs\n";
    $errors++;
    next;
    }
  }
  return %cLangs;
}


1;  # Return a true value from the file