diff options
-rw-r--r-- | basic/inc/basic/sberrors.hxx | 19 | ||||
-rw-r--r-- | basic/source/classes/sb.cxx | 49 | ||||
-rw-r--r-- | basic/source/classes/sb.src | 24 | ||||
-rw-r--r-- | basic/source/comp/exprtree.cxx | 10 | ||||
-rw-r--r-- | basic/source/runtime/methods.cxx | 94 | ||||
-rw-r--r-- | basic/source/sbx/sbxdbl.cxx | 9 | ||||
-rw-r--r-- | basic/source/sbx/sbxscan.cxx | 6 | ||||
-rw-r--r-- | basic/source/sbx/sbxvalue.cxx | 9 |
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 ) ) |