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

Generated by: LCOV version 1.10