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