summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-02-20 16:16:40 +0300
committerXisco Fauli <xiscofauli@libreoffice.org>2023-02-22 08:11:18 +0000
commit2074fd1b6c97e0b9b605297ad87e88647e3d05f9 (patch)
tree3b76604e41c68000b61c3384adfb3139230ceeaa /basic
parentab07e43f38455f3ba4f97275e72dd4eba1027040 (diff)
tdf#153752: SbxObject::Execute: extra characters in Option Compatible mode
Change-Id: Ib3e4bd9eb9a249123a686f2434ded7b529fb050f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147345 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147389
Diffstat (limited to 'basic')
-rw-r--r--basic/source/classes/sb.cxx2
-rw-r--r--basic/source/classes/sbxmod.cxx28
-rw-r--r--basic/source/comp/parser.cxx6
-rw-r--r--basic/source/runtime/runtime.cxx2
-rw-r--r--basic/source/runtime/stdobj.cxx2
-rw-r--r--basic/source/sbx/sbxexec.cxx66
6 files changed, 62 insertions, 44 deletions
diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx
index f1ab6dd1da0c..0296e2238ca1 100644
--- a/basic/source/classes/sb.cxx
+++ b/basic/source/classes/sb.cxx
@@ -744,7 +744,7 @@ SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule )
}
}
SetModuleType( ModuleType::CLASS );
- mbVBACompat = pClassModule->mbVBACompat;
+ mbVBASupport = pClassModule->mbVBASupport;
}
SbClassModuleObject::~SbClassModuleObject()
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx
index 60bdc9171b48..d8232a6815c8 100644
--- a/basic/source/classes/sbxmod.cxx
+++ b/basic/source/classes/sbxmod.cxx
@@ -416,9 +416,9 @@ static bool getDefaultVBAMode( StarBASIC* pb )
// A Basic module has set EXTSEARCH, so that the elements, that the module contains,
// could be found from other module.
-SbModule::SbModule( const OUString& rName, bool bVBACompat )
+SbModule::SbModule( const OUString& rName, bool bVBASupport )
: SbxObject( "StarBASICModule" ),
- pBreaks(nullptr), mbVBACompat( bVBACompat ), bIsProxyModule( false )
+ pBreaks(nullptr), mbVBASupport(bVBASupport), mbCompat(bVBASupport), bIsProxyModule(false)
{
SetName( rName );
SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::GlobalSearch );
@@ -802,11 +802,11 @@ void SbModule::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
void SbModule::SetSource32( const OUString& r )
{
// Default basic mode to library container mode, but... allow Option VBASupport 0/1 override
- SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) );
+ SetVBASupport( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) );
aOUSource = r;
StartDefinitions();
SbiTokenizer aTok( r );
- aTok.SetCompatible( IsVBACompat() );
+ aTok.SetCompatible( IsVBASupport() );
while( !aTok.IsEof() )
{
@@ -837,12 +837,13 @@ void SbModule::SetSource32( const OUString& r )
eCurTok = aTok.Next();
if( eCurTok == COMPATIBLE )
{
+ mbCompat = true;
aTok.SetCompatible( true );
}
else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) )
{
bool bIsVBA = ( aTok.GetDbl()== 1 );
- SetVBACompat( bIsVBA );
+ SetVBASupport( bIsVBA );
aTok.SetCompatible( bIsVBA );
}
}
@@ -974,15 +975,16 @@ static void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
}
-void SbModule::SetVBACompat( bool bCompat )
+void SbModule::SetVBASupport( bool bSupport )
{
- if( mbVBACompat == bCompat )
+ if( mbVBASupport == bSupport )
return;
- mbVBACompat = bCompat;
+ mbVBASupport = bSupport;
// initialize VBA document API
- if( mbVBACompat ) try
+ if( mbVBASupport ) try
{
+ mbCompat = true;
StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
uno::Reference< lang::XMultiServiceFactory > xFactory( getDocumentModel( pBasic ), uno::UNO_QUERY_THROW );
xFactory->createInstance( "ooo.vba.VBAGlobals" );
@@ -1067,7 +1069,7 @@ namespace
// Run a Basic-subprogram
void SbModule::Run( SbMethod* pMeth )
{
- SAL_INFO("basic","About to run " << pMeth->GetName() << ", vba compatmode is " << mbVBACompat );
+ SAL_INFO("basic","About to run " << pMeth->GetName() << ", vba compatmode is " << mbVBASupport );
static sal_uInt16 nMaxCallLevel = 0;
@@ -1088,7 +1090,7 @@ void SbModule::Run( SbMethod* pMeth )
/* If a VBA script in a document is started, get the VBA compatibility
interface from the document Basic library container, and notify all
VBA script listeners about the started script. */
- if( mbVBACompat )
+ if( mbVBASupport )
{
StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
if( pBasic && pBasic->IsDocBasic() ) try
@@ -1169,7 +1171,7 @@ void SbModule::Run( SbMethod* pMeth )
{
RunGuard xRuntimeGuard(this, pMeth, pMeth->nStart, pSbData, bDelInst);
- if (mbVBACompat)
+ if (mbVBASupport)
pSbData->pInst->EnableCompatibility(true);
xRuntimeGuard.run();
@@ -2500,7 +2502,7 @@ void SbUserFormModule::triggerResizeEvent()
SbUserFormModuleInstance* SbUserFormModule::CreateInstance()
{
- SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() );
+ SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBASupport() );
return pInstance;
}
diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx
index 777db4071615..70bc27dcd16b 100644
--- a/basic/source/comp/parser.cxx
+++ b/basic/source/comp/parser.cxx
@@ -145,7 +145,7 @@ SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
rTypeArray = new SbxArray; // array for user defined types
rEnumArray = new SbxArray; // array for Enum types
- bVBASupportOn = pm->IsVBACompat();
+ bVBASupportOn = pm->IsVBASupport();
if ( bVBASupportOn )
EnableCompatibility();
@@ -818,9 +818,9 @@ void SbiParser::Option()
}
// if the module setting is different
// reset it to what the Option tells us
- if ( bVBASupportOn != aGen.GetModule().IsVBACompat() )
+ if ( bVBASupportOn != aGen.GetModule().IsVBASupport() )
{
- aGen.GetModule().SetVBACompat( bVBASupportOn );
+ aGen.GetModule().SetVBASupport( bVBASupportOn );
}
break;
}
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index d0f49c8f6166..0e191623fe9d 100644
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -624,7 +624,7 @@ SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart )
nForLvl = 0;
nOps = 0;
refExprStk = new SbxArray;
- SetVBAEnabled( pMod->IsVBACompat() );
+ SetVBAEnabled( pMod->IsVBASupport() );
SetParameters( pe ? pe->GetParameters() : nullptr );
}
diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx
index 215f879369df..a89fdebb0472 100644
--- a/basic/source/runtime/stdobj.cxx
+++ b/basic/source/runtime/stdobj.cxx
@@ -993,7 +993,7 @@ SbxVariable* SbiStdObject::Find( const OUString& rName, SbxClassType t )
// No instance running => compiling a source on module level.
const SbModule* pModule = GetSbData()->pCompMod;
if (pModule)
- bCompatibility = pModule->IsVBACompat();
+ bCompatibility = pModule->IsVBASupport();
}
if ((bCompatibility && (NORMONLY_ & p->nArgs)) || (!bCompatibility && (COMPATONLY_ & p->nArgs)))
bFound = false;
diff --git a/basic/source/sbx/sbxexec.cxx b/basic/source/sbx/sbxexec.cxx
index f3abca766d35..de711944d36c 100644
--- a/basic/source/sbx/sbxexec.cxx
+++ b/basic/source/sbx/sbxexec.cxx
@@ -17,19 +17,23 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <basic/sbmod.hxx>
#include <basic/sbx.hxx>
#include <basic/sberrors.hxx>
#include <rtl/character.hxx>
#include <rtl/ustrbuf.hxx>
+#include <basiccharclass.hxx>
static SbxVariableRef Element
( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf,
- SbxClassType );
+ SbxClassType, bool bCompatible );
static const sal_Unicode* SkipWhitespace( const sal_Unicode* p )
{
- while( *p && ( *p == ' ' || *p == '\t' ) )
+ while( BasicCharClass::isWhitespace(*p) )
p++;
return p;
}
@@ -37,7 +41,7 @@ static const sal_Unicode* SkipWhitespace( const sal_Unicode* p )
// Scanning of a symbol. The symbol were inserted in rSym, the return value
// is the new scan position. The symbol is at errors empty.
-static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym )
+static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym, bool bCompatible )
{
sal_uInt16 nLen = 0;
// Did we have a nonstandard symbol?
@@ -54,7 +58,7 @@ static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym )
else
{
// A symbol had to begin with an alphabetic character or an underline
- if( !rtl::isAsciiAlpha( *p ) && *p != '_' )
+ if( !BasicCharClass::isAlpha( *p, bCompatible ) && *p != '_' )
{
SbxBase::SetError( ERRCODE_BASIC_SYNTAX );
}
@@ -62,7 +66,7 @@ static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym )
{
rSym = p;
// The it can contain alphabetic characters, numbers or underlines
- while( *p && (rtl::isAsciiAlphanumeric( *p ) || *p == '_') )
+ while( *p && (BasicCharClass::isAlphaNumeric( *p, bCompatible ) || *p == '_') )
{
p++;
nLen++;
@@ -81,15 +85,15 @@ static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym )
// Qualified name. Element.Element...
static SbxVariableRef QualifiedName
- ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, SbxClassType t )
+ ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, SbxClassType t, bool bCompatible )
{
SbxVariableRef refVar;
const sal_Unicode* p = SkipWhitespace( *ppBuf );
- if( rtl::isAsciiAlpha( *p ) || *p == '_' || *p == '[' )
+ if( BasicCharClass::isAlpha( *p, bCompatible ) || *p == '_' || *p == '[' )
{
// Read in the element
- refVar = Element( pObj, pGbl, &p, t );
+ refVar = Element( pObj, pGbl, &p, t, bCompatible );
while( refVar.is() && (*p == '.' || *p == '!') )
{
// It follows still an objectelement. The current element
@@ -103,7 +107,7 @@ static SbxVariableRef QualifiedName
break;
p++;
// And the next element please
- refVar = Element( pObj, pGbl, &p, t );
+ refVar = Element( pObj, pGbl, &p, t, bCompatible );
}
}
else
@@ -116,7 +120,7 @@ static SbxVariableRef QualifiedName
// a function (with optional parameters).
static SbxVariableRef Operand
- ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bVar )
+ ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bVar, bool bCompatible )
{
SbxVariableRef refVar( new SbxVariable );
const sal_Unicode* p = SkipWhitespace( *ppBuf );
@@ -159,7 +163,7 @@ static SbxVariableRef Operand
}
else
{
- refVar = QualifiedName( pObj, pGbl, &p, SbxClassType::DontCare );
+ refVar = QualifiedName( pObj, pGbl, &p, SbxClassType::DontCare, bCompatible );
}
*ppBuf = p;
return refVar;
@@ -168,15 +172,15 @@ static SbxVariableRef Operand
// Read in of a simple term. The operands +, -, * and /
// are supported.
-static SbxVariableRef MulDiv( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf )
+static SbxVariableRef MulDiv( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bCompatible )
{
const sal_Unicode* p = *ppBuf;
- SbxVariableRef refVar( Operand( pObj, pGbl, &p, false ) );
+ SbxVariableRef refVar( Operand( pObj, pGbl, &p, false, bCompatible ) );
p = SkipWhitespace( p );
while( refVar.is() && ( *p == '*' || *p == '/' ) )
{
sal_Unicode cOp = *p++;
- SbxVariableRef refVar2( Operand( pObj, pGbl, &p, false ) );
+ SbxVariableRef refVar2( Operand( pObj, pGbl, &p, false, bCompatible ) );
if( refVar2.is() )
{
// temporary variable!
@@ -198,15 +202,15 @@ static SbxVariableRef MulDiv( SbxObject* pObj, SbxObject* pGbl, const sal_Unicod
return refVar;
}
-static SbxVariableRef PlusMinus( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf )
+static SbxVariableRef PlusMinus( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bCompatible )
{
const sal_Unicode* p = *ppBuf;
- SbxVariableRef refVar( MulDiv( pObj, pGbl, &p ) );
+ SbxVariableRef refVar( MulDiv( pObj, pGbl, &p, bCompatible ) );
p = SkipWhitespace( p );
while( refVar.is() && ( *p == '+' || *p == '-' ) )
{
sal_Unicode cOp = *p++;
- SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p ) );
+ SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p, bCompatible ) );
if( refVar2.is() )
{
// temporary Variable!
@@ -228,10 +232,10 @@ static SbxVariableRef PlusMinus( SbxObject* pObj, SbxObject* pGbl, const sal_Uni
return refVar;
}
-static SbxVariableRef Assign( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf )
+static SbxVariableRef Assign( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bCompatible )
{
const sal_Unicode* p = *ppBuf;
- SbxVariableRef refVar( Operand( pObj, pGbl, &p, true ) );
+ SbxVariableRef refVar( Operand( pObj, pGbl, &p, true, bCompatible ) );
p = SkipWhitespace( p );
if( refVar.is() )
{
@@ -246,7 +250,7 @@ static SbxVariableRef Assign( SbxObject* pObj, SbxObject* pGbl, const sal_Unicod
else
{
p++;
- SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p ) );
+ SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p, bCompatible ) );
if( refVar2.is() )
{
SbxVariable* pVar = refVar.get();
@@ -270,10 +274,10 @@ static SbxVariableRef Assign( SbxObject* pObj, SbxObject* pGbl, const sal_Unicod
static SbxVariableRef Element
( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf,
- SbxClassType t )
+ SbxClassType t, bool bCompatible )
{
OUString aSym;
- const sal_Unicode* p = Symbol( *ppBuf, aSym );
+ const sal_Unicode* p = Symbol( *ppBuf, aSym, bCompatible );
SbxVariableRef refVar;
if( !aSym.isEmpty() )
{
@@ -299,7 +303,7 @@ static SbxVariableRef Element
// Search parameter always global!
while( *p && *p != ')' && *p != ']' )
{
- SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p );
+ SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p, bCompatible );
if( !refArg.is() )
{
// Error during the parsing
@@ -346,7 +350,7 @@ SbxVariable* SbxObject::Execute( const OUString& rTxt )
{
SetError( ERRCODE_BASIC_SYNTAX ); break;
}
- pVar = Assign( this, this, &p );
+ pVar = Assign( this, this, &p, IsModuleCompatible() );
if( !pVar.is() )
{
break;
@@ -369,7 +373,7 @@ SbxVariable* SbxObject::FindQualified( const OUString& rName, SbxClassType t )
{
return nullptr;
}
- pVar = QualifiedName( this, this, &p, t );
+ pVar = QualifiedName( this, this, &p, t, IsModuleCompatible() );
p = SkipWhitespace( p );
if( *p )
{
@@ -378,4 +382,16 @@ SbxVariable* SbxObject::FindQualified( const OUString& rName, SbxClassType t )
return pVar.get();
}
+bool SbxObject::IsModuleCompatible() const
+{
+ const SbxObject* pObj = this;
+ while (pObj)
+ {
+ if (auto pMod = dynamic_cast<const SbModule*>(pObj))
+ return pMod->IsCompatible();
+ pObj = pObj->GetParent();
+ }
+ return false;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */