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 :
21 : // Programmuebergreifende Includes.
22 : #include <rscdef.hxx>
23 :
24 : bool RscId::bNames = true;
25 :
26 722 : void RscId::SetNames( bool bSet )
27 : {
28 722 : bNames = bSet;
29 722 : }
30 :
31 2936585 : sal_Int32 RscId::GetNumber() const
32 : {
33 : sal_Int32 lVal;
34 2936585 : aExp.Evaluate( &lVal );
35 2936585 : return lVal;
36 : }
37 :
38 14826 : void RscId::Create( const RscExpType & rExpType )
39 : {
40 14826 : aExp = rExpType;
41 14826 : if( aExp.IsDefinition() )
42 0 : aExp.aExp.pDef->IncRef();
43 14826 : else if( aExp.IsExpression() )
44 : {
45 : sal_Int32 lValue;
46 :
47 0 : aExp.Evaluate( &lValue );
48 0 : aExp.SetLong( lValue );
49 : }
50 14826 : }
51 :
52 583090 : void RscId::Destroy()
53 : {
54 583090 : if( aExp.IsDefinition() )
55 0 : aExp.aExp.pDef->DecRef();
56 583090 : aExp.cType = RSCEXP_NOTHING;
57 583090 : }
58 :
59 18992 : RscId::RscId( const RscId& rRscId )
60 : {
61 18992 : aExp = rRscId.aExp;
62 18992 : if( aExp.IsDefinition() )
63 0 : aExp.aExp.pDef->IncRef();
64 18992 : }
65 :
66 0 : RscId::RscId( RscDefine * pDef )
67 : {
68 : RscExpType aExpType;
69 :
70 0 : aExpType.aExp.pDef = pDef;
71 0 : aExpType.cType = RSCEXP_DEF;
72 0 : aExpType.cUnused = false;
73 0 : Create( aExpType );
74 0 : }
75 :
76 122802 : RscId& RscId::operator = ( const RscId& rRscId )
77 : {
78 122802 : if( rRscId.aExp.IsDefinition() )
79 0 : rRscId.aExp.aExp.pDef->IncRef();
80 122802 : Destroy();
81 122802 : aExp = rRscId.aExp;
82 122802 : return *this;
83 : }
84 :
85 1168364 : bool RscId::operator == ( const RscId& rRscId ) const
86 : {
87 1168364 : return GetNumber() == rRscId.GetNumber();
88 : }
89 :
90 0 : bool RscId::operator < ( const RscId& rRscId ) const
91 : {
92 0 : return GetNumber() < rRscId.GetNumber();
93 : }
94 :
95 0 : bool RscId::operator > ( const RscId& rRscId ) const
96 : {
97 0 : return GetNumber() > rRscId.GetNumber();
98 : }
99 :
100 570483 : RscId::operator sal_Int32() const
101 : {
102 570483 : return GetNumber();
103 : }
104 :
105 24815 : OString RscId::GetName() const
106 : {
107 24815 : OStringBuffer aStr;
108 :
109 24815 : if ( !aExp.IsNothing() )
110 : {
111 20238 : if( bNames )
112 0 : aExp.AppendMacro(aStr);
113 : else
114 20238 : aStr.append(GetNumber());
115 : }
116 :
117 24815 : return aStr.makeStringAndClear();
118 : }
119 :
120 0 : RscDefine::RscDefine( sal_uLong lKey, const OString& rDefName, sal_Int32 lDefId )
121 0 : : StringNode( rDefName )
122 : {
123 0 : nRefCount = 0;
124 0 : lFileKey = lKey;
125 0 : lId = lDefId;
126 0 : pExp = NULL;
127 0 : }
128 :
129 0 : RscDefine::RscDefine( sal_uLong lKey, const OString& rDefName,
130 : RscExpression * pExpression )
131 : : StringNode( rDefName )
132 0 : , lId(0)
133 : {
134 0 : nRefCount = 0;
135 0 : lFileKey = lKey;
136 0 : pExpression->Evaluate( &lId );
137 0 : pExp = pExpression;
138 0 : }
139 :
140 0 : RscDefine::~RscDefine()
141 : {
142 0 : delete pExp;
143 0 : if( nRefCount )
144 0 : RscExit( 14 );
145 0 : }
146 :
147 0 : void RscDefine::DecRef()
148 : {
149 0 : nRefCount--;
150 0 : if( 0 == nRefCount )
151 : {
152 0 : delete this;
153 : }
154 0 : }
155 :
156 0 : void RscDefine::DefineToNumber()
157 : {
158 0 : if( pExp )
159 0 : delete pExp;
160 0 : pExp = NULL;
161 0 : SetName(OString::number(lId));
162 0 : }
163 :
164 0 : bool RscDefine::Evaluate()
165 : {
166 0 : bool bRet = true;
167 :
168 0 : if( pExp )
169 0 : bRet = !pExp->Evaluate( &lId );
170 :
171 0 : return bRet;
172 : }
173 :
174 0 : RscDefine * RscDefine::Search( const char * pStr )
175 : {
176 0 : return static_cast<RscDefine *>(StringNode::Search( pStr ));
177 : }
178 :
179 0 : OString RscDefine::GetMacro()
180 : {
181 0 : if( pExp )
182 0 : return pExp->GetMacro();
183 0 : return OString::number(lId);
184 : }
185 :
186 0 : RscDefine * RscDefineList::New( sal_uLong lFileKey, const OString& rDefName,
187 : sal_Int32 lDefId, size_t lPos )
188 : {
189 : RscDefine * pDef;
190 :
191 0 : pDef = new RscDefine( lFileKey, rDefName, lDefId );
192 0 : pDef->IncRef();
193 0 : if ( lPos < maList.size() )
194 : {
195 0 : RscSubDefList::iterator it = maList.begin();
196 0 : ::std::advance( it, lPos );
197 0 : maList.insert( it, pDef );
198 : }
199 : else
200 : {
201 0 : maList.push_back( pDef );
202 : }
203 0 : return pDef;
204 : }
205 :
206 0 : RscDefine * RscDefineList::New( sal_uLong lFileKey, const OString& rDefName,
207 : RscExpression * pExpression, size_t lPos )
208 : {
209 : RscDefine * pDef;
210 :
211 0 : pDef = new RscDefine( lFileKey, rDefName, pExpression );
212 0 : pDef->IncRef();
213 0 : if ( lPos < maList.size() )
214 : {
215 0 : RscSubDefList::iterator it = maList.begin();
216 0 : ::std::advance( it, lPos );
217 0 : maList.insert( it, pDef );
218 : }
219 : else
220 : {
221 0 : maList.push_back( pDef );
222 : }
223 0 : return pDef;
224 : }
225 :
226 835 : bool RscDefineList::Remove()
227 : {
228 835 : if ( maList.empty() )
229 835 : return false;
230 :
231 0 : maList[ 0 ]->DefineToNumber();
232 0 : maList[ 0 ]->DecRef();
233 0 : maList.erase( maList.begin() );
234 0 : return true;
235 : }
236 :
237 0 : void RscDefineList::WriteAll( FILE * fOutput )
238 : {
239 0 : for ( size_t i = 0, n = maList.size(); i < n; ++i )
240 : {
241 0 : RscDefine* pDefEle = maList[ i ];
242 : fprintf( fOutput, "#define %s %s\n",
243 : pDefEle->GetName().getStr(),
244 : pDefEle->GetMacro().getStr()
245 0 : );
246 : }
247 0 : }
248 :
249 2985659 : bool RscExpType::Evaluate( sal_Int32 * plValue ) const
250 : {
251 2985659 : if( IsDefinition() )
252 : {
253 0 : aExp.pDef->Evaluate();
254 : // Eventuellen Fehler ignorieren
255 0 : *plValue = aExp.pDef->GetNumber();
256 : }
257 2985659 : else if( IsExpression() )
258 0 : return aExp.pExp->Evaluate( plValue );
259 2985659 : else if( IsNothing() )
260 11721 : *plValue = 0;
261 : else
262 2973938 : *plValue = GetLong();
263 :
264 2985659 : return true;
265 : }
266 :
267 0 : void RscExpType::AppendMacro(OStringBuffer& rStr) const
268 : {
269 0 : if( IsDefinition() )
270 0 : rStr.append(aExp.pDef->GetName());
271 0 : else if( IsExpression() )
272 0 : rStr.append(aExp.pExp->GetMacro());
273 0 : else if( IsNumber() )
274 0 : rStr.append(GetLong());
275 0 : }
276 :
277 :
278 0 : RscExpression::RscExpression( RscExpType aLE, char cOp, RscExpType aRE )
279 : {
280 0 : aLeftExp = aLE;
281 0 : cOperation = cOp;
282 0 : aRightExp = aRE;
283 0 : if( aLeftExp.IsDefinition() )
284 0 : aLeftExp.aExp.pDef->IncRef();
285 0 : if( aRightExp.IsDefinition() )
286 0 : aRightExp.aExp.pDef->IncRef();
287 0 : }
288 :
289 0 : RscExpression::~RscExpression()
290 : {
291 0 : if( aLeftExp.IsDefinition() )
292 0 : aLeftExp.aExp.pDef->DecRef();
293 0 : else if( aLeftExp.IsExpression() )
294 0 : delete aLeftExp.aExp.pExp;
295 :
296 0 : if( aRightExp.IsDefinition() )
297 0 : aRightExp.aExp.pDef->DecRef();
298 0 : else if( aRightExp.IsExpression() )
299 0 : delete aRightExp.aExp.pExp;
300 0 : }
301 :
302 0 : bool RscExpression::Evaluate( sal_Int32 * plValue )
303 : {
304 : sal_Int32 lLeft;
305 : sal_Int32 lRight;
306 :
307 : // linken und rechten Zweig auswerten
308 0 : if( aLeftExp.Evaluate( &lLeft ) && aRightExp.Evaluate( &lRight ) )
309 : {
310 0 : if( cOperation == '&' )
311 0 : *plValue = lLeft & lRight;
312 0 : else if( cOperation == '|' )
313 0 : *plValue = lLeft | lRight;
314 0 : else if( cOperation == '+' )
315 0 : *plValue = lLeft + lRight;
316 0 : else if( cOperation == '-' )
317 0 : *plValue = lLeft - lRight;
318 0 : else if( cOperation == '*' )
319 0 : *plValue = lLeft * lRight;
320 0 : else if( cOperation == 'r' )
321 0 : *plValue = lLeft >> lRight;
322 0 : else if( cOperation == 'l' )
323 0 : *plValue = lLeft << lRight;
324 : else
325 : {
326 0 : if( 0L == lRight )
327 0 : return false;
328 0 : *plValue = lLeft / lRight;
329 : }
330 0 : return true;
331 : }
332 0 : return false;
333 : }
334 :
335 0 : OString RscExpression::GetMacro()
336 : {
337 0 : OStringBuffer aLeft;
338 :
339 : // Ausgabeoptimierung
340 0 : if( aLeftExp.IsNothing() )
341 : {
342 0 : if ( '-' == cOperation )
343 : {
344 0 : aLeft.append('(');
345 0 : aLeft.append('-');
346 : }
347 0 : aRightExp.AppendMacro(aLeft);
348 0 : if( '-' == cOperation )
349 : {
350 0 : aLeft.append(')');
351 : }
352 : }
353 0 : else if( aRightExp.IsNothing() )
354 0 : aLeftExp.AppendMacro(aLeft);
355 : else
356 : {
357 0 : aLeft.append('(');
358 : // linken Zweig auswerten
359 0 : aLeftExp.AppendMacro(aLeft);
360 :
361 0 : aLeft.append(cOperation);
362 :
363 0 : aLeft.append('(');
364 : // rechten Zweig auswerten
365 0 : aRightExp.AppendMacro(aLeft);
366 0 : aLeft.append(')');
367 :
368 0 : aLeft.append(')');
369 : }
370 :
371 0 : return aLeft.makeStringAndClear();
372 : }
373 :
374 779 : RscFile :: RscFile()
375 : {
376 779 : bLoaded = false;
377 779 : bIncFile = false;
378 779 : bDirty = false;
379 779 : bScanned = false;
380 779 : }
381 :
382 1558 : RscFile :: ~RscFile()
383 : {
384 1558 : for ( size_t i = 0, n = aDepLst.size(); i < n; ++i )
385 779 : delete aDepLst[ i ];
386 779 : aDepLst.clear();
387 :
388 : //von hinten nach vorne ist besser wegen der Abhaengigkeiten
389 : //Objekte zerstoeren sich, wenn Referenzzaehler NULL
390 779 : while( aDefLst.Remove() ) ;
391 779 : }
392 :
393 0 : bool RscFile::Depend( sal_uLong lDepend, sal_uLong lFree )
394 : {
395 0 : for ( size_t i = aDepLst.size(); i > 0; )
396 : {
397 0 : RscDepend * pDep = aDepLst[ --i ];
398 0 : if( pDep->GetFileKey() == lDepend )
399 : {
400 0 : for ( size_t j = i ? --i : 0; j > 0; )
401 : {
402 0 : pDep = aDepLst[ --j ];
403 0 : if( pDep->GetFileKey() == lFree )
404 0 : return true;
405 : }
406 0 : return false;
407 : }
408 : }
409 0 : return true;
410 : }
411 :
412 779 : bool RscFile :: InsertDependFile( sal_uLong lIncFile, size_t lPos )
413 : {
414 779 : for ( size_t i = 0, n = aDepLst.size(); i < n; ++i )
415 : {
416 0 : RscDepend* pDep = aDepLst[ i ];
417 0 : if( pDep->GetFileKey() == lIncFile )
418 0 : return true;
419 : }
420 :
421 : // Current-Zeiger steht auf letztem Element
422 779 : if( lPos >= aDepLst.size() )
423 : { //letztes Element muss immer letztes bleiben
424 : // Abhaengigkeit vor der letzten Position eintragen
425 779 : aDepLst.push_back( new RscDepend( lIncFile ) );
426 : }
427 : else
428 : {
429 0 : RscDependList::iterator it = aDepLst.begin();
430 0 : ::std::advance( it, lPos );
431 0 : aDepLst.insert( it, new RscDepend( lIncFile ) );
432 : }
433 779 : return true;
434 : }
435 :
436 417 : RscDefTree::~RscDefTree()
437 : {
438 417 : Remove();
439 417 : }
440 :
441 834 : void RscDefTree::Remove()
442 : {
443 1668 : while( pDefRoot )
444 : {
445 0 : RscDefine * pDef = pDefRoot;
446 0 : pDefRoot = static_cast<RscDefine *>(pDefRoot->Remove( pDefRoot ));
447 0 : pDef->DecRef();
448 : }
449 834 : }
450 :
451 0 : RscDefine * RscDefTree::Search( const char * pName )
452 : {
453 0 : if( pDefRoot )
454 0 : return pDefRoot->Search( pName );
455 0 : return NULL;
456 : }
457 :
458 0 : void RscDefTree::Insert( RscDefine * pDef )
459 : {
460 0 : if( pDefRoot )
461 0 : pDefRoot->Insert( pDef );
462 : else
463 0 : pDefRoot = pDef;
464 0 : pDef->IncRef();
465 0 : }
466 :
467 0 : void RscDefTree::Remove( RscDefine * pDef )
468 : {
469 0 : if( pDefRoot )
470 : {
471 : //falls pDef == pDefRoot
472 0 : pDefRoot = static_cast<RscDefine *>(pDefRoot->Remove( pDef ));
473 : }
474 0 : pDef->DecRef();
475 0 : }
476 :
477 0 : bool RscDefTree::Evaluate( RscDefine * pDef )
478 : {
479 0 : if( pDef )
480 : {
481 0 : if( !Evaluate( static_cast<RscDefine *>(pDef->Left()) ) )
482 0 : return false;
483 0 : if( !Evaluate( static_cast<RscDefine *>(pDef->Right()) ) )
484 0 : return false;
485 : }
486 0 : return true;
487 : }
488 :
489 417 : RscFileTab::RscFileTab()
490 : {
491 417 : }
492 :
493 834 : RscFileTab :: ~RscFileTab()
494 : {
495 :
496 417 : aDefTree.Remove();
497 :
498 417 : sal_uIntPtr aIndex = LastIndex();
499 1613 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
500 : {
501 779 : delete Remove( aIndex );
502 779 : aIndex = LastIndex();
503 : };
504 417 : }
505 :
506 780 : sal_uLong RscFileTab :: Find( const OString& rName )
507 : {
508 780 : sal_uIntPtr aIndex = FirstIndex();
509 1924 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && (Get(aIndex)->aFileName != rName) )
510 364 : aIndex = NextIndex(aIndex);
511 :
512 780 : if( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
513 1 : return aIndex;
514 : else
515 779 : return NOFILE_INDEX;
516 : }
517 :
518 0 : RscDefine * RscFileTab::FindDef( const char * pName )
519 : {
520 0 : return aDefTree.Search( pName );
521 : }
522 :
523 : /* This method gives back true when lDepend
524 : exists and is behind lFree, or when lDepend does not exist. */
525 0 : bool RscFileTab::Depend( sal_uLong lDepend, sal_uLong lFree )
526 : {
527 0 : if( lDepend == lFree )
528 0 : return true;
529 :
530 0 : sal_uIntPtr aIndex = FirstIndex();
531 0 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
532 : {
533 0 : RscFile * pFile = Get(aIndex);
534 0 : if( !pFile->IsIncFile() )
535 : {
536 0 : if( !pFile->Depend( lDepend, lFree ) )
537 0 : return false;
538 : }
539 0 : aIndex = NextIndex(aIndex);
540 : }
541 :
542 0 : return true;
543 : }
544 :
545 0 : bool RscFileTab::TestDef( sal_uLong lFileKey, size_t lPos,
546 : const RscDefine * pDefDec )
547 : {
548 0 : if( lFileKey == pDefDec->GetFileKey() )
549 : {
550 0 : RscFile * pFile = GetFile( pDefDec->GetFileKey() );
551 0 : if( pFile && (lPos <= pFile->aDefLst.GetPos( const_cast<RscDefine *>(pDefDec) ))
552 0 : && (lPos != ULONG_MAX ) )
553 : {
554 0 : return false;
555 : }
556 : }
557 0 : else if( !Depend( lFileKey, pDefDec->GetFileKey() ) )
558 0 : return false;
559 :
560 0 : return TestDef( lFileKey, lPos, pDefDec->pExp );
561 : }
562 :
563 0 : bool RscFileTab::TestDef( sal_uLong lFileKey, size_t lPos,
564 : const RscExpression * pExpDec )
565 : {
566 0 : if( !pExpDec )
567 0 : return true;
568 :
569 0 : if( pExpDec->aLeftExp.IsExpression() )
570 0 : if( !TestDef( lFileKey, lPos, pExpDec->aLeftExp.aExp.pExp ) )
571 0 : return false;
572 :
573 0 : if( pExpDec->aLeftExp.IsDefinition() )
574 0 : if( !TestDef( lFileKey, lPos, pExpDec->aLeftExp.aExp.pDef ) )
575 0 : return false;
576 :
577 0 : if( pExpDec->aRightExp.IsExpression() )
578 0 : if( !TestDef( lFileKey, lPos, pExpDec->aRightExp.aExp.pExp ) )
579 0 : return false;
580 :
581 0 : if( pExpDec->aRightExp.IsDefinition() )
582 0 : if( !TestDef( lFileKey, lPos, pExpDec->aRightExp.aExp.pDef ) )
583 0 : return false;
584 :
585 0 : return true;
586 : }
587 :
588 0 : RscDefine * RscFileTab::NewDef( sal_uLong lFileKey, const OString& rDefName,
589 : sal_Int32 lId, sal_uLong lPos )
590 : {
591 0 : RscDefine * pDef = FindDef( rDefName );
592 :
593 0 : if( !pDef )
594 : {
595 0 : RscFile * pFile = GetFile( lFileKey );
596 :
597 0 : if( pFile )
598 : {
599 0 : pDef = pFile->aDefLst.New( lFileKey, rDefName, lId, lPos );
600 0 : aDefTree.Insert( pDef );
601 : }
602 : }
603 : else
604 0 : pDef = NULL;
605 :
606 0 : return pDef;
607 : }
608 :
609 0 : RscDefine * RscFileTab::NewDef( sal_uLong lFileKey, const OString& rDefName,
610 : RscExpression * pExp, sal_uLong lPos )
611 : {
612 0 : RscDefine * pDef = FindDef( rDefName );
613 :
614 0 : if( !pDef )
615 : {
616 : //Macros in den Expressions sind definiert ?
617 0 : if( TestDef( lFileKey, lPos, pExp ) )
618 : {
619 0 : RscFile * pFile = GetFile( lFileKey );
620 :
621 0 : if( pFile )
622 : {
623 0 : pDef = pFile->aDefLst.New( lFileKey, rDefName, pExp, lPos );
624 0 : aDefTree.Insert( pDef );
625 : }
626 : }
627 : }
628 : else
629 0 : pDef = NULL;
630 :
631 0 : if( !pDef )
632 : {
633 : // pExp wird immer Eigentum und muss, wenn es nicht benoetigt wird
634 : // geloescht werden
635 0 : delete pExp;
636 : }
637 0 : return pDef;
638 : }
639 :
640 56 : void RscFileTab :: DeleteFileContext( sal_uLong lFileKey )
641 : {
642 : RscFile * pFName;
643 :
644 56 : pFName = GetFile( lFileKey );
645 56 : if( pFName )
646 : {
647 56 : for ( size_t i = 0, n = pFName->aDefLst.maList.size(); i < n; ++i )
648 : {
649 0 : RscDefine * pDef = pFName->aDefLst.maList[ i ];
650 0 : aDefTree.Remove( pDef );
651 : };
652 :
653 56 : while( pFName->aDefLst.Remove() ) ;
654 : }
655 56 : }
656 :
657 780 : sal_uLong RscFileTab :: NewCodeFile( const OString& rName )
658 : {
659 780 : sal_uLong lKey = Find( rName );
660 780 : if( UNIQUEINDEX_ENTRY_NOTFOUND == lKey )
661 : {
662 779 : RscFile * pFName = new RscFile();
663 779 : pFName->aFileName = rName;
664 779 : pFName->aPathName = rName;
665 779 : lKey = Insert( pFName );
666 779 : pFName->InsertDependFile( lKey, ULONG_MAX );
667 : }
668 780 : return lKey;
669 : }
670 :
671 0 : sal_uLong RscFileTab :: NewIncFile(const OString& rName,
672 : const OString& rPath)
673 : {
674 0 : sal_uLong lKey = Find( rName );
675 0 : if( UNIQUEINDEX_ENTRY_NOTFOUND == lKey )
676 : {
677 0 : RscFile * pFName = new RscFile();
678 0 : pFName->aFileName = rName;
679 0 : pFName->aPathName = rPath;
680 0 : pFName->SetIncFlag();
681 0 : lKey = Insert( pFName );
682 0 : pFName->InsertDependFile( lKey, ULONG_MAX );
683 : }
684 0 : return lKey;
685 : }
686 :
687 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|