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