1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 // Programmuebergreifende Includes.
24 bool RscId::bNames
= true;
26 void RscId::SetNames( bool bSet
)
31 sal_Int32
RscId::GetNumber() const
34 aExp
.Evaluate( &lVal
);
38 void RscId::Create( const RscExpType
& rExpType
)
41 if( aExp
.IsDefinition() )
42 aExp
.aExp
.pDef
->IncRef();
43 else if( aExp
.IsExpression() )
47 aExp
.Evaluate( &lValue
);
48 aExp
.SetLong( lValue
);
54 if( aExp
.IsDefinition() )
55 aExp
.aExp
.pDef
->DecRef();
56 aExp
.cType
= RSCEXP_NOTHING
;
59 RscId::RscId( const RscId
& rRscId
)
62 if( aExp
.IsDefinition() )
63 aExp
.aExp
.pDef
->IncRef();
66 RscId::RscId( RscDefine
* pDef
)
70 aExpType
.aExp
.pDef
= pDef
;
71 aExpType
.cType
= RSCEXP_DEF
;
72 aExpType
.cUnused
= false;
76 RscId
& RscId::operator = ( const RscId
& rRscId
)
78 if( rRscId
.aExp
.IsDefinition() )
79 rRscId
.aExp
.aExp
.pDef
->IncRef();
85 bool RscId::operator == ( const RscId
& rRscId
) const
87 return GetNumber() == rRscId
.GetNumber();
90 bool RscId::operator < ( const RscId
& rRscId
) const
92 return GetNumber() < rRscId
.GetNumber();
95 bool RscId::operator > ( const RscId
& rRscId
) const
97 return GetNumber() > rRscId
.GetNumber();
100 RscId::operator sal_Int32() const
105 OString
RscId::GetName() const
109 if ( !aExp
.IsNothing() )
112 aExp
.AppendMacro(aStr
);
114 aStr
.append(GetNumber());
117 return aStr
.makeStringAndClear();
120 RscDefine::RscDefine( sal_uLong lKey
, const OString
& rDefName
, sal_Int32 lDefId
)
121 : StringNode( rDefName
)
129 RscDefine::RscDefine( sal_uLong lKey
, const OString
& rDefName
,
130 RscExpression
* pExpression
)
131 : StringNode( rDefName
)
136 pExpression
->Evaluate( &lId
);
140 RscDefine::~RscDefine()
147 void RscDefine::DecRef()
156 void RscDefine::DefineToNumber()
161 SetName(OString::number(lId
));
164 bool RscDefine::Evaluate()
169 bRet
= !pExp
->Evaluate( &lId
);
174 RscDefine
* RscDefine::Search( const char * pStr
)
176 return static_cast<RscDefine
*>(StringNode::Search( pStr
));
179 OString
RscDefine::GetMacro()
182 return pExp
->GetMacro();
183 return OString::number(lId
);
186 RscDefine
* RscDefineList::New( sal_uLong lFileKey
, const OString
& rDefName
,
187 sal_Int32 lDefId
, size_t lPos
)
191 pDef
= new RscDefine( lFileKey
, rDefName
, lDefId
);
193 if ( lPos
< maList
.size() )
195 RscSubDefList::iterator it
= maList
.begin();
196 ::std::advance( it
, lPos
);
197 maList
.insert( it
, pDef
);
201 maList
.push_back( pDef
);
206 RscDefine
* RscDefineList::New( sal_uLong lFileKey
, const OString
& rDefName
,
207 RscExpression
* pExpression
, size_t lPos
)
211 pDef
= new RscDefine( lFileKey
, rDefName
, pExpression
);
213 if ( lPos
< maList
.size() )
215 RscSubDefList::iterator it
= maList
.begin();
216 ::std::advance( it
, lPos
);
217 maList
.insert( it
, pDef
);
221 maList
.push_back( pDef
);
226 bool RscDefineList::Remove()
228 if ( maList
.empty() )
231 maList
[ 0 ]->DefineToNumber();
232 maList
[ 0 ]->DecRef();
233 maList
.erase( maList
.begin() );
237 void RscDefineList::WriteAll( FILE * fOutput
)
239 for ( size_t i
= 0, n
= maList
.size(); i
< n
; ++i
)
241 RscDefine
* pDefEle
= maList
[ i
];
242 fprintf( fOutput
, "#define %s %s\n",
243 pDefEle
->GetName().getStr(),
244 pDefEle
->GetMacro().getStr()
249 bool RscExpType::Evaluate( sal_Int32
* plValue
) const
253 aExp
.pDef
->Evaluate();
254 // Eventuellen Fehler ignorieren
255 *plValue
= aExp
.pDef
->GetNumber();
257 else if( IsExpression() )
258 return aExp
.pExp
->Evaluate( plValue
);
259 else if( IsNothing() )
262 *plValue
= GetLong();
267 void RscExpType::AppendMacro(OStringBuffer
& rStr
) const
270 rStr
.append(aExp
.pDef
->GetName());
271 else if( IsExpression() )
272 rStr
.append(aExp
.pExp
->GetMacro());
273 else if( IsNumber() )
274 rStr
.append(GetLong());
278 RscExpression::RscExpression( RscExpType aLE
, char cOp
, RscExpType aRE
)
283 if( aLeftExp
.IsDefinition() )
284 aLeftExp
.aExp
.pDef
->IncRef();
285 if( aRightExp
.IsDefinition() )
286 aRightExp
.aExp
.pDef
->IncRef();
289 RscExpression::~RscExpression()
291 if( aLeftExp
.IsDefinition() )
292 aLeftExp
.aExp
.pDef
->DecRef();
293 else if( aLeftExp
.IsExpression() )
294 delete aLeftExp
.aExp
.pExp
;
296 if( aRightExp
.IsDefinition() )
297 aRightExp
.aExp
.pDef
->DecRef();
298 else if( aRightExp
.IsExpression() )
299 delete aRightExp
.aExp
.pExp
;
302 bool RscExpression::Evaluate( sal_Int32
* plValue
)
307 // linken und rechten Zweig auswerten
308 if( aLeftExp
.Evaluate( &lLeft
) && aRightExp
.Evaluate( &lRight
) )
310 if( cOperation
== '&' )
311 *plValue
= lLeft
& lRight
;
312 else if( cOperation
== '|' )
313 *plValue
= lLeft
| lRight
;
314 else if( cOperation
== '+' )
315 *plValue
= lLeft
+ lRight
;
316 else if( cOperation
== '-' )
317 *plValue
= lLeft
- lRight
;
318 else if( cOperation
== '*' )
319 *plValue
= lLeft
* lRight
;
320 else if( cOperation
== 'r' )
321 *plValue
= lLeft
>> lRight
;
322 else if( cOperation
== 'l' )
323 *plValue
= lLeft
<< lRight
;
328 *plValue
= lLeft
/ lRight
;
335 OString
RscExpression::GetMacro()
339 // Ausgabeoptimierung
340 if( aLeftExp
.IsNothing() )
342 if ( '-' == cOperation
)
347 aRightExp
.AppendMacro(aLeft
);
348 if( '-' == cOperation
)
353 else if( aRightExp
.IsNothing() )
354 aLeftExp
.AppendMacro(aLeft
);
358 // linken Zweig auswerten
359 aLeftExp
.AppendMacro(aLeft
);
361 aLeft
.append(cOperation
);
364 // rechten Zweig auswerten
365 aRightExp
.AppendMacro(aLeft
);
371 return aLeft
.makeStringAndClear();
382 RscFile :: ~RscFile()
384 for ( size_t i
= 0, n
= aDepLst
.size(); i
< n
; ++i
)
388 //von hinten nach vorne ist besser wegen der Abhaengigkeiten
389 //Objekte zerstoeren sich, wenn Referenzzaehler NULL
390 while( aDefLst
.Remove() ) ;
393 bool RscFile::Depend( sal_uLong lDepend
, sal_uLong lFree
)
395 for ( size_t i
= aDepLst
.size(); i
> 0; )
397 RscDepend
* pDep
= aDepLst
[ --i
];
398 if( pDep
->GetFileKey() == lDepend
)
400 for ( size_t j
= i
? --i
: 0; j
> 0; )
402 pDep
= aDepLst
[ --j
];
403 if( pDep
->GetFileKey() == lFree
)
412 bool RscFile :: InsertDependFile( sal_uLong lIncFile
, size_t lPos
)
414 for ( size_t i
= 0, n
= aDepLst
.size(); i
< n
; ++i
)
416 RscDepend
* pDep
= aDepLst
[ i
];
417 if( pDep
->GetFileKey() == lIncFile
)
421 // Current-Zeiger steht auf letztem Element
422 if( lPos
>= aDepLst
.size() )
423 { //letztes Element muss immer letztes bleiben
424 // Abhaengigkeit vor der letzten Position eintragen
425 aDepLst
.push_back( new RscDepend( lIncFile
) );
429 RscDependList::iterator it
= aDepLst
.begin();
430 ::std::advance( it
, lPos
);
431 aDepLst
.insert( it
, new RscDepend( lIncFile
) );
436 RscDefTree::~RscDefTree()
441 void RscDefTree::Remove()
445 RscDefine
* pDef
= pDefRoot
;
446 pDefRoot
= static_cast<RscDefine
*>(pDefRoot
->Remove( pDefRoot
));
451 RscDefine
* RscDefTree::Search( const char * pName
)
454 return pDefRoot
->Search( pName
);
458 void RscDefTree::Insert( RscDefine
* pDef
)
461 pDefRoot
->Insert( pDef
);
467 void RscDefTree::Remove( RscDefine
* pDef
)
471 //falls pDef == pDefRoot
472 pDefRoot
= static_cast<RscDefine
*>(pDefRoot
->Remove( pDef
));
477 bool RscDefTree::Evaluate( RscDefine
* pDef
)
481 if( !Evaluate( static_cast<RscDefine
*>(pDef
->Left()) ) )
483 if( !Evaluate( static_cast<RscDefine
*>(pDef
->Right()) ) )
489 RscFileTab::RscFileTab()
493 RscFileTab :: ~RscFileTab()
498 sal_uIntPtr aIndex
= LastIndex();
499 while( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
)
501 delete Remove( aIndex
);
502 aIndex
= LastIndex();
506 sal_uLong
RscFileTab :: Find( const OString
& rName
)
508 sal_uIntPtr aIndex
= FirstIndex();
509 while( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
&& (Get(aIndex
)->aFileName
!= rName
) )
510 aIndex
= NextIndex(aIndex
);
512 if( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
)
518 RscDefine
* RscFileTab::FindDef( const char * pName
)
520 return aDefTree
.Search( pName
);
523 /* This method gives back true when lDepend
524 exists and is behind lFree, or when lDepend does not exist. */
525 bool RscFileTab::Depend( sal_uLong lDepend
, sal_uLong lFree
)
527 if( lDepend
== lFree
)
530 sal_uIntPtr aIndex
= FirstIndex();
531 while( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
)
533 RscFile
* pFile
= Get(aIndex
);
534 if( !pFile
->IsIncFile() )
536 if( !pFile
->Depend( lDepend
, lFree
) )
539 aIndex
= NextIndex(aIndex
);
545 bool RscFileTab::TestDef( sal_uLong lFileKey
, size_t lPos
,
546 const RscDefine
* pDefDec
)
548 if( lFileKey
== pDefDec
->GetFileKey() )
550 RscFile
* pFile
= GetFile( pDefDec
->GetFileKey() );
551 if( pFile
&& (lPos
<= pFile
->aDefLst
.GetPos( const_cast<RscDefine
*>(pDefDec
) ))
552 && (lPos
!= ULONG_MAX
) )
557 else if( !Depend( lFileKey
, pDefDec
->GetFileKey() ) )
560 return TestDef( lFileKey
, lPos
, pDefDec
->pExp
);
563 bool RscFileTab::TestDef( sal_uLong lFileKey
, size_t lPos
,
564 const RscExpression
* pExpDec
)
569 if( pExpDec
->aLeftExp
.IsExpression() )
570 if( !TestDef( lFileKey
, lPos
, pExpDec
->aLeftExp
.aExp
.pExp
) )
573 if( pExpDec
->aLeftExp
.IsDefinition() )
574 if( !TestDef( lFileKey
, lPos
, pExpDec
->aLeftExp
.aExp
.pDef
) )
577 if( pExpDec
->aRightExp
.IsExpression() )
578 if( !TestDef( lFileKey
, lPos
, pExpDec
->aRightExp
.aExp
.pExp
) )
581 if( pExpDec
->aRightExp
.IsDefinition() )
582 if( !TestDef( lFileKey
, lPos
, pExpDec
->aRightExp
.aExp
.pDef
) )
588 RscDefine
* RscFileTab::NewDef( sal_uLong lFileKey
, const OString
& rDefName
,
589 sal_Int32 lId
, sal_uLong lPos
)
591 RscDefine
* pDef
= FindDef( rDefName
);
595 RscFile
* pFile
= GetFile( lFileKey
);
599 pDef
= pFile
->aDefLst
.New( lFileKey
, rDefName
, lId
, lPos
);
600 aDefTree
.Insert( pDef
);
609 RscDefine
* RscFileTab::NewDef( sal_uLong lFileKey
, const OString
& rDefName
,
610 RscExpression
* pExp
, sal_uLong lPos
)
612 RscDefine
* pDef
= FindDef( rDefName
);
616 //Macros in den Expressions sind definiert ?
617 if( TestDef( lFileKey
, lPos
, pExp
) )
619 RscFile
* pFile
= GetFile( lFileKey
);
623 pDef
= pFile
->aDefLst
.New( lFileKey
, rDefName
, pExp
, lPos
);
624 aDefTree
.Insert( pDef
);
633 // pExp wird immer Eigentum und muss, wenn es nicht benoetigt wird
640 void RscFileTab :: DeleteFileContext( sal_uLong lFileKey
)
644 pFName
= GetFile( lFileKey
);
647 for ( size_t i
= 0, n
= pFName
->aDefLst
.maList
.size(); i
< n
; ++i
)
649 RscDefine
* pDef
= pFName
->aDefLst
.maList
[ i
];
650 aDefTree
.Remove( pDef
);
653 while( pFName
->aDefLst
.Remove() ) ;
657 sal_uLong
RscFileTab :: NewCodeFile( const OString
& rName
)
659 sal_uLong lKey
= Find( rName
);
660 if( UNIQUEINDEX_ENTRY_NOTFOUND
== lKey
)
662 RscFile
* pFName
= new RscFile();
663 pFName
->aFileName
= rName
;
664 pFName
->aPathName
= rName
;
665 lKey
= Insert( pFName
);
666 pFName
->InsertDependFile( lKey
, ULONG_MAX
);
671 sal_uLong
RscFileTab :: NewIncFile(const OString
& rName
,
672 const OString
& rPath
)
674 sal_uLong lKey
= Find( rName
);
675 if( UNIQUEINDEX_ENTRY_NOTFOUND
== lKey
)
677 RscFile
* pFName
= new RscFile();
678 pFName
->aFileName
= rName
;
679 pFName
->aPathName
= rPath
;
680 pFName
->SetIncFlag();
681 lKey
= Insert( pFName
);
682 pFName
->InsertDependFile( lKey
, ULONG_MAX
);
687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */