xref: /aoo42x/main/l10ntools/scripts/localize.pl (revision 7e90fac2)
1:
2eval 'exec perl -wS $0 ${1+"$@"}'
3    if 0;
4
5
6#**************************************************************
7#
8#  Licensed to the Apache Software Foundation (ASF) under one
9#  or more contributor license agreements.  See the NOTICE file
10#  distributed with this work for additional information
11#  regarding copyright ownership.  The ASF licenses this file
12#  to you under the Apache License, Version 2.0 (the
13#  "License"); you may not use this file except in compliance
14#  with the License.  You may obtain a copy of the License at
15#
16#    http://www.apache.org/licenses/LICENSE-2.0
17#
18#  Unless required by applicable law or agreed to in writing,
19#  software distributed under the License is distributed on an
20#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21#  KIND, either express or implied.  See the License for the
22#  specific language governing permissions and limitations
23#  under the License.
24#
25#**************************************************************
26
27
28
29use strict;
30use Getopt::Long;
31use IO::Handle;
32use File::Find;
33use File::Temp;
34use File::Path;
35use File::Copy;
36use File::Glob qw(:glob csh_glob);
37use Cwd;
38
39my $CVS_BINARY = "/usr/bin/cvs";
40# ver 1.1
41#
42#### module lookup
43#use lib ("$ENV{SOLARENV}/bin/modules", "$ENV{COMMON_ENV_TOOLS}/modules");
44
45#### module lookup
46# OOo conform
47my @lib_dirs;
48BEGIN {
49    if ( !defined($ENV{SOLARENV}) ) {
50        die "No environment found (environment variable SOLARENV is undefined)";
51    }
52    push(@lib_dirs, "$ENV{SOLARENV}/bin/modules");
53    push(@lib_dirs, "$ENV{COMMON_ENV_TOOLS}/modules") if defined($ENV{COMMON_ENV_TOOLS});
54}
55use lib (@lib_dirs);
56
57#### globals ####
58my $sdffile                 = '';
59my $no_sort                 = '';
60my $create_dirs             = '';
61my $multi_localize_files    = '';
62my $module_to_merge         = '';
63my $sort_sdf_before         = '';
64my $outputfile              = '';
65my $no_gsicheck             = '';
66my $mode                    = '';
67my $bVerbose                = "0";
68my $srcpath                 = '';
69my $languages;
70#my %sl_modules;     # Contains all modules where en-US and de is source language
71my $use_default_date = '0';
72my $force_ooo_module = '0';
73my %is_ooo_module;
74my %is_so_module;
75
76         #         (                           leftpart                                                     )            (           rightpart                    )
77         #            prj      file      dummy     type       gid       lid      helpid    pform     width      lang       text    helptext  qhelptext   title    timestamp
78my $sdf_regex  = "((([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*))\t([^\t]*)\t(([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t)([^\t]*))";
79my $file_types = "(src|hrc|xcs|xcu|lng|ulf|xrm|xhp|xcd|xgf|xxl|xrb)";
80# Always use this date to prevent cvs conflicts
81my $default_date = "2002-02-02 02:02:02";
82my @sdfparticles;
83
84#### main ####
85parse_options();
86
87my $binpath = '';
88if( defined $ENV{UPDMINOREXT} )
89{
90    $binpath = $ENV{SOLARVER}."/".$ENV{INPATH}."/bin".$ENV{UPDMINOREXT}."/" ;
91}
92else
93{
94    $binpath = $ENV{SOLARVER}."/".$ENV{INPATH}."/bin/" ;
95}
96
97#%sl_modules = fetch_sourcelanguage_dirlist();
98
99
100if   ( $mode eq "merge"    )    {
101    if ( ! $no_gsicheck ){
102        merge_gsicheck();
103    }
104    splitfile( $sdffile );
105    if ( ! $no_gsicheck ){
106        unlink $sdffile;             # remove temp file!
107    }
108}
109elsif( $mode eq "extract"  )    {
110    collectfiles( $outputfile );
111}
112else                            {
113    usage();
114}
115
116exit(0);
117
118#########################################################
119sub splitfile{
120
121    my $lastFile        = '';
122    my $currentFile     = '';
123    my $cur_sdffile     = '';
124    my $last_sdffile    = '';
125    my $delim;
126    my $badDelim;
127    my $start           = 'TRUE';
128    my %index  = ();
129    my %block;
130
131    STDOUT->autoflush( 1 );
132
133    #print STDOUT "Open File $sdffile\n";
134    open MYFILE , "< $sdffile"
135    or die "Can't open '$sdffile'\n";
136
137#    my %lang_hash;
138    my %string_hash_ooo;
139    my %string_hash_so;
140    my %so_modules;
141    $so_modules{ "extras_full" } = "TRUE";
142
143    while( <MYFILE>){
144         if( /$sdf_regex/ ){
145            my $line           = defined $_ ? $_ : '';
146            my $prj            = defined $3 ? $3 : '';
147            my $file           = defined $4 ? $4 : '';
148            my $type           = defined $6 ? $6 : '';
149            my $gid            = defined $7 ? $7 : '';
150            my $lid            = defined $8 ? $8 : '';
151            my $lang           = defined $12 ? $12 : '';
152            my $plattform      = defined $10 ? $10 : '';
153            my $helpid         = defined $9 ? $9 : '';
154            next if( $prj eq "binfilter" );     # Don't merge strings into binfilter module
155	        chomp( $line );
156
157            if( $force_ooo_module )
158            {
159                $string_hash_ooo { $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line;
160            }
161            else
162            {
163                $string_hash_so{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line;
164            }
165        }
166    }
167    close( MYFILE );
168
169    if( !defined $ENV{SOURCE_ROOT_DIR} ){
170        print "Error, no SOURCE_ROOT_DIR in env found.\n";
171        exit( -1 );
172    }
173    my $src_root = $ENV{SOURCE_ROOT_DIR};
174    my $ooo_src_root = $src_root."/l10n";
175    my $so_l10n_path  = $src_root."/sun/l10n_so/source";
176    my $ooo_l10n_path = $ooo_src_root."/l10n/source";
177
178    #print "$so_l10n_path\n";
179    #print "$ooo_l10n_path\n";
180
181    if( $force_ooo_module )
182    {
183        write_sdf( \%string_hash_ooo , $ooo_l10n_path );
184    }
185    else
186    {
187        write_sdf( \%string_hash_so , $so_l10n_path );
188    }
189}
190
191sub write_sdf
192{
193    my $string_hash         = shift;
194    my $l10n_file           = shift;
195
196    foreach my $lang( keys( %{ $string_hash } ) )
197    {
198        my @sdf_file;
199        next , if( $lang eq "en-US" );
200
201        mkdir $l10n_file."/$lang";
202        # mkdir!!!!
203        my $current_l10n_file = $l10n_file."/$lang/localize.sdf";
204        print "Writing '$current_l10n_file'\n";
205        if( open DESTFILE , "< $current_l10n_file" ){
206
207            while(<DESTFILE>){
208                if( /$sdf_regex/ ){
209                    my $line           = defined $_ ? $_ : '';
210                    my $prj            = defined $3 ? $3 : '';
211                    my $file           = defined $4 ? $4 : '';
212                    my $type           = defined $6 ? $6 : '';
213                    my $gid            = defined $7 ? $7 : '';
214                    my $lid            = defined $8 ? $8 : '';
215                    my $lang           = defined $12 ? $12 : '';
216                    my $plattform      = defined $10 ? $10 : '';
217                    my $helpid         = defined $9 ? $9 : '';
218
219                    chomp( $line );
220                    if ( defined $string_hash->{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } )
221                    {
222                        # Changed String!
223                        push @sdf_file , $string_hash->{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } ;
224                        $string_hash->{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = undef;
225                    }
226                    else
227                    {
228                        # No new string
229                        push @sdf_file , $line;
230                    }
231                }
232            }
233        }
234        close( DESTFILE );
235        #Now just append the enw strings
236        #FIXME!!! Implement insertion in the correct order
237        foreach my $key ( keys ( %{ $string_hash->{ $lang } } ) )
238        {
239            push @sdf_file , $string_hash->{ $lang }{ $key } , if ( defined $string_hash->{ $lang }{ $key } );
240            #print "WARNING: Not defined = ".$string_hash->{ $lang }{ $key }."\n", if( ! defined  $string_hash->{ $lang }{ $key } );
241        }
242
243        # Write the new file
244        my ( $TMPFILE , $tmpfile ) = File::Temp::tempfile();
245        if( open DESTFILE , "+> $tmpfile " ){
246            print DESTFILE get_license_header();
247            foreach my $string( @sdf_file ){
248                print DESTFILE "$string\n";
249            }
250            close ( DESTFILE );
251            if( move( $current_l10n_file , $current_l10n_file.".backup" ) ){
252                if( copy( $tmpfile , $current_l10n_file ) ){
253                    unlink $l10n_file.".backup";
254                 } else { print STDERR "Can't open/create '$l10n_file', original file is renamed to $l10n_file.backup\n"; }
255            } else { print STDERR "Can't open/create '$l10n_file'\n"; }
256         }else{
257            print STDERR "WARNING: Can't open/create '$l10n_file'\n";
258         }
259         unlink $tmpfile;
260     }
261}
262
263#########################################################
264
265sub get_license_header{
266    return
267"#\n".
268"#    ####    ###     #   #   ###   #####    #####  ####   #####  #####  \n".
269"#    #   #  #   #    ##  #  #   #    #      #      #   #    #      #    \n".
270"#    #   #  #   #    # # #  #   #    #      ###    #   #    #      #    \n".
271"#    #   #  #   #    #  ##  #   #    #      #      #   #    #      #    \n".
272"#    ####    ###     #   #   ###     #      #####  ####   #####    #    \n".
273"#\n".
274"#    DO NOT EDIT! This file will be overwritten by localisation process\n".
275"#\n".
276"#*************************************************************************\n".
277"#\n".
278"# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n".
279"# \n".
280"# Copyright 2000, 2010 Oracle and/or its affiliates.\n".
281"#\n".
282"# OpenOffice.org - a multi-platform office productivity suite\n".
283"#\n".
284"# This file is part of OpenOffice.org.\n".
285"#\n".
286"# OpenOffice.org is free software: you can redistribute it and/or modify\n".
287"# it under the terms of the GNU Lesser General Public License version 3\n".
288"# only, as published by the Free Software Foundation.\n".
289"#\n".
290"# OpenOffice.org is distributed in the hope that it will be useful,\n".
291"# but WITHOUT ANY WARRANTY; without even the implied warranty of\n".
292"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n".
293"# GNU Lesser General Public License version 3 for more details\n".
294"# (a copy is included in the LICENSE file that accompanied this code).\n".
295"#\n".
296"# You should have received a copy of the GNU Lesser General Public License\n".
297"# version 3 along with OpenOffice.org.  If not, see\n".
298"# <http://www.openoffice.org/license.html>\n".
299"# for a copy of the LGPLv3 License.\n".
300"#\n".
301"#*************************************************************************\n";
302}
303######## Check input sdf file and use only the correct part
304sub merge_gsicheck{
305    my $command = '';
306    my ( $TMPHANDLE , $tmpfile ) = File::Temp::tempfile();
307    close ( $TMPHANDLE );
308
309    $command = "$ENV{WRAPCMD} " if( $ENV{WRAPCMD} );
310    $command .= "$ENV{SOLARVER}/$ENV{INPATH}/bin/gsicheck";
311
312    my $errfile = $sdffile.".err";
313    $command .= " -k -c -wcf $tmpfile -wef $errfile -l \"\" $sdffile";
314    #my $rc = system( $command );
315    my $output = `$command`;
316    my $rc = $? << 8;
317    if ( $output ne "" ){
318        print STDOUT "### gsicheck ###\n";
319        print STDOUT "### The file $errfile have been written containing the errors in your sdf file. Those lines will not be merged: ###\n\n";
320        print STDOUT "$output\n";
321        print STDOUT "################\n";
322
323    }else{
324        # Remove the 0 Byte file
325        unlink $errfile;
326    }
327    $sdffile = $tmpfile;
328}
329#########################################################
330# find search function
331sub wanted
332{
333    my $file = $File::Find::name;
334    if( -f $file && $file =~ /.*localize.sdf$/ && !( $file =~ /.*\.svn.*/ ) ) {
335        push   @sdfparticles , $file;
336        if( $bVerbose eq "1" ) { print STDOUT "$file\n"; }
337        else { print ".";  }
338    }
339}
340
341sub add_paths
342{
343    my $langhash_ref            = shift;
344    my $root_dir = $ENV{ SRC_ROOT };
345    my $ooo_l10n_dir = "$root_dir/l10n/source";
346    my $so_l10n_dir  = "$root_dir/l10n_so/source";
347
348    if( -e $ooo_l10n_dir )
349    {
350        foreach my $lang ( keys( %{ $langhash_ref } ) )
351        {
352            my $loc_file = "$ooo_l10n_dir/$lang/localize.sdf";
353            if( -e $loc_file )
354            {
355                push @sdfparticles , "$ooo_l10n_dir/$lang/localize.sdf";
356            }
357            else { print "WARNING: $loc_file not found ....\n"; }
358        }
359    }
360    else { die "ERROR: Can not find directory $ooo_l10n_dir!!!" }
361    if( -e $so_l10n_dir )
362    {
363        foreach my $lang ( keys( %{ $langhash_ref } ) )
364        {
365            my $loc_file = "$so_l10n_dir/$lang/localize.sdf";
366            if( -e $loc_file )
367            {
368                push @sdfparticles , "$ooo_l10n_dir/$lang/localize.sdf";
369            }
370            else { #print "WARNING: $loc_file not found ....\n";
371            }
372        }
373
374    }
375}
376sub collectfiles{
377    print STDOUT "### Localize\n";
378    my $localizehash_ref;
379    my ( $bAll , $bUseLocalize, $langhash_ref , $bHasSourceLanguage , $bFakeEnglish ) = parseLanguages();
380
381    # Enable autoflush on STDOUT
382    # $| = 1;
383    STDOUT->autoflush( 1 );
384
385    my $working_path = getcwd();
386    chdir $ENV{SOURCE_ROOT_DIR}, if defined $ENV{SOURCE_ROOT_DIR};
387    add_paths( $langhash_ref );
388
389    my ( $LOCALIZEPARTICLE , $localizeSDF ) = File::Temp::tempfile();
390    close( $LOCALIZEPARTICLE );
391
392    my ( $ALLPARTICLES_MERGED , $particleSDF_merged )     = File::Temp::tempfile();
393    close( $ALLPARTICLES_MERGED );
394    my ( $LOCALIZE_LOG , $my_localize_log ) = File::Temp::tempfile();
395    close( $LOCALIZE_LOG );
396
397    ## Get the localize en-US extract
398    if( $bAll || $bUseLocalize ){
399        print "### Fetching source language strings\n";
400        my $command = "";
401        my $args    = "";
402
403        if( $ENV{WRAPCMD} ){
404            $command = $ENV{WRAPCMD}.$binpath."localize_sl";
405        }else{
406            $command = $binpath."localize_sl";
407        }
408        print $command;
409        # -e
410        # if ( -x $command ){
411        if( $command ){
412            if( !$bVerbose  ){ $args .= " "; }
413            $args .= " -e -f $localizeSDF -l ";
414            my $bFlag="";
415            if( $bAll ) {$args .= " en-US";}
416            else{
417              my @list;
418              foreach my $isokey ( keys( %{ $langhash_ref } ) ){
419                push @list , $isokey;
420                if( $langhash_ref->{ $isokey } ne "" ){
421                    push @list , $langhash_ref->{ $isokey };
422                }
423              }
424              remove_duplicates( \@list );
425              foreach my $isokey ( @list ){
426                switch :{
427                       ( $isokey=~ /^en-US$/i  )
428                        && do{
429                                if( $bFlag eq "TRUE" ){ $args .= ",en-US"; }
430                                else {
431                                    $args .= "en-US";  $bFlag = "TRUE";
432                                 }
433                              };
434
435                    } #switch
436                } #foreach
437              } # if
438        } # if
439        if ( $bVerbose ) { print STDOUT $command.$args."\n"; }
440
441        my $rc = system( $command.$args );
442
443        if( $rc < 0 ){    print STDERR "ERROR: localize rc = $rc\n"; exit( -1 ); }
444        ( $localizehash_ref )  = read_file( $localizeSDF , $langhash_ref );
445
446    }
447    ## Get sdf particles
448#*****************
449    open ALLPARTICLES_MERGED , "+>> $particleSDF_merged"
450    or die "Can't open $particleSDF_merged";
451
452    ## Fill fackback hash
453    my( $fallbackhashhash_ref ) = fetch_fallback( \@sdfparticles , $localizeSDF ,  $langhash_ref );
454    my %block;
455    my $cur_fallback;
456    if( !$bAll) {
457        foreach my $cur_lang ( keys( %{ $langhash_ref } ) ){
458            #print STDOUT "DBG: G1 cur_lang=$cur_lang\n";
459            $cur_fallback = $langhash_ref->{ $cur_lang };
460            if( $cur_fallback ne "" ){
461                # Insert fallback strings
462                #print STDOUT "DBG: Renaming $cur_fallback to $cur_lang in fallbackhash\n";
463                rename_language(  $fallbackhashhash_ref ,  $cur_fallback , $cur_lang );
464            }
465            foreach my $currentfile ( @sdfparticles ){
466                if ( open MYFILE , "< $currentfile" ) {
467                    while(<MYFILE>){
468                        if( /$sdf_regex/ ){
469                            my $line           = defined $_ ? $_ : '';
470                            my $prj            = defined $3 ? $3 : '';
471                            my $file           = defined $4 ? $4 : '';
472                            my $type           = defined $6 ? $6 : '';
473                            my $gid            = defined $7 ? $7 : '';
474                            my $lid            = defined $8 ? $8 : '';
475                            my $lang           = defined $12 ? $12 : '';
476                            my $plattform      = defined $10 ? $10 : '';
477                            my $helpid         = defined $9 ? $9 : '';
478
479                            chomp( $line );
480
481                            if ( $lang eq $cur_lang ){
482                                # Overwrite fallback strings with collected strings
483                                #if( ( !has_two_sourcelanguages( $cur_lang) && $cur_lang eq "de" ) || $cur_lang ne "en-US" ){
484                                     $fallbackhashhash_ref->{ $cur_lang }{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } =  $line ;
485                                     #}
486
487                            }
488                        }
489                    }
490                }else { print STDERR "WARNING: Can't open file $currentfile"; }
491            }
492
493            foreach my $line ( keys( %{$fallbackhashhash_ref->{ $cur_lang } } )) {
494                if( #$cur_lang ne "de" &&
495                    $cur_lang ne "en-US" ){
496                    print ALLPARTICLES_MERGED ( $fallbackhashhash_ref->{ $cur_lang }{ $line }, "\n" );
497                }
498             }
499        }
500    } else {
501        foreach my $currentfile ( @sdfparticles ){
502            if ( open MYFILE , "< $currentfile" ) {
503                while( <MYFILE> ){
504                    print ALLPARTICLES_MERGED ( $_, "\n" );  # recheck de / en-US !
505                }
506            }
507            else { print STDERR "WARNING: Can't open file $currentfile"; }
508        }
509    }
510    close ALLPARTICLES_MERGED;
511
512    # Hash of array
513    my %output;
514    my @order;
515
516    ## Join both
517    if( $outputfile ){
518        if( open DESTFILE , "+> $outputfile" ){
519            if( !open LOCALIZEPARTICLE ,  "< $localizeSDF" ) { print STDERR "ERROR: Can't open file $localizeSDF\n"; }
520            if( !open ALLPARTICLES_MERGED , "< $particleSDF_merged" ) { print STDERR "ERROR: Can't open file $particleSDF_merged\n"; }
521
522            # Insert localize
523            my $extract_date="";
524            while ( <LOCALIZEPARTICLE> ){
525                if( /$sdf_regex/ ){
526                    my $leftpart       = defined $2 ? $2 : '';
527                    my $lang           = defined $12 ? $12 : '';
528                    my $rightpart      = defined $13 ? $13 : '';
529                    my $timestamp      = defined $18 ? $18 : '';
530
531                    my $prj            = defined $3 ? $3 : '';
532                    my $file           = defined $4 ? $4 : '';
533                    my $type           = defined $6 ? $6 : '';
534                    my $gid            = defined $7 ? $7 : '';
535                    my $lid            = defined $8 ? $8 : '';
536                    #my $lang           = defined $12 ? $12 : '';
537                    my $plattform      = defined $10 ? $10 : '';
538                    my $helpid         = defined $9 ? $9 : '';
539
540
541                    if( $use_default_date )
542                    {
543                        $extract_date = "$default_date\n" ;
544                    }
545                    elsif( $extract_date eq "" ) {
546                        $extract_date = $timestamp ;
547                        $extract_date =~ tr/\r\n//d;
548                        $extract_date .= "\n";
549                    }
550
551                    if( $bAll ){ print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date ; }
552                    else {
553                        foreach my $sLang ( keys( %{ $langhash_ref } ) ){
554                            if( $sLang=~ /all/i )                       {
555                                push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } ,  $leftpart."\t".$lang."\t".$rightpart.$extract_date ;
556                                #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date;
557                            }
558                            #if( $sLang eq "de" && $lang eq "de" )       {
559                            #    push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } ,  $leftpart."\t".$lang."\t".$rightpart.$extract_date ;
560                                #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date;
561                                #}
562                            if( $sLang eq "en-US" && $lang eq "en-US" ) {
563                                push @order , $prj.$gid.$lid.$file.$type.$plattform.$helpid;
564                                if( !$bFakeEnglish ){ push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } ,  $leftpart."\t".$lang."\t".$rightpart.$extract_date ; }
565                                #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date;
566                            }
567
568                        }
569                    }
570                }
571            }
572            # Insert particles
573            while ( <ALLPARTICLES_MERGED> ){
574                if( /$sdf_regex/ ){
575                    my $leftpart       = defined $2 ? $2 : '';
576                    my $prj            = defined $3 ? $3 : '';
577                    my $lang           = defined $12 ? $12 : '';
578                    my $rightpart      = defined $13 ? $13 : '';
579                    my $timestamp      = defined $18 ? $18 : '';
580
581                    #my $prj            = defined $3 ? $3 : '';
582                    my $file           = defined $4 ? $4 : '';
583                    my $type           = defined $6 ? $6 : '';
584                    my $gid            = defined $7 ? $7 : '';
585                    my $lid            = defined $8 ? $8 : '';
586                    #my $lang           = defined $12 ? $12 : '';
587                    my $plattform      = defined $10 ? $10 : '';
588                    my $helpid         = defined $9 ? $9 : '';
589
590
591                    if( $use_default_date )
592                    {
593                        $extract_date = "$default_date\n" ;
594                    }
595                    elsif( $extract_date eq "" )
596                    {
597                        $extract_date = $timestamp;
598                    }
599
600                    if( ! ( $prj =~ /binfilter/i ) ) {
601                        push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } , $leftpart."\t".$lang."\t".$rightpart.$extract_date ;
602                        #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date ;
603                    }
604                 }
605            }
606
607            # Write!
608            foreach my $curkey ( @order ){
609                foreach my $curlist ( $output{ $curkey } ){
610                    foreach my $line ( @{$curlist} ){
611                        print DESTFILE $line;
612                    }
613                }
614            }
615
616        }else { print STDERR "Can't open $outputfile";}
617    }
618    close DESTFILE;
619    close LOCALIZEPARTICLE;
620    close ALLPARTICLES_MERGED;
621    chdir $working_path;
622
623    #print STDOUT "DBG: \$localizeSDF $localizeSDF \$particleSDF_merged $particleSDF_merged\n";
624    unlink $localizeSDF , $particleSDF_merged ,  $my_localize_log;
625
626    #sort_outfile( $outputfile );
627    #remove_obsolete( $outputfile ) , if $bHasSourceLanguage ne "";
628    }
629
630#########################################################
631sub remove_obsolete{
632    my $outfile = shift;
633    my @lines;
634    my $enusleftpart;
635    my @good_lines;
636
637    print STDOUT "### Removing obsolete strings\n";
638
639    # Kick out all strings without en-US reference
640    if ( open ( SORTEDFILE , "< $outfile" ) ){
641        while( <SORTEDFILE> ){
642            if( /$sdf_regex/ ){
643                my $line           = defined $_ ? $_ : '';
644                my $language       = defined $12 ? $12 : '';
645                my $prj            = defined $3 ? $3 : '';
646                my $file           = defined $4 ? $4 : '';
647                my $type           = defined $6 ? $6 : '';
648                my $gid            = defined $7 ? $7 : '';
649                my $lid            = defined $8 ? $8 : '';
650                my $plattform      = defined $10 ? $10 : '';
651                my $helpid         = defined $9 ? $9 : '';
652
653                my $leftpart = $prj.$gid.$lid.$file.$type.$plattform.$helpid;
654
655                if( $language eq "en-US" ){                 # source string found, 1. entry
656                    $enusleftpart = $leftpart;
657                    push @good_lines , $line;
658                }else{
659                    if( !defined $enusleftpart or !defined $leftpart ){
660                        print STDERR "BADLINE: $line\n";
661                        print STDERR "\$enusleftpart = $enusleftpart\n";
662                        print STDERR "\$leftpart = $leftpart\n";
663                    }
664                    if( $enusleftpart eq $leftpart ){   # matching language
665                        push @good_lines , $line;
666                    }
667                    #else{
668                    #    print STDERR "OUT:  \$enusleftpart=$enusleftpart \$leftpart=$leftpart \$line=$line\n";
669                    #}
670                }
671            }
672        }
673        close SORTEDFILE;
674    } else { print STDERR "ERROR: Can't open file $outfile\n";}
675
676    # Write file
677    if ( open ( SORTEDFILE , "> $outfile" ) ){
678        foreach my $newline ( @good_lines ) {
679            print SORTEDFILE $newline;
680        }
681        close SORTEDFILE;
682    } else { print STDERR "ERROR: Can't open file $outfile\n";}
683
684}
685#########################################################
686sub sort_outfile{
687        my $outfile = shift;
688        print STDOUT "### Sorting ... $outfile ...";
689        my @lines;
690        my @sorted_lines;
691
692
693        #if ( open ( SORTEDFILE , "< $outputfile" ) ){
694        if ( open ( SORTEDFILE , "< $outfile" ) ){
695            my $line;
696            while ( <SORTEDFILE> ){
697                $line = $_;
698                if( $line =~ /^[^\#]/ ){
699                    push @lines , $line;
700                }
701            }
702            close SORTEDFILE;
703            @sorted_lines = sort {
704                my $xa_lang          = "";
705                my $xa_left_part    = "";
706                my $xa_right_part    = "";
707                my $xa_timestamp     = "";
708                my $xb_lang          = "";
709                my $xb_left_part    = "";
710                my $xb_right_part    = "";
711                my $xb_timestamp     = "";
712                my $xa               = "";
713                my $xb               = "";
714                my @alist;
715                my @blist;
716
717                if( $a=~ /$sdf_regex/ ){
718                    $xa_left_part       = defined $2 ? $2 : '';
719                    $xa_lang           = defined $12 ? $12 : '';
720                    $xa_right_part     = defined $13 ? $13 : '';
721                    $xa_left_part = remove_last_column( $xa_left_part );
722
723                }
724                if( $b=~ /$sdf_regex/ ){
725                    $xb_left_part       = defined $2 ? $2 : '';
726                    $xb_lang           = defined $12 ? $12 : '';
727                    $xb_right_part     = defined $13 ? $13 : '';
728                    $xb_left_part = remove_last_column( $xb_left_part );
729
730
731                }
732                if( (  $xa_left_part cmp $xb_left_part ) == 0 ){         # Left part equal
733                     if( ( $xa_lang cmp $xb_lang ) == 0 ){               # Lang equal
734                         return ( $xa_right_part cmp $xb_right_part );   # Right part compare
735                    }
736                    elsif( $xa_lang eq "en-US" ) { return -1; }        # en-US wins
737                    elsif( $xb_lang eq "en-US" ) { return 1;  }        # en-US wins
738                    else { return $xa_lang cmp $xb_lang; }             # lang compare
739                }
740                else {
741                    return $xa_left_part cmp $xb_left_part;        # Left part compare
742                }
743            } @lines;
744
745            if ( open ( SORTEDFILE , "> $outfile" ) ){
746                print SORTEDFILE get_license_header();
747                foreach my $newline ( @sorted_lines ) {
748                    print SORTEDFILE $newline;
749                    #print STDOUT $newline;
750                }
751            }
752            close SORTEDFILE;
753        } else { print STDERR "WARNING: Can't open file $outfile\n";}
754	print "done\n";
755
756}
757#########################################################
758sub remove_last_column{
759    my $string                  = shift;
760    my @alist = split ( "\t" , $string );
761    pop @alist;
762    return join( "\t" , @alist );
763}
764
765#########################################################
766sub rename_language{
767    my $fallbackhashhash_ref    = shift;
768    my $cur_fallback            = shift;
769    my $cur_lang                = shift;
770    my $line;
771
772    foreach my $key( keys ( %{ $fallbackhashhash_ref->{ $cur_fallback } } ) ){
773        $line = $fallbackhashhash_ref->{ $cur_fallback }{ $key };
774        if( $line =~ /$sdf_regex/ ){
775            my $leftpart       = defined $2 ? $2 : '';
776            my $lang           = defined $12 ? $12 : '';
777            my $rightpart      = defined $13 ? $13 : '';
778
779            $fallbackhashhash_ref->{ $cur_lang }{ $key } = $leftpart."\t".$cur_lang."\t".$rightpart;
780        }
781    }
782}
783
784############################################################
785sub remove_duplicates{
786    my $list_ref    = shift;
787    my %tmphash;
788    foreach my $key ( @{ $list_ref } ){ $tmphash{ $key } = '' ; }
789    @{$list_ref} = keys( %tmphash );
790}
791
792##############################################################
793sub fetch_fallback{
794    my $sdfparticleslist_ref   = shift;
795    my $localizeSDF            = shift;
796    my $langhash_ref           = shift;
797    my %fallbackhashhash;
798    my $cur_lang;
799    my @langlist;
800
801    foreach my $key ( keys ( %{ $langhash_ref } ) ){
802        $cur_lang = $langhash_ref->{ $key };
803        if ( $cur_lang ne "" ) {
804            push @langlist , $cur_lang;
805        }
806    }
807    remove_duplicates( \@langlist );
808    foreach  $cur_lang ( @langlist ){
809        if( $cur_lang eq "en-US" ){
810            read_fallbacks_from_source( $localizeSDF , $cur_lang , \%fallbackhashhash );
811        }
812    }
813
814    # remove de / en-US
815    my @tmplist;
816    foreach $cur_lang( @langlist ){
817        if(  $cur_lang ne "en-US" ){
818           push @tmplist , $cur_lang;
819
820        }
821    }
822    @langlist = @tmplist;
823    if ( $#langlist +1 ){
824        read_fallbacks_from_particles( $sdfparticleslist_ref , \@langlist , \%fallbackhashhash );
825
826    }
827    return (\%fallbackhashhash);
828}
829
830#########################################################
831sub write_file{
832
833    my $localizeFile = shift;
834    my $index_ref    = shift;
835
836    if( open DESTFILE , "+> $localizeFile" ){
837        foreach my $key( %{ $index_ref } ){
838            print DESTFILE ($index_ref->{ $key }, "\n" );
839        }
840        close DESTFILE;
841    }else {
842      print STDERR "Can't open/create '$localizeFile'";
843    }
844}
845
846#########################################################
847sub read_file{
848
849    my $sdffile         = shift;
850    my $langhash_ref    = shift;
851    my %block           = ();
852
853    open MYFILE , "< $sdffile"
854        or die "Can't open '$sdffile'\n";
855        while( <MYFILE>){
856          if( /$sdf_regex/ ){
857            my $line           = defined $_ ? $_ : '';
858            my $prj            = defined $3 ? $3 : '';
859            my $file           = defined $4 ? $4 : '';
860            my $type           = defined $6 ? $6 : '';
861            my $gid            = defined $7 ? $7 : '';
862            my $lid            = defined $8 ? $8 : '';
863            my $plattform      = defined $10 ? $10 : '';
864            my $lang           = defined $12 ? $12 : '';
865            my $helpid         = defined $9 ? $9 : '';
866
867            foreach my $isolang ( keys ( %{ $langhash_ref } ) ){
868                if( $isolang=~ /$lang/i || $isolang=~ /all/i ) { $block{$prj.$gid.$lid.$file.$type.$plattform.$helpid } =  $line ; }
869            }
870        }
871    }
872    return (\%block);
873}
874
875#########################################################
876sub read_fallbacks_from_particles{
877
878    my $sdfparticleslist_ref    = shift;
879    my $isolanglist_ref         = shift;
880    my $fallbackhashhash_ref    = shift;
881    my $block_ref;
882    foreach my $currentfile ( @{ $sdfparticleslist_ref } ){
883        if ( open MYFILE , "< $currentfile" ) {
884            while(<MYFILE>){
885                if( /$sdf_regex/ ){
886                    my $line           = defined $_ ? $_ : '';
887                    my $prj            = defined $3 ? $3 : '';
888                    my $file           = defined $4 ? $4 : '';
889                    my $type           = defined $6 ? $6 : '';
890                    my $gid            = defined $7 ? $7 : '';
891                    my $lid            = defined $8 ? $8 : '';
892                    my $lang           = defined $12 ? $12 : '';
893                    my $plattform      = defined $10 ? $10 : '';
894                    my $helpid         = defined $9 ? $9 : '';
895
896                    chomp( $line );
897
898                    foreach my $isolang ( @{$isolanglist_ref}  ){
899                        if( $isolang=~ /$lang/i ) {
900                            $fallbackhashhash_ref->{ $isolang }{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } =  $line ;
901                        }
902                    }
903                }
904            }
905       }else { print STDERR "WARNING: Can't open file $currentfile"; }
906    }
907}
908
909#########################################################
910sub read_fallbacks_from_source{
911
912    my $sdffile                 = shift;
913    my $isolang                 = shift;
914    my $fallbackhashhash_ref    = shift;
915    my $block_ref;
916    # read fallback for single file
917    open MYFILE , "< $sdffile"
918        or die "Can't open '$sdffile'\n";
919
920    while( <MYFILE>){
921          if( /$sdf_regex/ ){
922            my $line           = defined $_ ? $_ : '';
923            my $prj            = defined $3 ? $3 : '';
924            my $file           = defined $4 ? $4 : '';
925            my $type           = defined $6 ? $6 : '';
926            my $gid            = defined $7 ? $7 : '';
927            my $lid            = defined $8 ? $8 : '';
928            my $helpid         = defined $9 ? $9 : '';
929            my $lang           = defined $12 ? $12 : '';
930            my $plattform      = defined $10 ? $10 : '';
931
932            chomp( $line );
933            if( $isolang=~ /$lang/i ) { $fallbackhashhash_ref->{ $isolang }{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } =  $line ;
934            }
935        }
936    }
937}
938
939#########################################################
940sub parseLanguages{
941
942    my $bAll;
943    my $bUseLocalize;
944    my $bHasSourceLanguage="";
945    my $bFakeEnglish="";
946    my %langhash;
947    my $iso="";
948    my $fallback="";
949
950    #### -l all
951    if(   $languages=~ /all/ ){
952        $bAll = "TRUE";
953        $bHasSourceLanguage = "TRUE";
954    }
955    ### -l fr=de,de
956    elsif( $languages=~ /.*,.*/ ){
957        my @tmpstr =  split "," , $languages;
958        for my $lang ( @tmpstr ){
959            if( $lang=~ /([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)(=([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*))?/ ){
960                $iso        = $1;
961                $fallback   = $4;
962
963                if( ( $iso && $iso=~ /(en-US)/i )  || ( $fallback && $fallback=~ /(en-US)/i ) ) {
964                    $bUseLocalize = "TRUE";
965                }
966                if( ( $iso && $iso=~ /(en-US)/i ) ) {
967                    $bHasSourceLanguage = "TRUE";
968                }
969             if( $fallback ) { $langhash{ $iso } = $fallback;   }
970             else            { $langhash{ $iso } = "";          }
971            }
972        }
973    }
974    ### -l de
975    else{
976        if( $languages=~ /([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)(=([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*))?/ ){
977            $iso        = $1;
978            $fallback   = $4;
979
980            if( ( $iso && $iso=~ /(en-US)/i )  || ( $fallback && $fallback=~ /(en-US)/i ) ) {
981                $bUseLocalize = "TRUE";
982
983            }
984            if( ( $iso && $iso=~ /(en-US)/i )  ) {
985                $bHasSourceLanguage = "TRUE";
986            }
987
988             if( $fallback ) { $langhash{ $iso } = $fallback;   }
989             else            { $langhash{ $iso } = "";          }
990        }
991    }
992    # HACK en-US always needed!
993    if( !$bHasSourceLanguage ){
994        #$bHasSourceLanguage = "TRUE";
995        $bUseLocalize = "TRUE";
996        $bFakeEnglish = "TRUE";
997        $langhash{ "en-US" } = "";
998    }
999    return ( $bAll ,  $bUseLocalize , \%langhash , $bHasSourceLanguage, $bFakeEnglish);
1000}
1001
1002#########################################################
1003sub parse_options{
1004
1005    my $help;
1006    my $merge;
1007    my $extract;
1008    my $success = GetOptions('f=s' => \$sdffile , 'l=s' => \$languages , 's=s' => \$srcpath ,  'h' => \$help , 'v' => \$bVerbose ,
1009                             'm' => \$merge , 'e' => \$extract , 'x' => \$no_sort , 'd' => \$use_default_date , 'c' => \$create_dirs ,
1010                             'n' => \$no_gsicheck , 'o' => \$force_ooo_module );
1011    $outputfile = $sdffile;
1012
1013    #print STDOUT "DBG: lang = $languages\n";
1014    if( !$srcpath ){
1015        $srcpath = "$ENV{SRC_ROOT}";
1016        if( !$srcpath ){
1017	        print STDERR "No path to the source root found!\n\n";
1018	        usage();
1019            exit(1);
1020        }
1021    }
1022    if( $help ){
1023        usage();
1024        exit(0);
1025    }
1026    if( !$success || $#ARGV > 1 || ( !$sdffile ) ){
1027        usage();
1028        exit(1);
1029    }
1030    if( $merge && $sdffile && ! ( -r $sdffile)){
1031        print STDERR "Can't open file '$sdffile'\n";
1032        exit(1);
1033    }
1034    if( !( $languages=~ /[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*(=[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)?(,[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*(=[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)?)*/ ) ){
1035        print STDERR "Please check the -l iso code\n";
1036        exit(1);
1037    }
1038    if( ( !$merge && !$extract ) || ( $merge && $extract ) ){ usage();exit( -1 );}
1039    if( $extract ){ $mode = "extract"; }
1040    else          { $mode = "merge";   }
1041}
1042#my $multi_localize_files    = ''; h
1043#my $module_to_merge         = ''; i
1044#my $sort_sdf_before         = ''; g
1045
1046#########################################################
1047sub usage{
1048
1049    print STDERR "Usage: localize.pl\n";
1050    print STDERR "Split or collect SDF files\n";
1051    print STDERR "           merge: -m -f <sdffile>    -l l1[=f1][,l2[=f2]][...] [ -s <sourceroot> ] [ -c ]\n";
1052    print STDERR "         extract: -e -f <outputfile> -l <lang> [ -s <sourceroot> ] [-d]\n";
1053    print STDERR "Options:\n";
1054    print STDERR "    -h              help\n";
1055    print STDERR "    -m              Merge mode\n";
1056    print STDERR "    -e              Extract mode\n";
1057    print STDERR "    -f <sdffile>    To split a big SDF file into particles\n";
1058    print STDERR "       <outputfile> To collect and join all particles to one big file\n";
1059    print STDERR "    -s <sourceroot> Path to the modules, if no \$SRC_ROOT is set\n";
1060    print STDERR "    -l ( all | <isocode> | <isocode>=fallback ) comma seperated languages\n";
1061    print STDERR "    -d              Use default date in extracted sdf file\n";
1062    print STDERR "    -c              Create needed directories\n";
1063    print STDERR "    -g              Sort sdf file before mergeing\n";
1064    print STDERR "    -h              File with localize.sdf's\n!";
1065    print STDERR "    -n              No gsicheck\n";
1066    print STDERR "    -i              Module to merge\n";
1067    print STDERR "    -o              force using ooo localization from the l10n module instead of l10n_so; \n";
1068    print STDERR "                    useful if the type can't be detected by the .svn tags; \n";
1069    print STDERR "    -v              Verbose\n";
1070    print STDERR "\nExample:\n";
1071    print STDERR "\nlocalize -e -l en-US,pt-BR=en-US -f my.sdf\n( Extract en-US and pt-BR with en-US fallback )\n";
1072    print STDERR "\nlocalize -m -l cs -f my.sdf\n( Merge cs translation into the sourcecode ) \n";
1073}
1074
1075