diff -r fe49e33862e2 -r 04b7640f6fb5 dtdinstaller/bin/convert_file.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dtdinstaller/bin/convert_file.pm Wed Sep 01 12:32:13 2010 +0100 @@ -0,0 +1,399 @@ +# +# Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +package Convert_file; + +# Hash of file meta information (name etc.). +my %file_meta_info; + +# List of logical name entries. +my @entries = (); + +sub convert_file { + my $file_to_process = shift; + + %file_meta_info = (); + @entries = (); + + # Convert LOC file to DTD... + if ($file_to_process =~ /\.loc$/) { + (my $file_to_write = $file_to_process) =~ s/\.loc$/.dtd/; + (my $file_log = $file_to_process) =~ s/\.loc$/.log/; + &read_loc_file($file_to_process); + &write_dtd_file($file_to_process, $file_to_write, $file_log); + } + # Convert DTD file to LOC... + elsif ($file_to_process =~ /\.dtd$/) { + (my $file_to_write = $file_to_process) =~ s/\.dtd$/.loc/; + (my $file_log = $file_to_process) =~ s/\.dtd$/.log/; + &read_dtd_file($file_to_process); + &write_loc_file($file_to_process, $file_to_write, $file_log); + } + else { + print "Unknown file format.\n"; + } +} + +# This subroutine reads DTD file into a data structure. Reading is done line +# by line. +# Adding extra complexity to this subroutine is the fact that ENTITY tag can +# either be declared before attribute definitions or after them. +sub read_dtd_file { + my $file_to_process = shift; + + open(FILE, $file_to_process) + or die "Can't open `$file_to_process' for reading: $!"; + + my %entry; + my $attribute_read = "FALSE"; + my $entity_read = "FALSE"; + + while (my $line = ) { + # NCR notation is used in DTD files. This is removed since it's not + # used in LOC files. + #&remove_NCR_notation(\$line); + chomp($line); + + SWITCH: { + # Extract file meta data. + # Matches eg. "> + if ($line =~ /\s*( ""> + if ($line =~ /\s* attributes -> entity + if ($attribute_read eq "TRUE" && $entity_read eq "TRUE") { + my %temp = %entry; + %entry = (); + push @entries, \%temp; + $attribute_read = "FALSE"; + $entity_read = "TRUE"; + + (my $loc_name, my $translation) = + $line =~ /\s* entity + elsif ($attribute_read eq "TRUE" && $entity_read eq "FALSE") { + (my $loc_name, my $translation) = + $line =~ /\s*.layout "" + if ($line =~ /\s*.[^\.]*(.layout|.description|.recycled|.release|.grammar|.term|.refers|.islocalizable|.item_type|.action_before|.action_after|.variables|.parents)\s*".[^"]*/) { + (my $item_name, my $content) = + $line =~ /\s*.[^\.]*.(.[^\s]*)\s*"(.[^"]*)/; + + $item_name =~ s/parents/Parents/; + $item_name =~ s/variables/Variables/; + + $entry{$item_name} = $content; + last SWITCH; + } + # Matches attribute tag. + if ($line =~ /\s*.[^\.]*.attributes/) { + # Case: entity -> attributes -> attributes + if ($entity_read eq "TRUE" && $attribute_read eq "TRUE") { + my %temp = %entry; + %entry = (); + push @entries, \%temp; + $entity_read = "FALSE"; + } + $attribute_read = "TRUE"; + + last SWITCH; + } + } + } + + # Include last entry also to results. This happens if file ends with an + # entry where attributes are defined after ENTITY. + if ($attribute_read eq "TRUE" && $entity_read eq "TRUE") { + my %temp = %entry; + %entry = (); + push @entries, \%temp; + } + + close FILE; +} + +# This subroutine reads LOC file into a data structure. Reading is done line +# by line. +sub read_loc_file { + my $file_to_process = shift; + + chmod ($file_to_process, 0777); # Make sure that file can be read, before trying to open it + + open(FILE, $file_to_process) + or die "Can't open `$file_to_process' for reading: $!"; + + my %entry; + + while (my $line = ) { + # NCR notation is used in DTD files. Not allowed characters are + # converted to NCR. + #&add_NCR_notation(\$line); + chomp($line); + + # Each line with #define defines a logical name/translation pair. This + # is saved to the data structure. + if ($line =~ /\s*#define\s*.[^\s]*\s*".[^"]*/) { + (my $item_name, my $content) = + $line =~ /\s*#define\s*(.[^\s]*)\s*"(.*)"$/; + + $entry{'logical_name'} = $item_name; + $entry{'translation'} = $content; + my %temp = %entry; + %entry = (); + push @entries, \%temp; + } + } + + close FILE; +} + +# This subroutine writes the data into a LOC file. +sub write_loc_file { + my $file_to_process = shift; + my $file_to_write = shift; + my $file_log = shift; + + open(my $file_handle, ">$file_to_write") + or die "Can't open `$file_to_write' for writing: $!"; + + open(my $log_file_handle, ">$file_log") + or die "Can't open `$file_log' for writing: $!"; + + my $tstamp = localtime(time); + + print $log_file_handle "Log created $tstamp:\n" . + "Errors and warnings for conversion of " . + "$file_to_process to $file_to_write\n\n"; + + # Write file header info. Mostly static text. + &write_loc_header($file_handle); + + print $file_handle "\n"; + + # This array defines the order in which attributes are written to a LOC + # file. + my @fields = ("item_type", "action_before", "action_after", "grammar", + "refers", "Parents", "Variables"); + + for my $i (0 .. $#entries) { + # Analyze entry for correctness and report possible errors. + &print_dtd_errors_and_warnings(\%{$entries[$i]}, $log_file_handle); + + # Seach for attributes and write them to output if found. + for my $y (0 .. $#fields) { + if (exists($entries[$i]{$fields[$y]})) { + print $file_handle + "//d: [$fields[$y]] : \"$entries[$i]{$fields[$y]}\"\n"; + } + } + + print $file_handle "//d: $entries[$i]{'description'}\n"; + print $file_handle "//l: $entries[$i]{'layout'}\n"; + print $file_handle "//r: $entries[$i]{'release'}\n"; + + print $file_handle "#define $entries[$i]{'logical_name'}" . + " \"$entries[$i]{'translation'}\"\n\n"; + } + + close $file_handle; + close $log_file_handle; +} + +sub print_dtd_errors_and_warnings { + my $entry_ref = shift; + my $log_file_handle = shift; + + # Either description or item_type and action_before should be defined. + if (!exists($entry_ref->{'description'}) && + !(exists($entry_ref->{'item_type'}) && + exists($entry_ref->{'action_before'}))) + { + print $log_file_handle "ERROR: $entry_ref->{'logical_name'} " . + "does not have any description data!\n"; + } + if (!exists($entry_ref->{'layout'})) { + print $log_file_handle "ERROR: $entry_ref->{'logical_name'} " . + "missing layout definition!\n"; + } + if (!exists($entry_ref->{'release'})) { + print $log_file_handle "ERROR: $entry_ref->{'logical_name'} " . + "missing release information!\n"; + } + if (!exists($entry_ref->{'Parents'})) { + print $log_file_handle "ERROR: $entry_ref->{'logical_name'} " . + "missing parent reference!\n"; + } + # Grammar should be defined if translation is a single word. + if (!($entry_ref->{'translation'} =~ /\s/) && + !exists($entry_ref->{'grammar'})) { + print $log_file_handle "\tWARNING: $entry_ref->{'logical_name'} " . + "is a single word, but no grammar data is " . + "given!\n"; + } + # Variables should be defined if translation contains variables. + if ($entry_ref->{'translation'} =~ /\%/ && + !exists($entry_ref->{'Variables'})) { + print $log_file_handle "\tWARNING: $entry_ref->{'logical_name'} " . + "has a variable or parameter, but no variable " . + "data is given!\n"; + } +} + +# This subroutine writes the data into a DTD file. Only ENTITY definitions are +# written i.e. no attribute definitions. +sub write_dtd_file { + my $file_to_process = shift; + my $file_to_write = shift; + my $file_log = shift; + + open(my $file_handle, ">$file_to_write") + or die "Can't open `$file_to_write' for writing: $!"; + + open(my $log_file_handle, ">$file_log") + or die "Can't open `$file_log' for writing: $!"; + + my $tstamp = localtime(time); + + print $log_file_handle "Log created $tstamp:\n" . + "Errors and warnings for conversion of " . + "$file_to_process to $file_to_write\n\n"; + + # Write file header info. Mostly static text. + my $file_name = ""; + if ($file_to_process =~ /\//) { + ($file_name) = $file_to_process =~ /\/(.[^\/]*)$/; + } + else { + $file_name = $file_to_process; + } + &write_dtd_header($file_handle, $file_name); + + for my $i (0 .. $#entries) { + print $log_file_handle "Found $entries[$i]{'logical_name'}\n"; + + $entries[$i]{'translation'} =~ s/\\"/"/g; + + print $file_handle "\n"; + } + + close $file_handle; + close $log_file_handle; +} + +sub write_loc_header { + my $file_handle = shift; + print $file_handle < + +EOT +} + +# Subroutine to add NCR notation to string. +sub add_NCR_notation { + my $string = shift; + # Replace characters with NCR notation. 'eh' is used to denote &# character + # sequence. If this is not used then &# sequence would be also replaced with + # NCR. + $$string =~ s/'/eh39;/g; + $$string =~ s/\%/eh37;/g; + $$string =~ s/>/eh62;/g; + $$string =~ s//g; + $$string =~ s/</