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