LCOV - code coverage report
Current view: top level - basic/source/comp - loops.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 142 308 46.1 %
Date: 2012-08-25 Functions: 5 13 38.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 169 597 28.3 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : #include "sbcomp.hxx"
      22                 :            : 
      23                 :            : // Single-line IF und Multiline IF
      24                 :            : 
      25                 :        249 : void SbiParser::If()
      26                 :            : {
      27                 :            :     sal_uInt32 nEndLbl;
      28                 :        249 :     SbiToken eTok = NIL;
      29                 :            :     // ignore end-tokens
      30         [ +  - ]:        249 :     SbiExpression aCond( this );
      31         [ +  - ]:        249 :     aCond.Gen();
      32         [ +  - ]:        249 :     TestToken( THEN );
      33 [ +  - ][ +  + ]:        249 :     if( IsEoln( Next() ) )
      34                 :            :     {
      35                 :            :         // At the end of each block a jump to ENDIF must be inserted,
      36                 :            :         // so that the condition is not evaluated again at ELSEIF.
      37                 :            :         // The table collects all jump points.
      38                 :            : #define JMP_TABLE_SIZE 100
      39                 :            :         sal_uInt32 pnJmpToEndLbl[JMP_TABLE_SIZE];   // 100 ELSEIFs allowed
      40                 :        247 :         sal_uInt16 iJmp = 0;                        // current table index
      41                 :            : 
      42                 :            :         // multiline IF
      43         [ +  - ]:        247 :         nEndLbl = aGen.Gen( _JUMPF, 0 );
      44         [ +  - ]:        247 :         eTok = Peek();
      45 [ +  - ][ +  + ]:       2275 :         while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
         [ +  + ][ +  - ]
         [ +  - ][ +  + ]
      46         [ +  - ]:       1014 :                 !bAbort && Parse() )
      47                 :            :         {
      48         [ +  - ]:       1014 :             eTok = Peek();
      49         [ -  + ]:       1014 :             if( IsEof() )
      50                 :            :             {
      51         [ #  # ]:          0 :                 Error( SbERR_BAD_BLOCK, IF ); bAbort = sal_True; return;
      52                 :            :             }
      53                 :            :         }
      54         [ -  + ]:        247 :         while( eTok == ELSEIF )
      55                 :            :         {
      56                 :            :             // jump to ENDIF in case of a successful IF/ELSEIF
      57         [ #  # ]:          0 :             if( iJmp >= JMP_TABLE_SIZE )
      58                 :            :             {
      59         [ #  # ]:          0 :                 Error( SbERR_PROG_TOO_LARGE );  bAbort = sal_True;  return;
      60                 :            :             }
      61         [ #  # ]:          0 :             pnJmpToEndLbl[iJmp++] = aGen.Gen( _JUMP, 0 );
      62                 :            : 
      63         [ #  # ]:          0 :             Next();
      64         [ #  # ]:          0 :             aGen.BackChain( nEndLbl );
      65                 :            : 
      66         [ #  # ]:          0 :             aGen.Statement();
      67 [ #  # ][ #  # ]:          0 :             SbiExpression* pCond = new SbiExpression( this );
      68         [ #  # ]:          0 :             pCond->Gen();
      69         [ #  # ]:          0 :             nEndLbl = aGen.Gen( _JUMPF, 0 );
      70 [ #  # ][ #  # ]:          0 :             delete pCond;
      71         [ #  # ]:          0 :             TestToken( THEN );
      72         [ #  # ]:          0 :             eTok = Peek();
      73 [ #  # ][ #  # ]:          0 :             while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      74         [ #  # ]:          0 :                     !bAbort && Parse() )
      75                 :            :             {
      76         [ #  # ]:          0 :                 eTok = Peek();
      77         [ #  # ]:          0 :                 if( IsEof() )
      78                 :            :                 {
      79         [ #  # ]:          0 :                     Error( SbERR_BAD_BLOCK, ELSEIF );  bAbort = sal_True; return;
      80                 :            :                 }
      81                 :            :             }
      82                 :            :         }
      83         [ +  + ]:        247 :         if( eTok == ELSE )
      84                 :            :         {
      85         [ +  - ]:         62 :             Next();
      86                 :         62 :             sal_uInt32 nElseLbl = nEndLbl;
      87         [ +  - ]:         62 :             nEndLbl = aGen.Gen( _JUMP, 0 );
      88         [ +  - ]:         62 :             aGen.BackChain( nElseLbl );
      89                 :            : 
      90         [ +  - ]:         62 :             aGen.Statement();
      91         [ +  - ]:         62 :             StmntBlock( ENDIF );
      92                 :            :         }
      93         [ +  - ]:        185 :         else if( eTok == ENDIF )
      94         [ +  - ]:        185 :             Next();
      95                 :            : 
      96                 :            : 
      97         [ -  + ]:        247 :         while( iJmp > 0 )
      98                 :            :         {
      99                 :          0 :             iJmp--;
     100         [ #  # ]:          0 :             aGen.BackChain( pnJmpToEndLbl[iJmp] );
     101                 :            :         }
     102                 :            :     }
     103                 :            :     else
     104                 :            :     {
     105                 :            :         // single line IF
     106                 :          2 :         bSingleLineIf = true;
     107         [ +  - ]:          2 :         nEndLbl = aGen.Gen( _JUMPF, 0 );
     108         [ +  - ]:          2 :         Push( eCurTok );
     109         [ +  - ]:          2 :         while( !bAbort )
     110                 :            :         {
     111 [ +  - ][ -  + ]:          2 :             if( !Parse() ) break;
     112         [ +  - ]:          2 :             eTok = Peek();
     113 [ +  - ][ -  + ]:          2 :             if( eTok == ELSE || eTok == EOLN || eTok == REM )
                 [ #  # ]
     114                 :          2 :                 break;
     115                 :            :         }
     116         [ -  + ]:          2 :         if( eTok == ELSE )
     117                 :            :         {
     118         [ #  # ]:          0 :             Next();
     119                 :          0 :             sal_uInt32 nElseLbl = nEndLbl;
     120         [ #  # ]:          0 :             nEndLbl = aGen.Gen( _JUMP, 0 );
     121         [ #  # ]:          0 :             aGen.BackChain( nElseLbl );
     122         [ #  # ]:          0 :             while( !bAbort )
     123                 :            :             {
     124 [ #  # ][ #  # ]:          0 :                 if( !Parse() ) break;
     125         [ #  # ]:          0 :                 eTok = Peek();
     126         [ #  # ]:          0 :                 if( eTok == EOLN )
     127                 :          0 :                     break;
     128                 :            :             }
     129                 :            :         }
     130                 :          2 :         bSingleLineIf = false;
     131                 :            :     }
     132 [ +  - ][ +  - ]:        249 :     aGen.BackChain( nEndLbl );
                 [ +  - ]
     133                 :            : }
     134                 :            : 
     135                 :            : // ELSE/ELSEIF/ENDIF without IF
     136                 :            : 
     137                 :          0 : void SbiParser::NoIf()
     138                 :            : {
     139                 :          0 :     Error( SbERR_NO_IF );
     140                 :          0 :     StmntBlock( ENDIF );
     141                 :          0 : }
     142                 :            : 
     143                 :            : // DO WHILE...LOOP
     144                 :            : // DO ... LOOP WHILE
     145                 :            : 
     146                 :          0 : void SbiParser::DoLoop()
     147                 :            : {
     148                 :          0 :     sal_uInt32 nStartLbl = aGen.GetPC();
     149                 :          0 :     OpenBlock( DO );
     150                 :          0 :     SbiToken eTok = Next();
     151         [ #  # ]:          0 :     if( IsEoln( eTok ) )
     152                 :            :     {
     153                 :            :         // DO ... LOOP [WHILE|UNTIL expr]
     154                 :          0 :         StmntBlock( LOOP );
     155                 :          0 :         eTok = Next();
     156 [ #  # ][ #  # ]:          0 :         if( eTok == UNTIL || eTok == WHILE )
     157                 :            :         {
     158         [ #  # ]:          0 :             SbiExpression aExpr( this );
     159         [ #  # ]:          0 :             aExpr.Gen();
     160 [ #  # ][ #  # ]:          0 :             aGen.Gen( eTok == UNTIL ? _JUMPF : _JUMPT, nStartLbl );
                 [ #  # ]
     161                 :            :         } else
     162 [ #  # ][ #  # ]:          0 :             if (eTok == EOLN || eTok == REM)
     163                 :          0 :                 aGen.Gen (_JUMP, nStartLbl);
     164                 :            :             else
     165                 :          0 :                 Error( SbERR_EXPECTED, WHILE );
     166                 :            :     }
     167                 :            :     else
     168                 :            :     {
     169                 :            :         // DO [WHILE|UNTIL expr] ... LOOP
     170 [ #  # ][ #  # ]:          0 :         if( eTok == UNTIL || eTok == WHILE )
     171                 :            :         {
     172         [ #  # ]:          0 :             SbiExpression aCond( this );
     173 [ #  # ][ #  # ]:          0 :             aCond.Gen();
     174                 :            :         }
     175         [ #  # ]:          0 :         sal_uInt32 nEndLbl = aGen.Gen( eTok == UNTIL ? _JUMPT : _JUMPF, 0 );
     176                 :          0 :         StmntBlock( LOOP );
     177                 :          0 :         TestEoln();
     178                 :          0 :         aGen.Gen( _JUMP, nStartLbl );
     179                 :          0 :         aGen.BackChain( nEndLbl );
     180                 :            :     }
     181                 :          0 :     CloseBlock();
     182                 :          0 : }
     183                 :            : 
     184                 :            : // WHILE ... WEND
     185                 :            : 
     186                 :          0 : void SbiParser::While()
     187                 :            : {
     188         [ #  # ]:          0 :     SbiExpression aCond( this );
     189         [ #  # ]:          0 :     sal_uInt32 nStartLbl = aGen.GetPC();
     190         [ #  # ]:          0 :     aCond.Gen();
     191         [ #  # ]:          0 :     sal_uInt32 nEndLbl = aGen.Gen( _JUMPF, 0 );
     192         [ #  # ]:          0 :     StmntBlock( WEND );
     193         [ #  # ]:          0 :     aGen.Gen( _JUMP, nStartLbl );
     194 [ #  # ][ #  # ]:          0 :     aGen.BackChain( nEndLbl );
     195                 :          0 : }
     196                 :            : 
     197                 :            : // FOR var = expr TO expr STEP
     198                 :            : 
     199                 :         36 : void SbiParser::For()
     200                 :            : {
     201         [ +  - ]:         36 :     bool bForEach = ( Peek() == EACH );
     202         [ -  + ]:         36 :     if( bForEach )
     203         [ #  # ]:          0 :         Next();
     204         [ +  - ]:         36 :     SbiExpression aLvalue( this, SbOPERAND );
     205         [ +  - ]:         36 :     aLvalue.Gen();      // variable on the Stack
     206                 :            : 
     207         [ -  + ]:         36 :     if( bForEach )
     208                 :            :     {
     209         [ #  # ]:          0 :         TestToken( _IN_ );
     210         [ #  # ]:          0 :         SbiExpression aCollExpr( this, SbOPERAND );
     211         [ #  # ]:          0 :         aCollExpr.Gen();    // Colletion var to for stack
     212         [ #  # ]:          0 :         TestEoln();
     213 [ #  # ][ #  # ]:          0 :         aGen.Gen( _INITFOREACH );
     214                 :            :     }
     215                 :            :     else
     216                 :            :     {
     217         [ +  - ]:         36 :         TestToken( EQ );
     218         [ +  - ]:         36 :         SbiExpression aStartExpr( this );
     219         [ +  - ]:         36 :         aStartExpr.Gen();
     220         [ +  - ]:         36 :         TestToken( TO );
     221         [ +  - ]:         36 :         SbiExpression aStopExpr( this );
     222         [ +  - ]:         36 :         aStopExpr.Gen();
     223 [ +  - ][ -  + ]:         36 :         if( Peek() == STEP )
     224                 :            :         {
     225         [ #  # ]:          0 :             Next();
     226         [ #  # ]:          0 :             SbiExpression aStepExpr( this );
     227 [ #  # ][ #  # ]:          0 :             aStepExpr.Gen();
     228                 :            :         }
     229                 :            :         else
     230                 :            :         {
     231         [ +  - ]:         36 :             SbiExpression aOne( this, 1, SbxINTEGER );
     232 [ +  - ][ +  - ]:         36 :             aOne.Gen();
     233                 :            :         }
     234         [ +  - ]:         36 :         TestEoln();
     235                 :            :         // The stack has all 4 elements now: variable, start, end, increment
     236                 :            :         // bind start value
     237 [ +  - ][ +  - ]:         36 :         aGen.Gen( _INITFOR );
                 [ +  - ]
     238                 :            :     }
     239                 :            : 
     240         [ +  - ]:         36 :     sal_uInt32 nLoop = aGen.GetPC();
     241                 :            :     // do tests, maybe free the stack
     242         [ +  - ]:         36 :     sal_uInt32 nEndTarget = aGen.Gen( _TESTFOR, 0 );
     243         [ +  - ]:         36 :     OpenBlock( FOR );
     244         [ +  - ]:         36 :     StmntBlock( NEXT );
     245         [ +  - ]:         36 :     aGen.Gen( _NEXT );
     246         [ +  - ]:         36 :     aGen.Gen( _JUMP, nLoop );
     247                 :            :     // are there variables after NEXT?
     248 [ +  - ][ +  + ]:         36 :     if( Peek() == SYMBOL )
     249                 :            :     {
     250         [ +  - ]:         30 :         SbiExpression aVar( this, SbOPERAND );
     251 [ +  - ][ +  - ]:         30 :         if( aVar.GetRealVar() != aLvalue.GetRealVar() )
                 [ -  + ]
     252 [ #  # ][ #  # ]:         30 :             Error( SbERR_EXPECTED, aLvalue.GetRealVar()->GetName() );
         [ #  # ][ #  # ]
                 [ +  - ]
     253                 :            :     }
     254         [ +  - ]:         36 :     aGen.BackChain( nEndTarget );
     255 [ +  - ][ +  - ]:         36 :     CloseBlock();
     256                 :         36 : }
     257                 :            : 
     258                 :            : // WITH .. END WITH
     259                 :            : 
     260                 :          0 : void SbiParser::With()
     261                 :            : {
     262         [ #  # ]:          0 :     SbiExpression aVar( this, SbOPERAND );
     263                 :            : 
     264         [ #  # ]:          0 :     SbiExprNode *pNode = aVar.GetExprNode()->GetRealNode();
     265         [ #  # ]:          0 :     SbiSymDef* pDef = pNode->GetVar();
     266                 :            :     // Variant, from 27.6.1997, #41090: empty -> must be Object
     267 [ #  # ][ #  # ]:          0 :     if( pDef->GetType() == SbxVARIANT || pDef->GetType() == SbxEMPTY )
                 [ #  # ]
     268         [ #  # ]:          0 :         pDef->SetType( SbxOBJECT );
     269         [ #  # ]:          0 :     else if( pDef->GetType() != SbxOBJECT )
     270         [ #  # ]:          0 :         Error( SbERR_NEEDS_OBJECT );
     271                 :            : 
     272                 :            : 
     273                 :          0 :     pNode->SetType( SbxOBJECT );
     274                 :            : 
     275         [ #  # ]:          0 :     OpenBlock( NIL, aVar.GetExprNode() );
     276         [ #  # ]:          0 :     StmntBlock( ENDWITH );
     277 [ #  # ][ #  # ]:          0 :     CloseBlock();
     278                 :          0 : }
     279                 :            : 
     280                 :            : // LOOP/NEXT/WEND without construct
     281                 :            : 
     282                 :          0 : void SbiParser::BadBlock()
     283                 :            : {
     284         [ #  # ]:          0 :     if( eEndTok )
     285                 :          0 :         Error( SbERR_BAD_BLOCK, eEndTok );
     286                 :            :     else
     287                 :          0 :         Error( SbERR_BAD_BLOCK, "Loop/Next/Wend" );
     288                 :          0 : }
     289                 :            : 
     290                 :            : // On expr Goto/Gosub n,n,n...
     291                 :            : 
     292                 :          0 : void SbiParser::OnGoto()
     293                 :            : {
     294         [ #  # ]:          0 :     SbiExpression aCond( this );
     295         [ #  # ]:          0 :     aCond.Gen();
     296         [ #  # ]:          0 :     sal_uInt32 nLabelsTarget = aGen.Gen( _ONJUMP, 0 );
     297         [ #  # ]:          0 :     SbiToken eTok = Next();
     298 [ #  # ][ #  # ]:          0 :     if( eTok != GOTO && eTok != GOSUB )
     299                 :            :     {
     300         [ #  # ]:          0 :         Error( SbERR_EXPECTED, "GoTo/GoSub" );
     301                 :          0 :         eTok = GOTO;
     302                 :            :     }
     303                 :            : 
     304                 :          0 :     sal_uInt32 nLbl = 0;
     305 [ #  # ][ #  # ]:          0 :     do
                 [ #  # ]
     306                 :            :     {
     307         [ #  # ]:          0 :         Next(); // get label
     308 [ #  # ][ #  # ]:          0 :         if( MayBeLabel() )
     309                 :            :         {
     310 [ #  # ][ #  # ]:          0 :             sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
                 [ #  # ]
     311         [ #  # ]:          0 :             aGen.Gen( _JUMP, nOff );
     312                 :          0 :             nLbl++;
     313                 :            :         }
     314         [ #  # ]:          0 :         else Error( SbERR_LABEL_EXPECTED );
     315                 :            :     }
     316         [ #  # ]:          0 :     while( !bAbort && TestComma() );
     317         [ #  # ]:          0 :     if( eTok == GOSUB )
     318                 :          0 :         nLbl |= 0x8000;
     319 [ #  # ][ #  # ]:          0 :     aGen.Patch( nLabelsTarget, nLbl );
     320                 :          0 : }
     321                 :            : 
     322                 :            : // GOTO/GOSUB
     323                 :            : 
     324                 :          2 : void SbiParser::Goto()
     325                 :            : {
     326         [ +  - ]:          2 :     SbiOpcode eOp = eCurTok == GOTO ? _JUMP : _GOSUB;
     327                 :          2 :     Next();
     328         [ +  - ]:          2 :     if( MayBeLabel() )
     329                 :            :     {
     330         [ +  - ]:          2 :         sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
     331                 :          2 :         aGen.Gen( eOp, nOff );
     332                 :            :     }
     333                 :          0 :     else Error( SbERR_LABEL_EXPECTED );
     334                 :          2 : }
     335                 :            : 
     336                 :            : // RETURN [label]
     337                 :            : 
     338                 :          0 : void SbiParser::Return()
     339                 :            : {
     340                 :          0 :     Next();
     341         [ #  # ]:          0 :     if( MayBeLabel() )
     342                 :            :     {
     343         [ #  # ]:          0 :         sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
     344                 :          0 :         aGen.Gen( _RETURN, nOff );
     345                 :            :     }
     346                 :          0 :     else aGen.Gen( _RETURN, 0 );
     347                 :          0 : }
     348                 :            : 
     349                 :            : // SELECT CASE
     350                 :            : 
     351                 :         16 : void SbiParser::Select()
     352                 :            : {
     353         [ +  - ]:         16 :     TestToken( CASE );
     354         [ +  - ]:         16 :     SbiExpression aCase( this );
     355                 :         16 :     SbiToken eTok = NIL;
     356         [ +  - ]:         16 :     aCase.Gen();
     357         [ +  - ]:         16 :     aGen.Gen( _CASE );
     358         [ +  - ]:         16 :     TestEoln();
     359                 :         16 :     sal_uInt32 nNextTarget = 0;
     360                 :         16 :     sal_uInt32 nDoneTarget = 0;
     361                 :         16 :     sal_Bool bElse = sal_False;
     362                 :            : 
     363         [ +  - ]:        168 :     while( !bAbort )
     364                 :            :     {
     365         [ +  - ]:        168 :         eTok = Next();
     366         [ +  + ]:        168 :         if( eTok == CASE )
     367                 :            :         {
     368         [ +  + ]:        152 :             if( nNextTarget )
     369         [ +  - ]:        136 :                 aGen.BackChain( nNextTarget ), nNextTarget = 0;
     370         [ +  - ]:        152 :             aGen.Statement();
     371                 :            : 
     372                 :        152 :             sal_Bool bDone = sal_False;
     373                 :        152 :             sal_uInt32 nTrueTarget = 0;
     374 [ +  - ][ +  + ]:        152 :             if( Peek() == ELSE )
     375                 :            :             {
     376                 :            :                 // CASE ELSE
     377         [ +  - ]:         12 :                 Next();
     378                 :         12 :                 bElse = sal_True;
     379                 :            :             }
     380         [ +  + ]:        288 :             else while( !bDone )
     381                 :            :             {
     382         [ -  + ]:        148 :                 if( bElse )
     383         [ #  # ]:          0 :                     Error( SbERR_SYNTAX );
     384         [ +  - ]:        148 :                 SbiToken eTok2 = Peek();
     385 [ +  - ][ +  - ]:        148 :                 if( eTok2 == IS || ( eTok2 >= EQ && eTok2 <= GE ) )
                 [ -  + ]
     386                 :            :                 {   // CASE [IS] operator expr
     387         [ #  # ]:          0 :                     if( eTok2 == IS )
     388         [ #  # ]:          0 :                         Next();
     389         [ #  # ]:          0 :                     eTok2 = Peek();
     390 [ #  # ][ #  # ]:          0 :                     if( eTok2 < EQ || eTok2 > GE )
     391         [ #  # ]:          0 :                         Error( SbERR_SYNTAX );
     392         [ #  # ]:          0 :                     else Next();
     393         [ #  # ]:          0 :                     SbiExpression aCompare( this );
     394         [ #  # ]:          0 :                     aCompare.Gen();
     395                 :            :                     nTrueTarget = aGen.Gen(
     396                 :            :                         _CASEIS, nTrueTarget,
     397                 :            :                         sal::static_int_cast< sal_uInt16 >(
     398 [ #  # ][ #  # ]:          0 :                             SbxEQ + ( eTok2 - EQ ) ) );
     399                 :            :                 }
     400                 :            :                 else
     401                 :            :                 {   // CASE expr | expr TO expr
     402         [ +  - ]:        148 :                     SbiExpression aCase1( this );
     403         [ +  - ]:        148 :                     aCase1.Gen();
     404 [ +  - ][ -  + ]:        148 :                     if( Peek() == TO )
     405                 :            :                     {
     406                 :            :                         // CASE a TO b
     407         [ #  # ]:          0 :                         Next();
     408         [ #  # ]:          0 :                         SbiExpression aCase2( this );
     409         [ #  # ]:          0 :                         aCase2.Gen();
     410 [ #  # ][ #  # ]:          0 :                         nTrueTarget = aGen.Gen( _CASETO, nTrueTarget );
     411                 :            :                     }
     412                 :            :                     else
     413                 :            :                         // CASE a
     414 [ +  - ][ +  - ]:        148 :                         nTrueTarget = aGen.Gen( _CASEIS, nTrueTarget, SbxEQ );
     415                 :            : 
     416                 :            :                 }
     417 [ +  - ][ +  + ]:        148 :                 if( Peek() == COMMA ) Next();
                 [ +  - ]
     418         [ +  - ]:        140 :                 else TestEoln(), bDone = sal_True;
     419                 :            :             }
     420                 :            : 
     421         [ +  + ]:        152 :             if( !bElse )
     422                 :            :             {
     423         [ +  - ]:        140 :                 nNextTarget = aGen.Gen( _JUMP, nNextTarget );
     424         [ +  - ]:        140 :                 aGen.BackChain( nTrueTarget );
     425                 :            :             }
     426                 :            :             // build the statement body
     427         [ +  - ]:        326 :             while( !bAbort )
     428                 :            :             {
     429         [ +  - ]:        326 :                 eTok = Peek();
     430 [ +  - ][ -  + ]:        326 :                 if( eTok == CASE || eTok == ENDSELECT )
     431                 :          0 :                     break;
     432 [ +  - ][ -  + ]:        326 :                 if( !Parse() ) goto done;
     433         [ +  - ]:        326 :                 eTok = Peek();
     434 [ +  + ][ +  + ]:        326 :                 if( eTok == CASE || eTok == ENDSELECT )
     435                 :        152 :                     break;
     436                 :            :             }
     437         [ +  + ]:        152 :             if( !bElse )
     438         [ +  - ]:        140 :                 nDoneTarget = aGen.Gen( _JUMP, nDoneTarget );
     439                 :            :         }
     440         [ +  - ]:         16 :         else if( !IsEoln( eTok ) )
     441                 :         16 :             break;
     442                 :            :     }
     443                 :            : done:
     444         [ -  + ]:         16 :     if( eTok != ENDSELECT )
     445         [ #  # ]:          0 :         Error( SbERR_EXPECTED, ENDSELECT );
     446         [ +  + ]:         16 :     if( nNextTarget )
     447         [ +  - ]:          4 :         aGen.BackChain( nNextTarget );
     448         [ +  - ]:         16 :     aGen.BackChain( nDoneTarget );
     449 [ +  - ][ +  - ]:         16 :     aGen.Gen( _ENDCASE );
     450                 :         16 : }
     451                 :            : 
     452                 :            : // ON Error/Variable
     453                 :            : 
     454                 :            : #ifdef _MSC_VER
     455                 :            : #pragma optimize("",off)
     456                 :            : #endif
     457                 :            : 
     458                 :         14 : void SbiParser::On()
     459                 :            : {
     460         [ +  - ]:         14 :     SbiToken eTok = Peek();
     461 [ +  - ][ +  - ]:         14 :     String aString = SbiTokenizer::Symbol(eTok);
     462 [ +  - ][ +  + ]:         14 :     if (aString.EqualsIgnoreCaseAscii("ERROR"))
     463                 :          2 :         eTok = _ERROR_; // Error comes as SYMBOL
     464 [ +  + ][ -  + ]:         14 :     if( eTok != _ERROR_ && eTok != LOCAL ) OnGoto();
                 [ #  # ]
     465                 :            :     else
     466                 :            :     {
     467 [ +  + ][ +  - ]:         14 :         if( eTok == LOCAL ) Next();
     468         [ +  - ]:         14 :         Next (); // no more TestToken, as there'd be an error otherwise
     469                 :            : 
     470         [ +  - ]:         14 :         Next(); // get token after error
     471         [ +  - ]:         14 :         if( eCurTok == GOTO )
     472                 :            :         {
     473                 :            :             // ON ERROR GOTO label|0
     474         [ +  - ]:         14 :             Next();
     475                 :         14 :             bool bError_ = false;
     476 [ +  - ][ +  - ]:         14 :             if( MayBeLabel() )
     477                 :            :             {
     478 [ -  + ][ #  # ]:         14 :                 if( eCurTok == NUMBER && !nVal )
     479         [ #  # ]:          0 :                     aGen.Gen( _STDERROR );
     480                 :            :                 else
     481                 :            :                 {
     482 [ +  - ][ +  - ]:         14 :                     sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
                 [ +  - ]
     483         [ +  - ]:         14 :                     aGen.Gen( _ERRHDL, nOff );
     484                 :            :                 }
     485                 :            :             }
     486         [ #  # ]:          0 :             else if( eCurTok == MINUS )
     487                 :            :             {
     488         [ #  # ]:          0 :                 Next();
     489 [ #  # ][ #  # ]:          0 :                 if( eCurTok == NUMBER && nVal == 1 )
     490         [ #  # ]:          0 :                     aGen.Gen( _STDERROR );
     491                 :            :                 else
     492                 :          0 :                     bError_ = true;
     493                 :            :             }
     494         [ -  + ]:         14 :             if( bError_ )
     495         [ #  # ]:          0 :                 Error( SbERR_LABEL_EXPECTED );
     496                 :            :         }
     497         [ #  # ]:          0 :         else if( eCurTok == RESUME )
     498                 :            :         {
     499         [ #  # ]:          0 :             TestToken( NEXT );
     500         [ #  # ]:          0 :             aGen.Gen( _NOERROR );
     501                 :            :         }
     502         [ #  # ]:          0 :         else Error( SbERR_EXPECTED, "GoTo/Resume" );
     503         [ +  - ]:         14 :     }
     504                 :         14 : }
     505                 :            : 
     506                 :            : #ifdef _MSC_VER
     507                 :            : #pragma optimize("",off)
     508                 :            : #endif
     509                 :            : 
     510                 :            : // RESUME [0]|NEXT|label
     511                 :            : 
     512                 :          0 : void SbiParser::Resume()
     513                 :            : {
     514                 :            :     sal_uInt32 nLbl;
     515                 :            : 
     516   [ #  #  #  #  :          0 :     switch( Next() )
                      # ]
     517                 :            :     {
     518                 :            :         case EOS:
     519                 :            :         case EOLN:
     520                 :          0 :             aGen.Gen( _RESUME, 0 );
     521                 :          0 :             break;
     522                 :            :         case NEXT:
     523                 :          0 :             aGen.Gen( _RESUME, 1 );
     524                 :          0 :             Next();
     525                 :          0 :             break;
     526                 :            :         case NUMBER:
     527         [ #  # ]:          0 :             if( !nVal )
     528                 :            :             {
     529                 :          0 :                 aGen.Gen( _RESUME, 0 );
     530                 :          0 :                 break;
     531                 :            :             } // fall thru
     532                 :            :         case SYMBOL:
     533         [ #  # ]:          0 :             if( MayBeLabel() )
     534                 :            :             {
     535         [ #  # ]:          0 :                 nLbl = pProc->GetLabels().Reference( aSym );
     536                 :          0 :                 aGen.Gen( _RESUME, nLbl );
     537                 :          0 :                 Next();
     538                 :          0 :                 break;
     539                 :            :             } // fall thru
     540                 :            :         default:
     541                 :          0 :             Error( SbERR_LABEL_EXPECTED );
     542                 :            :     }
     543                 :          0 : }
     544                 :            : 
     545                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10