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 #ifndef _EXPORT_HXX 29 #define _EXPORT_HXX 30 31 #ifndef L10NTOOLS_DIRECTORY_HXX 32 #define L10NTOOLS_DIRECTORY_HXX 33 #include <l10ntools/directory.hxx> 34 #endif 35 36 37 // #define MERGE_SOURCE_LANGUAGES <- To merge en-US and de resource 38 39 #include <tools/string.hxx> 40 #include <tools/list.hxx> 41 #include <tools/stream.hxx> 42 #include <tools/fsys.hxx> 43 #include <osl/file.hxx> 44 #include <osl/file.h> 45 46 #include <hash_map> /* std::hashmap*/ 47 #include <iterator> /* std::iterator*/ 48 #include <set> /* std::set*/ 49 #include <vector> /* std::vector*/ 50 #include <queue> 51 #include <string> 52 53 #include <unistd.h> 54 #ifdef WNT 55 #include <direct.h> 56 #endif 57 58 #define NO_TRANSLATE_ISO "x-no-translate" 59 60 #define JAPANESE_ISO "ja" 61 62 63 struct eqstr{ 64 sal_Bool operator()(const char* s1, const char* s2) const{ 65 return strcmp(s1,s2)==0; 66 } 67 }; 68 69 struct equalByteString{ 70 bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { 71 return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL; 72 } 73 }; 74 struct lessByteString{ 75 bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { 76 return rKey1.CompareTo( rKey2 )==COMPARE_LESS; 77 } 78 }; 79 80 struct hashByteString{ 81 size_t operator()( const ByteString& rName ) const{ 82 std::hash< const char* > myHash; 83 return myHash( rName.GetBuffer() ); 84 } 85 }; 86 87 class PFormEntrys; 88 class MergeData; 89 typedef std::set<ByteString , lessByteString > ByteStringSet; 90 91 typedef std::hash_map<ByteString , ByteString , hashByteString,equalByteString> 92 ByteStringHashMap; 93 94 typedef std::hash_map<ByteString , bool , hashByteString,equalByteString> 95 ByteStringBoolHashMap; 96 97 typedef std::hash_map<ByteString , PFormEntrys* , hashByteString,equalByteString> 98 PFormEntrysHashMap; 99 100 typedef std::hash_map<ByteString , MergeData* , hashByteString,equalByteString> 101 MergeDataHashMap; 102 103 #define SOURCE_LANGUAGE ByteString("en-US") 104 #define LIST_REFID "LIST_REFID" 105 106 typedef ByteStringHashMap ExportListEntry; 107 108 DECLARE_LIST( ExportListBase, ExportListEntry * ) 109 110 // 111 // class ExportList 112 // 113 114 class ExportList : public ExportListBase 115 { 116 private: 117 sal_uLong nSourceLanguageListEntryCount; 118 119 public: 120 ExportList() : ExportListBase() { nSourceLanguageListEntryCount = 0; } 121 sal_uLong GetSourceLanguageListEntryCount() { return nSourceLanguageListEntryCount; } 122 void NewSourceLanguageListEntry() { nSourceLanguageListEntryCount++; } 123 }; 124 125 #define REFID_NONE 0xFFFF 126 127 // 128 // struct ResData 129 // 130 131 /****************************************************************************** 132 * Purpose: holds mandatory data to export a single res (used with ResStack) 133 ******************************************************************************/ 134 135 #define ID_LEVEL_NULL 0x0000 136 #define ID_LEVEL_AUTOID 0x0001 137 #define ID_LEVEL_TEXT 0x0002 138 #define ID_LEVEL_FIELDNAME 0x0003 139 #define ID_LEVEL_ACCESSPATH 0x0004 140 #define ID_LEVEL_IDENTIFIER 0x0005 141 #define ID_LEVEL_LISTINDEX 0x0006 142 143 class ResData 144 { 145 public: 146 ~ResData(); 147 sal_Bool SetId( const ByteString &rId, sal_uInt16 nLevel ); 148 149 sal_uInt16 nWidth; 150 sal_uInt16 nChildIndex; 151 sal_uInt16 nIdLevel; 152 sal_Bool bChild; 153 sal_Bool bChildWithText; 154 155 sal_Bool bText; 156 sal_Bool bHelpText; 157 sal_Bool bQuickHelpText; 158 sal_Bool bTitle; 159 sal_Bool bList; 160 161 sal_Bool bRestMerged; 162 163 ByteString sResTyp; 164 ByteString sId; 165 ByteString sGId; 166 ByteString sHelpId; 167 ByteString sFilename; 168 169 ByteStringHashMap sText; 170 sal_uInt16 nTextRefId; 171 172 ByteStringHashMap sHelpText; 173 sal_uInt16 nHelpTextRefId; 174 175 ByteStringHashMap sQuickHelpText; 176 sal_uInt16 nQuickHelpTextRefId; 177 178 ByteStringHashMap sTitle; 179 sal_uInt16 nTitleRefId; 180 181 ByteString sTextTyp; 182 ByteStringHashMap aFallbackData; 183 ByteStringHashMap aMergedLanguages; 184 185 ExportList *pStringList; 186 ExportList *pUIEntries; 187 ExportList *pItemList; 188 ExportList *pFilterList; 189 ExportList *pPairedList; 190 191 ByteString sPForm; 192 193 void Dump(); 194 void addFallbackData( ByteString& sId , const ByteString& sText ); 195 bool getFallbackData( ByteString& sId , ByteString& sText); 196 197 void addMergedLanguage( ByteString& sLang ); 198 bool isMerged( ByteString& sLang ); 199 ResData( const ByteString &rPF, const ByteString &rGId ) 200 : 201 nWidth( 0 ), 202 nChildIndex( 0 ), 203 nIdLevel( ID_LEVEL_NULL ), 204 bChild( sal_False ), 205 bChildWithText( sal_False ), 206 bText( sal_False ), 207 bHelpText( sal_False ), 208 bQuickHelpText( sal_False ), 209 bTitle( sal_False ), 210 bList( sal_False ), 211 bRestMerged( sal_False ), 212 sGId( rGId ), 213 nTextRefId( REFID_NONE ), 214 nHelpTextRefId( REFID_NONE ), 215 nQuickHelpTextRefId( REFID_NONE ), 216 nTitleRefId( REFID_NONE ), 217 sTextTyp( "Text" ), 218 pStringList( NULL ), 219 pUIEntries( NULL ), 220 pItemList( NULL ), 221 pFilterList( NULL ), 222 pPairedList( NULL ), 223 sPForm( rPF ) 224 { 225 sGId.EraseAllChars( '\r' ); 226 sPForm.EraseAllChars( '\r' ); 227 }; 228 ResData( const ByteString &rPF, const ByteString &rGId , const ByteString &rFilename ) 229 : 230 nChildIndex( 0 ), 231 nIdLevel( ID_LEVEL_NULL ), 232 bChild( sal_False ), 233 bChildWithText( sal_False ), 234 bText( sal_False ), 235 bHelpText( sal_False ), 236 bQuickHelpText( sal_False ), 237 bTitle( sal_False ), 238 bList( sal_False ), 239 bRestMerged( sal_False ), 240 sGId( rGId ), 241 sFilename( rFilename ), 242 nTextRefId( REFID_NONE ), 243 nHelpTextRefId( REFID_NONE ), 244 nQuickHelpTextRefId( REFID_NONE ), 245 nTitleRefId( REFID_NONE ), 246 sTextTyp( "Text" ), 247 pStringList( NULL ), 248 pUIEntries( NULL ), 249 pItemList( NULL ), 250 pFilterList( NULL ), 251 pPairedList( NULL ), 252 sPForm( rPF ) 253 254 { 255 sGId.EraseAllChars( '\r' ); 256 sPForm.EraseAllChars( '\r' ); 257 }; 258 259 260 }; 261 262 263 // 264 // class Export 265 // 266 267 /****************************************************************************** 268 * Purpose: syntax check and export of *.src, called from lexer 269 ******************************************************************************/ 270 271 #define LIST_NON 0x0000 272 #define LIST_STRING 0x0001 273 #define LIST_FILTER 0x0002 274 #define LIST_ITEM 0x0004 275 #define LIST_PAIRED 0x0005 276 #define LIST_UIENTRIES 0x0008 277 #define STRING_TYP_TEXT 0x0010 278 #define STRING_TYP_HELPTEXT 0x0020 279 #define STRING_TYP_QUICKHELPTEXT 0x0040 280 #define STRING_TYP_TITLE 0x0080 281 282 #define MERGE_MODE_NORMAL 0x0000 283 #define MERGE_MODE_LIST 0x0001 284 285 DECLARE_LIST( ResStack, ResData * ) 286 // forwards 287 class WordTransformer; 288 class ParserQueue; 289 290 class Export 291 { 292 private: 293 WordTransformer *pWordTransformer; 294 295 CharSet aCharSet; // used charset in src 296 297 SvFileStream aOutput; 298 299 ResStack aResStack; // stack for parsing recursive 300 301 ByteString sActPForm; // hold cur. system 302 303 sal_Bool bDefine; // cur. res. in a define? 304 sal_Bool bNextMustBeDefineEOL; // define but no \ at lineend 305 sal_uLong nLevel; // res. recursiv? how deep? 306 sal_uInt16 nList; // cur. res. is String- or FilterList 307 ByteString nListLang; 308 sal_uLong nListIndex; 309 sal_uLong nListLevel; 310 bool bSkipFile; 311 ByteString sProject; 312 ByteString sRoot; 313 sal_Bool bEnableExport; 314 sal_Bool bMergeMode; 315 ByteString sMergeSrc; 316 ByteString sLastListLine; 317 sal_Bool bError; // any errors while export? 318 sal_Bool bReadOver; 319 sal_Bool bDontWriteOutput; 320 ByteString sLastTextTyp; 321 static bool isInitialized; 322 ByteString sFilename; 323 324 325 public: 326 ParserQueue* pParseQueue; // public ? 327 static ByteString sLanguages; // public ? 328 static ByteString sForcedLanguages; // public ? 329 330 331 static bool skipProject( ByteString sPrj ) ; 332 static void InitLanguages( bool bMergeMode = false ); 333 static void InitForcedLanguages( bool bMergeMode = false ); 334 static std::vector<ByteString> GetLanguages(); 335 static std::vector<ByteString> GetForcedLanguages(); 336 337 static void SetLanguages( std::vector<ByteString> val ); 338 static void RemoveUTF8ByteOrderMarker( ByteString &rString ); 339 static bool hasUTF8ByteOrderMarker( const ByteString &rString ); 340 static void RemoveUTF8ByteOrderMarkerFromFile( const ByteString &rFilename ); 341 static bool fileHasUTF8ByteOrderMarker( const ByteString &rString ); 342 static ByteString GetIsoLangByIndex( sal_uInt16 nIndex ); 343 static void QuotHTML( ByteString &rString ); 344 static bool CopyFile( const ByteString& source , const ByteString& dest ); 345 346 static void QuotHTMLXRM( ByteString &rString ); 347 static void UnquotHTML( ByteString &rString ); 348 349 static const char* GetEnv( const char *pVar ); 350 static int getCurrentDirectory( rtl::OUString& base_fqurl , rtl::OUString& base ); 351 352 static bool isSourceLanguage( const ByteString &sLanguage ); 353 static bool isAllowed( const ByteString &sLanguage ); 354 355 static bool LanguageAllowed( const ByteString &nLanguage ); 356 static void Languages( std::vector<ByteString>::const_iterator& begin , std::vector<ByteString>::const_iterator& end ); 357 static void getRandomName( const ByteString& sPrefix , ByteString& sRandStr , const ByteString& sPostfix ); 358 static void getRandomName( ByteString& sRandStr ); 359 static void getCurrentDir( std::string& dir ); 360 361 static void replaceEncoding( ByteString& rString ); 362 363 static ByteString GetFallbackLanguage( const ByteString nLanguage ); 364 static void FillInFallbacks( ResData *pResData ); 365 static void FillInListFallbacks( ExportList *pList, const ByteString &nSource, const ByteString &nFallback ); 366 static ByteString GetTimeStamp(); 367 static sal_Bool ConvertLineEnds( ByteString sSource, ByteString sDestination ); 368 static ByteString GetNativeFile( ByteString sSource ); 369 static DirEntry GetTempFile(); 370 371 static void DumpExportList( ByteString& sListName , ExportList& aList ); 372 static ByteString DumpMap( ByteString& sMapName , ByteStringHashMap& aMap ); 373 374 private: 375 static std::vector<ByteString> aLanguages; 376 static std::vector<ByteString> aForcedLanguages; 377 378 sal_Bool ListExists( ResData *pResData, sal_uInt16 nLst ); 379 380 sal_Bool WriteData( ResData *pResData, sal_Bool bCreateNew = sal_False );// called befor dest. cur ResData 381 sal_Bool WriteExportList( ResData *pResData, ExportList *pExportList, 382 const ByteString &rTyp, sal_Bool bCreateNew = sal_False ); 383 384 ByteString MergePairedList( ByteString& sLine , ByteString& sText ); 385 386 ByteString FullId(); // creates cur. GID 387 388 bool PairedListFallback( ByteString& sText , ResData& aResData ); 389 390 ByteString GetPairedListID ( const ByteString& sText ); 391 ByteString GetPairedListString ( const ByteString& sText ); 392 ByteString StripList ( const ByteString& sText ); 393 394 void UnmergeUTF8( ByteString& sOrig ); 395 void InsertListEntry( const ByteString &rText, const ByteString &rLine ); 396 void CleanValue( ByteString &rValue ); 397 ByteString GetText( const ByteString &rSource, int nToken ); 398 399 sal_Bool PrepareTextToMerge( ByteString &rText, sal_uInt16 nTyp, 400 ByteString &nLangIndex, ResData *pResData ); 401 402 void MergeRest( ResData *pResData, sal_uInt16 nMode = MERGE_MODE_NORMAL ); 403 void ConvertMergeContent( ByteString &rText ); 404 405 void WriteToMerged( const ByteString &rText , bool bSDFContent ); 406 void SetChildWithText(); 407 408 void CutComment( ByteString &rText ); 409 410 public: 411 Export( const ByteString &rOutput, sal_Bool bWrite, 412 const ByteString &rPrj, const ByteString &rPrjRoot , const ByteString& rFile ); 413 Export( const ByteString &rOutput, sal_Bool bWrite, 414 const ByteString &rPrj, const ByteString &rPrjRoot, 415 const ByteString &rMergeSource , const ByteString& rFile ); 416 ~Export(); 417 418 void Init(); 419 int Execute( int nToken, const char * pToken ); // called from lexer 420 void SetError() { bError = sal_True; } 421 sal_Bool GetError() { return bError; } 422 }; 423 424 425 // 426 // class PFormEntrys 427 // 428 429 /****************************************************************************** 430 * Purpose: holds information of data to merge (one pform) 431 ******************************************************************************/ 432 433 class PFormEntrys : public ByteString 434 { 435 friend class MergeDataFile; 436 private: 437 ByteString sHelpText; // empty string 438 ByteStringHashMap sText; 439 ByteStringBoolHashMap bTextFirst; 440 ByteStringHashMap sQuickHelpText; 441 ByteStringBoolHashMap bQuickHelpTextFirst; 442 ByteStringHashMap sTitle; 443 ByteStringBoolHashMap bTitleFirst; 444 445 public: 446 PFormEntrys( const ByteString &rPForm ) : ByteString( rPForm ) {}; 447 ByteString Dump(); 448 void InsertEntry( 449 const ByteString &nId , 450 const ByteString &rText, 451 const ByteString &rQuickHelpText, 452 const ByteString &rTitle 453 ) 454 { 455 sText[ nId ] = rText; 456 bTextFirst[ nId ] = true; 457 sQuickHelpText[ nId ] = rQuickHelpText; 458 bQuickHelpTextFirst[ nId ] = true; 459 sTitle[ nId ] = rTitle; 460 bTitleFirst[ nId ] = true; 461 } 462 sal_Bool GetText( ByteString &rReturn, sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel = sal_False ); 463 sal_Bool GetTransex3Text( ByteString &rReturn, sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel = sal_False ); 464 465 }; 466 467 // 468 // class MergeData 469 // 470 471 /****************************************************************************** 472 * Purpose: holds information of data to merge (one ressource) 473 ******************************************************************************/ 474 475 class MergeDataFile; 476 477 class MergeData 478 { 479 friend class MergeDataFile; 480 private: 481 ByteString sTyp; 482 ByteString sGID; 483 ByteString sLID; 484 ByteString sFilename; 485 PFormEntrysHashMap aMap; 486 public: 487 MergeData( const ByteString &rTyp, const ByteString &rGID, const ByteString &rLID , const ByteString &rFilename ) 488 : sTyp( rTyp ), sGID( rGID ), sLID( rLID ) , sFilename( rFilename ) {}; 489 ~MergeData(); 490 PFormEntrys* InsertEntry( const ByteString &rPForm ); 491 PFormEntrys* GetPFormEntrys( ResData *pResData ); 492 493 void Insert( const ByteString& rPFO , PFormEntrys* pfEntrys ); 494 PFormEntrys* GetPFObject( const ByteString& rPFO ); 495 496 ByteString Dump(); 497 sal_Bool operator==( ResData *pData ); 498 }; 499 500 // 501 // class MergeDataFile 502 // 503 504 /****************************************************************************** 505 * Purpose: holds information of data to merge 506 ******************************************************************************/ 507 508 class MergeDataFile 509 { 510 private: 511 sal_Bool bErrorLog; 512 ByteString sErrorLog; 513 SvFileStream aErrLog; 514 MergeDataHashMap aMap; 515 std::set<ByteString> aLanguageSet; 516 517 MergeData *GetMergeData( ResData *pResData , bool bCaseSensitve = false ); 518 void InsertEntry( const ByteString &rTYP, const ByteString &rGID, const ByteString &rLID, 519 const ByteString &rPFO, 520 const ByteString &nLang, const ByteString &rTEXT, 521 const ByteString &rQHTEXT, const ByteString &rTITLE, 522 const ByteString &sFilename, bool bCaseSensitive 523 ); 524 ByteString Dump(); 525 void WriteError( const ByteString &rLine ); 526 527 public: 528 MergeDataFile( const ByteString &rFileName, const ByteString& rFile , sal_Bool bErrLog, CharSet aCharSet, bool bCaseSensitive = false ); 529 ~MergeDataFile(); 530 531 std::vector<ByteString> GetLanguages(); 532 533 PFormEntrys *GetPFormEntrys( ResData *pResData ); 534 PFormEntrys *GetPFormEntrysCaseSensitive( ResData *pResData ); 535 536 static ByteString CreateKey( const ByteString& rTYP , const ByteString& rGID , const ByteString& rLID , const ByteString& rFilename , bool bCaseSensitive = false ); 537 }; 538 539 540 class QueueEntry 541 { 542 public: 543 QueueEntry( int nTypVal , ByteString sLineVal ): nTyp( nTypVal ) , sLine( sLineVal ){}; 544 int nTyp; 545 ByteString sLine; 546 }; 547 548 class ParserQueue 549 { 550 public: 551 552 ParserQueue( Export& aExportObj ); 553 ~ParserQueue(); 554 555 inline void Push( const QueueEntry& aEntry ); 556 bool bCurrentIsM; // public ? 557 bool bNextIsM; // public ? 558 bool bLastWasM; // public ? 559 bool bMflag; // public ? 560 561 void Close(); 562 private: 563 // Future / Next 564 std::queue<QueueEntry>* aQueueNext; 565 // Current 566 std::queue<QueueEntry>* aQueueCur; 567 // Ref 568 std::queue<QueueEntry>* aQref; 569 570 Export& aExport; 571 bool bStart; 572 bool bStartNext; 573 574 inline void Pop( std::queue<QueueEntry>& aQueue ); 575 576 }; 577 #endif 578 579