summaryrefslogtreecommitdiff
path: root/basic/source/runtime
diff options
context:
space:
mode:
authorNoel Power <noel.power@novell.com>2010-10-06 10:16:27 +0100
committerNoel Power <noel.power@novell.com>2010-10-06 10:16:27 +0100
commit0b21b8b146fc4b982c7c9bbb866b9ff18a29332a (patch)
tree9b36a1dee6f92703604bcc86564568eefe711c22 /basic/source/runtime
parent8d4d17664c9c6207fa35458075559d1fbfbfa2a5 (diff)
initial commit for vba blob ( not including container_control stuff )
Diffstat (limited to 'basic/source/runtime')
-rw-r--r--basic/source/runtime/methods.cxx166
-rw-r--r--basic/source/runtime/methods1.cxx551
-rw-r--r--basic/source/runtime/rtlproto.hxx14
-rwxr-xr-xbasic/source/runtime/runtime.cxx32
-rw-r--r--basic/source/runtime/stdobj.cxx123
-rw-r--r--basic/source/runtime/step0.cxx99
-rw-r--r--basic/source/runtime/step1.cxx13
-rwxr-xr-xbasic/source/runtime/step2.cxx8
8 files changed, 942 insertions, 64 deletions
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
index 1a60a5d79a45..6d305d0ba51c 100644
--- a/basic/source/runtime/methods.cxx
+++ b/basic/source/runtime/methods.cxx
@@ -48,6 +48,7 @@
#include <unotools/ucbstreamhelper.hxx>
#include <tools/wldcrd.hxx>
#include <i18npool/lang.h>
+#include <rtl/string.hxx>
#include "runtime.hxx"
#include "sbunoobj.hxx"
@@ -75,13 +76,16 @@
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
-
+#include <com/sun/star/script/XErrorQuery.hpp>
+#include <ooo/vba/XHelperInterface.hpp>
+#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
using namespace comphelper;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::ucb;
using namespace com::sun::star::io;
+using namespace com::sun::star::script;
#endif /* _USE_UNO */
@@ -103,6 +107,8 @@ using namespace com::sun::star::io;
#include <stdlib.h>
#include <ctype.h>
+SbxVariable* getDefaultProp( SbxVariable* pRef );
+
#if defined (WIN) || defined (WNT) || defined (OS2)
#include <direct.h> // _getdcwd get current work directory, _chdrive
#endif
@@ -121,6 +127,9 @@ using namespace com::sun::star::io;
#include <io.h>
#endif
+
+#include <basic/sbobjmod.hxx>
+
#include <basic/sbobjmod.hxx>
static void FilterWhiteSpace( String& rStr )
@@ -706,6 +715,36 @@ RTLFUNC(MkDir) // JSM
{
try
{
+ if ( SbiRuntime::isVBAEnabled() )
+ {
+ // If aPath is the folder name, not a path, then create the folder under current directory.
+ INetURLObject aTryPathURL( aPath );
+ ::rtl::OUString sPathURL = aTryPathURL.GetMainURL( INetURLObject::NO_DECODE );
+ if ( !sPathURL.getLength() )
+ {
+ File::getFileURLFromSystemPath( aPath, sPathURL );
+ }
+ INetURLObject aPathURL( sPathURL );
+ if ( !aPathURL.GetPath().getLength() )
+ {
+ ::rtl::OUString sCurDirURL;
+ SbxArrayRef pPar = new SbxArray;
+ SbxVariableRef pVar = new SbxVariable();
+ pPar->Put( pVar, 0 );
+ SbRtl_CurDir( pBasic, *pPar, FALSE );
+ String aCurPath = pPar->Get(0)->GetString();
+
+ File::getFileURLFromSystemPath( aCurPath, sCurDirURL );
+ INetURLObject aDirURL( sCurDirURL );
+ aDirURL.Append( aPath );
+ ::rtl::OUString aTmpPath = aDirURL.GetMainURL( INetURLObject::NO_DECODE );
+ if ( aTmpPath.getLength() > 0 )
+ {
+ aPath = aTmpPath;
+ }
+ }
+ }
+
xSFI->createFolder( getFullPath( aPath ) );
}
catch( Exception & )
@@ -940,6 +979,26 @@ RTLFUNC(Hex)
}
}
+RTLFUNC(FuncCaller)
+{
+ (void)pBasic;
+ (void)bWrite;
+ if ( SbiRuntime::isVBAEnabled() && pINST && pINST->pRun )
+ {
+ if ( pINST->pRun->GetExternalCaller() )
+ *rPar.Get(0) = *pINST->pRun->GetExternalCaller();
+ else
+ {
+ SbxVariableRef pVar = new SbxVariable(SbxVARIANT);
+ *rPar.Get(0) = *pVar;
+ }
+ }
+ else
+ {
+ StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
+ }
+
+}
// InStr( [start],string,string,[compare] )
RTLFUNC(InStr)
@@ -2411,7 +2470,18 @@ RTLFUNC(IsEmpty)
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
- rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
+ {
+ SbxVariable* pVar = NULL;
+ if( SbiRuntime::isVBAEnabled() )
+ pVar = getDefaultProp( rPar.Get(1) );
+ if ( pVar )
+ {
+ pVar->Broadcast( SBX_HINT_DATAWANTED );
+ rPar.Get( 0 )->PutBool( pVar->IsEmpty() );
+ }
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
+ }
}
RTLFUNC(IsError)
@@ -2422,7 +2492,22 @@ RTLFUNC(IsError)
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
- rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
+ {
+ SbxVariable* pVar =rPar.Get( 1 );
+ SbUnoObject* pObj = PTR_CAST(SbUnoObject,pVar );
+ if ( !pObj )
+ {
+ if ( SbxBase* pBaseObj = pVar->GetObject() )
+ pObj = PTR_CAST(SbUnoObject, pBaseObj );
+ }
+ Reference< XErrorQuery > xError;
+ if ( pObj )
+ xError.set( pObj->getUnoAny(), UNO_QUERY );
+ if ( xError.is() )
+ rPar.Get( 0 )->PutBool( xError->hasError() );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
+ }
}
RTLFUNC(IsNull)
@@ -3542,6 +3627,13 @@ RTLFUNC(Shell)
NAMESPACE_VOS(OArgumentList) aArgList( pArgumentList, nParamCount );
bSucc = pApp->execute( eOptions, aArgList ) == NAMESPACE_VOS(OProcess)::E_None;
}
+ long nResult = 0;
+ NAMESPACE_VOS(OProcess)::TProcessInfo aInfo;
+ // We should return the identifier of the executing process when is running VBA, because method Shell(...) returns it in Excel.
+ if ( bSucc && SbiRuntime::isVBAEnabled() && pApp->getInfo( NAMESPACE_VOS(OProcess)::TData_Identifier, &aInfo ) == NAMESPACE_VOS(OProcess)::E_None )
+ {
+ nResult = aInfo.Ident;
+ }
/*
if( nParamCount == 0 )
@@ -3556,7 +3648,7 @@ RTLFUNC(Shell)
if( !bSucc )
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
else
- rPar.Get(0)->PutLong( 0 );
+ rPar.Get(0)->PutLong( nResult );
}
}
@@ -3627,6 +3719,65 @@ String getBasicTypeName( SbxDataType eType )
return aRetStr;
}
+String getObjectTypeName( SbxVariable* pVar )
+{
+ rtl::OUString sRet( RTL_CONSTASCII_USTRINGPARAM("Object") );
+ if ( pVar )
+ {
+ SbxBase* pObj = pVar->GetObject();
+ if( !pObj )
+ sRet = String( RTL_CONSTASCII_USTRINGPARAM("Nothing") );
+ else
+ {
+ SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pVar );
+ if ( !pUnoObj )
+ {
+ if ( SbxBase* pBaseObj = pVar->GetObject() )
+ pUnoObj = PTR_CAST(SbUnoObject, pBaseObj );
+ }
+ if ( pUnoObj )
+ {
+ Any aObj = pUnoObj->getUnoAny();
+ // For upstreaming unless we start to build oovbaapi by default
+ // we need to get detect the vba-ness of the object in some
+ // other way
+ // note: Automation objects do not support XServiceInfo
+ Reference< XServiceInfo > xServInfo( aObj, UNO_QUERY );
+ if ( xServInfo.is() )
+ {
+ // is this a VBA object ?
+ Reference< ooo::vba::XHelperInterface > xVBA( aObj, UNO_QUERY );
+ Sequence< rtl::OUString > sServices = xServInfo->getSupportedServiceNames();
+ if ( sServices.getLength() )
+ sRet = sServices[ 0 ];
+ }
+ else
+ {
+ Reference< com::sun::star::bridge::oleautomation::XAutomationObject > xAutoMation( aObj, UNO_QUERY );
+ if ( xAutoMation.is() )
+ {
+ Reference< XInvocation > xInv( aObj, UNO_QUERY );
+ if ( xInv.is() )
+ {
+ try
+ {
+ xInv->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("$GetTypeName") ) ) >>= sRet;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ }
+ sal_Int32 nDot = sRet.lastIndexOf( '.' );
+ if ( nDot != -1 && nDot < sRet.getLength() )
+ sRet = sRet.copy( nDot + 1 );
+ }
+ }
+ }
+ return sRet;
+}
+
RTLFUNC(TypeName)
{
(void)pBasic;
@@ -3638,7 +3789,12 @@ RTLFUNC(TypeName)
{
SbxDataType eType = rPar.Get(1)->GetType();
BOOL bIsArray = ( ( eType & SbxARRAY ) != 0 );
- String aRetStr = getBasicTypeName( eType );
+
+ String aRetStr;
+ if ( SbiRuntime::isVBAEnabled() && eType == SbxOBJECT )
+ aRetStr = getObjectTypeName( rPar.Get(1) );
+ else
+ aRetStr = getBasicTypeName( eType );
if( bIsArray )
aRetStr.AppendAscii( "()" );
rPar.Get(0)->PutString( aRetStr );
diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx
index 62e9c388f5c5..033e7b1bd247 100644
--- a/basic/source/runtime/methods1.cxx
+++ b/basic/source/runtime/methods1.cxx
@@ -78,11 +78,15 @@
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/i18n/XCalendar.hpp>
+#include <com/sun/star/sheet/XFunctionAccess.hpp>
using namespace comphelper;
+using namespace com::sun::star::sheet;
using namespace com::sun::star::uno;
using namespace com::sun::star::i18n;
+void unoToSbxValue( SbxVariable* pVar, const Any& aValue );
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, com::sun::star::beans::Property* pUnoProperty = NULL );
static Reference< XCalendar > getLocaleCalendar( void )
{
@@ -528,6 +532,10 @@ RTLFUNC(DoEvents)
(void)pBasic;
(void)bWrite;
(void)rPar;
+// don't undstand what upstream are up to
+// we already process application events etc. in between
+// basic runtime pcode ( on a timed basis )
+#if 0
// Dummy implementation as the following code leads
// to performance problems for unknown reasons
//Timer aTimer;
@@ -535,6 +543,9 @@ RTLFUNC(DoEvents)
//aTimer.Start();
//while ( aTimer.IsActive() )
// Application::Reschedule();
+#endif
+ // always return 0
+ rPar.Get(0)->PutInteger( 0 );
}
RTLFUNC(GetGUIVersion)
@@ -2518,6 +2529,546 @@ RTLFUNC(Round)
rPar.Get(0)->PutDouble( dRes );
}
+void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const rtl::OUString& sFuncName, SbxVariable* pRet )
+{
+ static Reference< XFunctionAccess > xFunc;
+ Any aRes;
+ try
+ {
+ if ( !xFunc.is() )
+ {
+ Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() );
+ if( xFactory.is() )
+ {
+ xFunc.set( xFactory->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.sheet.FunctionAccess")), UNO_QUERY_THROW);
+ }
+ }
+ Any aRet = xFunc->callFunction( sFuncName, aArgs );
+
+ unoToSbxValue( pRet, aRet );
+
+ }
+ catch( Exception& )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+}
+
+RTLFUNC(SYD)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // retrieve non-optional params
+
+ Sequence< Any > aParams( 4 );
+ aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
+ aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
+ aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
+ aParams[ 3 ] <<= makeAny( rPar.Get(4)->GetDouble() );
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SYD") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(SLN)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // retrieve non-optional params
+
+ Sequence< Any > aParams( 3 );
+ aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
+ aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
+ aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SLN") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(Pmt)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 || nArgCount > 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double rate = rPar.Get(1)->GetDouble();
+ double nper = rPar.Get(2)->GetDouble();
+ double pmt = rPar.Get(3)->GetDouble();
+
+ // set default values for Optional args
+ double fv = 0;
+ double type = 0;
+
+ // fv
+ if ( nArgCount >= 4 )
+ {
+ if( rPar.Get(4)->GetType() != SbxEMPTY )
+ fv = rPar.Get(4)->GetDouble();
+ }
+ // type
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ type = rPar.Get(5)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 5 );
+ aParams[ 0 ] <<= rate;
+ aParams[ 1 ] <<= nper;
+ aParams[ 2 ] <<= pmt;
+ aParams[ 3 ] <<= fv;
+ aParams[ 4 ] <<= type;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Pmt") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(PPmt)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 4 || nArgCount > 6 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double rate = rPar.Get(1)->GetDouble();
+ double per = rPar.Get(2)->GetDouble();
+ double nper = rPar.Get(3)->GetDouble();
+ double pv = rPar.Get(4)->GetDouble();
+
+ // set default values for Optional args
+ double fv = 0;
+ double type = 0;
+
+ // fv
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ fv = rPar.Get(5)->GetDouble();
+ }
+ // type
+ if ( nArgCount >= 6 )
+ {
+ if( rPar.Get(6)->GetType() != SbxEMPTY )
+ type = rPar.Get(6)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 6 );
+ aParams[ 0 ] <<= rate;
+ aParams[ 1 ] <<= per;
+ aParams[ 2 ] <<= nper;
+ aParams[ 3 ] <<= pv;
+ aParams[ 4 ] <<= fv;
+ aParams[ 5 ] <<= type;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PPmt") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(PV)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 || nArgCount > 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double rate = rPar.Get(1)->GetDouble();
+ double nper = rPar.Get(2)->GetDouble();
+ double pmt = rPar.Get(3)->GetDouble();
+
+ // set default values for Optional args
+ double fv = 0;
+ double type = 0;
+
+ // fv
+ if ( nArgCount >= 4 )
+ {
+ if( rPar.Get(4)->GetType() != SbxEMPTY )
+ fv = rPar.Get(4)->GetDouble();
+ }
+ // type
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ type = rPar.Get(5)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 5 );
+ aParams[ 0 ] <<= rate;
+ aParams[ 1 ] <<= nper;
+ aParams[ 2 ] <<= pmt;
+ aParams[ 3 ] <<= fv;
+ aParams[ 4 ] <<= type;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PV") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(NPV)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 1 || nArgCount > 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Sequence< Any > aParams( 2 );
+ aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
+ Any aValues = sbxToUnoValue( rPar.Get(2),
+ getCppuType( (Sequence<double>*)0 ) );
+
+ // convert for calc functions
+ Sequence< Sequence< double > > sValues(1);
+ aValues >>= sValues[ 0 ];
+ aValues <<= sValues;
+
+ aParams[ 1 ] <<= aValues;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NPV") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(NPer)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 || nArgCount > 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double rate = rPar.Get(1)->GetDouble();
+ double pmt = rPar.Get(2)->GetDouble();
+ double pv = rPar.Get(3)->GetDouble();
+
+ // set default values for Optional args
+ double fv = 0;
+ double type = 0;
+
+ // fv
+ if ( nArgCount >= 4 )
+ {
+ if( rPar.Get(4)->GetType() != SbxEMPTY )
+ fv = rPar.Get(4)->GetDouble();
+ }
+ // type
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ type = rPar.Get(5)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 5 );
+ aParams[ 0 ] <<= rate;
+ aParams[ 1 ] <<= pmt;
+ aParams[ 2 ] <<= pv;
+ aParams[ 3 ] <<= fv;
+ aParams[ 4 ] <<= type;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NPer") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(MIRR)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // retrieve non-optional params
+
+ Sequence< Any > aParams( 3 );
+ Any aValues = sbxToUnoValue( rPar.Get(1),
+ getCppuType( (Sequence<double>*)0 ) );
+
+ // convert for calc functions
+ Sequence< Sequence< double > > sValues(1);
+ aValues >>= sValues[ 0 ];
+ aValues <<= sValues;
+
+ aParams[ 0 ] <<= aValues;
+ aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
+ aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("MIRR") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(IRR)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 1 || nArgCount > 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+ Any aValues = sbxToUnoValue( rPar.Get(1),
+ getCppuType( (Sequence<double>*)0 ) );
+
+ // convert for calc functions
+ Sequence< Sequence< double > > sValues(1);
+ aValues >>= sValues[ 0 ];
+ aValues <<= sValues;
+
+ // set default values for Optional args
+ double guess = 0.1;
+ // guess
+ if ( nArgCount >= 2 )
+ {
+ if( rPar.Get(2)->GetType() != SbxEMPTY )
+ guess = rPar.Get(2)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 2 );
+ aParams[ 0 ] <<= aValues;
+ aParams[ 1 ] <<= guess;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IRR") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(IPmt)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 4 || nArgCount > 6 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double rate = rPar.Get(1)->GetDouble();
+ double per = rPar.Get(2)->GetInteger();
+ double nper = rPar.Get(3)->GetDouble();
+ double pv = rPar.Get(4)->GetDouble();
+
+ // set default values for Optional args
+ double fv = 0;
+ double type = 0;
+
+ // fv
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ fv = rPar.Get(5)->GetDouble();
+ }
+ // type
+ if ( nArgCount >= 6 )
+ {
+ if( rPar.Get(6)->GetType() != SbxEMPTY )
+ type = rPar.Get(6)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 6 );
+ aParams[ 0 ] <<= rate;
+ aParams[ 1 ] <<= per;
+ aParams[ 2 ] <<= nper;
+ aParams[ 3 ] <<= pv;
+ aParams[ 4 ] <<= fv;
+ aParams[ 5 ] <<= type;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IPmt") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(FV)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 || nArgCount > 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double rate = rPar.Get(1)->GetDouble();
+ double nper = rPar.Get(2)->GetDouble();
+ double pmt = rPar.Get(3)->GetDouble();
+
+ // set default values for Optional args
+ double pv = 0;
+ double type = 0;
+
+ // pv
+ if ( nArgCount >= 4 )
+ {
+ if( rPar.Get(4)->GetType() != SbxEMPTY )
+ pv = rPar.Get(4)->GetDouble();
+ }
+ // type
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ type = rPar.Get(5)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 5 );
+ aParams[ 0 ] <<= rate;
+ aParams[ 1 ] <<= nper;
+ aParams[ 2 ] <<= pmt;
+ aParams[ 3 ] <<= pv;
+ aParams[ 4 ] <<= type;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FV") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(DDB)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 4 || nArgCount > 5 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double cost = rPar.Get(1)->GetDouble();
+ double salvage = rPar.Get(2)->GetDouble();
+ double life = rPar.Get(3)->GetDouble();
+ double period = rPar.Get(4)->GetDouble();
+
+ // set default values for Optional args
+ double factor = 2;
+
+ // factor
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ factor = rPar.Get(5)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 5 );
+ aParams[ 0 ] <<= cost;
+ aParams[ 1 ] <<= salvage;
+ aParams[ 2 ] <<= life;
+ aParams[ 3 ] <<= period;
+ aParams[ 4 ] <<= factor;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DDB") ), rPar.Get( 0 ) );
+}
+
+RTLFUNC(Rate)
+{
+ (void)pBasic;
+ (void)bWrite;
+
+ ULONG nArgCount = rPar.Count()-1;
+
+ if ( nArgCount < 3 || nArgCount > 6 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // retrieve non-optional params
+
+ double nper = 0;
+ double pmt = 0;
+ double pv = 0;
+
+ nper = rPar.Get(1)->GetDouble();
+ pmt = rPar.Get(2)->GetDouble();
+ pv = rPar.Get(3)->GetDouble();
+
+ // set default values for Optional args
+ double fv = 0;
+ double type = 0;
+ double guess = 0.1;
+
+ // fv
+ if ( nArgCount >= 4 )
+ {
+ if( rPar.Get(4)->GetType() != SbxEMPTY )
+ fv = rPar.Get(4)->GetDouble();
+ }
+
+ // type
+ if ( nArgCount >= 5 )
+ {
+ if( rPar.Get(5)->GetType() != SbxEMPTY )
+ type = rPar.Get(5)->GetDouble();
+ }
+
+ // guess
+ if ( nArgCount >= 6 )
+ {
+ if( rPar.Get(6)->GetType() != SbxEMPTY )
+ type = rPar.Get(6)->GetDouble();
+ }
+
+ Sequence< Any > aParams( 6 );
+ aParams[ 0 ] <<= nper;
+ aParams[ 1 ] <<= pmt;
+ aParams[ 2 ] <<= pv;
+ aParams[ 3 ] <<= fv;
+ aParams[ 4 ] <<= type;
+ aParams[ 5 ] <<= guess;
+
+ CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Rate") ), rPar.Get( 0 ) );
+}
+
RTLFUNC(StrReverse)
{
(void)pBasic;
diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx
index 5437654f69a0..bfcb8633e90b 100644
--- a/basic/source/runtime/rtlproto.hxx
+++ b/basic/source/runtime/rtlproto.hxx
@@ -165,29 +165,41 @@ extern RTLFUNC(Kill); // JSM
extern RTLFUNC(MkDir); // JSM
extern RTLFUNC(RmDir); // JSM
extern RTLFUNC(SendKeys); // JSM
+extern RTLFUNC(DDB);
extern RTLFUNC(DimArray);
extern RTLFUNC(Dir);
extern RTLFUNC(DoEvents);
extern RTLFUNC(Exp);
extern RTLFUNC(FileLen);
extern RTLFUNC(Fix);
+extern RTLFUNC(FV);
extern RTLFUNC(Hex);
extern RTLFUNC(Input);
extern RTLFUNC(InStr);
extern RTLFUNC(InStrRev);
extern RTLFUNC(Int);
+extern RTLFUNC(IPmt);
+extern RTLFUNC(IRR);
extern RTLFUNC(Join);
extern RTLFUNC(LCase);
extern RTLFUNC(Left);
extern RTLFUNC(Log);
extern RTLFUNC(LTrim);
extern RTLFUNC(Mid);
+extern RTLFUNC(MIRR);
+extern RTLFUNC(NPer);
+extern RTLFUNC(NPV);
extern RTLFUNC(Oct);
+extern RTLFUNC(Pmt);
+extern RTLFUNC(PPmt);
+extern RTLFUNC(PV);
+extern RTLFUNC(Rate);
extern RTLFUNC(Replace);
extern RTLFUNC(Right);
extern RTLFUNC(RTrim);
extern RTLFUNC(RTL);
extern RTLFUNC(Sgn);
+extern RTLFUNC(SLN);
extern RTLFUNC(Space);
extern RTLFUNC(Split);
extern RTLFUNC(Sqr);
@@ -195,6 +207,7 @@ extern RTLFUNC(Str);
extern RTLFUNC(StrComp);
extern RTLFUNC(String);
extern RTLFUNC(StrReverse);
+extern RTLFUNC(SYD);
extern RTLFUNC(Tan);
extern RTLFUNC(UCase);
extern RTLFUNC(Val);
@@ -297,6 +310,7 @@ extern RTLFUNC(Switch);
extern RTLFUNC(Wait);
//i#64882# add new WaitUntil
extern RTLFUNC(WaitUntil);
+extern RTLFUNC(FuncCaller);
extern RTLFUNC(GetGUIVersion);
extern RTLFUNC(Choose);
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index 1bb6fb82e113..c30f64af2fe3 100755
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -46,6 +46,8 @@
#include "errobject.hxx"
#include "sbtrace.hxx"
+SbxVariable* getDefaultProp( SbxVariable* pRef );
+
using namespace ::com::sun::star;
bool SbiRuntime::isVBAEnabled()
@@ -544,7 +546,7 @@ SbxArray* SbiInstance::GetLocals( SbMethod* pMeth )
SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, UINT32 nStart )
: rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ),
- pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0)
+ pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), mpExtCaller(0), m_nLastTime(0)
{
nFlags = pe ? pe->GetDebugFlags() : 0;
pIosys = pInst->pIosys;
@@ -601,6 +603,13 @@ SbiRuntime::~SbiRuntime()
void SbiRuntime::SetVBAEnabled(bool bEnabled )
{
bVBAEnabled = bEnabled;
+ if ( bVBAEnabled )
+ {
+ if ( pMeth )
+ mpExtCaller = pMeth->mCaller;
+ }
+ else
+ mpExtCaller = 0;
}
// Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt
@@ -1029,7 +1038,25 @@ SbxVariable* SbiRuntime::GetTOS( short n )
void SbiRuntime::TOSMakeTemp()
{
SbxVariable* p = refExprStk->Get( nExprLvl - 1 );
- if( p->GetRefCount() != 1 )
+ if ( p->GetType() == SbxEMPTY )
+ p->Broadcast( SBX_HINT_DATAWANTED );
+
+ SbxVariable* pDflt = NULL;
+ if ( bVBAEnabled && ( p->GetType() == SbxOBJECT || p->GetType() == SbxVARIANT ) && ( pDflt = getDefaultProp( p ) ) )
+ {
+ pDflt->Broadcast( SBX_HINT_DATAWANTED );
+ // replacing new p 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 );
+ p = new SbxVariable( *pDflt );
+ p->SetFlag( SBX_READWRITE );
+ refExprStk->Put( p, nExprLvl - 1 );
+// return;
+ }
+
+ else if( p->GetRefCount() != 1 )
{
SbxVariable* pNew = new SbxVariable( *p );
pNew->SetFlag( SBX_READWRITE );
@@ -1038,7 +1065,6 @@ void SbiRuntime::TOSMakeTemp()
}
// Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf
-
void SbiRuntime::PushGosub( const BYTE* pc )
{
if( ++nGosubLvl > MAXRECURSION )
diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx
index 4455901bfeba..1e127486b432 100644
--- a/basic/source/runtime/stdobj.cxx
+++ b/basic/source/runtime/stdobj.cxx
@@ -33,7 +33,7 @@
#include <basic/sbstdobj.hxx>
#include "rtlproto.hxx"
#include "sbintern.hxx"
-
+#include <hash_map>
// Das nArgs-Feld eines Tabelleneintrags ist wie folgt verschluesselt:
// Zur Zeit wird davon ausgegangen, dass Properties keine Parameter
// benoetigen!
@@ -69,6 +69,45 @@ struct Methods {
USHORT nHash; // Hashcode
};
+struct StringHashCode
+{
+ size_t operator()( const String& rStr ) const
+ {
+ return rtl_ustr_hashCode_WithLength( rStr.GetBuffer(), rStr.Len() );
+ }
+};
+
+class VBABlacklist
+{
+friend class VBABlackListQuery;
+ std::hash_map< String, bool, StringHashCode > mBlackList;
+ VBABlacklist()
+ {
+ const char* list[] = { "Red" };
+ sal_Int32 nSize = sizeof( list ) / sizeof( list[ 0 ] );
+ for ( sal_Int32 index = 0; index < nSize; ++index )
+ {
+ mBlackList[ String::CreateFromAscii( list[ index ] ).ToLowerAscii() ] = true;
+ }
+ }
+public:
+ bool isBlackListed( const String& sName )
+ {
+ String sNameLower( sName );
+ sNameLower.ToLowerAscii();
+ return ( mBlackList.find( sNameLower ) != mBlackList.end() );
+ }
+};
+
+class VBABlackListQuery
+{
+public:
+ static bool isBlackListed( const String& sName )
+ {
+ static VBABlacklist blackList;
+ return blackList.isBlackListed( sName );
+ }
+};
static Methods aMethods[] = {
{ "AboutStarBasic", SbxNULL, 1 | _FUNCTION, RTLNAME(AboutStarBasic),0 },
@@ -171,7 +210,12 @@ static Methods aMethods[] = {
{ "expression", SbxVARIANT, 0,NULL,0 },
{ "CVErr", SbxVARIANT, 1 | _FUNCTION, RTLNAME(CVErr),0 },
{ "expression", SbxVARIANT, 0,NULL,0 },
-
+{ "DDB", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(DDB),0 },
+ { "Cost", SbxDOUBLE, 0, NULL,0 },
+ { "Salvage", SbxDOUBLE, 0, NULL,0 },
+ { "Life", SbxDOUBLE, 0, NULL,0 },
+ { "Period", SbxDOUBLE, 0, NULL,0 },
+ { "Factor", SbxVARIANT, _OPT, NULL,0 },
{ "Date", SbxDATE, _LFUNCTION,RTLNAME(Date),0 },
{ "DateAdd", SbxDATE, 3 | _FUNCTION, RTLNAME(DateAdd),0 },
{ "Interval", SbxSTRING, 0,NULL,0 },
@@ -216,7 +260,7 @@ static Methods aMethods[] = {
{ "Dir", SbxSTRING, 2 | _FUNCTION, RTLNAME(Dir),0 },
{ "FileSpec", SbxSTRING, _OPT, NULL,0 },
{ "attrmask", SbxINTEGER, _OPT, NULL,0 },
-{ "DoEvents", SbxEMPTY, _FUNCTION, RTLNAME(DoEvents),0 },
+{ "DoEvents", SbxINTEGER, _FUNCTION, RTLNAME(DoEvents),0 },
{ "DumpAllObjects", SbxEMPTY, 2 | _SUB, RTLNAME(DumpAllObjects),0 },
{ "FileSpec", SbxSTRING, 0,NULL,0 },
{ "DumpAll", SbxINTEGER, _OPT, NULL,0 },
@@ -271,6 +315,12 @@ static Methods aMethods[] = {
{ "FreeLibrary", SbxNULL, 1 | _FUNCTION, RTLNAME(FreeLibrary),0 },
{ "Modulename", SbxSTRING, 0,NULL,0 },
+{ "FV", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(FV),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "NPer", SbxDOUBLE, 0, NULL,0 },
+ { "Pmt", SbxDOUBLE, 0, NULL,0 },
+ { "PV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
{ "Get", SbxNULL, 3 | _FUNCTION, RTLNAME(Get),0 },
{ "filenumber", SbxINTEGER, 0,NULL,0 },
{ "recordnumber", SbxLONG, 0,NULL,0 },
@@ -331,6 +381,16 @@ static Methods aMethods[] = {
{ "Compare", SbxINTEGER, _OPT, NULL,0 },
{ "Int", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Int),0 },
{ "number", SbxDOUBLE, 0,NULL,0 },
+{ "IPmt", SbxDOUBLE, 6 | _FUNCTION | _COMPTMASK, RTLNAME(IPmt),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "Per", SbxDOUBLE, 0, NULL,0 },
+ { "NPer", SbxDOUBLE, 0, NULL,0 },
+ { "PV", SbxDOUBLE, 0, NULL,0 },
+ { "FV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
+{ "IRR", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(IRR),0 },
+ { "ValueArray", SbxARRAY, 0, NULL,0 },
+ { "Guess", SbxVARIANT, _OPT, NULL,0 },
{ "IsArray", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsArray),0 },
{ "Variant", SbxVARIANT, 0,NULL,0 },
{ "IsDate", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsDate),0 },
@@ -401,6 +461,10 @@ static Methods aMethods[] = {
{ "Length", SbxLONG, _OPT, NULL,0 },
{ "Minute", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Minute),0 },
{ "Date", SbxDATE, 0,NULL,0 },
+{ "MIRR", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(MIRR),0 },
+ { "ValueArray", SbxARRAY, 0, NULL,0 },
+ { "FinanceRate", SbxDOUBLE, 0, NULL,0 },
+ { "ReinvestRate", SbxDOUBLE, 0, NULL,0 },
{ "MkDir", SbxNULL, 1 | _FUNCTION, RTLNAME(MkDir),0 },
{ "pathname", SbxSTRING, 0,NULL,0 },
{ "Month", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Month),0 },
@@ -417,6 +481,15 @@ static Methods aMethods[] = {
{ "Nothing", SbxOBJECT, _CPROP, RTLNAME(Nothing),0 },
{ "Now", SbxDATE, _FUNCTION, RTLNAME(Now),0 },
+{ "NPer", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(NPer),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "Pmt", SbxDOUBLE, 0, NULL,0 },
+ { "PV", SbxDOUBLE, 0, NULL,0 },
+ { "FV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
+{ "NPV", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(NPV),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "ValueArray", SbxARRAY, 0, NULL,0 },
{ "Null", SbxNULL, _CPROP, RTLNAME(Null),0 },
{ "Oct", SbxSTRING, 1 | _FUNCTION, RTLNAME(Oct),0 },
@@ -428,16 +501,46 @@ static Methods aMethods[] = {
{ "stop", SbxLONG, 0,NULL,0 },
{ "interval", SbxLONG, 0,NULL,0 },
{ "Pi", SbxDOUBLE, _CPROP, RTLNAME(PI),0 },
+
+{ "Pmt", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(Pmt),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "NPer", SbxDOUBLE, 0, NULL,0 },
+ { "PV", SbxDOUBLE, 0, NULL,0 },
+ { "FV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
+
+{ "PPmt", SbxDOUBLE, 6 | _FUNCTION | _COMPTMASK, RTLNAME(PPmt),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "Per", SbxDOUBLE, 0, NULL,0 },
+ { "NPer", SbxDOUBLE, 0, NULL,0 },
+ { "PV", SbxDOUBLE, 0, NULL,0 },
+ { "FV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
+
{ "Put", SbxNULL, 3 | _FUNCTION, RTLNAME(Put),0 },
{ "filenumber", SbxINTEGER, 0,NULL,0 },
{ "recordnumber", SbxLONG, 0,NULL,0 },
{ "variablename", SbxVARIANT, 0,NULL,0 },
+{ "PV", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(PV),0 },
+ { "Rate", SbxDOUBLE, 0, NULL,0 },
+ { "NPer", SbxDOUBLE, 0, NULL,0 },
+ { "Pmt", SbxDOUBLE, 0, NULL,0 },
+ { "FV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
+
{ "QBColor", SbxLONG, 1 | _FUNCTION, RTLNAME(QBColor),0 },
{ "number", SbxINTEGER, 0,NULL,0 },
{ "Randomize", SbxNULL, 1 | _FUNCTION, RTLNAME(Randomize),0 },
{ "Number", SbxDOUBLE, _OPT, NULL,0 },
+{ "Rate", SbxDOUBLE, 6 | _FUNCTION | _COMPTMASK, RTLNAME(Rate),0 },
+ { "NPer", SbxDOUBLE, 0, NULL,0 },
+ { "Pmt", SbxDOUBLE, 0, NULL,0 },
+ { "PV", SbxDOUBLE, 0, NULL,0 },
+ { "FV", SbxVARIANT, _OPT, NULL,0 },
+ { "Due", SbxVARIANT, _OPT, NULL,0 },
+ { "Guess", SbxVARIANT, _OPT, NULL,0 },
{ "Red", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Red),0 },
{ "RGB-Value", SbxLONG, 0,NULL,0 },
{ "Reset", SbxNULL, 0 | _FUNCTION, RTLNAME(Reset),0 },
@@ -491,6 +594,15 @@ static Methods aMethods[] = {
{ "WindowStyle", SbxINTEGER, _OPT, NULL,0 },
{ "Sin", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Sin),0 },
{ "number", SbxDOUBLE, 0,NULL,0 },
+{ "SLN", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(SLN),0 },
+ { "Cost", SbxDOUBLE, 0,NULL,0 },
+ { "Double", SbxDOUBLE, 0,NULL,0 },
+ { "Life", SbxDOUBLE, 0,NULL,0 },
+{ "SYD", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(SYD),0 },
+ { "Cost", SbxDOUBLE, 0,NULL,0 },
+ { "Salvage", SbxDOUBLE, 0,NULL,0 },
+ { "Life", SbxDOUBLE, 0,NULL,0 },
+ { "Period", SbxDOUBLE, 0,NULL,0 },
{ "Space", SbxSTRING, 1 | _FUNCTION, RTLNAME(Space),0 },
{ "string", SbxLONG, 0,NULL,0 },
{ "Spc", SbxSTRING, 1 | _FUNCTION, RTLNAME(Spc),0 },
@@ -605,6 +717,7 @@ static Methods aMethods[] = {
{ "Wait", SbxNULL, 1 | _FUNCTION, RTLNAME(Wait),0 },
{ "Milliseconds", SbxLONG, 0,NULL,0 },
+{ "FuncCaller", SbxVARIANT, _FUNCTION, RTLNAME(FuncCaller),0 },
//#i64882#
{ "WaitUntil", SbxNULL, 1 | _FUNCTION, RTLNAME(WaitUntil),0 },
{ "Date", SbxDOUBLE, 0,NULL,0 },
@@ -683,13 +796,15 @@ SbxVariable* SbiStdObject::Find( const String& rName, SbxClassType t )
&& ( p->nHash == nHash_ )
&& ( rName.EqualsIgnoreCaseAscii( p->pName ) ) )
{
+ SbiInstance* pInst = pINST;
bFound = TRUE;
if( p->nArgs & _COMPTMASK )
{
- SbiInstance* pInst = pINST;
if( !pInst || !pInst->IsCompatibility() )
bFound = FALSE;
}
+ if ( pInst && pInst->IsCompatibility() && VBABlackListQuery::isBlackListed( rName ) )
+ bFound = FALSE;
break;
}
nIndex += ( p->nArgs & _ARGSMASK ) + 1;
diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx
index 06a8bb19af00..e184d8928f3f 100644
--- a/basic/source/runtime/step0.cxx
+++ b/basic/source/runtime/step0.cxx
@@ -48,6 +48,11 @@ Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::
#include <algorithm>
+// for a patch forward declaring these methods below makes sense
+// but, #FIXME lets really just move the methods to the top
+void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType );
+void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled );
+
SbxVariable* getDefaultProp( SbxVariable* pRef );
void SbiRuntime::StepNOP()
@@ -59,34 +64,6 @@ void SbiRuntime::StepArith( SbxOperator eOp )
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 );
@@ -109,19 +86,24 @@ void SbiRuntime::StepCompare( SbxOperator eOp )
// values ( and type ) set as appropriate
SbxDataType p1Type = p1->GetType();
SbxDataType p2Type = p2->GetType();
+ if ( p1Type == SbxEMPTY )
+ {
+ p1->Broadcast( SBX_HINT_DATAWANTED );
+ p1Type = p1->GetType();
+ }
+ if ( p2Type == SbxEMPTY )
+ {
+ p2->Broadcast( SBX_HINT_DATAWANTED );
+ 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 )
+ if ( p1Type == SbxOBJECT )
{
SbxVariable* pDflt = getDefaultProp( p1 );
if ( pDflt )
@@ -141,8 +123,21 @@ void SbiRuntime::StepCompare( SbxOperator eOp )
#ifndef WIN
static SbxVariable* pTRUE = NULL;
static SbxVariable* pFALSE = NULL;
-
- if( p2->Compare( eOp, *p1 ) )
+ static SbxVariable* pNULL = NULL;
+ // why do this on non-windows ?
+ // why do this at all ?
+ // I dumbly follow the pattern :-/
+ if ( bVBAEnabled && ( p1->IsNull() || p2->IsNull() ) )
+ {
+ if( !pNULL )
+ {
+ pNULL = new SbxVariable;
+ pNULL->PutNull();
+ pNULL->AddRef();
+ }
+ PushVar( pNULL );
+ }
+ else if( p2->Compare( eOp, *p1 ) )
{
if( !pTRUE )
{
@@ -163,9 +158,14 @@ void SbiRuntime::StepCompare( SbxOperator eOp )
PushVar( pFALSE );
}
#else
- BOOL bRes = p2->Compare( eOp, *p1 );
SbxVariable* pRes = new SbxVariable;
- pRes->PutBool( bRes );
+ if ( bVBAEnabled && ( p1->IsNull() || p2->IsNull() ) )
+ pRes->PutNull();
+ else
+ {
+ BOOL bRes = p2->Compare( eOp, *p1 );
+ pRes->PutBool( bRes );
+ }
PushVar( pRes );
#endif
}
@@ -679,6 +679,17 @@ void SbiRuntime::StepDIM()
// #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx)
void SbiRuntime::DimImpl( SbxVariableRef refVar )
{
+ // If refDim then this DIM statement is terminating a ReDIM and
+ // previous StepERASE_CLEAR for an array, the following actions have
+ // been delayed from ( StepERASE_CLEAR ) 'till here
+ if ( refRedim )
+ {
+ if ( !refRedimpArray ) // only erase the array not ReDim Preserve
+ lcl_eraseImpl( refVar, bVBAEnabled );
+ SbxDataType eType = refVar->GetType();
+ lcl_clearImpl( refVar, eType );
+ refRedim = NULL;
+ }
SbxArray* pDims = refVar->GetParameters();
// Muss eine gerade Anzahl Argumente haben
// Man denke daran, dass Arg[0] nicht zaehlt!
@@ -844,6 +855,7 @@ void SbiRuntime::StepREDIMP()
void SbiRuntime::StepREDIMP_ERASE()
{
SbxVariableRef refVar = PopVar();
+ refRedim = refVar;
SbxDataType eType = refVar->GetType();
if( eType & SbxARRAY )
{
@@ -854,12 +866,6 @@ void SbiRuntime::StepREDIMP_ERASE()
refRedimpArray = pDimArray;
}
- // As in ERASE
- USHORT nSavFlags = refVar->GetFlags();
- refVar->ResetFlag( SBX_FIXED );
- refVar->SetType( SbxDataType(eType & 0x0FFF) );
- refVar->SetFlags( nSavFlags );
- refVar->Clear();
}
else
if( refVar->IsFixed() )
@@ -932,10 +938,7 @@ void SbiRuntime::StepERASE()
void SbiRuntime::StepERASE_CLEAR()
{
- SbxVariableRef refVar = PopVar();
- lcl_eraseImpl( refVar, bVBAEnabled );
- SbxDataType eType = refVar->GetType();
- lcl_clearImpl( refVar, eType );
+ refRedim = PopVar();
}
void SbiRuntime::StepARRAYACCESS()
diff --git a/basic/source/runtime/step1.cxx b/basic/source/runtime/step1.cxx
index e23ef864218e..ec440a33f16c 100644
--- a/basic/source/runtime/step1.cxx
+++ b/basic/source/runtime/step1.cxx
@@ -93,6 +93,15 @@ void SbiRuntime::StepARGN( UINT32 nOp1 )
{
String aAlias( pImg->GetString( static_cast<short>( nOp1 ) ) );
SbxVariableRef pVal = PopVar();
+ if( bVBAEnabled && ( pVal->ISA(SbxMethod) || pVal->ISA(SbUnoProperty) || pVal->ISA(SbProcedureProperty) ) )
+ {
+ // named variables ( that are Any especially properties ) can be empty at this point and need a broadcast
+ if ( pVal->GetType() == SbxEMPTY )
+ pVal->Broadcast( SBX_HINT_DATAWANTED );
+ // Methoden und Properties evaluieren!
+ SbxVariable* pRes = new SbxVariable( *pVal );
+ pVal = pRes;
+ }
refArgv->Put( pVal, nArgc );
refArgv->PutAlias( aAlias, nArgc++ );
}
@@ -182,7 +191,9 @@ void SbiRuntime::StepJUMPT( UINT32 nOp1 )
void SbiRuntime::StepJUMPF( UINT32 nOp1 )
{
SbxVariableRef p = PopVar();
- if( !p->GetBool() )
+ // In a test e.g. If Null then
+ // will evaluate Null will act as if False
+ if( ( bVBAEnabled && p->IsNull() ) || !p->GetBool() )
StepJUMP( nOp1 );
}
diff --git a/basic/source/runtime/step2.cxx b/basic/source/runtime/step2.cxx
index 587b0ae7a590..347d2646754f 100755
--- a/basic/source/runtime/step2.cxx
+++ b/basic/source/runtime/step2.cxx
@@ -141,7 +141,7 @@ SbxVariable* SbiRuntime::FindElement
if ( pElem )
bSetName = false; // don't overwrite uno name
else
- pElem = getVBAConstant( aName );
+ pElem = VBAConstantHelper::instance().getVBAConstant( aName );
}
// #72382 VORSICHT! Liefert jetzt wegen unbekannten
// Modulen IMMER ein Ergebnis!
@@ -457,7 +457,7 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem )
{
// Falls wir ein Array haben, wollen wir bitte das Array-Element!
SbxArray* pPar;
- if( pElem->GetType() & SbxARRAY )
+ if( ( pElem->GetType() & SbxARRAY ) && (SbxVariable*)refRedim != pElem )
{
SbxBase* pElemObj = pElem->GetObject();
SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
@@ -489,7 +489,7 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem )
pPar->Put( NULL, 0 );
}
// Index-Access bei UnoObjekten beruecksichtigen
- else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) )
+ else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) && ( !bVBAEnabled || ( bVBAEnabled && !pElem->ISA(SbxProperty) ) ) )
{
pPar = pElem->GetParameters();
if ( pPar )
@@ -733,6 +733,8 @@ void SbiRuntime::StepPARAM( UINT32 nOp1, UINT32 nOp2 )
SaveRef( q );
*q = *p;
p = q;
+ if ( i )
+ refParams->Put( p, i );
}
SetupArgs( p, nOp1 );
PushVar( CheckArray( p ) );