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