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_rsc.hxx" 30 /****************** I N C L U D E S **************************************/ 31 // C and C++ Includes. 32 #include <ctype.h> // isdigit(), isalpha() 33 #include <stdlib.h> 34 #include <stdio.h> 35 #include <string.h> 36 37 #include <tools/fsys.hxx> 38 #include <tools/rc.h> 39 #include <tools/isofallback.hxx> 40 #include <rtl/strbuf.hxx> 41 42 // Programmabhaengige Includes. 43 #include <rsctree.hxx> 44 #include <rsctop.hxx> 45 #include <rscmgr.hxx> 46 #include <rscdb.hxx> 47 #include <rscrsc.hxx> 48 49 using namespace rtl; 50 51 /************************************************************************* 52 |* 53 |* RscTypCont :: RscTypCont 54 |* 55 |* Beschreibung RES.DOC 56 |* Ersterstellung MM 22.03.90 57 |* Letzte Aenderung MM 27.06.90 58 |* 59 *************************************************************************/ 60 RscTypCont :: RscTypCont( RscError * pErrHdl, 61 RSCBYTEORDER_TYPE nOrder, 62 const ByteString & rSearchPath, 63 sal_uInt32 nFlagsP ) 64 : 65 nSourceCharSet( RTL_TEXTENCODING_UTF8 ), 66 nByteOrder( nOrder ), 67 aSearchPath( rSearchPath ), 68 aBool( pHS->getID( "sal_Bool" ), RSC_NOTYPE ), 69 aShort( pHS->getID( "short" ), RSC_NOTYPE ), 70 aUShort( pHS->getID( "sal_uInt16" ), RSC_NOTYPE ), 71 aLong( pHS->getID( "long" ), RSC_NOTYPE ), 72 aEnumLong( pHS->getID( "enum_long" ), RSC_NOTYPE ), 73 aIdUShort( pHS->getID( "IDUSHORT" ), RSC_NOTYPE ), 74 aIdNoZeroUShort( pHS->getID( "IDUSHORT" ), RSC_NOTYPE ), 75 aNoZeroShort( pHS->getID( "NoZeroShort" ), RSC_NOTYPE ), 76 a1to12Short( pHS->getID( "MonthShort" ), RSC_NOTYPE ), 77 a0to23Short( pHS->getID( "HourShort" ), RSC_NOTYPE ), 78 a1to31Short( pHS->getID( "DayShort" ), RSC_NOTYPE ), 79 a0to59Short( pHS->getID( "MinuteShort" ), RSC_NOTYPE ), 80 a0to99Short( pHS->getID( "_0to59Short" ), RSC_NOTYPE ), 81 a0to9999Short( pHS->getID( "YearShort" ), RSC_NOTYPE ), 82 aIdLong( pHS->getID( "IDLONG" ), RSC_NOTYPE ), 83 aString( pHS->getID( "Chars" ), RSC_NOTYPE ), 84 aStringLiteral( pHS->getID( "Chars" ), RSC_NOTYPE ), 85 aWinBits( pHS->getID( "WinBits" ), RSC_NOTYPE ), 86 aLangType(), 87 aLangString( pHS->getID( "Lang_Chars" ), RSC_NOTYPE, &aString, &aLangType ), 88 aLangShort( pHS->getID( "Lang_short" ), RSC_NOTYPE, &aShort, &aLangType ), 89 nAcceleratorType( 0 ), 90 nFlags( nFlagsP ) 91 { 92 nUniqueId = 256; 93 nPMId = RSC_VERSIONCONTROL +1; //mindestens einen groesser 94 pEH = pErrHdl; 95 Init(); 96 } 97 98 static sal_uInt32 getLangIdAndShortenLocale( RscTypCont* pTypCont, 99 rtl::OString& rLang, 100 rtl::OString& rCountry, 101 rtl::OString& rVariant ) 102 { 103 rtl::OStringBuffer aLangStr( 64 ); 104 aLangStr.append( rLang.toAsciiLowerCase() ); 105 if( rCountry.getLength() ) 106 { 107 aLangStr.append( '-' ); 108 aLangStr.append( rCountry.toAsciiUpperCase() ); 109 } 110 if( rVariant.getLength() ) 111 { 112 aLangStr.append( '-' ); 113 aLangStr.append( rVariant ); 114 } 115 rtl::OString aL( aLangStr.makeStringAndClear() ); 116 sal_uInt32 nRet = GetLangId( aL ); 117 if( nRet == 0 ) 118 { 119 pTypCont->AddLanguage( aL ); 120 nRet = GetLangId( aL ); 121 } 122 if( rVariant.getLength() ) 123 rVariant = rtl::OString(); 124 else if( rCountry.getLength() ) 125 rCountry = rtl::OString(); 126 else 127 rLang = rtl::OString(); 128 #if OSL_DEBUG_LEVEL > 1 129 fprintf( stderr, " %s (0x%hx)", aL.getStr(), (int)nRet ); 130 #endif 131 return nRet; 132 } 133 134 ByteString RscTypCont::ChangeLanguage( const ByteString& rNewLang ) 135 { 136 ByteString aRet = aLanguage; 137 aLanguage = rNewLang; 138 139 rtl::OString aLang = aLanguage; 140 rtl::OString aLg, aCountry, aVariant; 141 sal_Int32 nIndex = 0; 142 aLg = aLang.getToken( 0, '-', nIndex ); 143 if( nIndex != -1 ) 144 aCountry = aLang.getToken( 0, '-', nIndex ); 145 if( nIndex != -1 ) 146 aVariant = aLang.copy( nIndex ); 147 148 bool bAppendEnUsFallback = 149 ! (rNewLang.EqualsIgnoreCaseAscii( "en-US" ) || 150 rNewLang.EqualsIgnoreCaseAscii( "x-no-translate" ) ); 151 152 #if OSL_DEBUG_LEVEL > 1 153 fprintf( stderr, "RscTypCont::ChangeLanguage:" ); 154 #endif 155 aLangFallbacks.clear(); 156 157 do 158 { 159 aLangFallbacks.push_back(getLangIdAndShortenLocale( this, aLg, aCountry, aVariant ) ); 160 } while( aLg.getLength() ); 161 162 if( bAppendEnUsFallback ) 163 { 164 aLg = "en"; 165 aCountry = "US"; 166 aVariant = rtl::OString(); 167 aLangFallbacks.push_back( getLangIdAndShortenLocale( this, aLg, aCountry, aVariant ) ); 168 } 169 170 #if OSL_DEBUG_LEVEL > 1 171 fprintf( stderr, "\n" ); 172 #endif 173 174 return aRet; 175 } 176 177 Atom RscTypCont::AddLanguage( const char* pLang ) 178 { 179 return aLangType.AddLanguage( pLang, aNmTb ); 180 } 181 182 183 /************************************************************************* 184 |* 185 |* RscTypCont :: ~RscTypCont 186 |* 187 |* Beschreibung RES.DOC 188 |* Ersterstellung MM 22.03.90 189 |* Letzte Aenderung MM 27.06.90 190 |* 191 *************************************************************************/ 192 void DestroyNode( RscTop * pRscTop, ObjNode * pObjNode ){ 193 if( pObjNode ){ 194 DestroyNode( pRscTop, (ObjNode*)pObjNode->Left() ); 195 DestroyNode( pRscTop, (ObjNode*)pObjNode->Right() ); 196 197 if( pObjNode->GetRscObj() ){ 198 pRscTop->Destroy( RSCINST( pRscTop, pObjNode->GetRscObj() ) ); 199 rtl_freeMemory( pObjNode->GetRscObj() ); 200 } 201 delete pObjNode; 202 }; 203 } 204 205 void DestroySubTrees( RscTop * pRscTop ){ 206 if( pRscTop ){ 207 DestroySubTrees( (RscTop*)pRscTop->Left() ); 208 209 DestroyNode( pRscTop, pRscTop->GetObjNode() ); 210 211 DestroySubTrees( (RscTop*)pRscTop->Right() ); 212 }; 213 } 214 215 void DestroyTree( RscTop * pRscTop ){ 216 if( pRscTop ){ 217 DestroyTree( (RscTop*)pRscTop->Left() ); 218 DestroyTree( (RscTop*)pRscTop->Right() ); 219 220 delete pRscTop; 221 }; 222 } 223 224 void Pre_dtorTree( RscTop * pRscTop ){ 225 if( pRscTop ){ 226 Pre_dtorTree( (RscTop*)pRscTop->Left() ); 227 Pre_dtorTree( (RscTop*)pRscTop->Right() ); 228 229 pRscTop->Pre_dtor(); 230 }; 231 } 232 233 RscTypCont :: ~RscTypCont(){ 234 RscTop * pRscTmp; 235 RscSysEntry * pSysEntry; 236 237 // Alle Unterbaeume loeschen 238 aVersion.pClass->Destroy( aVersion ); 239 rtl_freeMemory( aVersion.pData ); 240 DestroySubTrees( pRoot ); 241 242 // Alle Klassen noch gueltig, jeweilige Instanzen freigeben 243 // BasisTypen 244 pRscTmp = aBaseLst.First(); 245 while( pRscTmp ){ 246 pRscTmp->Pre_dtor(); 247 pRscTmp = aBaseLst.Next(); 248 }; 249 aBool.Pre_dtor(); 250 aShort.Pre_dtor(); 251 aUShort.Pre_dtor(); 252 aIdUShort.Pre_dtor(); 253 aIdNoZeroUShort.Pre_dtor(); 254 aNoZeroShort.Pre_dtor(); 255 aIdLong.Pre_dtor(); 256 aString.Pre_dtor(); 257 aWinBits.Pre_dtor(); 258 aVersion.pClass->Pre_dtor(); 259 // Zusammengesetzte Typen 260 Pre_dtorTree( pRoot ); 261 262 // Klassen zerstoeren 263 delete aVersion.pClass; 264 DestroyTree( pRoot ); 265 266 while( NULL != (pRscTmp = aBaseLst.Remove()) ){ 267 delete pRscTmp; 268 }; 269 270 while( NULL != (pSysEntry = aSysLst.Remove()) ){ 271 delete pSysEntry; 272 }; 273 } 274 275 void RscTypCont::ClearSysNames() 276 { 277 RscSysEntry * pSysEntry; 278 while( NULL != (pSysEntry = aSysLst.Remove()) ){ 279 delete pSysEntry; 280 }; 281 } 282 283 //======================================================================= 284 RscTop * RscTypCont::SearchType( Atom nId ) 285 /* [Beschreibung] 286 287 Sucht eine Basistyp nId; 288 */ 289 { 290 if( nId == InvalidAtom ) 291 return NULL; 292 293 #define ELSE_IF( a ) \ 294 else if( a.GetId() == nId ) \ 295 return &a; \ 296 297 if( aBool.GetId() == nId ) 298 return &aBool; 299 ELSE_IF( aShort ) 300 ELSE_IF( aUShort ) 301 ELSE_IF( aLong ) 302 ELSE_IF( aEnumLong ) 303 ELSE_IF( aIdUShort ) 304 ELSE_IF( aIdNoZeroUShort ) 305 ELSE_IF( aNoZeroShort ) 306 ELSE_IF( a1to12Short ) 307 ELSE_IF( a0to23Short ) 308 ELSE_IF( a1to31Short ) 309 ELSE_IF( a0to59Short ) 310 ELSE_IF( a0to99Short ) 311 ELSE_IF( a0to9999Short ) 312 ELSE_IF( aIdLong ) 313 ELSE_IF( aString ) 314 ELSE_IF( aWinBits ) 315 ELSE_IF( aLangType ) 316 ELSE_IF( aLangString ) 317 ELSE_IF( aLangShort ) 318 319 RscTop * pEle = aBaseLst.First(); 320 while( pEle ) 321 { 322 if( pEle->GetId() == nId ) 323 return pEle; 324 pEle = aBaseLst.Next(); 325 } 326 return NULL; 327 } 328 329 /************************************************************************* 330 |* 331 |* RscTypCont :: Search 332 |* 333 |* Beschreibung RES.DOC 334 |* Ersterstellung MM 22.03.90 335 |* Letzte Aenderung MM 27.06.90 336 |* 337 *************************************************************************/ 338 RscTop * RscTypCont :: Search( Atom nRT ){ 339 return( (RscTop *)pRoot->Search( nRT ) ); 340 } 341 342 CLASS_DATA RscTypCont :: Search( Atom nRT, const RscId & rId ){ 343 ObjNode *pObjNode; 344 RscTop *pRscTop; 345 346 if( NULL != (pRscTop = Search( nRT )) ){ 347 if( NULL != (pObjNode = pRscTop->GetObjNode( rId )) ){ 348 return( pObjNode->GetRscObj() ); 349 } 350 } 351 return( (CLASS_DATA)0 ); 352 } 353 354 /************************************************************************* 355 |* 356 |* RscTypCont :: Delete() 357 |* 358 |* Beschreibung 359 |* Ersterstellung MM 10.07.91 360 |* Letzte Aenderung MM 10.07.91 361 |* 362 *************************************************************************/ 363 void RscTypCont :: Delete( Atom nRT, const RscId & rId ){ 364 ObjNode * pObjNode; 365 RscTop * pRscTop; 366 367 if( NULL != (pRscTop = Search( nRT )) ){ 368 if( NULL != (pObjNode = pRscTop->GetObjNode()) ){ 369 pObjNode = pObjNode->Search( rId ); 370 371 if( pObjNode ){ 372 //Objekt aus Baum entfernen 373 pRscTop->pObjBiTree = 374 (ObjNode *)pRscTop->pObjBiTree->Remove( pObjNode ); 375 376 if( pObjNode->GetRscObj() ){ 377 pRscTop->Destroy( RSCINST( pRscTop, 378 pObjNode->GetRscObj() ) ); 379 rtl_freeMemory( pObjNode->GetRscObj() ); 380 } 381 delete pObjNode; 382 } 383 } 384 } 385 } 386 387 /************************************************************************* 388 |* 389 |* RscTypCont :: PutSysName() 390 |* 391 |* Beschreibung RES.DOC 392 |* Ersterstellung MM 22.03.90 393 |* Letzte Aenderung MM 27.06.90 394 |* 395 *************************************************************************/ 396 sal_uInt32 RscTypCont :: PutSysName( sal_uInt32 nRscTyp, char * pFileName, 397 sal_uInt32 nConst, sal_uInt32 nId, sal_Bool bFirst ) 398 { 399 RscSysEntry * pSysEntry; 400 sal_Bool bId1 = sal_False; 401 402 pSysEntry = aSysLst.First(); 403 while( pSysEntry ) 404 { 405 if( pSysEntry->nKey == 1 ) 406 bId1 = sal_True; 407 if( !strcmp( pSysEntry->aFileName.GetBuffer(), pFileName ) ) 408 if( pSysEntry->nRscTyp == nRscTyp 409 && pSysEntry->nTyp == nConst 410 && pSysEntry->nRefId == nId ) 411 break; 412 pSysEntry = aSysLst.Next(); 413 } 414 415 if ( !pSysEntry || (bFirst && !bId1) ) 416 { 417 pSysEntry = new RscSysEntry; 418 pSysEntry->nKey = nUniqueId++; 419 pSysEntry->nRscTyp = nRscTyp; 420 pSysEntry->nTyp = nConst; 421 pSysEntry->nRefId = nId; 422 pSysEntry->aFileName = (const char*)pFileName; 423 if( bFirst && !bId1 ) 424 { 425 pSysEntry->nKey = 1; 426 aSysLst.Insert( pSysEntry, (sal_uLong)0 ); 427 } 428 else 429 aSysLst.Insert( pSysEntry, LIST_APPEND ); 430 } 431 432 return pSysEntry->nKey; 433 } 434 435 /************************************************************************* 436 |* 437 |* RscTypCont :: WriteInc 438 |* 439 |* Beschreibung RES.DOC 440 |* Ersterstellung MM 21.06.90 441 |* Letzte Aenderung MM 21.06.90 442 |* 443 *************************************************************************/ 444 void RscTypCont :: WriteInc( FILE * fOutput, sal_uLong lFileKey ) 445 { 446 RscFile * pFName; 447 448 if( NOFILE_INDEX == lFileKey ) 449 { 450 pFName = aFileTab.First(); 451 while( pFName ) 452 { 453 if( pFName && pFName->IsIncFile() ) 454 { 455 fprintf( fOutput, "#include " ); 456 fprintf( fOutput, "\"%s\"\n", 457 pFName->aFileName.GetBuffer() ); 458 } 459 pFName = aFileTab.Next(); 460 } 461 } 462 else 463 { 464 RscDepend * pDep; 465 RscFile * pFile; 466 467 pFName = aFileTab.Get( lFileKey ); 468 if( pFName ) 469 { 470 pDep = pFName->First(); 471 while( pDep ) 472 { 473 if( pDep->GetFileKey() != lFileKey ) 474 { 475 pFile = aFileTab.GetFile( pDep->GetFileKey() ); 476 if( pFile ) 477 { 478 fprintf( fOutput, "#include " ); 479 fprintf( fOutput, "\"%s\"\n", 480 pFile->aFileName.GetBuffer() ); 481 } 482 } 483 pDep = pFName->Next(); 484 }; 485 }; 486 }; 487 } 488 489 /************************************************************************* 490 |* 491 |* RscTypCont :: Methoden die ueber all Knoten laufen 492 |* 493 |* Beschreibung RES.DOC 494 |* Ersterstellung MM 22.03.90 495 |* Letzte Aenderung MM 09.12.91 496 |* 497 *************************************************************************/ 498 499 class RscEnumerateObj 500 { 501 friend class RscEnumerateRef; 502 private: 503 ERRTYPE aError; // Enthaelt den ersten Fehler 504 RscTypCont* pTypCont; 505 FILE * fOutput; // AusgabeDatei 506 sal_uLong lFileKey; // Welche src-Datei 507 RscTop * pClass; 508 509 DECL_LINK( CallBackWriteRc, ObjNode * ); 510 DECL_LINK( CallBackWriteSrc, ObjNode * ); 511 DECL_LINK( CallBackWriteCxx, ObjNode * ); 512 DECL_LINK( CallBackWriteHxx, ObjNode * ); 513 514 ERRTYPE WriteRc( RscTop * pCl, ObjNode * pRoot ) 515 { 516 pClass = pCl; 517 if( pRoot ) 518 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteRc ) ); 519 return aError; 520 } 521 ERRTYPE WriteSrc( RscTop * pCl, ObjNode * pRoot ){ 522 pClass = pCl; 523 if( pRoot ) 524 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteSrc ) ); 525 return aError; 526 } 527 ERRTYPE WriteCxx( RscTop * pCl, ObjNode * pRoot ){ 528 pClass = pCl; 529 if( pRoot ) 530 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteCxx ) ); 531 return aError; 532 } 533 ERRTYPE WriteHxx( RscTop * pCl, ObjNode * pRoot ){ 534 pClass = pCl; 535 if( pRoot ) 536 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteHxx ) ); 537 return aError; 538 } 539 public: 540 void WriteRcFile( RscWriteRc & rMem, FILE * fOutput ); 541 }; 542 543 /************************************************************************* 544 |* 545 |* RscEnumerateObj :: CallBackWriteRc 546 |* 547 |* Beschreibung 548 |* Ersterstellung MM 09.12.91 549 |* Letzte Aenderung MM 09.12.91 550 |* 551 *************************************************************************/ 552 IMPL_LINK( RscEnumerateObj, CallBackWriteRc, ObjNode *, pObjNode ) 553 { 554 RscWriteRc aMem( pTypCont->GetByteOrder() ); 555 556 aError = pClass->WriteRcHeader( RSCINST( pClass, pObjNode->GetRscObj() ), 557 aMem, pTypCont, 558 pObjNode->GetRscId(), 0, sal_True ); 559 if( aError.IsError() || aError.IsWarning() ) 560 pTypCont->pEH->Error( aError, pClass, pObjNode->GetRscId() ); 561 562 WriteRcFile( aMem, fOutput ); 563 return 0; 564 } 565 566 /************************************************************************* 567 |* 568 |* RscEnumerateObj :: CallBackWriteSrc 569 |* 570 |* Beschreibung 571 |* Ersterstellung MM 09.12.91 572 |* Letzte Aenderung MM 09.12.91 573 |* 574 *************************************************************************/ 575 IMPL_LINK_INLINE_START( RscEnumerateObj, CallBackWriteSrc, ObjNode *, pObjNode ) 576 { 577 if( pObjNode->GetFileKey() == lFileKey ){ 578 pClass->WriteSrcHeader( RSCINST( pClass, pObjNode->GetRscObj() ), 579 fOutput, pTypCont, 0, 580 pObjNode->GetRscId(), "" ); 581 fprintf( fOutput, ";\n" ); 582 } 583 return 0; 584 } 585 IMPL_LINK_INLINE_END( RscEnumerateObj, CallBackWriteSrc, ObjNode *, pObjNode ) 586 587 /************************************************************************* 588 |* 589 |* RscEnumerateObj :: CallBackWriteCxx 590 |* 591 |* Beschreibung 592 |* Ersterstellung MM 09.12.91 593 |* Letzte Aenderung MM 09.12.91 594 |* 595 *************************************************************************/ 596 IMPL_LINK_INLINE_START( RscEnumerateObj, CallBackWriteCxx, ObjNode *, pObjNode ) 597 { 598 if( pClass->IsCodeWriteable() && pObjNode->GetFileKey() == lFileKey ) 599 aError = pClass->WriteCxxHeader( 600 RSCINST( pClass, pObjNode->GetRscObj() ), 601 fOutput, pTypCont, pObjNode->GetRscId() ); 602 return 0; 603 } 604 IMPL_LINK_INLINE_END( RscEnumerateObj, CallBackWriteCxx, ObjNode *, pObjNode ) 605 606 /************************************************************************* 607 |* 608 |* RscEnumerateObj :: CallBackWriteHxx 609 |* 610 |* Beschreibung 611 |* Ersterstellung MM 09.12.91 612 |* Letzte Aenderung MM 09.12.91 613 |* 614 *************************************************************************/ 615 IMPL_LINK_INLINE_START( RscEnumerateObj, CallBackWriteHxx, ObjNode *, pObjNode ) 616 { 617 if( pClass->IsCodeWriteable() && pObjNode->GetFileKey() == lFileKey ) 618 aError = pClass->WriteHxxHeader( 619 RSCINST( pClass, pObjNode->GetRscObj() ), 620 fOutput, pTypCont, pObjNode->GetRscId() ); 621 return 0; 622 } 623 IMPL_LINK_INLINE_END( RscEnumerateObj, CallBackWriteHxx, ObjNode *, pObjNode ) 624 625 /************************************************************************* 626 |* 627 |* RscEnumerateObj :: WriteRcFile 628 |* 629 |* Beschreibung 630 |* Ersterstellung MM 09.12.91 631 |* Letzte Aenderung MM 09.12.91 632 |* 633 *************************************************************************/ 634 void RscEnumerateObj :: WriteRcFile( RscWriteRc & rMem, FILE * fOut ){ 635 // Definition der Struktur, aus denen die Resource aufgebaut ist 636 /* 637 struct RSHEADER_TYPE{ 638 sal_uInt32 nId; // Identifier der Resource 639 sal_uInt32 nRT; // Resource Typ 640 sal_uInt32 nGlobOff; // Globaler Offset 641 sal_uInt32 nLocalOff; // Lokaler Offset 642 } aHeader; 643 */ 644 645 sal_uInt32 nId = rMem.GetLong( 0 ); 646 sal_uInt32 nRT = rMem.GetLong( 4 ); 647 648 // Tabelle wird entsprechend gefuellt 649 pTypCont->PutTranslatorKey( (sal_uInt64(nRT) << 32) + sal_uInt64(nId) ); 650 651 if( nRT == RSC_VERSIONCONTROL ) 652 { // kommt immmer als letztes 653 sal_Int32 nCount = pTypCont->aIdTranslator.size(); 654 // groesse der Tabelle 655 sal_uInt32 nSize = (nCount * (sizeof(sal_uInt64)+sizeof(sal_Int32))) + sizeof(sal_Int32); 656 657 rMem.Put( nCount ); //Anzahl speichern 658 for( std::map< sal_uInt64, sal_uLong >::const_iterator it = 659 pTypCont->aIdTranslator.begin(); it != pTypCont->aIdTranslator.end(); ++it ) 660 { 661 // Schluessel schreiben 662 rMem.Put( it->first ); 663 // Objekt Id oder Position schreiben 664 rMem.Put( (sal_Int32)it->second ); 665 } 666 rMem.Put( nSize ); // Groesse hinten Speichern 667 } 668 669 //Dateioffset neu setzen 670 pTypCont->IncFilePos( rMem.Size() ); 671 672 673 //Position wurde vorher in Tabelle geschrieben 674 fwrite( rMem.GetBuffer(), rMem.Size(), 1, fOut ); 675 676 }; 677 678 class RscEnumerateRef 679 { 680 private: 681 RscTop * pRoot; 682 683 DECL_LINK( CallBackWriteRc, RscTop * ); 684 DECL_LINK( CallBackWriteSrc, RscTop * ); 685 DECL_LINK( CallBackWriteCxx, RscTop * ); 686 DECL_LINK( CallBackWriteHxx, RscTop * ); 687 DECL_LINK( CallBackWriteSyntax, RscTop * ); 688 DECL_LINK( CallBackWriteRcCtor, RscTop * ); 689 public: 690 RscEnumerateObj aEnumObj; 691 692 RscEnumerateRef( RscTypCont * pTC, RscTop * pR, 693 FILE * fOutput ) 694 { 695 aEnumObj.pTypCont = pTC; 696 aEnumObj.fOutput = fOutput; 697 pRoot = pR; 698 } 699 ERRTYPE WriteRc() 700 { 701 aEnumObj.aError.Clear(); 702 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteRc ) ); 703 return aEnumObj.aError; 704 }; 705 706 ERRTYPE WriteSrc( sal_uLong lFileKey ) 707 { 708 aEnumObj.lFileKey = lFileKey; 709 710 aEnumObj.aError.Clear(); 711 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteSrc ) ); 712 return aEnumObj.aError; 713 } 714 715 ERRTYPE WriteCxx( sal_uLong lFileKey ) 716 { 717 aEnumObj.lFileKey = lFileKey; 718 719 aEnumObj.aError.Clear(); 720 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteCxx ) ); 721 return aEnumObj.aError; 722 } 723 724 ERRTYPE WriteHxx( sal_uLong lFileKey ) 725 { 726 aEnumObj.lFileKey = lFileKey; 727 728 aEnumObj.aError.Clear(); 729 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteHxx ) ); 730 return aEnumObj.aError; 731 } 732 733 void WriteSyntax() 734 { 735 pRoot->EnumNodes( LINK( this, RscEnumerateRef, 736 CallBackWriteSyntax ) ); 737 } 738 739 void WriteRcCtor() 740 { 741 pRoot->EnumNodes( LINK( this, RscEnumerateRef, 742 CallBackWriteRcCtor ) ); 743 } 744 }; 745 746 /************************************************************************* 747 |* 748 |* RscRscEnumerateRef :: CallBack... 749 |* 750 |* Beschreibung 751 |* Ersterstellung MM 09.12.91 752 |* Letzte Aenderung MM 09.12.91 753 |* 754 *************************************************************************/ 755 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteRc, RscTop *, pRef ) 756 { 757 aEnumObj.WriteRc( pRef, pRef->GetObjNode() ); 758 return 0; 759 } 760 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteRc, RscTop *, pRef ) 761 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteSrc, RscTop *, pRef ) 762 { 763 aEnumObj.WriteSrc( pRef, pRef->GetObjNode() ); 764 return 0; 765 } 766 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteSrc, RscTop *, pRef ) 767 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteCxx, RscTop *, pRef ) 768 { 769 if( pRef->IsCodeWriteable() ) 770 aEnumObj.WriteCxx( pRef, pRef->GetObjNode() ); 771 return 0; 772 } 773 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteCxx, RscTop *, pRef ) 774 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteHxx, RscTop *, pRef ) 775 { 776 if( pRef->IsCodeWriteable() ) 777 aEnumObj.WriteHxx( pRef, pRef->GetObjNode() ); 778 return 0; 779 } 780 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteHxx, RscTop *, pRef ) 781 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteSyntax, RscTop *, pRef ) 782 { 783 pRef->WriteSyntaxHeader( aEnumObj.fOutput, aEnumObj.pTypCont ); 784 return 0; 785 } 786 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteSyntax, RscTop *, pRef ) 787 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteRcCtor, RscTop *, pRef ) 788 { 789 pRef->WriteRcCtor( aEnumObj.fOutput, aEnumObj.pTypCont ); 790 return 0; 791 } 792 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteRcCtor, RscTop *, pRef ) 793 794 /************************************************************************* 795 |* 796 |* RscTypCont :: WriteRc 797 |* 798 |* Beschreibung RES.DOC 799 |* Ersterstellung MM 22.03.90 800 |* Letzte Aenderung MM 22.07.91 801 |* 802 *************************************************************************/ 803 804 ERRTYPE RscTypCont::WriteRc( WriteRcContext& rContext ) 805 { 806 ERRTYPE aError; 807 RscEnumerateRef aEnumRef( this, pRoot, rContext.fOutput ); 808 809 aIdTranslator.clear(); 810 nFilePos = 0; 811 nPMId = RSCVERSION_ID +1; //mindestens einen groesser 812 813 aError = aEnumRef.WriteRc(); 814 815 // version control 816 RscWriteRc aMem( nByteOrder ); 817 aVersion.pClass->WriteRcHeader( aVersion, aMem, this, RscId( RSCVERSION_ID ), 0, sal_True ); 818 aEnumRef.aEnumObj.WriteRcFile( aMem, rContext.fOutput ); 819 820 return aError; 821 } 822 823 /************************************************************************* 824 |* 825 |* RscTypCont :: WriteSrc 826 |* 827 |* Beschreibung RES.DOC 828 |* Ersterstellung MM 22.03.90 829 |* Letzte Aenderung MM 27.06.90 830 |* 831 *************************************************************************/ 832 void RscTypCont :: WriteSrc( FILE * fOutput, sal_uLong nFileKey, 833 CharSet /*nCharSet*/, sal_Bool bName ) 834 { 835 RscFile * pFName; 836 RscEnumerateRef aEnumRef( this, pRoot, fOutput ); 837 838 unsigned char aUTF8BOM[3] = { 0xef, 0xbb, 0xbf }; 839 fwrite( aUTF8BOM, sizeof(unsigned char), sizeof(aUTF8BOM)/sizeof(aUTF8BOM[0]), fOutput ); 840 if( bName ) 841 { 842 WriteInc( fOutput, nFileKey ); 843 844 if( NOFILE_INDEX == nFileKey ) 845 { 846 pFName = aFileTab.First(); 847 while( pFName ){ 848 if( !pFName->IsIncFile() ) 849 pFName->aDefLst.WriteAll( fOutput ); 850 aEnumRef.WriteSrc( aFileTab.GetIndex( pFName ) ); 851 pFName = aFileTab.Next(); 852 }; 853 } 854 else 855 { 856 pFName = aFileTab.Get( nFileKey ); 857 if( pFName ){ 858 pFName->aDefLst.WriteAll( fOutput ); 859 aEnumRef.WriteSrc( nFileKey ); 860 } 861 } 862 } 863 else 864 { 865 RscId::SetNames( sal_False ); 866 if( NOFILE_INDEX == nFileKey ) 867 { 868 pFName = aFileTab.First(); 869 while( pFName ) 870 { 871 aEnumRef.WriteSrc( aFileTab.GetIndex( pFName ) ); 872 pFName = aFileTab.Next(); 873 }; 874 } 875 else 876 aEnumRef.WriteSrc( nFileKey ); 877 RscId::SetNames(); 878 }; 879 } 880 881 /************************************************************************* 882 |* 883 |* RscTypCont :: WriteHxx 884 |* 885 |* Beschreibung 886 |* Ersterstellung MM 30.05.91 887 |* Letzte Aenderung MM 30.05.91 888 |* 889 *************************************************************************/ 890 ERRTYPE RscTypCont :: WriteHxx( FILE * fOutput, sal_uLong nFileKey ) 891 { 892 fprintf( fOutput, "#include <tools/rc.hxx>\n" ); 893 fprintf( fOutput, "#include <tools/resid.hxx>\n" ); 894 fprintf( fOutput, "#include <vcl/accel.hxx>\n" ); 895 fprintf( fOutput, "#include <vcl/bitmap.hxx>\n" ); 896 fprintf( fOutput, "#include <vcl/button.hxx>\n" ); 897 fprintf( fOutput, "#include <tools/color.hxx>\n" ); 898 fprintf( fOutput, "#include <vcl/combobox.hxx>\n" ); 899 fprintf( fOutput, "#include <vcl/ctrl.hxx>\n" ); 900 fprintf( fOutput, "#include <vcl/dialog.hxx>\n" ); 901 fprintf( fOutput, "#include <vcl/edit.hxx>\n" ); 902 fprintf( fOutput, "#include <vcl/field.hxx>\n" ); 903 fprintf( fOutput, "#include <vcl/fixed.hxx>\n" ); 904 fprintf( fOutput, "#include <vcl/group.hxx>\n" ); 905 fprintf( fOutput, "#include <vcl/image.hxx>\n" ); 906 fprintf( fOutput, "#include <vcl/button.hxx>\n" ); 907 fprintf( fOutput, "#include <vcl/keycod.hxx>\n" ); 908 fprintf( fOutput, "#include <vcl/lstbox.hxx>\n" ); 909 fprintf( fOutput, "#include <vcl/mapmod.hxx>\n" ); 910 fprintf( fOutput, "#include <vcl/menu.hxx>\n" ); 911 fprintf( fOutput, "#include <vcl/menubtn.hxx>\n" ); 912 fprintf( fOutput, "#include <vcl/morebtn.hxx>\n" ); 913 fprintf( fOutput, "#include <vcl/msgbox.hxx>\n" ); 914 fprintf( fOutput, "#include <vcl/scrbar.hxx>\n" ); 915 fprintf( fOutput, "#include <vcl/spin.hxx>\n" ); 916 fprintf( fOutput, "#include <vcl/spinfld.hxx>\n" ); 917 fprintf( fOutput, "#include <vcl/splitwin.hxx>\n" ); 918 fprintf( fOutput, "#include <vcl/status.hxx>\n" ); 919 fprintf( fOutput, "#include <vcl/tabctrl.hxx>\n" ); 920 fprintf( fOutput, "#include <vcl/tabdlg.hxx>\n" ); 921 fprintf( fOutput, "#include <vcl/tabpage.hxx>\n" ); 922 fprintf( fOutput, "#include <vcl/toolbox.hxx>\n" ); 923 fprintf( fOutput, "#include <vcl/window.hxx>\n" ); 924 fprintf( fOutput, "#include <vcl/wrkwin.hxx>\n" ); 925 fprintf( fOutput, "#include <svtools/svmedit.hxx>\n" ); 926 927 RscEnumerateRef aEnumRef( this, pRoot, fOutput ); 928 ERRTYPE aError; 929 930 if( NOFILE_INDEX == nFileKey ) 931 { 932 RscFile * pFName; 933 934 pFName = aFileTab.First(); 935 while( pFName ) 936 { 937 aError = aEnumRef.WriteHxx( aFileTab.GetIndex( pFName ) ); 938 pFName = aFileTab.Next(); 939 }; 940 } 941 else 942 aError = aEnumRef.WriteHxx( nFileKey ); 943 944 return aError; 945 } 946 947 /************************************************************************* 948 |* 949 |* RscTypCont :: WriteCxx 950 |* 951 |* Beschreibung 952 |* Ersterstellung MM 30.05.91 953 |* Letzte Aenderung MM 30.05.91 954 |* 955 *************************************************************************/ 956 ERRTYPE RscTypCont::WriteCxx( FILE * fOutput, sal_uLong nFileKey, 957 const ByteString & rHxxName ) 958 { 959 RscEnumerateRef aEnumRef( this, pRoot, fOutput ); 960 ERRTYPE aError; 961 fprintf( fOutput, "#include <string.h>\n" ); 962 WriteInc( fOutput, nFileKey ); 963 if( rHxxName.Len() ) 964 fprintf( fOutput, "#include \"%s\"\n", rHxxName.GetBuffer() ); 965 fprintf( fOutput, "\n\n" ); 966 967 if( NOFILE_INDEX == nFileKey ) 968 { 969 RscFile * pFName; 970 971 pFName = aFileTab.First(); 972 while( pFName ) 973 { 974 aError = aEnumRef.WriteCxx( aFileTab.GetIndex( pFName ) ); 975 pFName = aFileTab.Next(); 976 }; 977 } 978 else 979 aError = aEnumRef.WriteCxx( nFileKey ); 980 981 return aError; 982 } 983 984 /************************************************************************* 985 |* 986 |* RscTypCont :: WriteSyntax 987 |* 988 |* Beschreibung 989 |* Ersterstellung MM 30.05.91 990 |* Letzte Aenderung MM 30.05.91 991 |* 992 *************************************************************************/ 993 void RscTypCont::WriteSyntax( FILE * fOutput ) 994 { 995 for( sal_uInt32 i = 0; i < aBaseLst.Count(); i++ ) 996 aBaseLst.GetObject( i )->WriteSyntaxHeader( fOutput, this ); 997 RscEnumerateRef aEnumRef( this, pRoot, fOutput ); 998 aEnumRef.WriteSyntax(); 999 } 1000 1001 //======================================================================= 1002 void RscTypCont::WriteRcCtor 1003 ( 1004 FILE * fOutput 1005 ) 1006 { 1007 RscEnumerateRef aEnumRef( this, pRoot, fOutput ); 1008 aEnumRef.WriteRcCtor(); 1009 } 1010 1011 /************************************************************************* 1012 |* 1013 |* RscTypCont :: Delete() 1014 |* 1015 |* Beschreibung 1016 |* Ersterstellung MM 09.12.91 1017 |* Letzte Aenderung MM 09.12.91 1018 |* 1019 *************************************************************************/ 1020 class RscDel 1021 { 1022 sal_uLong lFileKey; 1023 DECL_LINK( Delete, RscTop * ); 1024 public: 1025 RscDel( RscTop * pRoot, sal_uLong lKey ); 1026 }; 1027 1028 1029 inline RscDel::RscDel( RscTop * pRoot, sal_uLong lKey ) 1030 { 1031 lFileKey = lKey; 1032 pRoot->EnumNodes( LINK( this, RscDel, Delete ) ); 1033 } 1034 1035 IMPL_LINK_INLINE_START( RscDel, Delete, RscTop *, pNode ) 1036 { 1037 if( pNode->GetObjNode() ) 1038 pNode->pObjBiTree = pNode->GetObjNode()->DelObjNode( pNode, lFileKey ); 1039 return 0; 1040 } 1041 IMPL_LINK_INLINE_END( RscDel, Delete, RscTop *, pNode ) 1042 1043 void RscTypCont :: Delete( sal_uLong lFileKey ){ 1044 // Resourceinstanzen loeschen 1045 RscDel aDel( pRoot, lFileKey ); 1046 // Defines loeschen 1047 aFileTab.DeleteFileContext( lFileKey ); 1048 } 1049 1050 /************************************************************************* 1051 |* 1052 |* RscTypCont :: MakeConsistent() 1053 |* 1054 |* Beschreibung 1055 |* Ersterstellung MM 23.09.91 1056 |* Letzte Aenderung MM 23.09.91 1057 |* 1058 *************************************************************************/ 1059 sal_Bool IsInstConsistent( ObjNode * pObjNode, RscTop * pRscTop, 1060 RscInconsList * pList ) 1061 { 1062 sal_Bool bRet = sal_True; 1063 1064 if( pObjNode ){ 1065 RSCINST aTmpI; 1066 1067 if( ! IsInstConsistent( (ObjNode*)pObjNode->Left(), pRscTop, pList ) ) 1068 bRet = sal_False; 1069 1070 aTmpI.pClass = pRscTop; 1071 aTmpI.pData = pObjNode->GetRscObj(); 1072 if( ! aTmpI.pClass->IsConsistent( aTmpI, pList ) ) 1073 bRet = sal_False; 1074 1075 if( ! IsInstConsistent( (ObjNode*)pObjNode->Right(), pRscTop, pList ) ) 1076 bRet = sal_False; 1077 }; 1078 1079 return( bRet ); 1080 } 1081 1082 sal_Bool MakeConsistent( RscTop * pRscTop, RscInconsList * pList ) 1083 { 1084 sal_Bool bRet = sal_True; 1085 1086 if( pRscTop ){ 1087 if( ! ::MakeConsistent( (RscTop*)pRscTop->Left(), pList ) ) 1088 bRet = sal_False; 1089 1090 if( pRscTop->GetObjNode() ){ 1091 if( ! pRscTop->GetObjNode()->IsConsistent() ){ 1092 pRscTop->GetObjNode()->OrderTree(); 1093 if( ! pRscTop->GetObjNode()->IsConsistent( pList ) ) 1094 bRet = sal_False; 1095 } 1096 if( ! IsInstConsistent( pRscTop->GetObjNode(), pRscTop, pList ) ) 1097 bRet = sal_False; 1098 } 1099 1100 if( ! ::MakeConsistent( (RscTop*)pRscTop->Right(), pList ) ) 1101 bRet = sal_False; 1102 }; 1103 1104 return bRet; 1105 } 1106 1107 sal_Bool RscTypCont :: MakeConsistent( RscInconsList * pList ){ 1108 return( ::MakeConsistent( pRoot, pList ) ); 1109 } 1110 1111 sal_uInt32 RscTypCont::PutTranslatorKey( sal_uInt64 nKey ) 1112 { 1113 aIdTranslator[ nKey ] = nFilePos; 1114 return nPMId++; 1115 } 1116 1117