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 sal_Bool
RscId::bNames
= sal_True
;
26 void RscId::SetNames( sal_Bool bSet
) { bNames
= bSet
; }
28 sal_Int32
RscId::GetNumber() const{
30 aExp
.Evaluate( &lVal
);
34 void RscId::Create( const RscExpType
& rExpType
)
37 if( aExp
.IsDefinition() )
38 aExp
.aExp
.pDef
->IncRef();
39 else if( aExp
.IsExpression() ){
42 aExp
.Evaluate( &lValue
);
43 aExp
.SetLong( lValue
);
47 void RscId::Destroy(){
48 if( aExp
.IsDefinition() )
49 aExp
.aExp
.pDef
->DecRef();
50 aExp
.cType
= RSCEXP_NOTHING
;
53 RscId::RscId( const RscId
& rRscId
){
55 if( aExp
.IsDefinition() )
56 aExp
.aExp
.pDef
->IncRef();
59 RscId::RscId( RscDefine
* pDef
){
62 aExpType
.aExp
.pDef
= pDef
;
63 aExpType
.cType
= RSCEXP_DEF
;
67 RscId
& RscId::operator = ( const RscId
& rRscId
){
68 if( rRscId
.aExp
.IsDefinition() )
69 rRscId
.aExp
.aExp
.pDef
->IncRef();
75 sal_Bool
RscId::operator == ( const RscId
& rRscId
) const
77 return( GetNumber() == rRscId
.GetNumber() );
80 sal_Bool
RscId::operator < ( const RscId
& rRscId
) const
82 return( GetNumber() < rRscId
.GetNumber() );
85 sal_Bool
RscId::operator > ( const RscId
& rRscId
) const
87 return( GetNumber() > rRscId
.GetNumber() );
90 RscId::operator sal_Int32() const
92 return( GetNumber() );
95 OString
RscId::GetName() const
99 if ( !aExp
.IsNothing() )
102 aExp
.AppendMacro(aStr
);
104 aStr
.append(GetNumber());
107 return aStr
.makeStringAndClear();
110 RscDefine::RscDefine( sal_uLong lKey
, const OString
& rDefName
, sal_Int32 lDefId
)
111 : StringNode( rDefName
)
119 RscDefine::RscDefine( sal_uLong lKey
, const OString
& rDefName
,
120 RscExpression
* pExpression
)
121 : StringNode( rDefName
)
125 pExpression
->Evaluate( &lId
);
129 RscDefine::~RscDefine(){
136 void RscDefine::DecRef(){
138 if( 0 == nRefCount
){
143 void RscDefine::DefineToNumber()
148 SetName(OString::valueOf(lId
));
151 sal_Bool
RscDefine::Evaluate(){
152 sal_Bool bRet
= sal_True
;
155 bRet
= !pExp
->Evaluate( &lId
);
160 RscDefine
* RscDefine::Search( const char * pStr
){
161 return (RscDefine
*)StringNode::Search( pStr
);
164 OString
RscDefine::GetMacro()
167 return pExp
->GetMacro();
168 return OString::valueOf(lId
);
171 RscDefine
* RscDefineList::New( sal_uLong lFileKey
, const OString
& rDefName
,
172 sal_Int32 lDefId
, size_t lPos
)
176 pDef
= new RscDefine( lFileKey
, rDefName
, lDefId
);
178 if ( lPos
< maList
.size() )
180 RscSubDefList::iterator it
= maList
.begin();
181 ::std::advance( it
, lPos
);
182 maList
.insert( it
, pDef
);
184 maList
.push_back( pDef
);
189 RscDefine
* RscDefineList::New( sal_uLong lFileKey
, const OString
& rDefName
,
190 RscExpression
* pExpression
, size_t lPos
)
194 pDef
= new RscDefine( lFileKey
, rDefName
, pExpression
);
196 if ( lPos
< maList
.size() )
198 RscSubDefList::iterator it
= maList
.begin();
199 ::std::advance( it
, lPos
);
200 maList
.insert( it
, pDef
);
202 maList
.push_back( pDef
);
207 sal_Bool
RscDefineList::Remove() {
208 if ( maList
.empty() )
211 maList
[ 0 ]->DefineToNumber();
212 maList
[ 0 ]->DecRef();
213 maList
.erase( maList
.begin() );
217 void RscDefineList::WriteAll( FILE * fOutput
)
219 for ( size_t i
= 0, n
= maList
.size(); i
< n
; ++i
) {
220 RscDefine
* pDefEle
= maList
[ i
];
221 fprintf( fOutput
, "#define %s %s\n",
222 pDefEle
->GetName().getStr(),
223 pDefEle
->GetMacro().getStr()
228 sal_Bool
RscExpType::Evaluate( sal_Int32
* plValue
) const{
229 if( IsDefinition() ){
230 aExp
.pDef
->Evaluate();
231 // Eventuellen Fehler ignorieren
232 *plValue
= aExp
.pDef
->GetNumber();
234 else if( IsExpression() )
235 return( aExp
.pExp
->Evaluate( plValue
) );
236 else if( IsNothing() )
239 *plValue
= GetLong();
244 void RscExpType::AppendMacro(OStringBuffer
& rStr
) const
247 rStr
.append(aExp
.pDef
->GetName());
248 else if( IsExpression() )
249 rStr
.append(aExp
.pExp
->GetMacro());
250 else if( IsNumber() )
251 rStr
.append(GetLong());
255 RscExpression::RscExpression( RscExpType aLE
, char cOp
, RscExpType aRE
)
260 if( aLeftExp
.IsDefinition() )
261 aLeftExp
.aExp
.pDef
->IncRef();
262 if( aRightExp
.IsDefinition() )
263 aRightExp
.aExp
.pDef
->IncRef();
266 RscExpression::~RscExpression(){
267 if( aLeftExp
.IsDefinition() )
268 aLeftExp
.aExp
.pDef
->DecRef();
269 else if( aLeftExp
.IsExpression() )
270 delete aLeftExp
.aExp
.pExp
;
272 if( aRightExp
.IsDefinition() )
273 aRightExp
.aExp
.pDef
->DecRef();
274 else if( aRightExp
.IsExpression() )
275 delete aRightExp
.aExp
.pExp
;
278 sal_Bool
RscExpression::Evaluate( sal_Int32
* plValue
){
282 // linken und rechten Zweig auswerten
283 if( aLeftExp
.Evaluate( &lLeft
) && aRightExp
.Evaluate( &lRight
) ){
284 if( cOperation
== '&' )
285 *plValue
= lLeft
& lRight
;
286 else if( cOperation
== '|' )
287 *plValue
= lLeft
| lRight
;
288 else if( cOperation
== '+' )
289 *plValue
= lLeft
+ lRight
;
290 else if( cOperation
== '-' )
291 *plValue
= lLeft
- lRight
;
292 else if( cOperation
== '*' )
293 *plValue
= lLeft
* lRight
;
294 else if( cOperation
== 'r' )
295 *plValue
= lLeft
>> lRight
;
296 else if( cOperation
== 'l' )
297 *plValue
= lLeft
<< lRight
;
301 *plValue
= lLeft
/ lRight
;
308 OString
RscExpression::GetMacro()
312 // Ausgabeoptimierung
313 if( aLeftExp
.IsNothing() )
315 if ( '-' == cOperation
)
320 aRightExp
.AppendMacro(aLeft
);
321 if( '-' == cOperation
)
324 else if( aRightExp
.IsNothing() )
325 aLeftExp
.AppendMacro(aLeft
);
328 // linken Zweig auswerten
329 aLeftExp
.AppendMacro(aLeft
);
331 aLeft
.append(cOperation
);
334 // rechten Zweig auswerten
335 aRightExp
.AppendMacro(aLeft
);
341 return aLeft
.makeStringAndClear();
344 RscFile :: RscFile(){
346 bIncFile
= sal_False
;
348 bScanned
= sal_False
;
351 RscFile :: ~RscFile() {
352 for ( size_t i
= 0, n
= aDepLst
.size(); i
< n
; ++i
)
356 //von hinten nach vorne ist besser wegen der Abhaengigkeiten
357 //Objekte zerstoeren sich, wenn Referenzzaehler NULL
358 while( aDefLst
.Remove() ) ;
361 sal_Bool
RscFile::Depend( sal_uLong lDepend
, sal_uLong lFree
){
364 for ( size_t i
= aDepLst
.size(); i
> 0; )
366 pDep
= aDepLst
[ --i
];
367 if( pDep
->GetFileKey() == lDepend
) {
368 for ( size_t j
= i
? --i
: 0; j
> 0; )
370 pDep
= aDepLst
[ --j
];
371 if( pDep
->GetFileKey() == lFree
)
380 sal_Bool
RscFile :: InsertDependFile( sal_uLong lIncFile
, size_t lPos
)
382 for ( size_t i
= 0, n
= aDepLst
.size(); i
< n
; ++i
)
384 RscDepend
* pDep
= aDepLst
[ i
];
385 if( pDep
->GetFileKey() == lIncFile
)
389 // Current-Zeiger steht auf letztem Element
390 if( lPos
>= aDepLst
.size() ) { //letztes Element muss immer letztes bleiben
391 // Abhaengigkeit vor der letzten Position eintragen
392 aDepLst
.push_back( new RscDepend( lIncFile
) );
395 RscDependList::iterator it
= aDepLst
.begin();
396 ::std::advance( it
, lPos
);
397 aDepLst
.insert( it
, new RscDepend( lIncFile
) );
402 RscDefTree::~RscDefTree(){
406 void RscDefTree::Remove(){
410 pDefRoot
= (RscDefine
*)pDefRoot
->Remove( pDefRoot
);
415 RscDefine
* RscDefTree::Search( const char * pName
){
417 return pDefRoot
->Search( pName
);
421 void RscDefTree::Insert( RscDefine
* pDef
){
423 pDefRoot
->Insert( pDef
);
429 void RscDefTree::Remove( RscDefine
* pDef
){
431 //falls pDef == pDefRoot
432 pDefRoot
= (RscDefine
*)pDefRoot
->Remove( pDef
);
437 sal_Bool
RscDefTree::Evaluate( RscDefine
* pDef
){
439 if( !Evaluate( (RscDefine
*)pDef
->Left() ) )
441 if( !Evaluate( (RscDefine
*)pDef
->Right() ) )
447 RscFileTab::RscFileTab(){
450 RscFileTab :: ~RscFileTab(){
454 sal_uIntPtr aIndex
= LastIndex();
455 while( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
) {
456 delete Remove( aIndex
);
457 aIndex
= LastIndex();
461 sal_uLong
RscFileTab :: Find( const OString
& rName
)
463 sal_uIntPtr aIndex
= FirstIndex();
464 while( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
&& (Get(aIndex
)->aFileName
!= rName
) )
465 aIndex
= NextIndex(aIndex
);
467 if( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
)
473 RscDefine
* RscFileTab::FindDef( const char * pName
){
474 return aDefTree
.Search( pName
);
477 /* This method gives back sal_True when lDepend
478 exists and is behind lFree, or when lDepend does not exist. */
479 sal_Bool
RscFileTab::Depend( sal_uLong lDepend
, sal_uLong lFree
){
480 if( lDepend
== lFree
)
483 sal_uIntPtr aIndex
= FirstIndex();
484 while( aIndex
!= UNIQUEINDEX_ENTRY_NOTFOUND
){
485 RscFile
* pFile
= Get(aIndex
);
486 if( !pFile
->IsIncFile() ){
487 if( !pFile
->Depend( lDepend
, lFree
) )
490 aIndex
= NextIndex(aIndex
);
496 sal_Bool
RscFileTab::TestDef( sal_uLong lFileKey
, size_t lPos
,
497 const RscDefine
* pDefDec
)
499 if( lFileKey
== pDefDec
->GetFileKey() ) {
500 RscFile
* pFile
= GetFile( pDefDec
->GetFileKey() );
501 if( pFile
&& (lPos
<= pFile
->aDefLst
.GetPos( (RscDefine
*)pDefDec
))
502 && (lPos
!= ULONG_MAX
) )
505 else if( !Depend( lFileKey
, pDefDec
->GetFileKey() ) )
508 return TestDef( lFileKey
, lPos
, pDefDec
->pExp
);
511 sal_Bool
RscFileTab::TestDef( sal_uLong lFileKey
, size_t lPos
,
512 const RscExpression
* pExpDec
)
517 if( pExpDec
->aLeftExp
.IsExpression() )
518 if( !TestDef( lFileKey
, lPos
, pExpDec
->aLeftExp
.aExp
.pExp
) )
521 if( pExpDec
->aLeftExp
.IsDefinition() )
522 if( !TestDef( lFileKey
, lPos
, pExpDec
->aLeftExp
.aExp
.pDef
) )
525 if( pExpDec
->aRightExp
.IsExpression() )
526 if( !TestDef( lFileKey
, lPos
, pExpDec
->aRightExp
.aExp
.pExp
) )
529 if( pExpDec
->aRightExp
.IsDefinition() )
530 if( !TestDef( lFileKey
, lPos
, pExpDec
->aRightExp
.aExp
.pDef
) )
536 RscDefine
* RscFileTab::NewDef( sal_uLong lFileKey
, const OString
& rDefName
,
537 sal_Int32 lId
, sal_uLong lPos
)
539 RscDefine
* pDef
= FindDef( rDefName
);
542 RscFile
* pFile
= GetFile( lFileKey
);
545 pDef
= pFile
->aDefLst
.New( lFileKey
, rDefName
, lId
, lPos
);
546 aDefTree
.Insert( pDef
);
555 RscDefine
* RscFileTab::NewDef( sal_uLong lFileKey
, const OString
& rDefName
,
556 RscExpression
* pExp
, sal_uLong lPos
)
558 RscDefine
* pDef
= FindDef( rDefName
);
561 //Macros in den Expressions sind definiert ?
562 if( TestDef( lFileKey
, lPos
, pExp
) ){
563 RscFile
* pFile
= GetFile( lFileKey
);
566 pDef
= pFile
->aDefLst
.New( lFileKey
, rDefName
, pExp
, lPos
);
567 aDefTree
.Insert( pDef
);
575 // pExp wird immer Eigentum und muss, wenn es nicht benoetigt wird
582 void RscFileTab :: DeleteFileContext( sal_uLong lFileKey
){
585 pFName
= GetFile( lFileKey
);
589 for ( size_t i
= 0, n
= pFName
->aDefLst
.maList
.size(); i
< n
; ++i
) {
590 pDef
= pFName
->aDefLst
.maList
[ i
];
591 aDefTree
.Remove( pDef
);
593 while( pFName
->aDefLst
.Remove() ) ;
597 sal_uLong
RscFileTab :: NewCodeFile( const OString
& rName
)
599 sal_uLong lKey
= Find( rName
);
600 if( UNIQUEINDEX_ENTRY_NOTFOUND
== lKey
)
602 RscFile
* pFName
= new RscFile();
603 pFName
->aFileName
= rName
;
604 pFName
->aPathName
= rName
;
605 lKey
= Insert( pFName
);
606 pFName
->InsertDependFile( lKey
, ULONG_MAX
);
611 sal_uLong
RscFileTab :: NewIncFile(const OString
& rName
,
612 const OString
& rPath
)
614 sal_uLong lKey
= Find( rName
);
615 if( UNIQUEINDEX_ENTRY_NOTFOUND
== lKey
)
617 RscFile
* pFName
= new RscFile();
618 pFName
->aFileName
= rName
;
619 pFName
->aPathName
= rPath
;
620 pFName
->SetIncFlag();
621 lKey
= Insert( pFName
);
622 pFName
->InsertDependFile( lKey
, ULONG_MAX
);
627 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */