summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2007-08-30 09:01:41 +0000
committerVladimir Glazounov <vg@openoffice.org>2007-08-30 09:01:41 +0000
commit59f10af573235ad414bf02d625a3044814afa6ff (patch)
tree3cf86e9a41f0160631d8628c8d36f447242647ef /basic
parentcf2cfafad68b255d3a262a208adcf8b9fb4817a3 (diff)
INTEGRATION: CWS npower7 (1.27.42); FILE MERGED
2007/05/02 09:45:35 npower 1.27.42.7: #i76820# 2007/04/30 16:17:51 npower 1.27.42.6: RESYNC: (1.27-1.28); FILE MERGED 2007/03/02 11:18:26 npower 1.27.42.5: #i73830i# support for 'i\!' in Like expression 2007/03/02 10:09:48 npower 1.27.42.4: #i73830i# fix windows warnings 2007/02/19 10:28:53 npower 1.27.42.3: use a internal flag for vba mode 2007/02/16 17:14:15 npower 1.27.42.2: #i73830 compatible rtl like function 2007/02/16 17:06:54 npower 1.27.42.1: #i70380 compatible erase behaviour
Diffstat (limited to 'basic')
-rw-r--r--basic/source/runtime/step0.cxx224
1 files changed, 205 insertions, 19 deletions
diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx
index c9a578fbd712..b157e875def6 100644
--- a/basic/source/runtime/step0.cxx
+++ b/basic/source/runtime/step0.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: step0.cxx,v $
*
- * $Revision: 1.28 $
+ * $Revision: 1.29 $
*
- * last change: $Author: rt $ $Date: 2007-04-26 08:33:37 $
+ * last change: $Author: vg $ $Date: 2007-08-30 10:01:41 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -49,7 +49,11 @@
#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>
#include <algorithm>
@@ -64,7 +68,6 @@ void SbiRuntime::StepArith( SbxOperator eOp )
TOSMakeTemp();
SbxVariable* p2 = GetTOS();
- bool bVBAInterop = SbiRuntime::isVBAEnabled();
// 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
@@ -74,7 +77,7 @@ void SbiRuntime::StepArith( SbxOperator eOp )
// 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 ( bVBAInterop
+ if ( bVBAEnabled
&& ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT )
)
{
@@ -110,6 +113,40 @@ 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 );
+ }
+ }
+
+ }
#ifndef WIN
static SbxVariable* pTRUE = NULL;
static SbxVariable* pFALSE = NULL;
@@ -166,9 +203,116 @@ 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()
{
- StarBASIC::FatalError( SbERR_NOT_IMPLEMENTED );
+ 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
@@ -244,14 +388,13 @@ void SbiRuntime::StepPUT()
n = refVar->GetFlags();
refVar->SetFlag( SBX_WRITE );
}
- bool bVBAInterop = SbiRuntime::isVBAEnabled();
// 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 ( bVBAInterop )
+ if ( bVBAEnabled )
{
if ( refVar->GetType() == SbxOBJECT )
{
@@ -269,7 +412,7 @@ void SbiRuntime::StepPUT()
*refVar = *refVal;
// lhs is a property who's value is currently null
- if ( !bVBAInterop || ( bVBAInterop && refVar->GetType() != SbxEMPTY ) )
+ if ( !bVBAEnabled || ( bVBAEnabled && refVar->GetType() != SbxEMPTY ) )
// #67607 Uno-Structs kopieren
checkUnoStructCopy( refVal, refVar );
if( bFlagsChanged )
@@ -402,7 +545,7 @@ void SbiRuntime::StepSET()
{
SbxVariableRef refVal = PopVar();
SbxVariableRef refVar = PopVar();
- StepSET_Impl( refVal, refVar, SbiRuntime::isVBAEnabled() ); // this is really assigment
+ StepSET_Impl( refVal, refVar, bVBAEnabled ); // this is really assigment
}
void SbiRuntime::StepVBASET()
@@ -525,6 +668,8 @@ void SbiRuntime::DimImpl( SbxVariableRef refVar )
if( ub < lb )
Error( SbERR_OUT_OF_RANGE ), ub = lb;
pArray->AddDim32( lb, ub );
+ if ( lb != ub )
+ pArray->setHasFixedSize( true );
}
}
else
@@ -693,27 +838,51 @@ void SbiRuntime::StepREDIMP_ERASE()
refVar->SetType( SbxEMPTY );
}
+void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType )
+{
+ USHORT nSavFlags = refVar->GetFlags();
+ refVar->ResetFlag( SBX_FIXED );
+ refVar->SetType( SbxDataType(eType & 0x0FFF) );
+ refVar->SetFlags( nSavFlags );
+ refVar->Clear();
+}
-// Variable loeschen
-// TOS = Variable
-
-void SbiRuntime::StepERASE()
+void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled )
{
- SbxVariableRef refVar = PopVar();
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
- USHORT nSavFlags = refVar->GetFlags();
- refVar->ResetFlag( SBX_FIXED );
- refVar->SetType( SbxDataType(eType & 0x0FFF) );
- refVar->SetFlags( nSavFlags );
- refVar->Clear();
+ lcl_clearImpl( refVar, eType );
}
else
if( refVar->IsFixed() )
@@ -722,6 +891,23 @@ void SbiRuntime::StepERASE()
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 );
+}
+
// Einrichten eines Argvs
// nOp1 bleibt so -> 1. Element ist Returnwert