xref: /trunk/main/rsc/source/parser/rscdb.cxx (revision 24c56ab9)
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 *************************************************************************/
RscTypCont(RscError * pErrHdl,RSCBYTEORDER_TYPE nOrder,const ByteString & rSearchPath,sal_uInt32 nFlagsP)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 
getLangIdAndShortenLocale(RscTypCont * pTypCont,rtl::OString & rLang,rtl::OString & rCountry,rtl::OString & rVariant)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.getStr() );
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 
ChangeLanguage(const ByteString & rNewLang)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 
AddLanguage(const char * pLang)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 *************************************************************************/
DestroyNode(RscTop * pRscTop,ObjNode * pObjNode)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 
DestroySubTrees(RscTop * pRscTop)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 
DestroyTree(RscTop * pRscTop)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 
Pre_dtorTree(RscTop * pRscTop)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 
~RscTypCont()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 
ClearSysNames()271 void RscTypCont::ClearSysNames()
272 {
273 	RscSysEntry   * pSysEntry;
274 	while( NULL != (pSysEntry = aSysLst.Remove()) ){
275 		delete pSysEntry;
276 	};
277 }
278 
279 //=======================================================================
SearchType(Atom nId)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 *************************************************************************/
Search(Atom nRT)334 RscTop * RscTypCont :: Search( Atom nRT ){
335 	return( (RscTop *)pRoot->Search( nRT ) );
336 }
337 
Search(Atom nRT,const RscId & rId)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 *************************************************************************/
Delete(Atom nRT,const RscId & rId)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 *************************************************************************/
PutSysName(sal_uInt32 nRscTyp,char * pFileName,sal_uInt32 nConst,sal_uInt32 nId,sal_Bool bFirst)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 *************************************************************************/
WriteInc(FILE * fOutput,sal_uLong lFileKey)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 
WriteRc(RscTop * pCl,ObjNode * pRoot)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 	}
WriteSrc(RscTop * pCl,ObjNode * pRoot)517 	ERRTYPE WriteSrc( RscTop * pCl, ObjNode * pRoot ){
518 		pClass = pCl;
519 		if( pRoot )
520 			pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteSrc ) );
521 		return aError;
522 	}
WriteCxx(RscTop * pCl,ObjNode * pRoot)523 	ERRTYPE WriteCxx( RscTop * pCl, ObjNode * pRoot ){
524 		pClass = pCl;
525 		if( pRoot )
526 			pRoot->EnumNodes( LINK( this, RscEnumerateObj, CallBackWriteCxx ) );
527 		return aError;
528 	}
WriteHxx(RscTop * pCl,ObjNode * pRoot)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 *************************************************************************/
IMPL_LINK(RscEnumerateObj,CallBackWriteRc,ObjNode *,pObjNode)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 *************************************************************************/
IMPL_LINK_INLINE_START(RscEnumerateObj,CallBackWriteSrc,ObjNode *,pObjNode)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 }
IMPL_LINK_INLINE_END(RscEnumerateObj,CallBackWriteSrc,ObjNode *,pObjNode)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 }
IMPL_LINK_INLINE_END(RscEnumerateObj,CallBackWriteCxx,ObjNode *,pObjNode)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 }
IMPL_LINK_INLINE_END(RscEnumerateObj,CallBackWriteHxx,ObjNode *,pObjNode)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 
RscEnumerateRef(RscTypCont * pTC,RscTop * pR,FILE * fOutput)688 			RscEnumerateRef( RscTypCont * pTC, RscTop * pR,
689 							 FILE * fOutput )
690 			{
691 				aEnumObj.pTypCont = pTC;
692 				aEnumObj.fOutput  = fOutput;
693 				pRoot			  = pR;
694 			}
WriteRc()695 	ERRTYPE WriteRc()
696 	{
697 		aEnumObj.aError.Clear();
698 		pRoot->EnumNodes( LINK( this, RscEnumerateRef, CallBackWriteRc ) );
699 		return aEnumObj.aError;
700 	};
701 
WriteSrc(sal_uLong lFileKey)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 
WriteCxx(sal_uLong lFileKey)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 
WriteHxx(sal_uLong lFileKey)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 
WriteSyntax()729 	void	WriteSyntax()
730 			{
731 				pRoot->EnumNodes( LINK( this, RscEnumerateRef,
732 										CallBackWriteSyntax ) );
733 			}
734 
WriteRcCtor()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 *************************************************************************/
IMPL_LINK_INLINE_START(RscEnumerateRef,CallBackWriteRc,RscTop *,pRef)751 IMPL_LINK_INLINE_START( RscEnumerateRef, CallBackWriteRc, RscTop *, pRef )
752 {
753 	aEnumObj.WriteRc( pRef, pRef->GetObjNode() );
754 	return 0;
755 }
IMPL_LINK_INLINE_END(RscEnumerateRef,CallBackWriteRc,RscTop *,pRef)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 }
IMPL_LINK_INLINE_END(RscEnumerateRef,CallBackWriteSrc,RscTop *,pRef)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 }
IMPL_LINK_INLINE_END(RscEnumerateRef,CallBackWriteCxx,RscTop *,pRef)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 }
IMPL_LINK_INLINE_END(RscEnumerateRef,CallBackWriteHxx,RscTop *,pRef)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 }
IMPL_LINK_INLINE_END(RscEnumerateRef,CallBackWriteSyntax,RscTop *,pRef)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 }
IMPL_LINK_INLINE_END(RscEnumerateRef,CallBackWriteRcCtor,RscTop *,pRef)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 *************************************************************************/
WriteSrc(FILE * fOutput,sal_uLong nFileKey,CharSet,sal_Bool bName)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 *************************************************************************/
WriteHxx(FILE * fOutput,sal_uLong nFileKey)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 *************************************************************************/
WriteCxx(FILE * fOutput,sal_uLong nFileKey,const ByteString & rHxxName)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 *************************************************************************/
WriteSyntax(FILE * fOutput)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 //=======================================================================
WriteRcCtor(FILE * fOutput)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 
RscDel(RscTop * pRoot,sal_uLong lKey)1025 inline RscDel::RscDel( RscTop * pRoot, sal_uLong lKey )
1026 {
1027 	lFileKey = lKey;
1028 	pRoot->EnumNodes( LINK( this, RscDel, Delete ) );
1029 }
1030 
IMPL_LINK_INLINE_START(RscDel,Delete,RscTop *,pNode)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 }
IMPL_LINK_INLINE_END(RscDel,Delete,RscTop *,pNode)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 *************************************************************************/
IsInstConsistent(ObjNode * pObjNode,RscTop * pRscTop,RscInconsList * pList)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 
MakeConsistent(RscTop * pRscTop,RscInconsList * pList)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 
MakeConsistent(RscInconsList * pList)1103 sal_Bool RscTypCont :: MakeConsistent( RscInconsList * pList ){
1104 	return( ::MakeConsistent( pRoot, pList ) );
1105 }
1106 
PutTranslatorKey(sal_uInt64 nKey)1107 sal_uInt32 RscTypCont::PutTranslatorKey( sal_uInt64 nKey )
1108 {
1109     aIdTranslator[ nKey ] = nFilePos;
1110 	return nPMId++;
1111 }
1112 
1113