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