LCOV - code coverage report
Current view: top level - basic/source/comp - dim.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 272 663 41.0 %
Date: 2012-08-25 Functions: 8 19 42.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 339 1228 27.6 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <basic/sbx.hxx>
      21                 :            : #include "sbcomp.hxx"
      22                 :            : #include "sbunoobj.hxx"
      23                 :            : 
      24                 :            : 
      25                 :            : SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
      26                 :            : 
      27                 :            : // Declaration of a variable
      28                 :            : // If there are errors it will be parsed up to the comma or the newline.
      29                 :            : // Return-value: a new instance, which were inserted and then deleted.
      30                 :            : // Array-Indexex were returned as SbiDimList
      31                 :            : 
      32                 :        700 : SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, bool bStatic, bool bConst )
      33                 :            : {
      34                 :        700 :     bool bWithEvents = false;
      35         [ -  + ]:        700 :     if( Peek() == WITHEVENTS )
      36                 :            :     {
      37                 :          0 :         Next();
      38                 :          0 :         bWithEvents = true;
      39                 :            :     }
      40         [ -  + ]:        700 :     if( !TestSymbol() ) return NULL;
      41                 :        700 :     SbxDataType t = eScanType;
      42 [ +  + ][ +  - ]:        700 :     SbiSymDef* pDef = bConst ? new SbiConstDef( aSym ) : new SbiSymDef( aSym );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
           [ #  #  #  # ]
      43                 :        700 :     SbiDimList* pDim = NULL;
      44                 :            :     // Brackets?
      45         [ +  + ]:        700 :     if( Peek() == LPAREN )
      46                 :            :     {
      47         [ +  - ]:         48 :         pDim = new SbiDimList( this );
      48         [ +  + ]:         48 :         if( !pDim->GetDims() )
      49                 :         10 :             pDef->SetWithBrackets();
      50                 :            :     }
      51                 :        700 :     pDef->SetType( t );
      52         [ -  + ]:        700 :     if( bStatic )
      53                 :          0 :         pDef->SetStatic();
      54         [ -  + ]:        700 :     if( bWithEvents )
      55                 :          0 :         pDef->SetWithEvents();
      56                 :        700 :     TypeDecl( *pDef );
      57 [ -  + ][ +  + ]:        700 :     if( !ppDim && pDim )
      58                 :            :     {
      59         [ #  # ]:          0 :         if(pDim->GetDims() )
      60                 :          0 :             Error( SbERR_EXPECTED, "()" );
      61         [ #  # ]:          0 :         delete pDim;
      62                 :            :     }
      63         [ +  + ]:        700 :     else if( ppDim )
      64                 :        572 :         *ppDim = pDim;
      65                 :        700 :     return pDef;
      66                 :            : }
      67                 :            : 
      68                 :            : // Resolving of a AS-Type-Declaration
      69                 :            : // The data type were inserted into the handed over variable
      70                 :            : 
      71                 :        897 : void SbiParser::TypeDecl( SbiSymDef& rDef, bool bAsNewAlreadyParsed )
      72                 :            : {
      73                 :        897 :     SbxDataType eType = rDef.GetType();
      74 [ +  + ][ +  + ]:        897 :     if( bAsNewAlreadyParsed || Peek() == AS )
                 [ +  - ]
      75                 :            :     {
      76                 :        448 :         short nSize = 0;
      77         [ +  - ]:        448 :         if( !bAsNewAlreadyParsed )
      78                 :        448 :             Next();
      79                 :        448 :         rDef.SetDefinedAs();
      80                 :        448 :         SbiToken eTok = Next();
      81 [ +  + ][ +  - ]:        448 :         if( !bAsNewAlreadyParsed && eTok == NEW )
      82                 :            :         {
      83                 :         40 :             rDef.SetNew();
      84                 :         40 :             eTok = Next();
      85                 :            :         }
      86   [ -  +  +  +  :        448 :         switch( eTok )
                      - ]
      87                 :            :         {
      88                 :            :             case ANY:
      89         [ #  # ]:          0 :                 if( rDef.IsNew() )
      90                 :          0 :                     Error( SbERR_SYNTAX );
      91                 :          0 :                 eType = SbxVARIANT; break;
      92                 :            :             case TINTEGER:
      93                 :            :             case TLONG:
      94                 :            :             case TSINGLE:
      95                 :            :             case TDOUBLE:
      96                 :            :             case TCURRENCY:
      97                 :            :             case TDATE:
      98                 :            :             case TSTRING:
      99                 :            :             case TOBJECT:
     100                 :            :             case _ERROR_:
     101                 :            :             case TBOOLEAN:
     102                 :            :             case TVARIANT:
     103                 :            :             case TBYTE:
     104         [ -  + ]:        402 :                 if( rDef.IsNew() )
     105                 :          0 :                     Error( SbERR_SYNTAX );
     106         [ +  - ]:        402 :                 eType = (eTok==TBYTE) ? SbxBYTE : SbxDataType( eTok - TINTEGER + SbxINTEGER );
     107         [ +  + ]:        402 :                 if( eType == SbxSTRING )
     108                 :            :                 {
     109                 :            :                     // STRING*n ?
     110         [ -  + ]:        147 :                     if( Peek() == MUL )
     111                 :            :                     {       // fixed size!
     112         [ #  # ]:          0 :                         Next();
     113         [ #  # ]:          0 :                         SbiConstExpression aSize( this );
     114         [ #  # ]:          0 :                         nSize = aSize.GetShortValue();
     115 [ #  # ][ #  # ]:          0 :                         if( nSize < 0 || (bVBASupportOn && nSize <= 0) )
                 [ #  # ]
     116         [ #  # ]:          0 :                             Error( SbERR_OUT_OF_RANGE );
     117                 :            :                         else
     118         [ #  # ]:          0 :                             rDef.SetFixedStringLength( nSize );
     119                 :            :                     }
     120                 :            :                 }
     121                 :        402 :                 break;
     122                 :            :             case SYMBOL: // can only be a TYPE or a object class!
     123         [ -  + ]:         28 :                 if( eScanType != SbxVARIANT )
     124                 :          0 :                     Error( SbERR_SYNTAX );
     125                 :            :                 else
     126                 :            :                 {
     127         [ +  - ]:         28 :                     String aCompleteName = aSym;
     128                 :            : 
     129                 :            :                     // #52709 DIM AS NEW for Uno with full-qualified name
     130 [ +  - ][ +  + ]:         28 :                     if( Peek() == DOT )
     131                 :            :                     {
     132                 :         22 :                         rtl::OUString aDotStr( '.' );
     133 [ +  - ][ +  + ]:        110 :                         while( Peek() == DOT )
     134                 :            :                         {
     135         [ +  - ]:         88 :                             aCompleteName += aDotStr;
     136         [ +  - ]:         88 :                             Next();
     137         [ +  - ]:         88 :                             SbiToken ePeekTok = Peek();
     138 [ -  + ][ #  # ]:         88 :                             if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
                 [ +  - ]
     139                 :            :                             {
     140         [ +  - ]:         88 :                                 Next();
     141         [ +  - ]:         88 :                                 aCompleteName += aSym;
     142                 :            :                             }
     143                 :            :                             else
     144                 :            :                             {
     145         [ #  # ]:          0 :                                 Next();
     146         [ #  # ]:          0 :                                 Error( SbERR_UNEXPECTED, SYMBOL );
     147                 :          0 :                                 break;
     148                 :            :                             }
     149                 :         22 :                         }
     150                 :            :                     }
     151 [ +  - ][ +  - ]:          6 :                     else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) || ( IsVBASupportOn() && VBAConstantHelper::instance().isVBAConstantType( aCompleteName ) ) )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ +  - ][ +  - ]
           [ -  +  #  #  
                   #  # ]
     152                 :            :                     {
     153                 :          0 :                         eType = SbxLONG;
     154                 :            :                         break;
     155                 :            :                     }
     156                 :            : 
     157                 :            :                     // Take over in the String pool
     158 [ +  - ][ +  - ]:         28 :                     rDef.SetTypeId( aGblStrings.Add( aCompleteName ) );
     159                 :            : 
     160 [ -  + ][ -  + ]:         28 :                     if( rDef.IsNew() && pProc == NULL )
                 [ +  + ]
     161 [ #  # ][ +  - ]:         28 :                         aRequiredTypes.push_back( aCompleteName );
                 [ +  - ]
     162                 :            :                 }
     163                 :         28 :                 eType = SbxOBJECT;
     164                 :         28 :                 break;
     165                 :            :             case FIXSTRING: // new syntax for complex UNO types
     166                 :         18 :                 rDef.SetTypeId( aGblStrings.Add( aSym ) );
     167                 :         18 :                 eType = SbxOBJECT;
     168                 :         18 :                 break;
     169                 :            :             default:
     170                 :          0 :                 Error( SbERR_UNEXPECTED, eTok );
     171                 :          0 :                 Next();
     172                 :            :         }
     173                 :            :         // The variable could have been declared with a suffix
     174         [ +  + ]:        448 :         if( rDef.GetType() != SbxVARIANT )
     175                 :            :         {
     176         [ -  + ]:         46 :             if( rDef.GetType() != eType )
     177         [ #  # ]:          0 :                 Error( SbERR_VAR_DEFINED, rDef.GetName() );
     178 [ -  + ][ #  # ]:         46 :             else if( eType == SbxSTRING && rDef.GetLen() != nSize )
                 [ -  + ]
     179         [ #  # ]:          0 :                 Error( SbERR_VAR_DEFINED, rDef.GetName() );
     180                 :            :         }
     181                 :        448 :         rDef.SetType( eType );
     182                 :        448 :         rDef.SetLen( nSize );
     183                 :            :     }
     184                 :        897 : }
     185                 :            : 
     186                 :            : // Here variables, arrays and structures were definied.
     187                 :            : // DIM/PRIVATE/PUBLIC/GLOBAL
     188                 :            : 
     189                 :        435 : void SbiParser::Dim()
     190                 :            : {
     191 [ +  + ][ +  + ]:        435 :     DefVar( _DIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
     192                 :        435 : }
     193                 :            : 
     194                 :        435 : void SbiParser::DefVar( SbiOpcode eOp, bool bStatic )
     195                 :            : {
     196                 :        435 :     SbiSymPool* pOldPool = pPool;
     197                 :        435 :     bool bSwitchPool = false;
     198                 :        435 :     bool bPersistantGlobal = false;
     199                 :        435 :     SbiToken eFirstTok = eCurTok;
     200 [ +  + ][ +  - ]:        435 :     if( pProc && ( eCurTok == GLOBAL || eCurTok == PUBLIC || eCurTok == PRIVATE ) )
         [ +  - ][ -  + ]
     201         [ #  # ]:          0 :         Error( SbERR_NOT_IN_SUBR, eCurTok );
     202 [ +  - ][ +  + ]:        435 :     if( eCurTok == PUBLIC || eCurTok == GLOBAL )
     203                 :            :     {
     204                 :        132 :         bSwitchPool = true;     // at the right moment switch to the global pool
     205         [ +  - ]:        132 :         if( eCurTok == GLOBAL )
     206                 :        132 :             bPersistantGlobal = true;
     207                 :            :     }
     208                 :            :     // behavior in VBA is that a module scope variable's lifetime is
     209                 :            :     // tied to the document. e.g. a module scope variable is global
     210 [ +  + ][ +  + ]:        435 :        if(  GetBasic()->IsDocBasic() && bVBASupportOn && !pProc )
         [ +  + ][ +  + ]
     211                 :         25 :         bPersistantGlobal = true;
     212                 :            :     // PRIVATE is a synonymous for DIM
     213                 :            :     // _CONST_?
     214                 :        435 :     bool bConst = false;
     215         [ +  + ]:        435 :     if( eCurTok == _CONST_ )
     216                 :         62 :         bConst = true;
     217 [ +  - ][ +  + ]:        373 :     else if( Peek() == _CONST_ )
     218         [ +  - ]:         90 :         Next(), bConst = true;
     219                 :            : 
     220                 :            :     // #110004 It can also be a sub/function
     221 [ +  + ][ +  + ]:        435 :     if( !bConst && (eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ||
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
     222                 :            :                     eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE || eCurTok == TYPE) )
     223                 :            :     {
     224                 :            :         // Next token is read here, because !bConst
     225                 :         17 :         bool bPrivate = ( eFirstTok == PRIVATE );
     226                 :            : 
     227         [ -  + ]:         17 :         if( eCurTok == STATIC )
     228                 :            :         {
     229         [ #  # ]:          0 :             Next();
     230         [ #  # ]:          0 :             DefStatic( bPrivate );
     231                 :            :         }
     232 [ -  + ][ #  # ]:         17 :         else if( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY )
                 [ #  # ]
     233                 :            :         {
     234                 :            :             // End global chain if necessary (not done in
     235                 :            :             // SbiParser::Parse() under these conditions
     236 [ -  + ][ #  # ]:         17 :             if( bNewGblDefs && nGblChain == 0 )
     237                 :            :             {
     238         [ #  # ]:          0 :                 nGblChain = aGen.Gen( _JUMP, 0 );
     239                 :          0 :                 bNewGblDefs = false;
     240                 :            :             }
     241         [ +  - ]:         17 :             Next();
     242         [ +  - ]:         17 :             DefProc( false, bPrivate );
     243                 :            :             return;
     244                 :            :         }
     245         [ #  # ]:          0 :         else if( eCurTok == ENUM )
     246                 :            :         {
     247         [ #  # ]:          0 :             Next();
     248         [ #  # ]:          0 :             DefEnum( bPrivate );
     249                 :            :             return;
     250                 :            :         }
     251         [ #  # ]:          0 :         else if( eCurTok == DECLARE )
     252                 :            :         {
     253         [ #  # ]:          0 :             Next();
     254         [ #  # ]:          0 :             DefDeclare( bPrivate );
     255                 :            :             return;
     256                 :            :         }
     257                 :            :         // #i109049
     258         [ #  # ]:          0 :         else if( eCurTok == TYPE )
     259                 :            :         {
     260         [ #  # ]:          0 :             Next();
     261         [ #  # ]:          0 :             DefType( bPrivate );
     262                 :            :             return;
     263                 :            :         }
     264                 :            :     }
     265                 :            : 
     266                 :            : #ifdef SHARED
     267                 :            : #define tmpSHARED
     268                 :            : #undef SHARED
     269                 :            : #endif
     270                 :            :     // SHARED were ignored
     271 [ +  - ][ -  + ]:        418 :     if( Peek() == SHARED ) Next();
                 [ #  # ]
     272                 :            : #ifdef tmpSHARED
     273                 :            : #define SHARED
     274                 :            : #undef tmpSHARED
     275                 :            : #endif
     276                 :            :     // PRESERVE only at REDIM
     277 [ +  - ][ -  + ]:        418 :     if( Peek() == PRESERVE )
     278                 :            :     {
     279         [ #  # ]:          0 :         Next();
     280         [ #  # ]:          0 :         if( eOp == _REDIM )
     281                 :          0 :             eOp = _REDIMP;
     282                 :            :         else
     283         [ #  # ]:          0 :             Error( SbERR_UNEXPECTED, eCurTok );
     284                 :            :     }
     285                 :            :     SbiSymDef* pDef;
     286                 :            :     SbiDimList* pDim;
     287                 :            : 
     288                 :            :     // #40689, Statics -> Modul-Initialising, skip in Sub
     289                 :        418 :     sal_uInt32 nEndOfStaticLbl = 0;
     290 [ +  + ][ -  + ]:        418 :     if( !bVBASupportOn && bStatic )
     291                 :            :     {
     292         [ #  # ]:          0 :         nEndOfStaticLbl = aGen.Gen( _JUMP, 0 );
     293         [ #  # ]:          0 :         aGen.Statement();   // catch up on static here
     294                 :            :     }
     295                 :            : 
     296                 :        418 :     bool bDefined = false;
     297 [ +  - ][ +  - ]:        572 :     while( ( pDef = VarDecl( &pDim, bStatic, bConst ) ) != NULL )
     298                 :            :     {
     299                 :        572 :         EnableErrors();
     300                 :            :         // search variable:
     301         [ +  + ]:        572 :         if( bSwitchPool )
     302                 :        244 :             pPool = &aGlobals;
     303 [ +  - ][ +  - ]:        572 :         SbiSymDef* pOld = pPool->Find( pDef->GetName() );
     304                 :            :         // search also in the Runtime-Library
     305                 :        572 :         bool bRtlSym = false;
     306         [ +  - ]:        572 :         if( !pOld )
     307                 :            :         {
     308 [ +  - ][ +  - ]:        572 :             pOld = CheckRTLForSym( pDef->GetName(), SbxVARIANT );
     309         [ -  + ]:        572 :             if( pOld )
     310                 :          0 :                 bRtlSym = true;
     311                 :            :         }
     312 [ -  + ][ #  # ]:        572 :         if( pOld && !(eOp == _REDIM || eOp == _REDIMP) )
                 [ #  # ]
     313                 :            :         {
     314 [ #  # ][ #  # ]:          0 :             if( pDef->GetScope() == SbLOCAL && pOld->GetScope() != SbLOCAL )
         [ #  # ][ #  # ]
                 [ #  # ]
     315                 :          0 :                 pOld = NULL;
     316                 :            :         }
     317         [ -  + ]:        572 :         if( pOld )
     318                 :            :         {
     319                 :          0 :             bDefined = true;
     320                 :            :             // always an error at a RTL-S
     321 [ #  # ][ #  # ]:          0 :             if( !bRtlSym && (eOp == _REDIM || eOp == _REDIMP) )
                 [ #  # ]
     322                 :            :             {
     323                 :            :                 // compare the attributes at a REDIM
     324                 :            :                 SbxDataType eDefType;
     325                 :          0 :                 bool bError_ = false;
     326         [ #  # ]:          0 :                 if( pOld->IsStatic() )
     327                 :            :                 {
     328                 :          0 :                     bError_ = true;
     329                 :            :                 }
     330         [ #  # ]:          0 :                 else if( pOld->GetType() != ( eDefType = pDef->GetType() ) )
     331                 :            :                 {
     332 [ #  # ][ #  # ]:          0 :                     if( !( eDefType == SbxVARIANT && !pDef->IsDefinedAs() ) )
                 [ #  # ]
     333                 :          0 :                         bError_ = true;
     334                 :            :                 }
     335         [ #  # ]:          0 :                 if( bError_ )
     336 [ #  # ][ #  # ]:          0 :                     Error( SbERR_VAR_DEFINED, pDef->GetName() );
                 [ #  # ]
     337                 :            :             }
     338                 :            :             else
     339 [ #  # ][ #  # ]:          0 :                 Error( SbERR_VAR_DEFINED, pDef->GetName() );
                 [ #  # ]
     340 [ #  # ][ #  # ]:          0 :             delete pDef; pDef = pOld;
     341                 :            :         }
     342                 :            :         else
     343         [ +  - ]:        572 :             pPool->Add( pDef );
     344                 :            : 
     345                 :            :         // #36374: Create the variable in front of the distinction IsNew()
     346                 :            :         // Otherwise error at Dim Identifier As New Type and option explicit
     347 [ +  - ][ +  - ]:        830 :         if( !bDefined && !(eOp == _REDIM || eOp == _REDIMP)
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
     348         [ +  - ]:        258 :                       && ( !bConst || pDef->GetScope() == SbGLOBAL ) )
     349                 :            :         {
     350                 :            :             // Declare variable or global constant
     351                 :            :             SbiOpcode eOp2;
     352         [ +  - ]:        498 :             switch ( pDef->GetScope() )
              [ +  +  + ]
     353                 :            :             {
     354         [ +  - ]:        244 :                 case SbGLOBAL:  eOp2 = bPersistantGlobal ? _GLOBAL_P : _GLOBAL;
     355                 :        244 :                                 goto global;
     356         [ +  + ]:         10 :                 case SbPUBLIC:  eOp2 = bPersistantGlobal ? _PUBLIC_P : _PUBLIC;
     357                 :            :                                 // #40689, no own Opcode anymore
     358 [ +  + ][ -  + ]:         10 :                                 if( bVBASupportOn && bStatic )
     359                 :            :                                 {
     360                 :          0 :                                     eOp2 = _STATIC;
     361                 :          0 :                                     break;
     362                 :            :                                 }
     363         [ +  - ]:        254 :                 global:         aGen.BackChain( nGblChain );
     364                 :        254 :                                 nGblChain = 0;
     365                 :        254 :                                 bGblDefs = bNewGblDefs = true;
     366                 :        254 :                                 break;
     367                 :        244 :                 default:        eOp2 = _LOCAL;
     368                 :            :             }
     369                 :        498 :             sal_uInt32 nOpnd2 = sal::static_int_cast< sal_uInt16 >( pDef->GetType() );
     370         [ -  + ]:        498 :             if( pDef->IsWithEvents() )
     371                 :          0 :                 nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG;
     372                 :            : 
     373 [ +  + ][ -  + ]:        498 :             if( bCompatible && pDef->IsNew() )
                 [ -  + ]
     374                 :          0 :                 nOpnd2 |= SBX_TYPE_DIM_AS_NEW_FLAG;
     375                 :            : 
     376                 :        498 :             short nFixedStringLength = pDef->GetFixedStringLength();
     377         [ -  + ]:        498 :             if( nFixedStringLength >= 0 )
     378                 :          0 :                 nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (sal_uInt32(nFixedStringLength) << 17));     // len = all bits above 0x10000
     379                 :            : 
     380 [ +  + ][ +  + ]:        498 :             if( pDim != NULL && pDim->GetDims() > 0 )
                 [ +  + ]
     381                 :         38 :                 nOpnd2 |= SBX_TYPE_VAR_TO_DIM_FLAG;
     382                 :            : 
     383         [ +  - ]:        498 :             aGen.Gen( eOp2, pDef->GetId(), nOpnd2 );
     384                 :            :         }
     385                 :            : 
     386                 :            :         // Initialising for self-defined daty types
     387                 :            :         // and per NEW created variable
     388   [ +  +  +  + ]:        700 :         if( pDef->GetType() == SbxOBJECT
                 [ +  + ]
     389                 :        128 :          && pDef->GetTypeId() )
     390                 :            :         {
     391 [ +  - ][ -  + ]:         40 :             if( !bCompatible && !pDef->IsNew() )
                 [ -  + ]
     392                 :            :             {
     393 [ #  # ][ #  # ]:          0 :                 String aTypeName( aGblStrings.Find( pDef->GetTypeId() ) );
     394 [ #  # ][ #  # ]:          0 :                 if( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) == NULL )
                 [ #  # ]
     395 [ #  # ][ #  # ]:          0 :                     Error( SbERR_UNDEF_TYPE, aTypeName );
                 [ #  # ]
     396                 :            :             }
     397                 :            : 
     398         [ -  + ]:         40 :             if( bConst )
     399                 :            :             {
     400         [ #  # ]:          0 :                 Error( SbERR_SYNTAX );
     401                 :            :             }
     402                 :            : 
     403         [ +  + ]:         40 :             if( pDim )
     404                 :            :             {
     405         [ -  + ]:          8 :                 if( eOp == _REDIMP )
     406                 :            :                 {
     407         [ #  # ]:          0 :                     SbiExpression aExpr( this, *pDef, NULL );
     408         [ #  # ]:          0 :                     aExpr.Gen();
     409         [ #  # ]:          0 :                     aGen.Gen( _REDIMP_ERASE );
     410                 :            : 
     411                 :          0 :                     pDef->SetDims( pDim->GetDims() );
     412         [ #  # ]:          0 :                     SbiExpression aExpr2( this, *pDef, pDim );
     413         [ #  # ]:          0 :                     aExpr2.Gen();
     414 [ #  # ][ #  # ]:          0 :                     aGen.Gen( _DCREATE_REDIMP, pDef->GetId(), pDef->GetTypeId() );
                 [ #  # ]
     415                 :            :                 }
     416                 :            :                 else
     417                 :            :                 {
     418                 :          8 :                     pDef->SetDims( pDim->GetDims() );
     419         [ +  - ]:          8 :                     SbiExpression aExpr( this, *pDef, pDim );
     420         [ +  - ]:          8 :                     aExpr.Gen();
     421 [ +  - ][ +  - ]:          8 :                     aGen.Gen( _DCREATE, pDef->GetId(), pDef->GetTypeId() );
     422                 :            :                 }
     423                 :            :             }
     424                 :            :             else
     425                 :            :             {
     426         [ +  - ]:         32 :                 SbiExpression aExpr( this, *pDef );
     427         [ +  - ]:         32 :                 aExpr.Gen();
     428         [ +  - ]:         32 :                 SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE;
     429         [ +  - ]:         32 :                 aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
     430         [ -  + ]:         32 :                 if ( bVBASupportOn )
     431         [ #  # ]:          0 :                     aGen.Gen( _VBASET );
     432                 :            :                 else
     433 [ +  - ][ +  - ]:         32 :                     aGen.Gen( _SET );
     434                 :            :             }
     435                 :            :         }
     436                 :            :         else
     437                 :            :         {
     438         [ +  + ]:        532 :             if( bConst )
     439                 :            :             {
     440                 :            :                 // Definition of the constants
     441         [ -  + ]:        258 :                 if( pDim )
     442                 :            :                 {
     443         [ #  # ]:          0 :                     Error( SbERR_SYNTAX );
     444 [ #  # ][ #  # ]:          0 :                     delete pDim;
     445                 :            :                 }
     446         [ +  - ]:        258 :                 SbiExpression aVar( this, *pDef );
     447 [ +  - ][ -  + ]:        258 :                 if( !TestToken( EQ ) )
     448                 :            :                     goto MyBreak;   // (see below)
     449         [ +  - ]:        258 :                 SbiConstExpression aExpr( this );
     450 [ +  - ][ +  - ]:        258 :                 if( !bDefined && aExpr.IsValid() )
                 [ +  - ]
     451                 :            :                 {
     452 [ +  - ][ +  + ]:        258 :                     if( pDef->GetScope() == SbGLOBAL )
     453                 :            :                     {
     454                 :            :                         // Create code only for the global constant!
     455         [ +  - ]:        184 :                         aVar.Gen();
     456         [ +  - ]:        184 :                         aExpr.Gen();
     457         [ +  - ]:        184 :                         aGen.Gen( _PUTC );
     458                 :            :                     }
     459         [ +  - ]:        258 :                     SbiConstDef* pConst = pDef->GetConstDef();
     460         [ +  + ]:        258 :                     if( aExpr.GetType() == SbxSTRING )
     461         [ +  - ]:        132 :                         pConst->Set( aExpr.GetString() );
     462                 :            :                     else
     463         [ +  - ]:        126 :                         pConst->Set( aExpr.GetValue(), aExpr.GetType() );
     464 [ +  - ][ +  - ]:        258 :                 }
                 [ +  - ]
     465                 :            :             }
     466         [ +  + ]:        274 :             else if( pDim )
     467                 :            :             {
     468                 :            :                 // Dimension the variable
     469                 :            :                 // Delete the var at REDIM beforehand
     470         [ -  + ]:         40 :                 if( eOp == _REDIM )
     471                 :            :                 {
     472         [ #  # ]:          0 :                     SbiExpression aExpr( this, *pDef, NULL );
     473         [ #  # ]:          0 :                     aExpr.Gen();
     474         [ #  # ]:          0 :                     if ( bVBASupportOn )
     475                 :            :                         // delete the array but
     476                 :            :                         // clear the variable ( this
     477                 :            :                         // allows the processing of
     478                 :            :                         // the param to happen as normal without errors ( ordinary ERASE just clears the array )
     479         [ #  # ]:          0 :                         aGen.Gen( _ERASE_CLEAR );
     480                 :            :                     else
     481 [ #  # ][ #  # ]:          0 :                         aGen.Gen( _ERASE );
     482                 :            :                 }
     483         [ -  + ]:         40 :                 else if( eOp == _REDIMP )
     484                 :            :                 {
     485         [ #  # ]:          0 :                     SbiExpression aExpr( this, *pDef, NULL );
     486         [ #  # ]:          0 :                     aExpr.Gen();
     487 [ #  # ][ #  # ]:          0 :                     aGen.Gen( _REDIMP_ERASE );
     488                 :            :                 }
     489                 :         40 :                 pDef->SetDims( pDim->GetDims() );
     490         [ +  + ]:         40 :                 if( bPersistantGlobal )
     491                 :          4 :                     pDef->SetGlobal( sal_True );
     492         [ +  - ]:         40 :                 SbiExpression aExpr( this, *pDef, pDim );
     493         [ +  - ]:         40 :                 aExpr.Gen();
     494                 :         40 :                 pDef->SetGlobal( sal_False );
     495 [ +  - ][ +  - ]:         40 :                 aGen.Gen( (eOp == _STATIC) ? _DIM : eOp );
                 [ +  - ]
     496                 :            :             }
     497                 :            :         }
     498 [ +  - ][ +  + ]:        572 :         if( !TestComma() )
     499                 :        418 :             goto MyBreak;
     500                 :            : 
     501                 :            :         // Implementation of bSwitchPool (see above): pPool must not be set to &aGlobals
     502                 :            :         // at the VarDecl-Call.
     503                 :            :         // Apart from that the behavior should be absolutely identical,
     504                 :            :         // i.e., pPool had to be reset always at the end of the loop.
     505                 :            :         // also at a break
     506                 :        154 :         pPool = pOldPool;
     507                 :        154 :         continue;       // Skip MyBreak
     508                 :            :     MyBreak:
     509                 :        418 :         pPool = pOldPool;
     510                 :        418 :         break;
     511                 :            :     }
     512                 :            : 
     513                 :            :     // #40689, finalize the jump over statics declarations
     514 [ +  + ][ -  + ]:        418 :     if( !bVBASupportOn && bStatic )
     515                 :            :     {
     516                 :            :         // maintain the global chain
     517         [ #  # ]:          0 :         nGblChain = aGen.Gen( _JUMP, 0 );
     518                 :          0 :         bGblDefs = bNewGblDefs = true;
     519                 :            : 
     520                 :            :         // Register for Sub a jump to the end of statics
     521         [ #  # ]:        435 :         aGen.BackChain( nEndOfStaticLbl );
     522                 :            :     }
     523                 :            : 
     524                 :            : }
     525                 :            : 
     526                 :            : // Here were Arrays redimensioned.
     527                 :            : 
     528                 :          0 : void SbiParser::ReDim()
     529                 :            : {
     530 [ #  # ][ #  # ]:          0 :     DefVar( _REDIM, (  pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
     531                 :          0 : }
     532                 :            : 
     533                 :            : // ERASE array, ...
     534                 :            : 
     535                 :          0 : void SbiParser::Erase()
     536                 :            : {
     537         [ #  # ]:          0 :     while( !bAbort )
     538                 :            :     {
     539         [ #  # ]:          0 :         SbiExpression aExpr( this, SbLVALUE );
     540         [ #  # ]:          0 :         aExpr.Gen();
     541         [ #  # ]:          0 :         aGen.Gen( _ERASE );
     542 [ #  # ][ #  # ]:          0 :         if( !TestComma() ) break;
     543 [ #  # ][ #  # ]:          0 :     }
     544                 :          0 : }
     545                 :            : 
     546                 :            : // Declaration of a data type
     547                 :            : 
     548                 :          0 : void SbiParser::Type()
     549                 :            : {
     550                 :          0 :     DefType( false );
     551                 :          0 : }
     552                 :            : 
     553                 :          0 : void SbiParser::DefType( bool bPrivate )
     554                 :            : {
     555                 :            :     // TODO: Use bPrivate
     556                 :            :     (void)bPrivate;
     557                 :            : 
     558                 :            :     // Read the new Token lesen. It had to be a symbol
     559 [ #  # ][ #  # ]:          0 :     if (!TestSymbol())
     560                 :            :         return;
     561                 :            : 
     562 [ #  # ][ #  # ]:          0 :     if (rTypeArray->Find(aSym,SbxCLASS_OBJECT))
     563                 :            :     {
     564         [ #  # ]:          0 :         Error( SbERR_VAR_DEFINED, aSym );
     565                 :            :         return;
     566                 :            :     }
     567                 :            : 
     568 [ #  # ][ #  # ]:          0 :     SbxObject *pType = new SbxObject(aSym);
         [ #  # ][ #  # ]
     569                 :            : 
     570                 :            :     SbiSymDef* pElem;
     571                 :          0 :     SbiDimList* pDim = NULL;
     572                 :          0 :     bool bDone = false;
     573                 :            : 
     574 [ #  # ][ #  # ]:          0 :     while( !bDone && !IsEof() )
                 [ #  # ]
     575                 :            :     {
     576         [ #  # ]:          0 :         switch( Peek() )
              [ #  #  # ]
     577                 :            :         {
     578                 :            :             case ENDTYPE :
     579                 :          0 :                 pElem = NULL;
     580                 :          0 :                 bDone = true;
     581         [ #  # ]:          0 :                 Next();
     582                 :          0 :             break;
     583                 :            : 
     584                 :            :             case EOLN :
     585                 :            :             case REM :
     586                 :          0 :                 pElem = NULL;
     587         [ #  # ]:          0 :                 Next();
     588                 :          0 :             break;
     589                 :            : 
     590                 :            :             default:
     591         [ #  # ]:          0 :                 pElem = VarDecl(&pDim, false, false);
     592         [ #  # ]:          0 :                 if( !pElem )
     593                 :          0 :                     bDone = true;   // Error occurred
     594                 :            :         }
     595         [ #  # ]:          0 :         if( pElem )
     596                 :            :         {
     597                 :          0 :             SbxArray *pTypeMembers = pType->GetProperties();
     598 [ #  # ][ #  # ]:          0 :             String aElemName = pElem->GetName();
     599 [ #  # ][ #  # ]:          0 :             if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) )
                 [ #  # ]
     600         [ #  # ]:          0 :                 Error (SbERR_VAR_DEFINED);
     601                 :            :             else
     602                 :            :             {
     603                 :          0 :                 SbxDataType eElemType = pElem->GetType();
     604 [ #  # ][ #  # ]:          0 :                 SbxProperty *pTypeElem = new SbxProperty( aElemName, eElemType );
     605         [ #  # ]:          0 :                 if( pDim )
     606                 :            :                 {
     607 [ #  # ][ #  # ]:          0 :                     SbxDimArray* pArray = new SbxDimArray( pElem->GetType() );
     608         [ #  # ]:          0 :                     if ( pDim->GetSize() )
     609                 :            :                     {
     610                 :            :                         // Dimension the target array
     611                 :            : 
     612         [ #  # ]:          0 :                         for ( short i=0; i<pDim->GetSize();++i )
     613                 :            :                         {
     614                 :          0 :                             sal_Int32 ub = -1;
     615                 :          0 :                             sal_Int32 lb = nBase;
     616         [ #  # ]:          0 :                             SbiExprNode* pNode =  pDim->Get(i)->GetExprNode();
     617                 :          0 :                             ub = pNode->GetNumber();
     618 [ #  # ][ #  # ]:          0 :                             if ( !pDim->Get( i )->IsBased() ) // each dim is low/up
     619                 :            :                             {
     620         [ #  # ]:          0 :                                 if (  ++i >= pDim->GetSize() ) // trouble
     621         [ #  # ]:          0 :                                     StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
     622         [ #  # ]:          0 :                                 pNode =  pDim->Get(i)->GetExprNode();
     623                 :          0 :                                 lb = ub;
     624                 :          0 :                                 ub = pNode->GetNumber();
     625                 :            :                             }
     626         [ #  # ]:          0 :                             else if ( !bCompatible )
     627                 :          0 :                                 ub += nBase;
     628         [ #  # ]:          0 :                             pArray->AddDim32( lb, ub );
     629                 :            :                         }
     630                 :          0 :                         pArray->setHasFixedSize( true );
     631                 :            :                     }
     632                 :            :                     else
     633         [ #  # ]:          0 :                         pArray->unoAddDim( 0, -1 ); // variant array
     634                 :          0 :                     sal_uInt16 nSavFlags = pTypeElem->GetFlags();
     635                 :            :                     // need to reset the FIXED flag
     636                 :            :                     // when calling PutObject ( because the type will not match Object )
     637                 :          0 :                     pTypeElem->ResetFlag( SBX_FIXED );
     638         [ #  # ]:          0 :                     pTypeElem->PutObject( pArray );
     639                 :          0 :                     pTypeElem->SetFlags( nSavFlags );
     640                 :            :                 }
     641                 :            :                 // Nested user type?
     642         [ #  # ]:          0 :                 if( eElemType == SbxOBJECT )
     643                 :            :                 {
     644                 :          0 :                     sal_uInt16 nElemTypeId = pElem->GetTypeId();
     645         [ #  # ]:          0 :                     if( nElemTypeId != 0 )
     646                 :            :                     {
     647 [ #  # ][ #  # ]:          0 :                         String aTypeName( aGblStrings.Find( nElemTypeId ) );
     648 [ #  # ][ #  # ]:          0 :                         SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) );
     649         [ #  # ]:          0 :                         if( pTypeObj != NULL )
     650                 :            :                         {
     651         [ #  # ]:          0 :                             SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj );
     652         [ #  # ]:          0 :                             pTypeElem->PutObject( pCloneObj );
     653         [ #  # ]:          0 :                         }
     654                 :            :                     }
     655                 :            :                 }
     656 [ #  # ][ #  # ]:          0 :                 pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() );
     657                 :            :             }
     658 [ #  # ][ #  # ]:          0 :             delete pDim, pDim = NULL;
     659 [ #  # ][ #  # ]:          0 :             delete pElem;
                 [ #  # ]
     660                 :            :         }
     661                 :            :     }
     662                 :            : 
     663 [ #  # ][ #  # ]:          0 :     pType->Remove( rtl::OUString("Name"), SbxCLASS_DONTCARE );
                 [ #  # ]
     664 [ #  # ][ #  # ]:          0 :     pType->Remove( rtl::OUString("Parent"), SbxCLASS_DONTCARE );
                 [ #  # ]
     665                 :            : 
     666 [ #  # ][ #  # ]:          0 :     rTypeArray->Insert (pType,rTypeArray->Count());
     667                 :            : }
     668                 :            : 
     669                 :            : 
     670                 :            : // Declaration of Enum type
     671                 :            : 
     672                 :          0 : void SbiParser::Enum()
     673                 :            : {
     674                 :          0 :     DefEnum( false );
     675                 :          0 : }
     676                 :            : 
     677                 :          0 : void SbiParser::DefEnum( bool bPrivate )
     678                 :            : {
     679                 :            :     // Read a the new Token. It had to be a symbol
     680 [ #  # ][ #  # ]:          0 :     if (!TestSymbol())
     681                 :            :         return;
     682                 :            : 
     683         [ #  # ]:          0 :     String aEnumName = aSym;
     684 [ #  # ][ #  # ]:          0 :     if( rEnumArray->Find(aEnumName,SbxCLASS_OBJECT) )
                 [ #  # ]
     685                 :            :     {
     686         [ #  # ]:          0 :         Error( SbERR_VAR_DEFINED, aSym );
     687                 :            :         return;
     688                 :            :     }
     689                 :            : 
     690 [ #  # ][ #  # ]:          0 :     SbxObject *pEnum = new SbxObject( aEnumName );
     691         [ #  # ]:          0 :     if( bPrivate )
     692                 :          0 :         pEnum->SetFlag( SBX_PRIVATE );
     693                 :            : 
     694                 :            :     SbiSymDef* pElem;
     695                 :            :     SbiDimList* pDim;
     696                 :          0 :     bool bDone = false;
     697                 :            : 
     698                 :            :     // Starting with -1 to make first default value 0 after ++
     699                 :          0 :     sal_Int32 nCurrentEnumValue = -1;
     700 [ #  # ][ #  # ]:          0 :     while( !bDone && !IsEof() )
                 [ #  # ]
     701                 :            :     {
     702         [ #  # ]:          0 :         switch( Peek() )
              [ #  #  # ]
     703                 :            :         {
     704                 :            :             case ENDENUM :
     705                 :          0 :                 pElem = NULL;
     706                 :          0 :                 bDone = true;
     707         [ #  # ]:          0 :                 Next();
     708                 :          0 :             break;
     709                 :            : 
     710                 :            :             case EOLN :
     711                 :            :             case REM :
     712                 :          0 :                 pElem = NULL;
     713         [ #  # ]:          0 :                 Next();
     714                 :          0 :             break;
     715                 :            : 
     716                 :            :             default:
     717                 :            :             {
     718                 :            :                 // TODO: Check existing!
     719                 :          0 :                 bool bDefined = false;
     720                 :            : 
     721                 :          0 :                 pDim = NULL;
     722         [ #  # ]:          0 :                 pElem = VarDecl( &pDim, false, true );
     723         [ #  # ]:          0 :                 if( !pElem )
     724                 :            :                 {
     725                 :          0 :                     bDone = true;   // Error occurred
     726                 :            :                     break;
     727                 :            :                 }
     728         [ #  # ]:          0 :                 else if( pDim )
     729                 :            :                 {
     730 [ #  # ][ #  # ]:          0 :                     delete pDim;
     731         [ #  # ]:          0 :                     Error( SbERR_SYNTAX );
     732                 :          0 :                     bDone = true;   // Error occurred
     733                 :            :                     break;
     734                 :            :                 }
     735                 :            : 
     736         [ #  # ]:          0 :                 SbiExpression aVar( this, *pElem );
     737 [ #  # ][ #  # ]:          0 :                 if( Peek() == EQ )
     738                 :            :                 {
     739         [ #  # ]:          0 :                     Next();
     740                 :            : 
     741         [ #  # ]:          0 :                     SbiConstExpression aExpr( this );
     742 [ #  # ][ #  # ]:          0 :                     if( !bDefined && aExpr.IsValid() )
                 [ #  # ]
     743                 :            :                     {
     744 [ #  # ][ #  # ]:          0 :                         SbxVariableRef xConvertVar = new SbxVariable();
     745         [ #  # ]:          0 :                         if( aExpr.GetType() == SbxSTRING )
     746 [ #  # ][ #  # ]:          0 :                             xConvertVar->PutString( aExpr.GetString() );
     747                 :            :                         else
     748         [ #  # ]:          0 :                             xConvertVar->PutDouble( aExpr.GetValue() );
     749                 :            : 
     750 [ #  # ][ #  # ]:          0 :                         nCurrentEnumValue = xConvertVar->GetLong();
     751         [ #  # ]:          0 :                     }
     752                 :            :                 }
     753                 :            :                 else
     754                 :          0 :                     nCurrentEnumValue++;
     755                 :            : 
     756         [ #  # ]:          0 :                 SbiSymPool* pPoolToUse = bPrivate ? pPool : &aGlobals;
     757                 :            : 
     758 [ #  # ][ #  # ]:          0 :                 SbiSymDef* pOld = pPoolToUse->Find( pElem->GetName() );
     759         [ #  # ]:          0 :                 if( pOld )
     760                 :            :                 {
     761 [ #  # ][ #  # ]:          0 :                     Error( SbERR_VAR_DEFINED, pElem->GetName() );
                 [ #  # ]
     762                 :          0 :                     bDone = true;   // Error occurred
     763                 :            :                     break;
     764                 :            :                 }
     765                 :            : 
     766         [ #  # ]:          0 :                 pPool->Add( pElem );
     767                 :            : 
     768         [ #  # ]:          0 :                 if( !bPrivate )
     769                 :            :                 {
     770                 :          0 :                     SbiOpcode eOp = _GLOBAL;
     771         [ #  # ]:          0 :                     aGen.BackChain( nGblChain );
     772                 :          0 :                     nGblChain = 0;
     773                 :          0 :                     bGblDefs = bNewGblDefs = true;
     774                 :            :                     aGen.Gen(
     775                 :          0 :                         eOp, pElem->GetId(),
     776         [ #  # ]:          0 :                         sal::static_int_cast< sal_uInt16 >( pElem->GetType() ) );
     777                 :            : 
     778         [ #  # ]:          0 :                     aVar.Gen();
     779         [ #  # ]:          0 :                     sal_uInt16 nStringId = aGen.GetParser()->aGblStrings.Add( nCurrentEnumValue, SbxLONG );
     780         [ #  # ]:          0 :                     aGen.Gen( _NUMBER, nStringId );
     781         [ #  # ]:          0 :                     aGen.Gen( _PUTC );
     782                 :            :                 }
     783                 :            : 
     784         [ #  # ]:          0 :                 SbiConstDef* pConst = pElem->GetConstDef();
     785 [ #  # ][ #  # ]:          0 :                 pConst->Set( nCurrentEnumValue, SbxLONG );
                 [ #  # ]
     786                 :            :             }
     787                 :            :         }
     788         [ #  # ]:          0 :         if( pElem )
     789                 :            :         {
     790                 :          0 :             SbxArray *pEnumMembers = pEnum->GetProperties();
     791 [ #  # ][ #  # ]:          0 :             SbxProperty *pEnumElem = new SbxProperty( pElem->GetName(), SbxLONG );
                 [ #  # ]
     792         [ #  # ]:          0 :             pEnumElem->PutLong( nCurrentEnumValue );
     793                 :          0 :             pEnumElem->ResetFlag( SBX_WRITE );
     794                 :          0 :             pEnumElem->SetFlag( SBX_CONST );
     795 [ #  # ][ #  # ]:          0 :             pEnumMembers->Insert( pEnumElem, pEnumMembers->Count() );
     796                 :            :         }
     797                 :            :     }
     798                 :            : 
     799 [ #  # ][ #  # ]:          0 :     pEnum->Remove( rtl::OUString("Name"), SbxCLASS_DONTCARE );
                 [ #  # ]
     800 [ #  # ][ #  # ]:          0 :     pEnum->Remove( rtl::OUString("Parent"), SbxCLASS_DONTCARE );
                 [ #  # ]
     801                 :            : 
     802 [ #  # ][ #  # ]:          0 :     rEnumArray->Insert( pEnum, rEnumArray->Count() );
         [ #  # ][ #  # ]
     803                 :            : }
     804                 :            : 
     805                 :            : 
     806                 :            : // Procedure-Declaration
     807                 :            : // the first Token is already read in (SUB/FUNCTION)
     808                 :            : // xxx Name [LIB "name"[ALIAS "name"]][(Parameter)][AS TYPE]
     809                 :            : 
     810                 :        197 : SbiProcDef* SbiParser::ProcDecl( bool bDecl )
     811                 :            : {
     812                 :        197 :     bool bFunc = ( eCurTok == FUNCTION );
     813 [ +  - ][ +  - ]:        197 :     bool bProp = ( eCurTok == GET || eCurTok == SET || eCurTok == LET );
                 [ -  + ]
     814 [ +  - ][ -  + ]:        197 :     if( !TestSymbol() ) return NULL;
     815         [ +  - ]:        197 :     String aName( aSym );
     816                 :        197 :     SbxDataType eType = eScanType;
     817 [ +  - ][ +  - ]:        197 :     SbiProcDef* pDef = new SbiProcDef( this, aName, true );
     818         [ +  - ]:        197 :     pDef->SetType( eType );
     819 [ +  - ][ -  + ]:        197 :     if( Peek() == _CDECL_ )
     820                 :            :     {
     821         [ #  # ]:          0 :         Next(); pDef->SetCdecl();
     822                 :            :     }
     823 [ +  - ][ -  + ]:        197 :     if( Peek() == LIB )
     824                 :            :     {
     825         [ #  # ]:          0 :         Next();
     826 [ #  # ][ #  # ]:          0 :         if( Next() == FIXSTRING )
     827         [ #  # ]:          0 :             pDef->GetLib() = aSym;
     828                 :            :         else
     829         [ #  # ]:          0 :             Error( SbERR_SYNTAX );
     830                 :            :     }
     831 [ +  - ][ -  + ]:        197 :     if( Peek() == ALIAS )
     832                 :            :     {
     833         [ #  # ]:          0 :         Next();
     834 [ #  # ][ #  # ]:          0 :         if( Next() == FIXSTRING )
     835         [ #  # ]:          0 :             pDef->GetAlias() = aSym;
     836                 :            :         else
     837         [ #  # ]:          0 :             Error( SbERR_SYNTAX );
     838                 :            :     }
     839         [ +  - ]:        197 :     if( !bDecl )
     840                 :            :     {
     841                 :            :         // CDECL, LIB and ALIAS are invalid
     842         [ -  + ]:        197 :         if( pDef->GetLib().Len() )
     843         [ #  # ]:          0 :             Error( SbERR_UNEXPECTED, LIB );
     844         [ -  + ]:        197 :         if( pDef->GetAlias().Len() )
     845         [ #  # ]:          0 :             Error( SbERR_UNEXPECTED, ALIAS );
     846         [ -  + ]:        197 :         if( pDef->IsCdecl() )
     847         [ #  # ]:          0 :             Error( SbERR_UNEXPECTED, _CDECL_ );
     848                 :        197 :         pDef->SetCdecl( false );
     849         [ +  - ]:        197 :         pDef->GetLib().Erase();
     850         [ +  - ]:        197 :         pDef->GetAlias().Erase();
     851                 :            :     }
     852         [ #  # ]:          0 :     else if( !pDef->GetLib().Len() )
     853                 :            :     {
     854                 :            :         // ALIAS and CDECL only together with LIB
     855         [ #  # ]:          0 :         if( pDef->GetAlias().Len() )
     856         [ #  # ]:          0 :             Error( SbERR_UNEXPECTED, ALIAS );
     857         [ #  # ]:          0 :         if( pDef->IsCdecl() )
     858         [ #  # ]:          0 :             Error( SbERR_UNEXPECTED, _CDECL_ );
     859                 :          0 :         pDef->SetCdecl( false );
     860         [ #  # ]:          0 :         pDef->GetAlias().Erase();
     861                 :            :     }
     862                 :            :     // Brackets?
     863 [ +  - ][ +  + ]:        197 :     if( Peek() == LPAREN )
     864                 :            :     {
     865         [ +  - ]:        117 :         Next();
     866 [ +  - ][ +  + ]:        117 :         if( Peek() == RPAREN )
     867         [ +  - ]:         39 :             Next();
     868                 :            :         else
     869                 :        167 :           for(;;) {
     870                 :        128 :             bool bByVal = false;
     871                 :        128 :             bool bOptional = false;
     872                 :        128 :             bool bParamArray = false;
     873 [ +  - ][ +  + ]:        136 :             while( Peek() == BYVAL || Peek() == BYREF || Peek() == _OPTIONAL_ )
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
                 [ +  + ]
     874                 :            :             {
     875 [ +  - ][ +  + ]:          8 :                 if      ( Peek() == BYVAL )     Next(), bByVal = true;
                 [ +  - ]
     876 [ +  - ][ -  + ]:          2 :                 else if ( Peek() == BYREF )     Next(), bByVal = false;
                 [ #  # ]
     877 [ +  - ][ +  - ]:          2 :                 else if ( Peek() == _OPTIONAL_ )    Next(), bOptional = true;
                 [ +  - ]
     878                 :            :             }
     879 [ +  + ][ +  - ]:        128 :             if( bCompatible && Peek() == PARAMARRAY )
         [ -  + ][ -  + ]
     880                 :            :             {
     881 [ #  # ][ #  # ]:          0 :                 if( bByVal || bOptional )
     882         [ #  # ]:          0 :                     Error( SbERR_UNEXPECTED, PARAMARRAY );
     883         [ #  # ]:          0 :                 Next();
     884                 :          0 :                 bParamArray = true;
     885                 :            :             }
     886         [ +  - ]:        128 :             SbiSymDef* pPar = VarDecl( NULL, false, false );
     887         [ -  + ]:        128 :             if( !pPar )
     888                 :          0 :                 break;
     889         [ +  + ]:        128 :             if( bByVal )
     890                 :          6 :                 pPar->SetByVal();
     891         [ +  + ]:        128 :             if( bOptional )
     892                 :          2 :                 pPar->SetOptional();
     893         [ -  + ]:        128 :             if( bParamArray )
     894                 :          0 :                 pPar->SetParamArray();
     895         [ +  - ]:        128 :             pDef->GetParams().Add( pPar );
     896         [ +  - ]:        128 :             SbiToken eTok = Next();
     897 [ +  + ][ -  + ]:        128 :             if( eTok != COMMA && eTok != RPAREN )
     898                 :            :             {
     899                 :          0 :                 bool bError2 = true;
     900 [ #  # ][ #  # ]:          0 :                 if( bOptional && bCompatible && eTok == EQ )
                 [ #  # ]
     901                 :            :                 {
     902 [ #  # ][ #  # ]:          0 :                     SbiConstExpression* pDefaultExpr = new SbiConstExpression( this );
     903                 :          0 :                     SbxDataType eType2 = pDefaultExpr->GetType();
     904                 :            : 
     905                 :            :                     sal_uInt16 nStringId;
     906         [ #  # ]:          0 :                     if( eType2 == SbxSTRING )
     907 [ #  # ][ #  # ]:          0 :                         nStringId = aGblStrings.Add( pDefaultExpr->GetString() );
     908                 :            :                     else
     909         [ #  # ]:          0 :                         nStringId = aGblStrings.Add( pDefaultExpr->GetValue(), eType2 );
     910                 :            : 
     911                 :          0 :                     pPar->SetDefaultId( nStringId );
     912 [ #  # ][ #  # ]:          0 :                     delete pDefaultExpr;
     913                 :            : 
     914         [ #  # ]:          0 :                     eTok = Next();
     915 [ #  # ][ #  # ]:          0 :                     if( eTok == COMMA || eTok == RPAREN )
     916                 :          0 :                         bError2 = false;
     917                 :            :                 }
     918         [ #  # ]:          0 :                 if( bError2 )
     919                 :            :                 {
     920         [ #  # ]:          0 :                     Error( SbERR_EXPECTED, RPAREN );
     921                 :          0 :                     break;
     922                 :            :                 }
     923                 :            :             }
     924         [ +  + ]:        128 :             if( eTok == RPAREN )
     925                 :         78 :                 break;
     926                 :            :         }
     927                 :            :     }
     928         [ +  - ]:        197 :     TypeDecl( *pDef );
     929 [ -  + ][ #  # ]:        197 :     if( eType != SbxVARIANT && pDef->GetType() != eType )
                 [ -  + ]
     930 [ #  # ][ #  # ]:          0 :         Error( SbERR_BAD_DECLARATION, aName );
     931 [ +  + ][ +  + ]:        197 :     if( pDef->GetType() == SbxVARIANT && !( bFunc || bProp ) )
         [ +  - ][ +  + ]
     932         [ +  - ]:        134 :         pDef->SetType( SbxEMPTY );
     933         [ +  - ]:        197 :     return pDef;
     934                 :            : }
     935                 :            : 
     936                 :            : // DECLARE
     937                 :            : 
     938                 :          0 : void SbiParser::Declare()
     939                 :            : {
     940                 :          0 :     DefDeclare( false );
     941                 :          0 : }
     942                 :            : 
     943                 :          0 : void SbiParser::DefDeclare( bool bPrivate )
     944                 :            : {
     945                 :          0 :     Next();
     946 [ #  # ][ #  # ]:          0 :     if( eCurTok != SUB && eCurTok != FUNCTION )
     947                 :          0 :       Error( SbERR_UNEXPECTED, eCurTok );
     948                 :            :     else
     949                 :            :     {
     950                 :          0 :         bool bFunction = (eCurTok == FUNCTION);
     951                 :            : 
     952                 :          0 :         SbiProcDef* pDef = ProcDecl( true );
     953         [ #  # ]:          0 :         if( pDef )
     954                 :            :         {
     955         [ #  # ]:          0 :             if( !pDef->GetLib().Len() )
     956                 :          0 :                 Error( SbERR_EXPECTED, LIB );
     957                 :            :             // Is it already there?
     958                 :          0 :             SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
     959         [ #  # ]:          0 :             if( pOld )
     960                 :            :             {
     961                 :          0 :                 SbiProcDef* p = pOld->GetProcDef();
     962         [ #  # ]:          0 :                 if( !p )
     963                 :            :                 {
     964                 :            :                     // Declared as a variable
     965         [ #  # ]:          0 :                     Error( SbERR_BAD_DECLARATION, pDef->GetName() );
     966         [ #  # ]:          0 :                     delete pDef;
     967                 :          0 :                     pDef = NULL;
     968                 :            :                 }
     969                 :            :                 else
     970                 :          0 :                     pDef->Match( p );
     971                 :            :             }
     972                 :            :             else
     973                 :          0 :                 aPublics.Add( pDef );
     974                 :            : 
     975         [ #  # ]:          0 :             if ( pDef )
     976                 :            :             {
     977                 :          0 :                 pDef->SetPublic( !bPrivate );
     978                 :            : 
     979                 :            :                 // New declare handling
     980         [ #  # ]:          0 :                 if( pDef->GetLib().Len() > 0 )
     981                 :            :                 {
     982 [ #  # ][ #  # ]:          0 :                     if( bNewGblDefs && nGblChain == 0 )
     983                 :            :                     {
     984                 :          0 :                         nGblChain = aGen.Gen( _JUMP, 0 );
     985                 :          0 :                         bNewGblDefs = false;
     986                 :            :                     }
     987                 :            : 
     988                 :          0 :                     sal_uInt16 nSavLine = nLine;
     989                 :          0 :                     aGen.Statement();
     990                 :          0 :                     pDef->Define();
     991                 :          0 :                     pDef->SetLine1( nSavLine );
     992                 :          0 :                     pDef->SetLine2( nSavLine );
     993                 :            : 
     994                 :          0 :                     SbiSymPool& rPool = pDef->GetParams();
     995                 :          0 :                     sal_uInt16 nParCount = rPool.GetSize();
     996                 :            : 
     997                 :          0 :                     SbxDataType eType = pDef->GetType();
     998         [ #  # ]:          0 :                     if( bFunction )
     999                 :          0 :                         aGen.Gen( _PARAM, 0, sal::static_int_cast< sal_uInt16 >( eType ) );
    1000                 :            : 
    1001         [ #  # ]:          0 :                     if( nParCount > 1 )
    1002                 :            :                     {
    1003                 :          0 :                         aGen.Gen( _ARGC );
    1004                 :            : 
    1005         [ #  # ]:          0 :                         for( sal_uInt16 i = 1 ; i < nParCount ; ++i )
    1006                 :            :                         {
    1007                 :          0 :                             SbiSymDef* pParDef = rPool.Get( i );
    1008                 :          0 :                             SbxDataType eParType = pParDef->GetType();
    1009                 :            : 
    1010                 :          0 :                             aGen.Gen( _PARAM, i, sal::static_int_cast< sal_uInt16 >( eParType ) );
    1011                 :          0 :                             aGen.Gen( _ARGV );
    1012                 :            : 
    1013                 :          0 :                             sal_uInt16 nTyp = sal::static_int_cast< sal_uInt16 >( pParDef->GetType() );
    1014         [ #  # ]:          0 :                             if( pParDef->IsByVal() )
    1015                 :            :                             {
    1016                 :            :                                 // Reset to avoid additional byval in call to wrapper function
    1017                 :          0 :                                 pParDef->SetByVal( sal_False );
    1018                 :          0 :                                 nTyp |= 0x8000;
    1019                 :            :                             }
    1020                 :          0 :                             aGen.Gen( _ARGTYP, nTyp );
    1021                 :            :                         }
    1022                 :            :                     }
    1023                 :            : 
    1024 [ #  # ][ #  # ]:          0 :                     aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) );
    1025                 :            : 
    1026         [ #  # ]:          0 :                     SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL;
    1027                 :          0 :                     sal_uInt16 nId = pDef->GetId();
    1028         [ #  # ]:          0 :                     if( pDef->GetAlias().Len() )
    1029         [ #  # ]:          0 :                         nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() );
    1030         [ #  # ]:          0 :                     if( nParCount > 1 )
    1031                 :          0 :                         nId |= 0x8000;
    1032                 :          0 :                     aGen.Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( eType ) );
    1033                 :            : 
    1034         [ #  # ]:          0 :                     if( bFunction )
    1035                 :          0 :                         aGen.Gen( _PUT );
    1036                 :            : 
    1037                 :          0 :                     aGen.Gen( _LEAVE );
    1038                 :            :                 }
    1039                 :            :             }
    1040                 :            :         }
    1041                 :            :     }
    1042                 :          0 : }
    1043                 :            : 
    1044                 :          0 : void SbiParser::Attribute()
    1045                 :            : {
    1046                 :            :     // TODO: Need to implement the method as an attributed object.
    1047         [ #  # ]:          0 :     while( Next() != EQ )
    1048                 :            :     {
    1049         [ #  # ]:          0 :         if( Next() != DOT)
    1050                 :          0 :             break;
    1051                 :            :     }
    1052                 :            : 
    1053         [ #  # ]:          0 :     if( eCurTok != EQ )
    1054                 :          0 :         Error( SbERR_SYNTAX );
    1055                 :            :     else
    1056 [ #  # ][ #  # ]:          0 :         SbiExpression aValue( this );
    1057                 :            : 
    1058                 :            :     // Don't generate any code - just discard it.
    1059                 :          0 : }
    1060                 :            : 
    1061                 :            : // Call of a SUB or a FUNCTION
    1062                 :            : 
    1063                 :         72 : void SbiParser::Call()
    1064                 :            : {
    1065         [ +  - ]:         72 :     SbiExpression aVar( this, SbSYMBOL );
    1066         [ +  - ]:         72 :     aVar.Gen( FORCE_CALL );
    1067 [ +  - ][ +  - ]:         72 :     aGen.Gen( _GET );
    1068                 :         72 : }
    1069                 :            : 
    1070                 :            : // SUB/FUNCTION
    1071                 :            : 
    1072                 :        180 : void SbiParser::SubFunc()
    1073                 :            : {
    1074                 :        180 :     DefProc( false, false );
    1075                 :        180 : }
    1076                 :            : 
    1077                 :            : // Read in of a procedure
    1078                 :            : 
    1079                 :        197 : void SbiParser::DefProc( bool bStatic, bool bPrivate )
    1080                 :            : {
    1081                 :        197 :     sal_uInt16 l1 = nLine, l2 = nLine;
    1082                 :        197 :     bool bSub = ( eCurTok == SUB );
    1083                 :        197 :     bool bProperty = ( eCurTok == PROPERTY );
    1084                 :        197 :     PropertyMode ePropertyMode = PROPERTY_MODE_NONE;
    1085         [ -  + ]:        197 :     if( bProperty )
    1086                 :            :     {
    1087                 :          0 :         Next();
    1088         [ #  # ]:          0 :         if( eCurTok == GET )
    1089                 :          0 :             ePropertyMode = PROPERTY_MODE_GET;
    1090         [ #  # ]:          0 :         else if( eCurTok == LET )
    1091                 :          0 :             ePropertyMode = PROPERTY_MODE_LET;
    1092         [ #  # ]:          0 :         else if( eCurTok == SET )
    1093                 :          0 :             ePropertyMode = PROPERTY_MODE_SET;
    1094                 :            :         else
    1095                 :          0 :             Error( SbERR_EXPECTED, "Get or Let or Set" );
    1096                 :            :     }
    1097                 :            : 
    1098                 :        197 :     SbiToken eExit = eCurTok;
    1099                 :        197 :     SbiProcDef* pDef = ProcDecl( false );
    1100         [ -  + ]:        197 :     if( !pDef )
    1101                 :          0 :         return;
    1102                 :        197 :     pDef->setPropertyMode( ePropertyMode );
    1103                 :            : 
    1104                 :            :     // Is the Proc already declared?
    1105                 :        197 :     SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
    1106         [ +  + ]:        197 :     if( pOld )
    1107                 :            :     {
    1108                 :         74 :         bool bError_ = false;
    1109                 :            : 
    1110                 :         74 :         pProc = pOld->GetProcDef();
    1111         [ -  + ]:         74 :         if( !pProc )
    1112                 :            :         {
    1113                 :            :             // Declared as a variable
    1114         [ #  # ]:          0 :             Error( SbERR_BAD_DECLARATION, pDef->GetName() );
    1115         [ #  # ]:          0 :             delete pDef;
    1116                 :          0 :             pProc = NULL;
    1117                 :          0 :             bError_ = true;
    1118                 :            :         }
    1119                 :            :         // #100027: Multiple declaration -> Error
    1120                 :            :         // #112787: Not for setup, REMOVE for 8
    1121         [ -  + ]:         74 :         else if( pProc->IsUsedForProcDecl() )
    1122                 :            :         {
    1123                 :          0 :             PropertyMode ePropMode = pDef->getPropertyMode();
    1124 [ #  # ][ #  # ]:          0 :             if( ePropMode == PROPERTY_MODE_NONE || ePropMode == pProc->getPropertyMode() )
                 [ #  # ]
    1125                 :            :             {
    1126         [ #  # ]:          0 :                 Error( SbERR_PROC_DEFINED, pDef->GetName() );
    1127         [ #  # ]:          0 :                 delete pDef;
    1128                 :          0 :                 pProc = NULL;
    1129                 :          0 :                 bError_ = true;
    1130                 :            :             }
    1131                 :            :         }
    1132                 :            : 
    1133         [ +  - ]:         74 :         if( !bError_ )
    1134                 :            :         {
    1135                 :         74 :             pDef->Match( pProc );
    1136                 :         74 :             pProc = pDef;
    1137                 :            :         }
    1138                 :            :     }
    1139                 :            :     else
    1140                 :        123 :         aPublics.Add( pDef ), pProc = pDef;
    1141                 :            : 
    1142         [ -  + ]:        197 :     if( !pProc )
    1143                 :          0 :         return;
    1144                 :        197 :     pProc->SetPublic( !bPrivate );
    1145                 :            : 
    1146                 :            :     // Now we set the search hierarchy for symbols as well as the
    1147                 :            :     // current procedure.
    1148                 :        197 :     aPublics.SetProcId( pProc->GetId() );
    1149                 :        197 :     pProc->GetParams().SetParent( &aPublics );
    1150         [ -  + ]:        197 :     if( bStatic )
    1151                 :            :         {
    1152         [ #  # ]:          0 :         if ( bVBASupportOn )
    1153                 :          0 :             pProc->SetStatic( sal_True );
    1154                 :            :         else
    1155                 :          0 :             Error( SbERR_NOT_IMPLEMENTED ); // STATIC SUB ...
    1156                 :            :         }
    1157                 :            :      else
    1158                 :            :     {
    1159                 :        197 :         pProc->SetStatic( sal_False );
    1160                 :            :         }
    1161                 :            :     // Normal case: Local variable->parameter->global variable
    1162                 :        197 :     pProc->GetLocals().SetParent( &pProc->GetParams() );
    1163                 :        197 :     pPool = &pProc->GetLocals();
    1164                 :            : 
    1165                 :        197 :     pProc->Define();
    1166                 :        197 :     OpenBlock( eExit );
    1167 [ -  + ][ +  + ]:        197 :     StmntBlock( bSub ? ENDSUB : (bProperty ? ENDPROPERTY : ENDFUNC) );
    1168                 :        197 :     l2 = nLine;
    1169                 :        197 :     pProc->SetLine1( l1 );
    1170                 :        197 :     pProc->SetLine2( l2 );
    1171                 :        197 :     pPool = &aPublics;
    1172                 :        197 :     aPublics.SetProcId( 0 );
    1173                 :            :     // Open labels?
    1174                 :        197 :     pProc->GetLabels().CheckRefs();
    1175                 :        197 :     CloseBlock();
    1176                 :        197 :     aGen.Gen( _LEAVE );
    1177                 :        197 :     pProc = NULL;
    1178                 :            : }
    1179                 :            : 
    1180                 :            : // STATIC variable|procedure
    1181                 :            : 
    1182                 :          0 : void SbiParser::Static()
    1183                 :            : {
    1184                 :          0 :     DefStatic( false );
    1185                 :          0 : }
    1186                 :            : 
    1187                 :          0 : void SbiParser::DefStatic( bool bPrivate )
    1188                 :            : {
    1189         [ #  # ]:          0 :     switch( Peek() )
    1190                 :            :     {
    1191                 :            :         case SUB:
    1192                 :            :         case FUNCTION:
    1193                 :            :         case PROPERTY:
    1194                 :            :             // End global chain if necessary (not done in
    1195                 :            :             // SbiParser::Parse() under these conditions
    1196 [ #  # ][ #  # ]:          0 :             if( bNewGblDefs && nGblChain == 0 )
    1197                 :            :             {
    1198                 :          0 :                 nGblChain = aGen.Gen( _JUMP, 0 );
    1199                 :          0 :                 bNewGblDefs = false;
    1200                 :            :             }
    1201                 :          0 :             Next();
    1202                 :          0 :             DefProc( true, bPrivate );
    1203                 :          0 :             break;
    1204                 :            :         default: {
    1205         [ #  # ]:          0 :             if( !pProc )
    1206                 :          0 :                 Error( SbERR_NOT_IN_SUBR );
    1207                 :            :             // Reset the Pool, so that STATIC-Declarations go into the
    1208                 :            :             // global Pool
    1209                 :          0 :             SbiSymPool* p = pPool; pPool = &aPublics;
    1210                 :          0 :             DefVar( _STATIC, true );
    1211                 :          0 :             pPool = p;
    1212                 :          0 :             } break;
    1213                 :            :     }
    1214                 :          0 : }
    1215                 :            : 
    1216                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10