LCOV - code coverage report
Current view: top level - basic/source/comp - exprtree.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 430 585 73.5 %
Date: 2014-11-03 Functions: 25 29 86.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10