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