1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basic.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "runtime.hxx" 32*cdf0e10cSrcweir #ifndef GCC 33*cdf0e10cSrcweir #endif 34*cdf0e10cSrcweir #include "iosys.hxx" 35*cdf0e10cSrcweir #include "image.hxx" 36*cdf0e10cSrcweir #include "sbintern.hxx" 37*cdf0e10cSrcweir #include "sbunoobj.hxx" 38*cdf0e10cSrcweir #include "opcodes.hxx" 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/script/XDefaultMethod.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx> 44*cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir using namespace com::sun::star::uno; 47*cdf0e10cSrcweir using namespace com::sun::star::container; 48*cdf0e10cSrcweir using namespace com::sun::star::lang; 49*cdf0e10cSrcweir using namespace com::sun::star::beans; 50*cdf0e10cSrcweir using namespace com::sun::star::script; 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir using com::sun::star::uno::Reference; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir SbxVariable* getVBAConstant( const String& rName ); 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir // Suchen eines Elements 57*cdf0e10cSrcweir // Die Bits im String-ID: 58*cdf0e10cSrcweir // 0x8000 - Argv ist belegt 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir SbxVariable* SbiRuntime::FindElement 61*cdf0e10cSrcweir ( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt32 nOp2, SbError nNotFound, sal_Bool bLocal, sal_Bool bStatic ) 62*cdf0e10cSrcweir { 63*cdf0e10cSrcweir bool bIsVBAInterOp = SbiRuntime::isVBAEnabled(); 64*cdf0e10cSrcweir if( bIsVBAInterOp ) 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir StarBASIC* pMSOMacroRuntimeLib = GetSbData()->pMSOMacroRuntimLib; 67*cdf0e10cSrcweir if( pMSOMacroRuntimeLib != NULL ) 68*cdf0e10cSrcweir pMSOMacroRuntimeLib->ResetFlag( SBX_EXTSEARCH ); 69*cdf0e10cSrcweir } 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir SbxVariable* pElem = NULL; 72*cdf0e10cSrcweir if( !pObj ) 73*cdf0e10cSrcweir { 74*cdf0e10cSrcweir Error( SbERR_NO_OBJECT ); 75*cdf0e10cSrcweir pElem = new SbxVariable; 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir else 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir sal_Bool bFatalError = sal_False; 80*cdf0e10cSrcweir SbxDataType t = (SbxDataType) nOp2; 81*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) ); 82*cdf0e10cSrcweir // Hacky capture of Evaluate [] syntax 83*cdf0e10cSrcweir // this should be tackled I feel at the pcode level 84*cdf0e10cSrcweir if ( bIsVBAInterOp && aName.Search('[') == 0 ) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir // emulate pcode here 87*cdf0e10cSrcweir StepARGC(); 88*cdf0e10cSrcweir // psuedo StepLOADSC 89*cdf0e10cSrcweir String sArg = aName.Copy( 1, aName.Len() - 2 ); 90*cdf0e10cSrcweir SbxVariable* p = new SbxVariable; 91*cdf0e10cSrcweir p->PutString( sArg ); 92*cdf0e10cSrcweir PushVar( p ); 93*cdf0e10cSrcweir // 94*cdf0e10cSrcweir StepARGV(); 95*cdf0e10cSrcweir nOp1 = nOp1 | 0x8000; // indicate params are present 96*cdf0e10cSrcweir aName = String::CreateFromAscii("Evaluate"); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir if( bLocal ) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir if ( bStatic ) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir if ( pMeth ) 103*cdf0e10cSrcweir pElem = pMeth->GetStatics()->Find( aName, SbxCLASS_DONTCARE ); 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir if ( !pElem ) 107*cdf0e10cSrcweir pElem = refLocals->Find( aName, SbxCLASS_DONTCARE ); 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir if( !pElem ) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir // Die RTL brauchen wir nicht mehr zu durchsuchen! 112*cdf0e10cSrcweir sal_Bool bSave = rBasic.bNoRtl; 113*cdf0e10cSrcweir rBasic.bNoRtl = sal_True; 114*cdf0e10cSrcweir pElem = pObj->Find( aName, SbxCLASS_DONTCARE ); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir // #110004, #112015: Make private really private 117*cdf0e10cSrcweir if( bLocal && pElem ) // Local as flag for global search 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir if( pElem->IsSet( SBX_PRIVATE ) ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir SbiInstance* pInst_ = pINST; 122*cdf0e10cSrcweir if( pInst_ && pInst_->IsCompatibility() && pObj != pElem->GetParent() ) 123*cdf0e10cSrcweir pElem = NULL; // Found but in wrong module! 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir // Interfaces: Use SBX_EXTFOUND 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir rBasic.bNoRtl = bSave; 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir // Ist es ein globaler Uno-Bezeichner? 131*cdf0e10cSrcweir if( bLocal && !pElem ) 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir bool bSetName = true; // preserve normal behaviour 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir // i#i68894# if VBAInterOp favour searching vba globals 136*cdf0e10cSrcweir // over searching for uno classess 137*cdf0e10cSrcweir if ( bVBAEnabled ) 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir // Try Find in VBA symbols space 140*cdf0e10cSrcweir pElem = rBasic.VBAFind( aName, SbxCLASS_DONTCARE ); 141*cdf0e10cSrcweir if ( pElem ) 142*cdf0e10cSrcweir bSetName = false; // don't overwrite uno name 143*cdf0e10cSrcweir else 144*cdf0e10cSrcweir pElem = getVBAConstant( aName ); 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir if( !pElem ) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir // #72382 VORSICHT! Liefert jetzt wegen unbekannten 150*cdf0e10cSrcweir // Modulen IMMER ein Ergebnis! 151*cdf0e10cSrcweir SbUnoClass* pUnoClass = findUnoClass( aName ); 152*cdf0e10cSrcweir if( pUnoClass ) 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir pElem = new SbxVariable( t ); 155*cdf0e10cSrcweir SbxValues aRes( SbxOBJECT ); 156*cdf0e10cSrcweir aRes.pObj = pUnoClass; 157*cdf0e10cSrcweir pElem->SbxVariable::Put( aRes ); 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir // #62939 Wenn eine Uno-Klasse gefunden wurde, muss 162*cdf0e10cSrcweir // das Wrapper-Objekt gehalten werden, da sonst auch 163*cdf0e10cSrcweir // die Uno-Klasse, z.B. "stardiv" immer wieder neu 164*cdf0e10cSrcweir // aus der Registry gelesen werden muss 165*cdf0e10cSrcweir if( pElem ) 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir // #63774 Darf nicht mit gespeichert werden!!! 168*cdf0e10cSrcweir pElem->SetFlag( SBX_DONTSTORE ); 169*cdf0e10cSrcweir pElem->SetFlag( SBX_NO_MODIFY); 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir // #72382 Lokal speichern, sonst werden alle implizit 172*cdf0e10cSrcweir // deklarierten Vars automatisch global ! 173*cdf0e10cSrcweir if ( bSetName ) 174*cdf0e10cSrcweir pElem->SetName( aName ); 175*cdf0e10cSrcweir refLocals->Put( pElem, refLocals->Count() ); 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir if( !pElem ) 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir // Nicht da und nicht im Objekt? 182*cdf0e10cSrcweir // Hat das Ding Parameter, nicht einrichten! 183*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 184*cdf0e10cSrcweir bFatalError = sal_True; 185*cdf0e10cSrcweir // ALT: StarBASIC::FatalError( nNotFound ); 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir // Sonst, falls keine Parameter sind, anderen Error Code verwenden 188*cdf0e10cSrcweir if( !bLocal || pImg->GetFlag( SBIMG_EXPLICIT ) ) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir // #39108 Bei explizit und als ELEM immer ein Fatal Error 191*cdf0e10cSrcweir bFatalError = sal_True; 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir // Falls keine Parameter sind, anderen Error Code verwenden 194*cdf0e10cSrcweir if( !( nOp1 & 0x8000 ) && nNotFound == SbERR_PROC_UNDEFINED ) 195*cdf0e10cSrcweir nNotFound = SbERR_VAR_UNDEFINED; 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir if( bFatalError ) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir // #39108 Statt FatalError zu setzen, Dummy-Variable liefern 200*cdf0e10cSrcweir if( !xDummyVar.Is() ) 201*cdf0e10cSrcweir xDummyVar = new SbxVariable( SbxVARIANT ); 202*cdf0e10cSrcweir pElem = xDummyVar; 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir // Parameter von Hand loeschen 205*cdf0e10cSrcweir ClearArgvStack(); 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir // Normalen Error setzen 208*cdf0e10cSrcweir Error( nNotFound, aName ); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir else 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir if ( bStatic ) 213*cdf0e10cSrcweir pElem = StepSTATIC_Impl( aName, t ); 214*cdf0e10cSrcweir if ( !pElem ) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir // Sonst Variable neu anlegen 217*cdf0e10cSrcweir pElem = new SbxVariable( t ); 218*cdf0e10cSrcweir if( t != SbxVARIANT ) 219*cdf0e10cSrcweir pElem->SetFlag( SBX_FIXED ); 220*cdf0e10cSrcweir pElem->SetName( aName ); 221*cdf0e10cSrcweir refLocals->Put( pElem, refLocals->Count() ); 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir // #39108 Args koennen schon geloescht sein! 227*cdf0e10cSrcweir if( !bFatalError ) 228*cdf0e10cSrcweir SetupArgs( pElem, nOp1 ); 229*cdf0e10cSrcweir // Ein bestimmter Call-Type wurde gewuenscht, daher muessen 230*cdf0e10cSrcweir // wir hier den Typ setzen und das Ding anfassen, um den 231*cdf0e10cSrcweir // korrekten Returnwert zu erhalten! 232*cdf0e10cSrcweir if( pElem->IsA( TYPE(SbxMethod) ) ) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir // Soll der Typ konvertiert werden? 235*cdf0e10cSrcweir SbxDataType t2 = pElem->GetType(); 236*cdf0e10cSrcweir sal_Bool bSet = sal_False; 237*cdf0e10cSrcweir if( !( pElem->GetFlags() & SBX_FIXED ) ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir if( t != SbxVARIANT && t != t2 && 240*cdf0e10cSrcweir t >= SbxINTEGER && t <= SbxSTRING ) 241*cdf0e10cSrcweir pElem->SetType( t ), bSet = sal_True; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir // pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen 244*cdf0e10cSrcweir SbxVariableRef refTemp = pElem; 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // Moegliche Reste vom letzten Aufruf der SbxMethod beseitigen 247*cdf0e10cSrcweir // Vorher Schreiben freigeben, damit kein Error gesetzt wird. 248*cdf0e10cSrcweir sal_uInt16 nSavFlags = pElem->GetFlags(); 249*cdf0e10cSrcweir pElem->SetFlag( SBX_READWRITE | SBX_NO_BROADCAST ); 250*cdf0e10cSrcweir pElem->SbxValue::Clear(); 251*cdf0e10cSrcweir pElem->SetFlags( nSavFlags ); 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir // Erst nach dem Setzen anfassen, da z.B. LEFT() 254*cdf0e10cSrcweir // den Unterschied zwischen Left$() und Left() kennen muss 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir // AB 12.8.96: Da in PopVar() die Parameter von Methoden weggehauen 257*cdf0e10cSrcweir // werden, muessen wir hier explizit eine neue SbxMethod anlegen 258*cdf0e10cSrcweir SbxVariable* pNew = new SbxMethod( *((SbxMethod*)pElem) ); // das ist der Call! 259*cdf0e10cSrcweir //ALT: SbxVariable* pNew = new SbxVariable( *pElem ); // das ist der Call! 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir pElem->SetParameters(0); // sonst bleibt Ref auf sich selbst 262*cdf0e10cSrcweir pNew->SetFlag( SBX_READWRITE ); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir // den Datentypen zuruecksetzen? 265*cdf0e10cSrcweir if( bSet ) 266*cdf0e10cSrcweir pElem->SetType( t2 ); 267*cdf0e10cSrcweir pElem = pNew; 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir // Index-Access bei UnoObjekten beruecksichtigen 270*cdf0e10cSrcweir // definitely we want this for VBA where properties are often 271*cdf0e10cSrcweir // collections ( which need index access ), but lets only do 272*cdf0e10cSrcweir // this if we actually have params following 273*cdf0e10cSrcweir else if( bVBAEnabled && pElem->ISA(SbUnoProperty) && pElem->GetParameters() ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir // pElem auf eine Ref zuweisen, um ggf. eine Temp-Var zu loeschen 276*cdf0e10cSrcweir SbxVariableRef refTemp = pElem; 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir // Variable kopieren und dabei den Notify aufloesen 279*cdf0e10cSrcweir SbxVariable* pNew = new SbxVariable( *((SbxVariable*)pElem) ); // das ist der Call! 280*cdf0e10cSrcweir pElem->SetParameters( NULL ); // sonst bleibt Ref auf sich selbst 281*cdf0e10cSrcweir pElem = pNew; 282*cdf0e10cSrcweir } 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir return CheckArray( pElem ); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir // Find-Funktion ueber Name fuer aktuellen Scope (z.B. Abfrage aus BASIC-IDE) 288*cdf0e10cSrcweir SbxBase* SbiRuntime::FindElementExtern( const String& rName ) 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir // Hinweis zu #35281#: Es darf nicht davon ausgegangen werden, dass 291*cdf0e10cSrcweir // pMeth != null, da im RunInit noch keine gesetzt ist. 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir SbxVariable* pElem = NULL; 294*cdf0e10cSrcweir if( !pMod || !rName.Len() ) 295*cdf0e10cSrcweir return NULL; 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir // Lokal suchen 298*cdf0e10cSrcweir if( refLocals ) 299*cdf0e10cSrcweir pElem = refLocals->Find( rName, SbxCLASS_DONTCARE ); 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir // In Statics suchen 302*cdf0e10cSrcweir if ( !pElem && pMeth ) 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir // Bei Statics, Name der Methode davor setzen 305*cdf0e10cSrcweir String aMethName = pMeth->GetName(); 306*cdf0e10cSrcweir aMethName += ':'; 307*cdf0e10cSrcweir aMethName += rName; 308*cdf0e10cSrcweir pElem = pMod->Find(aMethName, SbxCLASS_DONTCARE); 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir // In Parameter-Liste suchen 312*cdf0e10cSrcweir if( !pElem && pMeth ) 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir SbxInfo* pInfo = pMeth->GetInfo(); 315*cdf0e10cSrcweir if( pInfo && refParams ) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir sal_uInt16 nParamCount = refParams->Count(); 318*cdf0e10cSrcweir sal_uInt16 j = 1; 319*cdf0e10cSrcweir const SbxParamInfo* pParam = pInfo->GetParam( j ); 320*cdf0e10cSrcweir while( pParam ) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir if( pParam->aName.EqualsIgnoreCaseAscii( rName ) ) 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir if( j >= nParamCount ) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir // Parameter is missing 327*cdf0e10cSrcweir pElem = new SbxVariable( SbxSTRING ); 328*cdf0e10cSrcweir pElem->PutString( String( RTL_CONSTASCII_USTRINGPARAM("<missing parameter>" ) ) ); 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir else 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir pElem = refParams->Get( j ); 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir break; 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir pParam = pInfo->GetParam( ++j ); 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir // Im Modul suchen 342*cdf0e10cSrcweir if( !pElem ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir // RTL nicht durchsuchen! 345*cdf0e10cSrcweir sal_Bool bSave = rBasic.bNoRtl; 346*cdf0e10cSrcweir rBasic.bNoRtl = sal_True; 347*cdf0e10cSrcweir pElem = pMod->Find( rName, SbxCLASS_DONTCARE ); 348*cdf0e10cSrcweir rBasic.bNoRtl = bSave; 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir return pElem; 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir // Argumente eines Elements setzen 355*cdf0e10cSrcweir // Dabei auch die Argumente umsetzen, falls benannte Parameter 356*cdf0e10cSrcweir // verwendet wurden 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir void SbiRuntime::SetupArgs( SbxVariable* p, sal_uInt32 nOp1 ) 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir if( !refArgv ) 363*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 364*cdf0e10cSrcweir sal_Bool bHasNamed = sal_False; 365*cdf0e10cSrcweir sal_uInt16 i; 366*cdf0e10cSrcweir sal_uInt16 nArgCount = refArgv->Count(); 367*cdf0e10cSrcweir for( i = 1 ; i < nArgCount ; i++ ) 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir if( refArgv->GetAlias( i ).Len() ) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir bHasNamed = sal_True; break; 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir if( bHasNamed ) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir // Wir haben mindestens einen benannten Parameter! 377*cdf0e10cSrcweir // Wir muessen also umsortieren 378*cdf0e10cSrcweir // Gibt es Parameter-Infos? 379*cdf0e10cSrcweir SbxInfo* pInfo = p->GetInfo(); 380*cdf0e10cSrcweir if( !pInfo ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir bool bError_ = true; 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir SbUnoMethod* pUnoMethod = PTR_CAST(SbUnoMethod,p); 385*cdf0e10cSrcweir SbUnoProperty* pUnoProperty = PTR_CAST(SbUnoProperty,p); 386*cdf0e10cSrcweir if( pUnoMethod || pUnoProperty ) 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir SbUnoObject* pParentUnoObj = PTR_CAST( SbUnoObject,p->GetParent() ); 389*cdf0e10cSrcweir if( pParentUnoObj ) 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir Any aUnoAny = pParentUnoObj->getUnoAny(); 392*cdf0e10cSrcweir Reference< XInvocation > xInvocation; 393*cdf0e10cSrcweir aUnoAny >>= xInvocation; 394*cdf0e10cSrcweir if( xInvocation.is() ) // TODO: if( xOLEAutomation.is() ) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir bError_ = false; 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir sal_uInt16 nCurPar = 1; 399*cdf0e10cSrcweir AutomationNamedArgsSbxArray* pArg = 400*cdf0e10cSrcweir new AutomationNamedArgsSbxArray( nArgCount ); 401*cdf0e10cSrcweir ::rtl::OUString* pNames = pArg->getNames().getArray(); 402*cdf0e10cSrcweir for( i = 1 ; i < nArgCount ; i++ ) 403*cdf0e10cSrcweir { 404*cdf0e10cSrcweir SbxVariable* pVar = refArgv->Get( i ); 405*cdf0e10cSrcweir const String& rName = refArgv->GetAlias( i ); 406*cdf0e10cSrcweir if( rName.Len() ) 407*cdf0e10cSrcweir pNames[i] = rName; 408*cdf0e10cSrcweir pArg->Put( pVar, nCurPar++ ); 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir refArgv = pArg; 411*cdf0e10cSrcweir } 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir else if( bVBAEnabled && p->GetType() == SbxOBJECT && (!p->ISA(SbxMethod) || !p->IsBroadcaster()) ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir // Check for default method with named parameters 417*cdf0e10cSrcweir SbxBaseRef pObj = (SbxBase*)p->GetObject(); 418*cdf0e10cSrcweir if( pObj && pObj->ISA(SbUnoObject) ) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj; 421*cdf0e10cSrcweir Any aAny = pUnoObj->getUnoAny(); 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue(); 426*cdf0e10cSrcweir Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY ); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir rtl::OUString sDefaultMethod; 429*cdf0e10cSrcweir if ( xDfltMethod.is() ) 430*cdf0e10cSrcweir sDefaultMethod = xDfltMethod->getDefaultMethodName(); 431*cdf0e10cSrcweir if ( sDefaultMethod.getLength() ) 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD ); 434*cdf0e10cSrcweir if( meth != NULL ) 435*cdf0e10cSrcweir pInfo = meth->GetInfo(); 436*cdf0e10cSrcweir if( pInfo ) 437*cdf0e10cSrcweir bError_ = false; 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir if( bError_ ) 443*cdf0e10cSrcweir Error( SbERR_NO_NAMED_ARGS ); 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir else 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir sal_uInt16 nCurPar = 1; 448*cdf0e10cSrcweir SbxArray* pArg = new SbxArray; 449*cdf0e10cSrcweir for( i = 1 ; i < nArgCount ; i++ ) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir SbxVariable* pVar = refArgv->Get( i ); 452*cdf0e10cSrcweir const String& rName = refArgv->GetAlias( i ); 453*cdf0e10cSrcweir if( rName.Len() ) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir // nCurPar wird auf den gefundenen Parameter gesetzt 456*cdf0e10cSrcweir sal_uInt16 j = 1; 457*cdf0e10cSrcweir const SbxParamInfo* pParam = pInfo->GetParam( j ); 458*cdf0e10cSrcweir while( pParam ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir if( pParam->aName.EqualsIgnoreCaseAscii( rName ) ) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir nCurPar = j; 463*cdf0e10cSrcweir break; 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir pParam = pInfo->GetParam( ++j ); 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir if( !pParam ) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir Error( SbERR_NAMED_NOT_FOUND ); break; 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir } 472*cdf0e10cSrcweir pArg->Put( pVar, nCurPar++ ); 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir refArgv = pArg; 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir } 477*cdf0e10cSrcweir // Eigene Var als Parameter 0 478*cdf0e10cSrcweir refArgv->Put( p, 0 ); 479*cdf0e10cSrcweir p->SetParameters( refArgv ); 480*cdf0e10cSrcweir PopArgv(); 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir else 483*cdf0e10cSrcweir p->SetParameters( NULL ); 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir // Holen eines Array-Elements 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir // Falls wir ein Array haben, wollen wir bitte das Array-Element! 491*cdf0e10cSrcweir SbxArray* pPar; 492*cdf0e10cSrcweir if( pElem->GetType() & SbxARRAY ) 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir SbxBase* pElemObj = pElem->GetObject(); 495*cdf0e10cSrcweir SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); 496*cdf0e10cSrcweir pPar = pElem->GetParameters(); 497*cdf0e10cSrcweir if( pDimArray ) 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir // Die Parameter koennen fehlen, wenn ein Array als 500*cdf0e10cSrcweir // Argument uebergeben wird. 501*cdf0e10cSrcweir if( pPar ) 502*cdf0e10cSrcweir pElem = pDimArray->Get( pPar ); 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir else 505*cdf0e10cSrcweir { 506*cdf0e10cSrcweir SbxArray* pArray = PTR_CAST(SbxArray,pElemObj); 507*cdf0e10cSrcweir if( pArray ) 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir if( !pPar ) 510*cdf0e10cSrcweir { 511*cdf0e10cSrcweir Error( SbERR_OUT_OF_RANGE ); 512*cdf0e10cSrcweir pElem = new SbxVariable; 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir else 515*cdf0e10cSrcweir pElem = pArray->Get( pPar->Get( 1 )->GetInteger() ); 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir // #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt 520*cdf0e10cSrcweir if( pPar ) 521*cdf0e10cSrcweir pPar->Put( NULL, 0 ); 522*cdf0e10cSrcweir } 523*cdf0e10cSrcweir // Index-Access bei UnoObjekten beruecksichtigen 524*cdf0e10cSrcweir else if( pElem->GetType() == SbxOBJECT && (!pElem->ISA(SbxMethod) || (bVBAEnabled && !pElem->IsBroadcaster()) ) ) 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir pPar = pElem->GetParameters(); 527*cdf0e10cSrcweir if ( pPar ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir // Ist es ein Uno-Objekt? 530*cdf0e10cSrcweir SbxBaseRef pObj = (SbxBase*)pElem->GetObject(); 531*cdf0e10cSrcweir if( pObj ) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir if( pObj->ISA(SbUnoObject) ) 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir SbUnoObject* pUnoObj = (SbUnoObject*)(SbxBase*)pObj; 536*cdf0e10cSrcweir Any aAny = pUnoObj->getUnoAny(); 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue(); 541*cdf0e10cSrcweir Reference< XIndexAccess > xIndexAccess( x, UNO_QUERY ); 542*cdf0e10cSrcweir if ( !bVBAEnabled ) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir // Haben wir Index-Access? 545*cdf0e10cSrcweir if( xIndexAccess.is() ) 546*cdf0e10cSrcweir { 547*cdf0e10cSrcweir sal_uInt32 nParamCount = (sal_uInt32)pPar->Count() - 1; 548*cdf0e10cSrcweir if( nParamCount != 1 ) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir StarBASIC::Error( SbERR_BAD_ARGUMENT ); 551*cdf0e10cSrcweir return pElem; 552*cdf0e10cSrcweir } 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir // Index holen 555*cdf0e10cSrcweir sal_Int32 nIndex = pPar->Get( 1 )->GetLong(); 556*cdf0e10cSrcweir Reference< XInterface > xRet; 557*cdf0e10cSrcweir try 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir Any aAny2 = xIndexAccess->getByIndex( nIndex ); 560*cdf0e10cSrcweir TypeClass eType = aAny2.getValueType().getTypeClass(); 561*cdf0e10cSrcweir if( eType == TypeClass_INTERFACE ) 562*cdf0e10cSrcweir xRet = *(Reference< XInterface >*)aAny2.getValue(); 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir catch (IndexOutOfBoundsException&) 565*cdf0e10cSrcweir { 566*cdf0e10cSrcweir // Bei Exception erstmal immer von Konvertierungs-Problem ausgehen 567*cdf0e10cSrcweir StarBASIC::Error( SbERR_OUT_OF_RANGE ); 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir // #57847 Immer neue Variable anlegen, sonst Fehler 571*cdf0e10cSrcweir // durch PutObject(NULL) bei ReadOnly-Properties. 572*cdf0e10cSrcweir pElem = new SbxVariable( SbxVARIANT ); 573*cdf0e10cSrcweir if( xRet.is() ) 574*cdf0e10cSrcweir { 575*cdf0e10cSrcweir aAny <<= xRet; 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir // #67173 Kein Namen angeben, damit echter Klassen-Namen eintragen wird 578*cdf0e10cSrcweir String aName; 579*cdf0e10cSrcweir SbxObjectRef xWrapper = (SbxObject*)new SbUnoObject( aName, aAny ); 580*cdf0e10cSrcweir pElem->PutObject( xWrapper ); 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir else 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir pElem->PutObject( NULL ); 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir else 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir rtl::OUString sDefaultMethod; 591*cdf0e10cSrcweir 592*cdf0e10cSrcweir Reference< XDefaultMethod > xDfltMethod( x, UNO_QUERY ); 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir if ( xDfltMethod.is() ) 595*cdf0e10cSrcweir sDefaultMethod = xDfltMethod->getDefaultMethodName(); 596*cdf0e10cSrcweir else if( xIndexAccess.is() ) 597*cdf0e10cSrcweir sDefaultMethod = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getByIndex" ) ); 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir if ( sDefaultMethod.getLength() ) 600*cdf0e10cSrcweir { 601*cdf0e10cSrcweir SbxVariable* meth = pUnoObj->Find( sDefaultMethod, SbxCLASS_METHOD ); 602*cdf0e10cSrcweir SbxVariableRef refTemp = meth; 603*cdf0e10cSrcweir if ( refTemp ) 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir meth->SetParameters( pPar ); 606*cdf0e10cSrcweir SbxVariable* pNew = new SbxMethod( *(SbxMethod*)meth ); 607*cdf0e10cSrcweir pElem = pNew; 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir // #42940, 0.Parameter zu NULL setzen, damit sich Var nicht selbst haelt 614*cdf0e10cSrcweir pPar->Put( NULL, 0 ); 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir else if( pObj->ISA(BasicCollection) ) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir BasicCollection* pCol = (BasicCollection*)(SbxBase*)pObj; 619*cdf0e10cSrcweir pElem = new SbxVariable( SbxVARIANT ); 620*cdf0e10cSrcweir pPar->Put( pElem, 0 ); 621*cdf0e10cSrcweir pCol->CollItem( pPar ); 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir } 624*cdf0e10cSrcweir else if( bVBAEnabled ) // !pObj 625*cdf0e10cSrcweir { 626*cdf0e10cSrcweir SbxArray* pParam = pElem->GetParameters(); 627*cdf0e10cSrcweir if( pParam != NULL && !pElem->IsSet( SBX_VAR_TO_DIM ) ) 628*cdf0e10cSrcweir Error( SbERR_NO_OBJECT ); 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir } 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir return pElem; 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir 636*cdf0e10cSrcweir // Laden eines Elements aus der Runtime-Library (+StringID+Typ) 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir void SbiRuntime::StepRTL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir PushVar( FindElement( rBasic.pRtl, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_False ) ); 641*cdf0e10cSrcweir } 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir void 644*cdf0e10cSrcweir SbiRuntime::StepFIND_Impl( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt32 nOp2, SbError nNotFound, sal_Bool bLocal, sal_Bool bStatic ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir if( !refLocals ) 647*cdf0e10cSrcweir refLocals = new SbxArray; 648*cdf0e10cSrcweir PushVar( FindElement( pObj, nOp1, nOp2, nNotFound, bLocal, bStatic ) ); 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir // Laden einer lokalen/globalen Variablen (+StringID+Typ) 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir void SbiRuntime::StepFIND( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_True ); 655*cdf0e10cSrcweir } 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir // Search inside a class module (CM) to enable global search in time 658*cdf0e10cSrcweir void SbiRuntime::StepFIND_CM( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 659*cdf0e10cSrcweir { 660*cdf0e10cSrcweir 661*cdf0e10cSrcweir SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pMod); 662*cdf0e10cSrcweir if( pClassModuleObject ) 663*cdf0e10cSrcweir pMod->SetFlag( SBX_GBLSEARCH ); 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_True ); 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir if( pClassModuleObject ) 668*cdf0e10cSrcweir pMod->ResetFlag( SBX_GBLSEARCH ); 669*cdf0e10cSrcweir } 670*cdf0e10cSrcweir 671*cdf0e10cSrcweir void SbiRuntime::StepFIND_STATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 672*cdf0e10cSrcweir { 673*cdf0e10cSrcweir StepFIND_Impl( pMod, nOp1, nOp2, SbERR_PROC_UNDEFINED, sal_True, sal_True ); 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir // Laden eines Objekt-Elements (+StringID+Typ) 677*cdf0e10cSrcweir // Das Objekt liegt auf TOS 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir void SbiRuntime::StepELEM( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir // Liegt auf dem TOS ein Objekt? 682*cdf0e10cSrcweir SbxVariableRef pObjVar = PopVar(); 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pObjVar); 685*cdf0e10cSrcweir if( !pObj ) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir SbxBase* pObjVarObj = pObjVar->GetObject(); 688*cdf0e10cSrcweir pObj = PTR_CAST(SbxObject,pObjVarObj); 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir // #56368 Bei StepElem Referenz sichern, sonst koennen Objekte 692*cdf0e10cSrcweir // in Qualifizierungsketten wie ActiveComponent.Selection(0).Text 693*cdf0e10cSrcweir // zu fueh die Referenz verlieren 694*cdf0e10cSrcweir // #74254 Jetzt per Liste 695*cdf0e10cSrcweir if( pObj ) 696*cdf0e10cSrcweir SaveRef( (SbxVariable*)pObj ); 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir PushVar( FindElement( pObj, nOp1, nOp2, SbERR_NO_METHOD, sal_False ) ); 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir 701*cdf0e10cSrcweir // Laden eines Parameters (+Offset+Typ) 702*cdf0e10cSrcweir // Wenn der Datentyp nicht stimmen sollte, eine Kopie anlegen 703*cdf0e10cSrcweir // Der Datentyp SbxEMPTY zeigt an, daa kein Parameter angegeben ist. 704*cdf0e10cSrcweir // Get( 0 ) darf EMPTY sein 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir void SbiRuntime::StepPARAM( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 707*cdf0e10cSrcweir { 708*cdf0e10cSrcweir sal_uInt16 i = static_cast<sal_uInt16>( nOp1 & 0x7FFF ); 709*cdf0e10cSrcweir SbxDataType t = (SbxDataType) nOp2; 710*cdf0e10cSrcweir SbxVariable* p; 711*cdf0e10cSrcweir 712*cdf0e10cSrcweir // #57915 Missing sauberer loesen 713*cdf0e10cSrcweir sal_uInt16 nParamCount = refParams->Count(); 714*cdf0e10cSrcweir if( i >= nParamCount ) 715*cdf0e10cSrcweir { 716*cdf0e10cSrcweir sal_Int16 iLoop = i; 717*cdf0e10cSrcweir while( iLoop >= nParamCount ) 718*cdf0e10cSrcweir { 719*cdf0e10cSrcweir p = new SbxVariable(); 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir if( SbiRuntime::isVBAEnabled() && 722*cdf0e10cSrcweir (t == SbxOBJECT || t == SbxSTRING) ) 723*cdf0e10cSrcweir { 724*cdf0e10cSrcweir if( t == SbxOBJECT ) 725*cdf0e10cSrcweir p->PutObject( NULL ); 726*cdf0e10cSrcweir else 727*cdf0e10cSrcweir p->PutString( String() ); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir else 730*cdf0e10cSrcweir p->PutErr( 448 ); // Wie in VB: Error-Code 448 (SbERR_NAMED_NOT_FOUND) 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir refParams->Put( p, iLoop ); 733*cdf0e10cSrcweir iLoop--; 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir p = refParams->Get( i ); 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir if( p->GetType() == SbxERROR && ( i ) ) 739*cdf0e10cSrcweir //if( p->GetType() == SbxEMPTY && ( i ) ) 740*cdf0e10cSrcweir { 741*cdf0e10cSrcweir // Wenn ein Parameter fehlt, kann er OPTIONAL sein 742*cdf0e10cSrcweir sal_Bool bOpt = sal_False; 743*cdf0e10cSrcweir if( pMeth ) 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir SbxInfo* pInfo = pMeth->GetInfo(); 746*cdf0e10cSrcweir if ( pInfo ) 747*cdf0e10cSrcweir { 748*cdf0e10cSrcweir const SbxParamInfo* pParam = pInfo->GetParam( i ); 749*cdf0e10cSrcweir if( pParam && ( (pParam->nFlags & SBX_OPTIONAL) != 0 ) ) 750*cdf0e10cSrcweir { 751*cdf0e10cSrcweir // Default value? 752*cdf0e10cSrcweir sal_uInt16 nDefaultId = sal::static_int_cast< sal_uInt16 >( 753*cdf0e10cSrcweir pParam->nUserData & 0xffff ); 754*cdf0e10cSrcweir if( nDefaultId > 0 ) 755*cdf0e10cSrcweir { 756*cdf0e10cSrcweir String aDefaultStr = pImg->GetString( nDefaultId ); 757*cdf0e10cSrcweir p = new SbxVariable(); 758*cdf0e10cSrcweir p->PutString( aDefaultStr ); 759*cdf0e10cSrcweir refParams->Put( p, i ); 760*cdf0e10cSrcweir } 761*cdf0e10cSrcweir bOpt = sal_True; 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir if( bOpt == sal_False ) 766*cdf0e10cSrcweir Error( SbERR_NOT_OPTIONAL ); 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir else if( t != SbxVARIANT && (SbxDataType)(p->GetType() & 0x0FFF ) != t ) 769*cdf0e10cSrcweir { 770*cdf0e10cSrcweir SbxVariable* q = new SbxVariable( t ); 771*cdf0e10cSrcweir SaveRef( q ); 772*cdf0e10cSrcweir *q = *p; 773*cdf0e10cSrcweir p = q; 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir SetupArgs( p, nOp1 ); 776*cdf0e10cSrcweir PushVar( CheckArray( p ) ); 777*cdf0e10cSrcweir } 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir // Case-Test (+True-Target+Test-Opcode) 780*cdf0e10cSrcweir 781*cdf0e10cSrcweir void SbiRuntime::StepCASEIS( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 782*cdf0e10cSrcweir { 783*cdf0e10cSrcweir if( !refCaseStk || !refCaseStk->Count() ) 784*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 785*cdf0e10cSrcweir else 786*cdf0e10cSrcweir { 787*cdf0e10cSrcweir SbxVariableRef xComp = PopVar(); 788*cdf0e10cSrcweir SbxVariableRef xCase = refCaseStk->Get( refCaseStk->Count() - 1 ); 789*cdf0e10cSrcweir if( xCase->Compare( (SbxOperator) nOp2, *xComp ) ) 790*cdf0e10cSrcweir StepJUMP( nOp1 ); 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir } 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir // Aufruf einer DLL-Prozedur (+StringID+Typ) 795*cdf0e10cSrcweir // Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist 796*cdf0e10cSrcweir 797*cdf0e10cSrcweir void SbiRuntime::StepCALL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 798*cdf0e10cSrcweir { 799*cdf0e10cSrcweir String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ); 800*cdf0e10cSrcweir SbxArray* pArgs = NULL; 801*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 802*cdf0e10cSrcweir pArgs = refArgv; 803*cdf0e10cSrcweir DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, sal_False ); 804*cdf0e10cSrcweir aLibName = String(); 805*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 806*cdf0e10cSrcweir PopArgv(); 807*cdf0e10cSrcweir } 808*cdf0e10cSrcweir 809*cdf0e10cSrcweir // Aufruf einer DLL-Prozedur nach CDecl (+StringID+Typ) 810*cdf0e10cSrcweir // Auch hier zeigt das MSB des StringIDs an, dass Argv belegt ist 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir void SbiRuntime::StepCALLC( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir String aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ); 815*cdf0e10cSrcweir SbxArray* pArgs = NULL; 816*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 817*cdf0e10cSrcweir pArgs = refArgv; 818*cdf0e10cSrcweir DllCall( aName, aLibName, pArgs, (SbxDataType) nOp2, sal_True ); 819*cdf0e10cSrcweir aLibName = String(); 820*cdf0e10cSrcweir if( nOp1 & 0x8000 ) 821*cdf0e10cSrcweir PopArgv(); 822*cdf0e10cSrcweir } 823*cdf0e10cSrcweir 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir // Beginn eines Statements (+Line+Col) 826*cdf0e10cSrcweir 827*cdf0e10cSrcweir void SbiRuntime::StepSTMNT( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 828*cdf0e10cSrcweir { 829*cdf0e10cSrcweir // Wenn der Expr-Stack am Anfang einen Statements eine Variable enthaelt, 830*cdf0e10cSrcweir // hat ein Trottel X als Funktion aufgerufen, obwohl es eine Variable ist! 831*cdf0e10cSrcweir sal_Bool bFatalExpr = sal_False; 832*cdf0e10cSrcweir String sUnknownMethodName; 833*cdf0e10cSrcweir if( nExprLvl > 1 ) 834*cdf0e10cSrcweir bFatalExpr = sal_True; 835*cdf0e10cSrcweir else if( nExprLvl ) 836*cdf0e10cSrcweir { 837*cdf0e10cSrcweir SbxVariable* p = refExprStk->Get( 0 ); 838*cdf0e10cSrcweir if( p->GetRefCount() > 1 839*cdf0e10cSrcweir && refLocals.Is() && refLocals->Find( p->GetName(), p->GetClass() ) ) 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir sUnknownMethodName = p->GetName(); 842*cdf0e10cSrcweir bFatalExpr = sal_True; 843*cdf0e10cSrcweir } 844*cdf0e10cSrcweir } 845*cdf0e10cSrcweir // Der Expr-Stack ist nun nicht mehr notwendig 846*cdf0e10cSrcweir ClearExprStack(); 847*cdf0e10cSrcweir 848*cdf0e10cSrcweir // #56368 Kuenstliche Referenz fuer StepElem wieder freigeben, 849*cdf0e10cSrcweir // damit sie nicht ueber ein Statement hinaus erhalten bleibt 850*cdf0e10cSrcweir //refSaveObj = NULL; 851*cdf0e10cSrcweir // #74254 Jetzt per Liste 852*cdf0e10cSrcweir ClearRefs(); 853*cdf0e10cSrcweir 854*cdf0e10cSrcweir // Wir muessen hier hart abbrechen, da sonst Zeile und Spalte nicht mehr 855*cdf0e10cSrcweir // stimmen! 856*cdf0e10cSrcweir if( bFatalExpr) 857*cdf0e10cSrcweir { 858*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_NO_METHOD, sUnknownMethodName ); 859*cdf0e10cSrcweir return; 860*cdf0e10cSrcweir } 861*cdf0e10cSrcweir pStmnt = pCode - 9; 862*cdf0e10cSrcweir sal_uInt16 nOld = nLine; 863*cdf0e10cSrcweir nLine = static_cast<short>( nOp1 ); 864*cdf0e10cSrcweir 865*cdf0e10cSrcweir // #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern 866*cdf0e10cSrcweir nCol1 = static_cast<short>( nOp2 & 0xFF ); 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir // Suchen des naechsten STMNT-Befehls, 869*cdf0e10cSrcweir // um die End-Spalte dieses Statements zu setzen 870*cdf0e10cSrcweir // Searches of the next STMNT instruction, 871*cdf0e10cSrcweir // around the final column of this statement to set 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir nCol2 = 0xffff; 874*cdf0e10cSrcweir sal_uInt16 n1, n2; 875*cdf0e10cSrcweir const sal_uInt8* p = pMod->FindNextStmnt( pCode, n1, n2 ); 876*cdf0e10cSrcweir if( p ) 877*cdf0e10cSrcweir { 878*cdf0e10cSrcweir if( n1 == nOp1 ) 879*cdf0e10cSrcweir { 880*cdf0e10cSrcweir // #29955 & 0xFF, um for-Schleifen-Ebene wegzufiltern 881*cdf0e10cSrcweir nCol2 = (n2 & 0xFF) - 1; 882*cdf0e10cSrcweir } 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir // #29955 for-Schleifen-Ebene korrigieren, #67452 NICHT im Error-Handler sonst Chaos 886*cdf0e10cSrcweir if( !bInError ) 887*cdf0e10cSrcweir { 888*cdf0e10cSrcweir // (Bei Spr�ngen aus Schleifen tritt hier eine Differenz auf) 889*cdf0e10cSrcweir sal_uInt16 nExspectedForLevel = static_cast<sal_uInt16>( nOp2 / 0x100 ); 890*cdf0e10cSrcweir if( pGosubStk ) 891*cdf0e10cSrcweir nExspectedForLevel = nExspectedForLevel + pGosubStk->nStartForLvl; 892*cdf0e10cSrcweir 893*cdf0e10cSrcweir // Wenn der tatsaechliche For-Level zu klein ist, wurde aus 894*cdf0e10cSrcweir // einer Schleife heraus gesprungen -> korrigieren 895*cdf0e10cSrcweir while( nForLvl > nExspectedForLevel ) 896*cdf0e10cSrcweir PopFor(); 897*cdf0e10cSrcweir } 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir // 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out 900*cdf0e10cSrcweir // Erkl�rung siehe bei _ImplGetBreakCallLevel. 901*cdf0e10cSrcweir if( pInst->nCallLvl <= pInst->nBreakCallLvl ) 902*cdf0e10cSrcweir //if( nFlags & SbDEBUG_STEPINTO ) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir StarBASIC* pStepBasic = GetCurrentBasic( &rBasic ); 905*cdf0e10cSrcweir sal_uInt16 nNewFlags = pStepBasic->StepPoint( nLine, nCol1, nCol2 ); 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir // Neuen BreakCallLevel ermitteln 908*cdf0e10cSrcweir pInst->CalcBreakCallLevel( nNewFlags ); 909*cdf0e10cSrcweir } 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir // Breakpoints nur bei STMNT-Befehlen in neuer Zeile! 912*cdf0e10cSrcweir else if( ( nOp1 != nOld ) 913*cdf0e10cSrcweir && ( nFlags & SbDEBUG_BREAK ) 914*cdf0e10cSrcweir && pMod->IsBP( static_cast<sal_uInt16>( nOp1 ) ) ) 915*cdf0e10cSrcweir { 916*cdf0e10cSrcweir StarBASIC* pBreakBasic = GetCurrentBasic( &rBasic ); 917*cdf0e10cSrcweir sal_uInt16 nNewFlags = pBreakBasic->BreakPoint( nLine, nCol1, nCol2 ); 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir // Neuen BreakCallLevel ermitteln 920*cdf0e10cSrcweir pInst->CalcBreakCallLevel( nNewFlags ); 921*cdf0e10cSrcweir //16.10.96, ALT: 922*cdf0e10cSrcweir //if( nNewFlags != SbDEBUG_CONTINUE ) 923*cdf0e10cSrcweir // nFlags = nNewFlags; 924*cdf0e10cSrcweir } 925*cdf0e10cSrcweir } 926*cdf0e10cSrcweir 927*cdf0e10cSrcweir // (+SvStreamFlags+Flags) 928*cdf0e10cSrcweir // Stack: Blocklaenge 929*cdf0e10cSrcweir // Kanalnummer 930*cdf0e10cSrcweir // Dateiname 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir void SbiRuntime::StepOPEN( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 933*cdf0e10cSrcweir { 934*cdf0e10cSrcweir SbxVariableRef pName = PopVar(); 935*cdf0e10cSrcweir SbxVariableRef pChan = PopVar(); 936*cdf0e10cSrcweir SbxVariableRef pLen = PopVar(); 937*cdf0e10cSrcweir short nBlkLen = pLen->GetInteger(); 938*cdf0e10cSrcweir short nChan = pChan->GetInteger(); 939*cdf0e10cSrcweir ByteString aName( pName->GetString(), gsl_getSystemTextEncoding() ); 940*cdf0e10cSrcweir pIosys->Open( nChan, aName, static_cast<short>( nOp1 ), 941*cdf0e10cSrcweir static_cast<short>( nOp2 ), nBlkLen ); 942*cdf0e10cSrcweir Error( pIosys->GetError() ); 943*cdf0e10cSrcweir } 944*cdf0e10cSrcweir 945*cdf0e10cSrcweir // Objekt kreieren (+StringID+StringID) 946*cdf0e10cSrcweir 947*cdf0e10cSrcweir void SbiRuntime::StepCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 948*cdf0e10cSrcweir { 949*cdf0e10cSrcweir String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) ); 950*cdf0e10cSrcweir SbxObject *pObj = SbxBase::CreateObject( aClass ); 951*cdf0e10cSrcweir if( !pObj ) 952*cdf0e10cSrcweir Error( SbERR_INVALID_OBJECT ); 953*cdf0e10cSrcweir else 954*cdf0e10cSrcweir { 955*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 956*cdf0e10cSrcweir pObj->SetName( aName ); 957*cdf0e10cSrcweir // Das Objekt muss BASIC rufen koennen 958*cdf0e10cSrcweir pObj->SetParent( &rBasic ); 959*cdf0e10cSrcweir SbxVariable* pNew = new SbxVariable; 960*cdf0e10cSrcweir pNew->PutObject( pObj ); 961*cdf0e10cSrcweir PushVar( pNew ); 962*cdf0e10cSrcweir } 963*cdf0e10cSrcweir } 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir void SbiRuntime::StepDCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 966*cdf0e10cSrcweir { 967*cdf0e10cSrcweir StepDCREATE_IMPL( nOp1, nOp2 ); 968*cdf0e10cSrcweir } 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir void SbiRuntime::StepDCREATE_REDIMP( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 971*cdf0e10cSrcweir { 972*cdf0e10cSrcweir StepDCREATE_IMPL( nOp1, nOp2 ); 973*cdf0e10cSrcweir } 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir 976*cdf0e10cSrcweir // Helper function for StepDCREATE_IMPL / bRedimp = true 977*cdf0e10cSrcweir void implCopyDimArray_DCREATE( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex, 978*cdf0e10cSrcweir short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds ) 979*cdf0e10cSrcweir { 980*cdf0e10cSrcweir sal_Int32& ri = pActualIndices[nActualDim]; 981*cdf0e10cSrcweir for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ ) 982*cdf0e10cSrcweir { 983*cdf0e10cSrcweir if( nActualDim < nMaxDimIndex ) 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir implCopyDimArray_DCREATE( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1, 986*cdf0e10cSrcweir pActualIndices, pLowerBounds, pUpperBounds ); 987*cdf0e10cSrcweir } 988*cdf0e10cSrcweir else 989*cdf0e10cSrcweir { 990*cdf0e10cSrcweir SbxVariable* pSource = pOldArray->Get32( pActualIndices ); 991*cdf0e10cSrcweir pNewArray->Put32( pSource, pActualIndices ); 992*cdf0e10cSrcweir } 993*cdf0e10cSrcweir } 994*cdf0e10cSrcweir } 995*cdf0e10cSrcweir 996*cdf0e10cSrcweir // #56204 Objekt-Array kreieren (+StringID+StringID), DCREATE == Dim-Create 997*cdf0e10cSrcweir void SbiRuntime::StepDCREATE_IMPL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 998*cdf0e10cSrcweir { 999*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 1000*cdf0e10cSrcweir 1001*cdf0e10cSrcweir DimImpl( refVar ); 1002*cdf0e10cSrcweir 1003*cdf0e10cSrcweir // Das Array mit Instanzen der geforderten Klasse fuellen 1004*cdf0e10cSrcweir SbxBaseRef xObj = (SbxBase*)refVar->GetObject(); 1005*cdf0e10cSrcweir if( !xObj ) 1006*cdf0e10cSrcweir { 1007*cdf0e10cSrcweir StarBASIC::Error( SbERR_INVALID_OBJECT ); 1008*cdf0e10cSrcweir return; 1009*cdf0e10cSrcweir } 1010*cdf0e10cSrcweir 1011*cdf0e10cSrcweir SbxDimArray* pArray = 0; 1012*cdf0e10cSrcweir if( xObj->ISA(SbxDimArray) ) 1013*cdf0e10cSrcweir { 1014*cdf0e10cSrcweir SbxBase* pObj = (SbxBase*)xObj; 1015*cdf0e10cSrcweir pArray = (SbxDimArray*)pObj; 1016*cdf0e10cSrcweir 1017*cdf0e10cSrcweir // Dimensionen auswerten 1018*cdf0e10cSrcweir short nDims = pArray->GetDims(); 1019*cdf0e10cSrcweir sal_Int32 nTotalSize = 0; 1020*cdf0e10cSrcweir 1021*cdf0e10cSrcweir // es muss ein eindimensionales Array sein 1022*cdf0e10cSrcweir sal_Int32 nLower, nUpper, nSize; 1023*cdf0e10cSrcweir sal_Int32 i; 1024*cdf0e10cSrcweir for( i = 0 ; i < nDims ; i++ ) 1025*cdf0e10cSrcweir { 1026*cdf0e10cSrcweir pArray->GetDim32( i+1, nLower, nUpper ); 1027*cdf0e10cSrcweir nSize = nUpper - nLower + 1; 1028*cdf0e10cSrcweir if( i == 0 ) 1029*cdf0e10cSrcweir nTotalSize = nSize; 1030*cdf0e10cSrcweir else 1031*cdf0e10cSrcweir nTotalSize *= nSize; 1032*cdf0e10cSrcweir } 1033*cdf0e10cSrcweir 1034*cdf0e10cSrcweir // Objekte anlegen und ins Array eintragen 1035*cdf0e10cSrcweir String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) ); 1036*cdf0e10cSrcweir for( i = 0 ; i < nTotalSize ; i++ ) 1037*cdf0e10cSrcweir { 1038*cdf0e10cSrcweir SbxObject *pClassObj = SbxBase::CreateObject( aClass ); 1039*cdf0e10cSrcweir if( !pClassObj ) 1040*cdf0e10cSrcweir { 1041*cdf0e10cSrcweir Error( SbERR_INVALID_OBJECT ); 1042*cdf0e10cSrcweir break; 1043*cdf0e10cSrcweir } 1044*cdf0e10cSrcweir else 1045*cdf0e10cSrcweir { 1046*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 1047*cdf0e10cSrcweir pClassObj->SetName( aName ); 1048*cdf0e10cSrcweir // Das Objekt muss BASIC rufen koennen 1049*cdf0e10cSrcweir pClassObj->SetParent( &rBasic ); 1050*cdf0e10cSrcweir pArray->SbxArray::Put32( pClassObj, i ); 1051*cdf0e10cSrcweir } 1052*cdf0e10cSrcweir } 1053*cdf0e10cSrcweir } 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray; 1056*cdf0e10cSrcweir if( pArray && pOldArray ) 1057*cdf0e10cSrcweir { 1058*cdf0e10cSrcweir short nDimsNew = pArray->GetDims(); 1059*cdf0e10cSrcweir short nDimsOld = pOldArray->GetDims(); 1060*cdf0e10cSrcweir short nDims = nDimsNew; 1061*cdf0e10cSrcweir sal_Bool bRangeError = sal_False; 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir // Store dims to use them for copying later 1064*cdf0e10cSrcweir sal_Int32* pLowerBounds = new sal_Int32[nDims]; 1065*cdf0e10cSrcweir sal_Int32* pUpperBounds = new sal_Int32[nDims]; 1066*cdf0e10cSrcweir sal_Int32* pActualIndices = new sal_Int32[nDims]; 1067*cdf0e10cSrcweir if( nDimsOld != nDimsNew ) 1068*cdf0e10cSrcweir { 1069*cdf0e10cSrcweir bRangeError = sal_True; 1070*cdf0e10cSrcweir } 1071*cdf0e10cSrcweir else 1072*cdf0e10cSrcweir { 1073*cdf0e10cSrcweir // Compare bounds 1074*cdf0e10cSrcweir for( short i = 1 ; i <= nDims ; i++ ) 1075*cdf0e10cSrcweir { 1076*cdf0e10cSrcweir sal_Int32 lBoundNew, uBoundNew; 1077*cdf0e10cSrcweir sal_Int32 lBoundOld, uBoundOld; 1078*cdf0e10cSrcweir pArray->GetDim32( i, lBoundNew, uBoundNew ); 1079*cdf0e10cSrcweir pOldArray->GetDim32( i, lBoundOld, uBoundOld ); 1080*cdf0e10cSrcweir 1081*cdf0e10cSrcweir lBoundNew = std::max( lBoundNew, lBoundOld ); 1082*cdf0e10cSrcweir uBoundNew = std::min( uBoundNew, uBoundOld ); 1083*cdf0e10cSrcweir short j = i - 1; 1084*cdf0e10cSrcweir pActualIndices[j] = pLowerBounds[j] = lBoundNew; 1085*cdf0e10cSrcweir pUpperBounds[j] = uBoundNew; 1086*cdf0e10cSrcweir } 1087*cdf0e10cSrcweir } 1088*cdf0e10cSrcweir 1089*cdf0e10cSrcweir if( bRangeError ) 1090*cdf0e10cSrcweir { 1091*cdf0e10cSrcweir StarBASIC::Error( SbERR_OUT_OF_RANGE ); 1092*cdf0e10cSrcweir } 1093*cdf0e10cSrcweir else 1094*cdf0e10cSrcweir { 1095*cdf0e10cSrcweir // Copy data from old array by going recursively through all dimensions 1096*cdf0e10cSrcweir // (It would be faster to work on the flat internal data array of an 1097*cdf0e10cSrcweir // SbyArray but this solution is clearer and easier) 1098*cdf0e10cSrcweir implCopyDimArray_DCREATE( pArray, pOldArray, nDims - 1, 1099*cdf0e10cSrcweir 0, pActualIndices, pLowerBounds, pUpperBounds ); 1100*cdf0e10cSrcweir } 1101*cdf0e10cSrcweir delete [] pUpperBounds; 1102*cdf0e10cSrcweir delete [] pLowerBounds; 1103*cdf0e10cSrcweir delete [] pActualIndices; 1104*cdf0e10cSrcweir refRedimpArray = NULL; 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir } 1107*cdf0e10cSrcweir 1108*cdf0e10cSrcweir // Objekt aus User-Type kreieren (+StringID+StringID) 1109*cdf0e10cSrcweir 1110*cdf0e10cSrcweir SbxObject* createUserTypeImpl( const String& rClassName ); // sb.cxx 1111*cdf0e10cSrcweir 1112*cdf0e10cSrcweir void SbiRuntime::StepTCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1113*cdf0e10cSrcweir { 1114*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 1115*cdf0e10cSrcweir String aClass( pImg->GetString( static_cast<short>( nOp2 ) ) ); 1116*cdf0e10cSrcweir 1117*cdf0e10cSrcweir SbxObject* pCopyObj = createUserTypeImpl( aClass ); 1118*cdf0e10cSrcweir if( pCopyObj ) 1119*cdf0e10cSrcweir pCopyObj->SetName( aName ); 1120*cdf0e10cSrcweir SbxVariable* pNew = new SbxVariable; 1121*cdf0e10cSrcweir pNew->PutObject( pCopyObj ); 1122*cdf0e10cSrcweir pNew->SetDeclareClassName( aClass ); 1123*cdf0e10cSrcweir PushVar( pNew ); 1124*cdf0e10cSrcweir } 1125*cdf0e10cSrcweir 1126*cdf0e10cSrcweir void SbiRuntime::implHandleSbxFlags( SbxVariable* pVar, SbxDataType t, sal_uInt32 nOp2 ) 1127*cdf0e10cSrcweir { 1128*cdf0e10cSrcweir bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0); 1129*cdf0e10cSrcweir if( bWithEvents ) 1130*cdf0e10cSrcweir pVar->SetFlag( SBX_WITH_EVENTS ); 1131*cdf0e10cSrcweir 1132*cdf0e10cSrcweir bool bDimAsNew = ((nOp2 & SBX_TYPE_DIM_AS_NEW_FLAG) != 0); 1133*cdf0e10cSrcweir if( bDimAsNew ) 1134*cdf0e10cSrcweir pVar->SetFlag( SBX_DIM_AS_NEW ); 1135*cdf0e10cSrcweir 1136*cdf0e10cSrcweir bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0); 1137*cdf0e10cSrcweir if( bFixedString ) 1138*cdf0e10cSrcweir { 1139*cdf0e10cSrcweir sal_uInt16 nCount = static_cast<sal_uInt16>( nOp2 >> 17 ); // len = all bits above 0x10000 1140*cdf0e10cSrcweir String aStr; 1141*cdf0e10cSrcweir aStr.Fill( nCount, 0 ); 1142*cdf0e10cSrcweir pVar->PutString( aStr ); 1143*cdf0e10cSrcweir } 1144*cdf0e10cSrcweir 1145*cdf0e10cSrcweir bool bVarToDim = ((nOp2 & SBX_TYPE_VAR_TO_DIM_FLAG) != 0); 1146*cdf0e10cSrcweir if( bVarToDim ) 1147*cdf0e10cSrcweir pVar->SetFlag( SBX_VAR_TO_DIM ); 1148*cdf0e10cSrcweir } 1149*cdf0e10cSrcweir 1150*cdf0e10cSrcweir // Einrichten einer lokalen Variablen (+StringID+Typ) 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir void SbiRuntime::StepLOCAL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1153*cdf0e10cSrcweir { 1154*cdf0e10cSrcweir if( !refLocals.Is() ) 1155*cdf0e10cSrcweir refLocals = new SbxArray; 1156*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 1157*cdf0e10cSrcweir if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL ) 1158*cdf0e10cSrcweir { 1159*cdf0e10cSrcweir SbxDataType t = (SbxDataType)(nOp2 & 0xffff); 1160*cdf0e10cSrcweir SbxVariable* p = new SbxVariable( t ); 1161*cdf0e10cSrcweir p->SetName( aName ); 1162*cdf0e10cSrcweir implHandleSbxFlags( p, t, nOp2 ); 1163*cdf0e10cSrcweir refLocals->Put( p, refLocals->Count() ); 1164*cdf0e10cSrcweir } 1165*cdf0e10cSrcweir } 1166*cdf0e10cSrcweir 1167*cdf0e10cSrcweir // Einrichten einer modulglobalen Variablen (+StringID+Typ) 1168*cdf0e10cSrcweir 1169*cdf0e10cSrcweir void SbiRuntime::StepPUBLIC_Impl( sal_uInt32 nOp1, sal_uInt32 nOp2, bool bUsedForClassModule ) 1170*cdf0e10cSrcweir { 1171*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 1172*cdf0e10cSrcweir SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);; 1173*cdf0e10cSrcweir sal_Bool bFlag = pMod->IsSet( SBX_NO_MODIFY ); 1174*cdf0e10cSrcweir pMod->SetFlag( SBX_NO_MODIFY ); 1175*cdf0e10cSrcweir SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY ); 1176*cdf0e10cSrcweir if( p.Is() ) 1177*cdf0e10cSrcweir pMod->Remove (p); 1178*cdf0e10cSrcweir SbProperty* pProp = pMod->GetProperty( aName, t ); 1179*cdf0e10cSrcweir if( !bUsedForClassModule ) 1180*cdf0e10cSrcweir pProp->SetFlag( SBX_PRIVATE ); 1181*cdf0e10cSrcweir if( !bFlag ) 1182*cdf0e10cSrcweir pMod->ResetFlag( SBX_NO_MODIFY ); 1183*cdf0e10cSrcweir if( pProp ) 1184*cdf0e10cSrcweir { 1185*cdf0e10cSrcweir pProp->SetFlag( SBX_DONTSTORE ); 1186*cdf0e10cSrcweir // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden' 1187*cdf0e10cSrcweir pProp->SetFlag( SBX_NO_MODIFY); 1188*cdf0e10cSrcweir 1189*cdf0e10cSrcweir implHandleSbxFlags( pProp, t, nOp2 ); 1190*cdf0e10cSrcweir } 1191*cdf0e10cSrcweir } 1192*cdf0e10cSrcweir 1193*cdf0e10cSrcweir void SbiRuntime::StepPUBLIC( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1194*cdf0e10cSrcweir { 1195*cdf0e10cSrcweir StepPUBLIC_Impl( nOp1, nOp2, false ); 1196*cdf0e10cSrcweir } 1197*cdf0e10cSrcweir 1198*cdf0e10cSrcweir void SbiRuntime::StepPUBLIC_P( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1199*cdf0e10cSrcweir { 1200*cdf0e10cSrcweir // Creates module variable that isn't reinitialised when 1201*cdf0e10cSrcweir // between invocations ( for VBASupport & document basic only ) 1202*cdf0e10cSrcweir if( pMod->pImage->bFirstInit ) 1203*cdf0e10cSrcweir { 1204*cdf0e10cSrcweir bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE ); 1205*cdf0e10cSrcweir StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule ); 1206*cdf0e10cSrcweir } 1207*cdf0e10cSrcweir } 1208*cdf0e10cSrcweir 1209*cdf0e10cSrcweir // Einrichten einer globalen Variablen (+StringID+Typ) 1210*cdf0e10cSrcweir 1211*cdf0e10cSrcweir void SbiRuntime::StepGLOBAL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1212*cdf0e10cSrcweir { 1213*cdf0e10cSrcweir if( pImg->GetFlag( SBIMG_CLASSMODULE ) ) 1214*cdf0e10cSrcweir StepPUBLIC_Impl( nOp1, nOp2, true ); 1215*cdf0e10cSrcweir 1216*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 1217*cdf0e10cSrcweir SbxDataType t = (SbxDataType)(nOp2 & 0xffff); 1218*cdf0e10cSrcweir 1219*cdf0e10cSrcweir // Store module scope variables at module scope 1220*cdf0e10cSrcweir // in non vba mode these are stored at the library level :/ 1221*cdf0e10cSrcweir // not sure if this really should not be enabled for ALL basic 1222*cdf0e10cSrcweir SbxObject* pStorage = &rBasic; 1223*cdf0e10cSrcweir if ( SbiRuntime::isVBAEnabled() ) 1224*cdf0e10cSrcweir { 1225*cdf0e10cSrcweir pStorage = pMod; 1226*cdf0e10cSrcweir pMod->AddVarName( aName ); 1227*cdf0e10cSrcweir } 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir sal_Bool bFlag = pStorage->IsSet( SBX_NO_MODIFY ); 1230*cdf0e10cSrcweir rBasic.SetFlag( SBX_NO_MODIFY ); 1231*cdf0e10cSrcweir SbxVariableRef p = pStorage->Find( aName, SbxCLASS_PROPERTY ); 1232*cdf0e10cSrcweir if( p.Is() ) 1233*cdf0e10cSrcweir pStorage->Remove (p); 1234*cdf0e10cSrcweir p = pStorage->Make( aName, SbxCLASS_PROPERTY, t ); 1235*cdf0e10cSrcweir if( !bFlag ) 1236*cdf0e10cSrcweir pStorage->ResetFlag( SBX_NO_MODIFY ); 1237*cdf0e10cSrcweir if( p ) 1238*cdf0e10cSrcweir { 1239*cdf0e10cSrcweir p->SetFlag( SBX_DONTSTORE ); 1240*cdf0e10cSrcweir // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden' 1241*cdf0e10cSrcweir p->SetFlag( SBX_NO_MODIFY); 1242*cdf0e10cSrcweir } 1243*cdf0e10cSrcweir } 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir 1246*cdf0e10cSrcweir // Creates global variable that isn't reinitialised when 1247*cdf0e10cSrcweir // basic is restarted, P=PERSIST (+StringID+Typ) 1248*cdf0e10cSrcweir 1249*cdf0e10cSrcweir void SbiRuntime::StepGLOBAL_P( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1250*cdf0e10cSrcweir { 1251*cdf0e10cSrcweir if( pMod->pImage->bFirstInit ) 1252*cdf0e10cSrcweir { 1253*cdf0e10cSrcweir StepGLOBAL( nOp1, nOp2 ); 1254*cdf0e10cSrcweir } 1255*cdf0e10cSrcweir } 1256*cdf0e10cSrcweir 1257*cdf0e10cSrcweir 1258*cdf0e10cSrcweir // Searches for global variable, behavior depends on the fact 1259*cdf0e10cSrcweir // if the variable is initialised for the first time 1260*cdf0e10cSrcweir 1261*cdf0e10cSrcweir void SbiRuntime::StepFIND_G( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1262*cdf0e10cSrcweir { 1263*cdf0e10cSrcweir if( pMod->pImage->bFirstInit ) 1264*cdf0e10cSrcweir { 1265*cdf0e10cSrcweir // Behave like always during first init 1266*cdf0e10cSrcweir StepFIND( nOp1, nOp2 ); 1267*cdf0e10cSrcweir } 1268*cdf0e10cSrcweir else 1269*cdf0e10cSrcweir { 1270*cdf0e10cSrcweir // Return dummy variable 1271*cdf0e10cSrcweir SbxDataType t = (SbxDataType) nOp2; 1272*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) ); 1273*cdf0e10cSrcweir 1274*cdf0e10cSrcweir SbxVariable* pDummyVar = new SbxVariable( t ); 1275*cdf0e10cSrcweir pDummyVar->SetName( aName ); 1276*cdf0e10cSrcweir PushVar( pDummyVar ); 1277*cdf0e10cSrcweir } 1278*cdf0e10cSrcweir } 1279*cdf0e10cSrcweir 1280*cdf0e10cSrcweir 1281*cdf0e10cSrcweir SbxVariable* SbiRuntime::StepSTATIC_Impl( String& aName, SbxDataType& t ) 1282*cdf0e10cSrcweir { 1283*cdf0e10cSrcweir SbxVariable* p = NULL; 1284*cdf0e10cSrcweir if ( pMeth ) 1285*cdf0e10cSrcweir { 1286*cdf0e10cSrcweir SbxArray* pStatics = pMeth->GetStatics(); 1287*cdf0e10cSrcweir if( pStatics && ( pStatics->Find( aName, SbxCLASS_DONTCARE ) == NULL ) ) 1288*cdf0e10cSrcweir { 1289*cdf0e10cSrcweir p = new SbxVariable( t ); 1290*cdf0e10cSrcweir if( t != SbxVARIANT ) 1291*cdf0e10cSrcweir p->SetFlag( SBX_FIXED ); 1292*cdf0e10cSrcweir p->SetName( aName ); 1293*cdf0e10cSrcweir pStatics->Put( p, pStatics->Count() ); 1294*cdf0e10cSrcweir } 1295*cdf0e10cSrcweir } 1296*cdf0e10cSrcweir return p; 1297*cdf0e10cSrcweir } 1298*cdf0e10cSrcweir // Einrichten einer statischen Variablen (+StringID+Typ) 1299*cdf0e10cSrcweir void SbiRuntime::StepSTATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 ) 1300*cdf0e10cSrcweir { 1301*cdf0e10cSrcweir String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); 1302*cdf0e10cSrcweir SbxDataType t = (SbxDataType) nOp2; 1303*cdf0e10cSrcweir StepSTATIC_Impl( aName, t ); 1304*cdf0e10cSrcweir } 1305*cdf0e10cSrcweir 1306