| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_basic.hxx" |
| #include <vcl/msgbox.hxx> |
| #include <tools/fsys.hxx> |
| |
| #include "errobject.hxx" |
| #include "runtime.hxx" |
| #include "sbintern.hxx" |
| #include "iosys.hxx" |
| #include <sb.hrc> |
| #include <basrid.hxx> |
| #include "sbunoobj.hxx" |
| #include "image.hxx" |
| #include <com/sun/star/uno/Any.hxx> |
| #include <com/sun/star/util/SearchOptions.hdl> |
| #include <vcl/svapp.hxx> |
| #include <unotools/textsearch.hxx> |
| |
| Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType, |
| const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj ); |
| |
| #include <algorithm> |
| #include <hash_map> |
| |
| SbxVariable* getDefaultProp( SbxVariable* pRef ); |
| |
| void SbiRuntime::StepNOP() |
| {} |
| |
| void SbiRuntime::StepArith( SbxOperator eOp ) |
| { |
| SbxVariableRef p1 = PopVar(); |
| TOSMakeTemp(); |
| SbxVariable* p2 = GetTOS(); |
| |
| |
| // This could & should be moved to the MakeTempTOS() method in runtime.cxx |
| // In the code which this is cut'npaste from there is a check for a ref |
| // count != 1 based on which the copy of the SbxVariable is done. |
| // see orig code in MakeTempTOS ( and I'm not sure what the significance, |
| // of that is ) |
| // here we alway seem to have a refcount of 1. Also it seems that |
| // MakeTempTOS is called for other operation, so I hold off for now |
| // until I have a better idea |
| if ( bVBAEnabled |
| && ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT ) |
| ) |
| { |
| SbxVariable* pDflt = getDefaultProp( p2 ); |
| if ( pDflt ) |
| { |
| pDflt->Broadcast( SBX_HINT_DATAWANTED ); |
| // replacing new p2 on stack causes object pointed by |
| // pDft->pParent to be deleted, when p2->Compute() is |
| // called below pParent is accessed ( but its deleted ) |
| // so set it to NULL now |
| pDflt->SetParent( NULL ); |
| p2 = new SbxVariable( *pDflt ); |
| p2->SetFlag( SBX_READWRITE ); |
| refExprStk->Put( p2, nExprLvl - 1 ); |
| } |
| } |
| |
| p2->ResetFlag( SBX_FIXED ); |
| p2->Compute( eOp, *p1 ); |
| |
| checkArithmeticOverflow( p2 ); |
| } |
| |
| void SbiRuntime::StepUnary( SbxOperator eOp ) |
| { |
| TOSMakeTemp(); |
| SbxVariable* p = GetTOS(); |
| p->Compute( eOp, *p ); |
| } |
| |
| void SbiRuntime::StepCompare( SbxOperator eOp ) |
| { |
| SbxVariableRef p1 = PopVar(); |
| SbxVariableRef p2 = PopVar(); |
| |
| // Make sure objects with default params have |
| // values ( and type ) set as appropriate |
| SbxDataType p1Type = p1->GetType(); |
| SbxDataType p2Type = p2->GetType(); |
| if ( p1Type == p2Type ) |
| { |
| if ( p1Type == SbxEMPTY ) |
| { |
| p1->Broadcast( SBX_HINT_DATAWANTED ); |
| p2->Broadcast( SBX_HINT_DATAWANTED ); |
| } |
| // if both sides are an object and have default props |
| // then we need to use the default props |
| // we don't need to worry if only one side ( lhs, rhs ) is an |
| // object ( object side will get coerced to correct type in |
| // Compare ) |
| else if ( p1Type == SbxOBJECT ) |
| { |
| SbxVariable* pDflt = getDefaultProp( p1 ); |
| if ( pDflt ) |
| { |
| p1 = pDflt; |
| p1->Broadcast( SBX_HINT_DATAWANTED ); |
| } |
| pDflt = getDefaultProp( p2 ); |
| if ( pDflt ) |
| { |
| p2 = pDflt; |
| p2->Broadcast( SBX_HINT_DATAWANTED ); |
| } |
| } |
| |
| } |
| static SbxVariable* pTRUE = NULL; |
| static SbxVariable* pFALSE = NULL; |
| |
| if( p2->Compare( eOp, *p1 ) ) |
| { |
| if( !pTRUE ) |
| { |
| pTRUE = new SbxVariable; |
| pTRUE->PutBool( sal_True ); |
| pTRUE->AddRef(); |
| } |
| PushVar( pTRUE ); |
| } |
| else |
| { |
| if( !pFALSE ) |
| { |
| pFALSE = new SbxVariable; |
| pFALSE->PutBool( sal_False ); |
| pFALSE->AddRef(); |
| } |
| PushVar( pFALSE ); |
| } |
| } |
| |
| void SbiRuntime::StepEXP() { StepArith( SbxEXP ); } |
| void SbiRuntime::StepMUL() { StepArith( SbxMUL ); } |
| void SbiRuntime::StepDIV() { StepArith( SbxDIV ); } |
| void SbiRuntime::StepIDIV() { StepArith( SbxIDIV ); } |
| void SbiRuntime::StepMOD() { StepArith( SbxMOD ); } |
| void SbiRuntime::StepPLUS() { StepArith( SbxPLUS ); } |
| void SbiRuntime::StepMINUS() { StepArith( SbxMINUS ); } |
| void SbiRuntime::StepCAT() { StepArith( SbxCAT ); } |
| void SbiRuntime::StepAND() { StepArith( SbxAND ); } |
| void SbiRuntime::StepOR() { StepArith( SbxOR ); } |
| void SbiRuntime::StepXOR() { StepArith( SbxXOR ); } |
| void SbiRuntime::StepEQV() { StepArith( SbxEQV ); } |
| void SbiRuntime::StepIMP() { StepArith( SbxIMP ); } |
| |
| void SbiRuntime::StepNEG() { StepUnary( SbxNEG ); } |
| void SbiRuntime::StepNOT() { StepUnary( SbxNOT ); } |
| |
| void SbiRuntime::StepEQ() { StepCompare( SbxEQ ); } |
| void SbiRuntime::StepNE() { StepCompare( SbxNE ); } |
| void SbiRuntime::StepLT() { StepCompare( SbxLT ); } |
| void SbiRuntime::StepGT() { StepCompare( SbxGT ); } |
| void SbiRuntime::StepLE() { StepCompare( SbxLE ); } |
| void SbiRuntime::StepGE() { StepCompare( SbxGE ); } |
| |
| namespace |
| { |
| bool NeedEsc(sal_Unicode cCode) |
| { |
| String sEsc(RTL_CONSTASCII_USTRINGPARAM(".^$+\\|{}()")); |
| return (STRING_NOTFOUND != sEsc.Search(cCode)); |
| } |
| |
| String VBALikeToRegexp(const String &rIn) |
| { |
| String sResult; |
| const sal_Unicode *start = rIn.GetBuffer(); |
| const sal_Unicode *end = start + rIn.Len(); |
| |
| int seenright = 0; |
| |
| sResult.Append('^'); |
| |
| while (start < end) |
| { |
| switch (*start) |
| { |
| case '?': |
| sResult.Append('.'); |
| start++; |
| break; |
| case '*': |
| sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM(".*"))); |
| start++; |
| break; |
| case '#': |
| sResult.Append(String(RTL_CONSTASCII_USTRINGPARAM("[0-9]"))); |
| start++; |
| break; |
| case ']': |
| sResult.Append('\\'); |
| sResult.Append(*start++); |
| break; |
| case '[': |
| sResult.Append(*start++); |
| seenright = 0; |
| while (start < end && !seenright) |
| { |
| switch (*start) |
| { |
| case '[': |
| case '?': |
| case '*': |
| sResult.Append('\\'); |
| sResult.Append(*start); |
| break; |
| case ']': |
| sResult.Append(*start); |
| seenright = 1; |
| break; |
| case '!': |
| sResult.Append('^'); |
| break; |
| default: |
| if (NeedEsc(*start)) |
| sResult.Append('\\'); |
| sResult.Append(*start); |
| break; |
| } |
| start++; |
| } |
| break; |
| default: |
| if (NeedEsc(*start)) |
| sResult.Append('\\'); |
| sResult.Append(*start++); |
| } |
| } |
| |
| sResult.Append('$'); |
| |
| return sResult; |
| } |
| } |
| |
| void SbiRuntime::StepLIKE() |
| { |
| SbxVariableRef refVar1 = PopVar(); |
| SbxVariableRef refVar2 = PopVar(); |
| |
| String pattern = VBALikeToRegexp(refVar1->GetString()); |
| String value = refVar2->GetString(); |
| |
| com::sun::star::util::SearchOptions aSearchOpt; |
| |
| aSearchOpt.algorithmType = com::sun::star::util::SearchAlgorithms_REGEXP; |
| |
| aSearchOpt.Locale = Application::GetSettings().GetLocale(); |
| aSearchOpt.searchString = pattern; |
| |
| int bTextMode(1); |
| bool bCompatibility = ( pINST && pINST->IsCompatibility() ); |
| if( bCompatibility ) |
| bTextMode = GetImageFlag( SBIMG_COMPARETEXT ); |
| |
| if( bTextMode ) |
| aSearchOpt.transliterateFlags |= com::sun::star::i18n::TransliterationModules_IGNORE_CASE; |
| |
| SbxVariable* pRes = new SbxVariable; |
| utl::TextSearch aSearch(aSearchOpt); |
| xub_StrLen nStart=0, nEnd=value.Len(); |
| int bRes = aSearch.SearchFrwrd(value, &nStart, &nEnd); |
| pRes->PutBool( bRes != 0 ); |
| |
| PushVar( pRes ); |
| } |
| |
| // TOS und TOS-1 sind beides Objektvariable und enthalten den selben Pointer |
| |
| void SbiRuntime::StepIS() |
| { |
| SbxVariableRef refVar1 = PopVar(); |
| SbxVariableRef refVar2 = PopVar(); |
| |
| SbxDataType eType1 = refVar1->GetType(); |
| SbxDataType eType2 = refVar2->GetType(); |
| if ( eType1 == SbxEMPTY ) |
| { |
| refVar1->Broadcast( SBX_HINT_DATAWANTED ); |
| eType1 = refVar1->GetType(); |
| } |
| if ( eType2 == SbxEMPTY ) |
| { |
| refVar2->Broadcast( SBX_HINT_DATAWANTED ); |
| eType2 = refVar2->GetType(); |
| } |
| |
| sal_Bool bRes = sal_Bool( eType1 == SbxOBJECT && eType2 == SbxOBJECT ); |
| if ( bVBAEnabled && !bRes ) |
| Error( SbERR_INVALID_USAGE_OBJECT ); |
| bRes = ( bRes && refVar1->GetObject() == refVar2->GetObject() ); |
| SbxVariable* pRes = new SbxVariable; |
| pRes->PutBool( bRes ); |
| PushVar( pRes ); |
| } |
| |
| // Aktualisieren des Wertes von TOS |
| |
| void SbiRuntime::StepGET() |
| { |
| SbxVariable* p = GetTOS(); |
| p->Broadcast( SBX_HINT_DATAWANTED ); |
| } |
| |
| // #67607 Uno-Structs kopieren |
| inline void checkUnoStructCopy( SbxVariableRef& refVal, SbxVariableRef& refVar ) |
| { |
| SbxDataType eVarType = refVar->GetType(); |
| if( eVarType != SbxOBJECT ) |
| return; |
| |
| SbxObjectRef xValObj = (SbxObject*)refVal->GetObject(); |
| if( !xValObj.Is() || xValObj->ISA(SbUnoAnyObject) ) |
| return; |
| |
| // #115826: Exclude ProcedureProperties to avoid call to Property Get procedure |
| if( refVar->ISA(SbProcedureProperty) ) |
| return; |
| |
| SbxObjectRef xVarObj = (SbxObject*)refVar->GetObject(); |
| SbxDataType eValType = refVal->GetType(); |
| if( eValType == SbxOBJECT && xVarObj == xValObj ) |
| { |
| SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)xVarObj); |
| if( pUnoObj ) |
| { |
| Any aAny = pUnoObj->getUnoAny(); |
| if( aAny.getValueType().getTypeClass() == TypeClass_STRUCT ) |
| { |
| SbUnoObject* pNewUnoObj = new SbUnoObject( pUnoObj->GetName(), aAny ); |
| // #70324: ClassName uebernehmen |
| pNewUnoObj->SetClassName( pUnoObj->GetClassName() ); |
| refVar->PutObject( pNewUnoObj ); |
| } |
| } |
| } |
| } |
| |
| |
| // Ablage von TOS in TOS-1 |
| |
| void SbiRuntime::StepPUT() |
| { |
| SbxVariableRef refVal = PopVar(); |
| SbxVariableRef refVar = PopVar(); |
| // Store auf die eigene Methode (innerhalb einer Function)? |
| sal_Bool bFlagsChanged = sal_False; |
| sal_uInt16 n = 0; |
| if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) |
| { |
| bFlagsChanged = sal_True; |
| n = refVar->GetFlags(); |
| refVar->SetFlag( SBX_WRITE ); |
| } |
| |
| // if left side arg is an object or variant and right handside isn't |
| // either an object or a variant then try and see if a default |
| // property exists. |
| // to use e.g. Range{"A1") = 34 |
| // could equate to Range("A1").Value = 34 |
| if ( bVBAEnabled ) |
| { |
| if ( refVar->GetType() == SbxOBJECT ) |
| { |
| SbxVariable* pDflt = getDefaultProp( refVar ); |
| if ( pDflt ) |
| refVar = pDflt; |
| } |
| if ( refVal->GetType() == SbxOBJECT ) |
| { |
| SbxVariable* pDflt = getDefaultProp( refVal ); |
| if ( pDflt ) |
| refVal = pDflt; |
| } |
| } |
| |
| *refVar = *refVal; |
| // lhs is a property who's value is currently null |
| if ( !bVBAEnabled || ( bVBAEnabled && refVar->GetType() != SbxEMPTY ) ) |
| // #67607 Uno-Structs kopieren |
| checkUnoStructCopy( refVal, refVar ); |
| if( bFlagsChanged ) |
| refVar->SetFlags( n ); |
| } |
| |
| |
| // VBA Dim As New behavior handling, save init object information |
| struct DimAsNewRecoverItem |
| { |
| String m_aObjClass; |
| String m_aObjName; |
| SbxObject* m_pObjParent; |
| SbModule* m_pClassModule; |
| |
| DimAsNewRecoverItem( void ) |
| : m_pObjParent( NULL ) |
| , m_pClassModule( NULL ) |
| {} |
| |
| DimAsNewRecoverItem( const String& rObjClass, const String& rObjName, |
| SbxObject* pObjParent, SbModule* pClassModule ) |
| : m_aObjClass( rObjClass ) |
| , m_aObjName( rObjName ) |
| , m_pObjParent( pObjParent ) |
| , m_pClassModule( pClassModule ) |
| {} |
| |
| }; |
| |
| |
| struct SbxVariablePtrHash |
| { |
| size_t operator()( SbxVariable* pVar ) const |
| { return (size_t)pVar; } |
| }; |
| |
| typedef std::hash_map< SbxVariable*, DimAsNewRecoverItem, SbxVariablePtrHash > DimAsNewRecoverHash; |
| |
| static DimAsNewRecoverHash GaDimAsNewRecoverHash; |
| |
| void removeDimAsNewRecoverItem( SbxVariable* pVar ) |
| { |
| DimAsNewRecoverHash::iterator it = GaDimAsNewRecoverHash.find( pVar ); |
| if( it != GaDimAsNewRecoverHash.end() ) |
| GaDimAsNewRecoverHash.erase( it ); |
| } |
| |
| |
| // Speichern Objektvariable |
| // Nicht-Objekt-Variable fuehren zu Fehlern |
| |
| static const char pCollectionStr[] = "Collection"; |
| |
| void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bHandleDefaultProp ) |
| { |
| // #67733 Typen mit Array-Flag sind auch ok |
| |
| // Check var, !object is no error for sure if, only if type is fixed |
| SbxDataType eVarType = refVar->GetType(); |
| if( !bHandleDefaultProp && eVarType != SbxOBJECT && !(eVarType & SbxARRAY) && refVar->IsFixed() ) |
| { |
| Error( SbERR_INVALID_USAGE_OBJECT ); |
| return; |
| } |
| |
| // Check value, !object is no error for sure if, only if type is fixed |
| SbxDataType eValType = refVal->GetType(); |
| // bool bGetValObject = false; |
| if( !bHandleDefaultProp && eValType != SbxOBJECT && !(eValType & SbxARRAY) && refVal->IsFixed() ) |
| { |
| Error( SbERR_INVALID_USAGE_OBJECT ); |
| return; |
| } |
| |
| // Getting in here causes problems with objects with default properties |
| // if they are SbxEMPTY I guess |
| if ( !bHandleDefaultProp || ( bHandleDefaultProp && eValType == SbxOBJECT ) ) |
| { |
| // Auf refVal GetObject fuer Collections ausloesen |
| SbxBase* pObjVarObj = refVal->GetObject(); |
| if( pObjVarObj ) |
| { |
| SbxVariableRef refObjVal = PTR_CAST(SbxObject,pObjVarObj); |
| |
| // #67733 Typen mit Array-Flag sind auch ok |
| if( refObjVal ) |
| refVal = refObjVal; |
| else if( !(eValType & SbxARRAY) ) |
| refVal = NULL; |
| } |
| } |
| |
| // #52896 Wenn Uno-Sequences bzw. allgemein Arrays einer als |
| // Object deklarierten Variable zugewiesen werden, kann hier |
| // refVal ungueltig sein! |
| if( !refVal ) |
| { |
| Error( SbERR_INVALID_USAGE_OBJECT ); |
| } |
| else |
| { |
| // Store auf die eigene Methode (innerhalb einer Function)? |
| sal_Bool bFlagsChanged = sal_False; |
| sal_uInt16 n = 0; |
| if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) |
| { |
| bFlagsChanged = sal_True; |
| n = refVar->GetFlags(); |
| refVar->SetFlag( SBX_WRITE ); |
| } |
| SbProcedureProperty* pProcProperty = PTR_CAST(SbProcedureProperty,(SbxVariable*)refVar); |
| if( pProcProperty ) |
| pProcProperty->setSet( true ); |
| |
| if ( bHandleDefaultProp ) |
| { |
| // get default properties for lhs & rhs where necessary |
| // SbxVariable* defaultProp = NULL; unused variable |
| bool bLHSHasDefaultProp = false; |
| // LHS try determine if a default prop exists |
| if ( refVar->GetType() == SbxOBJECT ) |
| { |
| SbxVariable* pDflt = getDefaultProp( refVar ); |
| if ( pDflt ) |
| { |
| refVar = pDflt; |
| bLHSHasDefaultProp = true; |
| } |
| } |
| // RHS only get a default prop is the rhs has one |
| if ( refVal->GetType() == SbxOBJECT ) |
| { |
| // check if lhs is a null object |
| // if it is then use the object not the default property |
| SbxObject* pObj = NULL; |
| |
| |
| pObj = PTR_CAST(SbxObject,(SbxVariable*)refVar); |
| |
| // calling GetObject on a SbxEMPTY variable raises |
| // object not set errors, make sure its an Object |
| if ( !pObj && refVar->GetType() == SbxOBJECT ) |
| { |
| SbxBase* pObjVarObj = refVar->GetObject(); |
| pObj = PTR_CAST(SbxObject,pObjVarObj); |
| } |
| SbxVariable* pDflt = NULL; |
| if ( pObj || bLHSHasDefaultProp ) |
| // lhs is either a valid object || or has a defaultProp |
| pDflt = getDefaultProp( refVal ); |
| if ( pDflt ) |
| refVal = pDflt; |
| } |
| } |
| |
| // Handle Dim As New |
| sal_Bool bDimAsNew = bVBAEnabled && refVar->IsSet( SBX_DIM_AS_NEW ); |
| SbxBaseRef xPrevVarObj; |
| if( bDimAsNew ) |
| xPrevVarObj = refVar->GetObject(); |
| |
| // Handle withevents |
| sal_Bool bWithEvents = refVar->IsSet( SBX_WITH_EVENTS ); |
| if ( bWithEvents ) |
| { |
| Reference< XInterface > xComListener; |
| |
| SbxBase* pObj = refVal->GetObject(); |
| SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL; |
| if( pUnoObj != NULL ) |
| { |
| Any aControlAny = pUnoObj->getUnoAny(); |
| String aDeclareClassName = refVar->GetDeclareClassName(); |
| ::rtl::OUString aVBAType = aDeclareClassName; |
| ::rtl::OUString aPrefix = refVar->GetName(); |
| SbxObjectRef xScopeObj = refVar->GetParent(); |
| xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj ); |
| |
| refVal->SetDeclareClassName( aDeclareClassName ); |
| refVal->SetComListener( xComListener, &rBasic ); // Hold reference |
| } |
| |
| *refVar = *refVal; |
| } |
| else |
| { |
| *refVar = *refVal; |
| } |
| |
| if ( bDimAsNew ) |
| { |
| if( !refVar->ISA(SbxObject) ) |
| { |
| SbxBase* pValObjBase = refVal->GetObject(); |
| if( pValObjBase == NULL ) |
| { |
| if( xPrevVarObj.Is() ) |
| { |
| // Object is overwritten with NULL, instantiate init object |
| DimAsNewRecoverHash::iterator it = GaDimAsNewRecoverHash.find( refVar ); |
| if( it != GaDimAsNewRecoverHash.end() ) |
| { |
| const DimAsNewRecoverItem& rItem = it->second; |
| if( rItem.m_pClassModule != NULL ) |
| { |
| SbClassModuleObject* pNewObj = new SbClassModuleObject( rItem.m_pClassModule ); |
| pNewObj->SetName( rItem.m_aObjName ); |
| pNewObj->SetParent( rItem.m_pObjParent ); |
| refVar->PutObject( pNewObj ); |
| } |
| else if( rItem.m_aObjClass.EqualsIgnoreCaseAscii( pCollectionStr ) ) |
| { |
| BasicCollection* pNewCollection = new BasicCollection( String( RTL_CONSTASCII_USTRINGPARAM(pCollectionStr) ) ); |
| pNewCollection->SetName( rItem.m_aObjName ); |
| pNewCollection->SetParent( rItem.m_pObjParent ); |
| refVar->PutObject( pNewCollection ); |
| } |
| } |
| } |
| } |
| else |
| { |
| // Does old value exist? |
| bool bFirstInit = !xPrevVarObj.Is(); |
| if( bFirstInit ) |
| { |
| // Store information to instantiate object later |
| SbxObject* pValObj = PTR_CAST(SbxObject,pValObjBase); |
| if( pValObj != NULL ) |
| { |
| String aObjClass = pValObj->GetClassName(); |
| |
| SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pValObjBase); |
| if( pClassModuleObj != NULL ) |
| { |
| SbModule* pClassModule = pClassModuleObj->getClassModule(); |
| GaDimAsNewRecoverHash[refVar] = |
| DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), pClassModule ); |
| } |
| else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) ) |
| { |
| GaDimAsNewRecoverHash[refVar] = |
| DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), NULL ); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| // lhs is a property who's value is currently (Empty e.g. no broadcast yet) |
| // in this case if there is a default prop involved the value of the |
| // default property may infact be void so the type will also be SbxEMPTY |
| // in this case we do not want to call checkUnoStructCopy 'cause that will |
| // cause an error also |
| if ( !bHandleDefaultProp || ( bHandleDefaultProp && ( refVar->GetType() != SbxEMPTY ) ) ) |
| // #67607 Uno-Structs kopieren |
| checkUnoStructCopy( refVal, refVar ); |
| if( bFlagsChanged ) |
| refVar->SetFlags( n ); |
| } |
| } |
| |
| void SbiRuntime::StepSET() |
| { |
| SbxVariableRef refVal = PopVar(); |
| SbxVariableRef refVar = PopVar(); |
| StepSET_Impl( refVal, refVar, bVBAEnabled ); // this is really assigment |
| } |
| |
| void SbiRuntime::StepVBASET() |
| { |
| SbxVariableRef refVal = PopVar(); |
| SbxVariableRef refVar = PopVar(); |
| // don't handle default property |
| StepSET_Impl( refVal, refVar, false ); // set obj = something |
| } |
| |
| |
| // JSM 07.10.95 |
| void SbiRuntime::StepLSET() |
| { |
| SbxVariableRef refVal = PopVar(); |
| SbxVariableRef refVar = PopVar(); |
| if( refVar->GetType() != SbxSTRING |
| || refVal->GetType() != SbxSTRING ) |
| Error( SbERR_INVALID_USAGE_OBJECT ); |
| else |
| { |
| // Store auf die eigene Methode (innerhalb einer Function)? |
| sal_uInt16 n = refVar->GetFlags(); |
| if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) |
| refVar->SetFlag( SBX_WRITE ); |
| String aRefVarString = refVar->GetString(); |
| String aRefValString = refVal->GetString(); |
| |
| sal_uInt16 nVarStrLen = aRefVarString.Len(); |
| sal_uInt16 nValStrLen = aRefValString.Len(); |
| String aNewStr; |
| if( nVarStrLen > nValStrLen ) |
| { |
| aRefVarString.Fill(nVarStrLen,' '); |
| aNewStr = aRefValString.Copy( 0, nValStrLen ); |
| aNewStr += aRefVarString.Copy( nValStrLen, nVarStrLen - nValStrLen ); |
| } |
| else |
| { |
| aNewStr = aRefValString.Copy( 0, nVarStrLen ); |
| } |
| |
| refVar->PutString( aNewStr ); |
| refVar->SetFlags( n ); |
| } |
| } |
| |
| // JSM 07.10.95 |
| void SbiRuntime::StepRSET() |
| { |
| SbxVariableRef refVal = PopVar(); |
| SbxVariableRef refVar = PopVar(); |
| if( refVar->GetType() != SbxSTRING |
| || refVal->GetType() != SbxSTRING ) |
| Error( SbERR_INVALID_USAGE_OBJECT ); |
| else |
| { |
| // Store auf die eigene Methode (innerhalb einer Function)? |
| sal_uInt16 n = refVar->GetFlags(); |
| if( (SbxVariable*) refVar == (SbxVariable*) pMeth ) |
| refVar->SetFlag( SBX_WRITE ); |
| String aRefVarString = refVar->GetString(); |
| String aRefValString = refVal->GetString(); |
| |
| sal_uInt16 nPos = 0; |
| sal_uInt16 nVarStrLen = aRefVarString.Len(); |
| if( nVarStrLen > aRefValString.Len() ) |
| { |
| aRefVarString.Fill(nVarStrLen,' '); |
| nPos = nVarStrLen - aRefValString.Len(); |
| } |
| aRefVarString = aRefVarString.Copy( 0, nPos ); |
| aRefVarString += aRefValString.Copy( 0, nVarStrLen - nPos ); |
| refVar->PutString(aRefVarString); |
| |
| refVar->SetFlags( n ); |
| } |
| } |
| |
| // Ablage von TOS in TOS-1, dann ReadOnly-Bit setzen |
| |
| void SbiRuntime::StepPUTC() |
| { |
| SbxVariableRef refVal = PopVar(); |
| SbxVariableRef refVar = PopVar(); |
| refVar->SetFlag( SBX_WRITE ); |
| *refVar = *refVal; |
| refVar->ResetFlag( SBX_WRITE ); |
| refVar->SetFlag( SBX_CONST ); |
| } |
| |
| // DIM |
| // TOS = Variable fuer das Array mit Dimensionsangaben als Parameter |
| |
| void SbiRuntime::StepDIM() |
| { |
| SbxVariableRef refVar = PopVar(); |
| DimImpl( refVar ); |
| } |
| |
| // #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx) |
| void SbiRuntime::DimImpl( SbxVariableRef refVar ) |
| { |
| SbxArray* pDims = refVar->GetParameters(); |
| // Muss eine gerade Anzahl Argumente haben |
| // Man denke daran, dass Arg[0] nicht zaehlt! |
| if( pDims && !( pDims->Count() & 1 ) ) |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| else |
| { |
| SbxDataType eType = refVar->IsFixed() ? refVar->GetType() : SbxVARIANT; |
| SbxDimArray* pArray = new SbxDimArray( eType ); |
| // AB 2.4.1996, auch Arrays ohne Dimensionsangaben zulassen (VB-komp.) |
| if( pDims ) |
| { |
| refVar->ResetFlag( SBX_VAR_TO_DIM ); |
| |
| for( sal_uInt16 i = 1; i < pDims->Count(); ) |
| { |
| sal_Int32 lb = pDims->Get( i++ )->GetLong(); |
| sal_Int32 ub = pDims->Get( i++ )->GetLong(); |
| if( ub < lb ) |
| Error( SbERR_OUT_OF_RANGE ), ub = lb; |
| pArray->AddDim32( lb, ub ); |
| if ( lb != ub ) |
| pArray->setHasFixedSize( true ); |
| } |
| } |
| else |
| { |
| // #62867 Beim Anlegen eines Arrays der Laenge 0 wie bei |
| // Uno-Sequences der Laenge 0 eine Dimension anlegen |
| pArray->unoAddDim( 0, -1 ); |
| } |
| sal_uInt16 nSavFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->PutObject( pArray ); |
| refVar->SetFlags( nSavFlags ); |
| refVar->SetParameters( NULL ); |
| } |
| } |
| |
| // REDIM |
| // TOS = Variable fuer das Array |
| // argv = Dimensionsangaben |
| |
| void SbiRuntime::StepREDIM() |
| { |
| // Im Moment ist es nichts anderes als Dim, da doppeltes Dim |
| // bereits vom Compiler erkannt wird. |
| StepDIM(); |
| } |
| |
| |
| // Helper function for StepREDIMP |
| void implCopyDimArray( SbxDimArray* pNewArray, SbxDimArray* pOldArray, short nMaxDimIndex, |
| short nActualDim, sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds ) |
| { |
| sal_Int32& ri = pActualIndices[nActualDim]; |
| for( ri = pLowerBounds[nActualDim] ; ri <= pUpperBounds[nActualDim] ; ri++ ) |
| { |
| if( nActualDim < nMaxDimIndex ) |
| { |
| implCopyDimArray( pNewArray, pOldArray, nMaxDimIndex, nActualDim + 1, |
| pActualIndices, pLowerBounds, pUpperBounds ); |
| } |
| else |
| { |
| SbxVariable* pSource = pOldArray->Get32( pActualIndices ); |
| SbxVariable* pDest = pNewArray->Get32( pActualIndices ); |
| if( pSource && pDest ) |
| *pDest = *pSource; |
| } |
| } |
| } |
| |
| // REDIM PRESERVE |
| // TOS = Variable fuer das Array |
| // argv = Dimensionsangaben |
| |
| void SbiRuntime::StepREDIMP() |
| { |
| SbxVariableRef refVar = PopVar(); |
| DimImpl( refVar ); |
| |
| // Now check, if we can copy from the old array |
| if( refRedimpArray.Is() ) |
| { |
| SbxBase* pElemObj = refVar->GetObject(); |
| SbxDimArray* pNewArray = PTR_CAST(SbxDimArray,pElemObj); |
| SbxDimArray* pOldArray = (SbxDimArray*)(SbxArray*)refRedimpArray; |
| if( pNewArray ) |
| { |
| short nDimsNew = pNewArray->GetDims(); |
| short nDimsOld = pOldArray->GetDims(); |
| short nDims = nDimsNew; |
| sal_Bool bRangeError = sal_False; |
| |
| // Store dims to use them for copying later |
| sal_Int32* pLowerBounds = new sal_Int32[nDims]; |
| sal_Int32* pUpperBounds = new sal_Int32[nDims]; |
| sal_Int32* pActualIndices = new sal_Int32[nDims]; |
| |
| if( nDimsOld != nDimsNew ) |
| { |
| bRangeError = sal_True; |
| } |
| else |
| { |
| // Compare bounds |
| for( short i = 1 ; i <= nDims ; i++ ) |
| { |
| sal_Int32 lBoundNew, uBoundNew; |
| sal_Int32 lBoundOld, uBoundOld; |
| pNewArray->GetDim32( i, lBoundNew, uBoundNew ); |
| pOldArray->GetDim32( i, lBoundOld, uBoundOld ); |
| |
| /* #69094 Allow all dimensions to be changed |
| although Visual Basic is not able to do so. |
| // All bounds but the last have to be the same |
| if( i < nDims && ( lBoundNew != lBoundOld || uBoundNew != uBoundOld ) ) |
| { |
| bRangeError = sal_True; |
| break; |
| } |
| else |
| */ |
| { |
| // #69094: if( i == nDims ) |
| { |
| lBoundNew = std::max( lBoundNew, lBoundOld ); |
| uBoundNew = std::min( uBoundNew, uBoundOld ); |
| } |
| short j = i - 1; |
| pActualIndices[j] = pLowerBounds[j] = lBoundNew; |
| pUpperBounds[j] = uBoundNew; |
| } |
| } |
| } |
| |
| if( bRangeError ) |
| { |
| StarBASIC::Error( SbERR_OUT_OF_RANGE ); |
| } |
| else |
| { |
| // Copy data from old array by going recursively through all dimensions |
| // (It would be faster to work on the flat internal data array of an |
| // SbyArray but this solution is clearer and easier) |
| implCopyDimArray( pNewArray, pOldArray, nDims - 1, |
| 0, pActualIndices, pLowerBounds, pUpperBounds ); |
| } |
| |
| delete[] pUpperBounds; |
| delete[] pLowerBounds; |
| delete[] pActualIndices; |
| refRedimpArray = NULL; |
| } |
| } |
| |
| //StarBASIC::FatalError( SbERR_NOT_IMPLEMENTED ); |
| } |
| |
| // REDIM_COPY |
| // TOS = Array-Variable, Reference to array is copied |
| // Variable is cleared as in ERASE |
| |
| void SbiRuntime::StepREDIMP_ERASE() |
| { |
| SbxVariableRef refVar = PopVar(); |
| SbxDataType eType = refVar->GetType(); |
| if( eType & SbxARRAY ) |
| { |
| SbxBase* pElemObj = refVar->GetObject(); |
| SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); |
| if( pDimArray ) |
| { |
| refRedimpArray = pDimArray; |
| } |
| |
| // As in ERASE |
| sal_uInt16 nSavFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->SetType( SbxDataType(eType & 0x0FFF) ); |
| refVar->SetFlags( nSavFlags ); |
| refVar->Clear(); |
| } |
| else |
| if( refVar->IsFixed() ) |
| refVar->Clear(); |
| else |
| refVar->SetType( SbxEMPTY ); |
| } |
| |
| void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType ) |
| { |
| sal_uInt16 nSavFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->SetType( SbxDataType(eType & 0x0FFF) ); |
| refVar->SetFlags( nSavFlags ); |
| refVar->Clear(); |
| } |
| |
| void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled ) |
| { |
| SbxDataType eType = refVar->GetType(); |
| if( eType & SbxARRAY ) |
| { |
| if ( bVBAEnabled ) |
| { |
| SbxBase* pElemObj = refVar->GetObject(); |
| SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); |
| bool bClearValues = true; |
| if( pDimArray ) |
| { |
| if ( pDimArray->hasFixedSize() ) |
| { |
| // Clear all Value(s) |
| pDimArray->SbxArray::Clear(); |
| bClearValues = false; |
| } |
| else |
| pDimArray->Clear(); // clear Dims |
| } |
| if ( bClearValues ) |
| { |
| SbxArray* pArray = PTR_CAST(SbxArray,pElemObj); |
| if ( pArray ) |
| pArray->Clear(); |
| } |
| } |
| else |
| // AB 2.4.1996 |
| // Arrays haben bei Erase nach VB ein recht komplexes Verhalten. Hier |
| // werden zunaechst nur die Typ-Probleme bei REDIM (#26295) beseitigt: |
| // Typ hart auf den Array-Typ setzen, da eine Variable mit Array |
| // SbxOBJECT ist. Bei REDIM entsteht dann ein SbxOBJECT-Array und |
| // der ursruengliche Typ geht verloren -> Laufzeitfehler |
| lcl_clearImpl( refVar, eType ); |
| } |
| else |
| if( refVar->IsFixed() ) |
| refVar->Clear(); |
| else |
| refVar->SetType( SbxEMPTY ); |
| } |
| |
| // Variable loeschen |
| // TOS = Variable |
| |
| void SbiRuntime::StepERASE() |
| { |
| SbxVariableRef refVar = PopVar(); |
| lcl_eraseImpl( refVar, bVBAEnabled ); |
| } |
| |
| void SbiRuntime::StepERASE_CLEAR() |
| { |
| SbxVariableRef refVar = PopVar(); |
| lcl_eraseImpl( refVar, bVBAEnabled ); |
| SbxDataType eType = refVar->GetType(); |
| lcl_clearImpl( refVar, eType ); |
| } |
| |
| void SbiRuntime::StepARRAYACCESS() |
| { |
| if( !refArgv ) |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| SbxVariableRef refVar = PopVar(); |
| refVar->SetParameters( refArgv ); |
| PopArgv(); |
| PushVar( CheckArray( refVar ) ); |
| } |
| |
| void SbiRuntime::StepBYVAL() |
| { |
| // Copy variable on stack to break call by reference |
| SbxVariableRef pVar = PopVar(); |
| SbxDataType t = pVar->GetType(); |
| |
| SbxVariable* pCopyVar = new SbxVariable( t ); |
| pCopyVar->SetFlag( SBX_READWRITE ); |
| *pCopyVar = *pVar; |
| |
| PushVar( pCopyVar ); |
| } |
| |
| // Einrichten eines Argvs |
| // nOp1 bleibt so -> 1. Element ist Returnwert |
| |
| void SbiRuntime::StepARGC() |
| { |
| PushArgv(); |
| refArgv = new SbxArray; |
| nArgc = 1; |
| } |
| |
| // Speichern eines Arguments in Argv |
| |
| void SbiRuntime::StepARGV() |
| { |
| if( !refArgv ) |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| else |
| { |
| SbxVariableRef pVal = PopVar(); |
| |
| // Before fix of #94916: |
| // if( pVal->ISA(SbxMethod) || pVal->ISA(SbxProperty) ) |
| if( pVal->ISA(SbxMethod) || pVal->ISA(SbUnoProperty) || pVal->ISA(SbProcedureProperty) ) |
| { |
| // Methoden und Properties evaluieren! |
| SbxVariable* pRes = new SbxVariable( *pVal ); |
| pVal = pRes; |
| } |
| refArgv->Put( pVal, nArgc++ ); |
| } |
| } |
| |
| // Input to Variable. Die Variable ist auf TOS und wird |
| // anschliessend entfernt. |
| |
| void SbiRuntime::StepINPUT() |
| { |
| String s; |
| char ch = 0; |
| SbError err; |
| // Skip whitespace |
| while( ( err = pIosys->GetError() ) == 0 ) |
| { |
| ch = pIosys->Read(); |
| if( ch != ' ' && ch != '\t' && ch != '\n' ) |
| break; |
| } |
| if( !err ) |
| { |
| // Scan until comma or whitespace |
| char sep = ( ch == '"' ) ? ch : 0; |
| if( sep ) ch = pIosys->Read(); |
| while( ( err = pIosys->GetError() ) == 0 ) |
| { |
| if( ch == sep ) |
| { |
| ch = pIosys->Read(); |
| if( ch != sep ) |
| break; |
| } |
| else if( !sep && (ch == ',' || ch == '\n') ) |
| break; |
| s += ch; |
| ch = pIosys->Read(); |
| } |
| // skip whitespace |
| if( ch == ' ' || ch == '\t' ) |
| while( ( err = pIosys->GetError() ) == 0 ) |
| { |
| if( ch != ' ' && ch != '\t' && ch != '\n' ) |
| break; |
| ch = pIosys->Read(); |
| } |
| } |
| if( !err ) |
| { |
| SbxVariableRef pVar = GetTOS(); |
| // Zuerst versuchen, die Variable mit einem numerischen Wert |
| // zu fuellen, dann mit einem Stringwert |
| if( !pVar->IsFixed() || pVar->IsNumeric() ) |
| { |
| sal_uInt16 nLen = 0; |
| if( !pVar->Scan( s, &nLen ) ) |
| { |
| err = SbxBase::GetError(); |
| SbxBase::ResetError(); |
| } |
| // Der Wert muss komplett eingescant werden |
| else if( nLen != s.Len() && !pVar->PutString( s ) ) |
| { |
| err = SbxBase::GetError(); |
| SbxBase::ResetError(); |
| } |
| else if( nLen != s.Len() && pVar->IsNumeric() ) |
| { |
| err = SbxBase::GetError(); |
| SbxBase::ResetError(); |
| if( !err ) |
| err = SbERR_CONVERSION; |
| } |
| } |
| else |
| { |
| pVar->PutString( s ); |
| err = SbxBase::GetError(); |
| SbxBase::ResetError(); |
| } |
| } |
| if( err == SbERR_USER_ABORT ) |
| Error( err ); |
| else if( err ) |
| { |
| if( pRestart && !pIosys->GetChannel() ) |
| { |
| BasResId aId( IDS_SBERR_START + 4 ); |
| String aMsg( aId ); |
| |
| //****** DON'T CHECK IN, TEST ONLY ******* |
| //****** DON'T CHECK IN, TEST ONLY ******* |
| // ErrorBox( NULL, WB_OK, aMsg ).Execute(); |
| //****** DON'T CHECK IN, TEST ONLY ******* |
| //****** DON'T CHECK IN, TEST ONLY ******* |
| |
| pCode = pRestart; |
| } |
| else |
| Error( err ); |
| } |
| else |
| { |
| // pIosys->ResetChannel(); |
| PopVar(); |
| } |
| } |
| |
| // Line Input to Variable. Die Variable ist auf TOS und wird |
| // anschliessend entfernt. |
| |
| void SbiRuntime::StepLINPUT() |
| { |
| ByteString aInput; |
| pIosys->Read( aInput ); |
| Error( pIosys->GetError() ); |
| SbxVariableRef p = PopVar(); |
| p->PutString( String( aInput, gsl_getSystemTextEncoding() ) ); |
| // pIosys->ResetChannel(); |
| } |
| |
| // Programmende |
| |
| void SbiRuntime::StepSTOP() |
| { |
| pInst->Stop(); |
| } |
| |
| // FOR-Variable initialisieren |
| |
| void SbiRuntime::StepINITFOR() |
| { |
| PushFor(); |
| } |
| |
| void SbiRuntime::StepINITFOREACH() |
| { |
| PushForEach(); |
| } |
| |
| // FOR-Variable inkrementieren |
| |
| void SbiRuntime::StepNEXT() |
| { |
| if( !pForStk ) |
| { |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| return; |
| } |
| if( pForStk->eForType == FOR_TO ) |
| pForStk->refVar->Compute( SbxPLUS, *pForStk->refInc ); |
| } |
| |
| // Anfang CASE: TOS in CASE-Stack |
| |
| void SbiRuntime::StepCASE() |
| { |
| if( !refCaseStk.Is() ) |
| refCaseStk = new SbxArray; |
| SbxVariableRef xVar = PopVar(); |
| refCaseStk->Put( xVar, refCaseStk->Count() ); |
| } |
| |
| // Ende CASE: Variable freigeben |
| |
| void SbiRuntime::StepENDCASE() |
| { |
| if( !refCaseStk || !refCaseStk->Count() ) |
| StarBASIC::FatalError( SbERR_INTERNAL_ERROR ); |
| else |
| refCaseStk->Remove( refCaseStk->Count() - 1 ); |
| } |
| |
| // Standard-Fehlerbehandlung |
| |
| void SbiRuntime::StepSTDERROR() |
| { |
| pError = NULL; bError = sal_True; |
| pInst->aErrorMsg = String(); |
| pInst->nErr = 0L; |
| pInst->nErl = 0; |
| nError = 0L; |
| SbxErrObject::getUnoErrObject()->Clear(); |
| } |
| |
| void SbiRuntime::StepNOERROR() |
| { |
| pInst->aErrorMsg = String(); |
| pInst->nErr = 0L; |
| pInst->nErl = 0; |
| nError = 0L; |
| SbxErrObject::getUnoErrObject()->Clear(); |
| bError = sal_False; |
| } |
| |
| // UP verlassen |
| |
| void SbiRuntime::StepLEAVE() |
| { |
| bRun = sal_False; |
| // If VBA and we are leaving an ErrorHandler then clear the error ( it's been processed ) |
| if ( bInError && pError ) |
| SbxErrObject::getUnoErrObject()->Clear(); |
| } |
| |
| void SbiRuntime::StepCHANNEL() // TOS = Kanalnummer |
| { |
| SbxVariableRef pChan = PopVar(); |
| short nChan = pChan->GetInteger(); |
| pIosys->SetChannel( nChan ); |
| Error( pIosys->GetError() ); |
| } |
| |
| void SbiRuntime::StepCHANNEL0() |
| { |
| pIosys->ResetChannel(); |
| } |
| |
| void SbiRuntime::StepPRINT() // print TOS |
| { |
| SbxVariableRef p = PopVar(); |
| String s1 = p->GetString(); |
| String s; |
| if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE ) |
| s = ' '; // ein Blank davor |
| s += s1; |
| ByteString aByteStr( s, gsl_getSystemTextEncoding() ); |
| pIosys->Write( aByteStr ); |
| Error( pIosys->GetError() ); |
| } |
| |
| void SbiRuntime::StepPRINTF() // print TOS in field |
| { |
| SbxVariableRef p = PopVar(); |
| String s1 = p->GetString(); |
| String s; |
| if( p->GetType() >= SbxINTEGER && p->GetType() <= SbxDOUBLE ) |
| s = ' '; // ein Blank davor |
| s += s1; |
| s.Expand( 14, ' ' ); |
| ByteString aByteStr( s, gsl_getSystemTextEncoding() ); |
| pIosys->Write( aByteStr ); |
| Error( pIosys->GetError() ); |
| } |
| |
| void SbiRuntime::StepWRITE() // write TOS |
| { |
| SbxVariableRef p = PopVar(); |
| // Muss der String gekapselt werden? |
| char ch = 0; |
| switch (p->GetType() ) |
| { |
| case SbxSTRING: ch = '"'; break; |
| case SbxCURRENCY: |
| case SbxBOOL: |
| case SbxDATE: ch = '#'; break; |
| default: break; |
| } |
| String s; |
| if( ch ) |
| s += ch; |
| s += p->GetString(); |
| if( ch ) |
| s += ch; |
| ByteString aByteStr( s, gsl_getSystemTextEncoding() ); |
| pIosys->Write( aByteStr ); |
| Error( pIosys->GetError() ); |
| } |
| |
| void SbiRuntime::StepRENAME() // Rename Tos+1 to Tos |
| { |
| SbxVariableRef pTos1 = PopVar(); |
| SbxVariableRef pTos = PopVar(); |
| String aDest = pTos1->GetString(); |
| String aSource = pTos->GetString(); |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| implStepRenameUCB( aSource, aDest ); |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| DirEntry aSourceDirEntry( aSource ); |
| if( aSourceDirEntry.Exists() ) |
| { |
| if( aSourceDirEntry.MoveTo( DirEntry(aDest) ) != FSYS_ERR_OK ) |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| } |
| else |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| #else |
| implStepRenameOSL( aSource, aDest ); |
| #endif |
| } |
| } |
| |
| // TOS = Prompt |
| |
| void SbiRuntime::StepPROMPT() |
| { |
| SbxVariableRef p = PopVar(); |
| ByteString aStr( p->GetString(), gsl_getSystemTextEncoding() ); |
| pIosys->SetPrompt( aStr ); |
| } |
| |
| // Set Restart point |
| |
| void SbiRuntime::StepRESTART() |
| { |
| pRestart = pCode; |
| } |
| |
| // Leerer Ausdruck auf Stack fuer fehlenden Parameter |
| |
| void SbiRuntime::StepEMPTY() |
| { |
| // #57915 Die Semantik von StepEMPTY() ist die Repraesentation eines fehlenden |
| // Arguments. Dies wird in VB durch ein durch den Wert 448 (SbERR_NAMED_NOT_FOUND) |
| // vom Typ Error repraesentiert. StepEmpty jetzt muesste besser StepMISSING() |
| // heissen, aber der Name wird der Einfachkeit halber beibehalten. |
| SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); |
| xVar->PutErr( 448 ); |
| PushVar( xVar ); |
| // ALT: PushVar( new SbxVariable( SbxEMPTY ) ); |
| } |
| |
| // TOS = Fehlercode |
| |
| void SbiRuntime::StepERROR() |
| { |
| SbxVariableRef refCode = PopVar(); |
| sal_uInt16 n = refCode->GetUShort(); |
| SbError error = StarBASIC::GetSfxFromVBError( n ); |
| if ( bVBAEnabled ) |
| pInst->Error( error ); |
| else |
| Error( error ); |
| } |
| |