LCOV - code coverage report
Current view: top level - basic/source/comp - exprtree.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 398 561 70.9 %
Date: 2012-08-25 Functions: 25 29 86.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 410 934 43.9 %

           Branch data     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                 :            : #include "sbcomp.hxx"
      22                 :            : #include <basic/sbx.hxx>        // because of ...IMPL_REF(...sbxvariable)
      23                 :            : #include "expr.hxx"
      24                 :            : 
      25                 :            : /***************************************************************************
      26                 :            : |*
      27                 :            : |*      SbiExpression
      28                 :            : |*
      29                 :            : ***************************************************************************/
      30                 :            : 
      31                 :       6036 : SbiExpression::SbiExpression( SbiParser* p, SbiExprType t,
      32                 :       6036 :     SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo )
      33                 :            : {
      34                 :       6036 :     pParser = p;
      35                 :       6036 :     bBased = bError = bByVal = bBracket = false;
      36                 :       6036 :     nParenLevel = 0;
      37                 :       6036 :     eCurExpr = t;
      38                 :       6036 :     m_eMode = eMode;
      39                 :       6036 :     pNext = NULL;
      40 [ +  - ][ +  - ]:       6036 :     pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean();
                 [ +  + ]
      41         [ +  + ]:       6036 :     if( t != SbSYMBOL )
      42         [ +  - ]:       4360 :         pExpr->Optimize();
      43 [ +  + ][ +  - ]:       6036 :     if( t == SbLVALUE && !pExpr->IsLvalue() )
         [ -  + ][ -  + ]
      44         [ #  # ]:          0 :         p->Error( SbERR_LVALUE_EXPECTED );
      45 [ +  + ][ +  - ]:       6036 :     if( t == SbOPERAND && !IsVariable() )
         [ -  + ][ -  + ]
      46         [ #  # ]:          0 :         p->Error( SbERR_VAR_EXPECTED );
      47                 :       6036 : }
      48                 :            : 
      49                 :         38 : SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t )
      50                 :            : {
      51                 :         38 :     pParser = p;
      52                 :         38 :     eCurExpr = SbOPERAND;
      53                 :         38 :     pNext = NULL;
      54                 :         38 :     bBased = bError = bByVal = bBracket = false;
      55 [ +  - ][ +  - ]:         38 :     pExpr = new SbiExprNode( pParser, n, t );
      56         [ +  - ]:         38 :     pExpr->Optimize();
      57                 :         38 : }
      58                 :            : 
      59                 :        338 : SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPar )
      60                 :            : {
      61                 :        338 :     pParser = p;
      62                 :        338 :     pNext = NULL;
      63                 :        338 :     bBased = bError = bByVal = bBracket = false;
      64                 :        338 :     eCurExpr = SbOPERAND;
      65 [ +  - ][ +  - ]:        338 :     pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar );
      66                 :        338 : }
      67                 :            : 
      68                 :       6412 : SbiExpression::~SbiExpression()
      69                 :            : {
      70 [ +  - ][ +  - ]:       6412 :     delete pExpr;
      71                 :       6412 : }
      72                 :            : 
      73                 :            : // reading in a complete identifier
      74                 :            : // an identifier has the following form:
      75                 :            : // name[(Parameter)][.Name[(parameter)]]...
      76                 :            : // structure elements are coupled via the element pNext,
      77                 :            : // so that they're not in the tree.
      78                 :            : 
      79                 :            : // Are there parameters without brackets following? This may be a number,
      80                 :            : // a string, a symbol or also a comma (if the 1st parameter is missing)
      81                 :            : 
      82                 :       6014 : static sal_Bool DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTok )
      83                 :            : {
      84         [ +  + ]:       6014 :     if( eTok == LPAREN )
      85                 :       1535 :         return sal_True;
      86                 :            :     // but only if similar to CALL!
      87 [ +  + ][ +  + ]:       4479 :     if( !p->WhiteSpace() || eCurExpr != SbSYMBOL )
                 [ +  + ]
      88                 :       3430 :         return sal_False;
      89 [ +  - ][ +  - ]:       1049 :     if (   eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
      90                 :            :         || eTok == SYMBOL || eTok == COMMA  || eTok == DOT || eTok == NOT || eTok == BYVAL )
      91                 :            :     {
      92                 :         12 :         return sal_True;
      93                 :            :     }
      94                 :            :     else // check for default params with reserved names ( e.g. names of tokens )
      95                 :            :     {
      96         [ +  - ]:       1037 :         SbiTokenizer tokens( *(SbiTokenizer*)p );
      97                 :            :         // Urk the Next() / Peek() symantics are... weird
      98         [ +  - ]:       1037 :         tokens.Next();
      99 [ +  - ][ -  + ]:       1037 :         if ( tokens.Peek() == ASSIGN )
     100 [ +  - ][ +  - ]:       1037 :             return sal_True;
     101                 :            :     }
     102                 :       6014 :     return sal_False;
     103                 :            : }
     104                 :            : 
     105                 :            : // definition of a new symbol
     106                 :            : 
     107                 :       1025 : static SbiSymDef* AddSym
     108                 :            :     ( SbiToken eTok, SbiSymPool& rPool, SbiExprType eCurExpr,
     109                 :            :       const String& rName, SbxDataType eType, SbiParameters* pPar )
     110                 :            : {
     111                 :            :     SbiSymDef* pDef;
     112                 :            :     // A= is not a procedure
     113 [ +  + ][ +  + ]:       1025 :     sal_Bool bHasType = sal_Bool( eTok == EQ || eTok == DOT );
     114 [ +  + ][ +  + ]:       1025 :     if( ( !bHasType && eCurExpr == SbSYMBOL ) || pPar )
                 [ +  + ]
     115                 :            :     {
     116                 :            :         // so this is a procedure
     117                 :            :         // the correct pool should be found out, as
     118                 :            :         // procs must always get into a public pool
     119                 :        370 :         SbiSymPool* pPool = &rPool;
     120         [ +  + ]:        370 :         if( pPool->GetScope() != SbPUBLIC )
     121                 :        136 :             pPool = &rPool.GetParser()->aPublics;
     122                 :        370 :         SbiProcDef* pProc = pPool->AddProc( rName );
     123                 :            : 
     124                 :            :         // special treatment for Colls like Documents(1)
     125         [ +  + ]:        370 :         if( eCurExpr == SbSTDEXPR )
     126                 :        154 :             bHasType = sal_True;
     127                 :            : 
     128                 :        370 :         pDef = pProc;
     129         [ +  + ]:        370 :         pDef->SetType( bHasType ? eType : SbxEMPTY );
     130         [ +  + ]:        370 :         if( pPar )
     131                 :            :         {
     132                 :            :             // generate dummy parameters
     133                 :        321 :             sal_uInt16 n = 1;
     134         [ +  + ]:        764 :             for( short i = 0; i < pPar->GetSize(); i++ )
     135                 :            :             {
     136         [ +  - ]:        443 :                 String aPar = rtl::OUString("PAR");
     137         [ +  - ]:        443 :                 aPar += ++n;
     138         [ +  - ]:        443 :                 pProc->GetParams().AddSym( aPar );
     139         [ +  - ]:        443 :             }
     140                 :        370 :         }
     141                 :            :     }
     142                 :            :     else
     143                 :            :     {
     144                 :            :         // or a normal symbol
     145                 :        655 :         pDef = rPool.AddSym( rName );
     146                 :        655 :         pDef->SetType( eType );
     147                 :            :     }
     148                 :       1025 :     return pDef;
     149                 :            : }
     150                 :            : 
     151                 :            : // currently even keywords are allowed (because of Dflt properties of the same name)
     152                 :            : 
     153                 :       5250 : SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo )
     154                 :            : {
     155 [ +  - ][ -  + ]:       5250 :     if( pParser->Peek() == DOT )
     156                 :            :     {
     157         [ #  # ]:          0 :         SbiExprNode* pWithVar = pParser->GetWithVar();
     158                 :            :         // #26608: get to the node-chain's end to pass the correct object
     159 [ #  # ][ #  # ]:          0 :         SbiSymDef* pDef = pWithVar ? pWithVar->GetRealVar() : NULL;
     160                 :          0 :         SbiExprNode* pNd = NULL;
     161         [ #  # ]:          0 :         if( !pDef )
     162                 :            :         {
     163         [ #  # ]:          0 :             pParser->Next();
     164                 :            :         }
     165                 :            :         else
     166                 :            :         {
     167         [ #  # ]:          0 :             pNd = ObjTerm( *pDef );
     168         [ #  # ]:          0 :             if( pNd )
     169                 :          0 :                 pNd->SetWithParent( pWithVar );
     170                 :            :         }
     171         [ #  # ]:          0 :         if( !pNd )
     172                 :            :         {
     173         [ #  # ]:          0 :             pParser->Error( SbERR_UNEXPECTED, DOT );
     174 [ #  # ][ #  # ]:          0 :             pNd = new SbiExprNode( pParser, 1.0, SbxDOUBLE );
     175                 :            :         }
     176                 :          0 :         return pNd;
     177                 :            :     }
     178                 :            : 
     179 [ +  - ][ +  - ]:       5250 :     SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok;
     180                 :            :     // memorize the parsing's begin
     181         [ +  - ]:       5250 :     pParser->LockColumn();
     182 [ +  - ][ +  - ]:       5250 :     String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol );
     183         [ +  - ]:       5250 :     SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType;
     184                 :       5250 :     SbiParameters* pPar = NULL;
     185                 :       5250 :     SbiExprListVector* pvMoreParLcl = NULL;
     186                 :            :     // are there parameters following?
     187         [ +  - ]:       5250 :     SbiToken eNextTok = pParser->Peek();
     188                 :            :     // is it a known parameter?
     189                 :            :     // create a string constant then, which will be recognized
     190                 :            :     // in the SbiParameters-ctor and is continued to be handled
     191         [ +  + ]:       5250 :     if( eNextTok == ASSIGN )
     192                 :            :     {
     193         [ +  - ]:         52 :         pParser->UnlockColumn();
     194 [ +  - ][ +  - ]:         52 :         return new SbiExprNode( pParser, aSym );
     195                 :            :     }
     196                 :            :     // no keywords allowed from here on!
     197         [ -  + ]:       5198 :     if( pParser->IsKwd( eTok ) )
     198                 :            :     {
     199 [ #  # ][ #  # ]:          0 :         if( pParser->IsCompatible() && eTok == INPUT )
                 [ #  # ]
     200                 :            :         {
     201                 :          0 :             eTok = SYMBOL;
     202                 :            :         }
     203                 :            :         else
     204                 :            :         {
     205         [ #  # ]:          0 :             pParser->Error( SbERR_SYNTAX );
     206                 :          0 :             bError = true;
     207                 :            :         }
     208                 :            :     }
     209                 :            : 
     210 [ +  - ][ +  + ]:       5198 :     if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) )
     211                 :            :     {
     212                 :       1117 :         bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE);
     213 [ +  - ][ +  - ]:       1117 :         pPar = new SbiParameters( pParser, bStandaloneExpression );
     214 [ +  - ][ -  + ]:       1117 :         bError = bError || !pPar->IsValid();
     215         [ +  - ]:       1117 :         if( !bError )
     216                 :       1117 :             bBracket = pPar->IsBracket();
     217         [ +  - ]:       1117 :         eTok = pParser->Peek();
     218                 :            : 
     219                 :            :         // i75443 check for additional sets of parameters
     220         [ -  + ]:       1117 :         while( eTok == LPAREN )
     221                 :            :         {
     222         [ #  # ]:          0 :             if( pvMoreParLcl == NULL )
     223 [ #  # ][ #  # ]:          0 :                 pvMoreParLcl = new SbiExprListVector();
     224 [ #  # ][ #  # ]:          0 :             SbiParameters* pAddPar = new SbiParameters( pParser );
     225         [ #  # ]:          0 :             pvMoreParLcl->push_back( pAddPar );
     226 [ #  # ][ #  # ]:          0 :             bError = bError || !pAddPar->IsValid();
     227         [ #  # ]:          0 :             eTok = pParser->Peek();
     228                 :            :         }
     229                 :            :     }
     230                 :            :     // It might be an object part, if . or ! is following.
     231                 :            :     // In case of . the variable must already be defined;
     232                 :            :     // it's an object, if pDef is NULL after the search.
     233                 :            :     sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM )
     234 [ +  + ][ -  + ]:       5198 :                     && !pParser->WhiteSpace() );
                 [ +  - ]
     235         [ +  + ]:       5198 :     if( bObj )
     236                 :            :     {
     237                 :        609 :         bBracket = false;   // Now the bracket for the first term is obsolete
     238         [ +  - ]:        609 :         if( eType == SbxVARIANT )
     239                 :        609 :             eType = SbxOBJECT;
     240                 :            :         else
     241                 :            :         {
     242                 :            :             // Name%. really does not work!
     243 [ #  # ][ #  # ]:          0 :             pParser->Error( SbERR_BAD_DECLARATION, aSym );
     244                 :          0 :             bError = true;
     245                 :            :         }
     246                 :            :     }
     247                 :            :     // Search:
     248         [ +  - ]:       5198 :     SbiSymDef* pDef = pParser->pPool->Find( aSym );
     249         [ +  + ]:       5198 :     if( !pDef )
     250                 :            :     {
     251                 :            :         // Part of the Runtime-Library?
     252                 :            :         // from 31.3.1996: swapped out to parser-method
     253                 :            :         // (is also needed in SbiParser::DefVar() in DIM.CXX)
     254         [ +  - ]:        683 :         pDef = pParser->CheckRTLForSym( aSym, eType );
     255                 :            : 
     256                 :            :         // #i109184: Check if symbol is or later will be defined inside module
     257                 :        683 :         SbModule& rMod = pParser->aGen.GetModule();
     258                 :        683 :         SbxArray* pModMethods = rMod.GetMethods();
     259 [ +  - ][ +  + ]:        683 :         if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) )
                 [ +  - ]
     260                 :         74 :             pDef = NULL;
     261                 :            :     }
     262         [ +  + ]:       5198 :     if( !pDef )
     263                 :            :     {
     264         [ +  + ]:        573 :         if( bObj )
     265                 :         28 :             eType = SbxOBJECT;
     266         [ +  - ]:        573 :         pDef = AddSym( eTok, *pParser->pPool, eCurExpr, aSym, eType, pPar );
     267                 :            :         // Looks like this is a local ( but undefined variable )
     268                 :            :         // if it is in a static procedure then make this Symbol
     269                 :            :         // static
     270 [ +  + ][ +  - ]:        573 :         if ( !bObj && pParser->pProc && pParser->pProc->IsStatic() )
         [ -  + ][ -  + ]
     271                 :          0 :             pDef->SetStatic();
     272                 :            :     }
     273                 :            :     else
     274                 :            :     {
     275                 :            : 
     276         [ +  - ]:       4625 :         SbiConstDef* pConst = pDef->GetConstDef();
     277         [ +  + ]:       4625 :         if( pConst )
     278                 :            :         {
     279         [ +  + ]:        568 :             if( pConst->GetType() == SbxSTRING )
     280 [ +  - ][ +  - ]:        340 :                 return new SbiExprNode( pParser, pConst->GetString() );
     281                 :            :             else
     282 [ +  - ][ +  - ]:        228 :                 return new SbiExprNode( pParser, pConst->GetValue(), pConst->GetType() );
     283                 :            :         }
     284                 :            : 
     285                 :            :         // 0 parameters come up to ()
     286         [ +  + ]:       4057 :         if( pDef->GetDims() )
     287                 :            :         {
     288 [ +  + ][ +  + ]:        252 :             if( pPar && pPar->GetSize() && pPar->GetSize() != pDef->GetDims() )
         [ -  + ][ -  + ]
     289         [ #  # ]:          0 :                 pParser->Error( SbERR_WRONG_DIMS );
     290                 :            :         }
     291         [ +  + ]:       4057 :         if( pDef->IsDefinedAs() )
     292                 :            :         {
     293                 :       1736 :             SbxDataType eDefType = pDef->GetType();
     294                 :            :             // #119187 Only error if types conflict
     295 [ +  + ][ -  + ]:       1736 :             if( eType >= SbxINTEGER && eType <= SbxSTRING && eType != eDefType )
                 [ +  - ]
     296                 :            :             {
     297                 :            :                 // How? Define with AS first and take a Suffix then?
     298 [ #  # ][ #  # ]:          0 :                 pParser->Error( SbERR_BAD_DECLARATION, aSym );
     299                 :          0 :                 bError = true;
     300                 :            :             }
     301         [ +  + ]:       1736 :             else if ( eType == SbxVARIANT )
     302                 :            :                 // if there's nothing named, take the type of the entry,
     303                 :            :                 // but only if the var hasn't been defined with AS XXX
     304                 :            :                 // so that we catch n% = 5 : print n
     305                 :       1736 :                 eType = eDefType;
     306                 :            :         }
     307                 :            :         // checking type of variables:
     308                 :            :         // is there named anything different in the scanner?
     309                 :            :         // That's OK for methods!
     310   [ +  +  +  + ]:       6337 :         if( eType != SbxVARIANT &&          // Variant takes everything
         [ +  + ][ +  + ]
     311                 :       2206 :             eType != pDef->GetType() &&
     312         [ +  - ]:         74 :             !pDef->GetProcDef() )
     313                 :            :         {
     314                 :            :             // maybe pDef describes an object that so far has only been
     315                 :            :             // recognized as SbxVARIANT - then change type of pDef
     316                 :            :             // from 16.12.95 (similar cases possible perhaps?!?)
     317 [ +  - ][ +  - ]:         69 :             if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT )
                 [ +  - ]
     318                 :            :             {
     319         [ +  - ]:         69 :                 pDef->SetType( SbxOBJECT );
     320                 :            :             }
     321                 :            :             else
     322                 :            :             {
     323 [ #  # ][ #  # ]:          0 :                 pParser->Error( SbERR_BAD_DECLARATION, aSym );
     324                 :          0 :                 bError = true;
     325                 :            :             }
     326                 :            :         }
     327                 :            :     }
     328 [ +  - ][ +  - ]:       4630 :     SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
     329         [ +  + ]:       4630 :     if( !pPar )
     330 [ +  - ][ +  - ]:       3513 :         pPar = new SbiParameters( pParser,sal_False,sal_False );
     331                 :       4630 :     pNd->aVar.pPar = pPar;
     332                 :       4630 :     pNd->aVar.pvMorePar = pvMoreParLcl;
     333         [ +  + ]:       4630 :     if( bObj )
     334                 :            :     {
     335                 :            :         // from 8.1.95: Object may also be of the type SbxVARIANT
     336         [ +  + ]:        609 :         if( pDef->GetType() == SbxVARIANT )
     337         [ +  - ]:          5 :             pDef->SetType( SbxOBJECT );
     338                 :            :         // if we scan something with point,
     339                 :            :         // the type must be SbxOBJECT
     340 [ -  + ][ #  # ]:        609 :         if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT )
                 [ -  + ]
     341                 :            :         {
     342                 :            :             // defer error until runtime if in vba mode
     343         [ #  # ]:          0 :             if ( !pParser->IsVBASupportOn() )
     344                 :            :             {
     345 [ #  # ][ #  # ]:          0 :                 pParser->Error( SbERR_BAD_DECLARATION, aSym );
     346                 :          0 :                 bError = true;
     347                 :            :             }
     348                 :            :         }
     349         [ +  - ]:        609 :         if( !bError )
     350         [ +  - ]:        609 :             pNd->aVar.pNext = ObjTerm( *pDef );
     351                 :            :     }
     352                 :            : 
     353         [ +  - ]:       4630 :     pParser->UnlockColumn();
     354         [ +  - ]:       5250 :     return pNd;
     355                 :            : }
     356                 :            : 
     357                 :            : // construction of an object term. A term of this kind is part
     358                 :            : // of an expression that begins with an object variable.
     359                 :            : 
     360                 :        816 : SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj )
     361                 :            : {
     362         [ +  - ]:        816 :     pParser->Next();
     363         [ +  - ]:        816 :     SbiToken eTok = pParser->Next();
     364 [ +  + ][ -  + ]:        816 :     if( eTok != SYMBOL && !pParser->IsKwd( eTok ) && !pParser->IsExtra( eTok ) )
         [ #  # ][ -  + ]
     365                 :            :     {
     366                 :            :         // #66745 Some operators can also be allowed
     367                 :            :         // as identifiers, important for StarOne
     368 [ #  # ][ #  # ]:          0 :         if( eTok != MOD && eTok != NOT && eTok != AND && eTok != OR &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     369                 :            :             eTok != XOR && eTok != EQV && eTok != IMP && eTok != IS )
     370                 :            :         {
     371         [ #  # ]:          0 :             pParser->Error( SbERR_VAR_EXPECTED );
     372                 :          0 :             bError = true;
     373                 :            :         }
     374                 :            :     }
     375                 :            : 
     376         [ -  + ]:        816 :     if( bError )
     377                 :          0 :         return NULL;
     378                 :            : 
     379         [ +  - ]:        816 :     String aSym( pParser->GetSym() );
     380                 :        816 :     SbxDataType eType = pParser->GetType();
     381                 :        816 :     SbiParameters* pPar = NULL;
     382                 :        816 :     SbiExprListVector* pvMoreParLcl = NULL;
     383         [ +  - ]:        816 :     eTok = pParser->Peek();
     384                 :            : 
     385 [ +  - ][ +  + ]:        816 :     if( DoParametersFollow( pParser, eCurExpr, eTok ) )
     386                 :            :     {
     387                 :        430 :         bool bStandaloneExpression = false;
     388 [ +  - ][ +  - ]:        430 :         pPar = new SbiParameters( pParser, bStandaloneExpression );
     389 [ +  - ][ -  + ]:        430 :         bError = bError || !pPar->IsValid();
     390         [ +  - ]:        430 :         eTok = pParser->Peek();
     391                 :            : 
     392                 :            :         // i109624 check for additional sets of parameters
     393         [ -  + ]:        430 :         while( eTok == LPAREN )
     394                 :            :         {
     395         [ #  # ]:          0 :             if( pvMoreParLcl == NULL )
     396 [ #  # ][ #  # ]:          0 :                 pvMoreParLcl = new SbiExprListVector();
     397 [ #  # ][ #  # ]:          0 :             SbiParameters* pAddPar = new SbiParameters( pParser );
     398         [ #  # ]:          0 :             pvMoreParLcl->push_back( pAddPar );
     399 [ #  # ][ #  # ]:          0 :             bError = bError || !pPar->IsValid();
     400         [ #  # ]:          0 :             eTok = pParser->Peek();
     401                 :            :         }
     402                 :            : 
     403                 :            :     }
     404 [ +  + ][ -  + ]:        816 :     sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() );
                 [ +  - ]
     405         [ +  + ]:        816 :     if( bObj )
     406                 :            :     {
     407         [ +  - ]:        207 :         if( eType == SbxVARIANT )
     408                 :        207 :             eType = SbxOBJECT;
     409                 :            :         else
     410                 :            :         {
     411                 :            :             // Name%. does really not work!
     412 [ #  # ][ #  # ]:          0 :             pParser->Error( SbERR_BAD_DECLARATION, aSym );
     413                 :          0 :             bError = true;
     414                 :            :         }
     415                 :            :     }
     416                 :            : 
     417                 :            :     // an object's symbol pool is always PUBLIC
     418         [ +  - ]:        816 :     SbiSymPool& rPool = rObj.GetPool();
     419                 :        816 :     rPool.SetScope( SbPUBLIC );
     420         [ +  - ]:        816 :     SbiSymDef* pDef = rPool.Find( aSym );
     421         [ +  + ]:        816 :     if( !pDef )
     422                 :            :     {
     423         [ +  - ]:        452 :         pDef = AddSym( eTok, rPool, eCurExpr, aSym, eType, pPar );
     424         [ +  - ]:        452 :         pDef->SetType( eType );
     425                 :            :     }
     426                 :            : 
     427 [ +  - ][ +  - ]:        816 :     SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
     428                 :        816 :     pNd->aVar.pPar = pPar;
     429                 :        816 :     pNd->aVar.pvMorePar = pvMoreParLcl;
     430         [ +  + ]:        816 :     if( bObj )
     431                 :            :     {
     432         [ +  + ]:        207 :         if( pDef->GetType() == SbxVARIANT )
     433         [ +  - ]:         13 :             pDef->SetType( SbxOBJECT );
     434                 :            : 
     435         [ -  + ]:        207 :         if( pDef->GetType() != SbxOBJECT )
     436                 :            :         {
     437 [ #  # ][ #  # ]:          0 :             pParser->Error( SbERR_BAD_DECLARATION, aSym );
     438                 :          0 :             bError = true;
     439                 :            :         }
     440         [ +  - ]:        207 :         if( !bError )
     441                 :            :         {
     442         [ +  - ]:        207 :             pNd->aVar.pNext = ObjTerm( *pDef );
     443                 :        207 :             pNd->eType = eType;
     444                 :            :         }
     445                 :            :     }
     446         [ +  - ]:        816 :     return pNd;
     447                 :            : }
     448                 :            : 
     449                 :            : // an operand can be:
     450                 :            : //      constant
     451                 :            : //      scalar variable
     452                 :            : //      structure elements
     453                 :            : //      array elements
     454                 :            : //      functions
     455                 :            : //      bracketed expressions
     456                 :            : 
     457                 :       5278 : SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf )
     458                 :            : {
     459                 :            :     SbiExprNode *pRes;
     460                 :            :     SbiToken eTok;
     461                 :            : 
     462                 :            :     // test operand:
     463   [ +  -  +  +  :       5278 :     switch( eTok = pParser->Peek() )
                   +  - ]
     464                 :            :     {
     465                 :            :         case SYMBOL:
     466                 :       3504 :             pRes = Term();
     467                 :            :             // process something like "IF Not r Is Nothing Then .."
     468 [ +  + ][ +  + ]:       3504 :             if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS )
         [ +  + ][ +  - ]
     469                 :            :             {
     470                 :          3 :                 eTok = pParser->Next();
     471         [ +  - ]:          3 :                 pRes = new SbiExprNode( pParser, pRes, eTok, Like() );
     472                 :            :             }
     473                 :       3504 :             break;
     474                 :            :         case DOT:   // .with
     475                 :          0 :             pRes = Term(); break;
     476                 :            :         case NUMBER:
     477                 :        486 :             pParser->Next();
     478         [ +  - ]:        486 :             pRes = new SbiExprNode( pParser, pParser->GetDbl(), pParser->GetType() );
     479                 :        486 :             break;
     480                 :            :         case FIXSTRING:
     481                 :       1142 :             pParser->Next();
     482 [ +  - ][ +  - ]:       1142 :             pRes = new SbiExprNode( pParser, pParser->GetSym() ); break;
     483                 :            :         case LPAREN:
     484                 :        146 :             pParser->Next();
     485 [ +  + ][ -  + ]:        146 :             if( nParenLevel == 0 && m_eMode == EXPRMODE_LPAREN_PENDING && pParser->Peek() == RPAREN )
         [ -  + ][ +  + ]
     486                 :            :             {
     487                 :          0 :                 m_eMode = EXPRMODE_EMPTY_PAREN;
     488         [ #  # ]:          0 :                 pRes = new SbiExprNode();   // Dummy node
     489                 :          0 :                 pParser->Next();
     490                 :          0 :                 break;
     491                 :            :             }
     492                 :        146 :             nParenLevel++;
     493                 :        146 :             pRes = Boolean();
     494         [ -  + ]:        146 :             if( pParser->Peek() != RPAREN )
     495                 :            :             {
     496                 :            :                 // If there was a LPARAM, it does not belong to the expression
     497 [ #  # ][ #  # ]:          0 :                 if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
     498                 :          0 :                     m_eMode = EXPRMODE_LPAREN_NOT_NEEDED;
     499                 :            :                 else
     500                 :          0 :                     pParser->Error( SbERR_BAD_BRACKETS );
     501                 :            :             }
     502                 :            :             else
     503                 :            :             {
     504                 :        146 :                 pParser->Next();
     505 [ +  + ][ +  + ]:        146 :                 if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
     506                 :            :                 {
     507                 :          8 :                     SbiToken eTokAfterRParen = pParser->Peek();
     508 [ +  - ][ +  - ]:          8 :                     if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT )
                 [ +  + ]
     509                 :          8 :                         m_eMode = EXPRMODE_ARRAY_OR_OBJECT;
     510                 :            :                     else
     511                 :          8 :                         m_eMode = EXPRMODE_STANDARD;
     512                 :            :                 }
     513                 :            :             }
     514                 :        146 :             nParenLevel--;
     515                 :        146 :             break;
     516                 :            :         default:
     517                 :            :             // keywords here are OK at the moment!
     518         [ #  # ]:          0 :             if( pParser->IsKwd( eTok ) )
     519                 :          0 :                 pRes = Term();
     520                 :            :             else
     521                 :            :             {
     522                 :          0 :                 pParser->Next();
     523         [ #  # ]:          0 :                 pRes = new SbiExprNode( pParser, 1.0, SbxDOUBLE );
     524                 :          0 :                 pParser->Error( SbERR_UNEXPECTED, eTok );
     525                 :            :             }
     526                 :            :     }
     527                 :       5278 :     return pRes;
     528                 :            : }
     529                 :            : 
     530                 :       5392 : SbiExprNode* SbiExpression::Unary()
     531                 :            : {
     532                 :            :     SbiExprNode* pNd;
     533                 :       5392 :     SbiToken eTok = pParser->Peek();
     534   [ +  +  -  -  :       5392 :     switch( eTok )
                   -  + ]
     535                 :            :     {
     536                 :            :         case MINUS:
     537                 :         66 :             eTok = NEG;
     538                 :         66 :             pParser->Next();
     539         [ +  - ]:         66 :             pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
     540                 :         66 :             break;
     541                 :            :         case NOT:
     542         [ -  + ]:         48 :             if( pParser->IsVBASupportOn() )
     543                 :            :             {
     544                 :          0 :                 pNd = Operand();
     545                 :            :             }
     546                 :            :             else
     547                 :            :             {
     548                 :         48 :                 pParser->Next();
     549         [ +  - ]:         48 :                 pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
     550                 :            :             }
     551                 :         48 :             break;
     552                 :            :         case PLUS:
     553                 :          0 :             pParser->Next();
     554                 :          0 :             pNd = Unary();
     555                 :          0 :             break;
     556                 :            :         case TYPEOF:
     557                 :            :         {
     558         [ #  # ]:          0 :             pParser->Next();
     559                 :          0 :             bool bUsedForTypeOf = true;
     560         [ #  # ]:          0 :             SbiExprNode* pObjNode = Operand( bUsedForTypeOf );
     561         [ #  # ]:          0 :             pParser->TestToken( IS );
     562         [ #  # ]:          0 :             String aDummy;
     563 [ #  # ][ #  # ]:          0 :             SbiSymDef* pTypeDef = new SbiSymDef( aDummy );
     564         [ #  # ]:          0 :             pParser->TypeDecl( *pTypeDef, sal_True );
     565 [ #  # ][ #  # ]:          0 :             pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() );
     566         [ #  # ]:          0 :             break;
     567                 :            :         }
     568                 :            :         case NEW:
     569                 :            :         {
     570         [ #  # ]:          0 :             pParser->Next();
     571         [ #  # ]:          0 :             String aStr;
     572 [ #  # ][ #  # ]:          0 :             SbiSymDef* pTypeDef = new SbiSymDef( aStr );
     573         [ #  # ]:          0 :             pParser->TypeDecl( *pTypeDef, sal_True );
     574 [ #  # ][ #  # ]:          0 :             pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() );
     575         [ #  # ]:          0 :             break;
     576                 :            :         }
     577                 :            :         default:
     578                 :       5278 :             pNd = Operand();
     579                 :            :     }
     580                 :       5392 :     return pNd;
     581                 :            : }
     582                 :            : 
     583                 :       5278 : SbiExprNode* SbiExpression::Exp()
     584                 :            : {
     585                 :       5278 :     SbiExprNode* pNd = Unary();
     586         [ +  - ]:       5278 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     587                 :            :     {
     588         [ -  + ]:       5278 :         while( pParser->Peek() == EXPON ) {
     589                 :          0 :             SbiToken eTok = pParser->Next();
     590         [ #  # ]:          0 :             pNd = new SbiExprNode( pParser, pNd, eTok, Unary() );
     591                 :            :         }
     592                 :            :     }
     593                 :       5278 :     return pNd;
     594                 :            : }
     595                 :            : 
     596                 :       5276 : SbiExprNode* SbiExpression::MulDiv()
     597                 :            : {
     598                 :       5276 :     SbiExprNode* pNd = Exp();
     599         [ +  - ]:       5276 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     600                 :            :     {
     601                 :       5278 :         for( ;; )
     602                 :            :         {
     603                 :       5278 :             SbiToken eTok = pParser->Peek();
     604 [ +  - ][ +  + ]:       5278 :             if( eTok != MUL && eTok != DIV )
     605                 :       5276 :                 break;
     606                 :          2 :             eTok = pParser->Next();
     607         [ +  - ]:          2 :             pNd = new SbiExprNode( pParser, pNd, eTok, Exp() );
     608                 :            :         }
     609                 :            :     }
     610                 :       5276 :     return pNd;
     611                 :            : }
     612                 :            : 
     613                 :       5276 : SbiExprNode* SbiExpression::IntDiv()
     614                 :            : {
     615                 :       5276 :     SbiExprNode* pNd = MulDiv();
     616         [ +  - ]:       5276 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     617                 :            :     {
     618         [ -  + ]:       5276 :         while( pParser->Peek() == IDIV ) {
     619                 :          0 :             SbiToken eTok = pParser->Next();
     620         [ #  # ]:          0 :             pNd = new SbiExprNode( pParser, pNd, eTok, MulDiv() );
     621                 :            :         }
     622                 :            :     }
     623                 :       5276 :     return pNd;
     624                 :            : }
     625                 :            : 
     626                 :       5276 : SbiExprNode* SbiExpression::Mod()
     627                 :            : {
     628                 :       5276 :     SbiExprNode* pNd = IntDiv();
     629         [ +  - ]:       5276 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     630                 :            :     {
     631         [ -  + ]:       5276 :         while( pParser->Peek() == MOD ) {
     632                 :          0 :             SbiToken eTok = pParser->Next();
     633         [ #  # ]:          0 :             pNd = new SbiExprNode( pParser, pNd, eTok, IntDiv() );
     634                 :            :         }
     635                 :            :     }
     636                 :       5276 :     return pNd;
     637                 :            : }
     638                 :            : 
     639                 :       4767 : SbiExprNode* SbiExpression::AddSub()
     640                 :            : {
     641                 :       4767 :     SbiExprNode* pNd = Mod();
     642         [ +  - ]:       4767 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     643                 :            :     {
     644                 :       5276 :         for( ;; )
     645                 :            :         {
     646                 :       5276 :             SbiToken eTok = pParser->Peek();
     647 [ +  + ][ +  + ]:       5276 :             if( eTok != PLUS && eTok != MINUS )
     648                 :       4767 :                 break;
     649                 :        509 :             eTok = pParser->Next();
     650         [ +  - ]:        509 :             pNd = new SbiExprNode( pParser, pNd, eTok, Mod() );
     651                 :            :         }
     652                 :            :     }
     653                 :       4767 :     return pNd;
     654                 :            : }
     655                 :            : 
     656                 :       4707 : SbiExprNode* SbiExpression::Cat()
     657                 :            : {
     658                 :       4707 :     SbiExprNode* pNd = AddSub();
     659         [ +  - ]:       4707 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     660                 :            :     {
     661                 :       4767 :         for( ;; )
     662                 :            :         {
     663                 :       4767 :             SbiToken eTok = pParser->Peek();
     664         [ +  + ]:       4767 :             if( eTok != CAT )
     665                 :       4707 :                 break;
     666                 :         60 :             eTok = pParser->Next();
     667         [ +  - ]:         60 :             pNd = new SbiExprNode( pParser, pNd, eTok, AddSub() );
     668                 :            :         }
     669                 :            :     }
     670                 :       4707 :     return pNd;
     671                 :            : }
     672                 :            : 
     673                 :       4607 : SbiExprNode* SbiExpression::Comp()
     674                 :            : {
     675                 :       4607 :     SbiExprNode* pNd = Cat();
     676         [ +  - ]:       4607 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     677                 :            :     {
     678                 :       4607 :         short nCount = 0;
     679                 :       4707 :         for( ;; )
     680                 :            :         {
     681                 :       4707 :             SbiToken eTok = pParser->Peek();
     682         [ +  + ]:       4707 :             if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT )
     683                 :          8 :                 break;
     684 [ +  + ][ +  + ]:       4699 :             if( eTok != EQ && eTok != NE && eTok != LT
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     685                 :            :              && eTok != GT && eTok != LE && eTok != GE )
     686                 :       4599 :                 break;
     687                 :        100 :             eTok = pParser->Next();
     688         [ +  - ]:        100 :             pNd = new SbiExprNode( pParser, pNd, eTok, Cat() );
     689                 :        100 :             nCount++;
     690                 :            :         }
     691                 :            :     }
     692                 :       4607 :     return pNd;
     693                 :            : }
     694                 :            : 
     695                 :            : 
     696                 :        757 : SbiExprNode* SbiExpression::VBA_Not()
     697                 :            : {
     698                 :        757 :     SbiExprNode* pNd = NULL;
     699                 :            : 
     700                 :        757 :     SbiToken eTok = pParser->Peek();
     701         [ +  + ]:        757 :     if( eTok == NOT )
     702                 :            :     {
     703                 :          3 :         pParser->Next();
     704         [ +  - ]:          3 :         pNd = new SbiExprNode( pParser, VBA_Not(), eTok, NULL );
     705                 :            :     }
     706                 :            :     else
     707                 :            :     {
     708                 :        754 :         pNd = Comp();
     709                 :            :     }
     710                 :        757 :     return pNd;
     711                 :            : }
     712                 :            : 
     713                 :       4607 : SbiExprNode* SbiExpression::Like()
     714                 :            : {
     715         [ +  + ]:       4607 :     SbiExprNode* pNd = pParser->IsVBASupportOn() ? VBA_Not() : Comp();
     716         [ +  - ]:       4607 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     717                 :            :     {
     718                 :       4607 :         short nCount = 0;
     719         [ -  + ]:       4607 :         while( pParser->Peek() == LIKE ) {
     720                 :          0 :             SbiToken eTok = pParser->Next();
     721         [ #  # ]:          0 :             pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++;
     722                 :            :         }
     723                 :            :         // multiple operands in a row does not work
     724 [ -  + ][ #  # ]:       4607 :         if( nCount > 1 && !pParser->IsVBASupportOn() )
                 [ -  + ]
     725                 :            :         {
     726                 :          0 :             pParser->Error( SbERR_SYNTAX );
     727                 :          0 :             bError = true;
     728                 :            :         }
     729                 :            :     }
     730                 :       4607 :     return pNd;
     731                 :            : }
     732                 :            : 
     733                 :       4436 : SbiExprNode* SbiExpression::Boolean()
     734                 :            : {
     735                 :       4436 :     SbiExprNode* pNd = Like();
     736         [ +  - ]:       4436 :     if( m_eMode != EXPRMODE_EMPTY_PAREN )
     737                 :            :     {
     738                 :       4604 :         for( ;; )
     739                 :            :         {
     740                 :       4604 :             SbiToken eTok = pParser->Peek();
     741 [ +  + ][ +  - ]:       4604 :             if( eTok != AND && eTok != OR && eTok != XOR
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
     742                 :            :              && eTok != EQV && eTok != IMP && eTok != IS )
     743                 :       4436 :                 break;
     744                 :        168 :             eTok = pParser->Next();
     745         [ +  - ]:        168 :             pNd = new SbiExprNode( pParser, pNd, eTok, Like() );
     746                 :            :         }
     747                 :            :     }
     748                 :       4436 :     return pNd;
     749                 :            : }
     750                 :            : 
     751                 :            : /***************************************************************************
     752                 :            : |*
     753                 :            : |*      SbiConstExpression
     754                 :            : |*
     755                 :            : ***************************************************************************/
     756                 :            : 
     757         [ +  - ]:        258 : SbiConstExpression::SbiConstExpression( SbiParser* p ) : SbiExpression( p )
     758                 :            : {
     759         [ +  - ]:        258 :     if( pExpr->IsConstant() )
     760                 :            :     {
     761                 :        258 :         eType = pExpr->GetType();
     762 [ +  + ][ +  - ]:        258 :         if( pExpr->IsNumber() )
     763                 :            :         {
     764                 :        126 :             nVal = pExpr->nVal;
     765                 :            :         }
     766                 :            :         else
     767                 :            :         {
     768                 :        132 :             nVal = 0;
     769         [ +  - ]:        132 :             aVal = pExpr->aStrVal;
     770                 :            :         }
     771                 :            :     }
     772                 :            :     else
     773                 :            :     {
     774                 :            :         // #40204 special treatment for sal_Bool-constants
     775                 :          0 :         sal_Bool bIsBool = sal_False;
     776         [ #  # ]:          0 :         if( pExpr->eNodeType == SbxVARVAL )
     777                 :            :         {
     778         [ #  # ]:          0 :             SbiSymDef* pVarDef = pExpr->GetVar();
     779                 :            : 
     780                 :          0 :             sal_Bool bBoolVal = sal_False;
     781 [ #  # ][ #  # ]:          0 :             if( pVarDef->GetName().EqualsIgnoreCaseAscii( "true" ) )
                 [ #  # ]
     782                 :            :             {
     783                 :          0 :                 bIsBool = sal_True;
     784                 :          0 :                 bBoolVal = sal_True;
     785                 :            :             }
     786 [ #  # ][ #  # ]:          0 :             else if( pVarDef->GetName().EqualsIgnoreCaseAscii( "false" ) )
                 [ #  # ]
     787                 :            :             //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
     788                 :            :             {
     789                 :          0 :                 bIsBool = sal_True;
     790                 :          0 :                 bBoolVal = sal_False;
     791                 :            :             }
     792                 :            : 
     793         [ #  # ]:          0 :             if( bIsBool )
     794                 :            :             {
     795 [ #  # ][ #  # ]:          0 :                 delete pExpr;
     796 [ #  # ][ #  # ]:          0 :                 pExpr = new SbiExprNode( pParser, (bBoolVal ? SbxTRUE : SbxFALSE), SbxINTEGER );
                 [ #  # ]
     797                 :          0 :                 eType = pExpr->GetType();
     798                 :          0 :                 nVal = pExpr->nVal;
     799                 :            :             }
     800                 :            :         }
     801                 :            : 
     802         [ #  # ]:          0 :         if( !bIsBool )
     803                 :            :         {
     804         [ #  # ]:          0 :             pParser->Error( SbERR_SYNTAX );
     805                 :          0 :             eType = SbxDOUBLE;
     806                 :          0 :             nVal = 0;
     807                 :            :         }
     808                 :            :     }
     809                 :        258 : }
     810                 :            : 
     811                 :          0 : short SbiConstExpression::GetShortValue()
     812                 :            : {
     813         [ #  # ]:          0 :     if( eType == SbxSTRING )
     814                 :            :     {
     815 [ #  # ][ #  # ]:          0 :         SbxVariableRef refConv = new SbxVariable;
     816 [ #  # ][ #  # ]:          0 :         refConv->PutString( aVal );
     817 [ #  # ][ #  # ]:          0 :         return refConv->GetInteger();
     818                 :            :     }
     819                 :            :     else
     820                 :            :     {
     821                 :          0 :         double n = nVal;
     822         [ #  # ]:          0 :         if( n > 0 ) n += .5; else n -= .5;
     823         [ #  # ]:          0 :         if( n > SbxMAXINT ) n = SbxMAXINT, pParser->Error( SbERR_OUT_OF_RANGE );
     824                 :            :         else
     825         [ #  # ]:          0 :         if( n < SbxMININT ) n = SbxMININT, pParser->Error( SbERR_OUT_OF_RANGE );
     826                 :          0 :         return (short) n;
     827                 :            :     }
     828                 :            : }
     829                 :            : 
     830                 :            : 
     831                 :            : /***************************************************************************
     832                 :            : |*
     833                 :            : |*      SbiExprList
     834                 :            : |*
     835                 :            : ***************************************************************************/
     836                 :            : 
     837                 :       5108 : SbiExprList::SbiExprList( SbiParser* p )
     838                 :            : {
     839                 :       5108 :     pParser = p;
     840                 :       5108 :     pFirst = NULL;
     841                 :            :     nExpr  =
     842                 :       5108 :     nDim   = 0;
     843                 :       5108 :     bError = false;
     844                 :       5108 :     bBracket = false;
     845                 :       5108 : }
     846                 :            : 
     847                 :       5108 : SbiExprList::~SbiExprList()
     848                 :            : {
     849                 :       5108 :     SbiExpression* p = pFirst;
     850         [ +  + ]:       7308 :     while( p )
     851                 :            :     {
     852                 :       2200 :         SbiExpression* q = p->pNext;
     853         [ +  - ]:       2200 :         delete p;
     854                 :       2200 :         p = q;
     855                 :            :     }
     856         [ -  + ]:       5108 : }
     857                 :            : 
     858                 :            : 
     859                 :          0 : SbiExpression* SbiExprList::Get( short n )
     860                 :            : {
     861                 :          0 :     SbiExpression* p = pFirst;
     862 [ #  # ][ #  # ]:          0 :     while( n-- && p )
                 [ #  # ]
     863                 :          0 :         p = p->pNext;
     864                 :          0 :     return p;
     865                 :            : }
     866                 :            : 
     867                 :          0 : void SbiExprList::addExpression( SbiExpression* pExpr )
     868                 :            : {
     869         [ #  # ]:          0 :     if( !pFirst )
     870                 :            :     {
     871                 :          0 :         pFirst = pExpr;
     872                 :          0 :         return;
     873                 :            :     }
     874                 :            : 
     875                 :          0 :     SbiExpression* p = pFirst;
     876         [ #  # ]:          0 :     while( p->pNext )
     877                 :          0 :         p = p->pNext;
     878                 :            : 
     879                 :          0 :     p->pNext = pExpr;
     880                 :            : }
     881                 :            : 
     882                 :            : 
     883                 :            : /***************************************************************************
     884                 :            : |*
     885                 :            : |*      SbiParameters
     886                 :            : |*
     887                 :            : ***************************************************************************/
     888                 :            : 
     889                 :            : // parsing constructor:
     890                 :            : // the parameter list is completely parsed
     891                 :            : // "procedurename()" is OK
     892                 :            : // it's a function without parameters then
     893                 :            : // i. e. you give an array as procedure parameter
     894                 :            : 
     895                 :            : // #i79918/#i80532: bConst has never been set to true
     896                 :            : // -> reused as bStandaloneExpression
     897                 :            : //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) :
     898                 :       5060 : SbiParameters::SbiParameters( SbiParser* p, bool bStandaloneExpression, bool bPar) :
     899                 :       5060 :     SbiExprList( p )
     900                 :            : {
     901         [ +  + ]:       5060 :     if( !bPar )
     902                 :            :         return;
     903                 :            : 
     904                 :            :     SbiExpression *pExpr;
     905         [ +  - ]:       1547 :     SbiToken eTok = pParser->Peek();
     906                 :            : 
     907                 :       1547 :     bool bAssumeExprLParenMode = false;
     908                 :       1547 :     bool bAssumeArrayMode = false;
     909         [ +  + ]:       1547 :     if( eTok == LPAREN )
     910                 :            :     {
     911         [ +  + ]:       1535 :         if( bStandaloneExpression )
     912                 :            :         {
     913                 :          8 :             bAssumeExprLParenMode = true;
     914                 :            :         }
     915                 :            :         else
     916                 :            :         {
     917                 :       1527 :             bBracket = true;
     918         [ +  - ]:       1527 :             pParser->Next();
     919         [ +  - ]:       1527 :             eTok = pParser->Peek();
     920                 :            :         }
     921                 :            :     }
     922                 :            : 
     923                 :            : 
     924 [ +  + ][ +  + ]:       1547 :     if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
         [ -  + ][ +  + ]
     925                 :            :     {
     926         [ +  - ]:         85 :         if( eTok == RPAREN )
     927         [ +  - ]:         85 :             pParser->Next();
     928                 :            :         return;
     929                 :            :     }
     930                 :            :     // read in parameter table and lay down in correct order!
     931                 :       1462 :     SbiExpression* pLast = NULL;
     932         [ +  - ]:       1462 :     String aName;
     933         [ +  - ]:       2158 :     while( !bError )
     934                 :            :     {
     935         [ +  - ]:       2158 :         aName.Erase();
     936                 :            :         // missing argument
     937         [ -  + ]:       2158 :         if( eTok == COMMA )
     938                 :            :         {
     939 [ #  # ][ #  # ]:          0 :             pExpr = new SbiExpression( pParser, 0, SbxEMPTY );
     940                 :            :         }
     941                 :            :         // named arguments: either .name= or name:=
     942                 :            :         else
     943                 :            :         {
     944                 :       2158 :             bool bByVal = false;
     945         [ -  + ]:       2158 :             if( eTok == BYVAL )
     946                 :            :             {
     947                 :          0 :                 bByVal = true;
     948         [ #  # ]:          0 :                 pParser->Next();
     949         [ #  # ]:          0 :                 eTok = pParser->Peek();
     950                 :            :             }
     951                 :            : 
     952         [ +  + ]:       2158 :             if( bAssumeExprLParenMode )
     953                 :            :             {
     954 [ +  - ][ +  - ]:          8 :                 pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING );
     955                 :          8 :                 bAssumeExprLParenMode = sal_False;
     956                 :            : 
     957                 :          8 :                 SbiExprMode eModeAfter = pExpr->m_eMode;
     958         [ -  + ]:          8 :                 if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED )
     959                 :            :                 {
     960                 :          0 :                     bBracket = true;
     961                 :            :                 }
     962         [ +  - ]:          8 :                 else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT )
     963                 :            :                 {
     964                 :            :                     // Expression "looks" like an array assignment
     965                 :            :                     // a(...)[(...)] = ? or a(...).b(...)
     966                 :            :                     // RPAREN is already parsed
     967                 :          8 :                     bBracket = true;
     968                 :          8 :                     bAssumeArrayMode = true;
     969                 :          8 :                     eTok = NIL;
     970                 :            :                 }
     971         [ #  # ]:          0 :                 else if( eModeAfter == EXPRMODE_EMPTY_PAREN )
     972                 :            :                 {
     973                 :          0 :                     bBracket = true;
     974 [ #  # ][ #  # ]:          0 :                     delete pExpr;
     975         [ #  # ]:          0 :                     if( bByVal )
     976         [ #  # ]:          0 :                         pParser->Error( SbERR_LVALUE_EXPECTED );
     977                 :            :                     return;
     978                 :            :                 }
     979                 :            :             }
     980                 :            :             else
     981 [ +  - ][ +  - ]:       2150 :                 pExpr = new SbiExpression( pParser );
     982                 :            : 
     983 [ -  + ][ #  # ]:       2158 :             if( bByVal && pExpr->IsLvalue() )
         [ #  # ][ -  + ]
     984                 :          0 :                 pExpr->SetByVal();
     985                 :            : 
     986         [ +  + ]:       2158 :             if( !bAssumeArrayMode )
     987                 :            :             {
     988 [ +  - ][ +  + ]:       2150 :                 if( pParser->Peek() == ASSIGN )
     989                 :            :                 {
     990                 :            :                     // VBA mode: name:=
     991                 :            :                     // SbiExpression::Term() has made as string out of it
     992         [ +  - ]:         52 :                     aName = pExpr->GetString();
     993 [ +  - ][ +  - ]:         52 :                     delete pExpr;
     994         [ +  - ]:         52 :                     pParser->Next();
     995 [ +  - ][ +  - ]:         52 :                     pExpr = new SbiExpression( pParser );
     996                 :            :                 }
     997         [ +  - ]:       2150 :                 pExpr->GetName() = aName;
     998                 :            :             }
     999                 :            :         }
    1000                 :       2158 :         pExpr->pNext = NULL;
    1001         [ +  + ]:       2158 :         if( !pLast )
    1002                 :       1462 :             pFirst = pLast = pExpr;
    1003                 :            :         else
    1004                 :        696 :             pLast->pNext = pExpr, pLast = pExpr;
    1005                 :       2158 :         nExpr++;
    1006 [ +  - ][ -  + ]:       2158 :         bError = bError || !pExpr->IsValid();
    1007                 :            : 
    1008         [ +  + ]:       2158 :         if( bAssumeArrayMode )
    1009                 :          8 :             break;
    1010                 :            : 
    1011                 :            :         // next element?
    1012         [ +  - ]:       2150 :         eTok = pParser->Peek();
    1013         [ +  + ]:       2150 :         if( eTok != COMMA )
    1014                 :            :         {
    1015 [ +  + ][ -  + ]:       1454 :             if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
         [ +  - ][ +  - ]
    1016                 :       1454 :                 break;
    1017                 :            :             pParser->Error( bBracket
    1018                 :            :                             ? SbERR_BAD_BRACKETS
    1019 [ #  # ][ #  # ]:          0 :                             : SbERR_EXPECTED, COMMA );
    1020                 :          0 :             bError = true;
    1021                 :            :         }
    1022                 :            :         else
    1023                 :            :         {
    1024         [ +  - ]:        696 :             pParser->Next();
    1025         [ +  - ]:        696 :             eTok = pParser->Peek();
    1026 [ +  + ][ +  - ]:        696 :             if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
         [ -  + ][ -  + ]
    1027                 :          0 :                 break;
    1028                 :            :         }
    1029                 :            :     }
    1030                 :            :     // closing bracket
    1031         [ +  + ]:       1462 :     if( eTok == RPAREN )
    1032                 :            :     {
    1033         [ +  - ]:       1442 :         pParser->Next();
    1034         [ +  - ]:       1442 :         pParser->Peek();
    1035         [ -  + ]:       1442 :         if( !bBracket )
    1036                 :            :         {
    1037         [ #  # ]:          0 :             pParser->Error( SbERR_BAD_BRACKETS );
    1038                 :          0 :             bError = true;
    1039                 :            :         }
    1040                 :            :     }
    1041 [ +  - ][ +  - ]:       5060 :     nDim = nExpr;
    1042                 :            : }
    1043                 :            : 
    1044                 :            : /***************************************************************************
    1045                 :            : |*
    1046                 :            : |*      SbiDimList
    1047                 :            : |*
    1048                 :            : ***************************************************************************/
    1049                 :            : 
    1050                 :            : // parsing constructor:
    1051                 :            : // A list of array dimensions is parsed. The expressions are tested for being
    1052                 :            : // numeric. The bCONST-Bit is reset when all expressions are Integer constants.
    1053                 :            : 
    1054                 :         48 : SbiDimList::SbiDimList( SbiParser* p ) : SbiExprList( p )
    1055                 :            : {
    1056                 :         48 :     bConst = true;
    1057                 :            : 
    1058 [ -  + ][ +  - ]:         48 :     if( pParser->Next() != LPAREN )
    1059                 :            :     {
    1060         [ #  # ]:          0 :         pParser->Error( SbERR_EXPECTED, LPAREN );
    1061                 :         48 :         bError = true; return;
    1062                 :            :     }
    1063                 :            : 
    1064 [ +  - ][ +  + ]:         48 :     if( pParser->Peek() != RPAREN )
    1065                 :            :     {
    1066                 :         38 :         SbiExpression *pExpr1, *pExpr2, *pLast = NULL;
    1067                 :            :         SbiToken eTok;
    1068                 :         42 :         for( ;; )
    1069                 :            :         {
    1070 [ +  - ][ +  - ]:         42 :             pExpr1 = new SbiExpression( pParser );
    1071         [ +  - ]:         42 :             eTok = pParser->Next();
    1072         [ -  + ]:         42 :             if( eTok == TO )
    1073                 :            :             {
    1074 [ #  # ][ #  # ]:          0 :                 pExpr2 = new SbiExpression( pParser );
    1075         [ #  # ]:          0 :                 eTok = pParser->Next();
    1076 [ #  # ][ #  # ]:          0 :                 bConst = bConst && pExpr1->IsIntConstant() && pExpr2->IsIntConstant();
         [ #  # ][ #  # ]
                 [ #  # ]
    1077 [ #  # ][ #  # ]:          0 :                 bError = bError || !pExpr1->IsValid() || !pExpr2->IsValid();
                 [ #  # ]
    1078                 :          0 :                 pExpr1->pNext = pExpr2;
    1079         [ #  # ]:          0 :                 if( !pLast )
    1080                 :          0 :                     pFirst = pExpr1;
    1081                 :            :                 else
    1082                 :          0 :                     pLast->pNext = pExpr1;
    1083                 :          0 :                 pLast = pExpr2;
    1084                 :          0 :                 nExpr += 2;
    1085                 :            :             }
    1086                 :            :             else
    1087                 :            :             {
    1088                 :         42 :                 pExpr1->SetBased();
    1089                 :         42 :                 pExpr1->pNext = NULL;
    1090 [ +  - ][ +  - ]:         42 :                 bConst = bConst && pExpr1->IsIntConstant();
                 [ +  - ]
    1091 [ +  - ][ -  + ]:         42 :                 bError = bError || !pExpr1->IsValid();
    1092         [ +  + ]:         42 :                 if( !pLast )
    1093                 :         38 :                     pFirst = pLast = pExpr1;
    1094                 :            :                 else
    1095                 :          4 :                     pLast->pNext = pExpr1, pLast = pExpr1;
    1096                 :         42 :                 nExpr++;
    1097                 :            :             }
    1098                 :         42 :             nDim++;
    1099         [ +  + ]:         42 :             if( eTok == RPAREN ) break;
    1100         [ -  + ]:          4 :             if( eTok != COMMA )
    1101                 :            :             {
    1102         [ #  # ]:          0 :                 pParser->Error( SbERR_BAD_BRACKETS );
    1103         [ #  # ]:          0 :                 pParser->Next();
    1104                 :          0 :                 break;
    1105                 :            :             }
    1106                 :            :         }
    1107                 :            :     }
    1108         [ +  - ]:         10 :     else pParser->Next();
    1109                 :            : }
    1110                 :            : 
    1111                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10