fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / rsc / source / tools / rscdef.cxx
blobd888a3e9b7ff384d2ac795d06f338233bcb85117
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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.
22 #include <rscdef.hxx>
24 sal_Bool RscId::bNames = sal_True;
26 void RscId::SetNames( sal_Bool bSet ) { bNames = bSet; }
28 sal_Int32 RscId::GetNumber() const{
29 sal_Int32 lVal;
30 aExp.Evaluate( &lVal );
31 return lVal;
34 void RscId::Create( const RscExpType & rExpType )
36 aExp = rExpType;
37 if( aExp.IsDefinition() )
38 aExp.aExp.pDef->IncRef();
39 else if( aExp.IsExpression() ){
40 sal_Int32 lValue;
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 ){
54 aExp = rRscId.aExp;
55 if( aExp.IsDefinition() )
56 aExp.aExp.pDef->IncRef();
59 RscId::RscId( RscDefine * pDef ){
60 RscExpType aExpType;
62 aExpType.aExp.pDef = pDef;
63 aExpType.cType = RSCEXP_DEF;
64 Create( aExpType );
67 RscId& RscId::operator = ( const RscId& rRscId ){
68 if( rRscId.aExp.IsDefinition() )
69 rRscId.aExp.aExp.pDef->IncRef();
70 Destroy();
71 aExp = rRscId.aExp;
72 return *this;
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
97 OStringBuffer aStr;
99 if ( !aExp.IsNothing() )
101 if( bNames )
102 aExp.AppendMacro(aStr);
103 else
104 aStr.append(GetNumber());
107 return aStr.makeStringAndClear();
110 RscDefine::RscDefine( sal_uLong lKey, const OString& rDefName, sal_Int32 lDefId )
111 : StringNode( rDefName )
113 nRefCount = 0;
114 lFileKey = lKey;
115 lId = lDefId;
116 pExp = NULL;
119 RscDefine::RscDefine( sal_uLong lKey, const OString& rDefName,
120 RscExpression * pExpression )
121 : StringNode( rDefName )
123 nRefCount = 0;
124 lFileKey = lKey;
125 pExpression->Evaluate( &lId );
126 pExp = pExpression;
129 RscDefine::~RscDefine(){
130 if( pExp )
131 delete pExp;
132 if( nRefCount )
133 RscExit( 14 );
136 void RscDefine::DecRef(){
137 nRefCount--;
138 if( 0 == nRefCount ){
139 delete this;
143 void RscDefine::DefineToNumber()
145 if( pExp )
146 delete pExp;
147 pExp = NULL;
148 SetName(OString::valueOf(lId));
151 sal_Bool RscDefine::Evaluate(){
152 sal_Bool bRet = sal_True;
154 if( pExp )
155 bRet = !pExp->Evaluate( &lId );
157 return bRet;
160 RscDefine * RscDefine::Search( const char * pStr ){
161 return (RscDefine *)StringNode::Search( pStr );
164 OString RscDefine::GetMacro()
166 if( pExp )
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 )
174 RscDefine * pDef;
176 pDef = new RscDefine( lFileKey, rDefName, lDefId );
177 pDef->IncRef();
178 if ( lPos < maList.size() )
180 RscSubDefList::iterator it = maList.begin();
181 ::std::advance( it, lPos );
182 maList.insert( it, pDef );
183 } else {
184 maList.push_back( pDef );
186 return pDef;
189 RscDefine * RscDefineList::New( sal_uLong lFileKey, const OString& rDefName,
190 RscExpression * pExpression, size_t lPos )
192 RscDefine * pDef;
194 pDef = new RscDefine( lFileKey, rDefName, pExpression );
195 pDef->IncRef();
196 if ( lPos < maList.size() )
198 RscSubDefList::iterator it = maList.begin();
199 ::std::advance( it, lPos );
200 maList.insert( it, pDef );
201 } else {
202 maList.push_back( pDef );
204 return pDef;
207 sal_Bool RscDefineList::Remove() {
208 if ( maList.empty() )
209 return sal_False;
211 maList[ 0 ]->DefineToNumber();
212 maList[ 0 ]->DecRef();
213 maList.erase( maList.begin() );
214 return sal_True;
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() )
237 *plValue = 0;
238 else
239 *plValue = GetLong();
241 return sal_True;
244 void RscExpType::AppendMacro(OStringBuffer& rStr) const
246 if( IsDefinition() )
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 )
257 aLeftExp = aLE;
258 cOperation = cOp;
259 aRightExp = 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 ){
279 sal_Int32 lLeft;
280 sal_Int32 lRight;
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;
298 else{
299 if( 0L == lRight )
300 return sal_False;
301 *plValue = lLeft / lRight;
303 return sal_True;
305 return sal_False;
308 OString RscExpression::GetMacro()
310 OStringBuffer aLeft;
312 // Ausgabeoptimierung
313 if( aLeftExp.IsNothing() )
315 if ( '-' == cOperation )
317 aLeft.append('(');
318 aLeft.append('-');
320 aRightExp.AppendMacro(aLeft);
321 if( '-' == cOperation )
322 aLeft.append(')');
324 else if( aRightExp.IsNothing() )
325 aLeftExp.AppendMacro(aLeft);
326 else{
327 aLeft.append('(');
328 // linken Zweig auswerten
329 aLeftExp.AppendMacro(aLeft);
331 aLeft.append(cOperation);
333 aLeft.append('(');
334 // rechten Zweig auswerten
335 aRightExp.AppendMacro(aLeft);
336 aLeft.append(')');
338 aLeft.append(')');
341 return aLeft.makeStringAndClear();
344 RscFile :: RscFile(){
345 bLoaded = sal_False;
346 bIncFile = sal_False;
347 bDirty = sal_False;
348 bScanned = sal_False;
351 RscFile :: ~RscFile() {
352 for ( size_t i = 0, n = aDepLst.size(); i < n; ++i )
353 delete aDepLst[ i ];
354 aDepLst.clear();
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 ){
362 RscDepend * pDep;
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 )
372 return sal_True;
374 return sal_False;
377 return sal_True;
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 )
386 return sal_True;
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 ) );
394 else {
395 RscDependList::iterator it = aDepLst.begin();
396 ::std::advance( it, lPos );
397 aDepLst.insert( it, new RscDepend( lIncFile ) );
399 return sal_True;
402 RscDefTree::~RscDefTree(){
403 Remove();
406 void RscDefTree::Remove(){
407 RscDefine * pDef;
408 while( pDefRoot ){
409 pDef = pDefRoot;
410 pDefRoot = (RscDefine *)pDefRoot->Remove( pDefRoot );
411 pDef->DecRef();
415 RscDefine * RscDefTree::Search( const char * pName ){
416 if( pDefRoot )
417 return pDefRoot->Search( pName );
418 return NULL;
421 void RscDefTree::Insert( RscDefine * pDef ){
422 if( pDefRoot )
423 pDefRoot->Insert( pDef );
424 else
425 pDefRoot = pDef;
426 pDef->IncRef();
429 void RscDefTree::Remove( RscDefine * pDef ){
430 if( pDefRoot ){
431 //falls pDef == pDefRoot
432 pDefRoot = (RscDefine *)pDefRoot->Remove( pDef );
434 pDef->DecRef();
437 sal_Bool RscDefTree::Evaluate( RscDefine * pDef ){
438 if( pDef ){
439 if( !Evaluate( (RscDefine *)pDef->Left() ) )
440 return sal_False;
441 if( !Evaluate( (RscDefine *)pDef->Right() ) )
442 return sal_False;
444 return sal_True;
447 RscFileTab::RscFileTab(){
450 RscFileTab :: ~RscFileTab(){
452 aDefTree.Remove();
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 )
468 return aIndex;
469 else
470 return NOFILE_INDEX;
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 )
481 return sal_True;
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 ) )
488 return sal_False;
490 aIndex = NextIndex(aIndex);
493 return sal_True;
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 ) )
503 return sal_False;
505 else if( !Depend( lFileKey, pDefDec->GetFileKey() ) )
506 return sal_False;
508 return TestDef( lFileKey, lPos, pDefDec->pExp );
511 sal_Bool RscFileTab::TestDef( sal_uLong lFileKey, size_t lPos,
512 const RscExpression * pExpDec )
514 if( !pExpDec )
515 return sal_True;
517 if( pExpDec->aLeftExp.IsExpression() )
518 if( !TestDef( lFileKey, lPos, pExpDec->aLeftExp.aExp.pExp ) )
519 return sal_False;
521 if( pExpDec->aLeftExp.IsDefinition() )
522 if( !TestDef( lFileKey, lPos, pExpDec->aLeftExp.aExp.pDef ) )
523 return sal_False;
525 if( pExpDec->aRightExp.IsExpression() )
526 if( !TestDef( lFileKey, lPos, pExpDec->aRightExp.aExp.pExp ) )
527 return sal_False;
529 if( pExpDec->aRightExp.IsDefinition() )
530 if( !TestDef( lFileKey, lPos, pExpDec->aRightExp.aExp.pDef ) )
531 return sal_False;
533 return sal_True;
536 RscDefine * RscFileTab::NewDef( sal_uLong lFileKey, const OString& rDefName,
537 sal_Int32 lId, sal_uLong lPos )
539 RscDefine * pDef = FindDef( rDefName );
541 if( !pDef ){
542 RscFile * pFile = GetFile( lFileKey );
544 if( pFile ){
545 pDef = pFile->aDefLst.New( lFileKey, rDefName, lId, lPos );
546 aDefTree.Insert( pDef );
549 else
550 pDef = NULL;
552 return( pDef );
555 RscDefine * RscFileTab::NewDef( sal_uLong lFileKey, const OString& rDefName,
556 RscExpression * pExp, sal_uLong lPos )
558 RscDefine * pDef = FindDef( rDefName );
560 if( !pDef ){
561 //Macros in den Expressions sind definiert ?
562 if( TestDef( lFileKey, lPos, pExp ) ){
563 RscFile * pFile = GetFile( lFileKey );
565 if( pFile ){
566 pDef = pFile->aDefLst.New( lFileKey, rDefName, pExp, lPos );
567 aDefTree.Insert( pDef );
571 else
572 pDef = NULL;
574 if( !pDef ){
575 // pExp wird immer Eigentum und muss, wenn es nicht benoetigt wird
576 // geloescht werden
577 delete pExp;
579 return( pDef );
582 void RscFileTab :: DeleteFileContext( sal_uLong lFileKey ){
583 RscFile * pFName;
585 pFName = GetFile( lFileKey );
586 if( pFName ){
587 RscDefine * pDef;
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 );
608 return lKey;
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 );
624 return lKey;
627 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */