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 0 : void RscId::SetNames( bool bSet )
27 : {
28 0 : bNames = bSet;
29 0 : }
30 :
31 0 : sal_Int32 RscId::GetNumber() const
32 : {
33 : sal_Int32 lVal;
34 0 : aExp.Evaluate( &lVal );
35 0 : return lVal;
36 : }
37 :
38 0 : void RscId::Create( const RscExpType & rExpType )
39 : {
40 0 : aExp = rExpType;
41 0 : if( aExp.IsDefinition() )
42 0 : aExp.aExp.pDef->IncRef();
43 0 : else if( aExp.IsExpression() )
44 : {
45 : sal_Int32 lValue;
46 :
47 0 : aExp.Evaluate( &lValue );
48 0 : aExp.SetLong( lValue );
49 : }
50 0 : }
51 :
52 0 : void RscId::Destroy()
53 : {
54 0 : if( aExp.IsDefinition() )
55 0 : aExp.aExp.pDef->DecRef();
56 0 : aExp.cType = RSCEXP_NOTHING;
57 0 : }
58 :
59 0 : RscId::RscId( const RscId& rRscId )
60 : {
61 0 : aExp = rRscId.aExp;
62 0 : if( aExp.IsDefinition() )
63 0 : aExp.aExp.pDef->IncRef();
64 0 : }
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 0 : RscId& RscId::operator = ( const RscId& rRscId )
77 : {
78 0 : if( rRscId.aExp.IsDefinition() )
79 0 : rRscId.aExp.aExp.pDef->IncRef();
80 0 : Destroy();
81 0 : aExp = rRscId.aExp;
82 0 : return *this;
83 : }
84 :
85 0 : bool RscId::operator == ( const RscId& rRscId ) const
86 : {
87 0 : 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 0 : RscId::operator sal_Int32() const
101 : {
102 0 : return GetNumber();
103 : }
104 :
105 0 : OString RscId::GetName() const
106 : {
107 0 : OStringBuffer aStr;
108 :
109 0 : if ( !aExp.IsNothing() )
110 : {
111 0 : if( bNames )
112 0 : aExp.AppendMacro(aStr);
113 : else
114 0 : aStr.append(GetNumber());
115 : }
116 :
117 0 : 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 0 : : StringNode( rDefName )
132 : {
133 0 : nRefCount = 0;
134 0 : lFileKey = lKey;
135 0 : pExpression->Evaluate( &lId );
136 0 : pExp = pExpression;
137 0 : }
138 :
139 0 : RscDefine::~RscDefine()
140 : {
141 0 : if( pExp )
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 (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 0 : bool RscDefineList::Remove()
227 : {
228 0 : if ( maList.empty() )
229 0 : 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 0 : bool RscExpType::Evaluate( sal_Int32 * plValue ) const
250 : {
251 0 : if( IsDefinition() )
252 : {
253 0 : aExp.pDef->Evaluate();
254 : // Eventuellen Fehler ignorieren
255 0 : *plValue = aExp.pDef->GetNumber();
256 : }
257 0 : else if( IsExpression() )
258 0 : return aExp.pExp->Evaluate( plValue );
259 0 : else if( IsNothing() )
260 0 : *plValue = 0;
261 : else
262 0 : *plValue = GetLong();
263 :
264 0 : 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 0 : RscFile :: RscFile()
375 : {
376 0 : bLoaded = false;
377 0 : bIncFile = false;
378 0 : bDirty = false;
379 0 : bScanned = false;
380 0 : }
381 :
382 0 : RscFile :: ~RscFile()
383 : {
384 0 : for ( size_t i = 0, n = aDepLst.size(); i < n; ++i )
385 0 : delete aDepLst[ i ];
386 0 : aDepLst.clear();
387 :
388 : //von hinten nach vorne ist besser wegen der Abhaengigkeiten
389 : //Objekte zerstoeren sich, wenn Referenzzaehler NULL
390 0 : while( aDefLst.Remove() ) ;
391 0 : }
392 :
393 0 : bool RscFile::Depend( sal_uLong lDepend, sal_uLong lFree )
394 : {
395 : RscDepend * pDep;
396 :
397 0 : for ( size_t i = aDepLst.size(); i > 0; )
398 : {
399 0 : pDep = aDepLst[ --i ];
400 0 : if( pDep->GetFileKey() == lDepend )
401 : {
402 0 : for ( size_t j = i ? --i : 0; j > 0; )
403 : {
404 0 : pDep = aDepLst[ --j ];
405 0 : if( pDep->GetFileKey() == lFree )
406 0 : return true;
407 : }
408 0 : return false;
409 : }
410 : }
411 0 : return true;
412 : }
413 :
414 0 : bool RscFile :: InsertDependFile( sal_uLong lIncFile, size_t lPos )
415 : {
416 0 : for ( size_t i = 0, n = aDepLst.size(); i < n; ++i )
417 : {
418 0 : RscDepend* pDep = aDepLst[ i ];
419 0 : if( pDep->GetFileKey() == lIncFile )
420 0 : return true;
421 : }
422 :
423 : // Current-Zeiger steht auf letztem Element
424 0 : if( lPos >= aDepLst.size() )
425 : { //letztes Element muss immer letztes bleiben
426 : // Abhaengigkeit vor der letzten Position eintragen
427 0 : aDepLst.push_back( new RscDepend( lIncFile ) );
428 : }
429 : else
430 : {
431 0 : RscDependList::iterator it = aDepLst.begin();
432 0 : ::std::advance( it, lPos );
433 0 : aDepLst.insert( it, new RscDepend( lIncFile ) );
434 : }
435 0 : return true;
436 : }
437 :
438 0 : RscDefTree::~RscDefTree()
439 : {
440 0 : Remove();
441 0 : }
442 :
443 0 : void RscDefTree::Remove()
444 : {
445 : RscDefine * pDef;
446 0 : while( pDefRoot )
447 : {
448 0 : pDef = pDefRoot;
449 0 : pDefRoot = (RscDefine *)pDefRoot->Remove( pDefRoot );
450 0 : pDef->DecRef();
451 : }
452 0 : }
453 :
454 0 : RscDefine * RscDefTree::Search( const char * pName )
455 : {
456 0 : if( pDefRoot )
457 0 : return pDefRoot->Search( pName );
458 0 : return NULL;
459 : }
460 :
461 0 : void RscDefTree::Insert( RscDefine * pDef )
462 : {
463 0 : if( pDefRoot )
464 0 : pDefRoot->Insert( pDef );
465 : else
466 0 : pDefRoot = pDef;
467 0 : pDef->IncRef();
468 0 : }
469 :
470 0 : void RscDefTree::Remove( RscDefine * pDef )
471 : {
472 0 : if( pDefRoot )
473 : {
474 : //falls pDef == pDefRoot
475 0 : pDefRoot = (RscDefine *)pDefRoot->Remove( pDef );
476 : }
477 0 : pDef->DecRef();
478 0 : }
479 :
480 0 : bool RscDefTree::Evaluate( RscDefine * pDef )
481 : {
482 0 : if( pDef )
483 : {
484 0 : if( !Evaluate( (RscDefine *)pDef->Left() ) )
485 0 : return false;
486 0 : if( !Evaluate( (RscDefine *)pDef->Right() ) )
487 0 : return false;
488 : };
489 0 : return true;
490 : }
491 :
492 0 : RscFileTab::RscFileTab()
493 : {
494 0 : }
495 :
496 0 : RscFileTab :: ~RscFileTab()
497 : {
498 :
499 0 : aDefTree.Remove();
500 :
501 0 : sal_uIntPtr aIndex = LastIndex();
502 0 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
503 : {
504 0 : delete Remove( aIndex );
505 0 : aIndex = LastIndex();
506 : };
507 0 : }
508 :
509 0 : sal_uLong RscFileTab :: Find( const OString& rName )
510 : {
511 0 : sal_uIntPtr aIndex = FirstIndex();
512 0 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && (Get(aIndex)->aFileName != rName) )
513 0 : aIndex = NextIndex(aIndex);
514 :
515 0 : if( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
516 0 : return aIndex;
517 : else
518 0 : return NOFILE_INDEX;
519 : }
520 :
521 0 : RscDefine * RscFileTab::FindDef( const char * pName )
522 : {
523 0 : return aDefTree.Search( pName );
524 : }
525 :
526 : /* This method gives back true when lDepend
527 : exists and is behind lFree, or when lDepend does not exist. */
528 0 : bool RscFileTab::Depend( sal_uLong lDepend, sal_uLong lFree )
529 : {
530 0 : if( lDepend == lFree )
531 0 : return true;
532 :
533 0 : sal_uIntPtr aIndex = FirstIndex();
534 0 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
535 : {
536 0 : RscFile * pFile = Get(aIndex);
537 0 : if( !pFile->IsIncFile() )
538 : {
539 0 : if( !pFile->Depend( lDepend, lFree ) )
540 0 : return false;
541 : };
542 0 : aIndex = NextIndex(aIndex);
543 : };
544 :
545 0 : return true;
546 : }
547 :
548 0 : bool RscFileTab::TestDef( sal_uLong lFileKey, size_t lPos,
549 : const RscDefine * pDefDec )
550 : {
551 0 : if( lFileKey == pDefDec->GetFileKey() )
552 : {
553 0 : RscFile * pFile = GetFile( pDefDec->GetFileKey() );
554 0 : if( pFile && (lPos <= pFile->aDefLst.GetPos( (RscDefine *)pDefDec ))
555 0 : && (lPos != ULONG_MAX ) )
556 : {
557 0 : return false;
558 : }
559 : }
560 0 : else if( !Depend( lFileKey, pDefDec->GetFileKey() ) )
561 0 : return false;
562 :
563 0 : return TestDef( lFileKey, lPos, pDefDec->pExp );
564 : }
565 :
566 0 : bool RscFileTab::TestDef( sal_uLong lFileKey, size_t lPos,
567 : const RscExpression * pExpDec )
568 : {
569 0 : if( !pExpDec )
570 0 : return true;
571 :
572 0 : if( pExpDec->aLeftExp.IsExpression() )
573 0 : if( !TestDef( lFileKey, lPos, pExpDec->aLeftExp.aExp.pExp ) )
574 0 : return false;
575 :
576 0 : if( pExpDec->aLeftExp.IsDefinition() )
577 0 : if( !TestDef( lFileKey, lPos, pExpDec->aLeftExp.aExp.pDef ) )
578 0 : return false;
579 :
580 0 : if( pExpDec->aRightExp.IsExpression() )
581 0 : if( !TestDef( lFileKey, lPos, pExpDec->aRightExp.aExp.pExp ) )
582 0 : return false;
583 :
584 0 : if( pExpDec->aRightExp.IsDefinition() )
585 0 : if( !TestDef( lFileKey, lPos, pExpDec->aRightExp.aExp.pDef ) )
586 0 : return false;
587 :
588 0 : return true;
589 : }
590 :
591 0 : RscDefine * RscFileTab::NewDef( sal_uLong lFileKey, const OString& rDefName,
592 : sal_Int32 lId, sal_uLong lPos )
593 : {
594 0 : RscDefine * pDef = FindDef( rDefName );
595 :
596 0 : if( !pDef )
597 : {
598 0 : RscFile * pFile = GetFile( lFileKey );
599 :
600 0 : if( pFile )
601 : {
602 0 : pDef = pFile->aDefLst.New( lFileKey, rDefName, lId, lPos );
603 0 : aDefTree.Insert( pDef );
604 : }
605 : }
606 : else
607 0 : pDef = NULL;
608 :
609 0 : return pDef;
610 : }
611 :
612 0 : RscDefine * RscFileTab::NewDef( sal_uLong lFileKey, const OString& rDefName,
613 : RscExpression * pExp, sal_uLong lPos )
614 : {
615 0 : RscDefine * pDef = FindDef( rDefName );
616 :
617 0 : if( !pDef )
618 : {
619 : //Macros in den Expressions sind definiert ?
620 0 : if( TestDef( lFileKey, lPos, pExp ) )
621 : {
622 0 : RscFile * pFile = GetFile( lFileKey );
623 :
624 0 : if( pFile )
625 : {
626 0 : pDef = pFile->aDefLst.New( lFileKey, rDefName, pExp, lPos );
627 0 : aDefTree.Insert( pDef );
628 : }
629 : }
630 : }
631 : else
632 0 : pDef = NULL;
633 :
634 0 : if( !pDef )
635 : {
636 : // pExp wird immer Eigentum und muss, wenn es nicht benoetigt wird
637 : // geloescht werden
638 0 : delete pExp;
639 : }
640 0 : return pDef;
641 : }
642 :
643 0 : void RscFileTab :: DeleteFileContext( sal_uLong lFileKey )
644 : {
645 : RscFile * pFName;
646 :
647 0 : pFName = GetFile( lFileKey );
648 0 : if( pFName )
649 : {
650 : RscDefine * pDef;
651 :
652 0 : for ( size_t i = 0, n = pFName->aDefLst.maList.size(); i < n; ++i )
653 : {
654 0 : pDef = pFName->aDefLst.maList[ i ];
655 0 : aDefTree.Remove( pDef );
656 : };
657 :
658 0 : while( pFName->aDefLst.Remove() ) ;
659 : }
660 0 : }
661 :
662 0 : sal_uLong RscFileTab :: NewCodeFile( const OString& rName )
663 : {
664 0 : sal_uLong lKey = Find( rName );
665 0 : if( UNIQUEINDEX_ENTRY_NOTFOUND == lKey )
666 : {
667 0 : RscFile * pFName = new RscFile();
668 0 : pFName->aFileName = rName;
669 0 : pFName->aPathName = rName;
670 0 : lKey = Insert( pFName );
671 0 : pFName->InsertDependFile( lKey, ULONG_MAX );
672 : }
673 0 : return lKey;
674 : }
675 :
676 0 : sal_uLong RscFileTab :: NewIncFile(const OString& rName,
677 : const OString& rPath)
678 : {
679 0 : sal_uLong lKey = Find( rName );
680 0 : if( UNIQUEINDEX_ENTRY_NOTFOUND == lKey )
681 : {
682 0 : RscFile * pFName = new RscFile();
683 0 : pFName->aFileName = rName;
684 0 : pFName->aPathName = rPath;
685 0 : pFName->SetIncFlag();
686 0 : lKey = Insert( pFName );
687 0 : pFName->InsertDependFile( lKey, ULONG_MAX );
688 : }
689 0 : return lKey;
690 : }
691 :
692 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|