xref: /trunk/main/l10ntools/source/localize.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_l10ntools.hxx"
30 
31 #include "srciter.hxx"
32 #include "export.hxx"
33 #include "treeconfig.hxx"
34 #include <string>
35 #include <vector>
36 #include <stdio.h>
37 #include <iostream>
38 #include "tools/errcode.hxx"
39 #include "tools/fsys.hxx"
40 
41 #ifndef L10NTOOLS_FILE_HXX
42 #define L10NTOOLS_FILE_HXX
43 #include <l10ntools/file.hxx>
44 #endif
45 
46 namespace transex3
47 {
48 
49 //
50 // SourceTreeLocalizer
51 //
52 
53 const char *ExeTable[][5] = {
54     { "src", "transex3", "  -UTF8 -e", "negative", "noiso" },
55     { "hrc", "transex3", "  -UTF8 -e", "positive", "noiso" },
56     { "tree", "xhtex", "", "negative", "noiso" },
57     { "xtx", "xtxex", "", "negative", "noiso" },
58     { "ulf", "ulfex", " -e", "negative", "noiso" },
59     { "xrb", "xmlex", "-UTF8 -e", "negative", "iso" },
60     { "xxl", "xmlex", "-UTF8 -e", "negative", "iso" },
61     { "xgf", "xmlex", "-UTF8 -e -t:xgf", "negative", "iso" },
62     { "xcd", "cfgex", "-UTF8 -e", "negative", "iso" },
63     { "xcu", "cfgex", "-UTF8 -e", "negative", "iso" },
64     { "xcs", "cfgex", "-UTF8 -e -f", "negative", "iso" },
65     { "xrm", "xrmex", "-UTF8 -e", "negative", "iso" },
66     { "xhp", "helpex", " -e", "negative", "noiso" },
67     { "properties", "jpropex", " -e", "negative", "noiso" },
68     { "NULL", "NULL", "NULL", "NULL", "NULL" }
69 };
70 
71 const char *NegativeList[] = {
72     "officecfg/data/org.openoffice.Office.Labels.xcd",
73     "officecfg/data/org/openoffice/Office/Labels.xcd",
74     "officecfg/data/org/openoffice/Office/SFX.xcd",
75     "officecfg/data/org/openoffice/Office/Accelerators.xcu",
76     "hidother.src",
77     "NULL"
78 };
79 
80 const char *PositiveList[] = {
81     "svx/inc/globlmn_tmpl.hrc",
82     "sw/source/ui/inc/swmn_tmpl.hrc",
83     "sw/source/ui/inc/swacc_tmpl.hrc",
84     "sw/source/ui/inc/toolbox_tmpl.hrc",
85     "offmgr/inc/offmenu_tmpl.hrc",
86     "offmgr/source/offapp/intro/intro_tmpl.hrc",
87     "dbaccess/source/ui/inc/toolbox_tmpl.hrc",
88     "svx/source/intro/intro_tmpl.hrc",
89     "dbaccess/source/ui/dlg/AutoControls_tmpl.hrc",
90     "svx/source/unodialogs/textconversiondlgs/chinese_direction_tmpl.hrc",
91     "chart2/source/controller/dialogs/res_DataLabel_tmpl.hrc",
92     "chart2/source/controller/dialogs/res_LegendPosition_tmpl.hrc",
93     "chart2/source/controller/dialogs/res_Statistic_tmpl.hrc",
94     "chart2/source/controller/dialogs/res_Titlesx_tmpl.hrc",
95     "chart2/source/controller/dialogs/res_SecondaryAxisCheckBoxes_tmpl.hrc",
96     "chart2/source/controller/menu/MenuItems_tmpl.hrc",
97     "chart2/source/controller/dialogs/res_ErrorBar_tmpl.hrc",
98     "chart2/source/controller/dialogs/res_Trendline_tmpl.hrc",
99     "svx.link/inc/globlmn_tmpl.hrc",
100     "sw.link/source/ui/inc/swmn_tmpl.hrc",
101     "sw.link/source/ui/inc/swacc_tmpl.hrc",
102     "sw.link/source/ui/inc/toolbox_tmpl.hrc",
103     "offmgr.link/inc/offmenu_tmpl.hrc",
104     "offmgr.link/source/offapp/intro/intro_tmpl.hrc",
105     "dbaccess.link/source/ui/inc/toolbox_tmpl.hrc",
106     "svx.link/source/intro/intro_tmpl.hrc",
107     "dbaccess.link/source/ui/dlg/AutoControls_tmpl.hrc",
108     "svx.link/source/unodialogs/textconversiondlgs/chinese_direction_tmpl.hrc",
109     "chart2.link/source/controller/dialogs/res_DataLabel_tmpl.hrc",
110     "chart2.link/source/controller/dialogs/res_LegendPosition_tmpl.hrc",
111     "chart2.link/source/controller/dialogs/res_Statistic_tmpl.hrc",
112     "chart2.link/source/controller/dialogs/res_Titlesx_tmpl.hrc",
113     "chart2.link/source/controller/dialogs/res_SecondaryAxisCheckBoxes_tmpl.hrc",
114     "chart2.link/source/controller/menu/MenuItems_tmpl.hrc",
115     "chart2.link/source/controller/dialogs/res_ErrorBar_tmpl.hrc",
116     "chart2.link/source/controller/dialogs/res_Trendline_tmpl.hrc",
117     "NULL"
118 };
119 
120 
121 const char PRJ_DIR_NAME[] = "prj";
122 const char DLIST_NAME[] = "d.lst";
123 
124 #define LOCALIZE_NONE       0x0000
125 #define LOCALIZE_EXTRACT    0x0001
126 #define LOCALIZE_MERGE      0x0002
127 
128 class SourceTreeLocalizer : public SourceTreeIterator
129 {
130 private:
131     SvFileStream aSDF;
132     sal_uInt16 nMode;
133 
134     ByteString sLanguageRestriction;
135 
136     ByteString sOutputFile;
137 
138     int nFileCnt;
139 
140     const ByteString GetProjectName( sal_Bool bAbs = sal_False );
141     const ByteString GetProjectRootRel();
142 
143 
144     sal_Bool CheckNegativeList( const ByteString &rFileName );
145     sal_Bool CheckPositiveList( const ByteString &rFileName );
146 
147     void WorkOnFile(
148         const ByteString &rFileName,
149         const ByteString &rExecutable,
150         const ByteString &rParameter
151     );
152 
153     void WorkOnFileType(
154         const ByteString &rDirectory,
155         const ByteString &rExtension,
156         const ByteString &rExecutable,
157         const ByteString &rParameter,
158         const ByteString &rCollectMode
159     );
160     void WorkOnDirectory( const ByteString &rDirectory );
161     sal_Bool ExecuteMerge();
162     sal_Bool MergeSingleFile(
163         const ByteString &rPrj,
164         const ByteString &rFile,
165         const ByteString &rSDFFile
166     );
167 
168 public:
169     SourceTreeLocalizer( const ByteString &rRoot, const ByteString &rVersion , bool bLocal , bool skip_links );
170     ~SourceTreeLocalizer();
171 
172     ByteString getSourceLanguages( ByteString sLanguageRestriction , ByteString sCommand );
173 
174     void SetLanguageRestriction( const ByteString& rRestrictions )
175         { sLanguageRestriction = rRestrictions; }
176     int getFileCnt();
177     sal_Bool Extract( const ByteString &rDestinationFile );
178     sal_Bool Merge( const ByteString &rSourceFile , const ByteString &rOutput );
179     int GetFileCnt();
180     virtual void OnExecuteDirectory( const rtl::OUString &rDirectory );
181 };
182 
183 /*****************************************************************************/
184 SourceTreeLocalizer::SourceTreeLocalizer(
185     const ByteString &rRoot, const ByteString &rVersion, bool bLocal_in , bool skip_links )
186 /*****************************************************************************/
187                 : SourceTreeIterator( rRoot, rVersion , bLocal_in ),
188                 nMode( LOCALIZE_NONE ),
189                 nFileCnt( 0 )
190 {
191         bSkipLinks  = skip_links ;
192 }
193 
194 /*****************************************************************************/
195 SourceTreeLocalizer::~SourceTreeLocalizer()
196 /*****************************************************************************/
197 {
198 }
199 
200 /*****************************************************************************/
201 const ByteString SourceTreeLocalizer::GetProjectName( sal_Bool bAbs )
202 /*****************************************************************************/
203 {
204     sal_Bool bFound = sal_False;
205     DirEntry aCur;
206     aCur.ToAbs();
207 
208     for ( ; ! bFound && aCur.Level() > 1; aCur.CutName() )
209     {
210         DirEntry aTest = aCur + DirEntry(PRJ_DIR_NAME) + DirEntry(DLIST_NAME);
211         if ( aTest.Exists() )
212         {
213             if ( bAbs )
214                 return ByteString( aCur.GetFull(), RTL_TEXTENCODING_ASCII_US );
215             else
216                 return ByteString( aCur.GetName(), RTL_TEXTENCODING_ASCII_US );
217         }
218     }
219 
220     return "";
221 }
222 /*****************************************************************************/
223 int SourceTreeLocalizer::GetFileCnt(){
224 /*****************************************************************************/
225     return nFileCnt;
226 }
227 
228 /*****************************************************************************/
229 const ByteString SourceTreeLocalizer::GetProjectRootRel()
230 /*****************************************************************************/
231 {
232     ByteString sProjectRoot( GetProjectName( sal_True ));
233     DirEntry aCur;
234     aCur.ToAbs();
235     ByteString sCur( aCur.GetFull(), RTL_TEXTENCODING_ASCII_US );
236 
237     if( sCur.SearchAndReplace( sProjectRoot, "" ) == STRING_NOTFOUND )
238         return "";
239 
240     ByteString sDelimiter(
241         DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US );
242 
243     sCur.SearchAndReplaceAll( sDelimiter, "/" );
244     sCur.EraseLeadingChars( '/' );
245     sal_uLong nCount = sCur.GetTokenCount( '/' );
246 
247     ByteString sProjectRootRel;
248     for ( sal_uLong i = 0; i < nCount; i++ ) {
249         if ( sProjectRootRel.Len())
250             sProjectRootRel += sDelimiter;
251         sProjectRootRel += "..";
252     }
253     if ( sProjectRootRel.Len())
254         return sProjectRootRel;
255 
256     return ".";
257 }
258 
259 bool skipProject( ByteString sPrj )
260 {
261     static const ByteString READLICENSE( "readlicense" );
262     return sPrj.EqualsIgnoreCaseAscii( READLICENSE );
263 }
264 
265 /*****************************************************************************/
266 void SourceTreeLocalizer::WorkOnFile(
267     const ByteString &rFileName, const ByteString &rExecutable,
268     const ByteString &rParameter )
269 /*****************************************************************************/
270 {
271         String sFull( rFileName, RTL_TEXTENCODING_ASCII_US );
272         DirEntry aEntry( sFull );
273         ByteString sFileName( aEntry.GetName(), RTL_TEXTENCODING_ASCII_US );
274 
275         // set current working directory
276         DirEntry aPath( aEntry.GetPath());
277         DirEntry aOldCWD;
278         aPath.SetCWD();
279 
280         ByteString sPrj( GetProjectName());
281         if ( sPrj.Len() && !skipProject( sPrj ) )
282         {
283             ByteString sRoot( GetProjectRootRel());
284 
285             DirEntry aTemp( Export::GetTempFile());
286             ByteString sTempFile( aTemp.GetFull(), RTL_TEXTENCODING_ASCII_US );
287 
288             ByteString sDel;
289 #if defined(WNT) || defined(OS2)
290             sDel=ByteString("\\");
291 #else
292             sDel=ByteString("/");
293 #endif
294             ByteString sPath1( Export::GetEnv("SOLARVER") );
295             ByteString sPath2( Export::GetEnv("INPATH") );
296             ByteString sPath3( "bin" );
297             ByteString sPath4( Export::GetEnv("UPDMINOREXT") );
298             ByteString sExecutable( sPath1 );
299             sExecutable += sDel ;
300             sExecutable += sPath2 ;
301             sExecutable += sDel;
302             sExecutable += sPath3 ;
303             sExecutable += sPath4 ;
304             sExecutable += sDel ;
305             sExecutable += rExecutable ;
306 
307 
308         ByteString sCommand( sExecutable );
309         sCommand += " ";
310         sCommand += rParameter;
311         sCommand += " -p ";
312         sCommand += sPrj;
313         sCommand += " -r ";
314         sCommand += sRoot;
315         sCommand += " -i ";
316         sCommand += sFileName;
317         sCommand += " -o ";
318         sCommand += sTempFile;
319         if ( sLanguageRestriction.Len()) {
320             sCommand += " -l ";
321         sCommand += getSourceLanguages( sLanguageRestriction , sCommand );
322         }
323 
324             //printf("DBG: %s\n",sCommand.GetBuffer());
325             if (system(sCommand.GetBuffer()) == -1)
326                 fprintf(stderr, "%s failed\n", sCommand.GetBuffer());
327             nFileCnt++;
328             printf(".");
329             fflush( stdout );
330 
331             SvFileStream aSDFIn( aTemp.GetFull(), STREAM_READ );
332             ByteString sLine;
333             while ( aSDFIn.IsOpen() && !aSDFIn.IsEof()) {
334                 aSDFIn.ReadLine( sLine );
335                 if ( sLine.Len()) {
336                     aSDF.WriteLine( sLine );
337                 }
338             }
339             aSDFIn.Close();
340 
341             aTemp.Kill();
342 
343         }
344         // reset current working directory
345         aOldCWD.SetCWD();
346 }
347 
348 ByteString SourceTreeLocalizer::getSourceLanguages( ByteString sLanguageRestriction_inout , ByteString sCommand )
349 {
350     // Source languages in helpcontent2 and macromigration en-US only!
351     if( sCommand.Search("helpex") != STRING_NOTFOUND ) {
352         sLanguageRestriction_inout.Assign( ByteString("en-US") );
353     }
354     else if( sCommand.Search("xmlex") != STRING_NOTFOUND ){
355         sLanguageRestriction_inout.Assign( ByteString("en-US") );
356     }
357     return sLanguageRestriction_inout;
358 }
359 
360 /*****************************************************************************/
361 sal_Bool SourceTreeLocalizer::CheckNegativeList( const ByteString &rFileName )
362 /*****************************************************************************/
363 {
364     sal_uLong nIndex = 0;
365     sal_Bool bReturn  = sal_True;
366 
367     ByteString sDelimiter(
368         DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US );
369 
370     ByteString sFileName( rFileName );
371     sFileName.ToLowerAscii();
372 
373     ByteString sNegative( NegativeList[ nIndex ] );
374     while( !sNegative.Equals( "NULL" ) && bReturn ) {
375         sNegative.SearchAndReplaceAll( "\\", sDelimiter );
376         sNegative.SearchAndReplaceAll( "/", sDelimiter );
377         sNegative.ToLowerAscii();
378 
379         if( sFileName.Search( sNegative ) == sFileName.Len() - sNegative.Len())
380             bReturn = sal_False;
381 
382         nIndex++;
383         sNegative = NegativeList[ nIndex ];
384     }
385 
386     return bReturn;
387 }
388 
389 /*****************************************************************************/
390 sal_Bool SourceTreeLocalizer::CheckPositiveList( const ByteString &rFileName )
391 /*****************************************************************************/
392 {
393     sal_uLong nIndex = 0;
394     sal_Bool bReturn  = sal_False;
395 
396     ByteString sDelimiter(
397         DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US );
398 
399     ByteString sFileName( rFileName );
400     sFileName.ToLowerAscii();
401 
402     ByteString sNegative( PositiveList[ nIndex ] );
403     while( !sNegative.Equals( "NULL" ) && !bReturn ) {
404         sNegative.SearchAndReplaceAll( "\\", sDelimiter );
405         sNegative.SearchAndReplaceAll( "/", sDelimiter );
406         sNegative.ToLowerAscii();
407 
408         if( sFileName.Search( sNegative ) == sFileName.Len() - sNegative.Len())
409             bReturn = sal_True;
410 
411         nIndex++;
412         sNegative = PositiveList[ nIndex ];
413     }
414 
415     return bReturn;
416 }
417 
418 /*****************************************************************************/
419 void SourceTreeLocalizer::WorkOnFileType(
420     const ByteString &rDirectory, const ByteString &rExtension,
421     const ByteString &rExecutable, const ByteString &rParameter,
422     const ByteString &rCollectMode
423 )
424 /*****************************************************************************/
425 {
426     String sWild( rDirectory, RTL_TEXTENCODING_ASCII_US );
427     sWild += DirEntry::GetAccessDelimiter();
428     sWild += String::CreateFromAscii( "*." );
429     sWild += String( rExtension, RTL_TEXTENCODING_ASCII_US );
430 
431     DirEntry aEntry( sWild );
432     Dir aDir( sWild, FSYS_KIND_FILE );
433 
434     for ( sal_uInt16 i = 0; i < aDir.Count(); i++ ) {
435         DirEntry aFile( aDir[ i ] );
436         ByteString sFile( aFile.GetFull(), RTL_TEXTENCODING_ASCII_US );
437 
438         sal_Bool bAllowed = sal_True;
439 
440         if ( rCollectMode.Equals( "negative" ))
441             bAllowed = CheckNegativeList( sFile );
442         else if ( rCollectMode.Equals( "positive" ))
443             bAllowed = CheckPositiveList( sFile );
444 
445         if ( bAllowed )
446             WorkOnFile( sFile, rExecutable, rParameter );
447     }
448 }
449 
450 /*****************************************************************************/
451 void SourceTreeLocalizer::WorkOnDirectory( const ByteString &rDirectory )
452 /*****************************************************************************/
453 {
454     //printf("Working on Directory %s\n",rDirectory.GetBuffer());
455     sal_uLong nIndex = 0;
456     ByteString sExtension( ExeTable[ nIndex ][ 0 ] );
457     ByteString sExecutable( ExeTable[ nIndex ][ 1 ] );
458     ByteString sParameter( ExeTable[ nIndex ][ 2 ] );
459     ByteString sCollectMode( ExeTable[ nIndex ][ 3 ] );
460 
461     while( !sExtension.Equals( "NULL" )) {
462         WorkOnFileType(
463             rDirectory,
464             sExtension,
465             sExecutable,
466             sParameter,
467             sCollectMode
468         );
469 
470         nIndex++;
471 
472         sExtension = ExeTable[ nIndex ][ 0 ];
473         sExecutable = ExeTable[ nIndex ][ 1 ];
474         sParameter = ExeTable[ nIndex ][ 2 ];
475         sCollectMode = ExeTable[ nIndex ][ 3 ];
476     }
477 }
478 
479 void SourceTreeLocalizer::OnExecuteDirectory( const rtl::OUString &aDirectory )
480 {
481     ByteString rDirectory( rtl::OUStringToOString( aDirectory , RTL_TEXTENCODING_UTF8 , aDirectory.getLength() ) ) ;
482     if ( nMode == LOCALIZE_NONE ){
483     }
484     else
485         WorkOnDirectory( rDirectory );
486 }
487 
488 /*****************************************************************************/
489 sal_Bool SourceTreeLocalizer::Extract( const ByteString &rDestinationFile )
490 /*****************************************************************************/
491 {
492     nMode = LOCALIZE_EXTRACT;
493 
494     aSDF.Open( String( rDestinationFile , RTL_TEXTENCODING_ASCII_US ) , STREAM_STD_WRITE );
495     aSDF.SetLineDelimiter( LINEEND_CRLF );
496 
497     sal_Bool bReturn = aSDF.IsOpen();
498     if ( bReturn ) {
499         aSDF.Seek( STREAM_SEEK_TO_END );
500         bReturn = StartExecute();
501         aSDF.Close();
502     }
503     else{
504         printf("ERROR: Can't create file %s\n", rDestinationFile.GetBuffer() );
505     }
506     nMode = LOCALIZE_NONE;
507     aSDF.Close();
508     return bReturn;
509 }
510 
511 /*****************************************************************************/
512 sal_Bool SourceTreeLocalizer::MergeSingleFile(
513     const ByteString &rPrj,
514     const ByteString &rFile,
515     const ByteString &rSDFFile
516 )
517 /*****************************************************************************/
518 {
519     //printf("MergeSingleFile(%s,%s,%s)",rPrj.GetBuffer(),rFile.GetBuffer(),rSDFFile.GetBuffer());
520     if ( !rFile.Len())
521         return sal_True;
522 
523     ByteString sRoot( Export::GetEnv( "SRC_ROOT" ));
524     DirEntry aEntry( String( sRoot, RTL_TEXTENCODING_ASCII_US ));
525     aEntry += DirEntry( String( rPrj, RTL_TEXTENCODING_ASCII_US ));
526 
527     ByteString sDelimiter(
528         DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US );
529 
530     ByteString sCur( rFile );
531     sCur.SearchAndReplaceAll( "\\", sDelimiter );
532     sCur.SearchAndReplaceAll( "/", sDelimiter );
533 
534     aEntry += DirEntry( String( sCur, RTL_TEXTENCODING_ASCII_US ));
535     ByteString sFile( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
536 
537     ByteString sBCur( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
538 
539     sal_uLong nIndex = 0;
540     ByteString sExtension( aEntry.GetExtension(), RTL_TEXTENCODING_ASCII_US );
541     ByteString sCandidate( ExeTable[ nIndex ][ 0 ] );
542 
543     while( !sCandidate.Equals ("NULL") && !sCandidate.Equals(sExtension) )
544         sCandidate = ExeTable[ ++nIndex ][ 0 ];
545 
546     if ( !sCandidate.Equals( "NULL" ) ) {
547         if( !aEntry.Exists()) {
548             DirEntryKind theDir=FSYS_KIND_FILE;
549             Dir myDir( aEntry.GetPath(), theDir);
550             DirEntry current;
551             sal_Bool found=sal_False;
552             for( sal_uInt16 x=0; x < myDir.Count() && !found;){
553                 current=myDir[x++];
554                 StringCompare result=current.GetName().CompareIgnoreCaseToAscii( aEntry.GetName() );
555                 if( result==COMPARE_EQUAL ){
556                     fprintf(stderr,"WARNING: %s not found\n", ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US).GetBuffer() );
557                     fprintf(stderr,"but use  %s instead \n" , ByteString(current.GetFull(), RTL_TEXTENCODING_ASCII_US).GetBuffer() );
558                     aEntry=current;
559                     found=sal_True;
560                 }
561             }
562             if(!found)  return sal_True;
563 
564         }
565 
566         DirEntry aOut( Export::GetTempFile() );
567         ByteString sOutput;
568         if( sOutputFile.Len() == 0 )
569             sOutput = ByteString ( aOut.GetFull(), RTL_TEXTENCODING_ASCII_US );
570         else
571             sOutput = sOutputFile;
572         ByteString sCommand( ExeTable[ nIndex ][ 1 ] );
573         sCommand += " -i ";
574         sCommand += ByteString( aEntry.GetName(), RTL_TEXTENCODING_ASCII_US );
575         sCommand += " -m ";
576         sCommand += rSDFFile;
577         sCommand += " -o ";
578         sCommand += sOutput;
579         sCommand += " ";
580         sCommand += ByteString( ExeTable[ nIndex ][ 2 ] );
581         if ( sLanguageRestriction.Len()) {
582             sCommand += " -l ";
583             sCommand += sLanguageRestriction;
584         }
585 
586         DirEntry aPath( aEntry.GetPath());
587         DirEntry aOldCWD;
588         aPath.SetCWD();
589 
590         if (system(sCommand.GetBuffer()) == -1)
591             fprintf(stderr, "%s failed\n", sCommand.GetBuffer());
592         nFileCnt++;
593         printf(".");
594         SvFileStream aInStream( aOut.GetFull(), STREAM_READ );
595         if ( !aInStream.IsOpen()) {
596             fprintf( stderr,
597                 "ERROR: Unable to open file %s for reading!\n",
598                 sOutput.GetBuffer());
599         }
600         else {
601             FileStat::SetReadOnlyFlag( aEntry, sal_False );
602             String myStr2(aEntry.GetFull());
603             String aTemp22 = String::CreateFromAscii("_tmp");
604             myStr2.Append(aTemp22);
605 
606             ByteString test(myStr2,RTL_TEXTENCODING_ASCII_US);
607             SvFileStream aOutStream( myStr2, STREAM_STD_WRITE | STREAM_TRUNC );
608             if ( !aOutStream.IsOpen()) {
609                 ByteString test2(myStr2,RTL_TEXTENCODING_ASCII_US);
610                 fprintf( stderr,"ERROR: Unable to open file %s for modification!\n", test2.GetBuffer());
611                 aInStream.Close();
612             }
613 
614             else {
615                 ByteString sLine;
616                 aOutStream.SetLineDelimiter( LINEEND_LF );
617 
618                 aInStream.ReadLine( sLine );
619                 while ( !aInStream.IsEof()) {
620                     aOutStream.WriteLine( sLine );
621                     aInStream.ReadLine( sLine );
622                 }
623                 aInStream.Close();
624                 aOutStream.Close();
625 
626 
627                     DirEntry myTempFile(ByteString(myStr2,RTL_TEXTENCODING_ASCII_US));      // xxx_tmp ->
628                     DirEntry myFile(ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US));// xxx
629 
630                     DirEntry oldFile(ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US));
631 
632                     if(oldFile.Kill()==ERRCODE_NONE){
633                         if(myTempFile.MoveTo(myFile)!=ERRCODE_NONE){
634                             fprintf( stderr, "ERROR: Can't rename file %s\n",ByteString(myStr2,RTL_TEXTENCODING_ASCII_US).GetBuffer());
635                         }
636                     }
637                     else{
638                         fprintf( stderr, "ERROR: Can't remove file %s\n",ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US).GetBuffer());
639                     }
640                 } // else
641 
642                 aOldCWD.SetCWD();
643                 aOut.Kill();
644             }   // else
645         }
646     return sal_True;
647 }
648 /*****************************************************************************/
649 sal_Bool SourceTreeLocalizer::ExecuteMerge( )
650 /*****************************************************************************/
651 {
652     DirEntry aEntry( Export::GetTempFile());
653     sal_Bool bReturn = sal_True;
654     bool bMerged = false;
655 
656     ByteString sFileName;
657     ByteString sCurFile;
658     ByteString sLine;
659     ByteString sFileKey;
660 
661     SvFileStream aFile;
662 
663     ByteString sOutputFileName = sOutputFile;
664     ByteString sInpath(".");
665     sInpath += Export::GetEnv("INPATH");
666     ByteString sBlank("");
667 
668     sOutputFileName.SearchAndReplaceAll( sInpath , sBlank );
669 
670     String sDel = DirEntry::GetAccessDelimiter();
671     ByteString sBDel( sDel.GetBuffer() , sDel.Len() , RTL_TEXTENCODING_UTF8 );
672     if( bLocal ){
673         xub_StrLen nPos = sOutputFileName.SearchBackward( sBDel.GetChar(0) );
674         sOutputFileName = sOutputFileName.Copy( nPos+1 , sOutputFileName.Len()-nPos-1 );
675     }
676     ByteStringBoolHashMap aFileHM;
677     // Read all possible files
678     while ( !aSDF.IsEof()) {
679         aSDF.ReadLine( sLine );
680         sFileName = sLine.GetToken( 0, '\t' );
681         sFileName += "#";
682         sFileName += sLine.GetToken( 1, '\t' );
683         aFileHM[sFileName]=true;
684     }
685 
686     for( ByteStringBoolHashMap::iterator iter = aFileHM.begin(); iter != aFileHM.end(); ++iter ){
687         sFileKey = iter->first;
688         aSDF.Seek( 0 );
689         aFile.Open( aEntry.GetFull(), STREAM_STD_WRITE |STREAM_TRUNC );
690 
691         while ( !aSDF.IsEof()) {
692             aSDF.ReadLine( sLine );
693             sFileName = sLine.GetToken( 0, '\t' );
694             sFileName += "#";
695             sFileName += sLine.GetToken( 1, '\t' );
696             if( sFileName.Len() && ( sFileName.CompareTo(sFileKey) == COMPARE_EQUAL ) ){
697                 if ( aFile.IsOpen() && sLine.Len())
698                     aFile.WriteLine( sLine );
699             }
700         }
701         if ( aFile.IsOpen())
702             aFile.Close();
703 
704         ByteString sPrj( sFileKey.GetToken( 0, '#' ));
705         ByteString sFile( sFileKey.GetToken( 1, '#' ));
706         ByteString sSDFFile( aFile.GetFileName(), RTL_TEXTENCODING_ASCII_US );
707 
708         //printf("localize test sPrj = %s , sFile = %s , sSDFFile = %s sOutputFileName = %s\n",sPrj.GetBuffer(), sFile.GetBuffer() , sSDFFile.GetBuffer() , sOutputFileName.GetBuffer() );
709 
710         // Test
711         bLocal = true;
712         // Test
713 
714         if( bLocal ){
715             sal_uInt16 nPos = sFile.SearchBackward( '\\' );
716             ByteString sTmp = sFile.Copy( nPos+1 , sFile.Len()-nPos-1 );
717             //printf("'%s'='%s'\n",sTmp.GetBuffer(), sOutputFileName.GetBuffer());
718             if( sTmp.CompareTo(sOutputFileName) == COMPARE_EQUAL ){
719                     bMerged = true;
720                     if ( !MergeSingleFile( sPrj, sFile, sSDFFile ))
721                         bReturn = sal_False;
722             }else{
723                 bMerged = true;
724                 //printf("MergeSingleFile('%s','%s','%s')\n",sPrj.GetBuffer(),sFile.GetBuffer(),sSDFFile.GetBuffer());
725                 if ( !MergeSingleFile( sPrj, sFile, sSDFFile ))
726                     bReturn = sal_False;
727             }
728         }
729     }
730     aEntry.Kill();
731     // If Outputfile not included in the SDF file copy it without merge
732 
733     if( bLocal && !bMerged ){
734         DirEntry aSourceFile( sOutputFileName.GetBuffer() );
735         FSysError aErr = aSourceFile.CopyTo( DirEntry ( sOutputFile.GetBuffer() ) , FSYS_ACTION_COPYFILE );
736         if( aErr != FSYS_ERR_OK ){
737             printf("ERROR: Can't copy file '%s' to '%s' %d\n",sOutputFileName.GetBuffer(),sOutputFile.GetBuffer(),sal::static_int_cast<int>(aErr));
738         }
739     }
740     return bReturn;
741 
742 }
743 
744 /*****************************************************************************/
745 sal_Bool SourceTreeLocalizer::Merge( const ByteString &rSourceFile , const ByteString &rOutput )
746 /*****************************************************************************/
747 {
748     sOutputFile = rOutput;
749     nMode = LOCALIZE_MERGE;
750     aSDF.Open( String( rSourceFile, RTL_TEXTENCODING_ASCII_US ),
751         STREAM_STD_READ );
752 
753     sal_Bool bReturn = aSDF.IsOpen();
754     if ( bReturn ) {
755         bReturn = ExecuteMerge();
756 //      aSDF.Close();
757     }
758     aSDF.Close();
759     nMode = LOCALIZE_NONE;
760     return bReturn;
761 }
762 
763 }
764 using namespace transex3;
765 
766 #define STATE_NONE      0x0000
767 #define STATE_EXPORT    0x0001
768 #define STATE_MERGE     0x0002
769 #define STATE_ISOCODE   0x0003
770 #define STATE_LANGUAGES 0x0004
771 #define STATE_FILENAME  0x0005
772 #define STATE_OUTPUT    0x0006
773 
774 /*****************************************************************************/
775 void Help()
776 /*****************************************************************************/
777 {
778     fprintf( stdout,
779         "localize (c)2001 by Sun Microsystems\n"
780         "====================================\n" );
781     fprintf( stdout,
782         "As part of the L10N framework, localize extracts and merges translations\n"
783         "out of and into the whole source tree.\n\n"
784         "Syntax: localize -e -l en-US -f FileName \n"
785         "Parameter:\n"
786         "\t-e: Extract mode\n"
787         "\tFileName: Output file when extract mode, input file when merge mode\n"
788         "\tl1...ln: supported languages (\"all\" for all languages).\n"
789     );
790 
791     fprintf( stdout,
792         "Valid language codes for l1...ln and f1...fn are:\n" );
793     fprintf( stdout,
794         "\nExample 1:\n"
795         "==========\n"
796         "localize -e -l en-US -f MyFile\n\n"
797         "All strings will be extracted for language de and language en-US.\n"
798     );
799 }
800 
801 /*****************************************************************************/
802 int Error()
803 /*****************************************************************************/
804 {
805     Help();
806     return 1;
807 }
808 
809 /*****************************************************************************/
810 sal_Bool CheckLanguages( ByteString &rLanguages )
811 /*****************************************************************************/
812 {
813     ByteString sTmp( rLanguages );
814     return true;
815 }
816 
817 /*****************************************************************************/
818 #if defined(UNX) || defined(OS2)
819 int main( int argc, char *argv[] )
820 #else
821 int _cdecl main( int argc, char *argv[] )
822 #endif
823 /*****************************************************************************/
824 {
825     String sTempBase( String::CreateFromAscii( "loc" ));
826     DirEntry::SetTempNameBase( sTempBase );
827     sal_uInt16 nState   = STATE_NONE;
828 
829     sal_Bool bExport    = sal_False;
830     sal_Bool bMerge     = sal_False;
831     bool bSkipLinks = false;
832 
833     ByteString sLanguages;
834     ByteString sFileName;
835     ByteString sOutput;
836 
837     bExport = sal_True;
838 
839     for( int i = 1; i < argc; i++ ) {
840         ByteString sSwitch( argv[ i ] );
841         sSwitch.ToUpperAscii();
842 
843         if ( sSwitch.Equals( "-E" )) {
844             nState = STATE_EXPORT;
845             if ( bMerge )
846                 return Error();
847             bExport = sal_True;
848         }
849         else if ( sSwitch.Equals( "-I" ) )
850             nState = STATE_ISOCODE;
851         else if ( sSwitch.Equals( "-L" ) )
852             nState = STATE_LANGUAGES;
853         else if ( sSwitch.Equals( "-F" ) )
854             nState = STATE_FILENAME;
855         else if ( ByteString( argv[ i ]).ToUpperAscii().Equals( "-O" ) )
856             nState = STATE_OUTPUT;
857         else {
858             switch ( nState ) {
859                 case STATE_NONE:
860                     return Error();
861                 case STATE_OUTPUT:
862                     if ( sOutput.Len())
863                         return Error();
864                     sOutput = ByteString( argv[ i ] );
865                     nState = STATE_NONE;
866                 break;
867                 case STATE_LANGUAGES:
868                     if ( sLanguages.Len())
869                         return Error();
870                     sLanguages = ByteString( argv[ i ] );
871                     nState = STATE_NONE;
872                 break;
873                 case STATE_FILENAME:
874                     if ( sFileName.Len())
875                         return Error();
876                     sFileName = ByteString( argv[ i ] );
877                     nState = STATE_NONE;
878                 break;
879                 default:
880                     return Error();
881             }
882         }
883     }
884     if ( !bMerge && !bExport ) {
885         Help();
886         return 1;
887     }
888 
889     ByteString sSolarVer( Export::GetEnv( "WORK_STAMP" ));
890     ByteString sVersion( Export::GetEnv( "WORK_STAMP" ));
891 
892     if ( !sSolarVer.Len() || !sVersion.Len()) {
893         fprintf( stderr, "ERROR: No environment set!\n" );
894         return 1;
895     }
896 
897     if ( !CheckLanguages( sLanguages ))
898         return 2;
899 
900     if ( !sFileName.Len()) {
901         fprintf( stderr, "ERROR: No filename given\n" );
902         return 3;
903     }
904 
905     DirEntry aEntry( String( sFileName , RTL_TEXTENCODING_ASCII_US ));
906     aEntry.ToAbs();
907     String sFullEntry = aEntry.GetFull();
908     ByteString sFileABS( aEntry.GetFull(), gsl_getSystemTextEncoding());
909     //printf("B %s\nA %s\n",rDestinationFile.GetBuffer(), sFile.GetBuffer());
910     sFileName = sFileABS;
911 
912     Treeconfig treeconfig;
913     vector<string> repos;
914     bool hasPwd = treeconfig.getActiveRepositories( repos );
915     if( hasPwd ) cout << "Found special path!\n";
916 
917     string minor_ext;
918     bool has_minor_ext;
919 
920     if( Export::GetEnv("UPDMINOREXT") != NULL )
921     {
922         minor_ext     = string( Export::GetEnv("UPDMINOREXT") );
923         has_minor_ext = minor_ext.size();
924     }
925     else
926         has_minor_ext = false;
927 
928     // localize through all repositories
929     for( vector<string>::iterator iter = repos.begin(); iter != repos.end() ; ++iter )
930     {
931         string curRepository;
932         if( has_minor_ext )
933             curRepository = string( Export::GetEnv("SOURCE_ROOT_DIR") ) + "/" + *iter + minor_ext;
934         else
935             curRepository = string( Export::GetEnv("SOURCE_ROOT_DIR") ) + "/" + *iter;
936         cout << "Localizing repository " << curRepository << "\n";
937         SourceTreeLocalizer aIter( ByteString( curRepository.c_str() ) , sVersion , (sOutput.Len() > 0) , bSkipLinks );
938         aIter.SetLanguageRestriction( sLanguages );
939         if ( bExport ){
940             fflush( stdout );
941             if( *iter == "ooo" )
942                 aIter.Extract( sFileName );
943             else
944             {
945                 ByteString sFileNameWithExt( sFileName );
946                 sFileNameWithExt += ByteString( "." );
947                 sFileNameWithExt += ByteString( (*iter).c_str() );
948                 aIter.Extract( sFileNameWithExt );
949             }
950             printf("\n%d files found!\n",aIter.GetFileCnt());
951         }
952     }
953     if( hasPwd )
954     {
955         string pwd;
956         Export::getCurrentDir( pwd );
957         cout << "Localizing repository " << pwd << "\n";
958         SourceTreeLocalizer aIter( ByteString( pwd.c_str() ) , sVersion , (sOutput.Len() > 0) , bSkipLinks );
959         aIter.SetLanguageRestriction( sLanguages );
960         if ( bExport ){
961             fflush( stdout );
962             aIter.Extract( sFileName );
963             printf("\n%d files found!\n",aIter.GetFileCnt());
964         }
965 
966     }
967 
968     return 0;
969 }
970 
971