1*e1f63238SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*e1f63238SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*e1f63238SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*e1f63238SAndrew Rist * distributed with this work for additional information 6*e1f63238SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*e1f63238SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*e1f63238SAndrew Rist * "License"); you may not use this file except in compliance 9*e1f63238SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*e1f63238SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*e1f63238SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*e1f63238SAndrew Rist * software distributed under the License is distributed on an 15*e1f63238SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*e1f63238SAndrew Rist * KIND, either express or implied. See the License for the 17*e1f63238SAndrew Rist * specific language governing permissions and limitations 18*e1f63238SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*e1f63238SAndrew Rist *************************************************************/ 21*e1f63238SAndrew Rist 22*e1f63238SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_basic.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <stdlib.h> 28cdf0e10cSrcweir #include <rtl/math.hxx> 29cdf0e10cSrcweir #include <basic/sbuno.hxx> 30cdf0e10cSrcweir #include "runtime.hxx" 31cdf0e10cSrcweir #include "sbintern.hxx" 32cdf0e10cSrcweir #include "iosys.hxx" 33cdf0e10cSrcweir #include "image.hxx" 34cdf0e10cSrcweir #include "sbunoobj.hxx" 35cdf0e10cSrcweir #include "errobject.hxx" 36cdf0e10cSrcweir 37cdf0e10cSrcweir bool checkUnoObjectType( SbUnoObject* refVal, const ::rtl::OUString& aClass ); 38cdf0e10cSrcweir 39cdf0e10cSrcweir // Laden einer numerischen Konstanten (+ID) 40cdf0e10cSrcweir 41cdf0e10cSrcweir void SbiRuntime::StepLOADNC( sal_uInt32 nOp1 ) 42cdf0e10cSrcweir { 43cdf0e10cSrcweir SbxVariable* p = new SbxVariable( SbxDOUBLE ); 44cdf0e10cSrcweir 45cdf0e10cSrcweir // #57844 Lokalisierte Funktion benutzen 46cdf0e10cSrcweir String aStr = pImg->GetString( static_cast<short>( nOp1 ) ); 47cdf0e10cSrcweir // Auch , zulassen !!! 48cdf0e10cSrcweir sal_uInt16 iComma = aStr.Search( ',' ); 49cdf0e10cSrcweir if( iComma != STRING_NOTFOUND ) 50cdf0e10cSrcweir { 51cdf0e10cSrcweir String aStr1 = aStr.Copy( 0, iComma ); 52cdf0e10cSrcweir String aStr2 = aStr.Copy( iComma + 1 ); 53cdf0e10cSrcweir aStr = aStr1; 54cdf0e10cSrcweir aStr += '.'; 55cdf0e10cSrcweir aStr += aStr2; 56cdf0e10cSrcweir } 57cdf0e10cSrcweir double n = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL ); 58cdf0e10cSrcweir 59cdf0e10cSrcweir p->PutDouble( n ); 60cdf0e10cSrcweir PushVar( p ); 61cdf0e10cSrcweir } 62cdf0e10cSrcweir 63cdf0e10cSrcweir // Laden einer Stringkonstanten (+ID) 64cdf0e10cSrcweir 65cdf0e10cSrcweir void SbiRuntime::StepLOADSC( sal_uInt32 nOp1 ) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir SbxVariable* p = new SbxVariable; 68cdf0e10cSrcweir p->PutString( pImg->GetString( static_cast<short>( nOp1 ) ) ); 69cdf0e10cSrcweir PushVar( p ); 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir // Immediate Load (+Wert) 73cdf0e10cSrcweir 74cdf0e10cSrcweir void SbiRuntime::StepLOADI( sal_uInt32 nOp1 ) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir SbxVariable* p = new SbxVariable; 77cdf0e10cSrcweir p->PutInteger( static_cast<sal_Int16>( nOp1 ) ); 78cdf0e10cSrcweir PushVar( p ); 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir // Speichern eines named Arguments in Argv (+Arg-Nr ab 1!) 82cdf0e10cSrcweir 83cdf0e10cSrcweir void SbiRuntime::StepARGN( sal_uInt32 nOp1 ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir if( !refArgv ) 86cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 87cdf0e10cSrcweir else 88cdf0e10cSrcweir { 89cdf0e10cSrcweir String aAlias( pImg->GetString( static_cast<short>( nOp1 ) ) ); 90cdf0e10cSrcweir SbxVariableRef pVal = PopVar(); 91cdf0e10cSrcweir refArgv->Put( pVal, nArgc ); 92cdf0e10cSrcweir refArgv->PutAlias( aAlias, nArgc++ ); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir } 95cdf0e10cSrcweir 96cdf0e10cSrcweir // Konvertierung des Typs eines Arguments in Argv fuer DECLARE-Fkt. (+Typ) 97cdf0e10cSrcweir 98cdf0e10cSrcweir void SbiRuntime::StepARGTYP( sal_uInt32 nOp1 ) 99cdf0e10cSrcweir { 100cdf0e10cSrcweir if( !refArgv ) 101cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 102cdf0e10cSrcweir else 103cdf0e10cSrcweir { 104cdf0e10cSrcweir sal_Bool bByVal = (nOp1 & 0x8000) != 0; // Ist BYVAL verlangt? 105cdf0e10cSrcweir SbxDataType t = (SbxDataType) (nOp1 & 0x7FFF); 106cdf0e10cSrcweir SbxVariable* pVar = refArgv->Get( refArgv->Count() - 1 ); // letztes Arg 107cdf0e10cSrcweir 108cdf0e10cSrcweir // BYVAL pr�fen 109cdf0e10cSrcweir if( pVar->GetRefCount() > 2 ) // 2 ist normal f�r BYVAL 110cdf0e10cSrcweir { 111cdf0e10cSrcweir // Parameter ist eine Referenz 112cdf0e10cSrcweir if( bByVal ) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir // Call by Value ist verlangt -> Kopie anlegen 115cdf0e10cSrcweir pVar = new SbxVariable( *pVar ); 116cdf0e10cSrcweir pVar->SetFlag( SBX_READWRITE ); 117cdf0e10cSrcweir refExprStk->Put( pVar, refArgv->Count() - 1 ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir else 120cdf0e10cSrcweir pVar->SetFlag( SBX_REFERENCE ); // Ref-Flag f�r DllMgr 121cdf0e10cSrcweir } 122cdf0e10cSrcweir else 123cdf0e10cSrcweir { 124cdf0e10cSrcweir // Parameter ist KEINE Referenz 125cdf0e10cSrcweir if( bByVal ) 126cdf0e10cSrcweir pVar->ResetFlag( SBX_REFERENCE ); // Keine Referenz -> OK 127cdf0e10cSrcweir else 128cdf0e10cSrcweir Error( SbERR_BAD_PARAMETERS ); // Referenz verlangt 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir if( pVar->GetType() != t ) 132cdf0e10cSrcweir { 133cdf0e10cSrcweir // Variant, damit richtige Konvertierung 134cdf0e10cSrcweir // Ausserdem Fehler, wenn SbxBYREF 135cdf0e10cSrcweir pVar->Convert( SbxVARIANT ); 136cdf0e10cSrcweir pVar->Convert( t ); 137cdf0e10cSrcweir } 138cdf0e10cSrcweir } 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir // String auf feste Laenge bringen (+Laenge) 142cdf0e10cSrcweir 143cdf0e10cSrcweir void SbiRuntime::StepPAD( sal_uInt32 nOp1 ) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir SbxVariable* p = GetTOS(); 146cdf0e10cSrcweir String& s = (String&)(const String&) *p; 147cdf0e10cSrcweir if( s.Len() > nOp1 ) 148cdf0e10cSrcweir s.Erase( static_cast<xub_StrLen>( nOp1 ) ); 149cdf0e10cSrcweir else 150cdf0e10cSrcweir s.Expand( static_cast<xub_StrLen>( nOp1 ), ' ' ); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir 153cdf0e10cSrcweir // Sprung (+Target) 154cdf0e10cSrcweir 155cdf0e10cSrcweir void SbiRuntime::StepJUMP( sal_uInt32 nOp1 ) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir #ifdef DBG_UTIL 158cdf0e10cSrcweir // #QUESTION shouln't this be 159cdf0e10cSrcweir // if( (sal_uInt8*)( nOp1+pImagGetCode() ) >= pImg->GetCodeSize() ) 160cdf0e10cSrcweir if( nOp1 >= pImg->GetCodeSize() ) 161cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 162cdf0e10cSrcweir #endif 163cdf0e10cSrcweir pCode = (const sal_uInt8*) pImg->GetCode() + nOp1; 164cdf0e10cSrcweir } 165cdf0e10cSrcweir 166cdf0e10cSrcweir // TOS auswerten, bedingter Sprung (+Target) 167cdf0e10cSrcweir 168cdf0e10cSrcweir void SbiRuntime::StepJUMPT( sal_uInt32 nOp1 ) 169cdf0e10cSrcweir { 170cdf0e10cSrcweir SbxVariableRef p = PopVar(); 171cdf0e10cSrcweir if( p->GetBool() ) 172cdf0e10cSrcweir StepJUMP( nOp1 ); 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir // TOS auswerten, bedingter Sprung (+Target) 176cdf0e10cSrcweir 177cdf0e10cSrcweir void SbiRuntime::StepJUMPF( sal_uInt32 nOp1 ) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir SbxVariableRef p = PopVar(); 180cdf0e10cSrcweir if( !p->GetBool() ) 181cdf0e10cSrcweir StepJUMP( nOp1 ); 182cdf0e10cSrcweir } 183cdf0e10cSrcweir 184cdf0e10cSrcweir // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal) 185cdf0e10cSrcweir // Sieht so aus: 186cdf0e10cSrcweir // ONJUMP 2 187cdf0e10cSrcweir // JUMP target1 188cdf0e10cSrcweir // JUMP target2 189cdf0e10cSrcweir // ... 190cdf0e10cSrcweir //Falls im Operanden 0x8000 gesetzt ist, Returnadresse pushen (ON..GOSUB) 191cdf0e10cSrcweir 192cdf0e10cSrcweir void SbiRuntime::StepONJUMP( sal_uInt32 nOp1 ) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir SbxVariableRef p = PopVar(); 195cdf0e10cSrcweir sal_Int16 n = p->GetInteger(); 196cdf0e10cSrcweir if( nOp1 & 0x8000 ) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir nOp1 &= 0x7FFF; 199cdf0e10cSrcweir //PushGosub( pCode + 3 * nOp1 ); 200cdf0e10cSrcweir PushGosub( pCode + 5 * nOp1 ); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir if( n < 1 || static_cast<sal_uInt32>(n) > nOp1 ) 203cdf0e10cSrcweir n = static_cast<sal_Int16>( nOp1 + 1 ); 204cdf0e10cSrcweir //nOp1 = (sal_uInt32) ( (const char*) pCode - pImg->GetCode() ) + 3 * --n; 205cdf0e10cSrcweir nOp1 = (sal_uInt32) ( (const char*) pCode - pImg->GetCode() ) + 5 * --n; 206cdf0e10cSrcweir StepJUMP( nOp1 ); 207cdf0e10cSrcweir } 208cdf0e10cSrcweir 209cdf0e10cSrcweir // UP-Aufruf (+Target) 210cdf0e10cSrcweir 211cdf0e10cSrcweir void SbiRuntime::StepGOSUB( sal_uInt32 nOp1 ) 212cdf0e10cSrcweir { 213cdf0e10cSrcweir PushGosub( pCode ); 214cdf0e10cSrcweir if( nOp1 >= pImg->GetCodeSize() ) 215cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 216cdf0e10cSrcweir pCode = (const sal_uInt8*) pImg->GetCode() + nOp1; 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir // UP-Return (+0 oder Target) 220cdf0e10cSrcweir 221cdf0e10cSrcweir void SbiRuntime::StepRETURN( sal_uInt32 nOp1 ) 222cdf0e10cSrcweir { 223cdf0e10cSrcweir PopGosub(); 224cdf0e10cSrcweir if( nOp1 ) 225cdf0e10cSrcweir StepJUMP( nOp1 ); 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir // FOR-Variable testen (+Endlabel) 229cdf0e10cSrcweir 230cdf0e10cSrcweir void SbiRuntime::StepTESTFOR( sal_uInt32 nOp1 ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir if( !pForStk ) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 235cdf0e10cSrcweir return; 236cdf0e10cSrcweir } 237cdf0e10cSrcweir 238cdf0e10cSrcweir bool bEndLoop = false; 239cdf0e10cSrcweir switch( pForStk->eForType ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir case FOR_TO: 242cdf0e10cSrcweir { 243cdf0e10cSrcweir SbxOperator eOp = ( pForStk->refInc->GetDouble() < 0 ) ? SbxLT : SbxGT; 244cdf0e10cSrcweir if( pForStk->refVar->Compare( eOp, *pForStk->refEnd ) ) 245cdf0e10cSrcweir bEndLoop = true; 246cdf0e10cSrcweir break; 247cdf0e10cSrcweir } 248cdf0e10cSrcweir case FOR_EACH_ARRAY: 249cdf0e10cSrcweir { 250cdf0e10cSrcweir SbiForStack* p = pForStk; 251cdf0e10cSrcweir if( p->pArrayCurIndices == NULL ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir bEndLoop = true; 254cdf0e10cSrcweir } 255cdf0e10cSrcweir else 256cdf0e10cSrcweir { 257cdf0e10cSrcweir SbxDimArray* pArray = (SbxDimArray*)(SbxVariable*)p->refEnd; 258cdf0e10cSrcweir short nDims = pArray->GetDims(); 259cdf0e10cSrcweir 260cdf0e10cSrcweir // Empty array? 261cdf0e10cSrcweir if( nDims == 1 && p->pArrayLowerBounds[0] > p->pArrayUpperBounds[0] ) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir bEndLoop = true; 264cdf0e10cSrcweir break; 265cdf0e10cSrcweir } 266cdf0e10cSrcweir SbxVariable* pVal = pArray->Get32( p->pArrayCurIndices ); 267cdf0e10cSrcweir *(p->refVar) = *pVal; 268cdf0e10cSrcweir 269cdf0e10cSrcweir bool bFoundNext = false; 270cdf0e10cSrcweir for( short i = 0 ; i < nDims ; i++ ) 271cdf0e10cSrcweir { 272cdf0e10cSrcweir if( p->pArrayCurIndices[i] < p->pArrayUpperBounds[i] ) 273cdf0e10cSrcweir { 274cdf0e10cSrcweir bFoundNext = true; 275cdf0e10cSrcweir p->pArrayCurIndices[i]++; 276cdf0e10cSrcweir for( short j = i - 1 ; j >= 0 ; j-- ) 277cdf0e10cSrcweir p->pArrayCurIndices[j] = p->pArrayLowerBounds[j]; 278cdf0e10cSrcweir break; 279cdf0e10cSrcweir } 280cdf0e10cSrcweir } 281cdf0e10cSrcweir if( !bFoundNext ) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir delete[] p->pArrayCurIndices; 284cdf0e10cSrcweir p->pArrayCurIndices = NULL; 285cdf0e10cSrcweir } 286cdf0e10cSrcweir } 287cdf0e10cSrcweir break; 288cdf0e10cSrcweir } 289cdf0e10cSrcweir case FOR_EACH_COLLECTION: 290cdf0e10cSrcweir { 291cdf0e10cSrcweir BasicCollection* pCollection = (BasicCollection*)(SbxVariable*)pForStk->refEnd; 292cdf0e10cSrcweir SbxArrayRef xItemArray = pCollection->xItemArray; 293cdf0e10cSrcweir sal_Int32 nCount = xItemArray->Count32(); 294cdf0e10cSrcweir if( pForStk->nCurCollectionIndex < nCount ) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir SbxVariable* pRes = xItemArray->Get32( pForStk->nCurCollectionIndex ); 297cdf0e10cSrcweir pForStk->nCurCollectionIndex++; 298cdf0e10cSrcweir (*pForStk->refVar) = *pRes; 299cdf0e10cSrcweir } 300cdf0e10cSrcweir else 301cdf0e10cSrcweir { 302cdf0e10cSrcweir bEndLoop = true; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir break; 305cdf0e10cSrcweir } 306cdf0e10cSrcweir case FOR_EACH_XENUMERATION: 307cdf0e10cSrcweir { 308cdf0e10cSrcweir SbiForStack* p = pForStk; 309cdf0e10cSrcweir if( p->xEnumeration->hasMoreElements() ) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir Any aElem = p->xEnumeration->nextElement(); 312cdf0e10cSrcweir SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); 313cdf0e10cSrcweir unoToSbxValue( (SbxVariable*)xVar, aElem ); 314cdf0e10cSrcweir (*pForStk->refVar) = *xVar; 315cdf0e10cSrcweir } 316cdf0e10cSrcweir else 317cdf0e10cSrcweir { 318cdf0e10cSrcweir bEndLoop = true; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir break; 321cdf0e10cSrcweir } 322cdf0e10cSrcweir } 323cdf0e10cSrcweir if( bEndLoop ) 324cdf0e10cSrcweir { 325cdf0e10cSrcweir PopFor(); 326cdf0e10cSrcweir StepJUMP( nOp1 ); 327cdf0e10cSrcweir } 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir // Tos+1 <= Tos+2 <= Tos, 2xremove (+Target) 331cdf0e10cSrcweir 332cdf0e10cSrcweir void SbiRuntime::StepCASETO( sal_uInt32 nOp1 ) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir if( !refCaseStk || !refCaseStk->Count() ) 335cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 336cdf0e10cSrcweir else 337cdf0e10cSrcweir { 338cdf0e10cSrcweir SbxVariableRef xTo = PopVar(); 339cdf0e10cSrcweir SbxVariableRef xFrom = PopVar(); 340cdf0e10cSrcweir SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 ); 341cdf0e10cSrcweir if( *xCase >= *xFrom && *xCase <= *xTo ) 342cdf0e10cSrcweir StepJUMP( nOp1 ); 343cdf0e10cSrcweir } 344cdf0e10cSrcweir } 345cdf0e10cSrcweir 346cdf0e10cSrcweir // Fehler-Handler 347cdf0e10cSrcweir 348cdf0e10cSrcweir void SbiRuntime::StepERRHDL( sal_uInt32 nOp1 ) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir const sal_uInt8* p = pCode; 351cdf0e10cSrcweir StepJUMP( nOp1 ); 352cdf0e10cSrcweir pError = pCode; 353cdf0e10cSrcweir pCode = p; 354cdf0e10cSrcweir pInst->aErrorMsg = String(); 355cdf0e10cSrcweir pInst->nErr = 0; 356cdf0e10cSrcweir pInst->nErl = 0; 357cdf0e10cSrcweir nError = 0; 358cdf0e10cSrcweir SbxErrObject::getUnoErrObject()->Clear(); 359cdf0e10cSrcweir } 360cdf0e10cSrcweir 361cdf0e10cSrcweir // Resume nach Fehlern (+0=statement, 1=next or Label) 362cdf0e10cSrcweir 363cdf0e10cSrcweir void SbiRuntime::StepRESUME( sal_uInt32 nOp1 ) 364cdf0e10cSrcweir { 365cdf0e10cSrcweir // AB #32714 Resume ohne Error? -> Fehler 366cdf0e10cSrcweir if( !bInError ) 367cdf0e10cSrcweir { 368cdf0e10cSrcweir Error( SbERR_BAD_RESUME ); 369cdf0e10cSrcweir return; 370cdf0e10cSrcweir } 371cdf0e10cSrcweir if( nOp1 ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir // Code-Zeiger auf naechstes Statement setzen 374cdf0e10cSrcweir sal_uInt16 n1, n2; 375cdf0e10cSrcweir pCode = pMod->FindNextStmnt( pErrCode, n1, n2, sal_True, pImg ); 376cdf0e10cSrcweir } 377cdf0e10cSrcweir else 378cdf0e10cSrcweir pCode = pErrStmnt; 379cdf0e10cSrcweir if ( pError ) // current in error handler ( and got a Resume Next statment ) 380cdf0e10cSrcweir SbxErrObject::getUnoErrObject()->Clear(); 381cdf0e10cSrcweir 382cdf0e10cSrcweir if( nOp1 > 1 ) 383cdf0e10cSrcweir StepJUMP( nOp1 ); 384cdf0e10cSrcweir pInst->aErrorMsg = String(); 385cdf0e10cSrcweir pInst->nErr = 0; 386cdf0e10cSrcweir pInst->nErl = 0; 387cdf0e10cSrcweir nError = 0; 388cdf0e10cSrcweir bInError = sal_False; 389cdf0e10cSrcweir 390cdf0e10cSrcweir // Error-Stack loeschen 391cdf0e10cSrcweir SbErrorStack*& rErrStack = GetSbData()->pErrStack; 392cdf0e10cSrcweir delete rErrStack; 393cdf0e10cSrcweir rErrStack = NULL; 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir // Kanal schliessen (+Kanal, 0=Alle) 397cdf0e10cSrcweir void SbiRuntime::StepCLOSE( sal_uInt32 nOp1 ) 398cdf0e10cSrcweir { 399cdf0e10cSrcweir SbError err; 400cdf0e10cSrcweir if( !nOp1 ) 401cdf0e10cSrcweir pIosys->Shutdown(); 402cdf0e10cSrcweir else 403cdf0e10cSrcweir { 404cdf0e10cSrcweir err = pIosys->GetError(); 405cdf0e10cSrcweir if( !err ) 406cdf0e10cSrcweir { 407cdf0e10cSrcweir pIosys->Close(); 408cdf0e10cSrcweir } 409cdf0e10cSrcweir } 410cdf0e10cSrcweir err = pIosys->GetError(); 411cdf0e10cSrcweir Error( err ); 412cdf0e10cSrcweir } 413cdf0e10cSrcweir 414cdf0e10cSrcweir // Zeichen ausgeben (+char) 415cdf0e10cSrcweir 416cdf0e10cSrcweir void SbiRuntime::StepPRCHAR( sal_uInt32 nOp1 ) 417cdf0e10cSrcweir { 418cdf0e10cSrcweir ByteString s( (char) nOp1 ); 419cdf0e10cSrcweir pIosys->Write( s ); 420cdf0e10cSrcweir Error( pIosys->GetError() ); 421cdf0e10cSrcweir } 422cdf0e10cSrcweir 423cdf0e10cSrcweir // Check, ob TOS eine bestimmte Objektklasse ist (+StringID) 424cdf0e10cSrcweir 425cdf0e10cSrcweir bool SbiRuntime::implIsClass( SbxObject* pObj, const String& aClass ) 426cdf0e10cSrcweir { 427cdf0e10cSrcweir bool bRet = true; 428cdf0e10cSrcweir 429cdf0e10cSrcweir if( aClass.Len() != 0 ) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir bRet = pObj->IsClass( aClass ); 432cdf0e10cSrcweir if( !bRet ) 433cdf0e10cSrcweir bRet = aClass.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("object") ) ); 434cdf0e10cSrcweir if( !bRet ) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir String aObjClass = pObj->GetClassName(); 437cdf0e10cSrcweir SbModule* pClassMod = pCLASSFAC->FindClass( aObjClass ); 438cdf0e10cSrcweir SbClassData* pClassData; 439cdf0e10cSrcweir if( pClassMod && (pClassData=pClassMod->pClassData) != NULL ) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir SbxVariable* pClassVar = 442cdf0e10cSrcweir pClassData->mxIfaces->Find( aClass, SbxCLASS_DONTCARE ); 443cdf0e10cSrcweir bRet = (pClassVar != NULL); 444cdf0e10cSrcweir } 445cdf0e10cSrcweir } 446cdf0e10cSrcweir } 447cdf0e10cSrcweir return bRet; 448cdf0e10cSrcweir } 449cdf0e10cSrcweir 450cdf0e10cSrcweir bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal, 451cdf0e10cSrcweir const String& aClass, bool bRaiseErrors, bool bDefault ) 452cdf0e10cSrcweir { 453cdf0e10cSrcweir bool bOk = bDefault; 454cdf0e10cSrcweir 455cdf0e10cSrcweir SbxDataType t = refVal->GetType(); 456cdf0e10cSrcweir if( t == SbxOBJECT ) 457cdf0e10cSrcweir { 458cdf0e10cSrcweir SbxObject* pObj; 459cdf0e10cSrcweir SbxVariable* pVal = (SbxVariable*)refVal; 460cdf0e10cSrcweir if( pVal->IsA( TYPE(SbxObject) ) ) 461cdf0e10cSrcweir pObj = (SbxObject*) pVal; 462cdf0e10cSrcweir else 463cdf0e10cSrcweir { 464cdf0e10cSrcweir pObj = (SbxObject*) refVal->GetObject(); 465cdf0e10cSrcweir if( pObj && !pObj->IsA( TYPE(SbxObject) ) ) 466cdf0e10cSrcweir pObj = NULL; 467cdf0e10cSrcweir } 468cdf0e10cSrcweir if( pObj ) 469cdf0e10cSrcweir { 470cdf0e10cSrcweir if( !implIsClass( pObj, aClass ) ) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir if ( bVBAEnabled && pObj->IsA( TYPE(SbUnoObject) ) ) 473cdf0e10cSrcweir { 474cdf0e10cSrcweir SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj); 475cdf0e10cSrcweir bOk = checkUnoObjectType( pUnoObj, aClass ); 476cdf0e10cSrcweir } 477cdf0e10cSrcweir else 478cdf0e10cSrcweir bOk = false; 479cdf0e10cSrcweir if ( !bOk ) 480cdf0e10cSrcweir { 481cdf0e10cSrcweir if( bRaiseErrors ) 482cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 483cdf0e10cSrcweir } 484cdf0e10cSrcweir } 485cdf0e10cSrcweir else 486cdf0e10cSrcweir { 487cdf0e10cSrcweir bOk = true; 488cdf0e10cSrcweir 489cdf0e10cSrcweir SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pObj); 490cdf0e10cSrcweir if( pClassModuleObject != NULL ) 491cdf0e10cSrcweir pClassModuleObject->triggerInitializeEvent(); 492cdf0e10cSrcweir } 493cdf0e10cSrcweir } 494cdf0e10cSrcweir } 495cdf0e10cSrcweir else 496cdf0e10cSrcweir { 497cdf0e10cSrcweir if ( !bVBAEnabled ) 498cdf0e10cSrcweir { 499cdf0e10cSrcweir if( bRaiseErrors ) 500cdf0e10cSrcweir Error( SbERR_NEEDS_OBJECT ); 501cdf0e10cSrcweir bOk = false; 502cdf0e10cSrcweir } 503cdf0e10cSrcweir } 504cdf0e10cSrcweir return bOk; 505cdf0e10cSrcweir } 506cdf0e10cSrcweir 507cdf0e10cSrcweir void SbiRuntime::StepSETCLASS_impl( sal_uInt32 nOp1, bool bHandleDflt ) 508cdf0e10cSrcweir { 509cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 510cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 511cdf0e10cSrcweir String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) ); 512cdf0e10cSrcweir 513cdf0e10cSrcweir bool bOk = checkClass_Impl( refVal, aClass, true ); 514cdf0e10cSrcweir if( bOk ) 515cdf0e10cSrcweir StepSET_Impl( refVal, refVar, bHandleDflt ); // don't do handle dflt prop for a "proper" set 516cdf0e10cSrcweir } 517cdf0e10cSrcweir 518cdf0e10cSrcweir void SbiRuntime::StepVBASETCLASS( sal_uInt32 nOp1 ) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir StepSETCLASS_impl( nOp1, false ); 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir void SbiRuntime::StepSETCLASS( sal_uInt32 nOp1 ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir StepSETCLASS_impl( nOp1, true ); 526cdf0e10cSrcweir } 527cdf0e10cSrcweir 528cdf0e10cSrcweir void SbiRuntime::StepTESTCLASS( sal_uInt32 nOp1 ) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir SbxVariableRef xObjVal = PopVar(); 531cdf0e10cSrcweir String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) ); 532cdf0e10cSrcweir bool bDefault = !bVBAEnabled; 533cdf0e10cSrcweir bool bOk = checkClass_Impl( xObjVal, aClass, false, bDefault ); 534cdf0e10cSrcweir 535cdf0e10cSrcweir SbxVariable* pRet = new SbxVariable; 536cdf0e10cSrcweir pRet->PutBool( bOk ); 537cdf0e10cSrcweir PushVar( pRet ); 538cdf0e10cSrcweir } 539cdf0e10cSrcweir 540cdf0e10cSrcweir // Library fuer anschliessenden Declare-Call definieren 541cdf0e10cSrcweir 542cdf0e10cSrcweir void SbiRuntime::StepLIB( sal_uInt32 nOp1 ) 543cdf0e10cSrcweir { 544cdf0e10cSrcweir aLibName = pImg->GetString( static_cast<short>( nOp1 ) ); 545cdf0e10cSrcweir } 546cdf0e10cSrcweir 547cdf0e10cSrcweir // TOS wird um BASE erhoeht, BASE davor gepusht (+BASE) 548cdf0e10cSrcweir // Dieser Opcode wird vor DIM/REDIM-Anweisungen gepusht, 549cdf0e10cSrcweir // wenn nur ein Index angegeben wurde. 550cdf0e10cSrcweir 551cdf0e10cSrcweir void SbiRuntime::StepBASED( sal_uInt32 nOp1 ) 552cdf0e10cSrcweir { 553cdf0e10cSrcweir SbxVariable* p1 = new SbxVariable; 554cdf0e10cSrcweir SbxVariableRef x2 = PopVar(); 555cdf0e10cSrcweir 556cdf0e10cSrcweir // #109275 Check compatiblity mode 557cdf0e10cSrcweir bool bCompatible = ((nOp1 & 0x8000) != 0); 558cdf0e10cSrcweir sal_uInt16 uBase = static_cast<sal_uInt16>(nOp1 & 1); // Can only be 0 or 1 559cdf0e10cSrcweir p1->PutInteger( uBase ); 560cdf0e10cSrcweir if( !bCompatible ) 561cdf0e10cSrcweir x2->Compute( SbxPLUS, *p1 ); 562cdf0e10cSrcweir PushVar( x2 ); // erst die Expr 563cdf0e10cSrcweir PushVar( p1 ); // dann die Base 564cdf0e10cSrcweir } 565cdf0e10cSrcweir 566cdf0e10cSrcweir 567cdf0e10cSrcweir 568cdf0e10cSrcweir 569cdf0e10cSrcweir 570