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