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 #include <vcl/msgbox.hxx> 31*cdf0e10cSrcweir #include <tools/fsys.hxx> 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "errobject.hxx" 34*cdf0e10cSrcweir #include "runtime.hxx" 35*cdf0e10cSrcweir #include "sbintern.hxx" 36*cdf0e10cSrcweir #include "iosys.hxx" 37*cdf0e10cSrcweir #include <sb.hrc> 38*cdf0e10cSrcweir #include <basrid.hxx> 39*cdf0e10cSrcweir #include "sbunoobj.hxx" 40*cdf0e10cSrcweir #include "image.hxx" 41*cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx> 42*cdf0e10cSrcweir #include <com/sun/star/util/SearchOptions.hdl> 43*cdf0e10cSrcweir #include <vcl/svapp.hxx> 44*cdf0e10cSrcweir #include <unotools/textsearch.hxx> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType, 47*cdf0e10cSrcweir const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj ); 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #include <algorithm> 50*cdf0e10cSrcweir #include <hash_map> 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir SbxVariable* getDefaultProp( SbxVariable* pRef ); 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir void SbiRuntime::StepNOP() 55*cdf0e10cSrcweir {} 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir void SbiRuntime::StepArith( SbxOperator eOp ) 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir SbxVariableRef p1 = PopVar(); 60*cdf0e10cSrcweir TOSMakeTemp(); 61*cdf0e10cSrcweir SbxVariable* p2 = GetTOS(); 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir // This could & should be moved to the MakeTempTOS() method in runtime.cxx 65*cdf0e10cSrcweir // In the code which this is cut'npaste from there is a check for a ref 66*cdf0e10cSrcweir // count != 1 based on which the copy of the SbxVariable is done. 67*cdf0e10cSrcweir // see orig code in MakeTempTOS ( and I'm not sure what the significance, 68*cdf0e10cSrcweir // of that is ) 69*cdf0e10cSrcweir // here we alway seem to have a refcount of 1. Also it seems that 70*cdf0e10cSrcweir // MakeTempTOS is called for other operation, so I hold off for now 71*cdf0e10cSrcweir // until I have a better idea 72*cdf0e10cSrcweir if ( bVBAEnabled 73*cdf0e10cSrcweir && ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT ) 74*cdf0e10cSrcweir ) 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir SbxVariable* pDflt = getDefaultProp( p2 ); 77*cdf0e10cSrcweir if ( pDflt ) 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir pDflt->Broadcast( SBX_HINT_DATAWANTED ); 80*cdf0e10cSrcweir // replacing new p2 on stack causes object pointed by 81*cdf0e10cSrcweir // pDft->pParent to be deleted, when p2->Compute() is 82*cdf0e10cSrcweir // called below pParent is accessed ( but its deleted ) 83*cdf0e10cSrcweir // so set it to NULL now 84*cdf0e10cSrcweir pDflt->SetParent( NULL ); 85*cdf0e10cSrcweir p2 = new SbxVariable( *pDflt ); 86*cdf0e10cSrcweir p2->SetFlag( SBX_READWRITE ); 87*cdf0e10cSrcweir refExprStk->Put( p2, nExprLvl - 1 ); 88*cdf0e10cSrcweir } 89*cdf0e10cSrcweir } 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir p2->ResetFlag( SBX_FIXED ); 92*cdf0e10cSrcweir p2->Compute( eOp, *p1 ); 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir checkArithmeticOverflow( p2 ); 95*cdf0e10cSrcweir } 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir void SbiRuntime::StepUnary( SbxOperator eOp ) 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir TOSMakeTemp(); 100*cdf0e10cSrcweir SbxVariable* p = GetTOS(); 101*cdf0e10cSrcweir p->Compute( eOp, *p ); 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir void SbiRuntime::StepCompare( SbxOperator eOp ) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir SbxVariableRef p1 = PopVar(); 107*cdf0e10cSrcweir SbxVariableRef p2 = PopVar(); 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir // Make sure objects with default params have 110*cdf0e10cSrcweir // values ( and type ) set as appropriate 111*cdf0e10cSrcweir SbxDataType p1Type = p1->GetType(); 112*cdf0e10cSrcweir SbxDataType p2Type = p2->GetType(); 113*cdf0e10cSrcweir if ( p1Type == p2Type ) 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir if ( p1Type == SbxEMPTY ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir p1->Broadcast( SBX_HINT_DATAWANTED ); 118*cdf0e10cSrcweir p2->Broadcast( SBX_HINT_DATAWANTED ); 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir // if both sides are an object and have default props 121*cdf0e10cSrcweir // then we need to use the default props 122*cdf0e10cSrcweir // we don't need to worry if only one side ( lhs, rhs ) is an 123*cdf0e10cSrcweir // object ( object side will get coerced to correct type in 124*cdf0e10cSrcweir // Compare ) 125*cdf0e10cSrcweir else if ( p1Type == SbxOBJECT ) 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir SbxVariable* pDflt = getDefaultProp( p1 ); 128*cdf0e10cSrcweir if ( pDflt ) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir p1 = pDflt; 131*cdf0e10cSrcweir p1->Broadcast( SBX_HINT_DATAWANTED ); 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir pDflt = getDefaultProp( p2 ); 134*cdf0e10cSrcweir if ( pDflt ) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir p2 = pDflt; 137*cdf0e10cSrcweir p2->Broadcast( SBX_HINT_DATAWANTED ); 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir static SbxVariable* pTRUE = NULL; 143*cdf0e10cSrcweir static SbxVariable* pFALSE = NULL; 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir if( p2->Compare( eOp, *p1 ) ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir if( !pTRUE ) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir pTRUE = new SbxVariable; 150*cdf0e10cSrcweir pTRUE->PutBool( sal_True ); 151*cdf0e10cSrcweir pTRUE->AddRef(); 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir PushVar( pTRUE ); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir else 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir if( !pFALSE ) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir pFALSE = new SbxVariable; 160*cdf0e10cSrcweir pFALSE->PutBool( sal_False ); 161*cdf0e10cSrcweir pFALSE->AddRef(); 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir PushVar( pFALSE ); 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir } 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir void SbiRuntime::StepEXP() { StepArith( SbxEXP ); } 168*cdf0e10cSrcweir void SbiRuntime::StepMUL() { StepArith( SbxMUL ); } 169*cdf0e10cSrcweir void SbiRuntime::StepDIV() { StepArith( SbxDIV ); } 170*cdf0e10cSrcweir void SbiRuntime::StepIDIV() { StepArith( SbxIDIV ); } 171*cdf0e10cSrcweir void SbiRuntime::StepMOD() { StepArith( SbxMOD ); } 172*cdf0e10cSrcweir void SbiRuntime::StepPLUS() { StepArith( SbxPLUS ); } 173*cdf0e10cSrcweir void SbiRuntime::StepMINUS() { StepArith( SbxMINUS ); } 174*cdf0e10cSrcweir void SbiRuntime::StepCAT() { StepArith( SbxCAT ); } 175*cdf0e10cSrcweir void SbiRuntime::StepAND() { StepArith( SbxAND ); } 176*cdf0e10cSrcweir void SbiRuntime::StepOR() { StepArith( SbxOR ); } 177*cdf0e10cSrcweir void SbiRuntime::StepXOR() { StepArith( SbxXOR ); } 178*cdf0e10cSrcweir void SbiRuntime::StepEQV() { StepArith( SbxEQV ); } 179*cdf0e10cSrcweir void SbiRuntime::StepIMP() { StepArith( SbxIMP ); } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir void SbiRuntime::StepNEG() { StepUnary( SbxNEG ); } 182*cdf0e10cSrcweir void SbiRuntime::StepNOT() { StepUnary( SbxNOT ); } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir void SbiRuntime::StepEQ() { StepCompare( SbxEQ ); } 185*cdf0e10cSrcweir void SbiRuntime::StepNE() { StepCompare( SbxNE ); } 186*cdf0e10cSrcweir void SbiRuntime::StepLT() { StepCompare( SbxLT ); } 187*cdf0e10cSrcweir void SbiRuntime::StepGT() { StepCompare( SbxGT ); } 188*cdf0e10cSrcweir void SbiRuntime::StepLE() { StepCompare( SbxLE ); } 189*cdf0e10cSrcweir void SbiRuntime::StepGE() { StepCompare( SbxGE ); } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir namespace 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir bool NeedEsc(sal_Unicode cCode) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir String sEsc(RTL_CONSTASCII_USTRINGPARAM(".^$+\\|{}()")); 196*cdf0e10cSrcweir return (STRING_NOTFOUND != sEsc.Search(cCode)); 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir String VBALikeToRegexp(const String &rIn) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir String sResult; 202*cdf0e10cSrcweir const sal_Unicode *start = rIn.GetBuffer(); 203*cdf0e10cSrcweir const sal_Unicode *end = start + rIn.Len(); 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir int seenright = 0; 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir sResult.Append('^'); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir while (start < end) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir switch (*start) 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir case '?': 214*cdf0e10cSrcweir sResult.Append('.'); 215*cdf0e10cSrcweir start++; 216*cdf0e10cSrcweir break; 217*cdf0e10cSrcweir case '*': 218*cdf0e10cSrcweir sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM(".*"))); 219*cdf0e10cSrcweir start++; 220*cdf0e10cSrcweir break; 221*cdf0e10cSrcweir case '#': 222*cdf0e10cSrcweir sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM("[0-9]"))); 223*cdf0e10cSrcweir start++; 224*cdf0e10cSrcweir break; 225*cdf0e10cSrcweir case ']': 226*cdf0e10cSrcweir sResult.Append('\\'); 227*cdf0e10cSrcweir sResult.Append(*start++); 228*cdf0e10cSrcweir break; 229*cdf0e10cSrcweir case '[': 230*cdf0e10cSrcweir sResult.Append(*start++); 231*cdf0e10cSrcweir seenright = 0; 232*cdf0e10cSrcweir while (start < end && !seenright) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir switch (*start) 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir case '[': 237*cdf0e10cSrcweir case '?': 238*cdf0e10cSrcweir case '*': 239*cdf0e10cSrcweir sResult.Append('\\'); 240*cdf0e10cSrcweir sResult.Append(*start); 241*cdf0e10cSrcweir break; 242*cdf0e10cSrcweir case ']': 243*cdf0e10cSrcweir sResult.Append(*start); 244*cdf0e10cSrcweir seenright = 1; 245*cdf0e10cSrcweir break; 246*cdf0e10cSrcweir case '!': 247*cdf0e10cSrcweir sResult.Append('^'); 248*cdf0e10cSrcweir break; 249*cdf0e10cSrcweir default: 250*cdf0e10cSrcweir if (NeedEsc(*start)) 251*cdf0e10cSrcweir sResult.Append('\\'); 252*cdf0e10cSrcweir sResult.Append(*start); 253*cdf0e10cSrcweir break; 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir start++; 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir break; 258*cdf0e10cSrcweir default: 259*cdf0e10cSrcweir if (NeedEsc(*start)) 260*cdf0e10cSrcweir sResult.Append('\\'); 261*cdf0e10cSrcweir sResult.Append(*start++); 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir sResult.Append('$'); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir return sResult; 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir void SbiRuntime::StepLIKE() 272*cdf0e10cSrcweir { 273*cdf0e10cSrcweir SbxVariableRef refVar1 = PopVar(); 274*cdf0e10cSrcweir SbxVariableRef refVar2 = PopVar(); 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir String pattern = VBALikeToRegexp(refVar1->GetString()); 277*cdf0e10cSrcweir String value = refVar2->GetString(); 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir com::sun::star::util::SearchOptions aSearchOpt; 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir aSearchOpt.algorithmType = com::sun::star::util::SearchAlgorithms_REGEXP; 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir aSearchOpt.Locale = Application::GetSettings().GetLocale(); 284*cdf0e10cSrcweir aSearchOpt.searchString = pattern; 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir int bTextMode(1); 287*cdf0e10cSrcweir bool bCompatibility = ( pINST && pINST->IsCompatibility() ); 288*cdf0e10cSrcweir if( bCompatibility ) 289*cdf0e10cSrcweir bTextMode = GetImageFlag( SBIMG_COMPARETEXT ); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir if( bTextMode ) 292*cdf0e10cSrcweir aSearchOpt.transliterateFlags |= com::sun::star::i18n::TransliterationModules_IGNORE_CASE; 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir SbxVariable* pRes = new SbxVariable; 295*cdf0e10cSrcweir utl::TextSearch aSearch(aSearchOpt); 296*cdf0e10cSrcweir xub_StrLen nStart=0, nEnd=value.Len(); 297*cdf0e10cSrcweir int bRes = aSearch.SearchFrwrd(value, &nStart, &nEnd); 298*cdf0e10cSrcweir pRes->PutBool( bRes != 0 ); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir PushVar( pRes ); 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir // TOS und TOS-1 sind beides Objektvariable und enthalten den selben Pointer 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir void SbiRuntime::StepIS() 306*cdf0e10cSrcweir { 307*cdf0e10cSrcweir SbxVariableRef refVar1 = PopVar(); 308*cdf0e10cSrcweir SbxVariableRef refVar2 = PopVar(); 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir SbxDataType eType1 = refVar1->GetType(); 311*cdf0e10cSrcweir SbxDataType eType2 = refVar2->GetType(); 312*cdf0e10cSrcweir if ( eType1 == SbxEMPTY ) 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir refVar1->Broadcast( SBX_HINT_DATAWANTED ); 315*cdf0e10cSrcweir eType1 = refVar1->GetType(); 316*cdf0e10cSrcweir } 317*cdf0e10cSrcweir if ( eType2 == SbxEMPTY ) 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir refVar2->Broadcast( SBX_HINT_DATAWANTED ); 320*cdf0e10cSrcweir eType2 = refVar2->GetType(); 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir sal_Bool bRes = sal_Bool( eType1 == SbxOBJECT && eType2 == SbxOBJECT ); 324*cdf0e10cSrcweir if ( bVBAEnabled && !bRes ) 325*cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 326*cdf0e10cSrcweir bRes = ( bRes && refVar1->GetObject() == refVar2->GetObject() ); 327*cdf0e10cSrcweir SbxVariable* pRes = new SbxVariable; 328*cdf0e10cSrcweir pRes->PutBool( bRes ); 329*cdf0e10cSrcweir PushVar( pRes ); 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir // Aktualisieren des Wertes von TOS 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir void SbiRuntime::StepGET() 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir SbxVariable* p = GetTOS(); 337*cdf0e10cSrcweir p->Broadcast( SBX_HINT_DATAWANTED ); 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir // #67607 Uno-Structs kopieren 341*cdf0e10cSrcweir inline void checkUnoStructCopy( SbxVariableRef& refVal, SbxVariableRef& refVar ) 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir SbxDataType eVarType = refVar->GetType(); 344*cdf0e10cSrcweir if( eVarType != SbxOBJECT ) 345*cdf0e10cSrcweir return; 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir SbxObjectRef xValObj = (SbxObject*)refVal->GetObject(); 348*cdf0e10cSrcweir if( !xValObj.Is() || xValObj->ISA(SbUnoAnyObject) ) 349*cdf0e10cSrcweir return; 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir // #115826: Exclude ProcedureProperties to avoid call to Property Get procedure 352*cdf0e10cSrcweir if( refVar->ISA(SbProcedureProperty) ) 353*cdf0e10cSrcweir return; 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir SbxObjectRef xVarObj = (SbxObject*)refVar->GetObject(); 356*cdf0e10cSrcweir SbxDataType eValType = refVal->GetType(); 357*cdf0e10cSrcweir if( eValType == SbxOBJECT && xVarObj == xValObj ) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)xVarObj); 360*cdf0e10cSrcweir if( pUnoObj ) 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir Any aAny = pUnoObj->getUnoAny(); 363*cdf0e10cSrcweir if( aAny.getValueType().getTypeClass() == TypeClass_STRUCT ) 364*cdf0e10cSrcweir { 365*cdf0e10cSrcweir SbUnoObject* pNewUnoObj = new SbUnoObject( pUnoObj->GetName(), aAny ); 366*cdf0e10cSrcweir // #70324: ClassName uebernehmen 367*cdf0e10cSrcweir pNewUnoObj->SetClassName( pUnoObj->GetClassName() ); 368*cdf0e10cSrcweir refVar->PutObject( pNewUnoObj ); 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir // Ablage von TOS in TOS-1 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir void SbiRuntime::StepPUT() 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 380*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 381*cdf0e10cSrcweir // Store auf die eigene Methode (innerhalb einer Function)? 382*cdf0e10cSrcweir sal_Bool bFlagsChanged = sal_False; 383*cdf0e10cSrcweir sal_uInt16 n = 0; 384*cdf0e10cSrcweir if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir bFlagsChanged = sal_True; 387*cdf0e10cSrcweir n = refVar->GetFlags(); 388*cdf0e10cSrcweir refVar->SetFlag( SBX_WRITE ); 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir // if left side arg is an object or variant and right handside isn't 392*cdf0e10cSrcweir // either an object or a variant then try and see if a default 393*cdf0e10cSrcweir // property exists. 394*cdf0e10cSrcweir // to use e.g. Range{"A1") = 34 395*cdf0e10cSrcweir // could equate to Range("A1").Value = 34 396*cdf0e10cSrcweir if ( bVBAEnabled ) 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir if ( refVar->GetType() == SbxOBJECT ) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir SbxVariable* pDflt = getDefaultProp( refVar ); 401*cdf0e10cSrcweir if ( pDflt ) 402*cdf0e10cSrcweir refVar = pDflt; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir if ( refVal->GetType() == SbxOBJECT ) 405*cdf0e10cSrcweir { 406*cdf0e10cSrcweir SbxVariable* pDflt = getDefaultProp( refVal ); 407*cdf0e10cSrcweir if ( pDflt ) 408*cdf0e10cSrcweir refVal = pDflt; 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir *refVar = *refVal; 413*cdf0e10cSrcweir // lhs is a property who's value is currently null 414*cdf0e10cSrcweir if ( !bVBAEnabled || ( bVBAEnabled && refVar->GetType() != SbxEMPTY ) ) 415*cdf0e10cSrcweir // #67607 Uno-Structs kopieren 416*cdf0e10cSrcweir checkUnoStructCopy( refVal, refVar ); 417*cdf0e10cSrcweir if( bFlagsChanged ) 418*cdf0e10cSrcweir refVar->SetFlags( n ); 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // VBA Dim As New behavior handling, save init object information 423*cdf0e10cSrcweir struct DimAsNewRecoverItem 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir String m_aObjClass; 426*cdf0e10cSrcweir String m_aObjName; 427*cdf0e10cSrcweir SbxObject* m_pObjParent; 428*cdf0e10cSrcweir SbModule* m_pClassModule; 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir DimAsNewRecoverItem( void ) 431*cdf0e10cSrcweir : m_pObjParent( NULL ) 432*cdf0e10cSrcweir , m_pClassModule( NULL ) 433*cdf0e10cSrcweir {} 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir DimAsNewRecoverItem( const String& rObjClass, const String& rObjName, 436*cdf0e10cSrcweir SbxObject* pObjParent, SbModule* pClassModule ) 437*cdf0e10cSrcweir : m_aObjClass( rObjClass ) 438*cdf0e10cSrcweir , m_aObjName( rObjName ) 439*cdf0e10cSrcweir , m_pObjParent( pObjParent ) 440*cdf0e10cSrcweir , m_pClassModule( pClassModule ) 441*cdf0e10cSrcweir {} 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir }; 444*cdf0e10cSrcweir 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir struct SbxVariablePtrHash 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir size_t operator()( SbxVariable* pVar ) const 449*cdf0e10cSrcweir { return (size_t)pVar; } 450*cdf0e10cSrcweir }; 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir typedef std::hash_map< SbxVariable*, DimAsNewRecoverItem, SbxVariablePtrHash > DimAsNewRecoverHash; 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir static DimAsNewRecoverHash GaDimAsNewRecoverHash; 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir void removeDimAsNewRecoverItem( SbxVariable* pVar ) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir DimAsNewRecoverHash::iterator it = GaDimAsNewRecoverHash.find( pVar ); 459*cdf0e10cSrcweir if( it != GaDimAsNewRecoverHash.end() ) 460*cdf0e10cSrcweir GaDimAsNewRecoverHash.erase( it ); 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir // Speichern Objektvariable 465*cdf0e10cSrcweir // Nicht-Objekt-Variable fuehren zu Fehlern 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir static const char pCollectionStr[] = "Collection"; 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bHandleDefaultProp ) 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir // #67733 Typen mit Array-Flag sind auch ok 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir // Check var, !object is no error for sure if, only if type is fixed 474*cdf0e10cSrcweir SbxDataType eVarType = refVar->GetType(); 475*cdf0e10cSrcweir if( !bHandleDefaultProp && eVarType != SbxOBJECT && !(eVarType & SbxARRAY) && refVar->IsFixed() ) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 478*cdf0e10cSrcweir return; 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir // Check value, !object is no error for sure if, only if type is fixed 482*cdf0e10cSrcweir SbxDataType eValType = refVal->GetType(); 483*cdf0e10cSrcweir // bool bGetValObject = false; 484*cdf0e10cSrcweir if( !bHandleDefaultProp && eValType != SbxOBJECT && !(eValType & SbxARRAY) && refVal->IsFixed() ) 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 487*cdf0e10cSrcweir return; 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir // Getting in here causes problems with objects with default properties 491*cdf0e10cSrcweir // if they are SbxEMPTY I guess 492*cdf0e10cSrcweir if ( !bHandleDefaultProp || ( bHandleDefaultProp && eValType == SbxOBJECT ) ) 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir // Auf refVal GetObject fuer Collections ausloesen 495*cdf0e10cSrcweir SbxBase* pObjVarObj = refVal->GetObject(); 496*cdf0e10cSrcweir if( pObjVarObj ) 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir SbxVariableRef refObjVal = PTR_CAST(SbxObject,pObjVarObj); 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir // #67733 Typen mit Array-Flag sind auch ok 501*cdf0e10cSrcweir if( refObjVal ) 502*cdf0e10cSrcweir refVal = refObjVal; 503*cdf0e10cSrcweir else if( !(eValType & SbxARRAY) ) 504*cdf0e10cSrcweir refVal = NULL; 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir // #52896 Wenn Uno-Sequences bzw. allgemein Arrays einer als 509*cdf0e10cSrcweir // Object deklarierten Variable zugewiesen werden, kann hier 510*cdf0e10cSrcweir // refVal ungueltig sein! 511*cdf0e10cSrcweir if( !refVal ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir else 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir // Store auf die eigene Methode (innerhalb einer Function)? 518*cdf0e10cSrcweir sal_Bool bFlagsChanged = sal_False; 519*cdf0e10cSrcweir sal_uInt16 n = 0; 520*cdf0e10cSrcweir if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) 521*cdf0e10cSrcweir { 522*cdf0e10cSrcweir bFlagsChanged = sal_True; 523*cdf0e10cSrcweir n = refVar->GetFlags(); 524*cdf0e10cSrcweir refVar->SetFlag( SBX_WRITE ); 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir SbProcedureProperty* pProcProperty = PTR_CAST(SbProcedureProperty,(SbxVariable*)refVar); 527*cdf0e10cSrcweir if( pProcProperty ) 528*cdf0e10cSrcweir pProcProperty->setSet( true ); 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir if ( bHandleDefaultProp ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir // get default properties for lhs & rhs where necessary 533*cdf0e10cSrcweir // SbxVariable* defaultProp = NULL; unused variable 534*cdf0e10cSrcweir bool bLHSHasDefaultProp = false; 535*cdf0e10cSrcweir // LHS try determine if a default prop exists 536*cdf0e10cSrcweir if ( refVar->GetType() == SbxOBJECT ) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir SbxVariable* pDflt = getDefaultProp( refVar ); 539*cdf0e10cSrcweir if ( pDflt ) 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir refVar = pDflt; 542*cdf0e10cSrcweir bLHSHasDefaultProp = true; 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir } 545*cdf0e10cSrcweir // RHS only get a default prop is the rhs has one 546*cdf0e10cSrcweir if ( refVal->GetType() == SbxOBJECT ) 547*cdf0e10cSrcweir { 548*cdf0e10cSrcweir // check if lhs is a null object 549*cdf0e10cSrcweir // if it is then use the object not the default property 550*cdf0e10cSrcweir SbxObject* pObj = NULL; 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir pObj = PTR_CAST(SbxObject,(SbxVariable*)refVar); 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir // calling GetObject on a SbxEMPTY variable raises 556*cdf0e10cSrcweir // object not set errors, make sure its an Object 557*cdf0e10cSrcweir if ( !pObj && refVar->GetType() == SbxOBJECT ) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir SbxBase* pObjVarObj = refVar->GetObject(); 560*cdf0e10cSrcweir pObj = PTR_CAST(SbxObject,pObjVarObj); 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir SbxVariable* pDflt = NULL; 563*cdf0e10cSrcweir if ( pObj || bLHSHasDefaultProp ) 564*cdf0e10cSrcweir // lhs is either a valid object || or has a defaultProp 565*cdf0e10cSrcweir pDflt = getDefaultProp( refVal ); 566*cdf0e10cSrcweir if ( pDflt ) 567*cdf0e10cSrcweir refVal = pDflt; 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir 571*cdf0e10cSrcweir // Handle Dim As New 572*cdf0e10cSrcweir sal_Bool bDimAsNew = bVBAEnabled && refVar->IsSet( SBX_DIM_AS_NEW ); 573*cdf0e10cSrcweir SbxBaseRef xPrevVarObj; 574*cdf0e10cSrcweir if( bDimAsNew ) 575*cdf0e10cSrcweir xPrevVarObj = refVar->GetObject(); 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir // Handle withevents 578*cdf0e10cSrcweir sal_Bool bWithEvents = refVar->IsSet( SBX_WITH_EVENTS ); 579*cdf0e10cSrcweir if ( bWithEvents ) 580*cdf0e10cSrcweir { 581*cdf0e10cSrcweir Reference< XInterface > xComListener; 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir SbxBase* pObj = refVal->GetObject(); 584*cdf0e10cSrcweir SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL; 585*cdf0e10cSrcweir if( pUnoObj != NULL ) 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir Any aControlAny = pUnoObj->getUnoAny(); 588*cdf0e10cSrcweir String aDeclareClassName = refVar->GetDeclareClassName(); 589*cdf0e10cSrcweir ::rtl::OUString aVBAType = aDeclareClassName; 590*cdf0e10cSrcweir ::rtl::OUString aPrefix = refVar->GetName(); 591*cdf0e10cSrcweir SbxObjectRef xScopeObj = refVar->GetParent(); 592*cdf0e10cSrcweir xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj ); 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir refVal->SetDeclareClassName( aDeclareClassName ); 595*cdf0e10cSrcweir refVal->SetComListener( xComListener, &rBasic ); // Hold reference 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir *refVar = *refVal; 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir else 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir *refVar = *refVal; 603*cdf0e10cSrcweir } 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir if ( bDimAsNew ) 606*cdf0e10cSrcweir { 607*cdf0e10cSrcweir if( !refVar->ISA(SbxObject) ) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir SbxBase* pValObjBase = refVal->GetObject(); 610*cdf0e10cSrcweir if( pValObjBase == NULL ) 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir if( xPrevVarObj.Is() ) 613*cdf0e10cSrcweir { 614*cdf0e10cSrcweir // Object is overwritten with NULL, instantiate init object 615*cdf0e10cSrcweir DimAsNewRecoverHash::iterator it = GaDimAsNewRecoverHash.find( refVar ); 616*cdf0e10cSrcweir if( it != GaDimAsNewRecoverHash.end() ) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir const DimAsNewRecoverItem& rItem = it->second; 619*cdf0e10cSrcweir if( rItem.m_pClassModule != NULL ) 620*cdf0e10cSrcweir { 621*cdf0e10cSrcweir SbClassModuleObject* pNewObj = new SbClassModuleObject( rItem.m_pClassModule ); 622*cdf0e10cSrcweir pNewObj->SetName( rItem.m_aObjName ); 623*cdf0e10cSrcweir pNewObj->SetParent( rItem.m_pObjParent ); 624*cdf0e10cSrcweir refVar->PutObject( pNewObj ); 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir else if( rItem.m_aObjClass.EqualsIgnoreCaseAscii( pCollectionStr ) ) 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir BasicCollection* pNewCollection = new BasicCollection( String( RTL_CONSTASCII_USTRINGPARAM(pCollectionStr) ) ); 629*cdf0e10cSrcweir pNewCollection->SetName( rItem.m_aObjName ); 630*cdf0e10cSrcweir pNewCollection->SetParent( rItem.m_pObjParent ); 631*cdf0e10cSrcweir refVar->PutObject( pNewCollection ); 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir } 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir } 636*cdf0e10cSrcweir else 637*cdf0e10cSrcweir { 638*cdf0e10cSrcweir // Does old value exist? 639*cdf0e10cSrcweir bool bFirstInit = !xPrevVarObj.Is(); 640*cdf0e10cSrcweir if( bFirstInit ) 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir // Store information to instantiate object later 643*cdf0e10cSrcweir SbxObject* pValObj = PTR_CAST(SbxObject,pValObjBase); 644*cdf0e10cSrcweir if( pValObj != NULL ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir String aObjClass = pValObj->GetClassName(); 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pValObjBase); 649*cdf0e10cSrcweir if( pClassModuleObj != NULL ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir SbModule* pClassModule = pClassModuleObj->getClassModule(); 652*cdf0e10cSrcweir GaDimAsNewRecoverHash[refVar] = 653*cdf0e10cSrcweir DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), pClassModule ); 654*cdf0e10cSrcweir } 655*cdf0e10cSrcweir else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) ) 656*cdf0e10cSrcweir { 657*cdf0e10cSrcweir GaDimAsNewRecoverHash[refVar] = 658*cdf0e10cSrcweir DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), NULL ); 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir // lhs is a property who's value is currently (Empty e.g. no broadcast yet) 668*cdf0e10cSrcweir // in this case if there is a default prop involved the value of the 669*cdf0e10cSrcweir // default property may infact be void so the type will also be SbxEMPTY 670*cdf0e10cSrcweir // in this case we do not want to call checkUnoStructCopy 'cause that will 671*cdf0e10cSrcweir // cause an error also 672*cdf0e10cSrcweir if ( !bHandleDefaultProp || ( bHandleDefaultProp && ( refVar->GetType() != SbxEMPTY ) ) ) 673*cdf0e10cSrcweir // #67607 Uno-Structs kopieren 674*cdf0e10cSrcweir checkUnoStructCopy( refVal, refVar ); 675*cdf0e10cSrcweir if( bFlagsChanged ) 676*cdf0e10cSrcweir refVar->SetFlags( n ); 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir void SbiRuntime::StepSET() 681*cdf0e10cSrcweir { 682*cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 683*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 684*cdf0e10cSrcweir StepSET_Impl( refVal, refVar, bVBAEnabled ); // this is really assigment 685*cdf0e10cSrcweir } 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir void SbiRuntime::StepVBASET() 688*cdf0e10cSrcweir { 689*cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 690*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 691*cdf0e10cSrcweir // don't handle default property 692*cdf0e10cSrcweir StepSET_Impl( refVal, refVar, false ); // set obj = something 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir 696*cdf0e10cSrcweir // JSM 07.10.95 697*cdf0e10cSrcweir void SbiRuntime::StepLSET() 698*cdf0e10cSrcweir { 699*cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 700*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 701*cdf0e10cSrcweir if( refVar->GetType() != SbxSTRING 702*cdf0e10cSrcweir || refVal->GetType() != SbxSTRING ) 703*cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 704*cdf0e10cSrcweir else 705*cdf0e10cSrcweir { 706*cdf0e10cSrcweir // Store auf die eigene Methode (innerhalb einer Function)? 707*cdf0e10cSrcweir sal_uInt16 n = refVar->GetFlags(); 708*cdf0e10cSrcweir if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) 709*cdf0e10cSrcweir refVar->SetFlag( SBX_WRITE ); 710*cdf0e10cSrcweir String aRefVarString = refVar->GetString(); 711*cdf0e10cSrcweir String aRefValString = refVal->GetString(); 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir sal_uInt16 nVarStrLen = aRefVarString.Len(); 714*cdf0e10cSrcweir sal_uInt16 nValStrLen = aRefValString.Len(); 715*cdf0e10cSrcweir String aNewStr; 716*cdf0e10cSrcweir if( nVarStrLen > nValStrLen ) 717*cdf0e10cSrcweir { 718*cdf0e10cSrcweir aRefVarString.Fill(nVarStrLen,' '); 719*cdf0e10cSrcweir aNewStr = aRefValString.Copy( 0, nValStrLen ); 720*cdf0e10cSrcweir aNewStr += aRefVarString.Copy( nValStrLen, nVarStrLen - nValStrLen ); 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir else 723*cdf0e10cSrcweir { 724*cdf0e10cSrcweir aNewStr = aRefValString.Copy( 0, nVarStrLen ); 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir refVar->PutString( aNewStr ); 728*cdf0e10cSrcweir refVar->SetFlags( n ); 729*cdf0e10cSrcweir } 730*cdf0e10cSrcweir } 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir // JSM 07.10.95 733*cdf0e10cSrcweir void SbiRuntime::StepRSET() 734*cdf0e10cSrcweir { 735*cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 736*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 737*cdf0e10cSrcweir if( refVar->GetType() != SbxSTRING 738*cdf0e10cSrcweir || refVal->GetType() != SbxSTRING ) 739*cdf0e10cSrcweir Error( SbERR_INVALID_USAGE_OBJECT ); 740*cdf0e10cSrcweir else 741*cdf0e10cSrcweir { 742*cdf0e10cSrcweir // Store auf die eigene Methode (innerhalb einer Function)? 743*cdf0e10cSrcweir sal_uInt16 n = refVar->GetFlags(); 744*cdf0e10cSrcweir if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) 745*cdf0e10cSrcweir refVar->SetFlag( SBX_WRITE ); 746*cdf0e10cSrcweir String aRefVarString = refVar->GetString(); 747*cdf0e10cSrcweir String aRefValString = refVal->GetString(); 748*cdf0e10cSrcweir 749*cdf0e10cSrcweir sal_uInt16 nPos = 0; 750*cdf0e10cSrcweir sal_uInt16 nVarStrLen = aRefVarString.Len(); 751*cdf0e10cSrcweir if( nVarStrLen > aRefValString.Len() ) 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir aRefVarString.Fill(nVarStrLen,' '); 754*cdf0e10cSrcweir nPos = nVarStrLen - aRefValString.Len(); 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir aRefVarString = aRefVarString.Copy( 0, nPos ); 757*cdf0e10cSrcweir aRefVarString += aRefValString.Copy( 0, nVarStrLen - nPos ); 758*cdf0e10cSrcweir refVar->PutString(aRefVarString); 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir refVar->SetFlags( n ); 761*cdf0e10cSrcweir } 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir // Ablage von TOS in TOS-1, dann ReadOnly-Bit setzen 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir void SbiRuntime::StepPUTC() 767*cdf0e10cSrcweir { 768*cdf0e10cSrcweir SbxVariableRef refVal = PopVar(); 769*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 770*cdf0e10cSrcweir refVar->SetFlag( SBX_WRITE ); 771*cdf0e10cSrcweir *refVar = *refVal; 772*cdf0e10cSrcweir refVar->ResetFlag( SBX_WRITE ); 773*cdf0e10cSrcweir refVar->SetFlag( SBX_CONST ); 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir // DIM 777*cdf0e10cSrcweir // TOS = Variable fuer das Array mit Dimensionsangaben als Parameter 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir void SbiRuntime::StepDIM() 780*cdf0e10cSrcweir { 781*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 782*cdf0e10cSrcweir DimImpl( refVar ); 783*cdf0e10cSrcweir } 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir // #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx) 786*cdf0e10cSrcweir void SbiRuntime::DimImpl( SbxVariableRef refVar ) 787*cdf0e10cSrcweir { 788*cdf0e10cSrcweir SbxArray* pDims = refVar->GetParameters(); 789*cdf0e10cSrcweir // Muss eine gerade Anzahl Argumente haben 790*cdf0e10cSrcweir // Man denke daran, dass Arg[0] nicht zaehlt! 791*cdf0e10cSrcweir if( pDims && !( pDims->Count() & 1 ) ) 792*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 793*cdf0e10cSrcweir else 794*cdf0e10cSrcweir { 795*cdf0e10cSrcweir SbxDataType eType = refVar->IsFixed() ? refVar->GetType() : SbxVARIANT; 796*cdf0e10cSrcweir SbxDimArray* pArray = new SbxDimArray( eType ); 797*cdf0e10cSrcweir // AB 2.4.1996, auch Arrays ohne Dimensionsangaben zulassen (VB-komp.) 798*cdf0e10cSrcweir if( pDims ) 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir refVar->ResetFlag( SBX_VAR_TO_DIM ); 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir for( sal_uInt16 i = 1; i < pDims->Count(); ) 803*cdf0e10cSrcweir { 804*cdf0e10cSrcweir sal_Int32 lb = pDims->Get( i++ )->GetLong(); 805*cdf0e10cSrcweir sal_Int32 ub = pDims->Get( i++ )->GetLong(); 806*cdf0e10cSrcweir if( ub < lb ) 807*cdf0e10cSrcweir Error( SbERR_OUT_OF_RANGE ), ub = lb; 808*cdf0e10cSrcweir pArray->AddDim32( lb, ub ); 809*cdf0e10cSrcweir if ( lb != ub ) 810*cdf0e10cSrcweir pArray->setHasFixedSize( true ); 811*cdf0e10cSrcweir } 812*cdf0e10cSrcweir } 813*cdf0e10cSrcweir else 814*cdf0e10cSrcweir { 815*cdf0e10cSrcweir // #62867 Beim Anlegen eines Arrays der Laenge 0 wie bei 816*cdf0e10cSrcweir // Uno-Sequences der Laenge 0 eine Dimension anlegen 817*cdf0e10cSrcweir pArray->unoAddDim( 0, -1 ); 818*cdf0e10cSrcweir } 819*cdf0e10cSrcweir sal_uInt16 nSavFlags = refVar->GetFlags(); 820*cdf0e10cSrcweir refVar->ResetFlag( SBX_FIXED ); 821*cdf0e10cSrcweir refVar->PutObject( pArray ); 822*cdf0e10cSrcweir refVar->SetFlags( nSavFlags ); 823*cdf0e10cSrcweir refVar->SetParameters( NULL ); 824*cdf0e10cSrcweir } 825*cdf0e10cSrcweir } 826*cdf0e10cSrcweir 827*cdf0e10cSrcweir // REDIM 828*cdf0e10cSrcweir // TOS = Variable fuer das Array 829*cdf0e10cSrcweir // argv = Dimensionsangaben 830*cdf0e10cSrcweir 831*cdf0e10cSrcweir void SbiRuntime::StepREDIM() 832*cdf0e10cSrcweir { 833*cdf0e10cSrcweir // Im Moment ist es nichts anderes als Dim, da doppeltes Dim 834*cdf0e10cSrcweir // bereits vom Compiler erkannt wird. 835*cdf0e10cSrcweir StepDIM(); 836*cdf0e10cSrcweir } 837*cdf0e10cSrcweir 838*cdf0e10cSrcweir 839*cdf0e10cSrcweir // Helper function for StepREDIMP 840*cdf0e10cSrcweir void implCopyDimArray( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex, 841*cdf0e10cSrcweir short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir sal_Int32& ri = pActualIndices[nActualDim]; 844*cdf0e10cSrcweir for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ ) 845*cdf0e10cSrcweir { 846*cdf0e10cSrcweir if( nActualDim < nMaxDimIndex ) 847*cdf0e10cSrcweir { 848*cdf0e10cSrcweir implCopyDimArray( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1, 849*cdf0e10cSrcweir pActualIndices, pLowerBounds, pUpperBounds ); 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir else 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir SbxVariable* pSource = pOldArray->Get32( pActualIndices ); 854*cdf0e10cSrcweir SbxVariable* pDest = pNewArray->Get32( pActualIndices ); 855*cdf0e10cSrcweir if( pSource && pDest ) 856*cdf0e10cSrcweir *pDest = *pSource; 857*cdf0e10cSrcweir } 858*cdf0e10cSrcweir } 859*cdf0e10cSrcweir } 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir // REDIM PRESERVE 862*cdf0e10cSrcweir // TOS = Variable fuer das Array 863*cdf0e10cSrcweir // argv = Dimensionsangaben 864*cdf0e10cSrcweir 865*cdf0e10cSrcweir void SbiRuntime::StepREDIMP() 866*cdf0e10cSrcweir { 867*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 868*cdf0e10cSrcweir DimImpl( refVar ); 869*cdf0e10cSrcweir 870*cdf0e10cSrcweir // Now check, if we can copy from the old array 871*cdf0e10cSrcweir if( refRedimpArray.Is() ) 872*cdf0e10cSrcweir { 873*cdf0e10cSrcweir SbxBase* pElemObj = refVar->GetObject(); 874*cdf0e10cSrcweir SbxDimArray* pNewArray = PTR_CAST(SbxDimArray,pElemObj); 875*cdf0e10cSrcweir SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray; 876*cdf0e10cSrcweir if( pNewArray ) 877*cdf0e10cSrcweir { 878*cdf0e10cSrcweir short nDimsNew = pNewArray->GetDims(); 879*cdf0e10cSrcweir short nDimsOld = pOldArray->GetDims(); 880*cdf0e10cSrcweir short nDims = nDimsNew; 881*cdf0e10cSrcweir sal_Bool bRangeError = sal_False; 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir // Store dims to use them for copying later 884*cdf0e10cSrcweir sal_Int32* pLowerBounds = new sal_Int32[nDims]; 885*cdf0e10cSrcweir sal_Int32* pUpperBounds = new sal_Int32[nDims]; 886*cdf0e10cSrcweir sal_Int32* pActualIndices = new sal_Int32[nDims]; 887*cdf0e10cSrcweir 888*cdf0e10cSrcweir if( nDimsOld != nDimsNew ) 889*cdf0e10cSrcweir { 890*cdf0e10cSrcweir bRangeError = sal_True; 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir else 893*cdf0e10cSrcweir { 894*cdf0e10cSrcweir // Compare bounds 895*cdf0e10cSrcweir for( short i = 1 ; i <= nDims ; i++ ) 896*cdf0e10cSrcweir { 897*cdf0e10cSrcweir sal_Int32 lBoundNew, uBoundNew; 898*cdf0e10cSrcweir sal_Int32 lBoundOld, uBoundOld; 899*cdf0e10cSrcweir pNewArray->GetDim32( i, lBoundNew, uBoundNew ); 900*cdf0e10cSrcweir pOldArray->GetDim32( i, lBoundOld, uBoundOld ); 901*cdf0e10cSrcweir 902*cdf0e10cSrcweir /* #69094 Allow all dimensions to be changed 903*cdf0e10cSrcweir although Visual Basic is not able to do so. 904*cdf0e10cSrcweir // All bounds but the last have to be the same 905*cdf0e10cSrcweir if( i < nDims && ( lBoundNew != lBoundOld || uBoundNew != uBoundOld ) ) 906*cdf0e10cSrcweir { 907*cdf0e10cSrcweir bRangeError = sal_True; 908*cdf0e10cSrcweir break; 909*cdf0e10cSrcweir } 910*cdf0e10cSrcweir else 911*cdf0e10cSrcweir */ 912*cdf0e10cSrcweir { 913*cdf0e10cSrcweir // #69094: if( i == nDims ) 914*cdf0e10cSrcweir { 915*cdf0e10cSrcweir lBoundNew = std::max( lBoundNew, lBoundOld ); 916*cdf0e10cSrcweir uBoundNew = std::min( uBoundNew, uBoundOld ); 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir short j = i - 1; 919*cdf0e10cSrcweir pActualIndices[j] = pLowerBounds[j] = lBoundNew; 920*cdf0e10cSrcweir pUpperBounds[j] = uBoundNew; 921*cdf0e10cSrcweir } 922*cdf0e10cSrcweir } 923*cdf0e10cSrcweir } 924*cdf0e10cSrcweir 925*cdf0e10cSrcweir if( bRangeError ) 926*cdf0e10cSrcweir { 927*cdf0e10cSrcweir StarBASIC::Error( SbERR_OUT_OF_RANGE ); 928*cdf0e10cSrcweir } 929*cdf0e10cSrcweir else 930*cdf0e10cSrcweir { 931*cdf0e10cSrcweir // Copy data from old array by going recursively through all dimensions 932*cdf0e10cSrcweir // (It would be faster to work on the flat internal data array of an 933*cdf0e10cSrcweir // SbyArray but this solution is clearer and easier) 934*cdf0e10cSrcweir implCopyDimArray( pNewArray, pOldArray, nDims - 1, 935*cdf0e10cSrcweir 0, pActualIndices, pLowerBounds, pUpperBounds ); 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir delete[] pUpperBounds; 939*cdf0e10cSrcweir delete[] pLowerBounds; 940*cdf0e10cSrcweir delete[] pActualIndices; 941*cdf0e10cSrcweir refRedimpArray = NULL; 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir } 944*cdf0e10cSrcweir 945*cdf0e10cSrcweir //StarBASIC::FatalError( SbERR_NOT_IMPLEMENTED ); 946*cdf0e10cSrcweir } 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir // REDIM_COPY 949*cdf0e10cSrcweir // TOS = Array-Variable, Reference to array is copied 950*cdf0e10cSrcweir // Variable is cleared as in ERASE 951*cdf0e10cSrcweir 952*cdf0e10cSrcweir void SbiRuntime::StepREDIMP_ERASE() 953*cdf0e10cSrcweir { 954*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 955*cdf0e10cSrcweir SbxDataType eType = refVar->GetType(); 956*cdf0e10cSrcweir if( eType & SbxARRAY ) 957*cdf0e10cSrcweir { 958*cdf0e10cSrcweir SbxBase* pElemObj = refVar->GetObject(); 959*cdf0e10cSrcweir SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); 960*cdf0e10cSrcweir if( pDimArray ) 961*cdf0e10cSrcweir { 962*cdf0e10cSrcweir refRedimpArray = pDimArray; 963*cdf0e10cSrcweir } 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir // As in ERASE 966*cdf0e10cSrcweir sal_uInt16 nSavFlags = refVar->GetFlags(); 967*cdf0e10cSrcweir refVar->ResetFlag( SBX_FIXED ); 968*cdf0e10cSrcweir refVar->SetType( SbxDataType(eType & 0x0FFF) ); 969*cdf0e10cSrcweir refVar->SetFlags( nSavFlags ); 970*cdf0e10cSrcweir refVar->Clear(); 971*cdf0e10cSrcweir } 972*cdf0e10cSrcweir else 973*cdf0e10cSrcweir if( refVar->IsFixed() ) 974*cdf0e10cSrcweir refVar->Clear(); 975*cdf0e10cSrcweir else 976*cdf0e10cSrcweir refVar->SetType( SbxEMPTY ); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir 979*cdf0e10cSrcweir void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType ) 980*cdf0e10cSrcweir { 981*cdf0e10cSrcweir sal_uInt16 nSavFlags = refVar->GetFlags(); 982*cdf0e10cSrcweir refVar->ResetFlag( SBX_FIXED ); 983*cdf0e10cSrcweir refVar->SetType( SbxDataType(eType & 0x0FFF) ); 984*cdf0e10cSrcweir refVar->SetFlags( nSavFlags ); 985*cdf0e10cSrcweir refVar->Clear(); 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled ) 989*cdf0e10cSrcweir { 990*cdf0e10cSrcweir SbxDataType eType = refVar->GetType(); 991*cdf0e10cSrcweir if( eType & SbxARRAY ) 992*cdf0e10cSrcweir { 993*cdf0e10cSrcweir if ( bVBAEnabled ) 994*cdf0e10cSrcweir { 995*cdf0e10cSrcweir SbxBase* pElemObj = refVar->GetObject(); 996*cdf0e10cSrcweir SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); 997*cdf0e10cSrcweir bool bClearValues = true; 998*cdf0e10cSrcweir if( pDimArray ) 999*cdf0e10cSrcweir { 1000*cdf0e10cSrcweir if ( pDimArray->hasFixedSize() ) 1001*cdf0e10cSrcweir { 1002*cdf0e10cSrcweir // Clear all Value(s) 1003*cdf0e10cSrcweir pDimArray->SbxArray::Clear(); 1004*cdf0e10cSrcweir bClearValues = false; 1005*cdf0e10cSrcweir } 1006*cdf0e10cSrcweir else 1007*cdf0e10cSrcweir pDimArray->Clear(); // clear Dims 1008*cdf0e10cSrcweir } 1009*cdf0e10cSrcweir if ( bClearValues ) 1010*cdf0e10cSrcweir { 1011*cdf0e10cSrcweir SbxArray* pArray = PTR_CAST(SbxArray,pElemObj); 1012*cdf0e10cSrcweir if ( pArray ) 1013*cdf0e10cSrcweir pArray->Clear(); 1014*cdf0e10cSrcweir } 1015*cdf0e10cSrcweir } 1016*cdf0e10cSrcweir else 1017*cdf0e10cSrcweir // AB 2.4.1996 1018*cdf0e10cSrcweir // Arrays haben bei Erase nach VB ein recht komplexes Verhalten. Hier 1019*cdf0e10cSrcweir // werden zunaechst nur die Typ-Probleme bei REDIM (#26295) beseitigt: 1020*cdf0e10cSrcweir // Typ hart auf den Array-Typ setzen, da eine Variable mit Array 1021*cdf0e10cSrcweir // SbxOBJECT ist. Bei REDIM entsteht dann ein SbxOBJECT-Array und 1022*cdf0e10cSrcweir // der ursruengliche Typ geht verloren -> Laufzeitfehler 1023*cdf0e10cSrcweir lcl_clearImpl( refVar, eType ); 1024*cdf0e10cSrcweir } 1025*cdf0e10cSrcweir else 1026*cdf0e10cSrcweir if( refVar->IsFixed() ) 1027*cdf0e10cSrcweir refVar->Clear(); 1028*cdf0e10cSrcweir else 1029*cdf0e10cSrcweir refVar->SetType( SbxEMPTY ); 1030*cdf0e10cSrcweir } 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir // Variable loeschen 1033*cdf0e10cSrcweir // TOS = Variable 1034*cdf0e10cSrcweir 1035*cdf0e10cSrcweir void SbiRuntime::StepERASE() 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 1038*cdf0e10cSrcweir lcl_eraseImpl( refVar, bVBAEnabled ); 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir void SbiRuntime::StepERASE_CLEAR() 1042*cdf0e10cSrcweir { 1043*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 1044*cdf0e10cSrcweir lcl_eraseImpl( refVar, bVBAEnabled ); 1045*cdf0e10cSrcweir SbxDataType eType = refVar->GetType(); 1046*cdf0e10cSrcweir lcl_clearImpl( refVar, eType ); 1047*cdf0e10cSrcweir } 1048*cdf0e10cSrcweir 1049*cdf0e10cSrcweir void SbiRuntime::StepARRAYACCESS() 1050*cdf0e10cSrcweir { 1051*cdf0e10cSrcweir if( !refArgv ) 1052*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 1053*cdf0e10cSrcweir SbxVariableRef refVar = PopVar(); 1054*cdf0e10cSrcweir refVar->SetParameters( refArgv ); 1055*cdf0e10cSrcweir PopArgv(); 1056*cdf0e10cSrcweir PushVar( CheckArray( refVar ) ); 1057*cdf0e10cSrcweir } 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir void SbiRuntime::StepBYVAL() 1060*cdf0e10cSrcweir { 1061*cdf0e10cSrcweir // Copy variable on stack to break call by reference 1062*cdf0e10cSrcweir SbxVariableRef pVar = PopVar(); 1063*cdf0e10cSrcweir SbxDataType t = pVar->GetType(); 1064*cdf0e10cSrcweir 1065*cdf0e10cSrcweir SbxVariable* pCopyVar = new SbxVariable( t ); 1066*cdf0e10cSrcweir pCopyVar->SetFlag( SBX_READWRITE ); 1067*cdf0e10cSrcweir *pCopyVar = *pVar; 1068*cdf0e10cSrcweir 1069*cdf0e10cSrcweir PushVar( pCopyVar ); 1070*cdf0e10cSrcweir } 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweir // Einrichten eines Argvs 1073*cdf0e10cSrcweir // nOp1 bleibt so -> 1. Element ist Returnwert 1074*cdf0e10cSrcweir 1075*cdf0e10cSrcweir void SbiRuntime::StepARGC() 1076*cdf0e10cSrcweir { 1077*cdf0e10cSrcweir PushArgv(); 1078*cdf0e10cSrcweir refArgv = new SbxArray; 1079*cdf0e10cSrcweir nArgc = 1; 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir // Speichern eines Arguments in Argv 1083*cdf0e10cSrcweir 1084*cdf0e10cSrcweir void SbiRuntime::StepARGV() 1085*cdf0e10cSrcweir { 1086*cdf0e10cSrcweir if( !refArgv ) 1087*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 1088*cdf0e10cSrcweir else 1089*cdf0e10cSrcweir { 1090*cdf0e10cSrcweir SbxVariableRef pVal = PopVar(); 1091*cdf0e10cSrcweir 1092*cdf0e10cSrcweir // Before fix of #94916: 1093*cdf0e10cSrcweir // if( pVal->ISA(SbxMethod) || pVal->ISA(SbxProperty) ) 1094*cdf0e10cSrcweir if( pVal->ISA(SbxMethod) || pVal->ISA(SbUnoProperty) || pVal->ISA(SbProcedureProperty) ) 1095*cdf0e10cSrcweir { 1096*cdf0e10cSrcweir // Methoden und Properties evaluieren! 1097*cdf0e10cSrcweir SbxVariable* pRes = new SbxVariable( *pVal ); 1098*cdf0e10cSrcweir pVal = pRes; 1099*cdf0e10cSrcweir } 1100*cdf0e10cSrcweir refArgv->Put( pVal, nArgc++ ); 1101*cdf0e10cSrcweir } 1102*cdf0e10cSrcweir } 1103*cdf0e10cSrcweir 1104*cdf0e10cSrcweir // Input to Variable. Die Variable ist auf TOS und wird 1105*cdf0e10cSrcweir // anschliessend entfernt. 1106*cdf0e10cSrcweir 1107*cdf0e10cSrcweir void SbiRuntime::StepINPUT() 1108*cdf0e10cSrcweir { 1109*cdf0e10cSrcweir String s; 1110*cdf0e10cSrcweir char ch = 0; 1111*cdf0e10cSrcweir SbError err; 1112*cdf0e10cSrcweir // Skip whitespace 1113*cdf0e10cSrcweir while( ( err = pIosys->GetError() ) == 0 ) 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir ch = pIosys->Read(); 1116*cdf0e10cSrcweir if( ch != ' ' && ch != '\t' && ch != '\n' ) 1117*cdf0e10cSrcweir break; 1118*cdf0e10cSrcweir } 1119*cdf0e10cSrcweir if( !err ) 1120*cdf0e10cSrcweir { 1121*cdf0e10cSrcweir // Scan until comma or whitespace 1122*cdf0e10cSrcweir char sep = ( ch == '"' ) ? ch : 0; 1123*cdf0e10cSrcweir if( sep ) ch = pIosys->Read(); 1124*cdf0e10cSrcweir while( ( err = pIosys->GetError() ) == 0 ) 1125*cdf0e10cSrcweir { 1126*cdf0e10cSrcweir if( ch == sep ) 1127*cdf0e10cSrcweir { 1128*cdf0e10cSrcweir ch = pIosys->Read(); 1129*cdf0e10cSrcweir if( ch != sep ) 1130*cdf0e10cSrcweir break; 1131*cdf0e10cSrcweir } 1132*cdf0e10cSrcweir else if( !sep && (ch == ',' || ch == '\n') ) 1133*cdf0e10cSrcweir break; 1134*cdf0e10cSrcweir s += ch; 1135*cdf0e10cSrcweir ch = pIosys->Read(); 1136*cdf0e10cSrcweir } 1137*cdf0e10cSrcweir // skip whitespace 1138*cdf0e10cSrcweir if( ch == ' ' || ch == '\t' ) 1139*cdf0e10cSrcweir while( ( err = pIosys->GetError() ) == 0 ) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir if( ch != ' ' && ch != '\t' && ch != '\n' ) 1142*cdf0e10cSrcweir break; 1143*cdf0e10cSrcweir ch = pIosys->Read(); 1144*cdf0e10cSrcweir } 1145*cdf0e10cSrcweir } 1146*cdf0e10cSrcweir if( !err ) 1147*cdf0e10cSrcweir { 1148*cdf0e10cSrcweir SbxVariableRef pVar = GetTOS(); 1149*cdf0e10cSrcweir // Zuerst versuchen, die Variable mit einem numerischen Wert 1150*cdf0e10cSrcweir // zu fuellen, dann mit einem Stringwert 1151*cdf0e10cSrcweir if( !pVar->IsFixed() || pVar->IsNumeric() ) 1152*cdf0e10cSrcweir { 1153*cdf0e10cSrcweir sal_uInt16 nLen = 0; 1154*cdf0e10cSrcweir if( !pVar->Scan( s, &nLen ) ) 1155*cdf0e10cSrcweir { 1156*cdf0e10cSrcweir err = SbxBase::GetError(); 1157*cdf0e10cSrcweir SbxBase::ResetError(); 1158*cdf0e10cSrcweir } 1159*cdf0e10cSrcweir // Der Wert muss komplett eingescant werden 1160*cdf0e10cSrcweir else if( nLen != s.Len() && !pVar->PutString( s ) ) 1161*cdf0e10cSrcweir { 1162*cdf0e10cSrcweir err = SbxBase::GetError(); 1163*cdf0e10cSrcweir SbxBase::ResetError(); 1164*cdf0e10cSrcweir } 1165*cdf0e10cSrcweir else if( nLen != s.Len() && pVar->IsNumeric() ) 1166*cdf0e10cSrcweir { 1167*cdf0e10cSrcweir err = SbxBase::GetError(); 1168*cdf0e10cSrcweir SbxBase::ResetError(); 1169*cdf0e10cSrcweir if( !err ) 1170*cdf0e10cSrcweir err = SbERR_CONVERSION; 1171*cdf0e10cSrcweir } 1172*cdf0e10cSrcweir } 1173*cdf0e10cSrcweir else 1174*cdf0e10cSrcweir { 1175*cdf0e10cSrcweir pVar->PutString( s ); 1176*cdf0e10cSrcweir err = SbxBase::GetError(); 1177*cdf0e10cSrcweir SbxBase::ResetError(); 1178*cdf0e10cSrcweir } 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir if( err == SbERR_USER_ABORT ) 1181*cdf0e10cSrcweir Error( err ); 1182*cdf0e10cSrcweir else if( err ) 1183*cdf0e10cSrcweir { 1184*cdf0e10cSrcweir if( pRestart && !pIosys->GetChannel() ) 1185*cdf0e10cSrcweir { 1186*cdf0e10cSrcweir BasResId aId( IDS_SBERR_START + 4 ); 1187*cdf0e10cSrcweir String aMsg( aId ); 1188*cdf0e10cSrcweir 1189*cdf0e10cSrcweir //****** DONT CHECK IN, TEST ONLY ******* 1190*cdf0e10cSrcweir //****** DONT CHECK IN, TEST ONLY ******* 1191*cdf0e10cSrcweir // ErrorBox( NULL, WB_OK, aMsg ).Execute(); 1192*cdf0e10cSrcweir //****** DONT CHECK IN, TEST ONLY ******* 1193*cdf0e10cSrcweir //****** DONT CHECK IN, TEST ONLY ******* 1194*cdf0e10cSrcweir 1195*cdf0e10cSrcweir pCode = pRestart; 1196*cdf0e10cSrcweir } 1197*cdf0e10cSrcweir else 1198*cdf0e10cSrcweir Error( err ); 1199*cdf0e10cSrcweir } 1200*cdf0e10cSrcweir else 1201*cdf0e10cSrcweir { 1202*cdf0e10cSrcweir // pIosys->ResetChannel(); 1203*cdf0e10cSrcweir PopVar(); 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir } 1206*cdf0e10cSrcweir 1207*cdf0e10cSrcweir // Line Input to Variable. Die Variable ist auf TOS und wird 1208*cdf0e10cSrcweir // anschliessend entfernt. 1209*cdf0e10cSrcweir 1210*cdf0e10cSrcweir void SbiRuntime::StepLINPUT() 1211*cdf0e10cSrcweir { 1212*cdf0e10cSrcweir ByteString aInput; 1213*cdf0e10cSrcweir pIosys->Read( aInput ); 1214*cdf0e10cSrcweir Error( pIosys->GetError() ); 1215*cdf0e10cSrcweir SbxVariableRef p = PopVar(); 1216*cdf0e10cSrcweir p->PutString( String( aInput, gsl_getSystemTextEncoding() ) ); 1217*cdf0e10cSrcweir // pIosys->ResetChannel(); 1218*cdf0e10cSrcweir } 1219*cdf0e10cSrcweir 1220*cdf0e10cSrcweir // Programmende 1221*cdf0e10cSrcweir 1222*cdf0e10cSrcweir void SbiRuntime::StepSTOP() 1223*cdf0e10cSrcweir { 1224*cdf0e10cSrcweir pInst->Stop(); 1225*cdf0e10cSrcweir } 1226*cdf0e10cSrcweir 1227*cdf0e10cSrcweir // FOR-Variable initialisieren 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir void SbiRuntime::StepINITFOR() 1230*cdf0e10cSrcweir { 1231*cdf0e10cSrcweir PushFor(); 1232*cdf0e10cSrcweir } 1233*cdf0e10cSrcweir 1234*cdf0e10cSrcweir void SbiRuntime::StepINITFOREACH() 1235*cdf0e10cSrcweir { 1236*cdf0e10cSrcweir PushForEach(); 1237*cdf0e10cSrcweir } 1238*cdf0e10cSrcweir 1239*cdf0e10cSrcweir // FOR-Variable inkrementieren 1240*cdf0e10cSrcweir 1241*cdf0e10cSrcweir void SbiRuntime::StepNEXT() 1242*cdf0e10cSrcweir { 1243*cdf0e10cSrcweir if( !pForStk ) 1244*cdf0e10cSrcweir { 1245*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 1246*cdf0e10cSrcweir return; 1247*cdf0e10cSrcweir } 1248*cdf0e10cSrcweir if( pForStk->eForType == FOR_TO ) 1249*cdf0e10cSrcweir pForStk->refVar->Compute( SbxPLUS, *pForStk->refInc ); 1250*cdf0e10cSrcweir } 1251*cdf0e10cSrcweir 1252*cdf0e10cSrcweir // Anfang CASE: TOS in CASE-Stack 1253*cdf0e10cSrcweir 1254*cdf0e10cSrcweir void SbiRuntime::StepCASE() 1255*cdf0e10cSrcweir { 1256*cdf0e10cSrcweir if( !refCaseStk.Is() ) 1257*cdf0e10cSrcweir refCaseStk = new SbxArray; 1258*cdf0e10cSrcweir SbxVariableRef xVar = PopVar(); 1259*cdf0e10cSrcweir refCaseStk->Put( xVar, refCaseStk->Count() ); 1260*cdf0e10cSrcweir } 1261*cdf0e10cSrcweir 1262*cdf0e10cSrcweir // Ende CASE: Variable freigeben 1263*cdf0e10cSrcweir 1264*cdf0e10cSrcweir void SbiRuntime::StepENDCASE() 1265*cdf0e10cSrcweir { 1266*cdf0e10cSrcweir if( !refCaseStk || !refCaseStk->Count() ) 1267*cdf0e10cSrcweir StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); 1268*cdf0e10cSrcweir else 1269*cdf0e10cSrcweir refCaseStk->Remove( refCaseStk->Count() - 1 ); 1270*cdf0e10cSrcweir } 1271*cdf0e10cSrcweir 1272*cdf0e10cSrcweir // Standard-Fehlerbehandlung 1273*cdf0e10cSrcweir 1274*cdf0e10cSrcweir void SbiRuntime::StepSTDERROR() 1275*cdf0e10cSrcweir { 1276*cdf0e10cSrcweir pError = NULL; bError = sal_True; 1277*cdf0e10cSrcweir pInst->aErrorMsg = String(); 1278*cdf0e10cSrcweir pInst->nErr = 0L; 1279*cdf0e10cSrcweir pInst->nErl = 0; 1280*cdf0e10cSrcweir nError = 0L; 1281*cdf0e10cSrcweir SbxErrObject::getUnoErrObject()->Clear(); 1282*cdf0e10cSrcweir } 1283*cdf0e10cSrcweir 1284*cdf0e10cSrcweir void SbiRuntime::StepNOERROR() 1285*cdf0e10cSrcweir { 1286*cdf0e10cSrcweir pInst->aErrorMsg = String(); 1287*cdf0e10cSrcweir pInst->nErr = 0L; 1288*cdf0e10cSrcweir pInst->nErl = 0; 1289*cdf0e10cSrcweir nError = 0L; 1290*cdf0e10cSrcweir SbxErrObject::getUnoErrObject()->Clear(); 1291*cdf0e10cSrcweir bError = sal_False; 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir 1294*cdf0e10cSrcweir // UP verlassen 1295*cdf0e10cSrcweir 1296*cdf0e10cSrcweir void SbiRuntime::StepLEAVE() 1297*cdf0e10cSrcweir { 1298*cdf0e10cSrcweir bRun = sal_False; 1299*cdf0e10cSrcweir // If VBA and we are leaving an ErrorHandler then clear the error ( it's been processed ) 1300*cdf0e10cSrcweir if ( bInError && pError ) 1301*cdf0e10cSrcweir SbxErrObject::getUnoErrObject()->Clear(); 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir void SbiRuntime::StepCHANNEL() // TOS = Kanalnummer 1305*cdf0e10cSrcweir { 1306*cdf0e10cSrcweir SbxVariableRef pChan = PopVar(); 1307*cdf0e10cSrcweir short nChan = pChan->GetInteger(); 1308*cdf0e10cSrcweir pIosys->SetChannel( nChan ); 1309*cdf0e10cSrcweir Error( pIosys->GetError() ); 1310*cdf0e10cSrcweir } 1311*cdf0e10cSrcweir 1312*cdf0e10cSrcweir void SbiRuntime::StepCHANNEL0() 1313*cdf0e10cSrcweir { 1314*cdf0e10cSrcweir pIosys->ResetChannel(); 1315*cdf0e10cSrcweir } 1316*cdf0e10cSrcweir 1317*cdf0e10cSrcweir void SbiRuntime::StepPRINT() // print TOS 1318*cdf0e10cSrcweir { 1319*cdf0e10cSrcweir SbxVariableRef p = PopVar(); 1320*cdf0e10cSrcweir String s1 = p->GetString(); 1321*cdf0e10cSrcweir String s; 1322*cdf0e10cSrcweir if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE ) 1323*cdf0e10cSrcweir s = ' '; // ein Blank davor 1324*cdf0e10cSrcweir s += s1; 1325*cdf0e10cSrcweir ByteString aByteStr( s, gsl_getSystemTextEncoding() ); 1326*cdf0e10cSrcweir pIosys->Write( aByteStr ); 1327*cdf0e10cSrcweir Error( pIosys->GetError() ); 1328*cdf0e10cSrcweir } 1329*cdf0e10cSrcweir 1330*cdf0e10cSrcweir void SbiRuntime::StepPRINTF() // print TOS in field 1331*cdf0e10cSrcweir { 1332*cdf0e10cSrcweir SbxVariableRef p = PopVar(); 1333*cdf0e10cSrcweir String s1 = p->GetString(); 1334*cdf0e10cSrcweir String s; 1335*cdf0e10cSrcweir if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE ) 1336*cdf0e10cSrcweir s = ' '; // ein Blank davor 1337*cdf0e10cSrcweir s += s1; 1338*cdf0e10cSrcweir s.Expand( 14, ' ' ); 1339*cdf0e10cSrcweir ByteString aByteStr( s, gsl_getSystemTextEncoding() ); 1340*cdf0e10cSrcweir pIosys->Write( aByteStr ); 1341*cdf0e10cSrcweir Error( pIosys->GetError() ); 1342*cdf0e10cSrcweir } 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir void SbiRuntime::StepWRITE() // write TOS 1345*cdf0e10cSrcweir { 1346*cdf0e10cSrcweir SbxVariableRef p = PopVar(); 1347*cdf0e10cSrcweir // Muss der String gekapselt werden? 1348*cdf0e10cSrcweir char ch = 0; 1349*cdf0e10cSrcweir switch (p->GetType() ) 1350*cdf0e10cSrcweir { 1351*cdf0e10cSrcweir case SbxSTRING: ch = '"'; break; 1352*cdf0e10cSrcweir case SbxCURRENCY: 1353*cdf0e10cSrcweir case SbxBOOL: 1354*cdf0e10cSrcweir case SbxDATE: ch = '#'; break; 1355*cdf0e10cSrcweir default: break; 1356*cdf0e10cSrcweir } 1357*cdf0e10cSrcweir String s; 1358*cdf0e10cSrcweir if( ch ) 1359*cdf0e10cSrcweir s += ch; 1360*cdf0e10cSrcweir s += p->GetString(); 1361*cdf0e10cSrcweir if( ch ) 1362*cdf0e10cSrcweir s += ch; 1363*cdf0e10cSrcweir ByteString aByteStr( s, gsl_getSystemTextEncoding() ); 1364*cdf0e10cSrcweir pIosys->Write( aByteStr ); 1365*cdf0e10cSrcweir Error( pIosys->GetError() ); 1366*cdf0e10cSrcweir } 1367*cdf0e10cSrcweir 1368*cdf0e10cSrcweir void SbiRuntime::StepRENAME() // Rename Tos+1 to Tos 1369*cdf0e10cSrcweir { 1370*cdf0e10cSrcweir SbxVariableRef pTos1 = PopVar(); 1371*cdf0e10cSrcweir SbxVariableRef pTos = PopVar(); 1372*cdf0e10cSrcweir String aDest = pTos1->GetString(); 1373*cdf0e10cSrcweir String aSource = pTos->GetString(); 1374*cdf0e10cSrcweir 1375*cdf0e10cSrcweir // <-- UCB 1376*cdf0e10cSrcweir if( hasUno() ) 1377*cdf0e10cSrcweir { 1378*cdf0e10cSrcweir implStepRenameUCB( aSource, aDest ); 1379*cdf0e10cSrcweir } 1380*cdf0e10cSrcweir else 1381*cdf0e10cSrcweir // --> UCB 1382*cdf0e10cSrcweir { 1383*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL 1384*cdf0e10cSrcweir DirEntry aSourceDirEntry( aSource ); 1385*cdf0e10cSrcweir if( aSourceDirEntry.Exists() ) 1386*cdf0e10cSrcweir { 1387*cdf0e10cSrcweir if( aSourceDirEntry.MoveTo( DirEntry(aDest) ) != FSYS_ERR_OK ) 1388*cdf0e10cSrcweir StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 1389*cdf0e10cSrcweir } 1390*cdf0e10cSrcweir else 1391*cdf0e10cSrcweir StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 1392*cdf0e10cSrcweir #else 1393*cdf0e10cSrcweir implStepRenameOSL( aSource, aDest ); 1394*cdf0e10cSrcweir #endif 1395*cdf0e10cSrcweir } 1396*cdf0e10cSrcweir } 1397*cdf0e10cSrcweir 1398*cdf0e10cSrcweir // TOS = Prompt 1399*cdf0e10cSrcweir 1400*cdf0e10cSrcweir void SbiRuntime::StepPROMPT() 1401*cdf0e10cSrcweir { 1402*cdf0e10cSrcweir SbxVariableRef p = PopVar(); 1403*cdf0e10cSrcweir ByteString aStr( p->GetString(), gsl_getSystemTextEncoding() ); 1404*cdf0e10cSrcweir pIosys->SetPrompt( aStr ); 1405*cdf0e10cSrcweir } 1406*cdf0e10cSrcweir 1407*cdf0e10cSrcweir // Set Restart point 1408*cdf0e10cSrcweir 1409*cdf0e10cSrcweir void SbiRuntime::StepRESTART() 1410*cdf0e10cSrcweir { 1411*cdf0e10cSrcweir pRestart = pCode; 1412*cdf0e10cSrcweir } 1413*cdf0e10cSrcweir 1414*cdf0e10cSrcweir // Leerer Ausdruck auf Stack fuer fehlenden Parameter 1415*cdf0e10cSrcweir 1416*cdf0e10cSrcweir void SbiRuntime::StepEMPTY() 1417*cdf0e10cSrcweir { 1418*cdf0e10cSrcweir // #57915 Die Semantik von StepEMPTY() ist die Repraesentation eines fehlenden 1419*cdf0e10cSrcweir // Arguments. Dies wird in VB durch ein durch den Wert 448 (SbERR_NAMED_NOT_FOUND) 1420*cdf0e10cSrcweir // vom Typ Error repraesentiert. StepEmpty jetzt muesste besser StepMISSING() 1421*cdf0e10cSrcweir // heissen, aber der Name wird der Einfachkeit halber beibehalten. 1422*cdf0e10cSrcweir SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); 1423*cdf0e10cSrcweir xVar->PutErr( 448 ); 1424*cdf0e10cSrcweir PushVar( xVar ); 1425*cdf0e10cSrcweir // ALT: PushVar( new SbxVariable( SbxEMPTY ) ); 1426*cdf0e10cSrcweir } 1427*cdf0e10cSrcweir 1428*cdf0e10cSrcweir // TOS = Fehlercode 1429*cdf0e10cSrcweir 1430*cdf0e10cSrcweir void SbiRuntime::StepERROR() 1431*cdf0e10cSrcweir { 1432*cdf0e10cSrcweir SbxVariableRef refCode = PopVar(); 1433*cdf0e10cSrcweir sal_uInt16 n = refCode->GetUShort(); 1434*cdf0e10cSrcweir SbError error = StarBASIC::GetSfxFromVBError( n ); 1435*cdf0e10cSrcweir if ( bVBAEnabled ) 1436*cdf0e10cSrcweir pInst->Error( error ); 1437*cdf0e10cSrcweir else 1438*cdf0e10cSrcweir Error( error ); 1439*cdf0e10cSrcweir } 1440*cdf0e10cSrcweir 1441