merge the formfield patch from ooo-build
[ooovba.git] / rsc / source / parser / rscdb.cxx
blob45b14b1bc929eb4031575c06c41994cd1031fb1d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rscdb.cxx,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_rsc.hxx"
33 /****************** I N C L U D E S **************************************/
34 // C and C++ Includes.
35 #include <ctype.h> // isdigit(), isalpha()
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
40 #include <tools/fsys.hxx>
41 #include <tools/rc.h>
42 #include <tools/isofallback.hxx>
43 #include <rtl/strbuf.hxx>
45 // Programmabhaengige Includes.
46 #include <rsctree.hxx>
47 #include <rsctop.hxx>
48 #include <rscmgr.hxx>
49 #include <rscdb.hxx>
50 #include <rscrsc.hxx>
52 using namespace rtl;
54 /*************************************************************************
56 |* RscTypCont :: RscTypCont
58 |* Beschreibung RES.DOC
59 |* Ersterstellung MM 22.03.90
60 |* Letzte Aenderung MM 27.06.90
62 *************************************************************************/
63 RscTypCont :: RscTypCont( RscError * pErrHdl,
64 RSCBYTEORDER_TYPE nOrder,
65 const ByteString & rSearchPath,
66 sal_uInt32 nFlagsP )
68 nSourceCharSet( RTL_TEXTENCODING_UTF8 ),
69 nByteOrder( nOrder ),
70 aSearchPath( rSearchPath ),
71 aBool( pHS->getID( "BOOL" ), RSC_NOTYPE ),
72 aShort( pHS->getID( "short" ), RSC_NOTYPE ),
73 aUShort( pHS->getID( "USHORT" ), RSC_NOTYPE ),
74 aLong( pHS->getID( "long" ), RSC_NOTYPE ),
75 aEnumLong( pHS->getID( "enum_long" ), RSC_NOTYPE ),
76 aIdUShort( pHS->getID( "IDUSHORT" ), RSC_NOTYPE ),
77 aIdNoZeroUShort( pHS->getID( "IDUSHORT" ), RSC_NOTYPE ),
78 aNoZeroShort( pHS->getID( "NoZeroShort" ), RSC_NOTYPE ),
79 a1to12Short( pHS->getID( "MonthShort" ), RSC_NOTYPE ),
80 a0to23Short( pHS->getID( "HourShort" ), RSC_NOTYPE ),
81 a1to31Short( pHS->getID( "DayShort" ), RSC_NOTYPE ),
82 a0to59Short( pHS->getID( "MinuteShort" ), RSC_NOTYPE ),
83 a0to99Short( pHS->getID( "_0to59Short" ), RSC_NOTYPE ),
84 a0to9999Short( pHS->getID( "YearShort" ), RSC_NOTYPE ),
85 aIdLong( pHS->getID( "IDLONG" ), RSC_NOTYPE ),
86 aString( pHS->getID( "Chars" ), RSC_NOTYPE ),
87 aWinBits( pHS->getID( "WinBits" ), RSC_NOTYPE ),
88 aLangType(),
89 aLangString( pHS->getID( "Lang_Chars" ), RSC_NOTYPE, &aString, &aLangType ),
90 aLangShort( pHS->getID( "Lang_short" ), RSC_NOTYPE, &aShort, &aLangType ),
91 nAcceleratorType( 0 ),
92 nFlags( nFlagsP )
94 nUniqueId = 256;
95 nPMId = RSC_VERSIONCONTROL +1; //mindestens einen groesser
96 pEH = pErrHdl;
97 Init();
100 static sal_uInt32 getLangIdAndShortenLocale( RscTypCont* pTypCont,
101 rtl::OString& rLang,
102 rtl::OString& rCountry,
103 rtl::OString& rVariant )
105 rtl::OStringBuffer aLangStr( 64 );
106 aLangStr.append( rLang.toAsciiLowerCase() );
107 if( rCountry.getLength() )
109 aLangStr.append( '-' );
110 aLangStr.append( rCountry.toAsciiUpperCase() );
112 if( rVariant.getLength() )
114 aLangStr.append( '-' );
115 aLangStr.append( rVariant );
117 rtl::OString aL( aLangStr.makeStringAndClear() );
118 sal_uInt32 nRet = GetLangId( aL );
119 if( nRet == 0 )
121 pTypCont->AddLanguage( aL );
122 nRet = GetLangId( aL );
124 if( rVariant.getLength() )
125 rVariant = rtl::OString();
126 else if( rCountry.getLength() )
127 rCountry = rtl::OString();
128 else
129 rLang = rtl::OString();
130 #if OSL_DEBUG_LEVEL > 1
131 fprintf( stderr, " %s (0x%hx)", aL.getStr(), nRet );
132 #endif
133 return nRet;
136 ByteString RscTypCont::ChangeLanguage( const ByteString& rNewLang )
138 ByteString aRet = aLanguage;
139 aLanguage = rNewLang;
141 rtl::OString aLang = aLanguage;
142 rtl::OString aLg, aCountry, aVariant;
143 sal_Int32 nIndex = 0;
144 aLg = aLang.getToken( 0, '-', nIndex );
145 if( nIndex != -1 )
146 aCountry = aLang.getToken( 0, '-', nIndex );
147 if( nIndex != -1 )
148 aVariant = aLang.copy( nIndex );
150 bool bAppendEnUsFallback =
151 ! (rNewLang.EqualsIgnoreCaseAscii( "en-US" ) ||
152 rNewLang.EqualsIgnoreCaseAscii( "x-no-translate" ) );
154 #if OSL_DEBUG_LEVEL > 1
155 fprintf( stderr, "RscTypCont::ChangeLanguage:" );
156 #endif
157 aLangFallbacks.clear();
161 aLangFallbacks.push_back(getLangIdAndShortenLocale( this, aLg, aCountry, aVariant ) );
162 } while( aLg.getLength() );
164 if( bAppendEnUsFallback )
166 aLg = "en";
167 aCountry = "US";
168 aVariant = rtl::OString();
169 aLangFallbacks.push_back( getLangIdAndShortenLocale( this, aLg, aCountry, aVariant ) );
172 #if OSL_DEBUG_LEVEL > 1
173 fprintf( stderr, "\n" );
174 #endif
176 return aRet;
179 Atom RscTypCont::AddLanguage( const char* pLang )
181 return aLangType.AddLanguage( pLang, aNmTb );
185 /*************************************************************************
187 |* RscTypCont :: ~RscTypCont
189 |* Beschreibung RES.DOC
190 |* Ersterstellung MM 22.03.90
191 |* Letzte Aenderung MM 27.06.90
193 *************************************************************************/
194 void DestroyNode( RscTop * pRscTop, ObjNode * pObjNode ){
195 if( pObjNode ){
196 DestroyNode( pRscTop, (ObjNode*)pObjNode->Left() );
197 DestroyNode( pRscTop, (ObjNode*)pObjNode->Right() );
199 if( pObjNode->GetRscObj() ){
200 pRscTop->Destroy( RSCINST( pRscTop, pObjNode->GetRscObj() ) );
201 rtl_freeMemory( pObjNode->GetRscObj() );
203 delete pObjNode;
207 void DestroySubTrees( RscTop * pRscTop ){
208 if( pRscTop ){
209 DestroySubTrees( (RscTop*)pRscTop->Left() );
211 DestroyNode( pRscTop, pRscTop->GetObjNode() );
213 DestroySubTrees( (RscTop*)pRscTop->Right() );
217 void DestroyTree( RscTop * pRscTop ){
218 if( pRscTop ){
219 DestroyTree( (RscTop*)pRscTop->Left() );
220 DestroyTree( (RscTop*)pRscTop->Right() );
222 delete pRscTop;
226 void Pre_dtorTree( RscTop * pRscTop ){
227 if( pRscTop ){
228 Pre_dtorTree( (RscTop*)pRscTop->Left() );
229 Pre_dtorTree( (RscTop*)pRscTop->Right() );
231 pRscTop->Pre_dtor();
235 RscTypCont :: ~RscTypCont(){
236 RscTop * pRscTmp;
237 RscSysEntry * pSysEntry;
239 // Alle Unterbaeume loeschen
240 aVersion.pClass->Destroy( aVersion );
241 rtl_freeMemory( aVersion.pData );
242 DestroySubTrees( pRoot );
244 // Alle Klassen noch gueltig, jeweilige Instanzen freigeben
245 // BasisTypen
246 pRscTmp = aBaseLst.First();
247 while( pRscTmp ){
248 pRscTmp->Pre_dtor();
249 pRscTmp = aBaseLst.Next();
251 aBool.Pre_dtor();
252 aShort.Pre_dtor();
253 aUShort.Pre_dtor();
254 aIdUShort.Pre_dtor();
255 aIdNoZeroUShort.Pre_dtor();
256 aNoZeroShort.Pre_dtor();
257 aIdLong.Pre_dtor();
258 aString.Pre_dtor();
259 aWinBits.Pre_dtor();
260 aVersion.pClass->Pre_dtor();
261 // Zusammengesetzte Typen
262 Pre_dtorTree( pRoot );
264 // Klassen zerstoeren
265 delete aVersion.pClass;
266 DestroyTree( pRoot );
268 while( NULL != (pRscTmp = aBaseLst.Remove()) ){
269 delete pRscTmp;
272 while( NULL != (pSysEntry = aSysLst.Remove()) ){
273 delete pSysEntry;
277 void RscTypCont::ClearSysNames()
279 RscSysEntry * pSysEntry;
280 while( NULL != (pSysEntry = aSysLst.Remove()) ){
281 delete pSysEntry;
285 //=======================================================================
286 RscTop * RscTypCont::SearchType( Atom nId )
287 /* [Beschreibung]
289 Sucht eine Basistyp nId;
292 if( nId == InvalidAtom )
293 return NULL;
295 #define ELSE_IF( a ) \
296 else if( a.GetId() == nId ) \
297 return &a; \
299 if( aBool.GetId() == nId )
300 return &aBool;
301 ELSE_IF( aShort )
302 ELSE_IF( aUShort )
303 ELSE_IF( aLong )
304 ELSE_IF( aEnumLong )
305 ELSE_IF( aIdUShort )
306 ELSE_IF( aIdNoZeroUShort )
307 ELSE_IF( aNoZeroShort )
308 ELSE_IF( a1to12Short )
309 ELSE_IF( a0to23Short )
310 ELSE_IF( a1to31Short )
311 ELSE_IF( a0to59Short )
312 ELSE_IF( a0to99Short )
313 ELSE_IF( a0to9999Short )
314 ELSE_IF( aIdLong )
315 ELSE_IF( aString )
316 ELSE_IF( aWinBits )
317 ELSE_IF( aLangType )
318 ELSE_IF( aLangString )
319 ELSE_IF( aLangShort )
321 RscTop * pEle = aBaseLst.First();
322 while( pEle )
324 if( pEle->GetId() == nId )
325 return pEle;
326 pEle = aBaseLst.Next();
328 return NULL;
331 /*************************************************************************
333 |* RscTypCont :: Search
335 |* Beschreibung RES.DOC
336 |* Ersterstellung MM 22.03.90
337 |* Letzte Aenderung MM 27.06.90
339 *************************************************************************/
340 RscTop * RscTypCont :: Search( Atom nRT ){
341 return( (RscTop *)pRoot->Search( nRT ) );
344 CLASS_DATA RscTypCont :: Search( Atom nRT, const RscId & rId ){
345 ObjNode *pObjNode;
346 RscTop *pRscTop;
348 if( NULL != (pRscTop = Search( nRT )) ){
349 if( NULL != (pObjNode = pRscTop->GetObjNode( rId )) ){
350 return( pObjNode->GetRscObj() );
353 return( (CLASS_DATA)0 );
356 /*************************************************************************
358 |* RscTypCont :: Delete()
360 |* Beschreibung
361 |* Ersterstellung MM 10.07.91
362 |* Letzte Aenderung MM 10.07.91
364 *************************************************************************/
365 void RscTypCont :: Delete( Atom nRT, const RscId & rId ){
366 ObjNode * pObjNode;
367 RscTop * pRscTop;
369 if( NULL != (pRscTop = Search( nRT )) ){
370 if( NULL != (pObjNode = pRscTop->GetObjNode()) ){
371 pObjNode = pObjNode->Search( rId );
373 if( pObjNode ){
374 //Objekt aus Baum entfernen
375 pRscTop->pObjBiTree =
376 (ObjNode *)pRscTop->pObjBiTree->Remove( pObjNode );
378 if( pObjNode->GetRscObj() ){
379 pRscTop->Destroy( RSCINST( pRscTop,
380 pObjNode->GetRscObj() ) );
381 rtl_freeMemory( pObjNode->GetRscObj() );
383 delete pObjNode;
389 /*************************************************************************
391 |* RscTypCont :: PutSysName()
393 |* Beschreibung RES.DOC
394 |* Ersterstellung MM 22.03.90
395 |* Letzte Aenderung MM 27.06.90
397 *************************************************************************/
398 sal_uInt32 RscTypCont :: PutSysName( sal_uInt32 nRscTyp, char * pFileName,
399 sal_uInt32 nConst, sal_uInt32 nId, BOOL bFirst )
401 RscSysEntry * pSysEntry;
402 BOOL bId1 = FALSE;
404 pSysEntry = aSysLst.First();
405 while( pSysEntry )
407 if( pSysEntry->nKey == 1 )
408 bId1 = TRUE;
409 if( !strcmp( pSysEntry->aFileName.GetBuffer(), pFileName ) )
410 if( pSysEntry->nRscTyp == nRscTyp
411 && pSysEntry->nTyp == nConst
412 && pSysEntry->nRefId == nId )
413 break;
414 pSysEntry = aSysLst.Next();
417 if ( !pSysEntry || (bFirst && !bId1) )
419 pSysEntry = new RscSysEntry;
420 pSysEntry->nKey = nUniqueId++;
421 pSysEntry->nRscTyp = nRscTyp;
422 pSysEntry->nTyp = nConst;
423 pSysEntry->nRefId = nId;
424 pSysEntry->aFileName = (const char*)pFileName;
425 if( bFirst && !bId1 )
427 pSysEntry->nKey = 1;
428 aSysLst.Insert( pSysEntry, (ULONG)0 );
430 else
431 aSysLst.Insert( pSysEntry, LIST_APPEND );
434 return pSysEntry->nKey;
437 /*************************************************************************
439 |* RscTypCont :: WriteInc
441 |* Beschreibung RES.DOC
442 |* Ersterstellung MM 21.06.90
443 |* Letzte Aenderung MM 21.06.90
445 *************************************************************************/
446 void RscTypCont :: WriteInc( FILE * fOutput, ULONG lFileKey )
448 RscFile * pFName;
450 if( NOFILE_INDEX == lFileKey )
452 pFName = aFileTab.First();
453 while( pFName )
455 if( pFName && pFName->IsIncFile() )
457 fprintf( fOutput, "#include " );
458 fprintf( fOutput, "\"%s\"\n",
459 pFName->aFileName.GetBuffer() );
461 pFName = aFileTab.Next();
464 else
466 RscDepend * pDep;
467 RscFile * pFile;
469 pFName = aFileTab.Get( lFileKey );
470 if( pFName )
472 pDep = pFName->First();
473 while( pDep )
475 if( pDep->GetFileKey() != lFileKey )
477 pFile = aFileTab.GetFile( pDep->GetFileKey() );
478 if( pFile )
480 fprintf( fOutput, "#include " );
481 fprintf( fOutput, "\"%s\"\n",
482 pFile->aFileName.GetBuffer() );
485 pDep = pFName->Next();
491 /*************************************************************************
493 |* RscTypCont :: Methoden die ueber all Knoten laufen
495 |* Beschreibung RES.DOC
496 |* Ersterstellung MM 22.03.90
497 |* Letzte Aenderung MM 09.12.91
499 *************************************************************************/
501 class RscEnumerateObj
503 friend class RscEnumerateRef;
504 private:
505 ERRTYPE aError; // Enthaelt den ersten Fehler
506 RscTypCont* pTypCont;
507 FILE * fOutput; // AusgabeDatei
508 ULONG lFileKey; // Welche src-Datei
509 RscTop * pClass;
511 DECL_LINK( CallBackWriteRc, ObjNode * );
512 DECL_LINK( CallBackWriteSrc, ObjNode * );
513 DECL_LINK( CallBackWriteCxx, ObjNode * );
514 DECL_LINK( CallBackWriteHxx, ObjNode * );
516 ERRTYPE WriteRc( RscTop * pCl, ObjNode * pRoot )
518 pClass = pCl;
519 if( pRoot )
520 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteRc ) );
521 return aError;
523 ERRTYPE WriteSrc( RscTop * pCl, ObjNode * pRoot ){
524 pClass = pCl;
525 if( pRoot )
526 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteSrc ) );
527 return aError;
529 ERRTYPE WriteCxx( RscTop * pCl, ObjNode * pRoot ){
530 pClass = pCl;
531 if( pRoot )
532 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteCxx ) );
533 return aError;
535 ERRTYPE WriteHxx( RscTop * pCl, ObjNode * pRoot ){
536 pClass = pCl;
537 if( pRoot )
538 pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteHxx ) );
539 return aError;
541 public:
542 void WriteRcFile( RscWriteRc & rMem, FILE * fOutput );
545 /*************************************************************************
547 |* RscEnumerateObj :: CallBackWriteRc
549 |* Beschreibung
550 |* Ersterstellung MM 09.12.91
551 |* Letzte Aenderung MM 09.12.91
553 *************************************************************************/
554 IMPL_LINK( RscEnumerateObj, CallBackWriteRc, ObjNode *, pObjNode )
556 RscWriteRc aMem( pTypCont->GetByteOrder() );
558 aError = pClass->WriteRcHeader( RSCINST( pClass, pObjNode->GetRscObj() ),
559 aMem, pTypCont,
560 pObjNode->GetRscId(), 0, TRUE );
561 if( aError.IsError() || aError.IsWarning() )
562 pTypCont->pEH->Error( aError, pClass, pObjNode->GetRscId() );
564 WriteRcFile( aMem, fOutput );
565 return 0;
568 /*************************************************************************
570 |* RscEnumerateObj :: CallBackWriteSrc
572 |* Beschreibung
573 |* Ersterstellung MM 09.12.91
574 |* Letzte Aenderung MM 09.12.91
576 *************************************************************************/
577 IMPL_LINK_INLINE_START( RscEnumerateObj, CallBackWriteSrc, ObjNode *, pObjNode )
579 if( pObjNode->GetFileKey() == lFileKey ){
580 pClass->WriteSrcHeader( RSCINST( pClass, pObjNode->GetRscObj() ),
581 fOutput, pTypCont, 0,
582 pObjNode->GetRscId(), "" );
583 fprintf( fOutput, ";\n" );
585 return 0;
587 IMPL_LINK_INLINE_END( RscEnumerateObj, CallBackWriteSrc, ObjNode *, pObjNode )
589 /*************************************************************************
591 |* RscEnumerateObj :: CallBackWriteCxx
593 |* Beschreibung
594 |* Ersterstellung MM 09.12.91
595 |* Letzte Aenderung MM 09.12.91
597 *************************************************************************/
598 IMPL_LINK_INLINE_START( RscEnumerateObj, CallBackWriteCxx, ObjNode *, pObjNode )
600 if( pClass->IsCodeWriteable() && pObjNode->GetFileKey() == lFileKey )
601 aError = pClass->WriteCxxHeader(
602 RSCINST( pClass, pObjNode->GetRscObj() ),
603 fOutput, pTypCont, pObjNode->GetRscId() );
604 return 0;
606 IMPL_LINK_INLINE_END( RscEnumerateObj, CallBackWriteCxx, ObjNode *, pObjNode )
608 /*************************************************************************
610 |* RscEnumerateObj :: CallBackWriteHxx
612 |* Beschreibung
613 |* Ersterstellung MM 09.12.91
614 |* Letzte Aenderung MM 09.12.91
616 *************************************************************************/
617 IMPL_LINK_INLINE_START( RscEnumerateObj, CallBackWriteHxx, ObjNode *, pObjNode )
619 if( pClass->IsCodeWriteable() && pObjNode->GetFileKey() == lFileKey )
620 aError = pClass->WriteHxxHeader(
621 RSCINST( pClass, pObjNode->GetRscObj() ),
622 fOutput, pTypCont, pObjNode->GetRscId() );
623 return 0;
625 IMPL_LINK_INLINE_END( RscEnumerateObj, CallBackWriteHxx, ObjNode *, pObjNode )
627 /*************************************************************************
629 |* RscEnumerateObj :: WriteRcFile
631 |* Beschreibung
632 |* Ersterstellung MM 09.12.91
633 |* Letzte Aenderung MM 09.12.91
635 *************************************************************************/
636 void RscEnumerateObj :: WriteRcFile( RscWriteRc & rMem, FILE * fOut ){
637 // Definition der Struktur, aus denen die Resource aufgebaut ist
639 struct RSHEADER_TYPE{
640 sal_uInt32 nId; // Identifier der Resource
641 sal_uInt32 nRT; // Resource Typ
642 sal_uInt32 nGlobOff; // Globaler Offset
643 sal_uInt32 nLocalOff; // Lokaler Offset
644 } aHeader;
647 sal_uInt32 nId = rMem.GetLong( 0 );
648 sal_uInt32 nRT = rMem.GetLong( 4 );
650 // Tabelle wird entsprechend gefuellt
651 pTypCont->PutTranslatorKey( (sal_uInt64(nRT) << 32) + sal_uInt64(nId) );
653 if( nRT == RSC_VERSIONCONTROL )
654 { // kommt immmer als letztes
655 INT32 nCount = pTypCont->aIdTranslator.size();
656 // groesse der Tabelle
657 UINT32 nSize = (nCount * (sizeof(sal_uInt64)+sizeof(INT32))) + sizeof(INT32);
659 rMem.Put( nCount ); //Anzahl speichern
660 for( std::map< sal_uInt64, ULONG >::const_iterator it =
661 pTypCont->aIdTranslator.begin(); it != pTypCont->aIdTranslator.end(); ++it )
663 // Schluessel schreiben
664 rMem.Put( it->first );
665 // Objekt Id oder Position schreiben
666 rMem.Put( (INT32)it->second );
668 rMem.Put( nSize ); // Groesse hinten Speichern
671 //Dateioffset neu setzen
672 pTypCont->IncFilePos( rMem.Size() );
675 //Position wurde vorher in Tabelle geschrieben
676 fwrite( rMem.GetBuffer(), rMem.Size(), 1, fOut );
680 class RscEnumerateRef
682 private:
683 RscTop * pRoot;
685 DECL_LINK( CallBackWriteRc, RscTop * );
686 DECL_LINK( CallBackWriteSrc, RscTop * );
687 DECL_LINK( CallBackWriteCxx, RscTop * );
688 DECL_LINK( CallBackWriteHxx, RscTop * );
689 DECL_LINK( CallBackWriteSyntax, RscTop * );
690 DECL_LINK( CallBackWriteRcCtor, RscTop * );
691 public:
692 RscEnumerateObj aEnumObj;
694 RscEnumerateRef( RscTypCont * pTC, RscTop * pR,
695 FILE * fOutput )
697 aEnumObj.pTypCont = pTC;
698 aEnumObj.fOutput = fOutput;
699 pRoot = pR;
701 ERRTYPE WriteRc()
703 aEnumObj.aError.Clear();
704 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteRc ) );
705 return aEnumObj.aError;
708 ERRTYPE WriteSrc( ULONG lFileKey )
710 aEnumObj.lFileKey = lFileKey;
712 aEnumObj.aError.Clear();
713 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteSrc ) );
714 return aEnumObj.aError;
717 ERRTYPE WriteCxx( ULONG lFileKey )
719 aEnumObj.lFileKey = lFileKey;
721 aEnumObj.aError.Clear();
722 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteCxx ) );
723 return aEnumObj.aError;
726 ERRTYPE WriteHxx( ULONG lFileKey )
728 aEnumObj.lFileKey = lFileKey;
730 aEnumObj.aError.Clear();
731 pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteHxx ) );
732 return aEnumObj.aError;
735 void WriteSyntax()
737 pRoot->EnumNodes( LINK( this, RscEnumerateRef,
738 CallBackWriteSyntax ) );
741 void WriteRcCtor()
743 pRoot->EnumNodes( LINK( this, RscEnumerateRef,
744 CallBackWriteRcCtor ) );
748 /*************************************************************************
750 |* RscRscEnumerateRef :: CallBack...
752 |* Beschreibung
753 |* Ersterstellung MM 09.12.91
754 |* Letzte Aenderung MM 09.12.91
756 *************************************************************************/
757 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteRc, RscTop *, pRef )
759 aEnumObj.WriteRc( pRef, pRef->GetObjNode() );
760 return 0;
762 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteRc, RscTop *, pRef )
763 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteSrc, RscTop *, pRef )
765 aEnumObj.WriteSrc( pRef, pRef->GetObjNode() );
766 return 0;
768 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteSrc, RscTop *, pRef )
769 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteCxx, RscTop *, pRef )
771 if( pRef->IsCodeWriteable() )
772 aEnumObj.WriteCxx( pRef, pRef->GetObjNode() );
773 return 0;
775 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteCxx, RscTop *, pRef )
776 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteHxx, RscTop *, pRef )
778 if( pRef->IsCodeWriteable() )
779 aEnumObj.WriteHxx( pRef, pRef->GetObjNode() );
780 return 0;
782 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteHxx, RscTop *, pRef )
783 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteSyntax, RscTop *, pRef )
785 pRef->WriteSyntaxHeader( aEnumObj.fOutput, aEnumObj.pTypCont );
786 return 0;
788 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteSyntax, RscTop *, pRef )
789 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteRcCtor, RscTop *, pRef )
791 pRef->WriteRcCtor( aEnumObj.fOutput, aEnumObj.pTypCont );
792 return 0;
794 IMPL_LINK_INLINE_END( RscEnumerateRef, CallBackWriteRcCtor, RscTop *, pRef )
796 /*************************************************************************
798 |* RscTypCont :: WriteRc
800 |* Beschreibung RES.DOC
801 |* Ersterstellung MM 22.03.90
802 |* Letzte Aenderung MM 22.07.91
804 *************************************************************************/
806 ERRTYPE RscTypCont::WriteRc( WriteRcContext& rContext )
808 ERRTYPE aError;
809 RscEnumerateRef aEnumRef( this, pRoot, rContext.fOutput );
811 aIdTranslator.clear();
812 nFilePos = 0;
813 nPMId = RSCVERSION_ID +1; //mindestens einen groesser
815 aError = aEnumRef.WriteRc();
817 // version control
818 RscWriteRc aMem( nByteOrder );
819 aVersion.pClass->WriteRcHeader( aVersion, aMem, this, RscId( RSCVERSION_ID ), 0, TRUE );
820 aEnumRef.aEnumObj.WriteRcFile( aMem, rContext.fOutput );
822 return aError;
825 /*************************************************************************
827 |* RscTypCont :: WriteSrc
829 |* Beschreibung RES.DOC
830 |* Ersterstellung MM 22.03.90
831 |* Letzte Aenderung MM 27.06.90
833 *************************************************************************/
834 void RscTypCont :: WriteSrc( FILE * fOutput, ULONG nFileKey,
835 CharSet /*nCharSet*/, BOOL bName )
837 RscFile * pFName;
838 RscEnumerateRef aEnumRef( this, pRoot, fOutput );
840 unsigned char aUTF8BOM[3] = { 0xef, 0xbb, 0xbf };
841 fwrite( aUTF8BOM, sizeof(unsigned char), sizeof(aUTF8BOM)/sizeof(aUTF8BOM[0]), fOutput );
842 if( bName )
844 WriteInc( fOutput, nFileKey );
846 if( NOFILE_INDEX == nFileKey )
848 pFName = aFileTab.First();
849 while( pFName ){
850 if( !pFName->IsIncFile() )
851 pFName->aDefLst.WriteAll( fOutput );
852 aEnumRef.WriteSrc( aFileTab.GetIndex( pFName ) );
853 pFName = aFileTab.Next();
856 else
858 pFName = aFileTab.Get( nFileKey );
859 if( pFName ){
860 pFName->aDefLst.WriteAll( fOutput );
861 aEnumRef.WriteSrc( nFileKey );
865 else
867 RscId::SetNames( FALSE );
868 if( NOFILE_INDEX == nFileKey )
870 pFName = aFileTab.First();
871 while( pFName )
873 aEnumRef.WriteSrc( aFileTab.GetIndex( pFName ) );
874 pFName = aFileTab.Next();
877 else
878 aEnumRef.WriteSrc( nFileKey );
879 RscId::SetNames();
883 /*************************************************************************
885 |* RscTypCont :: WriteHxx
887 |* Beschreibung
888 |* Ersterstellung MM 30.05.91
889 |* Letzte Aenderung MM 30.05.91
891 *************************************************************************/
892 ERRTYPE RscTypCont :: WriteHxx( FILE * fOutput, ULONG nFileKey )
894 fprintf( fOutput, "#include <tools/rc.hxx>\n" );
895 fprintf( fOutput, "#include <tools/resid.hxx>\n" );
896 fprintf( fOutput, "#include <vcl/accel.hxx>\n" );
897 fprintf( fOutput, "#include <vcl/bitmap.hxx>\n" );
898 fprintf( fOutput, "#include <vcl/button.hxx>\n" );
899 fprintf( fOutput, "#include <tools/color.hxx>\n" );
900 fprintf( fOutput, "#include <vcl/combobox.hxx>\n" );
901 fprintf( fOutput, "#include <vcl/ctrl.hxx>\n" );
902 fprintf( fOutput, "#include <vcl/dialog.hxx>\n" );
903 fprintf( fOutput, "#include <vcl/edit.hxx>\n" );
904 fprintf( fOutput, "#include <vcl/field.hxx>\n" );
905 fprintf( fOutput, "#include <vcl/fixed.hxx>\n" );
906 fprintf( fOutput, "#include <vcl/group.hxx>\n" );
907 fprintf( fOutput, "#include <vcl/image.hxx>\n" );
908 fprintf( fOutput, "#include <vcl/imagebtn.hxx>\n" );
909 fprintf( fOutput, "#include <vcl/keycod.hxx>\n" );
910 fprintf( fOutput, "#include <vcl/lstbox.hxx>\n" );
911 fprintf( fOutput, "#include <vcl/mapmod.hxx>\n" );
912 fprintf( fOutput, "#include <vcl/menu.hxx>\n" );
913 fprintf( fOutput, "#include <vcl/menubtn.hxx>\n" );
914 fprintf( fOutput, "#include <vcl/morebtn.hxx>\n" );
915 fprintf( fOutput, "#include <vcl/msgbox.hxx>\n" );
916 fprintf( fOutput, "#include <vcl/scrbar.hxx>\n" );
917 fprintf( fOutput, "#include <vcl/spin.hxx>\n" );
918 fprintf( fOutput, "#include <vcl/spinfld.hxx>\n" );
919 fprintf( fOutput, "#include <vcl/splitwin.hxx>\n" );
920 fprintf( fOutput, "#include <vcl/status.hxx>\n" );
921 fprintf( fOutput, "#include <vcl/tabctrl.hxx>\n" );
922 fprintf( fOutput, "#include <vcl/tabdlg.hxx>\n" );
923 fprintf( fOutput, "#include <vcl/tabpage.hxx>\n" );
924 fprintf( fOutput, "#include <vcl/toolbox.hxx>\n" );
925 fprintf( fOutput, "#include <vcl/window.hxx>\n" );
926 fprintf( fOutput, "#include <vcl/wrkwin.hxx>\n" );
927 fprintf( fOutput, "#include <svtools/svmedit.hxx>\n" );
929 RscEnumerateRef aEnumRef( this, pRoot, fOutput );
930 ERRTYPE aError;
932 if( NOFILE_INDEX == nFileKey )
934 RscFile * pFName;
936 pFName = aFileTab.First();
937 while( pFName )
939 aError = aEnumRef.WriteHxx( aFileTab.GetIndex( pFName ) );
940 pFName = aFileTab.Next();
943 else
944 aError = aEnumRef.WriteHxx( nFileKey );
946 return aError;
949 /*************************************************************************
951 |* RscTypCont :: WriteCxx
953 |* Beschreibung
954 |* Ersterstellung MM 30.05.91
955 |* Letzte Aenderung MM 30.05.91
957 *************************************************************************/
958 ERRTYPE RscTypCont::WriteCxx( FILE * fOutput, ULONG nFileKey,
959 const ByteString & rHxxName )
961 RscEnumerateRef aEnumRef( this, pRoot, fOutput );
962 ERRTYPE aError;
963 fprintf( fOutput, "#include <string.h>\n" );
964 WriteInc( fOutput, nFileKey );
965 if( rHxxName.Len() )
966 fprintf( fOutput, "#include \"%s\"\n", rHxxName.GetBuffer() );
967 fprintf( fOutput, "\n\n" );
969 if( NOFILE_INDEX == nFileKey )
971 RscFile * pFName;
973 pFName = aFileTab.First();
974 while( pFName )
976 aError = aEnumRef.WriteCxx( aFileTab.GetIndex( pFName ) );
977 pFName = aFileTab.Next();
980 else
981 aError = aEnumRef.WriteCxx( nFileKey );
983 return aError;
986 /*************************************************************************
988 |* RscTypCont :: WriteSyntax
990 |* Beschreibung
991 |* Ersterstellung MM 30.05.91
992 |* Letzte Aenderung MM 30.05.91
994 *************************************************************************/
995 void RscTypCont::WriteSyntax( FILE * fOutput )
997 for( sal_uInt32 i = 0; i < aBaseLst.Count(); i++ )
998 aBaseLst.GetObject( i )->WriteSyntaxHeader( fOutput, this );
999 RscEnumerateRef aEnumRef( this, pRoot, fOutput );
1000 aEnumRef.WriteSyntax();
1003 //=======================================================================
1004 void RscTypCont::WriteRcCtor
1006 FILE * fOutput
1009 RscEnumerateRef aEnumRef( this, pRoot, fOutput );
1010 aEnumRef.WriteRcCtor();
1013 /*************************************************************************
1015 |* RscTypCont :: Delete()
1017 |* Beschreibung
1018 |* Ersterstellung MM 09.12.91
1019 |* Letzte Aenderung MM 09.12.91
1021 *************************************************************************/
1022 class RscDel
1024 ULONG lFileKey;
1025 DECL_LINK( Delete, RscTop * );
1026 public:
1027 RscDel( RscTop * pRoot, ULONG lKey );
1031 inline RscDel::RscDel( RscTop * pRoot, ULONG lKey )
1033 lFileKey = lKey;
1034 pRoot->EnumNodes( LINK( this, RscDel, Delete ) );
1037 IMPL_LINK_INLINE_START( RscDel, Delete, RscTop *, pNode )
1039 if( pNode->GetObjNode() )
1040 pNode->pObjBiTree = pNode->GetObjNode()->DelObjNode( pNode, lFileKey );
1041 return 0;
1043 IMPL_LINK_INLINE_END( RscDel, Delete, RscTop *, pNode )
1045 void RscTypCont :: Delete( ULONG lFileKey ){
1046 // Resourceinstanzen loeschen
1047 RscDel aDel( pRoot, lFileKey );
1048 // Defines loeschen
1049 aFileTab.DeleteFileContext( lFileKey );
1052 /*************************************************************************
1054 |* RscTypCont :: MakeConsistent()
1056 |* Beschreibung
1057 |* Ersterstellung MM 23.09.91
1058 |* Letzte Aenderung MM 23.09.91
1060 *************************************************************************/
1061 BOOL IsInstConsistent( ObjNode * pObjNode, RscTop * pRscTop,
1062 RscInconsList * pList )
1064 BOOL bRet = TRUE;
1066 if( pObjNode ){
1067 RSCINST aTmpI;
1069 if( ! IsInstConsistent( (ObjNode*)pObjNode->Left(), pRscTop, pList ) )
1070 bRet = FALSE;
1072 aTmpI.pClass = pRscTop;
1073 aTmpI.pData = pObjNode->GetRscObj();
1074 if( ! aTmpI.pClass->IsConsistent( aTmpI, pList ) )
1075 bRet = FALSE;
1077 if( ! IsInstConsistent( (ObjNode*)pObjNode->Right(), pRscTop, pList ) )
1078 bRet = FALSE;
1081 return( bRet );
1084 BOOL MakeConsistent( RscTop * pRscTop, RscInconsList * pList )
1086 BOOL bRet = TRUE;
1088 if( pRscTop ){
1089 if( ! ::MakeConsistent( (RscTop*)pRscTop->Left(), pList ) )
1090 bRet = FALSE;
1092 if( pRscTop->GetObjNode() ){
1093 if( ! pRscTop->GetObjNode()->IsConsistent() ){
1094 pRscTop->GetObjNode()->OrderTree();
1095 if( ! pRscTop->GetObjNode()->IsConsistent( pList ) )
1096 bRet = FALSE;
1098 if( ! IsInstConsistent( pRscTop->GetObjNode(), pRscTop, pList ) )
1099 bRet = FALSE;
1102 if( ! ::MakeConsistent( (RscTop*)pRscTop->Right(), pList ) )
1103 bRet = FALSE;
1106 return bRet;
1109 BOOL RscTypCont :: MakeConsistent( RscInconsList * pList ){
1110 return( ::MakeConsistent( pRoot, pList ) );
1113 sal_uInt32 RscTypCont::PutTranslatorKey( sal_uInt64 nKey )
1115 aIdTranslator[ nKey ] = nFilePos;
1116 return nPMId++;