LCOV - code coverage report
Current view: top level - libreoffice/basic/source/runtime - runtime.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 253 544 46.5 %
Date: 2012-12-17 Functions: 28 55 50.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <tools/fsys.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <tools/wldcrd.hxx>
      23             : #include <svl/zforlist.hxx>
      24             : #include <unotools/syslocale.hxx>
      25             : #include "runtime.hxx"
      26             : #include "sbintern.hxx"
      27             : #include "opcodes.hxx"
      28             : #include "codegen.hxx"
      29             : #include "iosys.hxx"
      30             : #include "image.hxx"
      31             : #include "ddectrl.hxx"
      32             : #include "dllmgr.hxx"
      33             : #include <comphelper/processfactory.hxx>
      34             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      35             : #include "sbunoobj.hxx"
      36             : #include "errobject.hxx"
      37             : 
      38             : #include "comenumwrapper.hxx"
      39             : 
      40             : SbxVariable* getDefaultProp( SbxVariable* pRef );
      41             : 
      42             : using namespace ::com::sun::star;
      43             : 
      44        1608 : bool SbiRuntime::isVBAEnabled()
      45             : {
      46        1608 :     bool result = false;
      47        1608 :     SbiInstance* pInst = GetSbData()->pInst;
      48        1608 :     if ( pInst && GetSbData()->pInst->pRun )
      49        1552 :         result = pInst->pRun->bVBAEnabled;
      50        1608 :     return result;
      51             : }
      52             : 
      53         556 : void StarBASIC::SetVBAEnabled( bool bEnabled )
      54             : {
      55         556 :     if ( bDocBasic )
      56             :     {
      57         508 :         bVBAEnabled = bEnabled;
      58             :     }
      59         556 : }
      60             : 
      61          70 : bool StarBASIC::isVBAEnabled()
      62             : {
      63          70 :     if ( bDocBasic )
      64             :     {
      65          52 :         if( SbiRuntime::isVBAEnabled() )
      66           0 :             return true;
      67          52 :         return bVBAEnabled;
      68             :     }
      69          18 :     return false;
      70             : }
      71             : 
      72             : 
      73         620 : struct SbiArgvStack {                   // Argv stack:
      74             :     SbiArgvStack*  pNext;               // Stack Chain
      75             :     SbxArrayRef    refArgv;             // Argv
      76             :     short nArgc;                        // Argc
      77             : };
      78             : 
      79             : SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // all opcodes without operands
      80             :     &SbiRuntime::StepNOP,
      81             :     &SbiRuntime::StepEXP,
      82             :     &SbiRuntime::StepMUL,
      83             :     &SbiRuntime::StepDIV,
      84             :     &SbiRuntime::StepMOD,
      85             :     &SbiRuntime::StepPLUS,
      86             :     &SbiRuntime::StepMINUS,
      87             :     &SbiRuntime::StepNEG,
      88             :     &SbiRuntime::StepEQ,
      89             :     &SbiRuntime::StepNE,
      90             :     &SbiRuntime::StepLT,
      91             :     &SbiRuntime::StepGT,
      92             :     &SbiRuntime::StepLE,
      93             :     &SbiRuntime::StepGE,
      94             :     &SbiRuntime::StepIDIV,
      95             :     &SbiRuntime::StepAND,
      96             :     &SbiRuntime::StepOR,
      97             :     &SbiRuntime::StepXOR,
      98             :     &SbiRuntime::StepEQV,
      99             :     &SbiRuntime::StepIMP,
     100             :     &SbiRuntime::StepNOT,
     101             :     &SbiRuntime::StepCAT,
     102             : 
     103             :     &SbiRuntime::StepLIKE,
     104             :     &SbiRuntime::StepIS,
     105             :     // load/save
     106             :     &SbiRuntime::StepARGC,      // establish new Argv
     107             :     &SbiRuntime::StepARGV,      // TOS ==> current Argv
     108             :     &SbiRuntime::StepINPUT,     // Input ==> TOS
     109             :     &SbiRuntime::StepLINPUT,        // Line Input ==> TOS
     110             :     &SbiRuntime::StepGET,        // touch TOS
     111             :     &SbiRuntime::StepSET,        // save object TOS ==> TOS-1
     112             :     &SbiRuntime::StepPUT,       // TOS ==> TOS-1
     113             :     &SbiRuntime::StepPUTC,      // TOS ==> TOS-1, then ReadOnly
     114             :     &SbiRuntime::StepDIM,       // DIM
     115             :     &SbiRuntime::StepREDIM,         // REDIM
     116             :     &SbiRuntime::StepREDIMP,        // REDIM PRESERVE
     117             :     &SbiRuntime::StepERASE,         // delete TOS
     118             :     // branch
     119             :     &SbiRuntime::StepSTOP,          // program end
     120             :     &SbiRuntime::StepINITFOR,   // intitialize FOR-Variable
     121             :     &SbiRuntime::StepNEXT,      // increment FOR-Variable
     122             :     &SbiRuntime::StepCASE,      // beginning CASE
     123             :     &SbiRuntime::StepENDCASE,   // end CASE
     124             :     &SbiRuntime::StepSTDERROR,      // standard error handling
     125             :     &SbiRuntime::StepNOERROR,   // no error handling
     126             :     &SbiRuntime::StepLEAVE,     // leave UP
     127             :     // E/A
     128             :     &SbiRuntime::StepCHANNEL,   // TOS = channel number
     129             :     &SbiRuntime::StepPRINT,     // print TOS
     130             :     &SbiRuntime::StepPRINTF,        // print TOS in field
     131             :     &SbiRuntime::StepWRITE,     // write TOS
     132             :     &SbiRuntime::StepRENAME,        // Rename Tos+1 to Tos
     133             :     &SbiRuntime::StepPROMPT,        // define Input Prompt from TOS
     134             :     &SbiRuntime::StepRESTART,   // Set restart point
     135             :     &SbiRuntime::StepCHANNEL0,  // set E/A-channel 0
     136             :     &SbiRuntime::StepEMPTY,     // empty expression on stack
     137             :     &SbiRuntime::StepERROR,     // TOS = error code
     138             :     &SbiRuntime::StepLSET,      // save object TOS ==> TOS-1
     139             :     &SbiRuntime::StepRSET,      // save object TOS ==> TOS-1
     140             :     &SbiRuntime::StepREDIMP_ERASE,// Copy array object for REDIMP
     141             :     &SbiRuntime::StepINITFOREACH,// Init for each loop
     142             :     &SbiRuntime::StepVBASET,// vba-like set statement
     143             :     &SbiRuntime::StepERASE_CLEAR,// vba-like set statement
     144             :     &SbiRuntime::StepARRAYACCESS,// access TOS as array
     145             :     &SbiRuntime::StepBYVAL,     // access TOS as array
     146             : };
     147             : 
     148             : SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // all opcodes with one operand
     149             :     &SbiRuntime::StepLOADNC,        // loading a numeric constant (+ID)
     150             :     &SbiRuntime::StepLOADSC,        // loading a string constant (+ID)
     151             :     &SbiRuntime::StepLOADI,     // Immediate Load (+Wert)
     152             :     &SbiRuntime::StepARGN,      // save a named Args in Argv (+StringID)
     153             :     &SbiRuntime::StepPAD,       // bring string to a definite length (+length)
     154             :     // branches
     155             :     &SbiRuntime::StepJUMP,      // jump (+Target)
     156             :     &SbiRuntime::StepJUMPT,     // evaluate TOS, conditional jump (+Target)
     157             :     &SbiRuntime::StepJUMPF,     // evaluate TOS, conditional jump (+Target)
     158             :     &SbiRuntime::StepONJUMP,        // evaluate TOS, jump into JUMP-table (+MaxVal)
     159             :     &SbiRuntime::StepGOSUB,     // UP-call (+Target)
     160             :     &SbiRuntime::StepRETURN,        // UP-return (+0 or Target)
     161             :     &SbiRuntime::StepTESTFOR,   // check FOR-variable, increment (+Endlabel)
     162             :     &SbiRuntime::StepCASETO,        // Tos+1 <= Case <= Tos), 2xremove (+Target)
     163             :     &SbiRuntime::StepERRHDL,        // error handler (+Offset)
     164             :     &SbiRuntime::StepRESUME,        // resume after errors (+0 or 1 or Label)
     165             :     // E/A
     166             :     &SbiRuntime::StepCLOSE,     // (+channel/0)
     167             :     &SbiRuntime::StepPRCHAR,        // (+char)
     168             :     // management
     169             :     &SbiRuntime::StepSETCLASS,  // check set + class names (+StringId)
     170             :     &SbiRuntime::StepTESTCLASS, // Check TOS class (+StringId)
     171             :     &SbiRuntime::StepLIB,       // lib for declare-call (+StringId)
     172             :     &SbiRuntime::StepBASED,     // TOS is incremented by BASE, BASE is pushed before
     173             :     &SbiRuntime::StepARGTYP,        // convert last parameter in Argv (+Type)
     174             :     &SbiRuntime::StepVBASETCLASS,// vba-like set statement
     175             : };
     176             : 
     177             : SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// all opcodes with two operands
     178             :     &SbiRuntime::StepRTL,       // load from RTL (+StringID+Typ)
     179             :     &SbiRuntime::StepFIND,      // load (+StringID+Typ)
     180             :     &SbiRuntime::StepELEM,          // load element (+StringID+Typ)
     181             :     &SbiRuntime::StepPARAM,     // Parameter (+Offset+Typ)
     182             :     // Verzweigen
     183             :     &SbiRuntime::StepCALL,      // Declare-Call (+StringID+Typ)
     184             :     &SbiRuntime::StepCALLC,     // CDecl-Declare-Call (+StringID+Typ)
     185             :     &SbiRuntime::StepCASEIS,        // Case-Test (+Test-Opcode+False-Target)
     186             :     // Verwaltung
     187             :     &SbiRuntime::StepSTMNT,         // beginning of a statement (+Line+Col)
     188             :     // E/A
     189             :     &SbiRuntime::StepOPEN,          // (+SvStreamFlags+Flags)
     190             :     // Objects
     191             :     &SbiRuntime::StepLOCAL,     // define local variable (+StringId+Typ)
     192             :     &SbiRuntime::StepPUBLIC,        // module global variable (+StringID+Typ)
     193             :     &SbiRuntime::StepGLOBAL,        // define global variable (+StringID+Typ)
     194             :     &SbiRuntime::StepCREATE,        // create object (+StringId+StringId)
     195             :     &SbiRuntime::StepSTATIC,     // static variable (+StringId+StringId)
     196             :     &SbiRuntime::StepTCREATE,    // user-defined objects (+StringId+StringId)
     197             :     &SbiRuntime::StepDCREATE,    // create object-array (+StringID+StringID)
     198             :     &SbiRuntime::StepGLOBAL_P,   // define global variable which is not overwritten
     199             :                                  // by the Basic on a restart (+StringID+Typ)
     200             :     &SbiRuntime::StepFIND_G,        // finds global variable with special treatment because of _GLOBAL_P
     201             :     &SbiRuntime::StepDCREATE_REDIMP, // redimension object array (+StringID+StringID)
     202             :     &SbiRuntime::StepFIND_CM,    // Search inside a class module (CM) to enable global search in time
     203             :     &SbiRuntime::StepPUBLIC_P,    // Search inside a class module (CM) to enable global search in time
     204             :     &SbiRuntime::StepFIND_STATIC,    // Search inside a class module (CM) to enable global search in time
     205             : };
     206             : 
     207             : 
     208             : //                              SbiRTLData                              //
     209             : 
     210          20 : SbiRTLData::SbiRTLData()
     211             : {
     212          20 :     pDir        = 0;
     213          20 :     nDirFlags   = 0;
     214          20 :     nCurDirPos  = 0;
     215          20 :     pWildCard   = NULL;
     216          20 : }
     217             : 
     218          40 : SbiRTLData::~SbiRTLData()
     219             : {
     220          20 :     delete pDir;
     221          20 :     pDir = 0;
     222          20 :     delete pWildCard;
     223          20 : }
     224             : 
     225             : //                              SbiInstance                             //
     226             : 
     227             : // 16.10.96: #31460 new concept for StepInto/Over/Out
     228             : // The decision whether StepPoint shall be called is done with the help of
     229             : // the CallLevel. It's stopped when the current CallLevel is <= nBreakCallLvl.
     230             : // The current CallLevel can never be smaller than 1, as it's also incremented
     231             : // during the call of a method (also main). Therefore a BreakCallLvl from 0
     232             : // means that the program isn't stopped at all.
     233             : // (also have a look at: step2.cxx, SbiRuntime::StepSTMNT() )
     234             : 
     235             : 
     236          20 : void SbiInstance::CalcBreakCallLevel( sal_uInt16 nFlags )
     237             : {
     238             : 
     239          20 :     nFlags &= ~((sal_uInt16)SbDEBUG_BREAK);
     240             : 
     241             :     sal_uInt16 nRet;
     242          20 :     switch( nFlags )
     243             :     {
     244             :     case SbDEBUG_STEPINTO:
     245           0 :         nRet = nCallLvl + 1;    // CallLevel+1 is also stopped
     246           0 :         break;
     247             :     case SbDEBUG_STEPOVER | SbDEBUG_STEPINTO:
     248           0 :         nRet = nCallLvl;        // current CallLevel is stopped
     249           0 :         break;
     250             :     case SbDEBUG_STEPOUT:
     251           0 :         nRet = nCallLvl - 1;    // smaller CallLevel is stopped
     252           0 :         break;
     253             :     case SbDEBUG_CONTINUE:
     254             :         // Basic-IDE returns 0 instead of SbDEBUG_CONTINUE, so also default=continue
     255             :     default:
     256          20 :         nRet = 0;               // CallLevel is always > 0 -> no StepPoint
     257             :     }
     258          20 :     nBreakCallLvl = nRet;           // take result
     259          20 : }
     260             : 
     261          20 : SbiInstance::SbiInstance( StarBASIC* p )
     262             : {
     263          20 :     pBasic   = p;
     264          20 :     pNext    = NULL;
     265          20 :     pRun     = NULL;
     266          20 :     pIosys   = new SbiIoSystem;
     267          20 :     pDdeCtrl = new SbiDdeControl;
     268          20 :     pDllMgr  = 0; // on demand
     269          20 :     pNumberFormatter = 0; // on demand
     270          20 :     nCallLvl = 0;
     271          20 :     nBreakCallLvl = 0;
     272             :     nErr     =
     273          20 :     nErl     = 0;
     274          20 :     bReschedule = sal_True;
     275          20 :     bCompatibility = sal_False;
     276          20 : }
     277             : 
     278          40 : SbiInstance::~SbiInstance()
     279             : {
     280          40 :     while( pRun )
     281             :     {
     282           0 :         SbiRuntime* p = pRun->pNext;
     283           0 :         delete pRun;
     284           0 :         pRun = p;
     285             :     }
     286          20 :     delete pIosys;
     287          20 :     delete pDdeCtrl;
     288          20 :     delete pDllMgr;
     289          20 :     delete pNumberFormatter;
     290             : 
     291             :     try
     292             :     {
     293          20 :         int nSize = ComponentVector.size();
     294          20 :         if( nSize )
     295             :         {
     296           0 :             for( int i = nSize - 1 ; i >= 0 ; --i )
     297             :             {
     298           0 :                 Reference< XComponent > xDlgComponent = ComponentVector[i];
     299           0 :                 if( xDlgComponent.is() )
     300           0 :                     xDlgComponent->dispose();
     301           0 :             }
     302             :         }
     303             :     }
     304           0 :     catch( const Exception& )
     305             :     {
     306             :         OSL_FAIL( "SbiInstance::~SbiInstance: caught an exception while disposing the components!" );
     307             :     }
     308             : 
     309          20 :     ComponentVector.clear();
     310          20 : }
     311             : 
     312           0 : SbiDllMgr* SbiInstance::GetDllMgr()
     313             : {
     314           0 :     if( !pDllMgr )
     315             :     {
     316           0 :         pDllMgr = new SbiDllMgr;
     317             :     }
     318           0 :     return pDllMgr;
     319             : }
     320             : 
     321             : // #39629 create NumberFormatter with the help of a static method now
     322           0 : SvNumberFormatter* SbiInstance::GetNumberFormatter()
     323             : {
     324           0 :     LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
     325           0 :     SvtSysLocale aSysLocale;
     326           0 :     DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
     327           0 :     if( pNumberFormatter )
     328             :     {
     329           0 :         if( eLangType != meFormatterLangType ||
     330             :             eDate != meFormatterDateFormat )
     331             :         {
     332           0 :             delete pNumberFormatter;
     333           0 :             pNumberFormatter = NULL;
     334             :         }
     335             :     }
     336           0 :     meFormatterLangType = eLangType;
     337           0 :     meFormatterDateFormat = eDate;
     338           0 :     if( !pNumberFormatter )
     339             :     {
     340             :         PrepareNumberFormatter( pNumberFormatter, nStdDateIdx, nStdTimeIdx, nStdDateTimeIdx,
     341           0 :         &meFormatterLangType, &meFormatterDateFormat );
     342             :     }
     343           0 :     return pNumberFormatter;
     344             : }
     345             : 
     346             : // #39629 offer NumberFormatter static too
     347           0 : void SbiInstance::PrepareNumberFormatter( SvNumberFormatter*& rpNumberFormatter,
     348             :     sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx,
     349             :     LanguageType* peFormatterLangType, DateFormat* peFormatterDateFormat )
     350             : {
     351             :     com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
     352           0 :         xFactory = comphelper::getProcessServiceFactory();
     353             : 
     354             :     LanguageType eLangType;
     355           0 :     if( peFormatterLangType )
     356             :     {
     357           0 :         eLangType = *peFormatterLangType;
     358             :     }
     359             :     else
     360             :     {
     361           0 :         eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
     362             :     }
     363             :     DateFormat eDate;
     364           0 :     if( peFormatterDateFormat )
     365             :     {
     366           0 :         eDate = *peFormatterDateFormat;
     367             :     }
     368             :     else
     369             :     {
     370           0 :         SvtSysLocale aSysLocale;
     371           0 :         eDate = aSysLocale.GetLocaleData().getDateFormat();
     372             :     }
     373             : 
     374           0 :     rpNumberFormatter = new SvNumberFormatter( xFactory, eLangType );
     375             : 
     376           0 :     sal_Int32 nCheckPos = 0; short nType;
     377           0 :     rnStdTimeIdx = rpNumberFormatter->GetStandardFormat( NUMBERFORMAT_TIME, eLangType );
     378             : 
     379             :     // the formatter's standard templates have only got a two-digit date
     380             :     // -> registering an own format
     381             : 
     382             :     // HACK, beause the numberformatter doesn't swap the place holders
     383             :     // for month, day and year according to the system setting.
     384             :     // Problem: Print Year(Date) under engl. BS
     385             :     // also have a look at: svtools\source\sbx\sbxdate.cxx
     386             : 
     387           0 :     OUString aDateStr;
     388           0 :     switch( eDate )
     389             :     {
     390           0 :     case MDY: aDateStr = "MM.TT.JJJJ"; break;
     391           0 :     case DMY: aDateStr = "TT.MM.JJJJ"; break;
     392           0 :     case YMD: aDateStr = "JJJJ.MM.TT"; break;
     393           0 :     default:  aDateStr = "MM.TT.JJJJ"; break;
     394             :     }
     395             :     rpNumberFormatter->PutandConvertEntry( aDateStr, nCheckPos, nType,
     396           0 :                                            rnStdDateIdx, LANGUAGE_GERMAN, eLangType );
     397           0 :     nCheckPos = 0;
     398           0 :     OUString aStrHHMMSS(" HH:MM:SS");
     399           0 :     aDateStr += aStrHHMMSS;
     400             :     rpNumberFormatter->PutandConvertEntry( aDateStr, nCheckPos, nType,
     401           0 :         rnStdDateTimeIdx, LANGUAGE_GERMAN, eLangType );
     402           0 : }
     403             : 
     404             : 
     405             : // Let engine run. If Flags == SbDEBUG_CONTINUE, take Flags over
     406             : 
     407           0 : void SbiInstance::Stop()
     408             : {
     409           0 :     for( SbiRuntime* p = pRun; p; p = p->pNext )
     410             :     {
     411           0 :         p->Stop();
     412             :     }
     413           0 : }
     414             : 
     415             : // Allows Basic IDE to set watch mode to suppress errors
     416             : static bool bWatchMode = false;
     417             : 
     418           0 : void setBasicWatchMode( bool bOn )
     419             : {
     420           0 :     bWatchMode = bOn;
     421           0 : }
     422             : 
     423           0 : void SbiInstance::Error( SbError n )
     424             : {
     425           0 :     Error( n, OUString() );
     426           0 : }
     427             : 
     428           4 : void SbiInstance::Error( SbError n, const OUString& rMsg )
     429             : {
     430           4 :     if( !bWatchMode )
     431             :     {
     432           4 :         aErrorMsg = rMsg;
     433           4 :         pRun->Error( n );
     434             :     }
     435           4 : }
     436             : 
     437           0 : void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const OUString& rMsg )
     438             : {
     439           0 :     if( !bWatchMode )
     440             :     {
     441           0 :         SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
     442           0 :         if ( !n )
     443             :         {
     444           0 :             n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
     445             :         }
     446           0 :         aErrorMsg = rMsg;
     447           0 :         SbiRuntime::translateErrorToVba( n, aErrorMsg );
     448             : 
     449           0 :         bool bVBATranslationAlreadyDone = true;
     450           0 :         pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone );
     451             :     }
     452           0 : }
     453             : 
     454           0 : void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const OUString& rMsg )
     455             : {
     456           0 :     SbError n = StarBASIC::GetSfxFromVBError( static_cast< sal_uInt16 >( nVBNumber ) );
     457           0 :     if( !n )
     458             :     {
     459           0 :         n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors
     460             :     }
     461           0 :     aErrorMsg = rMsg;
     462           0 :     SbiRuntime::translateErrorToVba( n, aErrorMsg );
     463             : 
     464           0 :     nErr = n;
     465           0 : }
     466             : 
     467             : 
     468           0 : void SbiInstance::FatalError( SbError n )
     469             : {
     470           0 :     pRun->FatalError( n );
     471           0 : }
     472             : 
     473           0 : void SbiInstance::FatalError( SbError _errCode, const OUString& _details )
     474             : {
     475           0 :     pRun->FatalError( _errCode, _details );
     476           0 : }
     477             : 
     478           0 : void SbiInstance::Abort()
     479             : {
     480           0 :     StarBASIC* pErrBasic = GetCurrentBasic( pBasic );
     481           0 :     pErrBasic->RTError( nErr, aErrorMsg, pRun->nLine, pRun->nCol1, pRun->nCol2 );
     482           0 :     pBasic->Stop();
     483           0 : }
     484             : 
     485             : // can be unequal to pRTBasic
     486           0 : StarBASIC* GetCurrentBasic( StarBASIC* pRTBasic )
     487             : {
     488           0 :     StarBASIC* pCurBasic = pRTBasic;
     489           0 :     SbModule* pActiveModule = pRTBasic->GetActiveModule();
     490           0 :     if( pActiveModule )
     491             :     {
     492           0 :         SbxObject* pParent = pActiveModule->GetParent();
     493           0 :         if( pParent && pParent->ISA(StarBASIC) )
     494             :         {
     495           0 :             pCurBasic = (StarBASIC*)pParent;
     496             :         }
     497             :     }
     498           0 :     return pCurBasic;
     499             : }
     500             : 
     501           0 : SbModule* SbiInstance::GetActiveModule()
     502             : {
     503           0 :     if( pRun )
     504             :     {
     505           0 :         return pRun->GetModule();
     506             :     }
     507             :     else
     508             :     {
     509           0 :         return NULL;
     510             :     }
     511             : }
     512             : 
     513           0 : SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel )
     514             : {
     515           0 :     SbiRuntime* p = pRun;
     516           0 :     while( nLevel-- && p )
     517             :     {
     518           0 :         p = p->pNext;
     519             :     }
     520           0 :     return p ? p->GetCaller() : NULL;
     521             : }
     522             : 
     523             : //                              SbiInstance                             //
     524             : 
     525             : // Attention: pMeth can also be NULL (on a call of the init-code)
     526             : 
     527         136 : SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
     528         136 :          : rBasic( *(StarBASIC*)pm->pParent ), pInst( GetSbData()->pInst ),
     529         272 :            pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), mpExtCaller(0), m_nLastTime(0)
     530             : {
     531         136 :     nFlags    = pe ? pe->GetDebugFlags() : 0;
     532         136 :     pIosys    = pInst->pIosys;
     533         136 :     pArgvStk  = NULL;
     534         136 :     pGosubStk = NULL;
     535         136 :     pForStk   = NULL;
     536         136 :     pError    = NULL;
     537             :     pErrCode  =
     538             :     pErrStmnt =
     539         136 :     pRestart  = NULL;
     540         136 :     pNext     = NULL;
     541             :     pCode     =
     542         136 :     pStmnt    = (const sal_uInt8* ) pImg->GetCode() + nStart;
     543             :     bRun      =
     544         136 :     bError    = true;
     545         136 :     bInError  = false;
     546         136 :     bBlocked  = false;
     547         136 :     nLine     = 0;
     548         136 :     nCol1     = 0;
     549         136 :     nCol2     = 0;
     550         136 :     nExprLvl  = 0;
     551         136 :     nArgc     = 0;
     552         136 :     nError    = 0;
     553         136 :     nGosubLvl = 0;
     554         136 :     nForLvl   = 0;
     555         136 :     nOps      = 0;
     556         136 :     refExprStk = new SbxArray;
     557         136 :     SetVBAEnabled( pMod->IsVBACompat() );
     558             : #if defined GCC
     559         136 :     SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL );
     560             : #else
     561             :     SetParameters( pe ? pe->GetParameters() : NULL );
     562             : #endif
     563         136 :     pRefSaveList = NULL;
     564         136 :     pItemStoreList = NULL;
     565         136 : }
     566             : 
     567         272 : SbiRuntime::~SbiRuntime()
     568             : {
     569         136 :     ClearGosubStack();
     570         136 :     ClearArgvStack();
     571         136 :     ClearForStack();
     572             : 
     573             :     // #74254 free items for saving temporary references
     574         136 :     ClearRefs();
     575         308 :     while( pItemStoreList )
     576             :     {
     577          36 :         RefSaveItem* pToDeleteItem = pItemStoreList;
     578          36 :         pItemStoreList = pToDeleteItem->pNext;
     579          36 :         delete pToDeleteItem;
     580             :     }
     581         136 : }
     582             : 
     583         136 : void SbiRuntime::SetVBAEnabled(bool bEnabled )
     584             : {
     585         136 :     bVBAEnabled = bEnabled;
     586         136 :     if ( bVBAEnabled )
     587             :     {
     588         120 :         if ( pMeth )
     589             :         {
     590         118 :             mpExtCaller = pMeth->mCaller;
     591             :         }
     592             :     }
     593             :     else
     594             :     {
     595          16 :         mpExtCaller = 0;
     596             :     }
     597         136 : }
     598             : 
     599             : // Construction of the parameter list. All ByRef-parameters are directly
     600             : // taken over; copies of ByVal-parameters are created. If a particular
     601             : // data type is requested, it is converted.
     602             : 
     603         136 : void SbiRuntime::SetParameters( SbxArray* pParams )
     604             : {
     605         136 :     refParams = new SbxArray;
     606             :     // for the return value
     607         136 :     refParams->Put( pMeth, 0 );
     608             : 
     609         136 :     SbxInfo* pInfo = pMeth ? pMeth->GetInfo() : NULL;
     610         136 :     sal_uInt16 nParamCount = pParams ? pParams->Count() : 1;
     611         136 :     if( nParamCount > 1 )
     612             :     {
     613         448 :         for( sal_uInt16 i = 1 ; i < nParamCount ; i++ )
     614             :         {
     615         336 :             const SbxParamInfo* p = pInfo ? pInfo->GetParam( i ) : NULL;
     616             : 
     617             :             // #111897 ParamArray
     618         336 :             if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
     619             :             {
     620           0 :                 SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
     621           0 :                 sal_uInt16 nParamArrayParamCount = nParamCount - i;
     622           0 :                 pArray->unoAddDim( 0, nParamArrayParamCount - 1 );
     623           0 :                 for( sal_uInt16 j = i ; j < nParamCount ; j++ )
     624             :                 {
     625           0 :                     SbxVariable* v = pParams->Get( j );
     626           0 :                     short nDimIndex = j - i;
     627           0 :                     pArray->Put( v, &nDimIndex );
     628             :                 }
     629           0 :                 SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
     630           0 :                 pArrayVar->SetFlag( SBX_READWRITE );
     631           0 :                 pArrayVar->PutObject( pArray );
     632           0 :                 refParams->Put( pArrayVar, i );
     633             : 
     634             :                 // Block ParamArray for missing parameter
     635           0 :                 pInfo = NULL;
     636           0 :                 break;
     637             :             }
     638             : 
     639         336 :             SbxVariable* v = pParams->Get( i );
     640             :             // methods are always byval!
     641         336 :             sal_Bool bByVal = v->IsA( TYPE(SbxMethod) );
     642         336 :             SbxDataType t = v->GetType();
     643         336 :             bool bTargetTypeIsArray = false;
     644         336 :             if( p )
     645             :             {
     646         336 :                 bByVal |= sal_Bool( ( p->eType & SbxBYREF ) == 0 );
     647         336 :                 t = (SbxDataType) ( p->eType & 0x0FFF );
     648             : 
     649         784 :                 if( !bByVal && t != SbxVARIANT &&
     650         448 :                     (!v->IsFixed() || (SbxDataType)(v->GetType() & 0x0FFF ) != t) )
     651             :                 {
     652         224 :                     bByVal = sal_True;
     653             :                 }
     654             : 
     655         336 :                 bTargetTypeIsArray = (p->nUserData & PARAM_INFO_WITHBRACKETS) != 0;
     656             :             }
     657         336 :             if( bByVal )
     658             :             {
     659         224 :                 if( bTargetTypeIsArray )
     660             :                 {
     661           0 :                     t = SbxOBJECT;
     662             :                 }
     663         224 :                 SbxVariable* v2 = new SbxVariable( t );
     664         224 :                 v2->SetFlag( SBX_READWRITE );
     665         224 :                 *v2 = *v;
     666         224 :                 refParams->Put( v2, i );
     667             :             }
     668             :             else
     669             :             {
     670         112 :                 if( t != SbxVARIANT && t != ( v->GetType() & 0x0FFF ) )
     671             :                 {
     672           0 :                     if( p && (p->eType & SbxARRAY) )
     673             :                     {
     674           0 :                         Error( SbERR_CONVERSION );
     675             :                     }
     676             :                     else
     677             :                     {
     678           0 :                         v->Convert( t );
     679             :                     }
     680             :                 }
     681         112 :                 refParams->Put( v, i );
     682             :             }
     683         336 :             if( p )
     684             :             {
     685         336 :                 refParams->PutAlias( p->aName, i );
     686             :             }
     687             :         }
     688             :     }
     689             : 
     690             :     // ParamArray for missing parameter
     691         136 :     if( pInfo )
     692             :     {
     693             :         // #111897 Check first missing parameter for ParamArray
     694         134 :         const SbxParamInfo* p = pInfo->GetParam( nParamCount );
     695         134 :         if( p && (p->nUserData & PARAM_INFO_PARAMARRAY) != 0 )
     696             :         {
     697           0 :             SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
     698           0 :             pArray->unoAddDim( 0, -1 );
     699           0 :             SbxVariable* pArrayVar = new SbxVariable( SbxVARIANT );
     700           0 :             pArrayVar->SetFlag( SBX_READWRITE );
     701           0 :             pArrayVar->PutObject( pArray );
     702           0 :             refParams->Put( pArrayVar, nParamCount );
     703             :         }
     704             :     }
     705         136 : }
     706             : 
     707             : 
     708             : // execute a P-Code
     709             : 
     710        5116 : bool SbiRuntime::Step()
     711             : {
     712        5116 :     if( bRun )
     713             :     {
     714             :         // in any case check casually!
     715        5116 :         if( !( ++nOps & 0xF ) && pInst->IsReschedule() )
     716             :         {
     717         282 :             sal_uInt32 nTime = osl_getGlobalTimer();
     718         282 :             if (nTime - m_nLastTime > 5 ) // 20 ms
     719             :             {
     720         182 :                 Application::Reschedule();
     721         182 :                 m_nLastTime = nTime;
     722             :             }
     723             :         }
     724             : 
     725             :         // #i48868 blocked by next call level?
     726       10232 :         while( bBlocked )
     727             :         {
     728           0 :             if( pInst->IsReschedule() )
     729             :             {
     730           0 :                 Application::Reschedule();
     731             :             }
     732             :         }
     733             : 
     734        5116 :         SbiOpcode eOp = (SbiOpcode ) ( *pCode++ );
     735             :         sal_uInt32 nOp1, nOp2;
     736        5116 :         if (eOp <= SbOP0_END)
     737             :         {
     738        1740 :             (this->*( aStep0[ eOp ] ) )();
     739             :         }
     740        3376 :         else if (eOp >= SbOP1_START && eOp <= SbOP1_END)
     741             :         {
     742         730 :             nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
     743             : 
     744         730 :             (this->*( aStep1[ eOp - SbOP1_START ] ) )( nOp1 );
     745             :         }
     746        2646 :         else if (eOp >= SbOP2_START && eOp <= SbOP2_END)
     747             :         {
     748        2646 :             nOp1 = *pCode++; nOp1 |= *pCode++ << 8; nOp1 |= *pCode++ << 16; nOp1 |= *pCode++ << 24;
     749        2646 :             nOp2 = *pCode++; nOp2 |= *pCode++ << 8; nOp2 |= *pCode++ << 16; nOp2 |= *pCode++ << 24;
     750        2646 :             (this->*( aStep2[ eOp - SbOP2_START ] ) )( nOp1, nOp2 );
     751             :         }
     752             :         else
     753             :         {
     754           0 :             StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
     755             :         }
     756             : 
     757        5116 :         SbError nSbError = SbxBase::GetError();
     758        5116 :         Error( ERRCODE_TOERROR(nSbError) );
     759             : 
     760             :         // from 13.2.1997, new error handling:
     761             :         // ATTENTION: nError can be set already even if !nSbError
     762             :         // since nError can now also be set from other RT-instances
     763             : 
     764        5116 :         if( nError )
     765             :         {
     766           4 :             SbxBase::ResetError();
     767             :         }
     768             : 
     769             :         // from 15.3.96: display errors only if BASIC is still active
     770             :         // (especially not after compiler errors at the runtime)
     771        5116 :         if( nError && bRun )
     772             :         {
     773           4 :             SbError err = nError;
     774           4 :             ClearExprStack();
     775           4 :             nError = 0;
     776           4 :             pInst->nErr = err;
     777           4 :             pInst->nErl = nLine;
     778           4 :             pErrCode    = pCode;
     779           4 :             pErrStmnt   = pStmnt;
     780             :             // An error occurred in an error handler
     781             :             // force parent handler ( if there is one )
     782             :             // to handle the error
     783           4 :             bool bLetParentHandleThis = false;
     784             : 
     785             :             // in the error handler? so std-error
     786           4 :             if ( !bInError )
     787             :             {
     788           4 :                 bInError = true;
     789             : 
     790           4 :                 if( !bError )           // On Error Resume Next
     791             :                 {
     792           0 :                     StepRESUME( 1 );
     793             :                 }
     794           4 :                 else if( pError )       // On Error Goto ...
     795             :                 {
     796           4 :                     pCode = pError;
     797             :                 }
     798             :                 else
     799             :                 {
     800           0 :                     bLetParentHandleThis = true;
     801             :                 }
     802             :             }
     803             :             else
     804             :             {
     805           0 :                 bLetParentHandleThis = true;
     806           0 :                 pError = NULL; //terminate the handler
     807             :             }
     808           4 :             if ( bLetParentHandleThis )
     809             :             {
     810             :                 // from 13.2.1997, new error handling:
     811             :                 // consider superior error handlers
     812             : 
     813             :                 // there's no error handler -> find one farther above
     814           0 :                 SbiRuntime* pRtErrHdl = NULL;
     815           0 :                 SbiRuntime* pRt = this;
     816           0 :                 while( NULL != (pRt = pRt->pNext) )
     817             :                 {
     818           0 :                     if( !pRt->bError || pRt->pError != NULL )
     819             :                     {
     820           0 :                         pRtErrHdl = pRt;
     821           0 :                         break;
     822             :                     }
     823             :                 }
     824             : 
     825             : 
     826           0 :                 if( pRtErrHdl )
     827             :                 {
     828             :                     // manipulate all the RTs that are below in the call-stack
     829           0 :                     pRt = this;
     830           0 :                     do
     831             :                     {
     832           0 :                         pRt->nError = err;
     833           0 :                         if( pRt != pRtErrHdl )
     834             :                         {
     835           0 :                             pRt->bRun = false;
     836             :                         }
     837             :                         else
     838             :                         {
     839           0 :                             break;
     840             :                         }
     841           0 :                         pRt = pRt->pNext;
     842             :                     }
     843             :                     while( pRt );
     844             :                 }
     845             :                 // no error-hdl found -> old behaviour
     846             :                 else
     847             :                 {
     848           0 :                     pInst->Abort();
     849             :                 }
     850             :             }
     851             :         }
     852             :     }
     853        5116 :     return bRun;
     854             : }
     855             : 
     856        5120 : void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone )
     857             : {
     858        5120 :     if( n )
     859             :     {
     860           4 :         nError = n;
     861           4 :         if( isVBAEnabled() && !bVBATranslationAlreadyDone )
     862             :         {
     863           4 :             OUString aMsg = pInst->GetErrorMsg();
     864           4 :             sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg );
     865           4 :             SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject();
     866           4 :             SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar );
     867           4 :             if( pGlobErr != NULL )
     868             :             {
     869           4 :                 pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg );
     870             :             }
     871           4 :             pInst->aErrorMsg = aMsg;
     872           4 :             nError = SbERR_BASIC_COMPAT;
     873             :         }
     874             :     }
     875        5120 : }
     876             : 
     877           0 : void SbiRuntime::Error( SbError _errCode, const OUString& _details )
     878             : {
     879           0 :     if ( _errCode )
     880             :     {
     881             :         // Not correct for class module usage, remove for now
     882             :         //OSL_ENSURE( pInst->pRun == this, "SbiRuntime::Error: can't propagate the error message details!" );
     883           0 :         if ( pInst->pRun == this )
     884             :         {
     885           0 :             pInst->Error( _errCode, _details );
     886             :             //OSL_POSTCOND( nError == _errCode, "SbiRuntime::Error: the instance is expecte to propagate the error code back to me!" );
     887             :         }
     888             :         else
     889             :         {
     890           0 :             nError = _errCode;
     891             :         }
     892             :     }
     893           0 : }
     894             : 
     895           0 : void SbiRuntime::FatalError( SbError n )
     896             : {
     897           0 :     StepSTDERROR();
     898           0 :     Error( n );
     899           0 : }
     900             : 
     901           0 : void SbiRuntime::FatalError( SbError _errCode, const OUString& _details )
     902             : {
     903           0 :     StepSTDERROR();
     904           0 :     Error( _errCode, _details );
     905           0 : }
     906             : 
     907           4 : sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, OUString& rMsg )
     908             : {
     909             :     // If a message is defined use that ( in preference to
     910             :     // the defined one for the error ) NB #TODO
     911             :     // if there is an error defined it more than likely
     912             :     // is not the one you want ( some are the same though )
     913             :     // we really need a new vba compatible error list
     914           4 :     if ( rMsg.isEmpty() )
     915             :     {
     916             :         // TEST, has to be vb here always
     917             : #ifdef DBG_UTIL
     918             :         SbError nTmp = StarBASIC::GetSfxFromVBError( (sal_uInt16)nError );
     919             :         DBG_ASSERT( nTmp, "No VB error!" );
     920             : #endif
     921             : 
     922           0 :         StarBASIC::MakeErrorText( nError, rMsg );
     923           0 :         rMsg = StarBASIC::GetErrorText();
     924           0 :         if ( rMsg.isEmpty() ) // no message for err no, need localized resource here
     925             :         {
     926           0 :             rMsg = "Internal Object Error:";
     927             :         }
     928             :     }
     929             :     // no num? most likely then it *is* really a vba err
     930           4 :     sal_uInt16 nVBErrorCode = StarBASIC::GetVBErrorCode( nError );
     931           4 :     sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode;
     932           4 :     return nVBAErrorNumber;
     933             : }
     934             : 
     935             : //  Parameter, Locals, Caller
     936             : 
     937           0 : SbMethod* SbiRuntime::GetCaller()
     938             : {
     939           0 :     return pMeth;
     940             : }
     941             : 
     942             : //  Stacks
     943             : 
     944             : // The expression-stack is available for the continous evaluation
     945             : // of expressions.
     946             : 
     947        2212 : void SbiRuntime::PushVar( SbxVariable* pVar )
     948             : {
     949        2212 :     if( pVar )
     950             :     {
     951        2212 :         refExprStk->Put( pVar, nExprLvl++ );
     952             :     }
     953        2212 : }
     954             : 
     955        2212 : SbxVariableRef SbiRuntime::PopVar()
     956             : {
     957             : #ifdef DBG_UTIL
     958             :     if( !nExprLvl )
     959             :     {
     960             :         StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
     961             :         return new SbxVariable;
     962             :     }
     963             : #endif
     964        2212 :     SbxVariableRef xVar = refExprStk->Get( --nExprLvl );
     965             : #ifdef DBG_UTIL
     966             :     if ( xVar->GetName().equalsAscii( "Cells" ) )
     967             :         OSL_TRACE( "" );
     968             : #endif
     969             :     // methods hold themselves in parameter 0
     970        2212 :     if( xVar->IsA( TYPE(SbxMethod) ) )
     971             :     {
     972         508 :         xVar->SetParameters(0);
     973             :     }
     974        2212 :     return xVar;
     975             : }
     976             : 
     977         954 : bool SbiRuntime::ClearExprStack()
     978             : {
     979             :     // Attention: Clear() doesn't suffice as methods must be deleted
     980        1918 :     while ( nExprLvl )
     981             :     {
     982          10 :         PopVar();
     983             :     }
     984         954 :     refExprStk->Clear();
     985         954 :     return false;
     986             : }
     987             : 
     988             : // Take variable from the expression-stack without removing it
     989             : // n counts from 0
     990             : 
     991         262 : SbxVariable* SbiRuntime::GetTOS( short n )
     992             : {
     993         262 :     n = nExprLvl - n - 1;
     994             : #ifdef DBG_UTIL
     995             :     if( n < 0 )
     996             :     {
     997             :         StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
     998             :         return new SbxVariable;
     999             :     }
    1000             : #endif
    1001         262 :     return refExprStk->Get( (sal_uInt16) n );
    1002             : }
    1003             : 
    1004             : 
    1005         260 : void SbiRuntime::TOSMakeTemp()
    1006             : {
    1007         260 :     SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
    1008         260 :     if ( p->GetType() == SbxEMPTY )
    1009             :     {
    1010           0 :         p->Broadcast( SBX_HINT_DATAWANTED );
    1011             :     }
    1012             : 
    1013         260 :     SbxVariable* pDflt = NULL;
    1014         260 :     if ( bVBAEnabled &&  ( p->GetType() == SbxOBJECT || p->GetType() == SbxVARIANT  ) && ((pDflt = getDefaultProp(p)) != NULL) )
    1015             :     {
    1016           0 :         pDflt->Broadcast( SBX_HINT_DATAWANTED );
    1017             :         // replacing new p on stack causes object pointed by
    1018             :         // pDft->pParent to be deleted, when p2->Compute() is
    1019             :         // called below pParent is accessed ( but its deleted )
    1020             :         // so set it to NULL now
    1021           0 :         pDflt->SetParent( NULL );
    1022           0 :         p = new SbxVariable( *pDflt );
    1023           0 :         p->SetFlag( SBX_READWRITE );
    1024           0 :         refExprStk->Put( p, nExprLvl - 1 );
    1025             :     }
    1026         260 :     else if( p->GetRefCount() != 1 )
    1027             :     {
    1028         222 :         SbxVariable* pNew = new SbxVariable( *p );
    1029         222 :         pNew->SetFlag( SBX_READWRITE );
    1030         222 :         refExprStk->Put( pNew, nExprLvl - 1 );
    1031             :     }
    1032         260 : }
    1033             : 
    1034             : // the GOSUB-stack collects return-addresses for GOSUBs
    1035           0 : void SbiRuntime::PushGosub( const sal_uInt8* pc )
    1036             : {
    1037           0 :     if( ++nGosubLvl > MAXRECURSION )
    1038             :     {
    1039           0 :         StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
    1040             :     }
    1041           0 :     SbiGosubStack* p = new SbiGosubStack;
    1042           0 :     p->pCode  = pc;
    1043           0 :     p->pNext  = pGosubStk;
    1044           0 :     p->nStartForLvl = nForLvl;
    1045           0 :     pGosubStk = p;
    1046           0 : }
    1047             : 
    1048           0 : void SbiRuntime::PopGosub()
    1049             : {
    1050           0 :     if( !pGosubStk )
    1051             :     {
    1052           0 :         Error( SbERR_NO_GOSUB );
    1053             :     }
    1054             :     else
    1055             :     {
    1056           0 :         SbiGosubStack* p = pGosubStk;
    1057           0 :         pCode = p->pCode;
    1058           0 :         pGosubStk = p->pNext;
    1059           0 :         delete p;
    1060           0 :         nGosubLvl--;
    1061             :     }
    1062           0 : }
    1063             : 
    1064             : 
    1065         136 : void SbiRuntime::ClearGosubStack()
    1066             : {
    1067             :     SbiGosubStack* p;
    1068         272 :     while(( p = pGosubStk ) != NULL )
    1069             :     {
    1070           0 :         pGosubStk = p->pNext, delete p;
    1071             :     }
    1072         136 :     nGosubLvl = 0;
    1073         136 : }
    1074             : 
    1075             : // the Argv-stack collects current argument-vectors
    1076             : 
    1077         310 : void SbiRuntime::PushArgv()
    1078             : {
    1079         310 :     SbiArgvStack* p = new SbiArgvStack;
    1080         310 :     p->refArgv = refArgv;
    1081         310 :     p->nArgc = nArgc;
    1082         310 :     nArgc = 1;
    1083         310 :     refArgv.Clear();
    1084         310 :     p->pNext = pArgvStk;
    1085         310 :     pArgvStk = p;
    1086         310 : }
    1087             : 
    1088         310 : void SbiRuntime::PopArgv()
    1089             : {
    1090         310 :     if( pArgvStk )
    1091             :     {
    1092         310 :         SbiArgvStack* p = pArgvStk;
    1093         310 :         pArgvStk = p->pNext;
    1094         310 :         refArgv = p->refArgv;
    1095         310 :         nArgc = p->nArgc;
    1096         310 :         delete p;
    1097             :     }
    1098         310 : }
    1099             : 
    1100             : 
    1101         136 : void SbiRuntime::ClearArgvStack()
    1102             : {
    1103         272 :     while( pArgvStk )
    1104             :     {
    1105           0 :         PopArgv();
    1106             :     }
    1107         136 : }
    1108             : 
    1109             : // Push of the for-stack. The stack has increment, end, begin and variable.
    1110             : // After the creation of the stack-element the stack's empty.
    1111             : 
    1112           0 : void SbiRuntime::PushFor()
    1113             : {
    1114           0 :     SbiForStack* p = new SbiForStack;
    1115           0 :     p->eForType = FOR_TO;
    1116           0 :     p->pNext = pForStk;
    1117           0 :     pForStk = p;
    1118             : 
    1119           0 :     p->refInc = PopVar();
    1120           0 :     p->refEnd = PopVar();
    1121           0 :     SbxVariableRef xBgn = PopVar();
    1122           0 :     p->refVar = PopVar();
    1123           0 :     *(p->refVar) = *xBgn;
    1124           0 :     nForLvl++;
    1125           0 : }
    1126             : 
    1127           0 : void SbiRuntime::PushForEach()
    1128             : {
    1129           0 :     SbiForStack* p = new SbiForStack;
    1130           0 :     p->pNext = pForStk;
    1131           0 :     pForStk = p;
    1132             : 
    1133           0 :     SbxVariableRef xObjVar = PopVar();
    1134           0 :     SbxBase* pObj = xObjVar.Is() ? xObjVar->GetObject() : NULL;
    1135           0 :     if( pObj == NULL )
    1136             :     {
    1137           0 :         Error( SbERR_NO_OBJECT );
    1138             :         return;
    1139             :     }
    1140             : 
    1141           0 :     bool bError_ = false;
    1142             :     BasicCollection* pCollection;
    1143             :     SbxDimArray* pArray;
    1144             :     SbUnoObject* pUnoObj;
    1145           0 :     if( (pArray = PTR_CAST(SbxDimArray,pObj)) != NULL )
    1146             :     {
    1147           0 :         p->eForType = FOR_EACH_ARRAY;
    1148           0 :         p->refEnd = (SbxVariable*)pArray;
    1149             : 
    1150           0 :         short nDims = pArray->GetDims();
    1151           0 :         p->pArrayLowerBounds = new sal_Int32[nDims];
    1152           0 :         p->pArrayUpperBounds = new sal_Int32[nDims];
    1153           0 :         p->pArrayCurIndices  = new sal_Int32[nDims];
    1154             :         sal_Int32 lBound, uBound;
    1155           0 :         for( short i = 0 ; i < nDims ; i++ )
    1156             :         {
    1157           0 :             pArray->GetDim32( i+1, lBound, uBound );
    1158           0 :             p->pArrayCurIndices[i] = p->pArrayLowerBounds[i] = lBound;
    1159           0 :             p->pArrayUpperBounds[i] = uBound;
    1160             :         }
    1161             :     }
    1162           0 :     else if( (pCollection = PTR_CAST(BasicCollection,pObj)) != NULL )
    1163             :     {
    1164           0 :         p->eForType = FOR_EACH_COLLECTION;
    1165           0 :         p->refEnd = pCollection;
    1166           0 :         p->nCurCollectionIndex = 0;
    1167             :     }
    1168           0 :     else if( (pUnoObj = PTR_CAST(SbUnoObject,pObj)) != NULL )
    1169             :     {
    1170             :         // XEnumerationAccess?
    1171           0 :         Any aAny = pUnoObj->getUnoAny();
    1172           0 :         Reference< XEnumerationAccess > xEnumerationAccess;
    1173           0 :         if( (aAny >>= xEnumerationAccess) )
    1174             :         {
    1175           0 :             p->xEnumeration = xEnumerationAccess->createEnumeration();
    1176           0 :             p->eForType = FOR_EACH_XENUMERATION;
    1177             :         }
    1178           0 :         else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() )
    1179             :         {
    1180           0 :             uno::Reference< script::XInvocation > xInvocation;
    1181           0 :             if ( ( aAny >>= xInvocation ) && xInvocation.is() )
    1182             :             {
    1183             :                 try
    1184             :                 {
    1185           0 :                     p->xEnumeration = new ComEnumerationWrapper( xInvocation );
    1186           0 :                     p->eForType = FOR_EACH_XENUMERATION;
    1187             :                 }
    1188           0 :                 catch(const uno::Exception& )
    1189             :                 {}
    1190             :             }
    1191           0 :             if ( !p->xEnumeration.is() )
    1192             :             {
    1193           0 :                 bError_ = true;
    1194           0 :             }
    1195             :         }
    1196             :         else
    1197             :         {
    1198           0 :             bError_ = true;
    1199           0 :         }
    1200             :     }
    1201             :     else
    1202             :     {
    1203           0 :         bError_ = true;
    1204             :     }
    1205             : 
    1206           0 :     if( bError_ )
    1207             :     {
    1208           0 :         Error( SbERR_CONVERSION );
    1209             :         return;
    1210             :     }
    1211             : 
    1212             :     // Container variable
    1213           0 :     p->refVar = PopVar();
    1214           0 :     nForLvl++;
    1215             : }
    1216             : 
    1217             : 
    1218           0 : void SbiRuntime::PopFor()
    1219             : {
    1220           0 :     if( pForStk )
    1221             :     {
    1222           0 :         SbiForStack* p = pForStk;
    1223           0 :         pForStk = p->pNext;
    1224           0 :         delete p;
    1225           0 :         nForLvl--;
    1226             :     }
    1227           0 : }
    1228             : 
    1229             : 
    1230         136 : void SbiRuntime::ClearForStack()
    1231             : {
    1232         272 :     while( pForStk )
    1233             :     {
    1234           0 :         PopFor();
    1235             :     }
    1236         136 : }
    1237             : 
    1238           0 : SbiForStack* SbiRuntime::FindForStackItemForCollection( class BasicCollection* pCollection )
    1239             : {
    1240           0 :     for (SbiForStack *p = pForStk; p; p = p->pNext)
    1241             :     {
    1242           0 :         SbxVariable* pVar = p->refEnd.Is() ? (SbxVariable*)p->refEnd : NULL;
    1243           0 :         if( p->eForType == FOR_EACH_COLLECTION && pVar != NULL &&
    1244           0 :             PTR_CAST(BasicCollection,pVar) == pCollection )
    1245             :         {
    1246           0 :             return p;
    1247             :         }
    1248             :     }
    1249             : 
    1250           0 :     return NULL;
    1251             : }
    1252             : 
    1253             : 
    1254             : //////////////////////////////////////////////////////////////////////////
    1255             : //
    1256             : //  DLL-calls
    1257             : 
    1258           0 : void SbiRuntime::DllCall
    1259             :     ( const OUString& aFuncName,
    1260             :       const OUString& aDLLName,
    1261             :       SbxArray* pArgs,          // parameter (from index 1, can be NULL)
    1262             :       SbxDataType eResType,     // return value
    1263             :       bool bCDecl )         // true: according to C-conventions
    1264             : {
    1265             :     // No DllCall for "virtual" portal users
    1266           0 :     if( needSecurityRestrictions() )
    1267             :     {
    1268           0 :         StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
    1269           0 :         return;
    1270             :     }
    1271             : 
    1272             :     // NOT YET IMPLEMENTED
    1273             : 
    1274           0 :     SbxVariable* pRes = new SbxVariable( eResType );
    1275           0 :     SbiDllMgr* pDllMgr = pInst->GetDllMgr();
    1276           0 :     SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl );
    1277           0 :     if( nErr )
    1278             :     {
    1279           0 :         Error( nErr );
    1280             :     }
    1281           0 :     PushVar( pRes );
    1282             : }
    1283             : 
    1284           0 : sal_uInt16 SbiRuntime::GetImageFlag( sal_uInt16 n ) const
    1285             : {
    1286           0 :     return pImg->GetFlag( n );
    1287             : }
    1288             : 
    1289           0 : sal_uInt16 SbiRuntime::GetBase()
    1290             : {
    1291           0 :     return pImg->GetBase();
    1292             : }
    1293             : 
    1294             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10