summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basic/inc/basic/sberrors.hxx19
-rw-r--r--basic/source/classes/sb.cxx49
-rw-r--r--basic/source/classes/sb.src24
-rw-r--r--basic/source/comp/exprtree.cxx10
-rw-r--r--basic/source/runtime/methods.cxx94
-rw-r--r--basic/source/sbx/sbxdbl.cxx9
-rw-r--r--basic/source/sbx/sbxscan.cxx6
-rw-r--r--basic/source/sbx/sbxvalue.cxx9
8 files changed, 199 insertions, 21 deletions
diff --git a/basic/inc/basic/sberrors.hxx b/basic/inc/basic/sberrors.hxx
index c0b5bc1359..d9c4f2f7e0 100644
--- a/basic/inc/basic/sberrors.hxx
+++ b/basic/inc/basic/sberrors.hxx
@@ -277,6 +277,19 @@ typedef ULONG SbError;
#define ERRCODE_BASMGR_REMOVELIB (LAST_SBX_ERROR_ID+101UL) | ERRCODE_AREA_SBX
#define ERRCODE_BASMGR_UNLOADLIB (LAST_SBX_ERROR_ID+102UL) | ERRCODE_AREA_SBX
+#define ERRCODE_BASIC_ARRAY_FIX ((LAST_SBX_ERROR_ID+104UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // This array is fixed
+#define ERRCODE_BASIC_STRING_OVERFLOW ((LAST_SBX_ERROR_ID+105UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Out of string space
+#define ERRCODE_BASIC_EXPR_TOO_COMPLEX ((LAST_SBX_ERROR_ID+106UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Expression too complex
+#define ERRCODE_BASIC_OPER_NOT_PERFORM ((LAST_SBX_ERROR_ID+107UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Can't perform requested operation
+#define ERRCODE_BASIC_TOO_MANY_DLL ((LAST_SBX_ERROR_ID+108UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // Too many dll application clients
+#define ERRCODE_BASIC_LOOP_NOT_INIT ((LAST_SBX_ERROR_ID+109UL) | ERRCODE_AREA_SBX | \
+ ERRCODE_CLASS_COMPILER) // For loop not initialized
+
// Alte Codes auf neue mappen
#define SbERR_SYNTAX ERRCODE_BASIC_SYNTAX
#define SbERR_NO_GOSUB ERRCODE_BASIC_NO_GOSUB
@@ -400,6 +413,12 @@ typedef ULONG SbError;
#define SbERR_PROG_TOO_LARGE ERRCODE_BASIC_PROG_TOO_LARGE
#define SbERR_NO_STRINGS_ARRAYS ERRCODE_BASIC_NO_STRINGS_ARRAYS
#define SbERR_BASIC_EXCEPTION ERRCODE_BASIC_EXCEPTION
+#define SbERR_BASIC_ARRAY_FIX ERRCODE_BASIC_ARRAY_FIX
+#define SbERR_BASIC_STRING_OVERFLOW ERRCODE_BASIC_STRING_OVERFLOW
+#define SbERR_BASIC_EXPR_TOO_COMPLEX ERRCODE_BASIC_EXPR_TOO_COMPLEX
+#define SbERR_BASIC_OPER_NOT_PERFORM ERRCODE_BASIC_OPER_NOT_PERFORM
+#define SbERR_BASIC_TOO_MANY_DLL ERRCODE_BASIC_TOO_MANY_DLL
+#define SbERR_BASIC_LOOP_NOT_INIT ERRCODE_BASIC_LOOP_NOT_INIT
// #define SbERR_COMPILER_END ERRCODE_BASIC_COMPILER_END
/* ALT
diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx
index 7c9640bf13..f80c622ef8 100644
--- a/basic/source/classes/sb.cxx
+++ b/basic/source/classes/sb.cxx
@@ -1120,6 +1120,27 @@ USHORT StarBASIC::GetVBErrorCode( SbError nError )
{
USHORT nRet = 0;
+ if( SbiRuntime::isVBAEnabled() )
+ {
+ switch( nError )
+ {
+ case SbERR_BASIC_ARRAY_FIX:
+ return 10;
+ case SbERR_BASIC_STRING_OVERFLOW:
+ return 14;
+ case SbERR_BASIC_EXPR_TOO_COMPLEX:
+ return 16;
+ case SbERR_BASIC_OPER_NOT_PERFORM:
+ return 17;
+ case SbERR_BASIC_TOO_MANY_DLL:
+ return 47;
+ case SbERR_BASIC_LOOP_NOT_INIT:
+ return 92;
+ default:
+ nRet = 0;
+ }
+ }
+
// Suchschleife
const SFX_VB_ErrorItem* pErrItem;
USHORT nIndex = 0;
@@ -1141,7 +1162,33 @@ SbError StarBASIC::GetSfxFromVBError( USHORT nError )
{
SbError nRet = 0L;
- // Suchschleife
+ if( SbiRuntime::isVBAEnabled() )
+ {
+ switch( nError )
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 12:
+ case 73:
+ return 0L;
+ case 10:
+ return SbERR_BASIC_ARRAY_FIX;
+ case 14:
+ return SbERR_BASIC_STRING_OVERFLOW;
+ case 16:
+ return SbERR_BASIC_EXPR_TOO_COMPLEX;
+ case 17:
+ return SbERR_BASIC_OPER_NOT_PERFORM;
+ case 47:
+ return SbERR_BASIC_TOO_MANY_DLL;
+ case 92:
+ return SbERR_BASIC_LOOP_NOT_INIT;
+ default:
+ nRet = 0L;
+ }
+ }
const SFX_VB_ErrorItem* pErrItem;
USHORT nIndex = 0;
do
diff --git a/basic/source/classes/sb.src b/basic/source/classes/sb.src
index 56a9b64582..4daa8e0eac 100644
--- a/basic/source/classes/sb.src
+++ b/basic/source/classes/sb.src
@@ -567,6 +567,30 @@ Resource RID_BASIC_START
{
Text [ en-US ] = "An exception occurred $(ARG1)." ;
};
+ String ERRCODE_BASIC_ARRAY_FIX & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "This array is fixed or temporarily locked." ;
+ };
+ String ERRCODE_BASIC_STRING_OVERFLOW & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Out of string space." ;
+ };
+ String ERRCODE_BASIC_EXPR_TOO_COMPLEX & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Expression Too Complex." ;
+ };
+ String ERRCODE_BASIC_OPER_NOT_PERFORM & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Can't perform requested operation." ;
+ };
+ String ERRCODE_BASIC_TOO_MANY_DLL & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "Too many DLL application clients." ;
+ };
+ String ERRCODE_BASIC_LOOP_NOT_INIT & ERRCODE_RES_MASK
+ {
+ Text [ en-US ] = "For loop not initialized." ;
+ };
};
// Hinweis: IDS_SBERR_TERMINATED = IDS_SBERR_START+2000.
String IDS_SBERR_TERMINATED
diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx
index 9a9246791d..6e53f0781e 100644
--- a/basic/source/comp/exprtree.cxx
+++ b/basic/source/comp/exprtree.cxx
@@ -117,7 +117,7 @@ static BOOL DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTo
if( !p->WhiteSpace() || eCurExpr != SbSYMBOL )
return FALSE;
if ( eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING
- || eTok == SYMBOL || eTok == COMMA || eTok == DOT )
+ || eTok == SYMBOL || eTok == COMMA || eTok == DOT || eTok == NOT )
{
return TRUE;
}
@@ -495,6 +495,14 @@ SbiExprNode* SbiExpression::Operand()
switch( eTok = pParser->Peek() )
{
case SYMBOL:
+ pRes = Term();
+ // process something like "IF Not r Is Nothing Then .."
+ if( pParser->IsVBASupportOn() && pParser->Peek() == IS )
+ {
+ eTok = pParser->Next();
+ pRes = new SbiExprNode( pParser, pRes, eTok, Like() );
+ }
+ break;
case DOT: // .with
pRes = Term(); break;
case NUMBER:
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
index 333ff1c0dc..fe6014560d 100644
--- a/basic/source/runtime/methods.cxx
+++ b/basic/source/runtime/methods.cxx
@@ -1378,26 +1378,33 @@ RTLFUNC(Replace)
if ( nArgCount == 6 )
bTextMode = rPar.Get(6)->GetInteger();
- USHORT nStrLen = aExpStr.Len();
+ USHORT nExpStrLen = aExpStr.Len();
+ USHORT nFindStrLen = aFindStr.Len();
+ USHORT nReplaceStrLen = aReplaceStr.Len();
- if( lStartPos <= nStrLen )
+ if( lStartPos <= nExpStrLen )
{
- String aSrcStr( aExpStr );
- if( bTextMode )
+ USHORT nPos = static_cast<USHORT>( lStartPos - 1 );
+ USHORT nCounts = 0;
+ while( lCount == -1 || lCount > nCounts )
{
+ String aSrcStr( aExpStr );
+ if( bTextMode )
+ {
aSrcStr.ToUpperAscii();
aFindStr.ToUpperAscii();
- }
-
- USHORT nPos = aSrcStr.Search( aFindStr, static_cast<USHORT>( lStartPos - 1 ) );
- USHORT nCounts = 0;
- USHORT nReplaceLength = aReplaceStr.Len() ? aReplaceStr.Len():1;
- while( nPos != STRING_NOTFOUND && (lCount == -1 || lCount > nCounts) )
- {
- aExpStr.Replace( nPos, aFindStr.Len(), aReplaceStr );
- nPos = nPos + nReplaceLength;
+ }
nPos = aSrcStr.Search( aFindStr, nPos );
- nCounts++;
+ if( nPos != STRING_NOTFOUND )
+ {
+ aExpStr.Replace( nPos, nFindStrLen, aReplaceStr );
+ nPos = nPos - nFindStrLen + nReplaceStrLen + 1;
+ nCounts++;
+ }
+ else
+ {
+ break;
+ }
}
}
rPar.Get(0)->PutString( aExpStr.Copy( static_cast<USHORT>(lStartPos - 1) ) );
@@ -1779,17 +1786,52 @@ INT16 implGetDateYear( double aDate )
BOOL implDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, double& rdRet )
{
+ if ( nYear < 30 )
+ nYear += 2000;
if ( nYear < 100 )
nYear += 1900;
- if ((nYear < 100 || nYear > 9999) ||
- (nMonth < 1 || nMonth > 12 ) ||
- (nDay < 1 || nDay > 31 ))
+ Date aCurDate( nDay, nMonth, nYear );
+ if ((nYear < 100 || nYear > 9999) )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return FALSE;
}
+ if ( !SbiRuntime::isVBAEnabled() )
+ {
+ if ( (nMonth < 1 || nMonth > 12 )||
+ (nDay < 1 || nDay > 31 ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return FALSE;
+ }
+ }
+ else
+ {
+ // grab the year & month
+ aCurDate = Date( 1, (( nMonth % 12 ) > 0 ) ? ( nMonth % 12 ) : 12 + ( nMonth % 12 ), nYear );
+
+ // adjust year based on month value
+ // e.g. 2000, 0, xx = 1999, 12, xx ( or December of the previous year )
+ // 2000, 13, xx = 2001, 1, xx ( or January of the following year )
+ if( ( nMonth < 1 ) || ( nMonth > 12 ) )
+ {
+ // inacurrate around leap year, don't use days to calculate,
+ // just modify the months directory
+ INT16 nYearAdj = ( nMonth /12 ); // default to positive months inputed
+ if ( nMonth <=0 )
+ nYearAdj = ( ( nMonth -12 ) / 12 );
+ aCurDate.SetYear( aCurDate.GetYear() + nYearAdj );
+ }
+
+ // adjust day value,
+ // e.g. 2000, 2, 0 = 2000, 1, 31 or the last day of the previous month
+ // 2000, 1, 32 = 2000, 2, 1 or the first day of the following month
+ if( ( nDay < 1 ) || ( nDay > aCurDate.GetDaysInMonth() ) )
+ aCurDate += nDay - 1;
+ else
+ aCurDate.SetDay( nDay );
+ }
- Date aCurDate( nDay, nMonth, nYear );
long nDiffDays = GetDayDiff( aCurDate );
rdRet = (double)nDiffDays;
return TRUE;
@@ -1916,6 +1958,22 @@ RTLFUNC(DateValue)
String aStr( rPar.Get(1)->GetString() );
BOOL bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult );
short nType = pFormatter->GetType( nIndex );
+
+ // DateValue("February 12, 1969") raises error if the system locale is not en_US
+ // by using SbiInstance::GetNumberFormatter.
+ // It seems that both locale number formatter and English number formatter
+ // are supported in Visual Basic.
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ if( !bSuccess && ( eLangType != LANGUAGE_ENGLISH_US ) )
+ {
+ // Create a new SvNumberFormatter by using LANGUAGE_ENGLISH to get the date value;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ SvNumberFormatter aFormatter( xFactory, LANGUAGE_ENGLISH_US );
+ bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, fResult );
+ nType = aFormatter.GetType( nIndex );
+ }
+
if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME))
{
if ( nType == NUMBERFORMAT_DATETIME )
diff --git a/basic/source/sbx/sbxdbl.cxx b/basic/source/sbx/sbxdbl.cxx
index 6f47403dea..8cccdc54c2 100644
--- a/basic/source/sbx/sbxdbl.cxx
+++ b/basic/source/sbx/sbxdbl.cxx
@@ -33,6 +33,7 @@
#include <tools/errcode.hxx>
#include <basic/sbx.hxx>
#include "sbxconv.hxx"
+#include "runtime.hxx"
double ImpGetDouble( const SbxValues* p )
{
@@ -79,13 +80,21 @@ double ImpGetDouble( const SbxValues* p )
case SbxSTRING:
case SbxLPSTR:
if( !p->pString )
+ {
nRes = 0;
+ if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
else
{
double d;
SbxDataType t;
if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ {
nRes = 0;
+ if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
else
nRes = d;
}
diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx
index 0ce285de58..07a3012b60 100644
--- a/basic/source/sbx/sbxscan.cxx
+++ b/basic/source/sbx/sbxscan.cxx
@@ -53,6 +53,7 @@
#include <svtools/svtools.hrc>
#include "basrid.hxx"
+#include "runtime.hxx"
#include <svtools/zforlist.hxx>
#include <comphelper/processfactory.hxx>
@@ -231,6 +232,11 @@ SbxError ImpScan( const XubString& rWSrc, double& nVal, SbxDataType& rType,
if( l >= SbxMININT && l <= SbxMAXINT )
eScanType = SbxINTEGER;
}
+ else if ( SbiRuntime::isVBAEnabled() )
+ {
+ OSL_TRACE("Reporting error converting");
+ return SbxERR_CONVERSION;
+ }
if( pLen )
*pLen = (USHORT) ( p - pStart );
if( !bRes )
diff --git a/basic/source/sbx/sbxvalue.cxx b/basic/source/sbx/sbxvalue.cxx
index 4dce9be0b7..5c2105d89d 100644
--- a/basic/source/sbx/sbxvalue.cxx
+++ b/basic/source/sbx/sbxvalue.cxx
@@ -1147,7 +1147,13 @@ BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp )
{
SbxValues aL, aR;
bool bDecimal = false;
- if( eThisType == SbxSTRING || eOp == SbxCAT || ( bVBAInterop && ( eOpType == SbxSTRING ) && ( eOp == SbxPLUS ) ) )
+ if( bVBAInterop && ( ( eThisType == SbxSTRING && eOpType != SbxSTRING ) ||
+ ( eThisType != SbxSTRING && eOpType == SbxSTRING ) ) &&
+ ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS ) )
+ {
+ goto Lbl_OpIsDouble;
+ }
+ else if( eThisType == SbxSTRING || eOp == SbxCAT || ( bVBAInterop && ( eOpType == SbxSTRING ) && ( eOp == SbxPLUS ) ) )
{
if( eOp == SbxCAT || eOp == SbxPLUS )
{
@@ -1392,6 +1398,7 @@ BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp )
}
}
else
+Lbl_OpIsDouble:
{ // Andere Operatoren
aL.eType = aR.eType = SbxDOUBLE;
if( rOp.Get( aR ) )